]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/GContact.php
Remove obsolete mod/lockview.php file
[friendica.git] / src / Model / GContact.php
index 3da5513b503ace78c2abdf35bb78f2f4a7b92a9e..ec53133c941ba040461a4f35ed2154d1efd14efe 100644 (file)
@@ -26,8 +26,8 @@ use DOMXPath;
 use Exception;
 use Friendica\Core\Logger;
 use Friendica\Core\Protocol;
-use Friendica\Core\System;
 use Friendica\Core\Search;
+use Friendica\Core\System;
 use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\DI;
@@ -43,19 +43,6 @@ use Friendica\Util\Strings;
  */
 class GContact
 {
-       /**
-        * No discovery of followers/followings
-        */
-       const DISCOVERY_NONE = 0;
-       /**
-        * Only discover followers/followings from direct contacts
-        */
-       const DISCOVERY_DIRECT = 1;
-       /**
-        * Recursive discovery of followers/followings
-        */
-       const DISCOVERY_RECURSIVE = 2;
-
        /**
         * Search global contact table by nick or name
         *
@@ -95,7 +82,7 @@ class GContact
 
                $results = DBA::p("SELECT `nurl` FROM `gcontact`
                        WHERE NOT `hide` AND `network` IN (?, ?, ?, ?) AND
-                               ((`last_contact` >= `last_failure`) OR (`updated` >= `last_failure`)) AND
+                               NOT `failed` AND
                                (`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?) $extra_sql
                                GROUP BY `nurl` ORDER BY `nurl` DESC LIMIT 1000",
                        Protocol::DFRN, Protocol::ACTIVITYPUB, $ostatus, $diaspora, $search, $search, $search
@@ -111,7 +98,7 @@ class GContact
                                continue;
                        }
 
-                       $gcontacts[] = Contact::getDetailsByURL($result['nurl'], local_user());
+                       $gcontacts[] = Contact::getByURLForUser($result['nurl'], local_user());
                }
                DBA::close($results);
                return $gcontacts;
@@ -230,9 +217,8 @@ class GContact
                                throw new Exception('Probing for URL ' . $gcontact['url'] . ' failed');
                        }
 
-                       $orig_profile = $gcontact['url'];
-
                        $gcontact['server_url'] = $data['baseurl'];
+                       $gcontact['failed'] = false;
 
                        $gcontact = array_merge($gcontact, $data);
                }
@@ -275,8 +261,7 @@ class GContact
                        "SELECT count(*) as `total`
                        FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
                        WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
-                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR
-                       (`gcontact`.`updated` >= `gcontact`.`last_failure`))
+                       NOT `gcontact`.`failed`
                        AND `gcontact`.`nurl` IN (select nurl from contact where uid = %d and self = 0 and blocked = 0 and hidden = 0 and id != %d) ",
                        intval($cid),
                        intval($uid),
@@ -339,7 +324,7 @@ class GContact
                        WHERE `glink`.`cid` = %d and `glink`.`uid` = %d
                                AND `contact`.`uid` = %d AND `contact`.`self` = 0 AND `contact`.`blocked` = 0
                                AND `contact`.`hidden` = 0 AND `contact`.`id` != %d
-                               AND ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
+                               AND NOT `gcontact`.`failed`
                                $sql_extra LIMIT %d, %d",
                        intval($cid),
                        intval($uid),
@@ -398,7 +383,7 @@ class GContact
                        "SELECT count(*) as `total`
                        FROM `glink` INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
                        where `glink`.`cid` = %d and `glink`.`uid` = %d AND
-                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))",
+                       NOT `gcontact`.`failed`",
                        intval($cid),
                        intval($uid)
                );
@@ -426,7 +411,7 @@ class GContact
                        INNER JOIN `gcontact` on `glink`.`gcid` = `gcontact`.`id`
                        LEFT JOIN `contact` ON `contact`.`nurl` = `gcontact`.`nurl` AND `contact`.`uid` = %d
                        WHERE `glink`.`cid` = %d AND `glink`.`uid` = %d AND
-                       ((`gcontact`.`last_contact` >= `gcontact`.`last_failure`) OR (`gcontact`.`updated` >= `gcontact`.`last_failure`))
+                       NOT `gcontact`.`failed`
                        ORDER BY `gcontact`.`name` ASC LIMIT %d, %d ",
                        intval($uid),
                        intval($cid),
@@ -473,7 +458,7 @@ class GContact
                        AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
                        AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
                        AND `gcontact`.`updated` >= '%s' AND NOT `gcontact`.`hide`
-                       AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
+                       AND NOT `gcontact`.`failed`
                        AND `gcontact`.`network` IN (%s)
                        GROUP BY `glink`.`gcid` ORDER BY `gcontact`.`updated` DESC,`total` DESC LIMIT %d, %d",
                        intval($uid),
@@ -497,7 +482,7 @@ class GContact
                        AND NOT `gcontact`.`name` IN (SELECT `name` FROM `contact` WHERE `uid` = %d)
                        AND NOT `gcontact`.`id` IN (SELECT `gcid` FROM `gcign` WHERE `uid` = %d)
                        AND `gcontact`.`updated` >= '%s'
-                       AND `gcontact`.`last_contact` >= `gcontact`.`last_failure`
+                       AND NOT `gcontact`.`failed`
                        AND `gcontact`.`network` IN (%s)
                        ORDER BY rand() LIMIT %d, %d",
                        intval($uid),
@@ -539,7 +524,7 @@ class GContact
                $done[] = DI::baseUrl() . '/poco';
 
                if (strlen(DI::config()->get('system', 'directory'))) {
-                       $x = Network::fetchUrl(Search::getGlobalDirectory() . '/pubsites');
+                       $x = DI::httpRequest()->fetch(Search::getGlobalDirectory() . '/pubsites');
                        if (!empty($x)) {
                                $j = json_decode($x);
                                if (!empty($j->entries)) {
@@ -611,8 +596,6 @@ class GContact
         */
        public static function getId($contact)
        {
-               $gcontact_id = 0;
-
                if (empty($contact['network'])) {
                        Logger::notice('Empty network', ['url' => $contact['url'], 'callstack' => System::callstack()]);
                        return false;
@@ -627,42 +610,37 @@ class GContact
                        $contact['network'] = Protocol::OSTATUS;
                }
 
-               // All new contacts are hidden by default
-               if (!isset($contact['hide'])) {
-                       $contact['hide'] = true;
-               }
-
                // Remove unwanted parts from the contact url (e.g. '?zrl=...')
                if (in_array($contact['network'], Protocol::FEDERATED)) {
                        $contact['url'] = self::cleanContactUrl($contact['url']);
                }
 
-               DBA::lock('gcontact');
-               $fields = ['id', 'last_contact', 'last_failure', 'network'];
-               $gcnt = DBA::selectFirst('gcontact', $fields, ['nurl' => Strings::normaliseLink($contact['url'])]);
-               if (DBA::isResult($gcnt)) {
-                       $gcontact_id = $gcnt['id'];
-               } else {
-                       $contact['location'] = $contact['location'] ?? '';
-                       $contact['about'] = $contact['about'] ?? '';
-                       $contact['generation'] = $contact['generation'] ?? 0;
+               $condition = ['nurl' => Strings::normaliseLink($contact['url'])];
+               $gcontact = DBA::selectFirst('gcontact', ['id'], $condition, ['order' => ['id']]);
+               if (DBA::isResult($gcontact)) {
+                       return $gcontact['id'];
+               }
 
-                       $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']];
+               $contact['location'] = $contact['location'] ?? '';
+               $contact['about'] = $contact['about'] ?? '';
+               $contact['generation'] = $contact['generation'] ?? 0;
+               $contact['hide'] = $contact['hide'] ?? true;
 
-                       DBA::insert('gcontact', $fields);
+               $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'], 'failed' => false];
 
-                       $condition = ['nurl' => Strings::normaliseLink($contact['url'])];
-                       $cnt = DBA::selectFirst('gcontact', ['id', 'network'], $condition, ['order' => ['id']]);
-                       if (DBA::isResult($cnt)) {
-                               $gcontact_id = $cnt['id'];
-                       }
-               }
-               DBA::unlock();
+               DBA::insert('gcontact', $fields);
 
-               return $gcontact_id;
+               // We intentionally aren't using lastInsertId here. There is a chance for duplicates.
+               $gcontact = DBA::selectFirst('gcontact', ['id'], $condition, ['order' => ['id']]);
+               if (!DBA::isResult($gcontact)) {
+                       Logger::info('GContact creation failed', $fields);
+                       // Shouldn't happen
+                       return 0;
+               }
+               return $gcontact['id'];
        }
 
        /**
@@ -690,7 +668,7 @@ class GContact
                }
 
                $public_contact = DBA::selectFirst('gcontact', [
-                       'name', 'nick', 'photo', 'location', 'about', 'addr', 'generation', 'birthday', 'keywords', 'gsid',
+                       'name', 'nick', 'photo', 'location', 'about', 'addr', 'generation', 'birthday', 'keywords', 'gsid', 'failed',
                        'contact-type', 'hide', 'nsfw', 'network', 'alias', 'notify', 'server_url', 'connect', 'updated', 'url'
                ], ['id' => $gcontact_id]);
 
@@ -796,7 +774,7 @@ class GContact
                                'location' => $contact['location'], 'about' => $contact['about'],
                                'generation' => $contact['generation'], 'updated' => $contact['updated'],
                                'server_url' => $contact['server_url'], 'connect' => $contact['connect'],
-                               'gsid' => $contact['gsid']
+                               'failed' => $contact['failed'], 'gsid' => $contact['gsid']
                        ];
 
                        DBA::update('gcontact', $updated, $condition, $fields);
@@ -854,19 +832,19 @@ class GContact
                        return false;
                }
 
-               $curlResult = Network::curl($gserver['noscrape'] . '/' . $data['nick']);
+               $curlResult = DI::httpRequest()->get($gserver['noscrape'] . '/' . $data['nick']);
 
                if ($curlResult->isSuccess() && !empty($curlResult->getBody())) {
                        $noscrape = json_decode($curlResult->getBody(), true);
                        if (!empty($noscrape) && !empty($noscrape['updated'])) {
                                $noscrape['updated'] = DateTimeFormat::utc($noscrape['updated'], DateTimeFormat::MYSQL);
-                               $fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $noscrape['updated']];
+                               $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $noscrape['updated']];
                                DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
                                return true;
                        }
                } elseif ($curlResult->isTimeout()) {
                        // On a timeout return the existing value, but mark the contact as failure
-                       $fields = ['last_failure' => DateTimeFormat::utcNow()];
+                       $fields = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()];
                        DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
                        return true;
                }
@@ -924,7 +902,7 @@ class GContact
                        return;
                }
 
-               $fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
+               $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
                DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
        }
 
@@ -936,9 +914,9 @@ class GContact
        private static function updateFromFeed(array $data)
        {
                // Search for the newest entry in the feed
-               $curlResult = Network::curl($data['poll']);
+               $curlResult = DI::httpRequest()->get($data['poll']);
                if (!$curlResult->isSuccess()) {
-                       $fields = ['last_failure' => DateTimeFormat::utcNow()];
+                       $fields = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()];
                        DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
 
                        Logger::info("Profile wasn't reachable (no feed)", ['url' => $data['url']]);
@@ -979,7 +957,7 @@ class GContact
                        return;
                }
 
-               $fields = ['last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
+               $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
                DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
        }
        /**
@@ -1021,7 +999,7 @@ class GContact
                $fields = ['name', 'nick', 'url', 'nurl', 'location', 'about', 'keywords',
                        'bd', 'contact-type', 'network', 'addr', 'notify', 'alias', 'archive', 'term-date',
                        'created', 'updated', 'avatar', 'success_update', 'failure_update', 'forum', 'prv',
-                       'baseurl', 'gsid', 'sensitive', 'unsearchable'];
+                       'baseurl', 'gsid', 'sensitive', 'unsearchable', 'failed'];
 
                $contact = DBA::selectFirst('contact', $fields, array_merge($condition, ['uid' => 0, 'network' => Protocol::FEDERATED]));
                if (!DBA::isResult($contact)) {
@@ -1031,7 +1009,7 @@ class GContact
                $fields = ['name', 'nick', 'url', 'nurl', 'location', 'about', 'keywords', 'generation',
                        'birthday', 'contact-type', 'network', 'addr', 'notify', 'alias', 'archived', 'archive_date',
                        'created', 'updated', 'photo', 'last_contact', 'last_failure', 'community', 'connect',
-                       'server_url', 'gsid', 'nsfw', 'hide', 'id'];
+                       'server_url', 'gsid', 'nsfw', 'hide', 'id', 'failed'];
 
                $old_gcontact = DBA::selectFirst('gcontact', $fields, ['nurl' => $contact['nurl']]);
                $do_insert = !DBA::isResult($old_gcontact);
@@ -1043,7 +1021,7 @@ class GContact
 
                // These fields are identical in both contact and gcontact
                $fields = ['name', 'nick', 'url', 'nurl', 'location', 'about', 'keywords', 'gsid',
-                       'contact-type', 'network', 'addr', 'notify', 'alias', 'created', 'updated'];
+                       'contact-type', 'network', 'addr', 'notify', 'alias', 'created', 'updated', 'failed'];
 
                foreach ($fields as $field) {
                        $gcontact[$field] = $contact[$field];
@@ -1109,13 +1087,14 @@ class GContact
                $data = Probe::uri($url, $force);
 
                if (in_array($data['network'], [Protocol::PHANTOM])) {
-                       $fields = ['last_failure' => DateTimeFormat::utcNow()];
+                       $fields = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()];
                        DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($url)]);
                        Logger::info('Invalid network for contact', ['url' => $data['url'], 'callstack' => System::callstack()]);
                        return false;
                }
 
                $data['server_url'] = $data['baseurl'];
+               $data['failed'] = false;
 
                self::update($data);
 
@@ -1213,7 +1192,7 @@ class GContact
 
                $url = $server . '/main/statistics';
 
-               $curlResult = Network::curl($url);
+               $curlResult = DI::httpRequest()->get($url);
                if (!$curlResult->isSuccess()) {
                        return false;
                }
@@ -1277,7 +1256,7 @@ class GContact
 
                $r = DBA::select('gserver', ['nurl', 'url'], [
                        '`network` = ?
-                       AND `last_contact` >= `last_failure`
+                       AND NOT `failed`
                        AND `last_poco_query` < ?',
                        Protocol::OSTATUS,
                        $last_update
@@ -1296,129 +1275,6 @@ class GContact
                }
        }
 
-       /**
-        * Fetches the followers of a given profile and adds them
-        *
-        * @param string $url URL of a profile
-        * @return void
-        */
-       public static function discoverFollowers(string $url)
-       {
-               $gcontact = DBA::selectFirst('gcontact', ['id', 'last_discovery'], ['nurl' => Strings::normaliseLink(($url))]);
-               if (!DBA::isResult($gcontact)) {
-                       return;
-               }
-
-               if ($gcontact['last_discovery'] > DateTimeFormat::utc('now - 1 month')) {
-                       Logger::info('Last discovery was less then a month before.', ['url' => $url, 'discovery' => $gcontact['last_discovery']]);
-                       return;
-               }
-
-               $gcid = $gcontact['id'];
-
-               $apcontact = APContact::getByURL($url);
-
-               if (!empty($apcontact['followers']) && is_string($apcontact['followers'])) {
-                       $followers = ActivityPub::fetchItems($apcontact['followers']);
-               } else {
-                       $followers = [];
-               }
-
-               if (!empty($apcontact['following']) && is_string($apcontact['following'])) {
-                       $followings = ActivityPub::fetchItems($apcontact['following']);
-               } else {
-                       $followings = [];
-               }
-
-               if (!empty($followers) || !empty($followings)) {
-                       if (!empty($followers)) {
-                               // Clear the follower list, since it will be recreated in the next step
-                               DBA::update('gfollower', ['deleted' => true], ['gcid' => $gcid]);
-                       }
-
-                       $contacts = [];
-                       foreach (array_merge($followers, $followings) as $contact) {
-                               if (is_string($contact)) {
-                                       $contacts[] = $contact;
-                               } elseif (!empty($contact['url']) && is_string($contact['url'])) {
-                                       $contacts[] = $contact['url'];
-                               }
-                       }
-                       $contacts = array_unique($contacts);
-
-                       Logger::info('Discover AP contacts', ['url' => $url, 'contacts' => count($contacts)]);
-                       foreach ($contacts as $contact) {
-                               $gcontact = DBA::selectFirst('gcontact', ['id'], ['nurl' => Strings::normaliseLink(($contact))]);
-                               if (DBA::isResult($gcontact)) {
-                                       $fields = [];
-                                       if (in_array($contact, $followers)) {
-                                               $fields = ['gcid' => $gcid, 'follower-gcid' => $gcontact['id']];
-                                       } elseif (in_array($contact, $followings)) {
-                                               $fields = ['gcid' => $gcontact['id'], 'follower-gcid' => $gcid];
-                                       }
-
-                                       if (!empty($fields)) {
-                                               Logger::info('Set relation between contacts', $fields);
-                                               DBA::update('gfollower', ['deleted' => false], $fields, true);
-                                               continue;
-                                       }
-                               }
-
-                               if (!Network::isUrlBlocked($contact)) {
-                                       Logger::info('Discover new AP contact', ['url' => $contact]);
-                                       Worker::add(PRIORITY_LOW, 'UpdateGContact', $contact, 'nodiscover');
-                               } else {
-                                       Logger::info('No discovery, the URL is blocked.', ['url' => $contact]);
-                               }
-                       }
-                       if (!empty($followers)) {
-                               // Delete all followers that aren't undeleted
-                               DBA::delete('gfollower', ['gcid' => $gcid, 'deleted' => true]);
-                       }
-
-                       DBA::update('gcontact', ['last_discovery' => DateTimeFormat::utcNow()], ['id' => $gcid]);
-                       Logger::info('AP contacts discovery finished, last discovery set', ['url' => $url]);
-                       return;
-               }
-
-               $data = Probe::uri($url);
-               if (empty($data['poco'])) {
-                       return;
-               }
-
-               $curlResult = Network::curl($data['poco']);
-               if (!$curlResult->isSuccess()) {
-                       return;
-               }
-               $poco = json_decode($curlResult->getBody(), true);
-               if (empty($poco['entry'])) {
-                       return;
-               }
-
-               Logger::info('PoCo Discovery started', ['url' => $url, 'contacts' => count($poco['entry'])]);
-
-               foreach ($poco['entry'] as $entries) {
-                       if (!empty($entries['urls'])) {
-                               foreach ($entries['urls'] as $entry) {
-                                       if ($entry['type'] == 'profile') {
-                                               if (DBA::exists('gcontact', ['nurl' => Strings::normaliseLink(($entry['value']))])) {
-                                                       continue;
-                                               }
-                                               if (!Network::isUrlBlocked($entry['value'])) {
-                                                       Logger::info('Discover new PoCo contact', ['url' => $entry['value']]);
-                                                       Worker::add(PRIORITY_LOW, 'UpdateGContact', $entry['value'], 'nodiscover');
-                                               } else {
-                                                       Logger::info('No discovery, the URL is blocked.', ['url' => $entry['value']]);
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               DBA::update('gcontact', ['last_discovery' => DateTimeFormat::utcNow()], ['id' => $gcid]);
-               Logger::info('PoCo Discovery finished', ['url' => $url]);
-       }
-
        /**
         * Returns a random, global contact of the current node
         *
@@ -1428,8 +1284,8 @@ class GContact
        public static function getRandomUrl()
        {
                $r = DBA::selectFirst('gcontact', ['url'], [
-                       '`network` = ? 
-                       AND `last_contact` >= `last_failure`  
+                       '`network` = ?
+                       AND NOT `failed`
                        AND `updated` > ?',
                        Protocol::DFRN,
                        DateTimeFormat::utc('now - 1 month'),