X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FProtocol%2FPortableContact.php;h=7900ff540bfda7672d76416a6acba139c6b8d676;hb=1eb607b351bf5a63711745adc6e2e74f500cc1bb;hp=9c22a216319ff3d5095bb3dc2df9e95e58edd22c;hpb=8821d33f73785884cfce83e7b23d3ef19cc1bc11;p=friendica.git diff --git a/src/Protocol/PortableContact.php b/src/Protocol/PortableContact.php index 9c22a21631..7900ff540b 100644 --- a/src/Protocol/PortableContact.php +++ b/src/Protocol/PortableContact.php @@ -20,15 +20,20 @@ use Friendica\Core\Worker; use Friendica\Database\DBA; use Friendica\Model\GContact; use Friendica\Model\Profile; +use Friendica\Module\Register; use Friendica\Network\Probe; use Friendica\Util\DateTimeFormat; use Friendica\Util\Network; +use Friendica\Util\Strings; use Friendica\Util\XML; -require_once 'include/dba.php'; - class PortableContact { + const DISABLED = 0; + const USERS = 1; + const USERS_GCONTACTS = 2; + const USERS_GCONTACTS_FALLBACK = 3; + /** * @brief Fetch POCO data * @@ -45,7 +50,7 @@ class PortableContact * Once the global contact is stored add (if necessary) the contact linkage which associates * the given uid, cid to the global contact entry. There can be many uid/cid combinations * pointing to the same global contact id. - * + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function loadWorker($cid, $uid = 0, $zcid = 0, $url = null) { @@ -60,12 +65,10 @@ class PortableContact * @param integer $uid User ID * @param integer $zcid Global Contact ID * @param integer $url POCO address that should be polled - * + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ public static function load($cid, $uid, $zcid, $url) { - $a = get_app(); - if ($cid) { if (!$url || !$uid) { $contact = DBA::selectFirst('contact', ['poco', 'uid'], ['id' => $cid]); @@ -83,7 +86,7 @@ class PortableContact return; } - $url = $url . (($uid) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation') ; + $url = $url . (($uid) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation'); Logger::log('load: ' . $url, Logger::DEBUG); @@ -231,7 +234,6 @@ class PortableContact $friendica = preg_replace("=(https?://)(.*)/profile/(.*)=ism", "$1$2", $profile); if ($friendica != $profile) { $server_url = $friendica; - $network = Protocol::DFRN; } } @@ -239,7 +241,6 @@ class PortableContact $diaspora = preg_replace("=(https?://)(.*)/u/(.*)=ism", "$1$2", $profile); if ($diaspora != $profile) { $server_url = $diaspora; - $network = Protocol::DIASPORA; } } @@ -247,7 +248,6 @@ class PortableContact $red = preg_replace("=(https?://)(.*)/channel/(.*)=ism", "$1$2", $profile); if ($red != $profile) { $server_url = $red; - $network = Protocol::DIASPORA; } } @@ -256,7 +256,6 @@ class PortableContact $mastodon = preg_replace("=(https?://)(.*)/users/(.*)=ism", "$1$2", $profile); if ($mastodon != $profile) { $server_url = $mastodon; - $network = Protocol::OSTATUS; } } @@ -265,7 +264,6 @@ class PortableContact $ostatus = preg_replace("=(https?://)(.*)/user/(.*)=ism", "$1$2", $profile); if ($ostatus != $profile) { $server_url = $ostatus; - $network = Protocol::OSTATUS; } } @@ -274,7 +272,6 @@ class PortableContact $base = preg_replace("=(https?://)(.*?)/(.*)=ism", "$1$2", $profile); if ($base != $profile) { $server_url = $base; - $network = Protocol::PHANTOM; } } @@ -284,7 +281,7 @@ class PortableContact $r = q( "SELECT `id` FROM `gserver` WHERE `nurl` = '%s' AND `last_contact` > `last_failure`", - DBA::escape(normalise_link($server_url)) + DBA::escape(Strings::normaliseLink($server_url)) ); if (DBA::isResult($r)) { @@ -309,7 +306,7 @@ class PortableContact { $gcontacts = q( "SELECT * FROM `gcontact` WHERE `nurl` = '%s'", - DBA::escape(normalise_link($profile)) + DBA::escape(Strings::normaliseLink($profile)) ); if (!DBA::isResult($gcontacts)) { @@ -324,7 +321,7 @@ class PortableContact $server_url = ''; if ($force) { - $server_url = normalise_link(self::detectServer($profile)); + $server_url = Strings::normaliseLink(self::detectServer($profile)); } if (($server_url == '') && ($gcontacts[0]["server_url"] != "")) { @@ -332,10 +329,10 @@ class PortableContact } if (!$force && (($server_url == '') || ($gcontacts[0]["server_url"] == $gcontacts[0]["nurl"]))) { - $server_url = normalise_link(self::detectServer($profile)); + $server_url = Strings::normaliseLink(self::detectServer($profile)); } - if (!in_array($gcontacts[0]["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::FEED, Protocol::OSTATUS, ""])) { + if (!in_array($gcontacts[0]["network"], [Protocol::DFRN, Protocol::DIASPORA, Protocol::FEED, Protocol::OSTATUS, ""])) { Logger::log("Profile ".$profile.": Network type ".$gcontacts[0]["network"]." can't be checked", Logger::DEBUG); return false; } @@ -344,7 +341,7 @@ class PortableContact if (!self::checkServer($server_url, $gcontacts[0]["network"], $force)) { if ($force) { $fields = ['last_failure' => DateTimeFormat::utcNow()]; - DBA::update('gcontact', $fields, ['nurl' => normalise_link($profile)]); + DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($profile)]); } Logger::log("Profile ".$profile.": Server ".$server_url." wasn't reachable.", Logger::DEBUG); @@ -356,7 +353,7 @@ class PortableContact if (in_array($gcontacts[0]["network"], ["", Protocol::FEED])) { $server = q( "SELECT `network` FROM `gserver` WHERE `nurl` = '%s' AND `network` != ''", - DBA::escape(normalise_link($server_url)) + DBA::escape(Strings::normaliseLink($server_url)) ); if ($server) { @@ -369,7 +366,7 @@ class PortableContact // noscrape is really fast so we don't cache the call. if (($server_url != "") && ($gcontacts[0]["nick"] != "")) { // Use noscrape if possible - $server = q("SELECT `noscrape`, `network` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != ''", DBA::escape(normalise_link($server_url))); + $server = q("SELECT `noscrape`, `network` FROM `gserver` WHERE `nurl` = '%s' AND `noscrape` != ''", DBA::escape(Strings::normaliseLink($server_url))); if ($server) { $curlResult = Network::curl($server[0]["noscrape"]."/".$gcontacts[0]["nick"]); @@ -425,7 +422,7 @@ class PortableContact if (!empty($noscrape["updated"])) { $fields = ['last_contact' => DateTimeFormat::utcNow()]; - DBA::update('gcontact', $fields, ['nurl' => normalise_link($profile)]); + DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($profile)]); Logger::log("Profile ".$profile." was last updated at ".$noscrape["updated"]." (noscrape)", Logger::DEBUG); @@ -449,11 +446,11 @@ class PortableContact // Is the profile link the alternate OStatus link notation? (http://domain.tld/user/4711) // Then check the other link and delete this one if (($data["network"] == Protocol::OSTATUS) && self::alternateOStatusUrl($profile) - && (normalise_link($profile) == normalise_link($data["alias"])) - && (normalise_link($profile) != normalise_link($data["url"])) + && (Strings::normaliseLink($profile) == Strings::normaliseLink($data["alias"])) + && (Strings::normaliseLink($profile) != Strings::normaliseLink($data["url"])) ) { // Delete the old entry - DBA::delete('gcontact', ['nurl' => normalise_link($profile)]); + DBA::delete('gcontact', ['nurl' => Strings::normaliseLink($profile)]); $gcontact = array_merge($gcontacts[0], $data); @@ -474,7 +471,7 @@ class PortableContact if (($data["poll"] == "") || (in_array($data["network"], [Protocol::FEED, Protocol::PHANTOM]))) { $fields = ['last_failure' => DateTimeFormat::utcNow()]; - DBA::update('gcontact', $fields, ['nurl' => normalise_link($profile)]); + DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($profile)]); Logger::log("Profile ".$profile." wasn't reachable (profile)", Logger::DEBUG); return false; @@ -490,7 +487,7 @@ class PortableContact if (!$curlResult->isSuccess()) { $fields = ['last_failure' => DateTimeFormat::utcNow()]; - DBA::update('gcontact', $fields, ['nurl' => normalise_link($profile)]); + DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($profile)]); Logger::log("Profile ".$profile." wasn't reachable (no feed)", Logger::DEBUG); return false; @@ -533,11 +530,11 @@ class PortableContact $fields['updated'] = $last_updated; } - DBA::update('gcontact', $fields, ['nurl' => normalise_link($profile)]); + DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($profile)]); if (($gcontacts[0]["generation"] == 0)) { $fields = ['generation' => 9]; - DBA::update('gcontact', $fields, ['nurl' => normalise_link($profile)]); + DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($profile)]); } Logger::log("Profile ".$profile." was last updated at ".$last_updated, Logger::DEBUG); @@ -610,8 +607,6 @@ class PortableContact */ private static function detectPocoData(array $data) { - $server = false; - if (!isset($data['entry'])) { return false; } @@ -644,6 +639,7 @@ class PortableContact * * @param string $server_url address of the server * @return array Server data + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function fetchNodeinfo($server_url) { @@ -697,6 +693,7 @@ class PortableContact * * @param string $nodeinfo_url address of the nodeinfo path * @return array Server data + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function parseNodeinfo1($nodeinfo_url) { @@ -714,10 +711,10 @@ class PortableContact $server = []; - $server['register_policy'] = REGISTER_CLOSED; + $server['register_policy'] = Register::CLOSED; if (is_bool($nodeinfo['openRegistrations']) && $nodeinfo['openRegistrations']) { - $server['register_policy'] = REGISTER_OPEN; + $server['register_policy'] = Register::OPEN; } if (is_array($nodeinfo['software'])) { @@ -733,7 +730,7 @@ class PortableContact } } - if (is_array($nodeinfo['metadata']) && isset($nodeinfo['metadata']['nodeName'])) { + if (isset($nodeinfo['metadata']['nodeName'])) { $server['site_name'] = $nodeinfo['metadata']['nodeName']; } @@ -781,6 +778,7 @@ class PortableContact * * @param string $nodeinfo_url address of the nodeinfo path * @return array Server data + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function parseNodeinfo2($nodeinfo_url) { @@ -797,10 +795,10 @@ class PortableContact $server = []; - $server['register_policy'] = REGISTER_CLOSED; + $server['register_policy'] = Register::CLOSED; if (is_bool($nodeinfo['openRegistrations']) && $nodeinfo['openRegistrations']) { - $server['register_policy'] = REGISTER_OPEN; + $server['register_policy'] = Register::OPEN; } if (is_array($nodeinfo['software'])) { @@ -816,7 +814,7 @@ class PortableContact } } - if (is_array($nodeinfo['metadata']) && isset($nodeinfo['metadata']['nodeName'])) { + if (isset($nodeinfo['metadata']['nodeName'])) { $server['site_name'] = $nodeinfo['metadata']['nodeName']; } @@ -930,11 +928,11 @@ class PortableContact return false; } - $gserver = DBA::selectFirst('gserver', [], ['nurl' => normalise_link($server_url)]); + $gserver = DBA::selectFirst('gserver', [], ['nurl' => Strings::normaliseLink($server_url)]); if (DBA::isResult($gserver)) { if ($gserver["created"] <= DBA::NULL_DATETIME) { $fields = ['created' => DateTimeFormat::utcNow()]; - $condition = ['nurl' => normalise_link($server_url)]; + $condition = ['nurl' => Strings::normaliseLink($server_url)]; DBA::update('gserver', $fields, $condition); } $poco = $gserver["poco"]; @@ -990,7 +988,7 @@ class PortableContact // Mastodon uses the "@" for user profiles. // But this can be misunderstood. if (parse_url($server_url, PHP_URL_USER) != '') { - DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => normalise_link($server_url)]); + DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => Strings::normaliseLink($server_url)]); return false; } @@ -1006,7 +1004,7 @@ class PortableContact if (DBA::isResult($gserver) && ($orig_server_url == $server_url) && ($curlResult->isTimeout())) { Logger::log("Connection to server ".$server_url." timed out.", Logger::DEBUG); - DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => normalise_link($server_url)]); + DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => Strings::normaliseLink($server_url)]); return false; } @@ -1021,7 +1019,7 @@ class PortableContact // Quit if there is a timeout if ($curlResult->isTimeout()) { Logger::log("Connection to server " . $server_url . " timed out.", Logger::DEBUG); - DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => normalise_link($server_url)]); + DBA::update('gserver', ['last_failure' => DateTimeFormat::utcNow()], ['nurl' => Strings::normaliseLink($server_url)]); return false; } @@ -1048,7 +1046,7 @@ class PortableContact if (!$failure) { // This will be too low, but better than no value at all. - $registered_users = DBA::count('gcontact', ['server_url' => normalise_link($server_url)]); + $registered_users = DBA::count('gcontact', ['server_url' => Strings::normaliseLink($server_url)]); } // Look for poco @@ -1200,16 +1198,16 @@ class PortableContact if (!empty($data['register_policy'])) { switch ($data['register_policy']) { case "REGISTER_OPEN": - $register_policy = REGISTER_OPEN; + $register_policy = Register::OPEN; break; case "REGISTER_APPROVE": - $register_policy = REGISTER_APPROVE; + $register_policy = Register::APPROVE; break; case "REGISTER_CLOSED": default: - $register_policy = REGISTER_CLOSED; + $register_policy = Register::CLOSED; break; } } @@ -1275,11 +1273,11 @@ class PortableContact } if (!$closed && !$private and $inviteonly) { - $register_policy = REGISTER_APPROVE; + $register_policy = Register::APPROVE; } elseif (!$closed && !$private) { - $register_policy = REGISTER_OPEN; + $register_policy = Register::OPEN; } else { - $register_policy = REGISTER_CLOSED; + $register_policy = Register::CLOSED; } } } @@ -1313,9 +1311,9 @@ class PortableContact } if (!empty($data['registrations_open']) && $data['registrations_open']) { - $register_policy = REGISTER_OPEN; + $register_policy = Register::OPEN; } else { - $register_policy = REGISTER_CLOSED; + $register_policy = Register::CLOSED; } } } @@ -1374,14 +1372,29 @@ class PortableContact $site_name = $data['site_name']; } - $info = $data['info']; - if (in_array($data['register_policy'], ['REGISTER_CLOSED', 'REGISTER_APPROVE', 'REGISTER_OPEN'])) { - $register_policy = constant($data['register_policy']); - } else { - Logger::log("Register policy '{$data['register_policy']}' from $server_url is invalid."); - $register_policy = REGISTER_CLOSED; // set a default value + $info = defaults($data, 'info', ''); + + $register_policy = defaults($data, 'register_policy', 'REGISTER_CLOSED'); + switch ($register_policy) { + case 'REGISTER_OPEN': + $register_policy = Register::OPEN; + break; + + case 'REGISTER_APPROVE': + $register_policy = Register::APPROVE; + break; + + default: + Logger::log("Register policy '$register_policy' from $server_url is invalid."); + // Defaulting to closed + + case 'REGISTER_CLOSED': + case 'REGISTER_INVITATION': + $register_policy = Register::CLOSED; + break; } - $platform = $data['platform']; + + $platform = defaults($data, 'platform', ''); } } } @@ -1410,7 +1423,7 @@ class PortableContact } // Check again if the server exists - $found = DBA::exists('gserver', ['nurl' => normalise_link($server_url)]); + $found = DBA::exists('gserver', ['nurl' => Strings::normaliseLink($server_url)]); $version = strip_tags($version); $site_name = strip_tags($site_name); @@ -1424,9 +1437,9 @@ class PortableContact 'last_contact' => $last_contact, 'last_failure' => $last_failure]; if ($found) { - DBA::update('gserver', $fields, ['nurl' => normalise_link($server_url)]); + DBA::update('gserver', $fields, ['nurl' => Strings::normaliseLink($server_url)]); } elseif (!$failure) { - $fields['nurl'] = normalise_link($server_url); + $fields['nurl'] = Strings::normaliseLink($server_url); $fields['created'] = DateTimeFormat::utcNow(); DBA::insert('gserver', $fields); } @@ -1444,6 +1457,7 @@ class PortableContact * @brief Fetch relay data from a given server url * * @param string $server_url address of the server + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function discoverRelay($server_url) { @@ -1461,7 +1475,7 @@ class PortableContact return; } - $gserver = DBA::selectFirst('gserver', ['id', 'relay-subscribe', 'relay-scope'], ['nurl' => normalise_link($server_url)]); + $gserver = DBA::selectFirst('gserver', ['id', 'relay-subscribe', 'relay-scope'], ['nurl' => Strings::normaliseLink($server_url)]); if (!DBA::isResult($gserver)) { return; @@ -1518,6 +1532,7 @@ class PortableContact /** * @brief Returns a list of all known servers * @return array List of server urls + * @throws Exception */ public static function serverlist() { @@ -1542,6 +1557,7 @@ class PortableContact * @brief Fetch server list from remote servers and adds them when they are new. * * @param string $poco URL to the POCO endpoint + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function fetchServerlist($poco) { @@ -1560,7 +1576,7 @@ class PortableContact foreach ($serverlist as $server) { $server_url = str_replace("/index.php", "", $server['url']); - $r = q("SELECT `nurl` FROM `gserver` WHERE `nurl` = '%s'", DBA::escape(normalise_link($server_url))); + $r = q("SELECT `nurl` FROM `gserver` WHERE `nurl` = '%s'", DBA::escape(Strings::normaliseLink($server_url))); if (!DBA::isResult($r)) { Logger::log("Call server check for server ".$server_url, Logger::DEBUG); @@ -1634,21 +1650,19 @@ class PortableContact public static function discoverSingleServer($id) { - $r = q("SELECT `poco`, `nurl`, `url`, `network` FROM `gserver` WHERE `id` = %d", intval($id)); + $server = DBA::selectFirst('gserver', ['poco', 'nurl', 'url', 'network'], ['id' => $id]); - if (!DBA::isResult($r)) { + if (!DBA::isResult($server)) { return false; } - $server = $r[0]; - // Discover new servers out there (Works from Friendica version 3.5.2) self::fetchServerlist($server["poco"]); // Fetch all users from the other server $url = $server["poco"] . "/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,gender,contactType,generation"; - Logger::log("Fetch all users from the server " . $server["url"], Logger::DEBUG); + Logger::info("Fetch all users from the server " . $server["url"]); $curlResult = Network::curl($url); @@ -1659,7 +1673,7 @@ class PortableContact self::discoverServer($data, 2); } - if (Config::get('system', 'poco_discovery') > 1) { + if (Config::get('system', 'poco_discovery') >= self::USERS_GCONTACTS) { $timeframe = Config::get('system', 'poco_discovery_since'); if ($timeframe == 0) { @@ -1676,7 +1690,7 @@ class PortableContact $curlResult = Network::curl($url); if ($curlResult->isSuccess() && !empty($curlResult->getBody())) { - Logger::log("Fetch all global contacts from the server " . $server["nurl"], Logger::DEBUG); + Logger::info("Fetch all global contacts from the server " . $server["nurl"]); $data = json_decode($curlResult->getBody(), true); if (!empty($data)) { @@ -1684,8 +1698,8 @@ class PortableContact } } - if (!$success && (Config::get('system', 'poco_discovery') > 2)) { - Logger::log("Fetch contacts from users of the server " . $server["nurl"], Logger::DEBUG); + if (!$success && !empty($data) && Config::get('system', 'poco_discovery') >= self::USERS_GCONTACTS_FALLBACK) { + Logger::info("Fetch contacts from users of the server " . $server["nurl"]); self::discoverServerUsers($data, $server); } } @@ -1776,7 +1790,7 @@ class PortableContact $curlResult = Network::curl($url); if ($curlResult->isSuccess()) { - $data = json_decode($curlResult["body"], true); + $data = json_decode($curlResult->getBody(), true); if (!empty($data)) { self::discoverServer($data, 3);