+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]
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
---------
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
---------
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')
);
}
// 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'])));
}
}
* @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`,
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)
);
killme();
}
+ $items = $r;
$item = $r[0];
$r = q("SELECT `contact`.*, `user`.`nickname`, `user`.`timezone`, `user`.`page-flags`, `user`.`account-type`
$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;
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 ))
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>";
$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> <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> <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> <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']) {
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 = '';
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);
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();
return $ev;
}
-
function sort_by_date($a) {
usort($a,'ev_compare');
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;
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';
}
- // Existing event being modified
+ // Existing event being modified.
if ($arr['id']) {
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`,
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",
}
}
+/**
+ * @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;
}
/**
- * @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 {
}
/**
- * @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
* @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;
}
}
/**
- * @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`
}
/**
- * @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();
$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);
$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);
}
/**
- * @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))) {
}
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;
}
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
// 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 {
}
/**
- * @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 ",
/**
*
- * @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";
}
/**
- * @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;
/*
* 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;
'$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;
+}
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);
$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 = "";
}
}
- $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]";
}
use Friendica\App;
use Friendica\Core\System;
+use Friendica\Network\Probe;
require_once 'include/probe.php';
require_once 'include/socgraph.php';
-function new_contact($uid,$url,$interactive = false) {
+function new_contact($uid, $url, $interactive = false, $network = '') {
$result = array('cid' => -1, 'success' => false,'message' => '');
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) {
return($replace);
}
-function html2bbcode($message)
+function html2bbcode($message, $basepath = '')
{
$message = str_replace("\r", "", $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;
}
// 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;
+}
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();
));
}
- } 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)
* 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);
// 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);
$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 = '';
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 : '');
+}
// 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;
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'),
$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')) {
/**
}
}
-// 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
$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));
$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;
}
$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;
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];
));
}
- $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';
$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);
}
$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)) {
$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);
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) {
}
return trim($s);
-}}
-
-
+}
/**
* return array with details for categories and folders for an item
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
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
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
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
'$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")),
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",
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);
}
}
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"]) {
$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` = ''
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` = ''
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;
}
$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();
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);
}
// 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
$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 {
* @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
$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);
$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);
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: ' »';
}
# 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
"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"
#: 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"
#: mod/admin.php:644
msgid "Private Forum Account"
-msgstr "Private Gemeinschaftsforen Accoun"
+msgstr "Privates Forum Konto"
#: mod/admin.php:666
msgid "Message queues"
#: mod/admin.php:674
msgid "Registered users"
-msgstr "Registrierte Nutzer"
+msgstr "Registrierte Personen"
#: mod/admin.php:676
msgid "Pending registrations"
#: 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"
"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"
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"
$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";
$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";
$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";
-{{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");
--- /dev/null
+
+<div class="vevent">
+ <div class="summary event-summary">{{$title}}</div>
+
+ <div class="event-start">
+ <span class="event-label">{{$dtstart_label}}</span>
+ <span class="dtstart" title="$dtstart_title">{{$dtstart_dt}}</span>
+ </div>
+
+ {{if $finish}}
+ <div class="event-end">
+ <span class="event-label">{{$dtstart_label}}</span>
+ <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>
+ {{if $location.name}}
+ <span class="event-location">{{$location.name}}</span>
+ {{/if}}
+ {{if $location.map}}{{$location.map}}{{/if}}
+
+ </div>
+ {{/if}}
+</div>
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
+}
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;
.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;
section .profile-match-wrapper {
float: left;
}
+
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>\
// 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;
}
$("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) {
}
}
-
function showHideComments(id) {
if( $('#collapsed-comments-' + id).is(':visible')) {
$('#collapsed-comments-' + id).slideUp();
}
}
+// 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;
};
})( jQuery );
-
// current time in milliseconds, to send each request to make sure
// we 're not getting 304 response
function timeNow() {
--- /dev/null
+
+<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>