X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=src%2FModel%2FGContact.php;h=2caad945919f04e9fe7d19af279b6c34b0a02517;hb=e976bc0668f3bbd7518a5a0c37d9583688965683;hp=8c220a57aee45b1ba8b8620b98a61251d0cce2d1;hpb=98c12006d509f2ef4a98b06be04db7286c9da322;p=friendica.git diff --git a/src/Model/GContact.php b/src/Model/GContact.php index 8c220a57ae..2caad94591 100644 --- a/src/Model/GContact.php +++ b/src/Model/GContact.php @@ -1,5 +1,4 @@ Strings::normaliseLink($orig_profile)])) { - DBA::delete('gcontact', ['nurl' => Strings::normaliseLink($orig_profile)]); - } - } } if (!isset($gcontact['name']) || !isset($gcontact['photo'])) { @@ -221,7 +211,7 @@ class GContact } if (!in_array($gcontact['network'], Protocol::FEDERATED)) { - throw new Exception('No federated network ('.$gcontact['network'].') detected for URL '.$gcontact['url']); + throw new Exception('No federated network (' . $gcontact['network'] . ') detected for URL ' . $gcontact['url']); } if (empty($gcontact['server_url'])) { @@ -263,7 +253,6 @@ class GContact intval($cid) ); - // Logger::log("countCommonFriends: $uid $cid {$r[0]['total']}"); if (DBA::isResult($r)) { return $r[0]['total']; } @@ -432,15 +421,6 @@ class GContact return []; } - /* - * Uncommented because the result of the queries are to big to store it in the cache. - * We need to decide if we want to change the db column type or if we want to delete it. - */ - //$list = Cache::get('suggestion_query:'.$uid.':'.$start.':'.$limit); - //if (!is_null($list)) { - // return $list; - //} - $network = [Protocol::DFRN, Protocol::ACTIVITYPUB]; if (Config::get('system', 'diaspora_enabled')) { @@ -451,8 +431,7 @@ class GContact $network[] = Protocol::OSTATUS; } - $sql_network = implode("', '", $network); - $sql_network = "'".$sql_network."'"; + $sql_network = "'" . implode("', '", $network) . "'"; /// @todo This query is really slow // By now we cache the data for five minutes @@ -477,12 +456,6 @@ class GContact ); if (DBA::isResult($r) && count($r) >= ($limit -1)) { - /* - * Uncommented because the result of the queries are to big to store it in the cache. - * We need to decide if we want to change the db column type or if we want to delete it. - */ - //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $r, Cache::FIVE_MINUTES); - return $r; } @@ -518,11 +491,6 @@ class GContact array_pop($list); } - /* - * Uncommented because the result of the queries are to big to store it in the cache. - * We need to decide if we want to change the db column type or if we want to delete it. - */ - //Cache::set("suggestion_query:".$uid.":".$start.":".$limit, $list, Cache::FIVE_MINUTES); return $list; } @@ -540,7 +508,7 @@ class GContact $done[] = System::baseUrl() . '/poco'; if (strlen(Config::get('system', 'directory'))) { - $x = Network::fetchUrl(get_server().'/pubsites'); + $x = Network::fetchUrl(get_server() . '/pubsites'); if (!empty($x)) { $j = json_decode($x); if (!empty($j->entries)) { @@ -558,18 +526,11 @@ class GContact } // Query your contacts from Friendica and Redmatrix/Hubzilla for their contacts - $r = q( - "SELECT DISTINCT(`poco`) AS `poco` FROM `contact` WHERE `network` IN ('%s', '%s')", - DBA::escape(Protocol::DFRN), - DBA::escape(Protocol::DIASPORA) - ); - - if (DBA::isResult($r)) { - foreach ($r as $rr) { - $base = substr($rr['poco'], 0, strrpos($rr['poco'], '/')); - if (! in_array($base, $done)) { - PortableContact::loadWorker(0, 0, 0, $base); - } + $contacts = DBA::p("SELECT DISTINCT(`poco`) AS `poco` FROM `contact` WHERE `network` IN (?, ?)", Protocol::DFRN, Protocol::DIASPORA); + while ($contact = DBA::fetch($contacts)) { + $base = substr($contact['poco'], 0, strrpos($contact['poco'], '/')); + if (!in_array($base, $done)) { + PortableContact::loadWorker(0, 0, 0, $base); } } } @@ -586,49 +547,27 @@ class GContact { $parts = parse_url($url); - if (!isset($parts['scheme']) || !isset($parts['host'])) { + if (empty($parts['scheme']) || empty($parts['host'])) { return $url; } - $new_url = $parts['scheme'].'://'.$parts['host']; + $new_url = $parts['scheme'] . '://' . $parts['host']; - if (isset($parts['port'])) { - $new_url .= ':'.$parts['port']; + if (!empty($parts['port'])) { + $new_url .= ':' . $parts['port']; } - if (isset($parts['path'])) { + if (!empty($parts['path'])) { $new_url .= $parts['path']; } if ($new_url != $url) { - Logger::log('Cleaned contact url '.$url.' to '.$new_url.' - Called by: '.System::callstack(), Logger::DEBUG); + Logger::info('Cleaned contact url', ['url' => $url, 'new_url' => $new_url, 'callstack' => System::callstack()]); } return $new_url; } - /** - * @brief Replace alternate OStatus user format with the primary one - * - * @param array $contact contact array (called by reference) - * @return void - * @throws \Friendica\Network\HTTPException\InternalServerErrorException - * @throws \ImagickException - */ - public static function fixAlternateContactAddress(&$contact) - { - if (($contact['network'] == Protocol::OSTATUS) && PortableContact::alternateOStatusUrl($contact['url'])) { - $data = Probe::uri($contact['url']); - if ($contact['network'] == Protocol::OSTATUS) { - Logger::log('Fix primary url from '.$contact['url'].' to '.$data['url'].' - Called by: '.System::callstack(), Logger::DEBUG); - $contact['url'] = $data['url']; - $contact['addr'] = $data['addr']; - $contact['alias'] = $data['alias']; - $contact['server_url'] = $data['baseurl']; - } - } - } - /** * @brief Fetch the gcontact id, add an entry if not existed * @@ -646,12 +585,12 @@ class GContact $last_contact_str = ''; if (empty($contact['network'])) { - Logger::log('Empty network for contact url '.$contact['url'].' - Called by: '.System::callstack(), Logger::DEBUG); + Logger::notice('Empty network', ['url' => $contact['url'], 'callstack' => System::callstack()]); return false; } if (in_array($contact['network'], [Protocol::PHANTOM])) { - Logger::log('Invalid network for contact url '.$contact['url'].' - Called by: '.System::callstack(), Logger::DEBUG); + Logger::notice('Invalid network', ['url' => $contact['url'], 'callstack' => System::callstack()]); return false; } @@ -664,9 +603,6 @@ class GContact $contact['hide'] = true; } - // Replace alternate OStatus user format with the primary one - self::fixAlternateContactAddress($contact); - // Remove unwanted parts from the contact url (e.g. '?zrl=...') if (in_array($contact['network'], Protocol::FEDERATED)) { $contact['url'] = self::cleanContactUrl($contact['url']); @@ -679,7 +615,7 @@ class GContact $gcontact_id = $gcnt['id']; // Update every 90 days - if (in_array($gcnt['network'], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, ''])) { + if (empty($gcnt['network']) || in_array($gcnt['network'], Protocol::FEDERATED)) { $last_failure_str = $gcnt['last_failure']; $last_failure = strtotime($gcnt['last_failure']); $last_contact_str = $gcnt['last_contact']; @@ -691,35 +627,24 @@ class GContact $contact['about'] = $contact['about'] ?? ''; $contact['generation'] = $contact['generation'] ?? 0; - q( - "INSERT INTO `gcontact` (`name`, `nick`, `addr` , `network`, `url`, `nurl`, `photo`, `created`, `updated`, `location`, `about`, `hide`, `generation`) - VALUES ('%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', '%s', %d, %d)", - DBA::escape($contact['name']), - DBA::escape($contact['nick']), - DBA::escape($contact['addr']), - DBA::escape($contact['network']), - DBA::escape($contact['url']), - DBA::escape(Strings::normaliseLink($contact['url'])), - DBA::escape($contact['photo']), - DBA::escape(DateTimeFormat::utcNow()), - DBA::escape(DateTimeFormat::utcNow()), - DBA::escape($contact['location']), - DBA::escape($contact['about']), - intval($contact['hide']), - intval($contact['generation']) - ); + $fields = ['name' => $contact['name'], 'nick' => $contact['nick'] ?? '', 'addr' => $contact['addr'] ?? '', 'network' => $contact['network'], + 'url' => $contact['url'], 'nurl' => Strings::normaliseLink($contact['url']), 'photo' => $contact['photo'], + 'created' => DateTimeFormat::utcNow(), 'updated' => DateTimeFormat::utcNow(), 'location' => $contact['location'], + 'about' => $contact['about'], 'hide' => $contact['hide'], 'generation' => $contact['generation']]; + + DBA::insert('gcontact', $fields); $condition = ['nurl' => Strings::normaliseLink($contact['url'])]; $cnt = DBA::selectFirst('gcontact', ['id', 'network'], $condition, ['order' => ['id']]); if (DBA::isResult($cnt)) { $gcontact_id = $cnt['id']; - $doprobing = in_array($cnt['network'], [Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, '']); + $doprobing = (empty($cnt['network']) || in_array($cnt['network'], Protocol::FEDERATED)); } } DBA::unlock(); if ($doprobing) { - Logger::log("Last Contact: ". $last_contact_str." - Last Failure: ".$last_failure_str." - Checking: ".$contact['url'], Logger::DEBUG); + Logger::notice('Probing', ['contact' => $last_contact_str, "failure" => $last_failure_str, "checking" => $contact['url']]); Worker::add(PRIORITY_LOW, 'GProbe', $contact['url']); } @@ -796,9 +721,6 @@ class GContact $contact['network'] = Protocol::OSTATUS; } - // Replace alternate OStatus user format with the primary one - self::fixAlternateContactAddress($contact); - if (!isset($contact['updated'])) { $contact['updated'] = DateTimeFormat::utcNow(); } @@ -841,9 +763,9 @@ class GContact if ($update) { Logger::debug('Update gcontact.', ['contact' => $contact['url']]); - $condition = ['`nurl` = ? AND (`generation` = 0 OR `generation` >= ?)', - Strings::normaliseLink($contact['url']), $contact["generation"]]; - $contact["updated"] = DateTimeFormat::utc($contact["updated"]); + $condition = ["`nurl` = ? AND (`generation` = 0 OR `generation` >= ?)", + Strings::normaliseLink($contact['url']), $contact['generation']]; + $contact['updated'] = DateTimeFormat::utc($contact['updated']); $updated = [ 'photo' => $contact['photo'], 'name' => $contact['name'], @@ -888,14 +810,11 @@ class GContact return; } - // When the profile doesn't have got a feed, then we exit here - if (empty($data['poll'])) { - return; - } - - if ($data['network'] == Protocol::ACTIVITYPUB) { + if (!empty($data['outbox'])) { + self::updateFromOutbox($data['outbox'], $data); + } elseif (!empty($data['poll']) && ($data['network'] == Protocol::ACTIVITYPUB)) { self::updateFromOutbox($data['poll'], $data); - } else { + } elseif (!empty($data['poll'])) { self::updateFromFeed($data); } } @@ -920,7 +839,7 @@ class GContact if ($curlResult->isSuccess() && !empty($curlResult->getBody())) { $noscrape = json_decode($curlResult->getBody(), true); - if (!empty($noscrape)) { + if (!empty($noscrape) && !empty($noscrape['updated'])) { $noscrape['updated'] = DateTimeFormat::utc($noscrape['updated'], DateTimeFormat::MYSQL); $fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $noscrape['updated']]; DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]); @@ -938,7 +857,9 @@ class GContact /** * Update a global contact via an ActivityPub Outbox * - * @param string $data Probing result + * @param string $feed + * @param array $data Probing result + * @throws \Friendica\Network\HTTPException\InternalServerErrorException */ private static function updateFromOutbox(string $feed, array $data) { @@ -951,18 +872,32 @@ class GContact $items = $outbox['orderedItems']; } elseif (!empty($outbox['first']['orderedItems'])) { $items = $outbox['first']['orderedItems']; + } elseif (!empty($outbox['first']['href'])) { + self::updateFromOutbox($outbox['first']['href'], $data); + return; } elseif (!empty($outbox['first'])) { - self::updateFromOutbox($outbox['first'], $data); + if (is_string($outbox['first'])) { + self::updateFromOutbox($outbox['first'], $data); + } else { + Logger::warning('Unexpected data', ['outbox' => $outbox]); + } return; } else { $items = []; } $last_updated = ''; - foreach ($items as $activity) { - if ($last_updated < $activity['published']) { - $last_updated = $activity['published']; + if (!empty($activity['published'])) { + $published = DateTimeFormat::utc($activity['published']); + } elseif (!empty($activity['object']['published'])) { + $published = DateTimeFormat::utc($activity['object']['published']); + } else { + continue; + } + + if ($last_updated < $published) { + $last_updated = $published; } } @@ -1161,7 +1096,7 @@ class GContact return false; } - $data["server_url"] = $data["baseurl"]; + $data['server_url'] = $data['baseurl']; self::update($data); @@ -1181,43 +1116,32 @@ class GContact */ public static function updateForUser($uid) { - $r = q( - "SELECT `profile`.`locality`, `profile`.`region`, `profile`.`country-name`, - `profile`.`name`, `profile`.`about`, `profile`.`gender`, - `profile`.`pub_keywords`, `profile`.`dob`, `profile`.`photo`, - `profile`.`net-publish`, `user`.`nickname`, `user`.`hidewall`, - `contact`.`notify`, `contact`.`url`, `contact`.`addr` - FROM `profile` - INNER JOIN `user` ON `user`.`uid` = `profile`.`uid` - INNER JOIN `contact` ON `contact`.`uid` = `profile`.`uid` - WHERE `profile`.`uid` = %d AND `profile`.`is-default` AND `contact`.`self`", - intval($uid) - ); + $profile = Profile::getByUID($uid); + if (empty($profile)) { + Logger::error('Cannot find profile', ['uid' => $uid]); + return false; + } - if (!DBA::isResult($r)) { - Logger::log('Cannot find user with uid=' . $uid, Logger::INFO); + $user = User::getOwnerDataById($uid); + if (empty($user)) { + Logger::error('Cannot find user', ['uid' => $uid]); return false; } + $userdata = array_merge($profile, $user); + $location = Profile::formatLocation( - ["locality" => $r[0]["locality"], "region" => $r[0]["region"], "country-name" => $r[0]["country-name"]] + ['locality' => $userdata['locality'], 'region' => $userdata['region'], 'country-name' => $userdata['country-name']] ); - // The 'addr' field was added in 3.4.3 so it can be empty for older users - if ($r[0]['addr'] != '') { - $addr = $r[0]["nickname"].'@'.str_replace(["http://", "https://"], '', System::baseUrl()); - } else { - $addr = $r[0]['addr']; - } - - $gcontact = ['name' => $r[0]['name'], "location" => $location, 'about' => $r[0]['about'], - "gender" => $r[0]["gender"], 'keywords' => $r[0]["pub_keywords"], - "birthday" => $r[0]["dob"], "photo" => $r[0]["photo"], - "notify" => $r[0]["notify"], "url" => $r[0]['url'], - "hide" => ($r[0]["hidewall"] || !$r[0]["net-publish"]), - "nick" => $r[0]["nickname"], 'addr' => $addr, - "connect" => $addr, "server_url" => System::baseUrl(), - "generation" => 1, "network" => Protocol::DFRN]; + $gcontact = ['name' => $userdata['name'], 'location' => $location, 'about' => $userdata['about'], + 'gender' => $userdata['gender'], 'keywords' => $userdata['pub_keywords'], + 'birthday' => $userdata['dob'], 'photo' => $userdata['photo'], + "notify" => $userdata['notify'], 'url' => $userdata['url'], + "hide" => ($userdata['hidewall'] || !$userdata['net-publish']), + 'nick' => $userdata['nickname'], 'addr' => $userdata['addr'], + "connect" => $userdata['addr'], "server_url" => System::baseUrl(), + "generation" => 1, 'network' => Protocol::DFRN]; self::update($gcontact); } @@ -1234,9 +1158,9 @@ class GContact */ public static function fetchGsUsers($server) { - Logger::log("Fetching users from GNU Social server ".$server, Logger::DEBUG); + Logger::info('Fetching users from GNU Social server', ['server' => $server]); - $url = $server."/main/statistics"; + $url = $server . '/main/statistics'; $curlResult = Network::curl($url); if (!$curlResult->isSuccess()) { @@ -1247,9 +1171,9 @@ class GContact if (!empty($statistics->config->instance_address)) { if (!empty($statistics->config->instance_with_ssl)) { - $server = "https://"; + $server = 'https://'; } else { - $server = "http://"; + $server = 'http://'; } $server .= $statistics->config->instance_address; @@ -1257,9 +1181,9 @@ class GContact $hostname = $statistics->config->instance_address; } elseif (!empty($statistics->instance_address)) { if (!empty($statistics->instance_with_ssl)) { - $server = "https://"; + $server = 'https://'; } else { - $server = "http://"; + $server = 'http://'; } $server .= $statistics->instance_address; @@ -1269,14 +1193,14 @@ class GContact if (!empty($statistics->users)) { foreach ($statistics->users as $nick => $user) { - $profile_url = $server."/".$user->nickname; + $profile_url = $server . '/' . $user->nickname; - $contact = ["url" => $profile_url, + $contact = ['url' => $profile_url, 'name' => $user->fullname, - 'addr' => $user->nickname."@".$hostname, - "nick" => $user->nickname, + 'addr' => $user->nickname . '@' . $hostname, + 'nick' => $user->nickname, "network" => Protocol::OSTATUS, - "photo" => System::baseUrl()."/images/person-300.jpg"]; + 'photo' => System::baseUrl() . '/images/person-300.jpg']; if (isset($user->bio)) { $contact['about'] = $user->bio; @@ -1295,7 +1219,7 @@ class GContact */ public static function discoverGsUsers() { - $requery_days = intval(Config::get("system", "poco_requery_days")); + $requery_days = intval(Config::get('system', 'poco_requery_days')); $last_update = date("c", time() - (60 * 60 * 24 * $requery_days)); @@ -1316,7 +1240,7 @@ class GContact foreach ($r as $server) { self::fetchGsUsers($server['url']); - q("UPDATE `gserver` SET `last_poco_query` = '%s' WHERE `nurl` = '%s'", DBA::escape(DateTimeFormat::utcNow()), DBA::escape($server["nurl"])); + DBA::update('gserver', ['last_poco_query' => DateTimeFormat::utcNow()], ['nurl' => $server['nurl']]); } }