Merge remote-tracking branch 'upstream/3.6-rc' into url-shorten-ostatus

This commit is contained in:
Michael 2018-03-22 20:42:29 +00:00
commit 318de2f590
31 changed files with 7673 additions and 7386 deletions

View file

@ -41,6 +41,8 @@ php.ini file [or see 'poormancron' in section 8]
- some form of email server or email gateway such that PHP mail() works - some form of email server or email gateway such that PHP mail() works
- The POSIX module of PHP needs to be activated (e.g. RHEL, CentOS have disabled it)
- Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.) - Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.)
- ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks - ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks

View file

@ -70,7 +70,8 @@ See Wikipedia for more of them ([video](http://en.wikipedia.org/wiki/HTML5_video
<a name="avatars"></a> <a name="avatars"></a>
### Is it possible to have different avatars per profile? ### Is it possible to have different avatars per profile?
Yes. On your Edit/Manage Profiles page, you will find a "change profile photo" link. Yes.
On your Edit/Manage Profiles page, you will find a "change profile photo" link.
Clicking this will take you to a page where you can upload a photograph and select which profile it will be associated with. Clicking this will take you to a page where you can upload a photograph and select which profile it will be associated with.
To avoid privacy leakage, we only display the photograph associated with your default profile as the avatar in your posts. To avoid privacy leakage, we only display the photograph associated with your default profile as the avatar in your posts.
@ -111,15 +112,9 @@ After that, your account is deleted.
<a name="hashtag"></a> <a name="hashtag"></a>
### Can I follow a hashtag? ### Can I follow a hashtag?
No. The act of 'following' a hashtags is an interesting technology, but presents a few issues. Yes. Simply add the hash tag to your saved searches.
The posts will appear on your network page.
1. Posts would have to be copied to all sites on the network that are "listening" to that hashtag. This would increase the storage demands to the detriment of small sites. It would make the use of shared hosting practically impossible. For technical reasons, your answers to such posts won't appear on the "personal" tab in the network page and the whole thread isn't accessible via the API.
2. Making spam easy (tag spam is a serious issue on Twitter for instance)
3. It creates a natural bias towards large sites which hold more tagged content - if your network uses tagging instead of other conversation federation mechanisms such as groups/forums.
Instead, we offer other mechanisms for wide-area conversations while retaining a 'level playing ground' for both large and small sites, such as forums and community pages and shared tags.
<a name="rss"></a> <a name="rss"></a>
### How to create a RSS feed of the stream? ### How to create a RSS feed of the stream?

View file

@ -29,6 +29,7 @@ Requirements
* PHP 5.6+ (PHP 7 is recommended for performance) * PHP 5.6+ (PHP 7 is recommended for performance)
* PHP *command line* access with register_argc_argv set to true in the php.ini file * PHP *command line* access with register_argc_argv set to true in the php.ini file
* Curl, GD, PDO, MySQLi, hash, xml, zip and OpenSSL extensions * Curl, GD, PDO, MySQLi, hash, xml, zip and OpenSSL extensions
* The POSIX module of PHP needs to be activated (e.g. [RHEL, CentOS](http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7) have disabled it)
* some form of email server or email gateway such that PHP mail() works * some form of email server or email gateway such that PHP mail() works
* Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.) * Mysql 5.5.3+ or an equivalant alternative for MySQL (MariaDB, Percona Server etc.)
* the ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks (Windows) (Note: other options are presented in Section 7 of this document.) * the ability to schedule jobs with cron (Linux/Mac) or Scheduled Tasks (Windows) (Note: other options are presented in Section 7 of this document.)

View file

@ -10,7 +10,7 @@ Nutzer
* **[Ist es möglich, bei mehreren Profilen verschiedene Avatare (Nutzerbilder) zu haben?](help/FAQ#avatars)** * **[Ist es möglich, bei mehreren Profilen verschiedene Avatare (Nutzerbilder) zu haben?](help/FAQ#avatars)**
* **[Was ist der Unterschied zwischen blockierten|ignorierten|archivierten|versteckten Kontakten?](help/FAQ#contacts)** * **[Was ist der Unterschied zwischen blockierten|ignorierten|archivierten|versteckten Kontakten?](help/FAQ#contacts)**
* **[Was passiert, wenn ein Account gelöscht ist? Ist dieser richtig gelöscht?](help/FAQ#removed)** * **[Was passiert, wenn ein Account gelöscht ist? Ist dieser richtig gelöscht?](help/FAQ#removed)**
* **[Kann ich einem hashtag folgen?](help/FAQ#hashtag)** * **[Kann ich einem Hashtag folgen?](help/FAQ#hashtag)**
* **[Wie kann ich einen RSS-Feed meiner Netzwerkseite (Stream) erstellen?](help/FAQ#rss)** * **[Wie kann ich einen RSS-Feed meiner Netzwerkseite (Stream) erstellen?](help/FAQ#rss)**
* **[Gibt es Clients für Friendica?](help/FAQ#clients)** * **[Gibt es Clients für Friendica?](help/FAQ#clients)**
* **[Wo finde ich Hilfe?](help/FAQ#help)** * **[Wo finde ich Hilfe?](help/FAQ#help)**
@ -122,19 +122,11 @@ Dieses Vorgehen setzt voraus, dass Dein Profil für 24 Stunden weiterhin "teilwe
Wir können also Dein Profil blockieren und es so erscheinen lassen, als wären alle Daten sofort gelöscht, allerdings warten wir 24 Stunden (bzw. bis alle Deine Kontakte informiert wurden), bevor wir die Daten auch physikalisch löschen. Wir können also Dein Profil blockieren und es so erscheinen lassen, als wären alle Daten sofort gelöscht, allerdings warten wir 24 Stunden (bzw. bis alle Deine Kontakte informiert wurden), bevor wir die Daten auch physikalisch löschen.
<a name="hashtag"></a> <a name="hashtag"></a>
### Kann ich einem hashtag folgen? ### Kann ich einem Hashtag folgen?
Nein. Ja.
Die Möglichkeit, einem hashtag zu folgen, ist eine interessante Technik, führt aber zu einigen Schwierigkeiten. Füge die Tags zu Deinen gespeicherten Suchen hinzu, sie werden automatisch auf der Netzwerk-Seite auftauchen.
Bitte beachte, dass Deine Antworten auf solche Posts aus technischen Gründen nicht unter dem "Persönlich"-Reiter auf der Netzwerk-Seite und der gesamte Thread nicht per API zu sehen sind.
1.) Alle Beiträge, die diesen tag nutzen, müssten zu allen Seiten im Netzwerk kopiert werden. Das erhöht den Speicherbedarf und beeinträchtigt kleine Seiten. Die Nutzung von geteilten Hosting-Angeboten (Shared Hosting) wäre praktisch unmöglich.
2.) Die Verbreitung von Spam wäre vereinfacht (tag-Spam ist z.B. bei Twitter ein schwerwiegendes Problem)
3.) Der wichtigste Grund der gegen diese Technik spricht ist, dass sie eine natürliche Ausrichtung auf größere Seiten mit mehr getaggten Inhalten zur Folge hat. Dies kann z.B. aufkommen, wenn Dein Netzwerk tags anstelle von anderen Kommunikationsmitteln wie Gruppen oder Foren nutzt.
Stattdessen bieten wir andere Mechanismen, um globale Unterhaltungen zu erreichen, dabei aber eine angemesse Basis für kleine und große Seiten zu bieten.
Hierzu gehören Foren, Gruppen und geteilte tags.
<a name="rss"></a> <a name="rss"></a>
### Wie kann ich einen RSS-Feed meiner Netzwerkseite (Stream) erstellen? ### Wie kann ich einen RSS-Feed meiner Netzwerkseite (Stream) erstellen?

View file

@ -26,6 +26,7 @@ Wir planen, diese Einschränkung in einer zukünftigen Version zu beheben.
- PHP *Kommandozeilen*-Zugang mit register_argc_argv auf "true" gesetzt in der php.ini-Datei - PHP *Kommandozeilen*-Zugang mit register_argc_argv auf "true" gesetzt in der php.ini-Datei
- Curl, GD, PDO, MySQLi, xml, zip und OpenSSL-Erweiterung - Curl, GD, PDO, MySQLi, xml, zip und OpenSSL-Erweiterung
- etwas in der Art eines Email-Servers oder eines Gateways wie PHP mail() - etwas in der Art eines Email-Servers oder eines Gateways wie PHP mail()
- Das POSIX Modul muss aktiviert sein ([CentOS, RHEL](http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7http://www.bigsoft.co.uk/blog/index.php/2014/12/08/posix-php-commands-not-working-under-centos-7) haben dies z.B. deaktiviert)
- Mysql 5.5.3+ - Mysql 5.5.3+
- die Möglichkeit, wiederkehrende Aufgaben mit cron (Linux/Mac) oder "Scheduled Tasks" einzustellen (Windows) [Beachte: andere Optionen sind in Abschnitt 7 dieser Dokumentation zu finden] - die Möglichkeit, wiederkehrende Aufgaben mit cron (Linux/Mac) oder "Scheduled Tasks" einzustellen (Windows) [Beachte: andere Optionen sind in Abschnitt 7 dieser Dokumentation zu finden]
- Installation in einer Top-Level-Domain oder Subdomain (ohne eine Verzeichnis/Pfad-Komponente in der URL) wird bevorzugt. Verzeichnispfade sind für diesen Zweck nicht so günstig und wurden auch nicht ausführlich getestet. - Installation in einer Top-Level-Domain oder Subdomain (ohne eine Verzeichnis/Pfad-Komponente in der URL) wird bevorzugt. Verzeichnispfade sind für diesen Zweck nicht so günstig und wurden auch nicht ausführlich getestet.

View file

@ -101,6 +101,7 @@ class dba {
if (!$install) { if (!$install) {
System::unavailable(); System::unavailable();
} }
return false;
} }
$a->save_timestamp($stamp1, "network"); $a->save_timestamp($stamp1, "network");

View file

@ -18,10 +18,10 @@ require_once 'include/html2bbcode.php';
* @brief Creates a notification entry and possibly sends a mail * @brief Creates a notification entry and possibly sends a mail
* *
* @param array $params Array with the elements: * @param array $params Array with the elements:
uid, item, parent, type, otype, verb, event, * uid, item, parent, type, otype, verb, event,
link, subject, body, to_name, to_email, source_name, * link, subject, body, to_name, to_email, source_name,
source_link, activity, preamble, notify_flags, * source_link, activity, preamble, notify_flags,
language, show_in_notification_page * language, show_in_notification_page
*/ */
function notification($params) function notification($params)
{ {
@ -370,7 +370,7 @@ function notification($params)
'[url='.$params['source_link'].']'.$params['source_name'].'[/url]' '[url='.$params['source_link'].']'.$params['source_name'].'[/url]'
); );
$body = L10n::t('Full Name: %1$s\nSite Location: %2$s\nLogin Name: %3$s ' . "\x28" . '%4$s' . "\x28", $body = L10n::t('Full Name: %1$s\nSite Location: %2$s\nLogin Name: %3$s ' . "\x28" . '%4$s' . "\x29",
$params['source_name'], $params['source_name'],
$siteurl, $params['source_mail'], $siteurl, $params['source_mail'],
$params['source_nick'] $params['source_nick']

View file

@ -38,9 +38,9 @@ function format_event_html($ev, $simple = false) {
); );
if ($simple) { if ($simple) {
$o = "<h3>" . BBCode::convert($ev['summary']) . "</h3>"; $o = "<h3>" . BBCode::convert($ev['summary'], false, $simple) . "</h3>";
$o .= "<p>" . BBCode::convert($ev['desc']) . "</p>"; $o .= "<p>" . BBCode::convert($ev['desc'], false, $simple) . "</p>";
$o .= "<h4>" . L10n::t('Starts:') . "</h4><p>" . $event_start . "</p>"; $o .= "<h4>" . L10n::t('Starts:') . "</h4><p>" . $event_start . "</p>";
@ -49,7 +49,7 @@ function format_event_html($ev, $simple = false) {
} }
if (strlen($ev['location'])) { if (strlen($ev['location'])) {
$o .= "<h4>" . L10n::t('Location:') . "</h4><p>" . BBCode::convert($ev['location']) . "</p>"; $o .= "<h4>" . L10n::t('Location:') . "</h4><p>" . BBCode::convert($ev['location'], false, $simple) . "</p>";
} }
return $o; return $o;
@ -57,7 +57,7 @@ function format_event_html($ev, $simple = false) {
$o = '<div class="vevent">' . "\r\n"; $o = '<div class="vevent">' . "\r\n";
$o .= '<div class="summary event-summary">' . BBCode::convert($ev['summary']) . '</div>' . "\r\n"; $o .= '<div class="summary event-summary">' . BBCode::convert($ev['summary'], false, $simple) . '</div>' . "\r\n";
$o .= '<div class="event-start"><span class="event-label">' . L10n::t('Starts:') . '</span>&nbsp;<span class="dtstart" title="' $o .= '<div class="event-start"><span class="event-label">' . L10n::t('Starts:') . '</span>&nbsp;<span class="dtstart" title="'
. DateTimeFormat::utc($ev['start'], (($ev['adjust']) ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s' )) . DateTimeFormat::utc($ev['start'], (($ev['adjust']) ? DateTimeFormat::ATOM : 'Y-m-d\TH:i:s' ))
@ -71,16 +71,16 @@ function format_event_html($ev, $simple = false) {
. '</span></div>' . "\r\n"; . '</span></div>' . "\r\n";
} }
$o .= '<div class="description event-description">' . BBCode::convert($ev['desc']) . '</div>' . "\r\n"; $o .= '<div class="description event-description">' . BBCode::convert($ev['desc'], false, $simple) . '</div>' . "\r\n";
if (strlen($ev['location'])) { if (strlen($ev['location'])) {
$o .= '<div class="event-location"><span class="event-label">' . L10n::t('Location:') . '</span>&nbsp;<span class="location">' $o .= '<div class="event-location"><span class="event-label">' . L10n::t('Location:') . '</span>&nbsp;<span class="location">'
. BBCode::convert($ev['location']) . BBCode::convert($ev['location'], false, $simple)
. '</span></div>' . "\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) { if (strpos($ev['location'], "[map") !== false) {
$map = Map::byLocation($ev['location']); $map = Map::byLocation($ev['location'], $simple);
if ($map !== $ev['location']) { if ($map !== $ev['location']) {
$o.= $map; $o.= $map;
} }
@ -241,14 +241,20 @@ function event_store($arr) {
$a = get_app(); $a = get_app();
$arr['created'] = (($arr['created']) ? $arr['created'] : DateTimeFormat::utcNow()); $arr['created'] = (($arr['created']) ? DateTimeFormat::utc($arr['created']) : DateTimeFormat::utcNow());
$arr['edited'] = (($arr['edited']) ? $arr['edited'] : DateTimeFormat::utcNow()); $arr['edited'] = (($arr['edited']) ? DateTimeFormat::utc($arr['edited']) : DateTimeFormat::utcNow());
$arr['start'] = (($arr['start']) ? DateTimeFormat::utc($arr['start']) : NULL_DATE);
$arr['finish'] = (($arr['finish']) ? DateTimeFormat::utc($arr['finish']) : NULL_DATE);
$arr['type'] = (($arr['type']) ? $arr['type'] : 'event' ); $arr['type'] = (($arr['type']) ? $arr['type'] : 'event' );
$arr['cid'] = ((intval($arr['cid'])) ? intval($arr['cid']) : 0); $arr['cid'] = ((intval($arr['cid'])) ? intval($arr['cid']) : 0);
$arr['uri'] = (x($arr, 'uri') ? $arr['uri'] : item_new_uri($a->get_hostname(), $arr['uid'])); $arr['uri'] = (x($arr, 'uri') ? $arr['uri'] : item_new_uri($a->get_hostname(), $arr['uid']));
$arr['private'] = ((x($arr, 'private')) ? intval($arr['private']) : 0); $arr['private'] = ((x($arr, 'private')) ? intval($arr['private']) : 0);
$arr['guid'] = get_guid(32); $arr['guid'] = get_guid(32);
if ($arr['finish'] < NULL_DATE) {
$arr['finish'] = NULL_DATE;
}
if ($arr['cid']) { if ($arr['cid']) {
$c = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1", $c = q("SELECT * FROM `contact` WHERE `id` = %d AND `uid` = %d LIMIT 1",
intval($arr['cid']), intval($arr['cid']),

View file

@ -1062,7 +1062,7 @@ function linkify($s) {
* Load poke verbs * Load poke verbs
* *
* @return array index is present tense verb * @return array index is present tense verb
value is array containing past tense verb, translation of present, translation of past * value is array containing past tense verb, translation of present, translation of past
* @hook poke_verbs pokes array * @hook poke_verbs pokes array
*/ */
function get_poke_verbs() { function get_poke_verbs() {

View file

@ -39,7 +39,7 @@ function babel_content()
$o .= visible_lf($text) . EOL . EOL; $o .= visible_lf($text) . EOL . EOL;
$html = BBCode::convert($text); $html = BBCode::convert($text);
$o .= '<h2>' . L10n::t("bbcode \x28raw HTML\x28: ") . '</h2>' . EOL . EOL; $o .= '<h2>' . L10n::t("bbcode \x28raw HTML\x29: ") . '</h2>' . EOL . EOL;
$o .= htmlspecialchars($html) . EOL . EOL; $o .= htmlspecialchars($html) . EOL . EOL;
$o .= '<h2>' . L10n::t('bbcode: ') . '</h2>' . EOL . EOL; $o .= '<h2>' . L10n::t('bbcode: ') . '</h2>' . EOL . EOL;

View file

@ -45,6 +45,14 @@ function contacts_init(App $a)
} }
if (DBM::is_result($contact)) { if (DBM::is_result($contact)) {
if ($contact['self']) {
if (($a->argc == 3) && intval($a->argv[1]) && ($a->argv[2] == "posts")) {
goaway('profile/' . $contact['nick']);
} else {
goaway('profile/' . $contact['nick'] . '?tab=profile');
}
}
$a->data['contact'] = $contact; $a->data['contact'] = $contact;
if (($a->data['contact']['network'] != "") && ($a->data['contact']['network'] != NETWORK_DFRN)) { if (($a->data['contact']['network'] != "") && ($a->data['contact']['network'] != NETWORK_DFRN)) {
@ -940,6 +948,13 @@ function _contact_detail_for_template($rr)
$sparkle = ''; $sparkle = '';
} }
if ($rr['self']) {
$dir_icon = 'images/larrow.gif';
$alt_text = L10n::t('This is you');
$url = $rr['url'];
$sparkle = '';
}
return [ return [
'img_hover' => L10n::t('Visit %s\'s profile [%s]', $rr['name'], $rr['url']), 'img_hover' => L10n::t('Visit %s\'s profile [%s]', $rr['name'], $rr['url']),
'edit_hover' => L10n::t('Edit contact'), 'edit_hover' => L10n::t('Edit contact'),

View file

@ -15,6 +15,7 @@ use Friendica\Model\Profile;
use Friendica\Network\Probe; use Friendica\Network\Probe;
use Friendica\Protocol\PortableContact; use Friendica\Protocol\PortableContact;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Database\DBM;
require_once 'mod/contacts.php'; require_once 'mod/contacts.php';
@ -113,32 +114,22 @@ function dirfind_content(App $a, $prefix = "") {
/// @TODO These 2 SELECTs are not checked on validity with DBM::is_result() /// @TODO These 2 SELECTs are not checked on validity with DBM::is_result()
$count = q("SELECT count(*) AS `total` FROM `gcontact` $count = q("SELECT count(*) AS `total` FROM `gcontact`
LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` WHERE NOT `hide` AND `network` IN ('%s', '%s', '%s') AND
AND `contact`.`network` = `gcontact`.`network` ((`last_contact` >= `last_failure`) OR (`updated` >= `last_failure`)) AND
AND `contact`.`uid` = %d AND NOT `contact`.`blocked` (`url` LIKE '%s' OR `name` LIKE '%s' OR `location` LIKE '%s' OR
AND NOT `contact`.`pending` AND `contact`.`rel` IN ('%s', '%s') `addr` LIKE '%s' OR `about` LIKE '%s' OR `keywords` LIKE '%s') $extra_sql",
WHERE (`contact`.`id` > 0 OR (NOT `gcontact`.`hide` AND `gcontact`.`network` IN ('%s', '%s', '%s') AND
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)))) AND
(`gcontact`.`url` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`location` LIKE '%s' OR
`gcontact`.`addr` LIKE '%s' OR `gcontact`.`about` LIKE '%s' OR `gcontact`.`keywords` LIKE '%s') $extra_sql",
intval(local_user()), dbesc(CONTACT_IS_SHARING), dbesc(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora), dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2))); dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)));
$results = q("SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`photo`, `gcontact`.`network`, `gcontact`.`keywords`, `gcontact`.`addr` $results = q("SELECT `nurl`
FROM `gcontact` FROM `gcontact`
LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` WHERE NOT `hide` AND `network` IN ('%s', '%s', '%s') AND
AND `contact`.`network` = `gcontact`.`network` ((`last_contact` >= `last_failure`) OR (`updated` >= `last_failure`)) AND
AND `contact`.`uid` = %d AND NOT `contact`.`blocked` (`url` LIKE '%s' OR `name` LIKE '%s' OR `location` LIKE '%s' OR
AND NOT `contact`.`pending` AND `contact`.`rel` IN ('%s', '%s') `addr` LIKE '%s' OR `about` LIKE '%s' OR `keywords` LIKE '%s') $extra_sql
WHERE (`contact`.`id` > 0 OR (NOT `gcontact`.`hide` AND `gcontact`.`network` IN ('%s', '%s', '%s') AND GROUP BY `nurl`
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`)))) AND ORDER BY `updated` DESC LIMIT %d, %d",
(`gcontact`.`url` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`location` LIKE '%s' OR
`gcontact`.`addr` LIKE '%s' OR `gcontact`.`about` LIKE '%s' OR `gcontact`.`keywords` LIKE '%s') $extra_sql
GROUP BY `gcontact`.`nurl`
ORDER BY `gcontact`.`updated` DESC LIMIT %d, %d",
intval(local_user()), dbesc(CONTACT_IS_SHARING), dbesc(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora), dbesc(NETWORK_DFRN), dbesc($ostatus), dbesc($diaspora),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)),
dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)), dbesc(escape_tags($search2)),
@ -148,14 +139,21 @@ function dirfind_content(App $a, $prefix = "") {
$j->items_page = $perpage; $j->items_page = $perpage;
$j->page = $a->pager['page']; $j->page = $a->pager['page'];
foreach ($results AS $result) { foreach ($results AS $result) {
if (PortableContact::alternateOStatusUrl($result["url"])) { if (PortableContact::alternateOStatusUrl($result["nurl"])) {
continue; continue;
} }
$result = Contact::getDetailsByURL($result["url"], local_user(), $result); $urlparts = parse_url($result["nurl"]);
// Ignore results that look strange.
// For historic reasons the gcontact table does contain some garbage.
if (!empty($urlparts['query']) || !empty($urlparts['fragment'])) {
continue;
}
$result = Contact::getDetailsByURL($result["nurl"], local_user());
if ($result["name"] == "") { if ($result["name"] == "") {
$urlparts = parse_url($result["url"]);
$result["name"] = end(explode("/", $urlparts["path"])); $result["name"] = end(explode("/", $urlparts["path"]));
} }
@ -204,11 +202,10 @@ function dirfind_content(App $a, $prefix = "") {
if ($jj->cid > 0) { if ($jj->cid > 0) {
$connlnk = ""; $connlnk = "";
$conntxt = ""; $conntxt = "";
$contact = q("SELECT * FROM `contact` WHERE `id` = %d", $contact = dba::selectFirst('contact', [], ['id' => $jj->cid]);
intval($jj->cid)); if (DBM::is_result($contact)) {
if ($contact) { $photo_menu = Contact::photoMenu($contact);
$photo_menu = Contact::photoMenu($contact[0]); $details = _contact_detail_for_template($contact);
$details = _contact_detail_for_template($contact[0]);
$alt_text = $details['alt_text']; $alt_text = $details['alt_text'];
} else { } else {
$photo_menu = []; $photo_menu = [];

View file

@ -397,7 +397,8 @@ function check_funcs(&$checks) {
check_add($ck_funcs, L10n::t('PDO or MySQLi PHP module'), true, true, ""); check_add($ck_funcs, L10n::t('PDO or MySQLi PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('mb_string PHP module'), true, true, ""); check_add($ck_funcs, L10n::t('mb_string PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('XML PHP module'), true, true, ""); check_add($ck_funcs, L10n::t('XML PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('iconv module'), true, true, ""); check_add($ck_funcs, L10n::t('iconv PHP module'), true, true, "");
check_add($ck_funcs, L10n::t('POSIX PHP module'), true, true, "");
if (function_exists('apache_get_modules')) { if (function_exists('apache_get_modules')) {
if (! in_array('mod_rewrite',apache_get_modules())) { if (! in_array('mod_rewrite',apache_get_modules())) {
@ -432,8 +433,12 @@ function check_funcs(&$checks) {
$ck_funcs[4]['help'] = L10n::t('Error: mb_string PHP module required but not installed.'); $ck_funcs[4]['help'] = L10n::t('Error: mb_string PHP module required but not installed.');
} }
if (! function_exists('iconv_strlen')) { if (! function_exists('iconv_strlen')) {
$ck_funcs[6]['status'] = false;
$ck_funcs[6]['help'] = L10n::t('Error: iconv PHP module required but not installed.');
}
if (! function_exists('posix_kill')) {
$ck_funcs[7]['status'] = false; $ck_funcs[7]['status'] = false;
$ck_funcs[7]['help'] = L10n::t('Error: iconv PHP module required but not installed.'); $ck_funcs[7]['help'] = L10n::t('Error: POSIX PHP module required but not installed.');
} }
$checks = array_merge($checks, $ck_funcs); $checks = array_merge($checks, $ck_funcs);
@ -442,8 +447,8 @@ function check_funcs(&$checks) {
try { try {
$xml = new DOMDocument(); $xml = new DOMDocument();
} catch (Exception $e) { } catch (Exception $e) {
$ck_funcs[6]['status'] = false; $ck_funcs[5]['status'] = false;
$ck_funcs[6]['help'] = L10n::t('Error, XML PHP module required but not installed.'); $ck_funcs[5]['help'] = L10n::t('Error, XML PHP module required but not installed.');
} }
} }
@ -540,7 +545,7 @@ function load_database_rem($v, $i) {
} }
function load_database() { function load_database() {
$errors = DBStructure::update(false, true); $errors = DBStructure::update(false, true, true);
return $errors; return $errors;
} }

View file

@ -1598,8 +1598,8 @@ class BBCode
if (strpos($text, '[/map]') !== false) { if (strpos($text, '[/map]') !== false) {
$text = preg_replace_callback( $text = preg_replace_callback(
"/\[map\](.*?)\[\/map\]/ism", "/\[map\](.*?)\[\/map\]/ism",
function ($match) { function ($match) use ($simple_html) {
return str_replace($match[0], '<p class="map">' . Map::byLocation($match[1]) . '</p>', $match[0]); return str_replace($match[0], '<p class="map">' . Map::byLocation($match[1], $simple_html) . '</p>', $match[0]);
}, },
$text $text
); );
@ -1607,14 +1607,14 @@ class BBCode
if (strpos($text, '[map=') !== false) { if (strpos($text, '[map=') !== false) {
$text = preg_replace_callback( $text = preg_replace_callback(
"/\[map=(.*?)\]/ism", "/\[map=(.*?)\]/ism",
function ($match) { function ($match) use ($simple_html) {
return str_replace($match[0], '<p class="map">' . Map::byCoordinates(str_replace('/', ' ', $match[1])) . '</p>', $match[0]); return str_replace($match[0], '<p class="map">' . Map::byCoordinates(str_replace('/', ' ', $match[1]), $simple_html) . '</p>', $match[0]);
}, },
$text $text
); );
} }
if (strpos($text, '[map]') !== false) { if (strpos($text, '[map]') !== false) {
$text = preg_replace("/\[map\]/", '<div class="map"></div>', $text); $text = preg_replace("/\[map\]/", '<p class="map"></p>', $text);
} }
// Check for headers // Check for headers

View file

@ -199,12 +199,13 @@ class DBStructure
* *
* @param bool $verbose * @param bool $verbose
* @param bool $action Whether to actually apply the update * @param bool $action Whether to actually apply the update
* @param bool $install Is this the initial update during the installation?
* @param array $tables An array of the database tables * @param array $tables An array of the database tables
* @param array $definition An array of the definition tables * @param array $definition An array of the definition tables
* @return string Empty string if the update is successful, error messages otherwise * @return string Empty string if the update is successful, error messages otherwise
*/ */
public static function update($verbose, $action, array $tables = null, array $definition = null) { public static function update($verbose, $action, $install = false, array $tables = null, array $definition = null) {
if ($action) { if ($action && !$install) {
Config::set('system', 'maintenance', 1); Config::set('system', 'maintenance', 1);
Config::set('system', 'maintenance_reason', L10n::t(': Database update', DBM::date().' '.date('e'))); Config::set('system', 'maintenance_reason', L10n::t(': Database update', DBM::date().' '.date('e')));
} }
@ -455,7 +456,9 @@ class DBStructure
} }
if ($action) { if ($action) {
if (!$install) {
Config::set('system', 'maintenance_reason', L10n::t('%s: updating %s table.', DBM::date().' '.date('e'), $name)); Config::set('system', 'maintenance_reason', L10n::t('%s: updating %s table.', DBM::date().' '.date('e'), $name));
}
// Ensure index conversion to unique removes duplicates // Ensure index conversion to unique removes duplicates
if ($is_unique && ($temp_name != $name)) { if ($is_unique && ($temp_name != $name)) {
@ -505,16 +508,16 @@ class DBStructure
} }
} }
if ($action) { if ($action && !$install) {
Config::set('system', 'maintenance', 0); Config::set('system', 'maintenance', 0);
Config::set('system', 'maintenance_reason', ''); Config::set('system', 'maintenance_reason', '');
}
if ($errors) { if ($errors) {
Config::set('system', 'dbupdate', DB_UPDATE_FAILED); Config::set('system', 'dbupdate', DB_UPDATE_FAILED);
} else { } else {
Config::set('system', 'dbupdate', DB_UPDATE_SUCCESSFUL); Config::set('system', 'dbupdate', DB_UPDATE_SUCCESSFUL);
} }
}
return $errors; return $errors;
} }

View file

@ -514,7 +514,7 @@ class Contact extends BaseObject
} }
$sparkle = false; $sparkle = false;
if ($contact['network'] === NETWORK_DFRN) { if (($contact['network'] === NETWORK_DFRN) && !$contact['self']) {
$sparkle = true; $sparkle = true;
$profile_link = System::baseUrl() . '/redir/' . $contact['id']; $profile_link = System::baseUrl() . '/redir/' . $contact['id'];
} else { } else {
@ -531,18 +531,21 @@ class Contact extends BaseObject
$profile_link = $profile_link . '?url=profile'; $profile_link = $profile_link . '?url=profile';
} }
if (in_array($contact['network'], [NETWORK_DFRN, NETWORK_DIASPORA])) { if (in_array($contact['network'], [NETWORK_DFRN, NETWORK_DIASPORA]) && !$contact['self']) {
$pm_url = System::baseUrl() . '/message/new/' . $contact['id']; $pm_url = System::baseUrl() . '/message/new/' . $contact['id'];
} }
if ($contact['network'] == NETWORK_DFRN) { if (($contact['network'] == NETWORK_DFRN) && !$contact['self']) {
$poke_link = System::baseUrl() . '/poke/?f=&c=' . $contact['id']; $poke_link = System::baseUrl() . '/poke/?f=&c=' . $contact['id'];
} }
$contact_url = System::baseUrl() . '/contacts/' . $contact['id']; $contact_url = System::baseUrl() . '/contacts/' . $contact['id'];
$posts_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/posts'; $posts_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/posts';
if (!$contact['self']) {
$contact_drop_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/drop?confirm=1'; $contact_drop_link = System::baseUrl() . '/contacts/' . $contact['id'] . '/drop?confirm=1';
}
/** /**
* Menu array: * Menu array:

View file

@ -37,7 +37,10 @@ class GContact
*/ */
public static function searchByName($search, $mode = '') public static function searchByName($search, $mode = '')
{ {
if ($search) { if (empty($search)) {
return [];
}
// check supported networks // check supported networks
if (Config::get('system', 'diaspora_enabled')) { if (Config::get('system', 'diaspora_enabled')) {
$diaspora = NETWORK_DIASPORA; $diaspora = NETWORK_DIASPORA;
@ -60,33 +63,27 @@ class GContact
$search .= "%"; $search .= "%";
$results = q( $results = dba::p("SELECT `nurl` FROM `gcontact`
"SELECT `contact`.`id` AS `cid`, `gcontact`.`url`, `gcontact`.`name`, `gcontact`.`nick`, `gcontact`.`photo`, WHERE NOT `hide` AND `network` IN (?, ?, ?) AND
`gcontact`.`network`, `gcontact`.`keywords`, `gcontact`.`addr`, `gcontact`.`community` ((`last_contact` >= `last_failure`) OR (`updated` >= `last_failure`)) AND
FROM `gcontact` (`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?) $extra_sql
LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` GROUP BY `nurl` ORDER BY `nurl` DESC LIMIT 1000",
AND `contact`.`uid` = %d AND NOT `contact`.`blocked` NETWORK_DFRN, $ostatus, $diaspora, $search, $search, $search
AND NOT `contact`.`pending` AND `contact`.`rel` IN ('%s', '%s')
WHERE (`contact`.`id` > 0 OR (NOT `gcontact`.`hide` AND `gcontact`.`network` IN ('%s', '%s', '%s') AND
((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR
(`gcontact`.`updated` >= `gcontact`.`last_failure`)))) AND
(`gcontact`.`addr` LIKE '%s' OR `gcontact`.`name` LIKE '%s' OR `gcontact`.`nick` LIKE '%s') $extra_sql
GROUP BY `gcontact`.`nurl`
ORDER BY `gcontact`.`nurl` DESC
LIMIT 1000",
intval(local_user()),
dbesc(CONTACT_IS_SHARING),
dbesc(CONTACT_IS_FRIEND),
dbesc(NETWORK_DFRN),
dbesc($ostatus),
dbesc($diaspora),
dbesc(escape_tags($search)),
dbesc(escape_tags($search)),
dbesc(escape_tags($search))
); );
return $results; $gcontacts = [];
while ($result = dba::fetch($results)) {
$urlparts = parse_url($result["nurl"]);
// Ignore results that look strange.
// For historic reasons the gcontact table does contain some garbage.
if (!empty($urlparts['query']) || !empty($urlparts['fragment'])) {
continue;
} }
$gcontacts[] = Contact::getDetailsByURL($result["nurl"], local_user());
}
return $gcontacts;
} }
/** /**

View file

@ -356,6 +356,10 @@ class Item extends BaseObject
} }
} }
if (!empty($item['thr-parent'])) {
$item['parent-uri'] = $item['thr-parent'];
}
if (x($item, 'gravity')) { if (x($item, 'gravity')) {
$item['gravity'] = intval($item['gravity']); $item['gravity'] = intval($item['gravity']);
} elseif ($item['parent-uri'] === $item['uri']) { } elseif ($item['parent-uri'] === $item['uri']) {

View file

@ -2079,8 +2079,8 @@ class DFRN
return false; return false;
} }
$fields = ['title' => $item["title"], 'body' => $item["body"], $fields = ['title' => defaults($item, 'title', ''), 'body' => defaults($item, 'body', ''),
'tag' => $item["tag"], 'changed' => DateTimeFormat::utcNow(), 'tag' => defaults($item, 'tag', ''), 'changed' => DateTimeFormat::utcNow(),
'edited' => DateTimeFormat::utc($item["edited"])]; 'edited' => DateTimeFormat::utc($item["edited"])];
$condition = ["`uri` = ? AND `uid` IN (0, ?)", $item["uri"], $importer["importer_uid"]]; $condition = ["`uri` = ? AND `uid` IN (0, ?)", $item["uri"], $importer["importer_uid"]];

View file

@ -29,6 +29,7 @@ use Friendica\Util\Crypto;
use Friendica\Util\DateTimeFormat; use Friendica\Util\DateTimeFormat;
use Friendica\Util\Network; use Friendica\Util\Network;
use Friendica\Util\XML; use Friendica\Util\XML;
use Friendica\Util\Map;
use dba; use dba;
use SimpleXMLElement; use SimpleXMLElement;
@ -3217,13 +3218,14 @@ class Diaspora
} }
$logid = random_string(4); $logid = random_string(4);
$dest_url = ($public_batch ? $contact["batch"] : $contact["notify"]);
// Fetch the fcontact entry when there is missing data // We always try to use the data from the fcontact table.
// Will possibly happen when data is transmitted to a DFRN contact // This is important for transmitting data to Friendica servers.
if (empty($dest_url) && !empty($contact['addr'])) { if (!empty($contact['addr'])) {
$fcontact = self::personByHandle($contact['addr']); $fcontact = self::personByHandle($contact['addr']);
$dest_url = ($public_batch ? $fcontact["batch"] : $fcontact["notify"]); $dest_url = ($public_batch ? $fcontact["batch"] : $fcontact["notify"]);
} else {
$dest_url = ($public_batch ? $contact["batch"] : $contact["notify"]);
} }
if (!$dest_url) { if (!$dest_url) {
@ -3617,10 +3619,18 @@ class Diaspora
$eventdata['description'] = html_entity_decode(bb2diaspora($event['desc'])); $eventdata['description'] = html_entity_decode(bb2diaspora($event['desc']));
} }
if ($event['location']) { if ($event['location']) {
$event['location'] = preg_replace("/\[map\](.*?)\[\/map\]/ism", '$1', $event['location']);
$coord = Map::getCoordinates($event['location']);
$location = []; $location = [];
$location["address"] = html_entity_decode(bb2diaspora($event['location'])); $location["address"] = html_entity_decode(bb2diaspora($event['location']));
if (!empty($coord['lat']) && !empty($coord['lon'])) {
$location["lat"] = $coord['lat'];
$location["lng"] = $coord['lon'];
} else {
$location["lat"] = 0; $location["lat"] = 0;
$location["lng"] = 0; $location["lng"] = 0;
}
$eventdata['location'] = $location; $eventdata['location'] = $location;
} }
@ -3714,7 +3724,13 @@ class Diaspora
if (count($event)) { if (count($event)) {
$message['event'] = $event; $message['event'] = $event;
/// @todo Once Diaspora supports it, we will remove the body if (!empty($event['location']['address']) &&
!empty($event['location']['lat']) &&
!empty($event['location']['lng'])) {
$message['location'] = $event['location'];
}
/// @todo Once Diaspora supports it, we will remove the body and the location hack above
// $message['text'] = ''; // $message['text'] = '';
} }
} }

View file

@ -1288,6 +1288,13 @@ class OStatus
"rel" => "self", "type" => "application/atom+xml"]; "rel" => "self", "type" => "application/atom+xml"];
XML::addElement($doc, $root, "link", "", $attributes); XML::addElement($doc, $root, "link", "", $attributes);
if ($owner['account-type'] == ACCOUNT_TYPE_COMMUNITY) {
$condition = ['uid' => $owner['uid'], 'self' => false, 'pending' => false,
'archive' => false, 'hidden' => false, 'blocked' => false];
$members = dba::count('contact', $condition);
XML::addElement($doc, $root, "statusnet:group_info", "", ["member_count" => $members]);
}
return $root; return $root;
} }
@ -1379,16 +1386,22 @@ class OStatus
* *
* @return object author element * @return object author element
*/ */
private static function addAuthor($doc, $owner) private static function addAuthor($doc, $owner, $show_profile = true)
{ {
$profile = dba::selectFirst('profile', ['homepage', 'publish'], ['uid' => $owner['uid'], 'is-default' => true]); $profile = dba::selectFirst('profile', ['homepage', 'publish'], ['uid' => $owner['uid'], 'is-default' => true]);
$author = $doc->createElement("author"); $author = $doc->createElement("author");
XML::addElement($doc, $author, "id", $owner["url"]); XML::addElement($doc, $author, "id", $owner["url"]);
if ($owner['account-type'] == ACCOUNT_TYPE_COMMUNITY) {
XML::addElement($doc, $author, "activity:object-type", ACTIVITY_OBJ_GROUP);
} else {
XML::addElement($doc, $author, "activity:object-type", ACTIVITY_OBJ_PERSON); XML::addElement($doc, $author, "activity:object-type", ACTIVITY_OBJ_PERSON);
}
XML::addElement($doc, $author, "uri", $owner["url"]); XML::addElement($doc, $author, "uri", $owner["url"]);
XML::addElement($doc, $author, "name", $owner["nick"]); XML::addElement($doc, $author, "name", $owner["nick"]);
XML::addElement($doc, $author, "email", $owner["addr"]); XML::addElement($doc, $author, "email", $owner["addr"]);
if ($show_profile) {
XML::addElement($doc, $author, "summary", BBCode::convert($owner["about"], false, 7)); XML::addElement($doc, $author, "summary", BBCode::convert($owner["about"], false, 7));
}
$attributes = ["rel" => "alternate", "type" => "text/html", "href" => $owner["url"]]; $attributes = ["rel" => "alternate", "type" => "text/html", "href" => $owner["url"]];
XML::addElement($doc, $author, "link", "", $attributes); XML::addElement($doc, $author, "link", "", $attributes);
@ -1413,6 +1426,7 @@ class OStatus
XML::addElement($doc, $author, "poco:preferredUsername", $owner["nick"]); XML::addElement($doc, $author, "poco:preferredUsername", $owner["nick"]);
XML::addElement($doc, $author, "poco:displayName", $owner["name"]); XML::addElement($doc, $author, "poco:displayName", $owner["name"]);
if ($show_profile) {
XML::addElement($doc, $author, "poco:note", BBCode::convert($owner["about"], false, 7)); XML::addElement($doc, $author, "poco:note", BBCode::convert($owner["about"], false, 7));
if (trim($owner["location"]) != "") { if (trim($owner["location"]) != "") {
@ -1420,8 +1434,9 @@ class OStatus
XML::addElement($doc, $element, "poco:formatted", $owner["location"]); XML::addElement($doc, $element, "poco:formatted", $owner["location"]);
$author->appendChild($element); $author->appendChild($element);
} }
}
if (DBM::is_result($profile)) { if (DBM::is_result($profile) && !$show_profile) {
if (trim($profile["homepage"]) != "") { if (trim($profile["homepage"]) != "") {
$urls = $doc->createElement("poco:urls"); $urls = $doc->createElement("poco:urls");
XML::addElement($doc, $urls, "poco:type", "homepage"); XML::addElement($doc, $urls, "poco:type", "homepage");
@ -1432,11 +1447,12 @@ class OStatus
XML::addElement($doc, $author, "followers", "", ["url" => System::baseUrl()."/viewcontacts/".$owner["nick"]]); XML::addElement($doc, $author, "followers", "", ["url" => System::baseUrl()."/viewcontacts/".$owner["nick"]]);
XML::addElement($doc, $author, "statusnet:profile_info", "", ["local_id" => $owner["uid"]]); XML::addElement($doc, $author, "statusnet:profile_info", "", ["local_id" => $owner["uid"]]);
}
if ($profile["publish"]) { if ($profile["publish"]) {
XML::addElement($doc, $author, "mastodon:scope", "public"); XML::addElement($doc, $author, "mastodon:scope", "public");
} }
}
return $author; return $author;
} }
@ -1598,7 +1614,7 @@ class OStatus
logger("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.", LOGGER_DEBUG); logger("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.", LOGGER_DEBUG);
} }
$title = self::entryHeader($doc, $entry, $owner, $toplevel); $title = self::entryHeader($doc, $entry, $owner, $item, $toplevel);
$r = q( $r = q(
"SELECT * FROM `item` WHERE `uid` = %d AND `guid` = '%s' AND NOT `private` AND `network` IN ('%s', '%s', '%s') LIMIT 1", "SELECT * FROM `item` WHERE `uid` = %d AND `guid` = '%s' AND NOT `private` AND `network` IN ('%s', '%s', '%s') LIMIT 1",
@ -1627,7 +1643,7 @@ class OStatus
self::entryContent($doc, $as_object, $repeated_item, $owner, "", "", false); self::entryContent($doc, $as_object, $repeated_item, $owner, "", "", false);
$author = self::addAuthor($doc, $contact); $author = self::addAuthor($doc, $contact, false);
$as_object->appendChild($author); $as_object->appendChild($author);
$as_object2 = $doc->createElement("activity:object"); $as_object2 = $doc->createElement("activity:object");
@ -1669,7 +1685,7 @@ class OStatus
logger("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.", LOGGER_DEBUG); logger("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.", LOGGER_DEBUG);
} }
$title = self::entryHeader($doc, $entry, $owner, $toplevel); $title = self::entryHeader($doc, $entry, $owner, $item, $toplevel);
$verb = NAMESPACE_ACTIVITY_SCHEMA."favorite"; $verb = NAMESPACE_ACTIVITY_SCHEMA."favorite";
self::entryContent($doc, $entry, $item, $owner, "Favorite", $verb, false); self::entryContent($doc, $entry, $item, $owner, "Favorite", $verb, false);
@ -1792,7 +1808,7 @@ class OStatus
$item["body"] = sprintf($message, $owner["nick"], $contact["nick"]); $item["body"] = sprintf($message, $owner["nick"], $contact["nick"]);
self::entryHeader($doc, $entry, $owner, $toplevel); self::entryHeader($doc, $entry, $owner, $item, $toplevel);
self::entryContent($doc, $entry, $item, $owner, $title); self::entryContent($doc, $entry, $item, $owner, $title);
@ -1820,7 +1836,7 @@ class OStatus
logger("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.", LOGGER_DEBUG); logger("OStatus entry is from author ".$owner["url"]." - not from ".$item["author-link"].". Quitting.", LOGGER_DEBUG);
} }
$title = self::entryHeader($doc, $entry, $owner, $toplevel); $title = self::entryHeader($doc, $entry, $owner, $item, $toplevel);
XML::addElement($doc, $entry, "activity:object-type", ACTIVITY_OBJ_NOTE); XML::addElement($doc, $entry, "activity:object-type", ACTIVITY_OBJ_NOTE);
@ -1841,12 +1857,18 @@ class OStatus
* *
* @return string The title for the element * @return string The title for the element
*/ */
private static function entryHeader($doc, &$entry, $owner, $toplevel) private static function entryHeader($doc, &$entry, $owner, $item, $toplevel)
{ {
/// @todo Check if this title stuff is really needed (I guess not) /// @todo Check if this title stuff is really needed (I guess not)
if (!$toplevel) { if (!$toplevel) {
$entry = $doc->createElement("entry"); $entry = $doc->createElement("entry");
$title = sprintf("New note by %s", $owner["nick"]); $title = sprintf("New note by %s", $owner["nick"]);
if ($owner['account-type'] == ACCOUNT_TYPE_COMMUNITY) {
$contact = self::contactEntry($item['author-link'], $owner);
$author = self::addAuthor($doc, $contact, false);
$entry->appendChild($author);
}
} else { } else {
$entry = $doc->createElementNS(NAMESPACE_ATOM1, "entry"); $entry = $doc->createElementNS(NAMESPACE_ATOM1, "entry");
@ -2001,12 +2023,10 @@ class OStatus
$mentioned = $newmentions; $mentioned = $newmentions;
foreach ($mentioned as $mention) { foreach ($mentioned as $mention) {
$r = q( $condition = ['uid' => $owner['uid'], 'nurl' => normalise_link($mention)];
"SELECT `forum`, `prv` FROM `contact` WHERE `uid` = %d AND `nurl` = '%s'", $contact = dba::selectFirst('contact', ['forum', 'prv', 'self', 'contact-type'], $condition);
intval($owner["uid"]), if ($contact["forum"] || $contact["prv"] || ($owner['contact-type'] == ACCOUNT_TYPE_COMMUNITY) ||
dbesc(normalise_link($mention)) ($contact['self'] && ($owner['account-type'] == ACCOUNT_TYPE_COMMUNITY))) {
);
if ($r[0]["forum"] || $r[0]["prv"]) {
XML::addElement($doc, $entry, "link", "", XML::addElement($doc, $entry, "link", "",
[ [
"rel" => "mentioned", "rel" => "mentioned",
@ -2023,6 +2043,12 @@ class OStatus
} }
} }
if ($owner['account-type'] == ACCOUNT_TYPE_COMMUNITY) {
XML::addElement($doc, $entry, "link", "", ["rel" => "mentioned",
"ostatus:object-type" => "http://activitystrea.ms/schema/1.0/group",
"href" => $owner['url']]);
}
if (!$item["private"]) { if (!$item["private"]) {
XML::addElement($doc, $entry, "link", "", ["rel" => "ostatus:attention", XML::addElement($doc, $entry, "link", "", ["rel" => "ostatus:attention",
"href" => "http://activityschema.org/collection/public"]); "href" => "http://activityschema.org/collection/public"]);

View file

@ -945,6 +945,15 @@ class PortableContact
$register_policy = $gserver["register_policy"]; $register_policy = $gserver["register_policy"];
$registered_users = $gserver["registered-users"]; $registered_users = $gserver["registered-users"];
// See discussion under https://forum.friendi.ca/display/0b6b25a8135aabc37a5a0f5684081633
// It can happen that a zero date is in the database, but storing it again is forbidden.
if ($last_contact < NULL_DATE) {
$last_contact = NULL_DATE;
}
if ($last_failure < NULL_DATE) {
$last_failure = NULL_DATE;
}
if (!$force && !self::updateNeeded($gserver["created"], "", $last_failure, $last_contact)) { if (!$force && !self::updateNeeded($gserver["created"], "", $last_failure, $last_contact)) {
logger("Use cached data for server ".$server_url, LOGGER_DEBUG); logger("Use cached data for server ".$server_url, LOGGER_DEBUG);
return ($last_contact >= $last_failure); return ($last_contact >= $last_failure);
@ -1302,7 +1311,7 @@ class PortableContact
if (isset($data->version)) { if (isset($data->version)) {
$network = NETWORK_DFRN; $network = NETWORK_DFRN;
$noscrape = $data->no_scrape_url; $noscrape = defaults($data->no_scrape_url, '');
$version = $data->version; $version = $data->version;
$site_name = $data->site_name; $site_name = $data->site_name;
$info = $data->info; $info = $data->info;

View file

@ -10,17 +10,23 @@ use Friendica\Core\Addon;
* Leaflet Map related functions * Leaflet Map related functions
*/ */
class Map { class Map {
public static function byCoordinates($coord) { public static function byCoordinates($coord, $html_mode = 0) {
$coord = trim($coord); $coord = trim($coord);
$coord = str_replace([',','/',' '],[' ',' ',' '],$coord); $coord = str_replace([',','/',' '],[' ',' ',' '],$coord);
$arr = ['lat' => trim(substr($coord,0,strpos($coord,' '))), 'lon' => trim(substr($coord,strpos($coord,' ')+1)), 'html' => '']; $arr = ['lat' => trim(substr($coord,0,strpos($coord,' '))), 'lon' => trim(substr($coord,strpos($coord,' ')+1)), 'mode' => $html_mode, 'html' => ''];
Addon::callHooks('generate_map',$arr); Addon::callHooks('generate_map',$arr);
return ($arr['html']) ? $arr['html'] : $coord; return ($arr['html']) ? $arr['html'] : $coord;
} }
public static function byLocation($location) { public static function byLocation($location, $html_mode = 0) {
$arr = ['location' => $location, 'html' => '']; $arr = ['location' => $location, 'mode' => $html_mode, 'html' => ''];
Addon::callHooks('generate_named_map',$arr); Addon::callHooks('generate_named_map',$arr);
return ($arr['html']) ? $arr['html'] : $location; return ($arr['html']) ? $arr['html'] : $location;
} }
public static function getCoordinates($location) {
$arr = ['location' => $location, 'lat' => false, 'lon' => false];
Addon::callHooks('Map::getCoordinates', $arr);
return $arr;
}
} }

View file

@ -17,6 +17,7 @@ André Alves
André Lohan André Lohan
Andy H3 Andy H3
Andy Hee Andy Hee
AndyHee
Anthronaut Anthronaut
Arian - Cazare Muncitori Arian - Cazare Muncitori
Athalbert Athalbert
@ -75,6 +76,7 @@ Frederico Gonçalves Guimarães
Gerhard Seeber Gerhard Seeber
gerhard6380 gerhard6380
Gert Cauwenberg Gert Cauwenberg
GLComo
greeneyedred greeneyedred
Gregory Smith Gregory Smith
Haakon Meland Eriksen Haakon Meland Eriksen
@ -91,7 +93,6 @@ Jak
Jakob Jakob
Jens Tautenhahn Jens Tautenhahn
jensp jensp
Jeroen S
jeroenpraat jeroenpraat
Johannes Schwab Johannes Schwab
John Brazil John Brazil
@ -169,6 +170,7 @@ Silke Meyer
Simon L'nu Simon L'nu
Simó Albert i Beltran Simó Albert i Beltran
soko1 soko1
St John Karp
Stanislav N. Stanislav N.
StefOfficiel StefOfficiel
Sveinn í Felli Sveinn í Felli
@ -207,3 +209,4 @@ zotlabs
zottel zottel
Zvi ben Yaakov (a.k.a rdc) Zvi ben Yaakov (a.k.a rdc)
Михаил Михаил
朱陈锬

View file

@ -39,7 +39,7 @@ msgstr ""
"Project-Id-Version: friendica\n" "Project-Id-Version: friendica\n"
"Report-Msgid-Bugs-To: \n" "Report-Msgid-Bugs-To: \n"
"POT-Creation-Date: 2018-03-05 16:37+0100\n" "POT-Creation-Date: 2018-03-05 16:37+0100\n"
"PO-Revision-Date: 2018-03-07 16:22+0000\n" "PO-Revision-Date: 2018-03-19 17:22+0000\n"
"Last-Translator: Tobias Diekershoff <tobias.diekershoff@gmx.net>\n" "Last-Translator: Tobias Diekershoff <tobias.diekershoff@gmx.net>\n"
"Language-Team: German (http://www.transifex.com/Friendica/friendica/language/de/)\n" "Language-Team: German (http://www.transifex.com/Friendica/friendica/language/de/)\n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
@ -5459,7 +5459,7 @@ msgid ""
"Search the local directory instead of the global directory. When searching " "Search the local directory instead of the global directory. When searching "
"locally, every search will be executed on the global directory in the " "locally, every search will be executed on the global directory in the "
"background. This improves the search results when the search is repeated." "background. This improves the search results when the search is repeated."
msgstr "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." msgstr "Suche im lokalen Verzeichnis anstelle des globalen Verzeichnisses durchführen. Jede Suche wird im Hintergrund auch im globalen Verzeichnis durchgeführt um die Suchresultate zu verbessern, wenn diese Suche wiederholt wird."
#: mod/admin.php:1338 #: mod/admin.php:1338
msgid "Publish server information" msgid "Publish server information"

View file

@ -1220,7 +1220,7 @@ $a->strings["Periodically query other servers for contacts. You can choose betwe
$a->strings["Timeframe for fetching global contacts"] = "Zeitfenster für globale Kontakte"; $a->strings["Timeframe for fetching global contacts"] = "Zeitfenster für globale Kontakte";
$a->strings["When the discovery is activated, this value defines the timeframe for the activity of the global contacts that are fetched from other servers."] = "Wenn die Entdeckung neuer Kontakte aktiv ist, definiert dieses Zeitfenster den Zeitraum in dem globale Kontakte als aktiv gelten und von anderen Servern importiert werden."; $a->strings["When the discovery is activated, this value defines the timeframe for the activity of the global contacts that are fetched from other servers."] = "Wenn die Entdeckung neuer Kontakte aktiv ist, definiert dieses Zeitfenster den Zeitraum in dem globale Kontakte als aktiv gelten und von anderen Servern importiert werden.";
$a->strings["Search the local directory"] = "Lokales Verzeichnis durchsuchen"; $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["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 um die Suchresultate zu verbessern, wenn diese Suche wiederholt wird.";
$a->strings["Publish server information"] = "Server Informationen veröffentlichen"; $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 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["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["Check upstream version"] = "Suche nach Updates"; $a->strings["Check upstream version"] = "Suche nach Updates";

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -85,7 +85,7 @@ $a->config['system']['rino_encrypt'] = {{$rino}};
// default system theme // default system theme
$a->config['system']['theme'] = 'vier'; $a->config['system']['theme'] = 'vier';
$a->config['system']['allowed_themes'] = 'vier,quattro,duepuntozero,smoothly'; $a->config['system']['allowed_themes'] = 'vier,quattro,duepuntozero,smoothly,frio';
// By default allow pseudonyms // By default allow pseudonyms

View file

@ -32,7 +32,7 @@ function get_schema_info($schema){
'description' => "", 'description' => "",
'author' => [], 'author' => [],
'version' => "", 'version' => "",
'overwrites' => "" 'overwrites' => []
]; ];
if (!is_file($themepath . "schema/" . $schema . ".php")) return $info; if (!is_file($themepath . "schema/" . $schema . ".php")) return $info;

View file

@ -18,32 +18,22 @@ if (empty($style)) {
$style = "plus"; $style = "plus";
} }
if ($style == "flat") { $stylecss = '';
$stylecssfile = 'view/theme/vier/flat.css'; $modified = '';
} else if ($style == "netcolour") {
$stylecssfile = 'view/theme/vier/netcolour.css';
} else if ($style == "breathe") {
$stylecssfile = 'view/theme/vier/breathe.css';
} else if ($style == "plus") {
$stylecssfile = 'view/theme/vier/plus.css';
} else if ($style == "dark") {
$stylecssfile = 'view/theme/vier/dark.css';
} else if ($style == "plusminus") {
$stylecssfile = 'view/theme/vier/plusminus.css';
}
if (file_exists($THEMEPATH."//style.css")) { foreach (['style', $style] as $file) {
$stylecss = file_get_contents($THEMEPATH."//style.css")."\n"; $stylecssfile = $THEMEPATH . DIRECTORY_SEPARATOR . $file .'.css';
$modified = filemtime($THEMEPATH."//style.css"); if (file_exists($stylecssfile)) {
}
$stylemodified = filemtime($stylecssfile);
$stylecss .= file_get_contents($stylecssfile); $stylecss .= file_get_contents($stylecssfile);
$stylemodified = filemtime($stylecssfile);
if ($stylemodified > $modified) { if ($stylemodified > $modified) {
$modified = $stylemodified; $modified = $stylemodified;
} }
} else {
//TODO: use LOGGER_ERROR?
logger('Error: missing file: "' . $stylecssfile .'" (userid: '. $uid .')');
}
}
$modified = gmdate('r', $modified); $modified = gmdate('r', $modified);
$etag = md5($stylecss); $etag = md5($stylecss);
@ -54,7 +44,6 @@ header('ETag: "'.$etag.'"');
header('Last-Modified: '.$modified); header('Last-Modified: '.$modified);
if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) { if (isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) || isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
$cached_modified = gmdate('r', strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE'])); $cached_modified = gmdate('r', strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']));
$cached_etag = str_replace(['"', "-gzip"], ['', ''], $cached_etag = str_replace(['"', "-gzip"], ['', ''],
stripslashes($_SERVER['HTTP_IF_NONE_MATCH'])); stripslashes($_SERVER['HTTP_IF_NONE_MATCH']));