]> git.mxchange.org Git - friendica.git/commitdiff
Merge pull request #3797 from rabuzarus/20171015_-_duplicate_event
authorMichael Vogel <icarus@dabo.de>
Wed, 18 Oct 2017 16:57:58 +0000 (18:57 +0200)
committerGitHub <noreply@github.com>
Wed, 18 Oct 2017 16:57:58 +0000 (18:57 +0200)
 add event action: duplicate events

31 files changed:
CHANGELOG
README.translate.md
doc/translations.md
include/Contact.php
include/dfrn.php
include/event.php
include/feed.php
include/follow.php
include/html2bbcode.php
include/items.php
include/network.php
include/ostatus.php
include/text.php
js/country.js
mod/admin.php
mod/contacts.php
mod/display.php
mod/notes.php
mod/ostatus_subscribe.php
src/Core/System.php
src/ParseUrl.php
view/global.css
view/lang/de/messages.po
view/lang/de/strings.php
view/templates/display-head.tpl
view/templates/event_stream_item.tpl [new file with mode: 0644]
view/theme/frio/css/mod_events.css
view/theme/frio/css/style.css
view/theme/frio/js/mod_events.js
view/theme/frio/js/theme.js
view/theme/frio/templates/event_stream_item.tpl [new file with mode: 0644]

index 66766c5502499854d0989a6be2d450a8109d918a..e9b5cae857b7992aabc9facae617f4dc20a700b9 100644 (file)
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,29 @@
+Version 3.5.4 (2017-10-16)
+  Friendica Core:
+    Updates to the translations (DE) [translation teams]
+    Updates to the docs [tobiasd, annando]
+    Code refactoring [annando]
+    Fixing some problems with moving accounts to new nodes [annando]
+    Fixing the admin account in the Vagrant box [tobiasd]
+    Fixing a bug in the search functionality [annando]
+    Improvements to SQL queries [annando]
+    Improvements to the themes (frio) [annando]
+    Improvements to the import of RSS feeds [annando]
+    Improvements to the OStatus (GNU Social) compatibility [annando]
+    Added possibility to block contacts for a node [annando]
+    Added sending out the migration signal to Diaspora contacts [annando]
+    Added processing of Diaspora account migration signal [annando]
+    Added new fields to the generated data for displaying events [annando]
+    Update vier theme with new support forum URL [AlfredSK]
+    Update the DB handling for support of PHP 7.1 [annando]
+
+  Friendica Addons:
+    dav: Update the database handling [annando]
+    newmemberwidget: Update support forum URL [AlfredSK]
+
+  Closed Issues:
+    3711, 3714
+
 Version 3.5.3 (2017-10-05)
   Friendica Core:
     Updates to the translations (DE, EN-GB, EN-US, ES, ZH-CN) [translation teams]
index 696dec10b12ddb30aa6128d3ef7c89f9f664df90..83c24e05424022ef7103b9f765efb51ee511a601 100644 (file)
@@ -56,6 +56,9 @@ Assuming you want to convert the German localization which is placed in view/lan
        repository, push it to your fork of the friendica repository at github and
        issue a pull request for that commit.
 
+You should translate the PO files at Transifex.
+Otherwise your work might get lost, when the translation from Transifex is included to the Friendica repository after it was updated there.
+
 Utilities
 ---------
 
index c14b685be113578efdf712826d848c84e5c8058a..d6b48d9eac3579b3cd9aaf3169ae242a82e87964 100644 (file)
@@ -58,6 +58,9 @@ Assuming you want to convert the German localization which is placed in view/lan
        repository, push it to your fork of the friendica repository at github and
        issue a pull request for that commit.
 
+You should translate the PO files at Transifex.
+Otherwise your work might get lost, when the translation from Transifex is included to the Friendica repository after it was updated there.
+
 Utilities
 ---------
 
index 8b575bf122bfba5f8c8cc887e01eeeca65600823..88f588e2f6e4271b898e5111d34d30763953baab 100644 (file)
@@ -155,7 +155,7 @@ function mark_for_death($contact) {
 
 function unmark_for_death($contact) {
 
-       $r = q("SELECT `term-date` FROM `contact` WHERE `id` = %d AND `term-date` > '%s'",
+       $r = q("SELECT `term-date` FROM `contact` WHERE `id` = %d AND (`term-date` > '%s' OR `archive`)",
                intval($contact['id']),
                dbesc('1000-00-00 00:00:00')
        );
@@ -166,16 +166,11 @@ function unmark_for_death($contact) {
        }
 
        // It's a miracle. Our dead contact has inexplicably come back to life.
-       q("UPDATE `contact` SET `term-date` = '%s' WHERE `id` = %d",
-               dbesc(NULL_DATE),
-               intval($contact['id'])
-       );
+       $fields = array('term-date' => NULL_DATE, 'archive' => false);
+       dba::update('contact', $fields, array('id' => $contact['id']));
 
        if ($contact['url'] != '') {
-               q("UPDATE `contact` SET `term-date` = '%s' WHERE `nurl` = '%s'",
-                       dbesc(NULL_DATE),
-                       dbesc(normalise_link($contact['url']))
-               );
+               dba::update('contact', $fields, array('nurl' => normalise_link($contact['url'])));
        }
 }
 
index eb0f9fbb4ee0d0fd7513095f053d31f83e8f246b..55c51cb0118a69fd482b2f61c13a9046656647c0 100644 (file)
@@ -289,10 +289,17 @@ class dfrn {
         * @brief Generate an atom entry for a given item id
         *
         * @param int $item_id The item id
+        * @param boolean $conversation Show the conversation. If false show the single post.
         *
         * @return string DFRN feed entry
         */
-       public static function itemFeed($item_id) {
+       public static function itemFeed($item_id, $conversation = false) {
+               if ($conversation) {
+                       $condition = '`item`.`parent`';
+               } else {
+                       $condition = '`item`.`id`';
+               }
+
                $r = q("SELECT `item`.*, `item`.`id` AS `item_id`,
                        `contact`.`name`, `contact`.`network`, `contact`.`photo`, `contact`.`url`,
                        `contact`.`name-date`, `contact`.`uri-date`, `contact`.`avatar-date`,
@@ -302,8 +309,9 @@ class dfrn {
                        STRAIGHT_JOIN `contact` ON `contact`.`id` = `item`.`contact-id`
                                AND (NOT `contact`.`blocked` OR `contact`.`pending`)
                        LEFT JOIN `sign` ON `sign`.`iid` = `item`.`id`
-                       WHERE `item`.`id` = %d AND `item`.`visible` AND NOT `item`.`moderated` AND `item`.`parent` != 0
+                       WHERE %s = %d AND `item`.`visible` AND NOT `item`.`moderated` AND `item`.`parent` != 0
                        AND NOT `item`.`private`",
+                       $condition,
                        intval($item_id)
                );
 
@@ -311,6 +319,7 @@ class dfrn {
                        killme();
                }
 
+               $items = $r;
                $item = $r[0];
 
                $r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`, `user`.`account-type`
@@ -327,12 +336,31 @@ class dfrn {
 
                $doc = new DOMDocument('1.0', 'utf-8');
                $doc->formatOutput = true;
+               $type = 'html';
 
-               $alternatelink = $owner['url'];
+               if ($conversation) {
+                       $root = $doc->createElementNS(NAMESPACE_ATOM1, 'feed');
+                       $doc->appendChild($root);
 
-               $type = 'html';
+                       $root->setAttribute("xmlns:thr", NAMESPACE_THREAD);
+                       $root->setAttribute("xmlns:at", NAMESPACE_TOMB);
+                       $root->setAttribute("xmlns:media", NAMESPACE_MEDIA);
+                       $root->setAttribute("xmlns:dfrn", NAMESPACE_DFRN);
+                       $root->setAttribute("xmlns:activity", NAMESPACE_ACTIVITY);
+                       $root->setAttribute("xmlns:georss", NAMESPACE_GEORSS);
+                       $root->setAttribute("xmlns:poco", NAMESPACE_POCO);
+                       $root->setAttribute("xmlns:ostatus", NAMESPACE_OSTATUS);
+                       $root->setAttribute("xmlns:statusnet", NAMESPACE_STATUSNET);
+
+                       //$root = self::add_header($doc, $owner, "dfrn:owner", "", false);
 
-               $root = self::entry($doc, $type, $item, $owner, true, 0, true);
+                       foreach ($items as $item) {
+                               $entry = self::entry($doc, $type, $item, $owner, true, 0);
+                               $root->appendChild($entry);
+                       }
+               } else {
+                       $root = self::entry($doc, $type, $item, $owner, true, 0, true);
+               }
 
                $atom = trim($doc->saveXML());
                return $atom;
index bb05027a96fef4109922f446765dfafc537231b3..88e559a7f30b37038333c5dca5b598ca4e972b39 100644 (file)
@@ -12,12 +12,11 @@ require_once 'include/map.php';
 require_once 'include/datetime.php';
 
 function format_event_html($ev, $simple = false) {
-
        if (! ((is_array($ev)) && count($ev))) {
                return '';
        }
 
-       $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM
+       $bd_format = t('l F d, Y \@ g:i A') ; // Friday January 18, 2011 @ 8 AM.
 
        $event_start = (($ev['adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(),
                        $ev['start'] , $bd_format ))
@@ -32,7 +31,7 @@ function format_event_html($ev, $simple = false) {
        if ($simple) {
                $o = "<h3>" . bbcode($ev['summary']) . "</h3>";
 
-               $o .= "<p>" . bbcode($ev['desc']) . "</p>";
+               $o .= "<div>" . bbcode($ev['desc']) . "</div>";
 
                $o .= "<h4>" . t('Starts:') . "</h4><p>" . $event_start . "</p>";
 
@@ -49,29 +48,28 @@ function format_event_html($ev, $simple = false) {
 
        $o = '<div class="vevent">' . "\r\n";
 
+       $o .= '<div class="summary event-summary">' . bbcode($ev['summary']) . '</div>' . "\r\n";
 
-       $o .= '<p class="summary event-summary">' . bbcode($ev['summary']) . '</p>' . "\r\n";
-
-       $o .= '<p class="description event-description">' . bbcode($ev['desc']) . '</p>' . "\r\n";
-
-       $o .= '<p class="event-start">' . t('Starts:') . ' <abbr class="dtstart" title="'
+       $o .= '<div class="event-start"><span class="event-label">' . t('Starts:') . '</span>&nbsp;<span class="dtstart" title="'
                . datetime_convert('UTC', 'UTC', $ev['start'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
                . '" >'.$event_start
-               . '</abbr></p>' . "\r\n";
+               . '</span></div>' . "\r\n";
 
        if (! $ev['nofinish']) {
-               $o .= '<p class="event-end" >' . t('Finishes:') . ' <abbr class="dtend" title="'
+               $o .= '<div class="event-end" ><span class="event-label">' . t('Finishes:') . '</span>&nbsp;<span class="dtend" title="'
                        . datetime_convert('UTC', 'UTC', $ev['finish'], (($ev['adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s' ))
                        . '" >'.$event_end
-                       . '</abbr></p>' . "\r\n";
+                       . '</span></div>' . "\r\n";
        }
 
+       $o .= '<div class="description event-description">' . bbcode($ev['desc']) . '</div>' . "\r\n";
+
        if (strlen($ev['location'])) {
-               $o .= '<p class="event-location"> ' . t('Location:') . ' <span class="location">'
+               $o .= '<div class="event-location"><span class="event-label">' . t('Location:') . '</span>&nbsp;<span class="location">'
                        . bbcode($ev['location'])
-                       . '</span></p>' . "\r\n";
+                       . '</span></div>' . "\r\n";
 
-               // Include a map of the location if the [map] BBCode is used
+               // Include a map of the location if the [map] BBCode is used.
                if (strpos($ev['location'], "[map") !== false) {
                        $map = generate_named_map($ev['location']);
                        if ($map !== $ev['location']) {
@@ -84,6 +82,12 @@ function format_event_html($ev, $simple = false) {
        return $o;
 }
 
+/**
+ * @brief Convert an array with event data to bbcode.
+ * 
+ * @param array $ev Array which conains the event data.
+ * @return string The event as a bbcode formatted string.
+ */
 function format_event_bbcode($ev) {
 
        $o = '';
@@ -115,6 +119,13 @@ function format_event_bbcode($ev) {
        return $o;
 }
 
+/**
+ * @brief Extract bbcode formatted event data from a string
+ *     and convert it to html.
+ * 
+ * @params: string $s The string which should be parsed for event data.
+ * @return string The html output.
+ */
 function bbtovcal($s) {
        $o = '';
        $ev = bbtoevent($s);
@@ -126,6 +137,12 @@ function bbtovcal($s) {
        return $o;
 }
 
+/**
+ * @brief Extract bbcode formatted event data from a string.
+ * 
+ * @params: string $s The string which should be parsed for event data.
+ * @return array The array with the event information.
+ */
 function bbtoevent($s) {
 
        $ev = array();
@@ -165,7 +182,6 @@ function bbtoevent($s) {
        return $ev;
 }
 
-
 function sort_by_date($a) {
 
        usort($a,'ev_compare');
@@ -184,6 +200,15 @@ function ev_compare($a,$b) {
        return strcmp($date_a, $date_b);
 }
 
+/**
+ * @brief Delete an event from the event table.
+ * 
+ * Note: This function does only delete the event from the event table not its
+ * related entry in the item table.
+ * 
+ * @param int $event_id Event ID.
+ * @return void
+ */
 function event_delete($event_id) {
        if ($event_id == 0) {
                return;
@@ -193,6 +218,14 @@ function event_delete($event_id) {
        logger("Deleted event ".$event_id, LOGGER_DEBUG);
 }
 
+/**
+ * @brief Store the event.
+ * 
+ * Store the event in the event table and create an event item in the item table.
+ * 
+ * @param array $arr Array with event data.
+ * @return int The event id.
+ */
 function event_store($arr) {
 
        require_once 'include/datetime.php';
@@ -225,7 +258,7 @@ function event_store($arr) {
        }
 
 
-       // Existing event being modified
+       // Existing event being modified.
 
        if ($arr['id']) {
 
@@ -298,7 +331,6 @@ function event_store($arr) {
 
                return $item_id;
        } else {
-
                // New event. Store it.
 
                $r = q("INSERT INTO `event` (`uid`,`cid`,`guid`,`uri`,`created`,`edited`,`start`,`finish`,`summary`, `desc`,`location`,`type`,
@@ -322,7 +354,6 @@ function event_store($arr) {
                        dbesc($arr['allow_gid']),
                        dbesc($arr['deny_cid']),
                        dbesc($arr['deny_gid'])
-
                );
 
                $r = q("SELECT * FROM `event` WHERE `uri` = '%s' AND `uid` = %d LIMIT 1",
@@ -396,9 +427,14 @@ function event_store($arr) {
        }
 }
 
+/**
+ * @brief Create an array with translation strings used for events.
+ * 
+ * @return array Array with translations strings.
+ */
 function get_event_strings() {
 
-       // First day of the week (0 = Sunday)
+       // First day of the week (0 = Sunday).
        $firstDay = get_pconfig(local_user(), 'system', 'first_day_of_week');
        if ($firstDay === false) {
                $firstDay = 0;
@@ -466,17 +502,17 @@ function get_event_strings() {
 }
 
 /**
- * @brief Removes duplicated birthday events
+ * @brief Removes duplicated birthday events.
  *
- * @param array $dates Array of possibly duplicated events
- * @return array Cleaned events
+ * @param array $dates Array of possibly duplicated events.
+ * @return array Cleaned events.
  *
- * @todo We should replace this with a separate update function if there is some time left
+ * @todo We should replace this with a separate update function if there is some time left.
  */
 function event_remove_duplicates($dates) {
        $dates2 = array();
 
-       foreach ($dates AS $date) {
+       foreach ($dates as $date) {
                if ($date['type'] == 'birthday') {
                        $dates2[$date['uid'] . "-" . $date['cid'] . "-" . $date['start']] = $date;
                } else {
@@ -487,7 +523,7 @@ function event_remove_duplicates($dates) {
 }
 
 /**
- * @brief Get an event by its event ID
+ * @brief Get an event by its event ID.
  *
  * @param type $owner_uid The User ID of the owner of the event
  * @param type $event_params An assoziative array with
@@ -496,7 +532,7 @@ function event_remove_duplicates($dates) {
  * @return array Query result
  */
 function event_by_id($owner_uid = 0, $event_params, $sql_extra = '') {
-       // ownly allow events if there is a valid owner_id
+       // Ownly allow events if there is a valid owner_id.
        if ($owner_uid == 0) {
                return;
        }
@@ -516,26 +552,27 @@ function event_by_id($owner_uid = 0, $event_params, $sql_extra = '') {
 }
 
 /**
- * @brief Get all events in a specific timeframe
+ * @brief Get all events in a specific timeframe.
  *
- * @param int $owner_uid The User ID of the owner of the events
+ * @param int $owner_uid The User ID of the owner of the events.
  * @param array $event_params An assoziative array with
- *     int 'ignored' =>
- *     string 'start' => Start time of the timeframe
- *     string 'finish' => Finish time of the timeframe
- *     string 'adjust_start' =>
+ *     int 'ignored' =><br>
+ *     string 'start' => Start time of the timeframe.<br>
+ *     string 'finish' => Finish time of the timeframe.<br>
+ *     string 'adjust_start' =><br>
  *     string 'adjust_start' =>
  *
- * @param string $sql_extra Additional sql conditions (e.g. permission request)
- * @return array Query results
+ * @param string $sql_extra Additional sql conditions (e.g. permission request).
+ * 
+ * @return array Query results.
  */
 function events_by_date($owner_uid = 0, $event_params, $sql_extra = '') {
-       // Only allow events if there is a valid owner_id
+       // Only allow events if there is a valid owner_id.
        if ($owner_uid == 0) {
                return;
        }
 
-       // Query for the event by date
+       // Query for the event by date.
        $r = q("SELECT `event`.*, `item`.`id` AS `itemid`,`item`.`plink`,
                                `item`.`author-name`, `item`.`author-avatar`, `item`.`author-link` FROM `event`
                        LEFT JOIN `item` ON `item`.`event-id` = `event`.`id` AND `item`.`uid` = `event`.`uid`
@@ -559,10 +596,10 @@ function events_by_date($owner_uid = 0, $event_params, $sql_extra = '') {
 }
 
 /**
- * @brief Convert an array query results in an arry which could be used by the events template
+ * @brief Convert an array query results in an arry which could be used by the events template.
  *
- * @param array $arr Event query array
- * @return array Event array for the template
+ * @param array $arr Event query array.
+ * @return array Event array for the template.
  */
 function process_events($arr) {
        $events=array();
@@ -571,7 +608,6 @@ function process_events($arr) {
        $fmt = t('l, F j');
        if (count($arr)) {
                foreach ($arr as $rr) {
-
                        $j = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['start'], 'j') : datetime_convert('UTC', 'UTC', $rr['start'], 'j'));
                        $d = (($rr['adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $rr['start'], $fmt) : datetime_convert('UTC', 'UTC', $rr['start'], $fmt));
                        $d = day_translate($d);
@@ -588,7 +624,7 @@ function process_events($arr) {
                        $last_date = $d;
 
                        // Show edit and drop actions only if the user is the owner of the event and the event
-                       // is a real event (no bithdays)
+                       // is a real event (no bithdays).
                        if (local_user() && local_user() == $rr['uid'] && $rr['type'] == 'event') {
                                $edit = ((! $rr['cid']) ? array(System::baseUrl() . '/events/event/' . $rr['id'], t('Edit event'), '', '') : null);
                                $copy = ((! $rr['cid']) ? array(System::baseUrl() . '/events/copy/' . $rr['id'], t('Duplicate event'), '', '') : null);
@@ -628,13 +664,13 @@ function process_events($arr) {
 }
 
 /**
- * @brief Format event to export format (ical/csv)
+ * @brief Format event to export format (ical/csv).
  *
- * @param array $events Query result for events
- * @param string $format The output format (ical/csv)
- * @param string $timezone The timezone of the user (not implemented yet)
+ * @param array $events Query result for events.
+ * @param string $format The output format (ical/csv).
+ * @param string $timezone The timezone of the user (not implemented yet).
  *
- * @return string Content according to selected export format
+ * @return string Content according to selected export format.
  */
 function event_format_export ($events, $format = 'ical', $timezone) {
        if (! ((is_array($events)) && count($events))) {
@@ -642,7 +678,7 @@ function event_format_export ($events, $format = 'ical', $timezone) {
        }
 
        switch ($format) {
-               // Format the exported data as a CSV file
+               // Format the exported data as a CSV file.
                case "csv":
                        header("Content-type: text/csv");
                        $o = '"Subject", "Start Date", "Start Time", "Description", "End Date", "End Time", "Location"' . PHP_EOL;
@@ -663,7 +699,7 @@ function event_format_export ($events, $format = 'ical', $timezone) {
                        }
                        break;
 
-               // Format the exported data as a ics file
+               // Format the exported data as a ics file.
                case "ical":
                        header("Content-type: text/ics");
                        $o = 'BEGIN:VCALENDAR' . PHP_EOL
@@ -678,7 +714,6 @@ function event_format_export ($events, $format = 'ical', $timezone) {
                        //       but test your solution against http://icalvalid.cloudapp.net/
                        //       also long lines SHOULD be split at 75 characters length
                        foreach ($events as $event) {
-
                                if ($event['adjust'] == 1) {
                                        $UTC = 'Z';
                                } else {
@@ -731,32 +766,32 @@ function event_format_export ($events, $format = 'ical', $timezone) {
 }
 
 /**
- * @brief Get all events for a user ID
- *
- *    The query for events is done permission sensitive
+ * @brief Get all events for a user ID.
+ * 
+ *    The query for events is done permission sensitive.
  *    If the user is the owner of the calendar he/she
  *    will get all of his/her available events.
  *    If the user is only a visitor only the public events will
- *    be available
+ *    be available.
  *
- * @param int $uid The user ID
- * @param int $sql_extra Additional sql conditions for permission
+ * @param int $uid The user ID.
+ * @param int $sql_extra Additional sql conditions for permission.
  *
- * @return array Query results
+ * @return array Query results.
  */
 function events_by_uid($uid = 0, $sql_extra = '') {
        if ($uid == 0) {
                return;
        }
 
-       // The permission condition if no condition was transmitted
+       // The permission condition if no condition was transmitted.
        if ($sql_extra == '') {
                $sql_extra = " AND `allow_cid` = '' AND `allow_gid` = '' ";
        }
 
        // Does the user who requests happen to be the owner of the events
        // requested? then show all of your events, otherwise only those that
-       // don't have limitations set in allow_cid and allow_gid
+       // don't have limitations set in allow_cid and allow_gid.
        if (local_user() == $uid) {
                $r = q("SELECT `start`, `finish`, `adjust`, `summary`, `desc`, `location`, `nofinish`
                        FROM `event` WHERE `uid`= %d AND `cid` = 0 ",
@@ -776,42 +811,42 @@ function events_by_uid($uid = 0, $sql_extra = '') {
 
 /**
  *
- * @param int $uid The user ID
- * @param string $format Output format (ical/csv)
- * @return array With the results
- *     bool 'success' => True if the processing was successful
- *     string 'format' => The output format
- *     string 'extension' => The file extension of the output format
- *     string 'content' => The formatted output content
+ * @param int $uid The user ID.
+ * @param string $format Output format (ical/csv).
+ * @return array With the results:
+ *     bool 'success' => True if the processing was successful,<br>
+ *     string 'format' => The output format,<br>
+ *     string 'extension' => The file extension of the output format,<br>
+ *     string 'content' => The formatted output content.<br>
  *
- * @todo Respect authenticated users with events_by_uid()
+ * @todo Respect authenticated users with events_by_uid().
  */
 function event_export($uid, $format = 'ical') {
 
        $process = false;
 
-       // We are allowed to show events
-       // get the timezone the user is in
+       // We are allowed to show events.
+       // Get the timezone the user is in.
        $r = q("SELECT `timezone` FROM `user` WHERE `uid` = %d LIMIT 1", intval($uid));
        if (dbm::is_result($r)) {
                $timezone = $r[0]['timezone'];
        }
 
-       // Get all events which are owned by a uid (respects permissions);
+       // Get all events which are owned by a uid (respects permissions).
        $events = events_by_uid($uid);
 
-       // We have the events that are available for the requestor
-       // now format the output according to the requested format
+       // We have the events that are available for the requestor.
+       // Now format the output according to the requested format.
        if (count($events)) {
                $res = event_format_export($events, $format, $timezone);
        }
 
-       // If there are results the precess was successfull
+       // If there are results the precess was successfull.
        if (x($res)) {
                $process = true;
        }
 
-       // Get the file extension for the format
+       // Get the file extension for the format.
        switch ($format) {
                case "ical":
                        $file_ext = "ics";
@@ -836,33 +871,33 @@ function event_export($uid, $format = 'ical') {
 }
 
 /**
- * @brief Get the events widget
+ * @brief Get the events widget.
  *
- * @return string Formated html of the evens widget
+ * @return string Formated html of the evens widget.
  */
 function widget_events() {
        $a = get_app();
 
        $owner_uid = $a->data['user']['uid'];
        // $a->data is only available if the profile page is visited. If the visited page is not part
-       // of the profile page it should be the personal /events page. So we can use $a->user
+       // of the profile page it should be the personal /events page. So we can use $a->user.
        $user = ($a->data['user']['nickname'] ? $a->data['user']['nickname'] : $a->user['nickname']);
 
 
-       // The permission testing is a little bit tricky because we have to respect many cases
+       // The permission testing is a little bit tricky because we have to respect many cases.
 
-       // It's not the private events page (we don't get the $owner_uid for /events)
+       // It's not the private events page (we don't get the $owner_uid for /events).
        if (! local_user() && ! $owner_uid) {
                return;
        }
 
        /*
-        * Cal logged in user (test permission at foreign profile page)
-        * If the $owner uid is available we know it is part of one of the profile pages (like /cal)
+        * Cal logged in user (test permission at foreign profile page).
+        * If the $owner uid is available we know it is part of one of the profile pages (like /cal).
         * So we have to test if if it's the own profile page of the logged in user
         * or a foreign one. For foreign profile pages we need to check if the feature
         * for exporting the cal is enabled (otherwise the widget would appear for logged in users
-        * on foreigen profile pages even if the widget is disabled)
+        * on foreigen profile pages even if the widget is disabled).
         */
        if (intval($owner_uid) && local_user() !== $owner_uid && ! feature_enabled($owner_uid, "export_calendar")) {
                return;
@@ -870,7 +905,7 @@ function widget_events() {
 
        /*
         * If it's a kind of profile page (intval($owner_uid)) return if the user not logged in and
-        * export feature isn't enabled
+        * export feature isn't enabled.
         */
        if (intval($owner_uid) && ! local_user() && ! feature_enabled($owner_uid, "export_calendar")) {
                return;
@@ -883,3 +918,125 @@ function widget_events() {
                '$user' => $user
        ));
 }
+
+/**
+ * @brief Format an item array with event data to HTML.
+ * 
+ * @param arr $item Array with item and event data.
+ * @return string HTML output.
+ */
+function format_event_item($item) {
+       $same_date = false;
+       $finish    = false;
+
+       // Set the different time formats.
+       $dformat       = t('l F d, Y \@ g:i A'); // Friday January 18, 2011 @ 8:01 AM.
+       $dformat_short = t('D g:i A'); // Fri 8:01 AM.
+       $tformat       = t('g:i A'); // 8:01 AM.
+
+       // Convert the time to different formats.
+       $dtstart_dt = (($item['event-adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $item['event-start'], $dformat)) : day_translate(datetime_convert('UTC', 'UTC', $item['event-start'], $dformat)));
+       $dtstart_title = datetime_convert('UTC', 'UTC', $item['event-start'], (($item['event-adjust']) ? ATOM_TIME : 'Y-m-d\TH:i:s'));
+       // Format: Jan till Dec.
+       $month_short = (($item['event-adjust']) ? day_short_translate(datetime_convert('UTC', date_default_timezone_get(), $item['event-start'], 'M')) : day_short_translate(datetime_convert('UTC', 'UTC', $item['event-start'], 'M')));
+       // Format: 1 till 31.
+       $date_short = (($item['event-adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $item['event-start'], 'j') : datetime_convert('UTC', 'UTC', $item['event-start'], 'j'));
+       $start_time = (($item['event-adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $item['event-start'], $tformat) : datetime_convert('UTC', 'UTC', $item['event-start'], $tformat));
+       $start_short = (($item['event-adjust']) ? day_short_translate(datetime_convert('UTC', date_default_timezone_get(), $item['event-start'], $dformat_short)) : day_short_translate(datetime_convert('UTC', 'UTC', $item['event-start'], $dformat_short)));
+
+       // If the option 'nofinisch' isn't set, we need to format the finish date/time.
+       if (!$item['event-nofinish']) {
+               $finish = true;
+               $dtend_dt  = (($item['event-adjust']) ? day_translate(datetime_convert('UTC', date_default_timezone_get(), $item['event-finish'], $dformat)) : day_translate(datetime_convert('UTC', 'UTC', $item['event-finish'], $dformat)));
+               $dtend_title = datetime_convert('UTC', 'UTC', $item['event-finish'], (($item['event-adjust'])   ? ATOM_TIME : 'Y-m-d\TH:i:s'));
+               $end_short = (($item['event-adjust']) ? day_short_translate(datetime_convert('UTC', date_default_timezone_get(), $item['event-finish'], $dformat_short)) : day_short_translate(datetime_convert('UTC', 'UTC', $item['event-finish'], $dformat_short)));
+               $end_time = (($item['event-adjust']) ? datetime_convert('UTC', date_default_timezone_get(), $item['event-finish'], $tformat) : datetime_convert('UTC', 'UTC', $item['event-finish'], $tformat));
+               // Check if start and finish time is at the same day.
+               if (substr($dtstart_title, 0, 10) === substr($dtend_title, 0, 10)) {
+                       $same_date = true;
+               }
+       }
+
+       // Format the event location.
+       $evloc = event_location2array($item['event-location']);
+       $location = array(
+               'name' => prepare_text($evloc['name'])
+       );
+       // Construct the map HTML.
+       if (isset($evloc['address'])) {
+               $location['map'] = '<div class="map">' . generate_named_map($evloc['address']) . '</div>';
+       } elseif (isset($evloc['coordinates'])) {
+               $location['map'] = '<div class="map">' . generate_map(str_replace('/', ' ', $evloc['coordinates'])) . '</div>';
+       }
+
+       $event = replace_macros(get_markup_template('event_stream_item.tpl'), array(
+               '$id'             => $item['event-id'],
+               '$title'          => prepare_text($item['event-summary']),
+               '$dtstart_label'  => t('Starts:'),
+               '$dtstart_title'  => $dtstart_title,
+               '$dtstart_dt'     => $dtstart_dt,
+               '$finish'         => $finish,
+               '$dtend_label'    => t('Finishes:'),
+               '$dtend_title'    => $dtend_title,
+               '$dtend_dt'       => $dtend_dt,
+               '$month_short'    => $month_short,
+               '$date_short'     => $date_short,
+               '$same_date'      => $same_date,
+               '$start_time'     => $start_time,
+               '$start_short'    => $start_short,
+               '$end_time'       => $end_time,
+               '$end_short'      => $end_short,
+               '$author_name'    => $item['author-name'],
+               '$author_link'    => $item['author-link'],
+               '$author_avatar'  => $item['author-avatar'],
+               '$description'    => prepare_text($item['event-desc']),
+               '$location_label' => t('Location:'),
+               '$show_map_label' => t('Show map'),
+               '$hide_map_label' => t('Hide map'),
+               '$map_btn_label'  => t('Show map'),
+               '$location'       => $location
+       ));
+
+       return $event;
+}
+
+/**
+ * @brief Format a string with map bbcode to an array with location data.
+ * 
+ * Note: The string must only contain location data. A string with no bbcode will be
+ * handled as location name.
+ * 
+ * @param string $s The string with the bbcode formatted location data.
+ * 
+ * @return array The array with the location data.
+ *  'name' => The name of the location,<br>
+ * 'address' => The address of the location,<br>
+ * 'coordinates' => Latitude‎ and longitude‎ (e.g. '48.864716,2.349014').<br>
+ */
+function event_location2array($s = '') {
+       if ($s == '') {
+               return;
+       }
+
+       $location = array('name' => $s);
+
+       // Map tag with location name - e.g. [map]Paris[/map].
+       if (strpos($s, '[/map]') !== false) {
+               $found = preg_match("/\[map\](.*?)\[\/map\]/ism", $s, $match);
+               if (intval($found) > 0 && array_key_exists(1, $match)) {
+                       $location['address'] =  $match[1];
+                       // Remove the map bbcode from the location name.
+                       $location['name'] = str_replace($match[0], "", $s);
+               }
+       // Map tag with coordinates - e.g. [map=48.864716,2.349014].
+       } elseif (strpos($s, '[map=') !== false) {
+               $found = preg_match("/\[map=(.*?)\]/ism", $s, $match);
+               if (intval($found) > 0 && array_key_exists(1, $match)) {
+                       $location['coordinates'] =  $match[1];
+                       // Remove the map bbcode from the location name.
+                       $location['name'] = str_replace($match[0], "", $s);
+               }
+       }
+
+       return $location;
+}
index 5676566c422d5538bcde68cc4279f5aff4e9ca39..fb97c14ba126aa1875d1202df05a5caa8aad64e7 100644 (file)
@@ -27,6 +27,14 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
                return;
        }
 
+       if (!empty($contact['poll'])) {
+               $basepath = $contact['poll'];
+       } elseif (!empty($contact['url'])) {
+               $basepath = $contact['url'];
+       } else {
+               $basepath = '';
+       }
+
        $doc = new DOMDocument();
        @$doc->loadXML(trim($xml));
        $xpath = new DomXPath($doc);
@@ -311,6 +319,30 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
                        $item["attach"] .= '[attach]href="'.$href.'" length="'.$length.'" type="'.$type.'"[/attach]';
                }
 
+               $body = trim($xpath->evaluate('atom:content/text()', $entry)->item(0)->nodeValue);
+
+               if ($body == "") {
+                       $body = trim($xpath->evaluate('content:encoded/text()', $entry)->item(0)->nodeValue);
+               }
+               if ($body == "") {
+                       $body = trim($xpath->evaluate('description/text()', $entry)->item(0)->nodeValue);
+               }
+               if ($body == "") {
+                       $body = trim($xpath->evaluate('atom:summary/text()', $entry)->item(0)->nodeValue);
+               }
+
+               // remove the content of the title if it is identically to the body
+               // This helps with auto generated titles e.g. from tumblr
+               if (title_is_body($item["title"], $body)) {
+                       $item["title"] = "";
+               }
+               $item["body"] = html2bbcode($body, $basepath);
+
+               if (($item["body"] == '') && ($item["title"] != '')) {
+                       $item["body"] = $item["title"];
+                       $item["title"] = '';
+               }
+
                if ($contact["fetch_further_information"]) {
                        $preview = "";
 
@@ -321,36 +353,33 @@ function feed_import($xml,$importer,&$contact, &$hub, $simulate = false) {
                                }
                        }
 
-                       $item["body"] = $item["title"].add_page_info($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
-                       $item["tag"] = add_page_keywords($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
-                       $item["title"] = "";
-                       $item["object-type"] = ACTIVITY_OBJ_BOOKMARK;
-                       unset($item["attach"]);
-               } else {
-                       $body = trim($xpath->evaluate('atom:content/text()', $entry)->item(0)->nodeValue);
+                       // Remove a possible link to the item itself
+                       $item["body"] = str_replace($item["plink"], '', $item["body"]);
+                       $item["body"] = preg_replace('/\[url\=\](\w+.*?)\[\/url\]/i', '', $item["body"]);
 
-                       if ($body == "") {
-                               $body = trim($xpath->evaluate('content:encoded/text()', $entry)->item(0)->nodeValue);
-                       }
-                       if ($body == "") {
-                               $body = trim($xpath->evaluate('description/text()', $entry)->item(0)->nodeValue);
-                       }
-                       if ($body == "") {
-                               $body = trim($xpath->evaluate('atom:summary/text()', $entry)->item(0)->nodeValue);
+                       // Replace the content when the title is longer than the body
+                       $replace = (strlen($item["title"]) > strlen($item["body"]));
+
+                       // Replace it, when there is an image in the body
+                       if (strstr($item["body"], '[/img]')) {
+                               $replace = true;
                        }
 
-                       // remove the content of the title if it is identically to the body
-                       // This helps with auto generated titles e.g. from tumblr
-                       if (title_is_body($item["title"], $body)) {
-                               $item["title"] = "";
+                       // Replace it, when there is a link in the body
+                       if (strstr($item["body"], '[/url]')) {
+                               $replace = true;
                        }
-                       $item["body"] = html2bbcode($body);
 
-                       if (($item["body"] == '') && ($item["title"] != '')) {
+                       if ($replace) {
                                $item["body"] = $item["title"];
-                               $item["title"] = '';
                        }
-
+                       // We always strip the title since it will be added in the page information
+                       $item["title"] = "";
+                       $item["body"] = $item["body"].add_page_info($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
+                       $item["tag"] = add_page_keywords($item["plink"], false, $preview, ($contact["fetch_further_information"] == 2), $contact["ffi_keyword_blacklist"]);
+                       $item["object-type"] = ACTIVITY_OBJ_BOOKMARK;
+                       unset($item["attach"]);
+               } else {
                        if (!strstr($item["body"], '[url') && ($item['plink'] != '')) {
                                $item["body"] .= "[hr][url]".$item['plink']."[/url]";
                        }
index cac713b12f93def8d69703b58305e54cf23ce721..c5214fe4612ae22bb24e16338e8726af035c5aa2 100644 (file)
@@ -2,6 +2,7 @@
 
 use Friendica\App;
 use Friendica\Core\System;
+use Friendica\Network\Probe;
 
 require_once 'include/probe.php';
 require_once 'include/socgraph.php';
@@ -71,7 +72,7 @@ function update_contact($id) {
 
 
 
-function new_contact($uid,$url,$interactive = false) {
+function new_contact($uid, $url, $interactive = false, $network = '') {
 
        $result = array('cid' => -1, 'success' => false,'message' => '');
 
@@ -102,9 +103,13 @@ function new_contact($uid,$url,$interactive = false) {
 
        if (x($arr['contact'],'name')) {
                $ret = $arr['contact'];
+       } else {
+               $ret = Probe::uri($url, $network, $uid, false);
        }
-       else {
-               $ret = probe_url($url);
+
+       if (($network != '') && ($ret['network'] != $network)) {
+               logger('Expected network '.$network.' does not match actual network '.$ret['network']);
+               return result;
        }
 
        if ($ret['network'] === NETWORK_DFRN) {
index 435f6b77c1198aee5db6d753010581fbc86a65a0..a95c08cd564470c1147a58aa360e07a10af8e596 100644 (file)
@@ -79,7 +79,7 @@ function node2bbcodesub(&$doc, $oldnode, $attributes, $startbb, $endbb)
        return($replace);
 }
 
-function html2bbcode($message)
+function html2bbcode($message, $basepath = '')
 {
 
        $message = str_replace("\r", "", $message);
@@ -90,10 +90,10 @@ function html2bbcode($message)
                function ($matches) use (&$codeblocks) {
                        $return = '[codeblock-' . count($codeblocks) . ']';
 
-            $prefix = '[code]';
-            if ($matches[1] != '') {
-                $prefix = '[code=' . $matches[1] . ']';
-            }
+                       $prefix = '[code]';
+                       if ($matches[1] != '') {
+                               $prefix = '[code=' . $matches[1] . ']';
+                       }
                        $codeblocks[] = $prefix . $matches[2] . '[/code]';
                        return $return;
                }
@@ -313,15 +313,69 @@ function html2bbcode($message)
        // Restore code blocks
        $message = preg_replace_callback('#\[codeblock-([0-9]+)\]#iU',
                function ($matches) use ($codeblocks) {
-            $return = '';
-            if (isset($codeblocks[intval($matches[1])])) {
-                $return = $codeblocks[$matches[1]];
-            }
+                       $return = '';
+                       if (isset($codeblocks[intval($matches[1])])) {
+                               $return = $codeblocks[$matches[1]];
+                       }
                        return $return;
                }
        , $message);
 
        $message = trim($message);
 
+       if ($basepath != '') {
+               $message = addHostname($message, $basepath);
+       }
+
        return $message;
 }
+
+/**
+ * @brief Sub function to complete incomplete URL
+ *
+ * @param array $matches Result of preg_replace_callback
+ * @param string $basepath Basepath that is used to complete the URL
+ *
+ * @return string The expanded URL
+ */
+function addHostnameSub($matches, $basepath) {
+       $base = parse_url($basepath);
+
+       $link = $matches[0];
+       $url = $matches[1];
+
+       $parts = array_merge($base, parse_url($url));
+       $url2 = unParseUrl($parts);
+
+       return str_replace($url, $url2, $link);
+}
+
+/**
+ * @brief Complete incomplete URLs in BBCode
+ *
+ * @param string $body Body with URLs
+ * @param string $basepath Basepath that is used to complete the URL
+ *
+ * @return string Body with expanded URLs
+ */
+function addHostname($body, $basepath) {
+       $URLSearchString = "^\[\]";
+
+       $matches = array("/\[url\=([$URLSearchString]*)\].*?\[\/url\]/ism",
+                       "/\[url\]([$URLSearchString]*)\[\/url\]/ism",
+                       "/\[img\=[0-9]*x[0-9]*\](.*?)\[\/img\]/ism",
+                       "/\[img\](.*?)\[\/img\]/ism",
+                       "/\[zmg\=[0-9]*x[0-9]*\](.*?)\[\/img\]/ism",
+                       "/\[zmg\](.*?)\[\/zmg\]/ism",
+                       "/\[video\](.*?)\[\/video\]/ism",
+                       "/\[audio\](.*?)\[\/audio\]/ism",
+                       );
+
+       foreach ($matches AS $match) {
+               $body = preg_replace_callback($match,
+                                               function ($match) use ($basepath) {
+                                                       return addHostnameSub($match, $basepath);
+                                               }, $body);
+       }
+       return $body;
+}
index f19497f11eddcdc3651fa666d9812c900c17ecab..a67971cf57b90d833f263b0ece1ae24df3040f19 100644 (file)
@@ -1703,7 +1703,7 @@ function new_follower($importer, $contact, $datarray, $item, $sharing = false) {
                        intval($importer['uid'])
                );
 
-               if (dbm::is_result($r) && !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
+               if (dbm::is_result($r) && !in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE, PAGE_COMMUNITY))) {
 
                        // create notification
                        $hash = random_string();
@@ -1739,7 +1739,7 @@ function new_follower($importer, $contact, $datarray, $item, $sharing = false) {
                                ));
 
                        }
-               } elseif (dbm::is_result($r) && in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE))) {
+               } elseif (dbm::is_result($r) && in_array($r[0]['page-flags'], array(PAGE_SOAPBOX, PAGE_FREELOVE, PAGE_COMMUNITY))) {
                        $r = q("UPDATE `contact` SET `pending` = 0 WHERE `uid` = %d AND `url` = '%s' AND `pending` LIMIT 1",
                                        intval($importer['uid']),
                                        dbesc($url)
index 11a0fffbe671a827c3e524e10ed0bc7b76def26c..2a996cd933e9c351d2db65dad066f43a41c5a34e 100644 (file)
@@ -65,7 +65,7 @@ function fetch_url($url,$binary = false, &$redirects = 0, $timeout = 0, $accept_
  *    string 'body' => fetched content
  */
 function z_fetch_url($url, $binary = false, &$redirects = 0, $opts = array()) {
-       $ret = array('return_code' => 0, 'success' => false, 'header' => '', 'body' => '');
+       $ret = array('return_code' => 0, 'success' => false, 'header' => '', 'info' => '', 'body' => '');
 
        $stamp1 = microtime(true);
 
@@ -164,6 +164,15 @@ function z_fetch_url($url, $binary = false, &$redirects = 0, $opts = array()) {
        // if it throws any errors.
 
        $s = @curl_exec($ch);
+       $curl_info = @curl_getinfo($ch);
+
+       // Special treatment for HTTP Code 416
+       // See https://developer.mozilla.org/en-US/docs/Web/HTTP/Status/416
+       if (($curl_info['http_code'] == 416) && ($range > 0)) {
+               @curl_setopt($ch, CURLOPT_RANGE, '');
+               $s = @curl_exec($ch);
+               $curl_info = @curl_getinfo($ch);
+       }
 
        if (curl_errno($ch) !== CURLE_OK) {
                logger('fetch_url error fetching ' . $url . ': ' . curl_error($ch), LOGGER_NORMAL);
@@ -172,9 +181,10 @@ function z_fetch_url($url, $binary = false, &$redirects = 0, $opts = array()) {
        $ret['errno'] = curl_errno($ch);
 
        $base = $s;
-       $curl_info = @curl_getinfo($ch);
+       $ret['info'] = $curl_info;
 
        $http_code = $curl_info['http_code'];
+
        logger('fetch_url ' . $url . ': ' . $http_code . " " . $s, LOGGER_DATA);
        $header = '';
 
@@ -993,3 +1003,34 @@ function matching_url($url1, $url2) {
 
        return normalise_link($match);
 }
+
+/**
+ * @brief Glue url parts together
+ *
+ * @param array $parsed URL parts
+ *
+ * @return string The glued URL
+ */
+function unParseUrl($parsed) {
+       $get = function ($key) use ($parsed) {
+               return isset($parsed[$key]) ? $parsed[$key] : null;
+       };
+
+       $pass      = $get('pass');
+       $user      = $get('user');
+       $userinfo  = $pass !== null ? "$user:$pass" : $user;
+       $port      = $get('port');
+       $scheme    = $get('scheme');
+       $query     = $get('query');
+       $fragment  = $get('fragment');
+       $authority =
+               ($userinfo !== null ? $userinfo."@" : '') .
+               $get('host') .
+               ($port ? ":$port" : '');
+
+       return  (strlen($scheme) ? $scheme.":" : '') .
+               (strlen($authority) ? "//".$authority : '') .
+               $get('path') .
+               (strlen($query) ? "?".$query : '') .
+               (strlen($fragment) ? "#".$fragment : '');
+}
index 0e2caa2156d8dc6f32db15dcb2a529630e966afa..78916173e040a99167c8064ef3262ba3a886c75c 100644 (file)
@@ -149,6 +149,9 @@ class ostatus {
                // Only update the contacts if it is an OStatus contact
                if ($r && ($r['id'] > 0) && !$onlyfetch && ($contact["network"] == NETWORK_OSTATUS)) {
 
+                       // This contact is vital, so we awake it from the dead
+                       unmark_for_death($contact);
+
                        // Update contact data
 
                        $current = $contact;
index dc34edcd22b2024685e425bbd27551dff3cf2b42..8f0ff6e73e584153fce9fa13a318181bb55495e8 100644 (file)
@@ -1191,12 +1191,11 @@ function get_mood_verbs() {
        return $arr;
 }
 
-if (! function_exists('day_translate')) {
 /**
- * Translate days and months names
- *
- * @param string $s
- * @return string
+ * @brief Translate days and months names.
+ * 
+ * @param string $s String with day or month name.
+ * @return string Translated string.
  */
 function day_translate($s) {
        $ret = str_replace(array('Monday','Tuesday','Wednesday','Thursday','Friday','Saturday','Sunday'),
@@ -1208,8 +1207,23 @@ function day_translate($s) {
                $ret);
 
        return $ret;
-}}
+}
 
+/**
+ * @brief Translate short days and months names.
+ * 
+ * @param string $s String with short day or month name.
+ * @return string Translated string.
+ */
+function day_short_translate($s) {
+       $ret = str_replace(array('Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'),
+               array(t('Mon'), t('Tue'), t('Wed'), t('Thu'), t('Fri'), t('Sat'), t('Sund')),
+               $s);
+       $ret = str_replace(array('Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov','Dec'),
+               array(t('Jan'), t('Feb'), t('Mar'), t('Apr'), t('May'), ('Jun'), t('Jul'), t('Aug'), t('Sep'), t('Oct'), t('Nov'), t('Dec')),
+               $ret);
+       return $ret;
+}
 
 if (! function_exists('normalise_link')) {
 /**
@@ -1288,13 +1302,9 @@ function put_item_in_cache(&$item, $update = false) {
        }
 }
 
-// Given an item array, convert the body element from bbcode to html and add smilie icons.
-// If attach is true, also add icons for item attachments
-
-if (! function_exists('prepare_body')) {
 /**
- * Given an item array, convert the body element from bbcode to html and add smilie icons.
- * If attach is true, also add icons for item attachments
+ * @brief Given an item array, convert the body element from bbcode to html and add smilie icons.
+ * If attach is true, also add icons for item attachments.
  *
  * @param array $item
  * @param boolean $attach
@@ -1314,6 +1324,13 @@ function prepare_body(&$item, $attach = false, $preview = false) {
        $hashtags = array();
        $mentions = array();
 
+       // In order to provide theme developers more possibilities, event items
+       // are treated differently.
+       if ($item['object-type'] === ACTIVITY_OBJ_EVENT && isset($item['event-id'])) {
+               $ev = format_event_item($item);
+               return $ev;
+       }
+
        if (!get_config('system','suppress_tags')) {
                $taglist = dba::p("SELECT `type`, `term`, `url` FROM `term` WHERE `otype` = ? AND `oid` = ? AND `type` IN (?, ?) ORDER BY `tid`",
                                intval(TERM_OBJ_POST), intval($item['id']), intval(TERM_HASHTAG), intval(TERM_MENTION));
@@ -1346,10 +1363,10 @@ function prepare_body(&$item, $attach = false, $preview = false) {
        $item['hashtags'] = $hashtags;
        $item['mentions'] = $mentions;
 
-       // Update the cached values if there is no "zrl=..." on the links
-       $update = (!local_user() and !remote_user() and ($item["uid"] == 0));
+       // Update the cached values if there is no "zrl=..." on the links.
+       $update = (!local_user() && !remote_user() && ($item["uid"] == 0));
 
-       // Or update it if the current viewer is the intented viewer
+       // Or update it if the current viewer is the intented viewer.
        if (($item["uid"] == local_user()) && ($item["uid"] != 0)) {
                $update = true;
        }
@@ -1362,7 +1379,7 @@ function prepare_body(&$item, $attach = false, $preview = false) {
        $s = $prep_arr['html'];
 
        if (! $attach) {
-               // Replace the blockquotes with quotes that are used in mails
+               // Replace the blockquotes with quotes that are used in mails.
                $mailquote = '<blockquote type="cite" class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex;">';
                $s = str_replace(array('<blockquote>', '<blockquote class="spoiler">', '<blockquote class="author">'), array($mailquote, $mailquote, $mailquote), $s);
                return $s;
@@ -1375,7 +1392,7 @@ function prepare_body(&$item, $attach = false, $preview = false) {
                foreach ($arr as $r) {
                        $matches = false;
                        $icon = '';
-                       $cnt = preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r,$matches, PREG_SET_ORDER);
+                       $cnt = preg_match_all('|\[attach\]href=\"(.*?)\" length=\"(.*?)\" type=\"(.*?)\" title=\"(.*?)\"|',$r ,$matches, PREG_SET_ORDER);
                        if ($cnt) {
                                foreach ($matches as $mtch) {
                                        $mime = $mtch[3];
@@ -1408,9 +1425,9 @@ function prepare_body(&$item, $attach = false, $preview = false) {
                                                ));
                                        }
 
-                                       $filetype = strtolower(substr($mime, 0, strpos($mime,'/')));
+                                       $filetype = strtolower(substr($mime, 0, strpos($mime, '/')));
                                        if ($filetype) {
-                                               $filesubtype = strtolower(substr($mime, strpos($mime,'/') + 1));
+                                               $filesubtype = strtolower(substr($mime, strpos($mime, '/') + 1));
                                                $filesubtype = str_replace('.', '-', $filesubtype);
                                        } else {
                                                $filetype = 'unkn';
@@ -1430,19 +1447,19 @@ function prepare_body(&$item, $attach = false, $preview = false) {
                $s .= '<div class="body-attach">'.$as.'<div class="clear"></div></div>';
        }
 
-       // map
+       // Map.
        if (strpos($s, '<div class="map">') !== false && x($item, 'coord')) {
                $x = generate_map(trim($item['coord']));
                if ($x) {
-                       $s = preg_replace('/\<div class\=\"map\"\>/','$0' . $x,$s);
+                       $s = preg_replace('/\<div class\=\"map\"\>/', '$0' . $x, $s);
                }
        }
 
 
-       // Look for spoiler
+       // Look for spoiler.
        $spoilersearch = '<blockquote class="spoiler">';
 
-       // Remove line breaks before the spoiler
+       // Remove line breaks before the spoiler.
        while ((strpos($s, "\n" . $spoilersearch) !== false)) {
                $s = str_replace("\n" . $spoilersearch, $spoilersearch, $s);
        }
@@ -1458,7 +1475,7 @@ function prepare_body(&$item, $attach = false, $preview = false) {
                $s = substr($s, 0, $pos) . $spoilerreplace . substr($s, $pos + strlen($spoilersearch));
        }
 
-       // Look for quote with author
+       // Look for quote with author.
        $authorsearch = '<blockquote class="author">';
 
        while ((strpos($s, $authorsearch) !== false)) {
@@ -1469,7 +1486,7 @@ function prepare_body(&$item, $attach = false, $preview = false) {
                $s = substr($s, 0, $pos) . $authorreplace . substr($s, $pos + strlen($authorsearch));
        }
 
-       // replace friendica image url size with theme preference
+       // Replace friendica image url size with theme preference.
        if (x($a->theme_info, 'item_image_size')){
                $ps = $a->theme_info['item_image_size'];
                $s = preg_replace('|(<img[^>]+src="[^"]+/photo/[0-9a-f]+)-[0-9]|', "$1-" . $ps, $s);
@@ -1479,15 +1496,13 @@ function prepare_body(&$item, $attach = false, $preview = false) {
        call_hooks('prepare_body_final', $prep_arr);
 
        return $prep_arr['html'];
-}}
-
+}
 
-if (! function_exists('prepare_text')) {
 /**
- * Given a text string, convert from bbcode to html and add smilie icons.
+ * @brief Given a text string, convert from bbcode to html and add smilie icons.
  *
- * @param string $text
- * @return string
+ * @param string $text String with bbcode.
+ * @return string Formattet HTML.
  */
 function prepare_text($text) {
 
@@ -1500,9 +1515,7 @@ function prepare_text($text) {
        }
 
        return trim($s);
-}}
-
-
+}
 
 /**
  * return array with details for categories and folders for an item
index 9d386d50fead5b40fb94efe67d45dc0cd485c925..c6384a97692a15555b1522a8f5aaa2e93083223c 100644 (file)
@@ -80,7 +80,7 @@ aStates[55]="|Bjelovarsko-Bilogorska Zupanija|Brodsko-Posavska Zupanija|Dubrovac
 aStates[56]="|Camaguey|Ciego de Avila|Cienfuegos|Ciudad de La Habana|Granma|Guantanamo|Holguin|Isla de la Juventud|La Habana|Las Tunas|Matanzas|Pinar del Rio|Sancti Spiritus|Santiago de Cuba|Villa Clara";\r
 aStates[57]="|Famagusta|Kyrenia|Larnaca|Limassol|Nicosia|Paphos";\r
 aStates[58]="|Brnensky|Budejovicky|Jihlavsky|Karlovarsky|Kralovehradecky|Liberecky|Olomoucky|Ostravsky|Pardubicky|Plzensky|Praha|Stredocesky|Ustecky|Zlinsky";\r
-aStates[59]="|Arhus|Bornholm|Fredericksberg|Frederiksborg|Fyn|Kobenhavn|Kobenhavns|Nordjylland|Ribe|Ringkobing|Roskilde|Sonderjylland|Storstrom|Vejle|Vestsjalland|Viborg";\r
+aStates[59]="|Aalborg|Aarhus|Bornholm|Esbjerg|Falster|Frederiksberg|Fyn|Hillerød|Horsens|Kolding|København|Als|Langeland|Lolland|Midtjylland|Nordjylland|Nordsjælland|Odense|Randers|Roskilde|Syddanmark|Morsø|Møn|Sydsjælland|Vejle|Vestsjælland|Viborg";\r
 aStates[60]="|'Ali Sabih|Dikhil|Djibouti|Obock|Tadjoura";\r
 aStates[61]="|Saint Andrew|Saint David|Saint George|Saint John|Saint Joseph|Saint Luke|Saint Mark|Saint Patrick|Saint Paul|Saint Peter";\r
 aStates[62]="|Azua|Baoruco|Barahona|Dajabon|Distrito Nacional|Duarte|El Seibo|Elias Pina|Espaillat|Hato Mayor|Independencia|La Altagracia|La Romana|La Vega|Maria Trinidad Sanchez|Monsenor Nouel|Monte Cristi|Monte Plata|Pedernales|Peravia|Puerto Plata|Salcedo|Samana|San Cristobal|San Juan|San Pedro de Macoris|Sanchez Ramirez|Santiago|Santiago Rodriguez|Valverde";\r
@@ -97,7 +97,7 @@ aStates[71]="|Falkland Islands (Islas Malvinas)"
 aStates[72]="|Bordoy|Eysturoy|Mykines|Sandoy|Skuvoy|Streymoy|Suduroy|Tvoroyri|Vagar";\r
 aStates[73]="|Central|Eastern|Northern|Rotuma|Western";\r
 aStates[74]="|Aland|Etela-Suomen Laani|Ita-Suomen Laani|Lansi-Suomen Laani|Lappi|Oulun Laani";\r
-aStates[75]="|Alsace|Aquitaine|Auvergne|Basse-Normandie|Bourgogne|Bretagne|Centre|Champagne-Ardenne|Corse|Franche-Comte|Haute-Normandie|Ile-de-France|Languedoc-Roussillon|Limousin|Lorraine|Midi-Pyrenees|Nord-Pas-de-Calais|Pays de la Loire|Picardie|Poitou-Charentes|Provence-Alpes-Cote d'Azur|Rhone-Alpes";\r
+aStates[75]="|Alsace|Aquitaine|Auvergne|Basse-Normandie|Bourgogne|Bretagne|Centre|Champagne-Ardenne|Corse|Franche-Comté|Haute-Normandie|Île-de-France|Languedoc-Roussillon|Limousin|Lorraine|Midi-Pyrénées|Nord-Pas-de-Calais|Pays de la Loire|Picardie|Poitou-Charentes|Provence-Alpes-Côte d’Azur|Rhône-Alpes";\r
 aStates[76]="|French Guiana";\r
 aStates[77]="|Archipel des Marquises|Archipel des Tuamotu|Archipel des Tubuai|Iles du Vent|Iles Sous-le-Vent";\r
 aStates[78]="|Adelie Land|Ile Crozet|Iles Kerguelen|Iles Saint-Paul et Amsterdam";\r
@@ -112,7 +112,7 @@ aStates[86]="|Ile du Lys|Ile Glorieuse";
 aStates[87]="|Aitolia kai Akarnania|Akhaia|Argolis|Arkadhia|Arta|Attiki|Ayion Oros (Mt. Athos)|Dhodhekanisos|Drama|Evritania|Evros|Evvoia|Florina|Fokis|Fthiotis|Grevena|Ilia|Imathia|Ioannina|Irakleion|Kardhitsa|Kastoria|Kavala|Kefallinia|Kerkyra|Khalkidhiki|Khania|Khios|Kikladhes|Kilkis|Korinthia|Kozani|Lakonia|Larisa|Lasithi|Lesvos|Levkas|Magnisia|Messinia|Pella|Pieria|Preveza|Rethimni|Rodhopi|Samos|Serrai|Thesprotia|Thessaloniki|Trikala|Voiotia|Xanthi|Zakinthos";\r
 aStates[88]="|Avannaa (Nordgronland)|Kitaa (Vestgronland)|Tunu (Ostgronland)"\r
 aStates[89]="|Carriacou and Petit Martinique|Saint Andrew|Saint David|Saint George|Saint John|Saint Mark|Saint Patrick";\r
-aStates[90]="|Basse-Terre|Grande-Terre|Iles de la Petite Terre|Iles des Saintes|Marie-Galante";\r
+aStates[90]="|Basse-Terre|Grande-Terre|Îles de la Petite Terre|Îles des Saintes|Marie-Galante";\r
 aStates[91]="|Guam";\r
 aStates[92]="|Alta Verapaz|Baja Verapaz|Chimaltenango|Chiquimula|El Progreso|Escuintla|Guatemala|Huehuetenango|Izabal|Jalapa|Jutiapa|Peten|Quetzaltenango|Quiche|Retalhuleu|Sacatepequez|San Marcos|Santa Rosa|Solola|Suchitepequez|Totonicapan|Zacapa";\r
 aStates[93]="|Castel|Forest|St. Andrew|St. Martin|St. Peter Port|St. Pierre du Bois|St. Sampson|St. Saviour|Torteval|Vale";\r
@@ -209,7 +209,7 @@ aStates[183]="|Dolnoslaskie|Kujawsko-Pomorskie|Lodzkie|Lubelskie|Lubuskie|Malopo
 aStates[184]="|Acores (Azores)|Aveiro|Beja|Braga|Braganca|Castelo Branco|Coimbra|Evora|Faro|Guarda|Leiria|Lisboa|Madeira|Portalegre|Porto|Santarem|Setubal|Viana do Castelo|Vila Real|Viseu";\r
 aStates[185]="|Adjuntas|Aguada|Aguadilla|Aguas Buenas|Aibonito|Anasco|Arecibo|Arroyo|Barceloneta|Barranquitas|Bayamon|Cabo Rojo|Caguas|Camuy|Canovanas|Carolina|Catano|Cayey|Ceiba|Ciales|Cidra|Coamo|Comerio|Corozal|Culebra|Dorado|Fajardo|Florida|Guanica|Guayama|Guayanilla|Guaynabo|Gurabo|Hatillo|Hormigueros|Humacao|Isabela|Jayuya|Juana Diaz|Juncos|Lajas|Lares|Las Marias|Las Piedras|Loiza|Luquillo|Manati|Maricao|Maunabo|Mayaguez|Moca|Morovis|Naguabo|Naranjito|Orocovis|Patillas|Penuelas|Ponce|Quebradillas|Rincon|Rio Grande|Sabana Grande|Salinas|San German|San Juan|San Lorenzo|San Sebastian|Santa Isabel|Toa Alta|Toa Baja|Trujillo Alto|Utuado|Vega Alta|Vega Baja|Vieques|Villalba|Yabucoa|Yauco";\r
 aStates[186]="|Ad Dawhah|Al Ghuwayriyah|Al Jumayliyah|Al Khawr|Al Wakrah|Ar Rayyan|Jarayan al Batinah|Madinat ash Shamal|Umm Salal";\r
-aStates[187]="|Reunion";\r
+aStates[187]="|Réunion";\r
 aStates[188]="|Alba|Arad|Arges|Bacau|Bihor|Bistrita-Nasaud|Botosani|Braila|Brasov|Bucuresti|Buzau|Calarasi|Caras-Severin|Cluj|Constanta|Covasna|Dimbovita|Dolj|Galati|Giurgiu|Gorj|Harghita|Hunedoara|Ialomita|Iasi|Maramures|Mehedinti|Mures|Neamt|Olt|Prahova|Salaj|Satu Mare|Sibiu|Suceava|Teleorman|Timis|Tulcea|Vaslui|Vilcea|Vrancea";\r
 aStates[189]="|Adygeya (Maykop)|Aginskiy Buryatskiy (Aginskoye)|Altay (Gorno-Altaysk)|Altayskiy (Barnaul)|Amurskaya (Blagoveshchensk)|Arkhangel'skaya|Astrakhanskaya|Bashkortostan (Ufa)|Belgorodskaya|Bryanskaya|Buryatiya (Ulan-Ude)|Chechnya (Groznyy)|Chelyabinskaya|Chitinskaya|Chukotskiy (Anadyr')|Chuvashiya (Cheboksary)|Dagestan (Makhachkala)|Evenkiyskiy (Tura)|Ingushetiya (Nazran')|Irkutskaya|Ivanovskaya|Kabardino-Balkariya (Nal'chik)|Kaliningradskaya|Kalmykiya (Elista)|Kaluzhskaya|Kamchatskaya (Petropavlovsk-Kamchatskiy)|Karachayevo-Cherkesiya (Cherkessk)|Kareliya (Petrozavodsk)|Kemerovskaya|Khabarovskiy|Khakasiya (Abakan)|Khanty-Mansiyskiy (Khanty-Mansiysk)|Kirovskaya|Komi (Syktyvkar)|Komi-Permyatskiy (Kudymkar)|Koryakskiy (Palana)|Kostromskaya|Krasnodarskiy|Krasnoyarskiy|Kurganskaya|Kurskaya|Leningradskaya|Lipetskaya|Magadanskaya|Mariy-El (Yoshkar-Ola)|Mordoviya (Saransk)|Moskovskaya|Moskva (Moscow)|Murmanskaya|Nenetskiy (Nar'yan-Mar)|Nizhegorodskaya|Novgorodskaya|Novosibirskaya|Omskaya|Orenburgskaya|Orlovskaya (Orel)|Penzenskaya|Permskaya|Primorskiy (Vladivostok)|Pskovskaya|Rostovskaya|Ryazanskaya|Sakha (Yakutsk)|Sakhalinskaya (Yuzhno-Sakhalinsk)|Samarskaya|Sankt-Peterburg (Saint Petersburg)|Saratovskaya|Severnaya Osetiya-Alaniya [North Ossetia] (Vladikavkaz)|Smolenskaya|Stavropol'skiy|Sverdlovskaya (Yekaterinburg)|Tambovskaya|Tatarstan (Kazan')|Taymyrskiy (Dudinka)|Tomskaya|Tul'skaya|Tverskaya|Tyumenskaya|Tyva (Kyzyl)|Udmurtiya (Izhevsk)|Ul'yanovskaya|Ust'-Ordynskiy Buryatskiy (Ust'-Ordynskiy)|Vladimirskaya|Volgogradskaya|Vologodskaya|Voronezhskaya|Yamalo-Nenetskiy (Salekhard)|Yaroslavskaya|Yevreyskaya";\r
 aStates[190]="|Butare|Byumba|Cyangugu|Gikongoro|Gisenyi|Gitarama|Kibungo|Kibuye|Kigali Rurale|Kigali-ville|Ruhengeri|Umutara";\r
index 7c7ee51d53060228a2f21d87d14185090fa5cdc4..4f0622532f45d3f02a073c0255efbecb409dd980 100644 (file)
@@ -1239,7 +1239,7 @@ function admin_page_site(App $a) {
                '$proxy_disabled'       => array('proxy_disabled', t("Disable picture proxy"), get_config('system','proxy_disabled'), t("The picture proxy increases performance and privacy. It shouldn't be used on systems with very low bandwith.")),
                '$only_tag_search'      => array('only_tag_search', t("Only search in tags"), get_config('system','only_tag_search'), t("On large systems the text search can slow down the system extremely.")),
 
-               '$relocate_url'         => array('relocate_url', t("New base url"), System::baseUrl(), t("Change base url for this server. Sends relocate message to all DFRN contacts of all users.")),
+               '$relocate_url'         => array('relocate_url', t("New base url"), System::baseUrl(), t("Change base url for this server. Sends relocate message to all Friendica and Diaspora* contacts of all users.")),
 
                '$rino'                 => array('rino', t("RINO Encryption"), intval(get_config('system','rino_encrypt')), t("Encryption layer between nodes."), array("Disabled", "RINO1 (deprecated)", "RINO2")),
 
index eae4141bc9fe1b2294430e3211efa3060ca9f114..a129a665d131d67f2e55ab020218e01d2d22e1ef 100644 (file)
@@ -244,7 +244,7 @@ function _contact_update($contact_id) {
                return;
 
        if ($r[0]["network"] == NETWORK_OSTATUS) {
-               $result = new_contact($uid, $r[0]["url"], false);
+               $result = new_contact($uid, $r[0]["url"], false, $r[0]["network"]);
 
                if ($result['success'])
                        $r = q("UPDATE `contact` SET `subhub` = 1 WHERE `id` = %d",
index 1ecff36182197a0e4b9392638c48e86912cbb924..bdb32e9de9a8c462c4c658a09b343d004340fe7d 100644 (file)
@@ -17,7 +17,14 @@ function display_init(App $a) {
        if ($a->argc == 3) {
                if (substr($a->argv[2], -5) == '.atom') {
                        $item_id = substr($a->argv[2], 0, -5);
-                       displayShowFeed($item_id);
+                       displayShowFeed($item_id, false);
+               }
+       }
+
+       if ($a->argc == 4) {
+               if ($a->argv[3] == 'conversation.atom') {
+                       $item_id = $a->argv[2];
+                       displayShowFeed($item_id, true);
                }
        }
 
@@ -66,7 +73,7 @@ function display_init(App $a) {
 
                        if (strstr($_SERVER['HTTP_ACCEPT'], 'application/atom+xml')) {
                                logger('Directly serving XML for id '.$r["id"], LOGGER_DEBUG);
-                               displayShowFeed($r["id"]);
+                               displayShowFeed($r["id"], false);
                        }
 
                        if ($r["id"] != $r["parent"]) {
@@ -219,17 +226,18 @@ function display_content(App $a, $update = 0) {
                        $nick = "";
 
                        if (local_user()) {
-                               $r = dba::fetch_first("SELECT `id` FROM `item`
+                               $r = dba::fetch_first("SELECT `id`, `parent` FROM `item`
                                        WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
                                                AND `guid` = ? AND `uid` = ?", $a->argv[1], local_user());
                                if (dbm::is_result($r)) {
                                        $item_id = $r["id"];
+                                       $item_parent = $r["parent"];
                                        $nick = $a->user["nickname"];
                                }
                        }
 
                        if ($nick == "") {
-                               $r = dba::fetch_first("SELECT `user`.`nickname`, `item`.`id` FROM `item` STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
+                               $r = dba::fetch_first("SELECT `user`.`nickname`, `item`.`id`, `item`.`parent` FROM `item` STRAIGHT_JOIN `user` ON `user`.`uid` = `item`.`uid`
                                        WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
                                                AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''
                                                AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''
@@ -237,11 +245,12 @@ function display_content(App $a, $update = 0) {
                                                AND `item`.`guid` = ?", $a->argv[1]);
                                if (dbm::is_result($r)) {
                                        $item_id = $r["id"];
+                                       $item_parent = $r["parent"];
                                        $nick = $r["nickname"];
                                }
                        }
                        if ($nick == "") {
-                               $r = dba::fetch_first("SELECT `item`.`id` FROM `item`
+                               $r = dba::fetch_first("SELECT `item`.`id`, `item`.`parent` FROM `item`
                                        WHERE `item`.`visible` AND NOT `item`.`deleted` AND NOT `item`.`moderated`
                                                AND `item`.`allow_cid` = ''  AND `item`.`allow_gid` = ''
                                                AND `item`.`deny_cid`  = '' AND `item`.`deny_gid`  = ''
@@ -249,15 +258,17 @@ function display_content(App $a, $update = 0) {
                                                AND `item`.`guid` = ?", $a->argv[1]);
                                if (dbm::is_result($r)) {
                                        $item_id = $r["id"];
+                                       $item_parent = $r["parent"];
                                }
                        }
                }
        }
 
        if ($item_id && !is_numeric($item_id)) {
-               $r = dba::select('item', array('id'), array('uri' => $item_id, 'uid' => $a->profile['uid']), array('limit' => 1));
+               $r = dba::select('item', array('id', 'parent'), array('uri' => $item_id, 'uid' => $a->profile['uid']), array('limit' => 1));
                if (dbm::is_result($r)) {
                        $item_id = $r["id"];
+                       $item_parent = $r["parent"];
                } else {
                        $item_id = false;
                }
@@ -273,12 +284,15 @@ function display_content(App $a, $update = 0) {
        $is_public = dba::exists('item', array('id' => $item_id, 'private' => false));
        if ($is_public) {
                $alternate = System::baseUrl().'/display/'.$nick.'/'.$item_id.'.atom';
+               $conversation = System::baseUrl().'/display/'.$nick.'/'.$item_parent.'/conversation.atom';
        } else {
                $alternate = '';
+               $conversation = '';
        }
 
        $a->page['htmlhead'] .= replace_macros(get_markup_template('display-head.tpl'),
-                               array('$alternate' => $alternate));
+                               array('$alternate' => $alternate,
+                                       '$conversation' => $conversation));
 
        $groups = array();
 
@@ -476,8 +490,8 @@ function display_content(App $a, $update = 0) {
        return $o;
 }
 
-function displayShowFeed($item_id) {
-       $xml = dfrn::itemFeed($item_id);
+function displayShowFeed($item_id, $conversation) {
+       $xml = dfrn::itemFeed($item_id, $conversation);
        if ($xml == '') {
                http_status_exit(500);
        }
index 835627586cada10d58b75113a1783e4a852f4386..d1810604ca514bd8ddbcf292e061701017dbf2e5 100644 (file)
@@ -73,7 +73,7 @@ function notes_content(App $a, $update = false) {
 
        // default permissions - anonymous user
 
-       $sql_extra = " AND `allow_cid` = '<" . $a->contact['id'] . ">' ";
+       $sql_extra = " AND `item`.`allow_cid` = '<" . $a->contact['id'] . ">' ";
 
        $r = q("SELECT COUNT(*) AS `total`
                FROM `item` %s
index 3250bdc2a2d7cea10df77dc403afd92a0f6ade67..f835f0ed20b38fc17fca23a18c375841c1a868ab 100644 (file)
@@ -66,7 +66,7 @@ function ostatus_subscribe_content(App $a) {
 
        $data = probe_url($url);
        if ($data["network"] == NETWORK_OSTATUS) {
-               $result = new_contact($uid,$url,true);
+               $result = new_contact($uid, $url, true, NETWORK_OSTATUS);
                if ($result["success"]) {
                        $o .= " - ".t("success");
                } else {
index 36870af6d2cc2b7437e80f50ee4ab0df498f2581..a2c6f6509cbfcdb32c8afa3e0e50c22067039035 100644 (file)
@@ -57,22 +57,39 @@ class System {
         * @return string
         */
        public static function callstack($depth = 4) {
-               $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, $depth + 2);
+               $trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
 
                // We remove the first two items from the list since they contain data that we don't need.
                array_shift($trace);
                array_shift($trace);
 
                $callstack = array();
-               foreach ($trace AS $func) {
+               $counter = 0;
+               $previous = array('class' => '', 'function' => '');
+
+               // The ignore list contains all functions that are only wrapper functions
+               $ignore = array('get_config', 'get_pconfig', 'set_config', 'set_pconfig', 'fetch_url', 'probe_url');
+
+               while ($func = array_pop($trace)) {
                        if (!empty($func['class'])) {
-                               $callstack[] = $func['class'].'::'.$func['function'];
-                       } else {
+                               // Don't show multiple calls from the same function (mostly used for "dba" class)
+                               if (($previous['class'] != $func['class']) && ($previous['function'] != 'q')) {
+                                       $classparts = explode("\\", $func['class']);
+                                       $callstack[] = array_pop($classparts).'::'.$func['function'];
+                                       $previous = $func;
+                               }
+                       } elseif (!in_array($func['function'], $ignore)) {
                                $callstack[] = $func['function'];
+                               $previous = $func;
                        }
                }
 
-               return implode(', ', $callstack);
+               $callstack2 = array();
+               while ((count($callstack2) < $depth) && (count($callstack) > 0)) {
+                       $callstack2[] = array_pop($callstack);
+               }
+
+               return implode(', ', $callstack2);
        }
 
        /// @todo Move the following functions from boot.php
index 1674d5691459efde1a0df655dffc91d85f61b5ea..81c5671c90c5cac48bdb8c54187604c996b561aa 100644 (file)
@@ -139,53 +139,24 @@ class ParseUrl {
                $siteinfo["url"] = $url;
                $siteinfo["type"] = "link";
 
-               $check_cert = Config::get("system", "verifyssl");
-
-               $stamp1 = microtime(true);
-
-               $ch = curl_init();
-               curl_setopt($ch, CURLOPT_URL, $url);
-               curl_setopt($ch, CURLOPT_HEADER, 1);
-               curl_setopt($ch, CURLOPT_TIMEOUT, 10);
-               curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-               curl_setopt($ch, CURLOPT_USERAGENT, $a->get_useragent());
-               curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, (($check_cert) ? true : false));
-               if ($check_cert) {
-                       @curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
-               }
-
-               $range = intval(Config::get('system', 'curl_range_bytes', 0));
-
-               if ($range > 0) {
-                       curl_setopt($ch, CURLOPT_RANGE, '0-' . $range);
-               }
-
-               $header = curl_exec($ch);
-               $curl_info = @curl_getinfo($ch);
-               curl_close($ch);
-
-               $a->save_timestamp($stamp1, "network");
-
-               if ((($curl_info["http_code"] == "301") || ($curl_info["http_code"] == "302") || ($curl_info["http_code"] == "303") || ($curl_info["http_code"] == "307"))
-                       && (($curl_info["redirect_url"] != "") || ($curl_info["location"] != ""))) {
-                       if ($curl_info["redirect_url"] != "") {
-                               $siteinfo = self::getSiteinfo($curl_info["redirect_url"], $no_guessing, $do_oembed, ++$count);
-                       } else {
-                               $siteinfo = self::getSiteinfo($curl_info["location"], $no_guessing, $do_oembed, ++$count);
-                       }
+               $data = z_fetch_url($url);
+               if (!$data['success']) {
                        return($siteinfo);
                }
 
                // If the file is too large then exit
-               if ($curl_info["download_content_length"] > 1000000) {
+               if ($data["info"]["download_content_length"] > 1000000) {
                        return($siteinfo);
                }
 
                // If it isn't a HTML file then exit
-               if (($curl_info["content_type"] != "") && !strstr(strtolower($curl_info["content_type"]), "html")) {
+               if (($data["info"]["content_type"] != "") && !strstr(strtolower($data["info"]["content_type"]), "html")) {
                        return($siteinfo);
                }
 
+               $header = $data["header"];
+               $body = $data["body"];
+
                if ($do_oembed) {
 
                        $oembed_data = oembed_fetch_url($url);
@@ -217,14 +188,6 @@ class ParseUrl {
                        $charset = "utf-8";
                }
 
-               $pos = strpos($header, "\r\n\r\n");
-
-               if ($pos) {
-                       $body = trim(substr($header, $pos));
-               } else {
-                       $body = $header;
-               }
-
                if (($charset != "") && (strtoupper($charset) != "UTF-8")) {
                        logger("parseurl_getsiteinfo: detected charset ".$charset, LOGGER_DEBUG);
                        //$body = mb_convert_encoding($body, "UTF-8", $charset);
index ab57a762dd9edcf75d1c07f857ebeeb83ec2b89d..e990060943fb6f269ccc13c006cae89ab1ad35a1 100644 (file)
@@ -179,6 +179,24 @@ blockquote.shared_content {
   border: none;
 }
 
+/* Events */
+.event-summary {
+  margin: 0px 0px 10px 0px;
+  font-weight: bold;
+}
+
+.vevent .event-summary {
+  margin: 0px 0px 10px 0px;
+}
+
+.vevent .event-description {
+  padding: 10px 0;
+}
+
+.event-label {
+  font-weight: bold;
+}
+
 .settings-heading a:after{
   content: ' »';
 }
index 1e5e74891c0197b0fe9a32920fa3881e2f9a7336..25c0c97388f2b0eafffc8d3622390556fcf481ee 100644 (file)
@@ -15,6 +15,7 @@
 # Fabian Dost <friends@dostmusik.de>, 2012
 # greeneyedred <greeneyedred@googlemail.com>, 2012
 # Hauke Zühl <hzuehl@phone-talk.de>, 2012
+# Herbert Thielen <thielen@hs-worms.de>, 2017
 # Hauke Zühl <hzuehl@phone-talk.de>, 2011-2012
 # Johannes Schwab <johannes_schwab@gmx.de>, 2015
 # leberwurscht <leberwurscht@hoegners.de>, 2012
@@ -37,8 +38,8 @@ msgstr ""
 "Project-Id-Version: friendica\n"
 "Report-Msgid-Bugs-To: \n"
 "POT-Creation-Date: 2017-10-13 07:26+0200\n"
-"PO-Revision-Date: 2017-10-13 15:20+0000\n"
-"Last-Translator: Tobias Diekershoff <tobias.diekershoff@gmx.net>\n"
+"PO-Revision-Date: 2017-10-17 13:55+0000\n"
+"Last-Translator: Herbert Thielen <thielen@hs-worms.de>\n"
 "Language-Team: German (http://www.transifex.com/Friendica/friendica/language/de/)\n"
 "MIME-Version: 1.0\n"
 "Content-Type: text/plain; charset=UTF-8\n"
@@ -6846,15 +6847,15 @@ msgstr "Normales Konto"
 
 #: mod/admin.php:640 mod/admin.php:1551
 msgid "Automatic Follower Account"
-msgstr "Automatisc Folgender Account"
+msgstr "Automatisch folgendes Konto (Marktschreier)"
 
 #: mod/admin.php:641 mod/admin.php:1552
 msgid "Public Forum Account"
-msgstr "Öffentliche Gemeinschaftsforen Accoun"
+msgstr "Öffentliches Forum Konto"
 
 #: mod/admin.php:642 mod/admin.php:1553
 msgid "Automatic Friend Account"
-msgstr "Automatisches Freundekonto"
+msgstr "Automatische Freunde Seite"
 
 #: mod/admin.php:643
 msgid "Blog Account"
@@ -6862,7 +6863,7 @@ msgstr "Blog-Konto"
 
 #: mod/admin.php:644
 msgid "Private Forum Account"
-msgstr "Private Gemeinschaftsforen Accoun"
+msgstr "Privates Forum Konto"
 
 #: mod/admin.php:666
 msgid "Message queues"
@@ -6874,7 +6875,7 @@ msgstr "Zusammenfassung"
 
 #: mod/admin.php:674
 msgid "Registered users"
-msgstr "Registrierte Nutzer"
+msgstr "Registrierte Personen"
 
 #: mod/admin.php:676
 msgid "Pending registrations"
@@ -6902,7 +6903,7 @@ msgstr "Keine Gemeinschaftsseite"
 
 #: mod/admin.php:1075
 msgid "Public postings from users of this site"
-msgstr "Öffentliche Beiträge von Nutzer_innen dieser Seite"
+msgstr "Öffentliche Beiträge von NutzerInnen dieser Seite"
 
 #: mod/admin.php:1076
 msgid "Global community page"
@@ -7514,7 +7515,7 @@ msgid ""
 "contains the name and version of the server, number of users with public "
 "profiles, number of posts and the activated protocols and connectors. See <a"
 " href='http://the-federation.info/'>the-federation.info</a> for details."
-msgstr "Wenn aktiviert, werden allgemeine Informationen über den Server und Nutzungsdaten veröffentlicht. Die Daten beinhalten den Namen sowie die Version des Servers, die Anzahl der Nutzer_innen mit öffentlichen Profilen, die Anzahl der Beiträge sowie aktivierte Protokolle und Connectoren. Für Details bitte <a href='http://the-federation.info/'>the-federation.info</a> aufrufen."
+msgstr "Wenn aktiviert, werden allgemeine Informationen über den Server und Nutzungsdaten veröffentlicht. Die Daten beinhalten den Namen sowie die Version des Servers, die Anzahl der Personen mit öffentlichen Profilen, die Anzahl der Beiträge sowie aktivierte Protokolle und Connectoren. Für Details bitte <a href='http://the-federation.info/'>the-federation.info</a> aufrufen."
 
 #: mod/admin.php:1233
 msgid "Suppress Tags"
@@ -7597,7 +7598,7 @@ msgstr "Neue Basis-URL"
 msgid ""
 "Change base url for this server. Sends relocate message to all DFRN contacts"
 " of all users."
-msgstr "Ändert die Basis-URL dieses Servers und sendet eine Umzugsmitteilung an alle DFRN Kontakte deiner Nutzer_innen."
+msgstr "Ändert die Basis-URL dieses Servers und sendet eine Umzugsmitteilung an alle DFRN Kontakte deiner NutzerInnen."
 
 #: mod/admin.php:1244
 msgid "RINO Encryption"
index 4e863701fff830d7406c3edb2fddffdbba592b3e..866b2a996515d5eec242797440972ab29042f6a8 100644 (file)
@@ -1574,21 +1574,21 @@ $a->strings["The database update failed. Please run \"php include/dbstructure.ph
 $a->strings["The worker was never executed. Please check your database structure!"] = "Der Hintergrundprozess (worker) wurde noch nie gestartet. Bitte überprüfe deine Datenbankstruktur.";
 $a->strings["The last worker execution was on %s UTC. This is older than one hour. Please check your crontab settings."] = "Der Hintergrundprozess (worker) wurde zuletzt um %s UTC ausgeführt. Das war vor mehr als einer Stunde. Bitte überprüfe deine crontab Einstellungen.";
 $a->strings["Normal Account"] = "Normales Konto";
-$a->strings["Automatic Follower Account"] = "Automatisc Folgender Account";
-$a->strings["Public Forum Account"] = "Öffentliche Gemeinschaftsforen Accoun";
-$a->strings["Automatic Friend Account"] = "Automatisches Freundekonto";
+$a->strings["Automatic Follower Account"] = "Automatisch folgendes Konto (Marktschreier)";
+$a->strings["Public Forum Account"] = "Öffentliches Forum Konto";
+$a->strings["Automatic Friend Account"] = "Automatische Freunde Seite";
 $a->strings["Blog Account"] = "Blog-Konto";
-$a->strings["Private Forum Account"] = "Private Gemeinschaftsforen Accoun";
+$a->strings["Private Forum Account"] = "Privates Forum Konto";
 $a->strings["Message queues"] = "Nachrichten-Warteschlangen";
 $a->strings["Summary"] = "Zusammenfassung";
-$a->strings["Registered users"] = "Registrierte Nutzer";
+$a->strings["Registered users"] = "Registrierte Personen";
 $a->strings["Pending registrations"] = "Anstehende Anmeldungen";
 $a->strings["Version"] = "Version";
 $a->strings["Active plugins"] = "Aktive Plugins";
 $a->strings["Can not parse base url. Must have at least <scheme>://<domain>"] = "Die Basis-URL konnte nicht analysiert werden. Sie muss mindestens aus <protokoll>://<domain> bestehen";
 $a->strings["Site settings updated."] = "Seiteneinstellungen aktualisiert.";
 $a->strings["No community page"] = "Keine Gemeinschaftsseite";
-$a->strings["Public postings from users of this site"] = "Öffentliche Beiträge von Nutzer_innen dieser Seite";
+$a->strings["Public postings from users of this site"] = "Öffentliche Beiträge von NutzerInnen dieser Seite";
 $a->strings["Global community page"] = "Globale Gemeinschaftsseite";
 $a->strings["Never"] = "Niemals";
 $a->strings["At post arrival"] = "Beim Empfang von Nachrichten";
@@ -1719,7 +1719,7 @@ $a->strings["When the discovery is activated, this value defines the timeframe f
 $a->strings["Search the local directory"] = "Lokales Verzeichnis durchsuchen";
 $a->strings["Search the local directory instead of the global directory. When searching locally, every search will be executed on the global directory in the background. This improves the search results when the search is repeated."] = "Suche im lokalen Verzeichnis anstelle des globalen Verzeichnisses durchführen. Jede Suche wird im Hintergrund auch im globalen Verzeichnis durchgeführt umd die Suchresultate zu verbessern, wenn diese Suche wiederholt wird.";
 $a->strings["Publish server information"] = "Server Informationen veröffentlichen";
-$a->strings["If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See <a href='http://the-federation.info/'>the-federation.info</a> for details."] = "Wenn aktiviert, werden allgemeine Informationen über den Server und Nutzungsdaten veröffentlicht. Die Daten beinhalten den Namen sowie die Version des Servers, die Anzahl der Nutzer_innen mit öffentlichen Profilen, die Anzahl der Beiträge sowie aktivierte Protokolle und Connectoren. Für Details bitte <a href='http://the-federation.info/'>the-federation.info</a> aufrufen.";
+$a->strings["If enabled, general server and usage data will be published. The data contains the name and version of the server, number of users with public profiles, number of posts and the activated protocols and connectors. See <a href='http://the-federation.info/'>the-federation.info</a> for details."] = "Wenn aktiviert, werden allgemeine Informationen über den Server und Nutzungsdaten veröffentlicht. Die Daten beinhalten den Namen sowie die Version des Servers, die Anzahl der Personen mit öffentlichen Profilen, die Anzahl der Beiträge sowie aktivierte Protokolle und Connectoren. Für Details bitte <a href='http://the-federation.info/'>the-federation.info</a> aufrufen.";
 $a->strings["Suppress Tags"] = "Tags Unterdrücken";
 $a->strings["Suppress showing a list of hashtags at the end of the posting."] = "Unterdrückt die Anzeige von Tags am Ende eines Beitrags.";
 $a->strings["Path to item cache"] = "Pfad zum Eintrag Cache";
@@ -1737,7 +1737,7 @@ $a->strings["The picture proxy increases performance and privacy. It shouldn't b
 $a->strings["Only search in tags"] = "Nur in Tags suchen";
 $a->strings["On large systems the text search can slow down the system extremely."] = "Auf großen Knoten kann die Volltext-Suche das System ausbremsen.";
 $a->strings["New base url"] = "Neue Basis-URL";
-$a->strings["Change base url for this server. Sends relocate message to all DFRN contacts of all users."] = "Ändert die Basis-URL dieses Servers und sendet eine Umzugsmitteilung an alle DFRN Kontakte deiner Nutzer_innen.";
+$a->strings["Change base url for this server. Sends relocate message to all DFRN contacts of all users."] = "Ändert die Basis-URL dieses Servers und sendet eine Umzugsmitteilung an alle DFRN Kontakte deiner NutzerInnen.";
 $a->strings["RINO Encryption"] = "RINO Verschlüsselung";
 $a->strings["Encryption layer between nodes."] = "Verschlüsselung zwischen Friendica Instanzen";
 $a->strings["Maximum number of parallel workers"] = "Maximale Anzahl parallel laufender Worker";
index dda816214624576873eadf3d00389cc0f9ffd579..b0f0a828e717e49fce08d9ff6f049de7dec66b28 100644 (file)
@@ -1,4 +1,9 @@
-{{if $alternate}}<link href='{{$alternate}}' rel='alternate' type='application/atom+xml'>{{/if}}
+{{if $alternate}}
+<link href='{{$alternate}}' rel='alternate' type='application/atom+xml'>
+{{/if}}
+{{if $conversation}}
+<link href='{{$conversation}}' rel='conversation' type='application/atom+xml'>
+{{/if}}
 <script>
 $(document).ready(function() {
        $(".comment-edit-wrapper textarea").editor_autocomplete(baseurl+"/acl");
diff --git a/view/templates/event_stream_item.tpl b/view/templates/event_stream_item.tpl
new file mode 100644 (file)
index 0000000..16d1221
--- /dev/null
@@ -0,0 +1,29 @@
+
+<div class="vevent">
+       <div class="summary event-summary">{{$title}}</div>
+
+       <div class="event-start">
+               <span class="event-label">{{$dtstart_label}}</span>&nbsp;
+               <span class="dtstart" title="$dtstart_title">{{$dtstart_dt}}</span>
+       </div>
+
+       {{if $finish}}
+       <div class="event-end">
+               <span class="event-label">{{$dtstart_label}}</span>&nbsp;
+               <span class="dend" title="$dtend_title">{{$dtend_dt}}</span>
+       </div>
+       {{/if}}
+
+       <div class="description event-description">{{$description}}</div>
+
+       {{if $location}}
+       <div class="event-location">
+               <span class="event-label">{{$location_label}}</span>&nbsp;
+               {{if $location.name}}
+               <span class="event-location">{{$location.name}}</span>
+               {{/if}}
+               {{if $location.map}}{{$location.map}}{{/if}}
+               
+       </div>
+       {{/if}}
+</div>
index 6932b1d5079edf8aff3dbdcd2a16517d31beb5b1..65344ede956fb5a48fbe9e2dc565836a387e1d3b 100644 (file)
     width: 60px;
 }
 
-
-
 /**
  * The event-card
  */
 .event-card {
-       width: auto;
+    width: auto;
 }
 .event-card .event-label,
 .event-card .location-label {
     padding: 9px;
     padding-left: 0px;
 }
-.event-card .event-hover-left-date {
-    width: 60px;
-}
-.event-card .event-date-wrapper.medium > span {
-    display: block;
-    overflow: hidden;
-    text-align: center;
-    white-space: nowrap;
-}
-.event-card .event-date-wrapper.medium .event-hover-short-month {
-    font-size: 13px;
-    text-transform: uppercase;
-}
-.event-card .event-date-wrapper.medium .event-hover-short-date {
-    font-size: 24px;
-    line-height: 28px;
-    margin-top: 2px;
-}
-
-.event-card .event-card-basic-content .event-card-content {
-    width: 100%;
-    padding: 0 5px 0 15px;
-    box-shadow: 1.5px 0 0 0 rgba(0, 0, 0, .1) inset;
-}
-.event-card .event-hover-title {
-    font-size: 14px;
-    color: #555;
-    line-height: 15px;
-    font-weight: bold;
-}
-.event-card .event-hover-location {
-    margin-top: 10px;
-    font-size: 13px;
-}
 .event-card .event-hover-location .location {
     color: #777;
     font-size: 13px;
-}
\ No newline at end of file
+}
index 91ca763a75d299931415f4d6834c8506c9d34667..987a64eef0d16d8300498b36eb6801964dd273db 100644 (file)
@@ -1130,6 +1130,9 @@ aside .vcard #wallmessage-link {
     padding-right: 20px;
     margin-left: -14px;
 }
+#nav-short-info .contact-photo-wrapper.media-left {
+    float: left;
+}
 #vcard-short-photo-wrapper img,
 #nav-short-info .contact-wrapper img {
     height: 34px;
@@ -2447,7 +2450,96 @@ ul li:hover .contact-wrapper .contact-action-link:hover {
 .event-buttons .plink-event-link {
     margin-left: 20px;
 }
+.vevent .event-summary {
+    font-size: 16px;
+}
+.vevent .event-description {
+    padding: 10px 0;
+}
+.vevent .event-location .location {
+    font-size: inherit;
+    color: inherit;
+}
+.modal-body .vevent .event-summary {
+    display: none;
+}
 
+/* Event Cards */
+.event-card-details, .event-card-header {
+    width: 100%;
+}
+.event-card-header, .event-card-left-date {
+    float: left;
+}
+.vevent .event-card-header {
+    display: table;
+}
+.event-card-left-date {
+    width: 60px; /* Das muss wahrscheinlich unterschiedlich sein zwischen calendar und stream */
+}
+.event-card .event-date-wrapper > span {
+    display: block;
+    overflow: hidden;
+    text-align: center;
+    white-space: nowrap;
+}
+.event-card .event-date-wrapper .event-card-short-month {
+    font-size: 13px;
+    text-transform: uppercase;
+}
+.event-card .event-date-wrapper.medium .event-card-short-date {
+    font-size: 24px;
+    line-height: 28px;
+    margin-top: 2px;
+}
+.event-card .event-card-content {
+    width: 100%;
+    padding: 0 5px 0 15px;
+    box-shadow: 1.5px 0 0 0 rgba(0, 0, 0, .1) inset;
+    color: #777;
+    position: relative;
+}
+.event-card .event-card-content .event-map-btn {
+    position: absolute;
+    right: 0;
+    top:0;
+    line-height: 15px;
+}
+.event-card .event-card-title {
+    font-size: 14px;
+    color: #555;
+    line-height: 15px;
+    font-weight: bold;
+}
+.event-card .event-card-location {
+    margin-top: 10px;
+    font-size: 13px;
+}
+.event-card .event-card-location br {
+    content: " ";
+}
+.event-card .event-card-location br::after {
+    content: " ";
+}
+.event-card-profile-name a {
+    color: $link_color;
+}
+.event-card-profile-name a:hover {
+    color: $link_hover_color;
+}
+.event-card .event-card-content .event-location-map {
+    position: absolute;
+    left: -9999px;
+    top: -9999px;
+}
+.event-card .event-card-content .event-location-map .map{
+    margin-top: 10px;
+}
+
+.event-card .event-description .seperator {
+    margin-top: 0;
+    box-shadow: 0 1.5px 0 0 rgba(0, 0, 0, .1) inset;
+}
 /* Photos Pages */
 #photo-photo {
     position: relative;
@@ -2885,3 +2977,4 @@ body .tread-wrapper .hovercard:hover .hover-card-content a {
 section .profile-match-wrapper {
     float: left;
 }
+
index 5bd7c944986b3fe8db4481b91775ee4416a81ecd..9d10bbb8e7e25d16fb4a059c38c4e9f01f3df7d2 100644 (file)
@@ -127,17 +127,17 @@ function changeView(action, viewName) {
 function eventHoverBodyTemplate() {
        var template = '\
                <div class="event-card-basic-content media">\
-                       <div class="hover-card-details">\
-                               <div class="hover-card-header left-align">\
-                                       <div class="event-hover-left-date left-align">\
+                       <div class="event-card-details">\
+                               <div class="event-card-header">\
+                                       <div class="event-card-left-date">\
                                                <span class="event-date-wrapper medium">\
-                                                       <span class="event-hover-short-month">{5}</span>\
-                                                       <span class="event-hover-short-date">{6}</span>\
+                                                       <span class="event-card-short-month">{5}</span>\
+                                                       <span class="event-card-short-date">{6}</span>\
                                                </span>\
                                        </div>\
                                        <div class="event-card-content media-body">\
-                                               <div class="event-hover-title">{2}</div>\
-                                               <div class="event-property"><span class="event-hover-date">{4}</span>{3}\
+                                               <div class="event-card-title">{2}</div>\
+                                               <div class="event-property"><span class="event-card-date">{4}</span>{3}\
                                                {1}\
                                        </div>\
                                </div>\
@@ -150,14 +150,15 @@ function eventHoverBodyTemplate() {
 
 // The template for presenting the event location in the event hover-card
 function eventHoverLocationTemplate() {
-       var template = '<span class="event-hover-location"> {0}</span></div>';
+       var template = '<span role="presentation" aria-hidden="true"> · </span>\
+                       <span class="event-card-location"> {0}</span></div>';
        return template;
 }
 
 function eventHoverProfileNameTemplate() {
        var template = '\
-                       <div class="event-hover-profile-name profile-entry-name">\
-                               <span class="left-align1"><a href="{0}" class="userinfo">{1}</a></span>\
+                       <div class="event-card-profile-name profile-entry-name">\
+                               <a href="{0}" class="userinfo">{1}</a>\
                        </div>';
        return template;
 }
index 0329ae6c82cb16a287a6238b2d007a41f9dfbfe0..82cbace5cb7b9a142990b6f603a463fb27a23e0a 100644 (file)
@@ -353,6 +353,11 @@ $(document).ready(function(){
                        $("body").removeClass("aside-out");
                });
 
+       // Event listener for 'Show & hide event map' button in the network stream.
+       $("body").on("click", ".event-map-btn", function() {
+               showHideEventMap(this);
+       });
+
 });
 
 function openClose(theID) {
@@ -375,7 +380,6 @@ function showHide(theID) {
        }
 }
 
-
 function showHideComments(id) {
        if( $('#collapsed-comments-' + id).is(':visible')) {
                $('#collapsed-comments-' + id).slideUp();
@@ -389,6 +393,37 @@ function showHideComments(id) {
        }
 }
 
+// Show & hide event map in the network stream by button click.
+function showHideEventMap(elm) {
+       // Get the id of the map element - it should be provided through
+       // the atribute "data-map-id".
+       var mapID = elm.getAttribute('data-map-id');
+
+       // Get translation labels.
+       var mapshow = elm.getAttribute('data-show-label');
+       var maphide = elm.getAttribute('data-hide-label');
+
+       // Change the button labels.
+       if (elm.innerText == mapshow) {
+               $('#' + elm.id).text(maphide);
+       } else {
+               $('#' + elm.id).text(mapshow);
+       }
+       // Because maps are iframe elements, we cant hide it through css (display: none).
+       // We solve this issue by putting the map outside the screen with css.
+       // So the first time the 'Show map' button is pressed we move the map
+       // element into the screen area.
+       var mappos = $('#' + mapID).css('position');
+
+       if (mappos === 'absolute') {
+               $('#' + mapID).hide();
+               $('#' + mapID).css({position: 'relative', left: 'auto', top: 'auto'});
+               openClose(mapID);
+       } else {
+               openClose(mapID);
+       }
+       return false;
+}
 
 function justifyPhotos() {
        justifiedGalleryActive = true;
@@ -506,7 +541,6 @@ function filter_replace(item) {
        };
 })( jQuery );
 
-
 // current time in milliseconds, to send each request to make sure
 // we 're not getting 304 response
 function timeNow() {
diff --git a/view/theme/frio/templates/event_stream_item.tpl b/view/theme/frio/templates/event_stream_item.tpl
new file mode 100644 (file)
index 0000000..2b367dc
--- /dev/null
@@ -0,0 +1,44 @@
+
+<div class="vevent event-card">
+       <div class="vevent-header">
+               <div class="event-card-details">
+                       <div class="event-card-header">
+                               <div class="event-card-left-date">
+                                       <span class="event-date-wrapper medium">
+                                               <span class="event-card-short-month">{{$month_short}}</span>
+                                               <span class="event-card-short-date">{{$date_short}}</span>
+                                       </span>
+                               </div>
+                               <div class="event-card-content media-body">
+                                       <div class="event-title event-card-title summary event-summary">{{$title}}</div>
+                                       {{if $location.map}}<button id="event-map-btn-{{$id}}" class="event-map-btn btn-link fakelink nav nav-pills preferences" data-map-id="event-location-map-{{$id}}" data-show-label="{{$show_map_label}}" data-hide-label="{{$hide_map_label}}">{{$map_btn_label}}</button>{{/if}}
+                                       <div class="event-property">
+                                               <span class="event-date">
+                                                       <span class="event-start dtstart" title="{{$dtstart_title}}">{{$start_short}}</span>
+                                                       {{if $finish}} - <span class="event-end dtend" title="{{$dtend_title}}">{{if $same_date}}{{$end_time}}{{else}}{{$end_short}}{{/if}}</span>{{/if}}
+                                               </span>
+                                               {{if $location.name}}
+                                               <span role="presentation" aria-hidden="true"> · </span>
+                                               <span class="event-location event-card-location">{{$location.name}}</span>
+                                               {{/if}}
+                                       </div>
+                                       <div class="event-card-profile-name profile-entry-name">
+                                               <a href="{{$author_link}}" class="userinfo">{{$author_name}}</a>
+                                       </div>
+                                       {{if $location.map}}
+                                       <div id="event-location-map-{{$id}}" class="event-location-map">{{$location.map}}</div>
+                                       {{/if}}
+                               </div>
+                               <div class="clearfix"></div>
+                       </div>
+               </div>
+       </div>
+       <div class="clearfix"></div>
+
+       {{if $description}}
+       <div class="description event-description">
+               <hr class="seperator" />
+               {{$description}}
+       </div>
+{{/if}}
+</div>