]> git.mxchange.org Git - friendica.git/commitdiff
Poco and gcontact (mostly) removed
authorMichael <heluecht@pirati.ca>
Sat, 1 Aug 2020 16:15:18 +0000 (16:15 +0000)
committerMichael <heluecht@pirati.ca>
Sat, 1 Aug 2020 16:15:18 +0000 (16:15 +0000)
34 files changed:
mod/poco.php
mod/settings.php
src/Content/ContactSelector.php
src/Database/PostUpdate.php
src/Factory/Notification/Introduction.php
src/Model/Contact.php
src/Model/GContact.php
src/Model/GServer.php
src/Module/Admin/Federation.php
src/Module/Admin/Site.php
src/Module/Contact.php
src/Module/NoScrape.php
src/Module/Settings/Profile/Index.php
src/Protocol/DFRN.php
src/Protocol/Diaspora.php
src/Protocol/OStatus.php
src/Protocol/PortableContact.php [deleted file]
src/Worker/Cron.php
src/Worker/CronJobs.php
src/Worker/FetchPoCo.php [deleted file]
src/Worker/OnePoll.php
src/Worker/PullDirectory.php
src/Worker/SearchDirectory.php
src/Worker/UpdateGContact.php [deleted file]
src/Worker/UpdateGContacts.php [deleted file]
src/Worker/UpdateServerDirectories.php
src/Worker/UpdateServerDirectory.php
src/Worker/UpdateServerPeers.php
src/Worker/UpdateSuggestions.php [deleted file]
update.php
view/templates/admin/federation.tpl
view/templates/admin/site.tpl
view/theme/frio/templates/admin/site.tpl
view/theme/vier/theme.php

index abe10ee39cc2ef7a56540ab9008b354ae3ebf39a..41a1627271d617aa3ba75c1750309dd3e5b064f0 100644 (file)
@@ -27,7 +27,7 @@ use Friendica\Core\Protocol;
 use Friendica\Core\Renderer;
 use Friendica\Database\DBA;
 use Friendica\DI;
-use Friendica\Protocol\PortableContact;
+use Friendica\Model\GServer;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Strings;
 use Friendica\Util\XML;
@@ -56,16 +56,15 @@ function poco_init(App $a) {
 
        if ($a->argc > 1 && $a->argv[1] === '@server') {
                // List of all servers that this server knows
-               $ret = PortableContact::serverlist();
+               $ret = GServer::getActive();
                header('Content-type: application/json');
                echo json_encode($ret);
                exit();
        }
 
        if ($a->argc > 1 && $a->argv[1] === '@global') {
-               // List of all profiles that this server recently had data from
-               $global = true;
-               $update_limit = date(DateTimeFormat::MYSQL, time() - 30 * 86400);
+               // Global is not supported anymore
+               throw new \Friendica\Network\HTTPException\NotFoundException();
        }
        if ($a->argc > 2 && $a->argv[2] === '@me') {
                $justme = true;
@@ -99,17 +98,10 @@ function poco_init(App $a) {
        if (!empty($_GET['updatedSince'])) {
                $update_limit = date(DateTimeFormat::MYSQL, strtotime($_GET['updatedSince']));
        }
-       if ($global) {
-               $contacts = q("SELECT count(*) AS `total` FROM `gcontact` WHERE `updated` >= '%s' AND `updated` >= `last_failure` AND NOT `hide` AND `network` IN ('%s', '%s', '%s')",
-                       DBA::escape($update_limit),
-                       DBA::escape(Protocol::DFRN),
-                       DBA::escape(Protocol::DIASPORA),
-                       DBA::escape(Protocol::OSTATUS)
-               );
-       } elseif ($system_mode) {
+       if ($system_mode) {
                $totalResults = DBA::count('profile', ['net-publish' => true]);
        } else {
-               $contacts = q("SELECT count(*) AS `total` FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
+               $contacts = q("SELECT count(*) AS `total` FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `unsearchable` AND NOT `archive`
                        AND NOT `failed`
                        AND `network` IN ('%s', '%s', '%s', '%s') $sql_extra",
                        intval($user['uid']),
@@ -131,24 +123,13 @@ function poco_init(App $a) {
        }
        $itemsPerPage = ((!empty($_GET['count'])) ? intval($_GET['count']) : $totalResults);
 
-       if ($global) {
-               Logger::log("Start global query", Logger::DEBUG);
-               $contacts = q("SELECT * FROM `gcontact` WHERE `updated` > '%s' AND NOT `hide` AND `network` IN ('%s', '%s', '%s') AND `updated` > `last_failure`
-                       ORDER BY `updated` DESC LIMIT %d, %d",
-                       DBA::escape($update_limit),
-                       DBA::escape(Protocol::DFRN),
-                       DBA::escape(Protocol::DIASPORA),
-                       DBA::escape(Protocol::OSTATUS),
-                       intval($startIndex),
-                       intval($itemsPerPage)
-               );
-       } elseif ($system_mode) {
+       if ($system_mode) {
                Logger::log("Start system mode query", Logger::DEBUG);
                $contacts = DBA::selectToArray('owner-view', [], ['net-publish' => true], ['limit' => [$startIndex, $itemsPerPage]]);
        } else {
                Logger::log("Start query for user " . $user['nickname'], Logger::DEBUG);
-               $contacts = q("SELECT * FROM `contact` WHERE `uid` = %d AND `blocked` = 0 AND `pending` = 0 AND `hidden` = 0 AND `archive` = 0
-                       AND NOT `failed`
+               $contacts = q("SELECT * FROM `contact` WHERE `uid` = %d AND NOT `blocked` AND NOT `pending` AND NOT `hiddden` AND NOT `archive`
+                       AND NOT `failed` AND NOT `unsearchable`
                        AND `network` IN ('%s', '%s', '%s', '%s') $sql_extra LIMIT %d, %d",
                        intval($user['uid']),
                        DBA::escape(Protocol::DFRN),
index d02375ed7c657ee5b30fad15b44039d9ed19ff86..e147144e21633fef45cd8c234ed6fa12dcbf99f9 100644 (file)
@@ -31,7 +31,6 @@ use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Contact;
-use Friendica\Model\GContact;
 use Friendica\Model\Group;
 use Friendica\Model\Notify\Type;
 use Friendica\Model\User;
@@ -471,9 +470,6 @@ function settings_post(App $a)
 
        Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
 
-       // Update the global contact for the user
-       GContact::updateForUser(local_user());
-
        DI::baseUrl()->redirect('settings');
        return; // NOTREACHED
 }
index c834f8c514c4ccfcec0e63161a3596ca2178ca68..ec7bcab95cc53adb6b323778dee314a063d3abc4 100644 (file)
@@ -76,14 +76,6 @@ class ContactSelector
                        $server_url = Strings::normaliseLink($contact['baseurl']);
                }
 
-               if (empty($server_url)) {
-                       // Fetch the server url from the gcontact table
-                       $gcontact = DBA::selectFirst('gcontact', ['server_url'], ['nurl' => Strings::normaliseLink($profile)]);
-                       if (!empty($gcontact) && !empty($gcontact['server_url'])) {
-                               $server_url = Strings::normaliseLink($gcontact['server_url']);
-                       }
-               }
-
                if (empty($server_url)) {
                        // Create the server url out of the profile url
                        $parts = parse_url($profile);
index 6d8b197db145def8d7117cf3ed0b66d47edba589..6a8d663c5a8ae14e79b76ddcf735707a6efcb53f 100644 (file)
@@ -93,9 +93,6 @@ class PostUpdate
                if (!self::update1349()) {
                        return false;
                }
-               if (!self::update1350()) {
-                       return false;
-               }
 
                return true;
        }
@@ -997,57 +994,4 @@ class PostUpdate
 
                return false;
        }
-
-       /**
-        * update the "gsid" (global server id) field in the gcontact table
-        *
-        * @return bool "true" when the job is done
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       private static function update1350()
-       {
-               // Was the script completed?
-               if (DI::config()->get("system", "post_update_version") >= 1350) {
-                       return true;
-               }
-
-               $id = DI::config()->get("system", "post_update_version_1350_id", 0);
-
-               Logger::info('Start', ['gcontact' => $id]);
-
-               $start_id = $id;
-               $rows = 0;
-               $condition = ["`id` > ? AND `gsid` IS NULL AND `server_url` != '' AND NOT `server_url` IS NULL", $id];
-               $params = ['order' => ['id'], 'limit' => 10000];
-               $gcontacts = DBA::select('gcontact', ['id', 'server_url'], $condition, $params);
-
-               if (DBA::errorNo() != 0) {
-                       Logger::error('Database error', ['no' => DBA::errorNo(), 'message' => DBA::errorMessage()]);
-                       return false;
-               }
-
-               while ($gcontact = DBA::fetch($gcontacts)) {
-                       $id = $gcontact['id'];
-
-                       DBA::update('gcontact',
-                               ['gsid' => GServer::getID($gcontact['server_url'], true), 'server_url' => GServer::cleanURL($gcontact['server_url'])],
-                               ['id' => $gcontact['id']]);
-
-                       ++$rows;
-               }
-               DBA::close($gcontacts);
-
-               DI::config()->set("system", "post_update_version_1350_id", $id);
-
-               Logger::info('Processed', ['rows' => $rows, 'last' => $id]);
-
-               if ($start_id == $id) {
-                       DI::config()->set("system", "post_update_version", 1350);
-                       Logger::info('Done');
-                       return true;
-               }
-
-               return false;
-       }
 }
index 21aef9297a776537096d9e29587790560efe7434..a16926f9670af9648403bc46beb7576aedeba109 100644 (file)
@@ -99,17 +99,13 @@ class Introduction extends BaseFactory
                $formattedNotifications = [];
 
                try {
-                       /// @todo Fetch contact details by "Contact::getByUrl" instead of queries to contact, fcontact and gcontact
+                       /// @todo Fetch contact details by "Contact::getByUrl" instead of queries to contact and fcontact
                        $stmtNotifications = $this->dba->p(
                                "SELECT `intro`.`id` AS `intro_id`, `intro`.*, `contact`.*,
                                `fcontact`.`name` AS `fname`, `fcontact`.`url` AS `furl`, `fcontact`.`addr` AS `faddr`,
-                               `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`,
-                               `gcontact`.`location` AS `glocation`, `gcontact`.`about` AS `gabout`,
-                               `gcontact`.`keywords` AS `gkeywords`,
-                               `gcontact`.`network` AS `gnetwork`, `gcontact`.`addr` AS `gaddr`
+                               `fcontact`.`photo` AS `fphoto`, `fcontact`.`request` AS `frequest`
                        FROM `intro`
                                LEFT JOIN `contact` ON `contact`.`id` = `intro`.`contact-id`
-                               LEFT JOIN `gcontact` ON `gcontact`.`nurl` = `contact`.`nurl`
                                LEFT JOIN `fcontact` ON `intro`.`fid` = `fcontact`.`id`
                        WHERE `intro`.`uid` = ? $sql_extra
                        LIMIT ?, ?",
@@ -147,16 +143,14 @@ class Introduction extends BaseFactory
 
                                        // Normal connection requests
                                } else {
-                                       $notification = $this->getMissingData($notification);
-
                                        if (empty($notification['url'])) {
                                                continue;
                                        }
 
                                        // Don't show these data until you are connected. Diaspora is doing the same.
-                                       if ($notification['gnetwork'] === Protocol::DIASPORA) {
-                                               $notification['glocation'] = "";
-                                               $notification['gabout']    = "";
+                                       if ($notification['network'] === Protocol::DIASPORA) {
+                                               $notification['location'] = "";
+                                               $notification['about']    = "";
                                        }
 
                                        $formattedNotifications[] = new Notification\Introduction([
@@ -166,17 +160,17 @@ class Introduction extends BaseFactory
                                                'uid'            => $this->session->get('uid'),
                                                'intro_id'       => $notification['intro_id'],
                                                'contact_id'     => $notification['contact-id'],
-                                               'photo'          => (!empty($notification['photo']) ? Proxy::proxifyUrl($notification['photo'], false, Proxy::SIZE_SMALL) : "images/person-300.jpg"),
+                                               'photo'          => Contact::getPhoto($notification),
                                                'name'           => $notification['name'],
-                                               'location'       => BBCode::convert($notification['glocation'], false),
-                                               'about'          => BBCode::convert($notification['gabout'], false),
-                                               'keywords'       => $notification['gkeywords'],
+                                               'location'       => BBCode::convert($notification['location'], false),
+                                               'about'          => BBCode::convert($notification['about'], false),
+                                               'keywords'       => $notification['keywords'],
                                                'hidden'         => $notification['hidden'] == 1,
                                                'post_newfriend' => (intval($this->pConfig->get(local_user(), 'system', 'post_newfriend')) ? '1' : 0),
                                                'url'            => $notification['url'],
                                                'zrl'            => Contact::magicLink($notification['url']),
-                                               'addr'           => $notification['gaddr'],
-                                               'network'        => $notification['gnetwork'],
+                                               'addr'           => $notification['addr'],
+                                               'network'        => $notification['network'],
                                                'knowyou'        => $notification['knowyou'],
                                                'note'           => $notification['note'],
                                        ]);
@@ -188,41 +182,4 @@ class Introduction extends BaseFactory
 
                return $formattedNotifications;
        }
-
-       /**
-        * Check for missing contact data and try to fetch the data from
-        * from other sources
-        *
-        * @param array $intro The input array with the intro data
-        *
-        * @return array The array with the intro data
-        *
-        * @throws InternalServerErrorException
-        */
-       private function getMissingData(array $intro)
-       {
-               // If the network and the addr isn't available from the gcontact
-               // table entry, take the one of the contact table entry
-               if (empty($intro['gnetwork']) && !empty($intro['network'])) {
-                       $intro['gnetwork'] = $intro['network'];
-               }
-               if (empty($intro['gaddr']) && !empty($intro['addr'])) {
-                       $intro['gaddr'] = $intro['addr'];
-               }
-
-               // If the network and addr is still not available
-               // get the missing data data from other sources
-               if (empty($intro['gnetwork']) || empty($intro['gaddr'])) {
-                       $ret = Contact::getByURL($intro['url'], false, ['network', 'addr']);
-
-                       if (empty($intro['gnetwork']) && !empty($ret['network'])) {
-                               $intro['gnetwork'] = $ret['network'];
-                       }
-                       if (empty($intro['gaddr']) && !empty($ret['addr'])) {
-                               $intro['gaddr'] = $ret['addr'];
-                       }
-               }
-
-               return $intro;
-       }
 }
index 61b4c9d05a9855d07c92b59bd5a4f249cfca4c8d..18c378179e329284bacbf0cebf3ecf1e3ceea7b3 100644 (file)
@@ -21,6 +21,8 @@
 
 namespace Friendica\Model;
 
+use DOMDocument;
+use DOMXPath;
 use Friendica\App\BaseURL;
 use Friendica\Content\Pager;
 use Friendica\Core\Hook;
@@ -88,7 +90,7 @@ class Contact
        /**
         * Account types
         *
-        * TYPE_UNKNOWN - the account has been imported from gcontact where this is the default type value
+        * TYPE_UNKNOWN - unknown type
         *
         * TYPE_PERSON - the account belongs to a person
         *      Associated page types: PAGE_NORMAL, PAGE_SOAPBOX, PAGE_FREELOVE
@@ -1021,7 +1023,6 @@ class Contact
                                 */
                                DBA::update('contact', ['archive' => true], ['id' => $contact['id']]);
                                DBA::update('contact', ['archive' => true], ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]);
-                               GContact::updateFromPublicContactURL($contact['url']);
                        }
                }
        }
@@ -1066,7 +1067,6 @@ class Contact
                $fields = ['failed' => false, 'term-date' => DBA::NULL_DATETIME, 'archive' => false];
                DBA::update('contact', $fields, ['id' => $contact['id']]);
                DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($contact['url']), 'self' => false]);
-               GContact::updateFromPublicContactURL($contact['url']);
        }
 
        /**
@@ -1269,12 +1269,8 @@ class Contact
 
                $fields = ['url', 'addr', 'alias', 'notify', 'name', 'nick',
                        'photo', 'keywords', 'location', 'about', 'network'];
-               $data = DBA::selectFirst('gcontact', $fields, ['nurl' => Strings::normaliseLink($url)]);
-
-               if (!DBA::isResult($data)) {
-                       $condition = ['alias' => [$url, Strings::normaliseLink($url), $ssl_url]];
-                       $data = DBA::selectFirst('contact', $fields, $condition);
-               }
+               $condition = ['alias' => [$url, Strings::normaliseLink($url), $ssl_url]];
+               $data = DBA::selectFirst('contact', $fields, $condition);
 
                if (DBA::isResult($data)) {
                        $data["pubkey"] = '';
@@ -1706,7 +1702,6 @@ class Contact
                // There are several fields that indicate that the contact or user is a forum
                // "page-flags" is a field in the user table,
                // "forum" and "prv" are used in the contact table. They stand for User::PAGE_FLAGS_COMMUNITY and User::PAGE_FLAGS_PRVGROUP.
-               // "community" is used in the gcontact table and is true if the contact is User::PAGE_FLAGS_COMMUNITY or User::PAGE_FLAGS_PRVGROUP.
                if ((isset($contact['page-flags']) && (intval($contact['page-flags']) == User::PAGE_FLAGS_COMMUNITY))
                        || (isset($contact['page-flags']) && (intval($contact['page-flags']) == User::PAGE_FLAGS_PRVGROUP))
                        || (isset($contact['forum']) && intval($contact['forum']))
@@ -1994,9 +1989,6 @@ class Contact
                        return;
                }
 
-               // Update the corresponding gcontact entry
-               GContact::updateFromPublicContactID($id);
-
                // Archive or unarchive the contact. We only need to do this for the public contact.
                // The archive/unarchive function will update the personal contacts by themselves.
                $contact = DBA::selectFirst('contact', [], ['id' => $id]);
@@ -2155,11 +2147,6 @@ class Contact
 
                $new_pubkey = $ret['pubkey'];
 
-               // Update the gcontact entry
-               if ($uid == 0) {
-                       GContact::updateFromPublicContactID($id);
-               }
-
                $update = false;
 
                // make sure to not overwrite existing values with blank entries except some technical fields
@@ -3068,4 +3055,208 @@ class Contact
 
                return array_slice($contacts, $start, $limit);
        }
+
+       /**
+        * Add public contacts from an array
+        *
+        * @param array $urls
+        * @return array result "count", "added" and "updated"
+        */
+       public static function addContactsByArray(array $urls)
+       {
+               $added = 0;
+               $updated = 0;
+               $count = 0;
+
+               foreach ($urls as $url) {
+                       $contact = Contact::getByURL($url, false, ['id']); 
+                       if (empty($contact['id'])) {
+                               Worker::add(PRIORITY_LOW, 'AddContact', 0, $url);
+                               ++$added;
+                       } else {
+                               Worker::add(PRIORITY_LOW, 'UpdateContact', $contact['id']);
+                               ++$updated;
+                       }
+                       ++$count;
+               }
+
+               return ['count' => $count, 'added' => $added, 'updated' => $updated];
+       }
+
+       /**
+        * Set the last date that the contact had posted something
+        *
+        * This functionality is currently unused
+        *
+        * @param string $data  probing result
+        * @param bool   $force force updating
+        */
+       private static function setLastUpdate(array $data, bool $force = false)
+       {
+               $contact = self::getByURL($data['url'], false, []);
+               if (empty($contact)) {
+                       return;
+               }
+               if (!$force && !GServer::updateNeeded($contact['created'], $contact['updated'], $contact['last_failure'], $contact['last_contact'])) {
+                       Logger::info("Don't update profile", ['url' => $data['url'], 'updated' => $contact['updated']]);
+                       return;
+               }
+
+               if (self::updateFromNoScrape($data)) {
+                       return;
+               }
+
+               if (!empty($data['outbox'])) {
+                       self::updateFromOutbox($data['outbox'], $data);
+               } elseif (!empty($data['poll']) && ($data['network'] == Protocol::ACTIVITYPUB)) {
+                       self::updateFromOutbox($data['poll'], $data);
+               } elseif (!empty($data['poll'])) {
+                       self::updateFromFeed($data);
+               }
+       }
+
+       /**
+        * Update a global contact via the "noscrape" endpoint
+        *
+        * @param string $data Probing result
+        *
+        * @return bool 'true' if update was successful or the server was unreachable
+        */
+       private static function updateFromNoScrape(array $data)
+       {
+               // Check the 'noscrape' endpoint when it is a Friendica server
+               $gserver = DBA::selectFirst('gserver', ['noscrape'], ["`nurl` = ? AND `noscrape` != ''",
+               Strings::normaliseLink($data['baseurl'])]);
+               if (!DBA::isResult($gserver)) {
+                       return false;
+               }
+
+               $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 = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $noscrape['updated']];
+                               DBA::update('contact', $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 = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()];
+                       DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
+                       return true;
+               }
+               return false;
+       }
+
+       /**
+        * Update a global contact via an ActivityPub Outbox
+        *
+        * @param string $feed
+        * @param array  $data Probing result
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       private static function updateFromOutbox(string $feed, array $data)
+       {
+               $outbox = ActivityPub::fetchContent($feed);
+               if (empty($outbox)) {
+                       return;
+               }
+
+               if (!empty($outbox['orderedItems'])) {
+                       $items = $outbox['orderedItems'];
+               } elseif (!empty($outbox['first']['orderedItems'])) {
+                       $items = $outbox['first']['orderedItems'];
+               } elseif (!empty($outbox['first']['href']) && ($outbox['first']['href'] != $feed)) {
+                       self::updateFromOutbox($outbox['first']['href'], $data);
+                       return;
+               } elseif (!empty($outbox['first'])) {
+                       if (is_string($outbox['first']) && ($outbox['first'] != $feed)) {
+                               self::updateFromOutbox($outbox['first'], $data);
+                       } else {
+                               Logger::warning('Unexpected data', ['outbox' => $outbox]);
+                       }
+                       return;
+               } else {
+                       $items = [];
+               }
+
+               $last_updated = '';
+               foreach ($items as $activity) {
+                       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;
+                       }
+               }
+
+               if (empty($last_updated)) {
+                       return;
+               }
+
+               $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
+               DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
+       }
+
+       /**
+        * Update a global contact via an XML feed
+        *
+        * @param string $data Probing result
+        */
+       private static function updateFromFeed(array $data)
+       {
+               // Search for the newest entry in the feed
+               $curlResult = DI::httpRequest()->get($data['poll']);
+               if (!$curlResult->isSuccess()) {
+                       $fields = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()];
+                       DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
+
+                       Logger::info("Profile wasn't reachable (no feed)", ['url' => $data['url']]);
+                       return;
+               }
+
+               $doc = new DOMDocument();
+               @$doc->loadXML($curlResult->getBody());
+
+               $xpath = new DOMXPath($doc);
+               $xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
+
+               $entries = $xpath->query('/atom:feed/atom:entry');
+
+               $last_updated = '';
+
+               foreach ($entries as $entry) {
+                       $published_item = $xpath->query('atom:published/text()', $entry)->item(0);
+                       $updated_item   = $xpath->query('atom:updated/text()'  , $entry)->item(0);
+                       $published      = !empty($published_item->nodeValue) ? DateTimeFormat::utc($published_item->nodeValue) : null;
+                       $updated        = !empty($updated_item->nodeValue) ? DateTimeFormat::utc($updated_item->nodeValue) : null;
+
+                       if (empty($published) || empty($updated)) {
+                               Logger::notice('Invalid entry for XPath.', ['entry' => $entry, 'url' => $data['url']]);
+                               continue;
+                       }
+
+                       if ($last_updated < $published) {
+                               $last_updated = $published;
+                       }
+
+                       if ($last_updated < $updated) {
+                               $last_updated = $updated;
+                       }
+               }
+
+               if (empty($last_updated)) {
+                       return;
+               }
+
+               $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
+               DBA::update('contact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
+       }
 }
index fdf2d14077d8171c4bc063660b656fc922b8ca9e..6549e9efe23de0dbc410ec1340e66593f20845e4 100644 (file)
 
 namespace Friendica\Model;
 
-use DOMDocument;
-use DOMXPath;
 use Exception;
-use Friendica\Core\Logger;
 use Friendica\Core\Protocol;
-use Friendica\Core\Search;
-use Friendica\Core\System;
 use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Network\Probe;
-use Friendica\Protocol\ActivityPub;
-use Friendica\Protocol\PortableContact;
 use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Strings;
 
 /**
  * This class handles GlobalContact related functions
  */
 class GContact
 {
-       /**
-        * Link the gcontact entry with user, contact and global contact
-        *
-        * @param integer $gcid Global contact ID
-        * @param integer $uid  User ID
-        * @param integer $cid  Contact ID
-        * @param integer $zcid Global Contact ID
-        * @return void
-        * @throws Exception
-        */
-       public static function link($gcid, $uid = 0, $cid = 0, $zcid = 0)
-       {
-               if ($gcid <= 0) {
-                       return;
-               }
-
-               $condition = ['cid' => $cid, 'uid' => $uid, 'gcid' => $gcid, 'zcid' => $zcid];
-               DBA::update('glink', ['updated' => DateTimeFormat::utcNow()], $condition, true);
-       }
-
-       /**
-        * Sanitize the given gcontact data
-        *
-        * Generation:
-        *  0: No definition
-        *  1: Profiles on this server
-        *  2: Contacts of profiles on this server
-        *  3: Contacts of contacts of profiles on this server
-        *  4: ...
-        *
-        * @param array $gcontact array with gcontact data
-        * @return array $gcontact
-        * @throws Exception
-        */
-       public static function sanitize($gcontact)
-       {
-               if (empty($gcontact['url'])) {
-                       throw new Exception('URL is empty');
-               }
-
-               $gcontact['server_url'] = $gcontact['server_url'] ?? '';
-
-               $urlparts = parse_url($gcontact['url']);
-               if (empty($urlparts['scheme'])) {
-                       throw new Exception('This (' . $gcontact['url'] . ") doesn't seem to be an url.");
-               }
-
-               if (in_array($urlparts['host'], ['twitter.com', 'identi.ca'])) {
-                       throw new Exception('Contact from a non federated network ignored. (' . $gcontact['url'] . ')');
-               }
-
-               // Don't store the statusnet connector as network
-               // We can't simply set this to Protocol::OSTATUS since the connector could have fetched posts from friendica as well
-               if ($gcontact['network'] == Protocol::STATUSNET) {
-                       $gcontact['network'] = '';
-               }
-
-               // Assure that there are no parameter fragments in the profile url
-               if (empty($gcontact['*network']) || in_array($gcontact['network'], Protocol::FEDERATED)) {
-                       $gcontact['url'] = self::cleanContactUrl($gcontact['url']);
-               }
-
-               // The global contacts should contain the original picture, not the cached one
-               if (($gcontact['generation'] != 1) && stristr(Strings::normaliseLink($gcontact['photo']), Strings::normaliseLink(DI::baseUrl() . '/photo/'))) {
-                       $gcontact['photo'] = '';
-               }
-
-               if (empty($gcontact['network'])) {
-                       $gcontact['network'] = '';
-
-                       $condition = ["`uid` = 0 AND `nurl` = ? AND `network` != '' AND `network` != ?",
-                               Strings::normaliseLink($gcontact['url']), Protocol::STATUSNET];
-                       $contact = DBA::selectFirst('contact', ['network'], $condition);
-                       if (DBA::isResult($contact)) {
-                               $gcontact['network'] = $contact['network'];
-                       }
-
-                       if (($gcontact['network'] == '') || ($gcontact['network'] == Protocol::OSTATUS)) {
-                               $condition = ["`uid` = 0 AND `alias` IN (?, ?) AND `network` != '' AND `network` != ?",
-                                       $gcontact['url'], Strings::normaliseLink($gcontact['url']), Protocol::STATUSNET];
-                               $contact = DBA::selectFirst('contact', ['network'], $condition);
-                               if (DBA::isResult($contact)) {
-                                       $gcontact['network'] = $contact['network'];
-                               }
-                       }
-               }
-
-               $fields = ['network', 'updated', 'server_url', 'url', 'addr'];
-               $gcnt = DBA::selectFirst('gcontact', $fields, ['nurl' => Strings::normaliseLink($gcontact['url'])]);
-               if (DBA::isResult($gcnt)) {
-                       if (!isset($gcontact['network']) && ($gcnt['network'] != Protocol::STATUSNET)) {
-                               $gcontact['network'] = $gcnt['network'];
-                       }
-                       if ($gcontact['updated'] <= DBA::NULL_DATETIME) {
-                               $gcontact['updated'] = $gcnt['updated'];
-                       }
-                       if (!isset($gcontact['server_url']) && (Strings::normaliseLink($gcnt['server_url']) != Strings::normaliseLink($gcnt['url']))) {
-                               $gcontact['server_url'] = $gcnt['server_url'];
-                       }
-                       if (!isset($gcontact['addr'])) {
-                               $gcontact['addr'] = $gcnt['addr'];
-                       }
-               }
-
-               if ((!isset($gcontact['network']) || !isset($gcontact['name']) || !isset($gcontact['addr']) || !isset($gcontact['photo']) || !isset($gcontact['server_url']))
-                       && GServer::reachable($gcontact['url'], $gcontact['server_url'], $gcontact['network'], false)
-               ) {
-                       $data = Probe::uri($gcontact['url']);
-
-                       if ($data['network'] == Protocol::PHANTOM) {
-                               throw new Exception('Probing for URL ' . $gcontact['url'] . ' failed');
-                       }
-
-                       $gcontact['server_url'] = $data['baseurl'];
-                       $gcontact['failed'] = false;
-
-                       $gcontact = array_merge($gcontact, $data);
-               }
-
-               if (!isset($gcontact['name']) || !isset($gcontact['photo'])) {
-                       throw new Exception('No name and photo for URL '.$gcontact['url']);
-               }
-
-               if (!in_array($gcontact['network'], Protocol::FEDERATED)) {
-                       throw new Exception('No federated network (' . $gcontact['network'] . ') detected for URL ' . $gcontact['url']);
-               }
-
-               if (empty($gcontact['server_url'])) {
-                       // We check the server url to be sure that it is a real one
-                       $server_url = self::getBasepath($gcontact['url']);
-
-                       // We are now sure that it is a correct URL. So we use it in the future
-                       if ($server_url != '') {
-                               $gcontact['server_url'] = $server_url;
-                       }
-               }
-
-               // The server URL doesn't seem to be valid, so we don't store it.
-               if (!GServer::check($gcontact['server_url'], $gcontact['network'])) {
-                       $gcontact['server_url'] = '';
-               }
-
-               return $gcontact;
-       }
-
        /**
         * @param integer $uid id
         * @param integer $cid id
@@ -361,771 +206,6 @@ class GContact
                return $r;
        }
 
-       /**
-        * @return void
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        */
-       public static function updateSuggestions()
-       {
-               $done = [];
-
-               /// @TODO Check if it is really neccessary to poll the own server
-               PortableContact::loadWorker(0, 0, 0, DI::baseUrl() . '/poco');
-
-               $done[] = DI::baseUrl() . '/poco';
-
-               if (strlen(DI::config()->get('system', 'directory'))) {
-                       $x = DI::httpRequest()->fetch(Search::getGlobalDirectory() . '/pubsites');
-                       if (!empty($x)) {
-                               $j = json_decode($x);
-                               if (!empty($j->entries)) {
-                                       foreach ($j->entries as $entry) {
-                                               GServer::check($entry->url);
-
-                                               $url = $entry->url . '/poco';
-                                               if (!in_array($url, $done)) {
-                                                       PortableContact::loadWorker(0, 0, 0, $url);
-                                                       $done[] = $url;
-                                               }
-                                       }
-                               }
-                       }
-               }
-
-               // Query your contacts from Friendica and Redmatrix/Hubzilla for their contacts
-               $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);
-                       }
-               }
-               DBA::close($contacts);
-       }
-
-       /**
-        * Removes unwanted parts from a contact url
-        *
-        * @param string $url Contact url
-        *
-        * @return string Contact url with the wanted parts
-        * @throws Exception
-        */
-       public static function cleanContactUrl($url)
-       {
-               $parts = parse_url($url);
-
-               if (empty($parts['scheme']) || empty($parts['host'])) {
-                       return $url;
-               }
-
-               $new_url = $parts['scheme'] . '://' . $parts['host'];
-
-               if (!empty($parts['port'])) {
-                       $new_url .= ':' . $parts['port'];
-               }
-
-               if (!empty($parts['path'])) {
-                       $new_url .= $parts['path'];
-               }
-
-               if ($new_url != $url) {
-                       Logger::info('Cleaned contact url', ['url' => $url, 'new_url' => $new_url, 'callstack' => System::callstack()]);
-               }
-
-               return $new_url;
-       }
-
-       /**
-        * Fetch the gcontact id, add an entry if not existed
-        *
-        * @param array $contact contact array
-        *
-        * @return bool|int Returns false if not found, integer if contact was found
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function getId($contact)
-       {
-               if (empty($contact['network'])) {
-                       Logger::notice('Empty network', ['url' => $contact['url'], 'callstack' => System::callstack()]);
-                       return false;
-               }
-
-               if (in_array($contact['network'], [Protocol::PHANTOM])) {
-                       Logger::notice('Invalid network', ['url' => $contact['url'], 'callstack' => System::callstack()]);
-                       return false;
-               }
-
-               if ($contact['network'] == Protocol::STATUSNET) {
-                       $contact['network'] = Protocol::OSTATUS;
-               }
-
-               // Remove unwanted parts from the contact url (e.g. '?zrl=...')
-               if (in_array($contact['network'], Protocol::FEDERATED)) {
-                       $contact['url'] = self::cleanContactUrl($contact['url']);
-               }
-
-               $condition = ['nurl' => Strings::normaliseLink($contact['url'])];
-               $gcontact = DBA::selectFirst('gcontact', ['id'], $condition, ['order' => ['id']]);
-               if (DBA::isResult($gcontact)) {
-                       return $gcontact['id'];
-               }
-
-               $contact['location'] = $contact['location'] ?? '';
-               $contact['about'] = $contact['about'] ?? '';
-               $contact['generation'] = $contact['generation'] ?? 0;
-               $contact['hide'] = $contact['hide'] ?? true;
-
-               $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];
-
-               DBA::insert('gcontact', $fields);
-
-               // 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'];
-       }
-
-       /**
-        * Updates the gcontact table from a given array
-        *
-        * @param array $contact contact array
-        *
-        * @return bool|int Returns false if not found, integer if contact was found
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function update($contact)
-       {
-               // Check for invalid "contact-type" value
-               if (isset($contact['contact-type']) && (intval($contact['contact-type']) < 0)) {
-                       $contact['contact-type'] = 0;
-               }
-
-               /// @todo update contact table as well
-
-               $gcontact_id = self::getId($contact);
-
-               if (!$gcontact_id) {
-                       return false;
-               }
-
-               $public_contact = DBA::selectFirst('gcontact', [
-                       '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]);
-
-               if (!DBA::isResult($public_contact)) {
-                       return false;
-               }
-
-               // Get all field names
-               $fields = [];
-               foreach ($public_contact as $field => $data) {
-                       $fields[$field] = $data;
-               }
-
-               unset($fields['url']);
-               unset($fields['updated']);
-               unset($fields['hide']);
-
-               // Bugfix: We had an error in the storing of keywords which lead to the "0"
-               // This value is still transmitted via poco.
-               if (isset($contact['keywords']) && ($contact['keywords'] == '0')) {
-                       unset($contact['keywords']);
-               }
-
-               if (isset($public_contact['keywords']) && ($public_contact['keywords'] == '0')) {
-                       $public_contact['keywords'] = '';
-               }
-
-               // assign all unassigned fields from the database entry
-               foreach ($fields as $field => $data) {
-                       if (empty($contact[$field])) {
-                               $contact[$field] = $public_contact[$field];
-                       }
-               }
-
-               if (!isset($contact['hide'])) {
-                       $contact['hide'] = $public_contact['hide'];
-               }
-
-               $fields['hide'] = $public_contact['hide'];
-
-               if ($contact['network'] == Protocol::STATUSNET) {
-                       $contact['network'] = Protocol::OSTATUS;
-               }
-
-               if (!isset($contact['updated'])) {
-                       $contact['updated'] = DateTimeFormat::utcNow();
-               }
-
-               if ($contact['network'] == Protocol::TWITTER) {
-                       $contact['server_url'] = 'http://twitter.com';
-               }
-
-               if (empty($contact['server_url'])) {
-                       $data = Probe::uri($contact['url']);
-                       if ($data['network'] != Protocol::PHANTOM) {
-                               $contact['server_url'] = $data['baseurl'];
-                       }
-               } else {
-                       $contact['server_url'] = Strings::normaliseLink($contact['server_url']);
-               }
-
-               if (!empty($contact['server_url']) && empty($contact['gsid'])) {
-                       $contact['gsid'] = GServer::getID($contact['server_url']);
-               }
-
-               if (empty($contact['addr']) && !empty($contact['server_url']) && !empty($contact['nick'])) {
-                       $hostname = str_replace('http://', '', $contact['server_url']);
-                       $contact['addr'] = $contact['nick'] . '@' . $hostname;
-               }
-
-               // Check if any field changed
-               $update = false;
-               unset($fields['generation']);
-
-               if ((($contact['generation'] > 0) && ($contact['generation'] <= $public_contact['generation'])) || ($public_contact['generation'] == 0)) {
-                       foreach ($fields as $field => $data) {
-                               if ($contact[$field] != $public_contact[$field]) {
-                                       Logger::debug('Difference found.', ['contact' => $contact['url'], 'field' => $field, 'new' => $contact[$field], 'old' => $public_contact[$field]]);
-                                       $update = true;
-                               }
-                       }
-
-                       if ($contact['generation'] < $public_contact['generation']) {
-                               Logger::debug('Difference found.', ['contact' => $contact['url'], 'field' => 'generation', 'new' => $contact['generation'], 'old' => $public_contact['generation']]);
-                               $update = true;
-                       }
-               }
-
-               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']);
-
-                       $updated = [
-                               'photo' => $contact['photo'], 'name' => $contact['name'],
-                               'nick' => $contact['nick'], 'addr' => $contact['addr'],
-                               'network' => $contact['network'], 'birthday' => $contact['birthday'],
-                               'keywords' => $contact['keywords'],
-                               'hide' => $contact['hide'], 'nsfw' => $contact['nsfw'],
-                               'contact-type' => $contact['contact-type'], 'alias' => $contact['alias'],
-                               'notify' => $contact['notify'], 'url' => $contact['url'],
-                               'location' => $contact['location'], 'about' => $contact['about'],
-                               'generation' => $contact['generation'], 'updated' => $contact['updated'],
-                               'server_url' => $contact['server_url'], 'connect' => $contact['connect'],
-                               'failed' => $contact['failed'], 'gsid' => $contact['gsid']
-                       ];
-
-                       DBA::update('gcontact', $updated, $condition, $fields);
-               }
-
-               return $gcontact_id;
-       }
-
-       /**
-        * Set the last date that the contact had posted something
-        *
-        * @param string $data  Probing result
-        * @param bool   $force force updating
-        */
-       public static function setLastUpdate(array $data, bool $force = false)
-       {
-               // Fetch the global contact
-               $gcontact = DBA::selectFirst('gcontact', ['created', 'updated', 'last_contact', 'last_failure'],
-                       ['nurl' => Strings::normaliseLink($data['url'])]);
-               if (!DBA::isResult($gcontact)) {
-                       return;
-               }
-
-               if (!$force && !GServer::updateNeeded($gcontact['created'], $gcontact['updated'], $gcontact['last_failure'], $gcontact['last_contact'])) {
-                       Logger::info("Don't update profile", ['url' => $data['url'], 'updated' => $gcontact['updated']]);
-                       return;
-               }
-
-               if (self::updateFromNoScrape($data)) {
-                       return;
-               }
-
-               if (!empty($data['outbox'])) {
-                       self::updateFromOutbox($data['outbox'], $data);
-               } elseif (!empty($data['poll']) && ($data['network'] == Protocol::ACTIVITYPUB)) {
-                       self::updateFromOutbox($data['poll'], $data);
-               } elseif (!empty($data['poll'])) {
-                       self::updateFromFeed($data);
-               }
-       }
-
-       /**
-        * Update a global contact via the "noscrape" endpoint
-        *
-        * @param string $data Probing result
-        *
-        * @return bool 'true' if update was successful or the server was unreachable
-        */
-       private static function updateFromNoScrape(array $data)
-       {
-               // Check the 'noscrape' endpoint when it is a Friendica server
-               $gserver = DBA::selectFirst('gserver', ['noscrape'], ["`nurl` = ? AND `noscrape` != ''",
-               Strings::normaliseLink($data['baseurl'])]);
-               if (!DBA::isResult($gserver)) {
-                       return false;
-               }
-
-               $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 = ['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 = ['failed' => true, 'last_failure' => DateTimeFormat::utcNow()];
-                       DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
-                       return true;
-               }
-               return false;
-       }
-
-       /**
-        * Update a global contact via an ActivityPub Outbox
-        *
-        * @param string $feed
-        * @param array  $data Probing result
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        */
-       private static function updateFromOutbox(string $feed, array $data)
-       {
-               $outbox = ActivityPub::fetchContent($feed);
-               if (empty($outbox)) {
-                       return;
-               }
-
-               if (!empty($outbox['orderedItems'])) {
-                       $items = $outbox['orderedItems'];
-               } elseif (!empty($outbox['first']['orderedItems'])) {
-                       $items = $outbox['first']['orderedItems'];
-               } elseif (!empty($outbox['first']['href']) && ($outbox['first']['href'] != $feed)) {
-                       self::updateFromOutbox($outbox['first']['href'], $data);
-                       return;
-               } elseif (!empty($outbox['first'])) {
-                       if (is_string($outbox['first']) && ($outbox['first'] != $feed)) {
-                               self::updateFromOutbox($outbox['first'], $data);
-                       } else {
-                               Logger::warning('Unexpected data', ['outbox' => $outbox]);
-                       }
-                       return;
-               } else {
-                       $items = [];
-               }
-
-               $last_updated = '';
-               foreach ($items as $activity) {
-                       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;
-                       }
-               }
-
-               if (empty($last_updated)) {
-                       return;
-               }
-
-               $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
-               DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
-       }
-
-       /**
-        * Update a global contact via an XML feed
-        *
-        * @param string $data Probing result
-        */
-       private static function updateFromFeed(array $data)
-       {
-               // Search for the newest entry in the feed
-               $curlResult = DI::httpRequest()->get($data['poll']);
-               if (!$curlResult->isSuccess()) {
-                       $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']]);
-                       return;
-               }
-
-               $doc = new DOMDocument();
-               @$doc->loadXML($curlResult->getBody());
-
-               $xpath = new DOMXPath($doc);
-               $xpath->registerNamespace('atom', 'http://www.w3.org/2005/Atom');
-
-               $entries = $xpath->query('/atom:feed/atom:entry');
-
-               $last_updated = '';
-
-               foreach ($entries as $entry) {
-                       $published_item = $xpath->query('atom:published/text()', $entry)->item(0);
-                       $updated_item   = $xpath->query('atom:updated/text()'  , $entry)->item(0);
-                       $published      = !empty($published_item->nodeValue) ? DateTimeFormat::utc($published_item->nodeValue) : null;
-                       $updated        = !empty($updated_item->nodeValue) ? DateTimeFormat::utc($updated_item->nodeValue) : null;
-
-                       if (empty($published) || empty($updated)) {
-                               Logger::notice('Invalid entry for XPath.', ['entry' => $entry, 'url' => $data['url']]);
-                               continue;
-                       }
-
-                       if ($last_updated < $published) {
-                               $last_updated = $published;
-                       }
-
-                       if ($last_updated < $updated) {
-                               $last_updated = $updated;
-                       }
-               }
-
-               if (empty($last_updated)) {
-                       return;
-               }
-
-               $fields = ['failed' => false, 'last_contact' => DateTimeFormat::utcNow(), 'updated' => $last_updated];
-               DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($data['url'])]);
-       }
-       /**
-        * Updates the gcontact entry from a given public contact id
-        *
-        * @param integer $cid contact id
-        * @return void
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function updateFromPublicContactID($cid)
-       {
-               self::updateFromPublicContact(['id' => $cid]);
-       }
-
-       /**
-        * Updates the gcontact entry from a given public contact url
-        *
-        * @param string $url contact url
-        * @return integer gcontact id
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function updateFromPublicContactURL($url)
-       {
-               return self::updateFromPublicContact(['nurl' => Strings::normaliseLink($url)]);
-       }
-
-       /**
-        * Helper function for updateFromPublicContactID and updateFromPublicContactURL
-        *
-        * @param array $condition contact condition
-        * @return integer gcontact id
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       private static function updateFromPublicContact($condition)
-       {
-               $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', 'failed'];
-
-               $contact = DBA::selectFirst('contact', $fields, array_merge($condition, ['uid' => 0, 'network' => Protocol::FEDERATED]));
-               if (!DBA::isResult($contact)) {
-                       return 0;
-               }
-
-               $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', 'failed'];
-
-               $old_gcontact = DBA::selectFirst('gcontact', $fields, ['nurl' => $contact['nurl']]);
-               $do_insert = !DBA::isResult($old_gcontact);
-               if ($do_insert) {
-                       $old_gcontact = [];
-               }
-
-               $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', 'failed'];
-
-               foreach ($fields as $field) {
-                       $gcontact[$field] = $contact[$field];
-               }
-
-               // These fields are having different names but the same content
-               $gcontact['server_url'] = $contact['baseurl'] ?? ''; // "baseurl" can be null, "server_url" not
-               $gcontact['nsfw'] = $contact['sensitive'];
-               $gcontact['hide'] = $contact['unsearchable'];
-               $gcontact['archived'] = $contact['archive'];
-               $gcontact['archive_date'] = $contact['term-date'];
-               $gcontact['birthday'] = $contact['bd'];
-               $gcontact['photo'] = $contact['avatar'];
-               $gcontact['last_contact'] = $contact['success_update'];
-               $gcontact['last_failure'] = $contact['failure_update'];
-               $gcontact['community'] = ($contact['forum'] || $contact['prv']);
-
-               foreach (['last_contact', 'last_failure', 'updated'] as $field) {
-                       if (!empty($old_gcontact[$field]) && ($old_gcontact[$field] >= $gcontact[$field])) {
-                               unset($gcontact[$field]);
-                       }
-               }
-
-               if (!$gcontact['archived']) {
-                       $gcontact['archive_date'] = DBA::NULL_DATETIME;
-               }
-
-               if (!empty($old_gcontact['created']) && ($old_gcontact['created'] > DBA::NULL_DATETIME)
-                       && ($old_gcontact['created'] <= $gcontact['created'])) {
-                       unset($gcontact['created']);
-               }
-
-               if (empty($gcontact['birthday']) && ($gcontact['birthday'] <= DBA::NULL_DATETIME)) {
-                       unset($gcontact['birthday']);
-               }
-
-               if (empty($old_gcontact['generation']) || ($old_gcontact['generation'] > 2)) {
-                       $gcontact['generation'] = 2; // We fetched the data directly from the other server
-               }
-
-               if (!$do_insert) {
-                       DBA::update('gcontact', $gcontact, ['nurl' => $contact['nurl']], $old_gcontact);
-                       return $old_gcontact['id'];
-               } elseif (!$gcontact['archived']) {
-                       DBA::insert('gcontact', $gcontact);
-                       return DBA::lastInsertId();
-               }
-       }
-
-       /**
-        * Updates the gcontact entry from probe
-        *
-        * @param string  $url   profile link
-        * @param boolean $force Optional forcing of network probing (otherwise we use the cached data)
-        *
-        * @return boolean 'true' when contact had been updated
-        *
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function updateFromProbe($url, $force = false)
-       {
-               $data = Probe::uri($url, $force);
-
-               if (in_array($data['network'], [Protocol::PHANTOM])) {
-                       $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);
-
-               // Set the date of the latest post
-               self::setLastUpdate($data, $force);
-
-               return true;
-       }
-
-       /**
-        * Update the gcontact entry for a given user id
-        *
-        * @param int $uid User ID
-        * @return bool
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function updateForUser($uid)
-       {
-               $profile = Profile::getByUID($uid);
-               if (empty($profile)) {
-                       Logger::error('Cannot find profile', ['uid' => $uid]);
-                       return false;
-               }
-
-               $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' => $userdata['locality'], 'region' => $userdata['region'], 'country-name' => $userdata['country-name']]
-               );
-
-               $gcontact = ['name' => $userdata['name'], 'location' => $location, 'about' => $userdata['about'],
-                               'keywords' => $userdata['pub_keywords'],
-                               'birthday' => $userdata['dob'], 'photo' => $userdata['photo'],
-                               "notify" => $userdata['notify'], 'url' => $userdata['url'],
-                               "hide" => !$userdata['net-publish'],
-                               'nick' => $userdata['nickname'], 'addr' => $userdata['addr'],
-                               "connect" => $userdata['addr'], "server_url" => DI::baseUrl(),
-                               "generation" => 1, 'network' => Protocol::DFRN];
-
-               self::update($gcontact);
-       }
-
-       /**
-        * Get the basepath for a given contact link
-        *
-        * @param string $url The gcontact link
-        * @param boolean $dont_update Don't update the contact
-        *
-        * @return string basepath
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function getBasepath($url, $dont_update = false)
-       {
-               $gcontact = DBA::selectFirst('gcontact', ['server_url'], ['nurl' => Strings::normaliseLink($url)]);
-               if (!empty($gcontact['server_url'])) {
-                       return $gcontact['server_url'];
-               } elseif ($dont_update) {
-                       return '';
-               }
-
-               self::updateFromProbe($url, true);
-
-               // Fetch the result
-               $gcontact = DBA::selectFirst('gcontact', ['server_url'], ['nurl' => Strings::normaliseLink($url)]);
-               if (empty($gcontact['server_url'])) {
-                       Logger::info('No baseurl for gcontact', ['url' => $url]);
-                       return '';
-               }
-
-               Logger::info('Found baseurl for gcontact', ['url' => $url, 'baseurl' => $gcontact['server_url']]);
-               return $gcontact['server_url'];
-       }
-
-       /**
-        * Fetches users of given GNU Social server
-        *
-        * If the "Statistics" addon is enabled (See http://gstools.org/ for details) we query user data with this.
-        *
-        * @param string $server Server address
-        * @return bool
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function fetchGsUsers($server)
-       {
-               Logger::info('Fetching users from GNU Social server', ['server' => $server]);
-
-               $url = $server . '/main/statistics';
-
-               $curlResult = DI::httpRequest()->get($url);
-               if (!$curlResult->isSuccess()) {
-                       return false;
-               }
-
-               $statistics = json_decode($curlResult->getBody());
-
-               if (!empty($statistics->config->instance_address)) {
-                       if (!empty($statistics->config->instance_with_ssl)) {
-                               $server = 'https://';
-                       } else {
-                               $server = 'http://';
-                       }
-
-                       $server .= $statistics->config->instance_address;
-
-                       $hostname = $statistics->config->instance_address;
-               } elseif (!empty($statistics->instance_address)) {
-                       if (!empty($statistics->instance_with_ssl)) {
-                               $server = 'https://';
-                       } else {
-                               $server = 'http://';
-                       }
-
-                       $server .= $statistics->instance_address;
-
-                       $hostname = $statistics->instance_address;
-               }
-
-               if (!empty($statistics->users)) {
-                       foreach ($statistics->users as $nick => $user) {
-                               $profile_url = $server . '/' . $user->nickname;
-
-                               $contact = ['url' => $profile_url,
-                                               'name' => $user->fullname,
-                                               'addr' => $user->nickname . '@' . $hostname,
-                                               'nick' => $user->nickname,
-                                               "network" => Protocol::OSTATUS,
-                                               'photo' => DI::baseUrl() . '/images/person-300.jpg'];
-
-                               if (isset($user->bio)) {
-                                       $contact['about'] = $user->bio;
-                               }
-
-                               self::getId($contact);
-                       }
-               }
-       }
-
-       /**
-        * Asking GNU Social server on a regular base for their user data
-        *
-        * @return void
-        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
-        * @throws \ImagickException
-        */
-       public static function discoverGsUsers()
-       {
-               $requery_days = intval(DI::config()->get('system', 'poco_requery_days'));
-
-               $last_update = date("c", time() - (60 * 60 * 24 * $requery_days));
-
-               $r = DBA::select('gserver', ['nurl', 'url'], [
-                       '`network` = ?
-                       AND NOT `failed`
-                       AND `last_poco_query` < ?',
-                       Protocol::OSTATUS,
-                       $last_update
-               ], [
-                       'limit' => 5,
-                       'order' => ['RAND()']
-               ]);
-
-               if (!DBA::isResult($r)) {
-                       return;
-               }
-
-               foreach ($r as $server) {
-                       self::fetchGsUsers($server['url']);
-                       DBA::update('gserver', ['last_poco_query' => DateTimeFormat::utcNow()], ['nurl' => $server['nurl']]);
-               }
-       }
-
        /**
         * Returns a random, global contact of the current node
         *
index 07a5eaad3ec93374362c155bbfb1ff12555d25b4..aa598a729a0756a6950bf6e0210048983c8fd1f9 100644 (file)
@@ -32,7 +32,6 @@ use Friendica\DI;
 use Friendica\Module\Register;
 use Friendica\Network\CurlResult;
 use Friendica\Protocol\Diaspora;
-use Friendica\Protocol\PortableContact;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Network;
 use Friendica\Util\Strings;
@@ -111,7 +110,10 @@ class GServer
        public static function reachable(string $profile, string $server = '', string $network = '', bool $force = false)
        {
                if ($server == '') {
-                       $server = GContact::getBasepath($profile);
+                       $contact = Contact::getByURL($profile, null, ['baseurl']);
+                       if (!empty($contact['baseurl'])) {
+                               $server = $contact['baseurl'];
+                       }
                }
 
                if ($server == '') {
@@ -471,10 +473,9 @@ class GServer
                }
 
                if (!empty($serverdata['network']) && !empty($id) && ($serverdata['network'] != Protocol::PHANTOM)) {
-                       $gcontacts = DBA::count('gcontact', ['gsid' => $id]);
                        $apcontacts = DBA::count('apcontact', ['gsid' => $id]);
                        $contacts = DBA::count('contact', ['uid' => 0, 'gsid' => $id]);
-                       $max_users = max($gcontacts, $apcontacts, $contacts, $registeredUsers);
+                       $max_users = max($apcontacts, $contacts, $registeredUsers);
                        if ($max_users > $registeredUsers) {
                                Logger::info('Update registered users', ['id' => $id, 'url' => $serverdata['nurl'], 'registered-users' => $max_users]);
                                DBA::update('gserver', ['registered-users' => $max_users], ['id' => $id]);
@@ -959,12 +960,6 @@ class GServer
        {
                $contacts = [];
 
-               $gcontacts = DBA::select('gcontact', ['url', 'nurl'], ['server_url' => [$url, $serverdata['nurl']]]);
-               while ($gcontact = DBA::fetch($gcontacts)) {
-                       $contacts[$gcontact['nurl']] = $gcontact['url'];
-               }
-               DBA::close($gcontacts);
-
                $apcontacts = DBA::select('apcontact', ['url'], ['baseurl' => [$url, $serverdata['nurl']]]);
                while ($apcontact = DBA::fetch($apcontacts)) {
                        $contacts[Strings::normaliseLink($apcontact['url'])] = $apcontact['url'];
@@ -1556,20 +1551,6 @@ class GServer
                return !strpos($body, '>');
        }
 
-       /**
-        * Update the user directory of a given gserver record
-        *
-        * @param array $gserver gserver record
-        */
-       public static function updateDirectory(array $gserver)
-       {
-               /// @todo Add Mastodon API directory
-
-               if (!empty($gserver['poco'])) {
-                       PortableContact::discoverSingleServer($gserver['id']);
-               }
-       }
-
        /**
         * Update GServer entries
         */
@@ -1588,7 +1569,7 @@ class GServer
 
                $last_update = date('c', time() - (60 * 60 * 24 * $requery_days));
 
-               $gservers = DBA::p("SELECT `id`, `url`, `nurl`, `network`, `poco`
+               $gservers = DBA::p("SELECT `id`, `url`, `nurl`, `network`, `poco`, `directory-type`
                        FROM `gserver`
                        WHERE NOT `failed`
                        AND `directory-type` != ?
@@ -1672,4 +1653,18 @@ class GServer
 
                DI::config()->set('poco', 'last_federation_discovery', time());
        }
+
+       /**
+        * Returns a list of 1,000 active servers order by the last contact
+        *
+        * @return array List of server urls
+        * @throws Exception
+        */
+       public static function getActive()
+       {
+               $result = DBA::p("SELECT `url`, `site_name` AS `displayName`, `network`, `platform`, `version` FROM `gserver`
+                       WHERE `network` IN (?, ?, ?, ?) AND NOT `failed` ORDER BY `last_contact` LIMIT ?",
+                       Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::ACTIVITYPUB, 1000);
+               return DBA::toArray($result);
+       }
 }
index fd60b071526b88fc65e3b8106342db0554c72548..d0d30e85e10ff9f4de7405fd72a229fdcbba4b6a 100644 (file)
@@ -132,7 +132,6 @@ class Federation extends BaseAdmin
 
                // some helpful text
                $intro = DI::l10n()->t('This page offers you some numbers to the known part of the federated social network your Friendica node is part of. These numbers are not complete but only reflect the part of the network your node is aware of.');
-               $hint = DI::l10n()->t('The <em>Auto Discovered Contact Directory</em> feature is not enabled, it will improve the data displayed here.');
 
                // load the template, replace the macros and return the page content
                $t = Renderer::getMarkupTemplate('admin/federation.tpl');
@@ -140,8 +139,6 @@ class Federation extends BaseAdmin
                        '$title' => DI::l10n()->t('Administration'),
                        '$page' => DI::l10n()->t('Federation Statistics'),
                        '$intro' => $intro,
-                       '$hint' => $hint,
-                       '$autoactive' => DI::config()->get('system', 'poco_completion'),
                        '$counts' => $counts,
                        '$version' => FRIENDICA_VERSION,
                        '$legendtext' => DI::l10n()->t('Currently this node is aware of %d nodes with %d registered users from the following platforms:', $total, $users),
index 3bdcd71147c34dd4f986243bbc90afed4e92b48c..7b298cd937db4da836f4ee9bb9831e25c3c72df7 100644 (file)
@@ -31,7 +31,6 @@ use Friendica\DI;
 use Friendica\Model\ContactRelation;
 use Friendica\Module\BaseAdmin;
 use Friendica\Module\Register;
-use Friendica\Protocol\PortableContact;
 use Friendica\Util\BasePath;
 use Friendica\Util\EMailer\MailBuilder;
 use Friendica\Util\Strings;
@@ -104,12 +103,10 @@ class Site extends BaseAdmin
                        // update profile links in the format "http://server.tld"
                        update_table($a, "profile", ['photo', 'thumb'], $old_url, $new_url);
                        update_table($a, "contact", ['photo', 'thumb', 'micro', 'url', 'nurl', 'alias', 'request', 'notify', 'poll', 'confirm', 'poco', 'avatar'], $old_url, $new_url);
-                       update_table($a, "gcontact", ['url', 'nurl', 'photo', 'server_url', 'notify', 'alias'], $old_url, $new_url);
                        update_table($a, "item", ['owner-link', 'author-link', 'body', 'plink', 'tag'], $old_url, $new_url);
 
                        // update profile addresses in the format "user@server.tld"
                        update_table($a, "contact", ['addr'], $old_host, $new_host);
-                       update_table($a, "gcontact", ['connect', 'addr'], $old_host, $new_host);
 
                        // update config
                        DI::config()->set('system', 'url', $new_url);
@@ -180,10 +177,8 @@ class Site extends BaseAdmin
                $optimize_fragmentation = (!empty($_POST['optimize_fragmentation']) ? intval(trim($_POST['optimize_fragmentation'])) : 30);
                $contact_discovery      = (!empty($_POST['contact_discovery'])      ? intval(trim($_POST['contact_discovery']))      : ContactRelation::DISCOVERY_NONE);
                $synchronize_directory  = (!empty($_POST['synchronize_directory'])  ? intval(trim($_POST['synchronize_directory']))  : false);
-               $poco_completion        = (!empty($_POST['poco_completion'])        ? intval(trim($_POST['poco_completion']))        : false);
                $poco_requery_days      = (!empty($_POST['poco_requery_days'])      ? intval(trim($_POST['poco_requery_days']))      : 7);
-               $poco_discovery         = (!empty($_POST['poco_discovery'])         ? intval(trim($_POST['poco_discovery']))         : PortableContact::DISABLED);
-               $poco_discovery_since   = (!empty($_POST['poco_discovery_since'])   ? intval(trim($_POST['poco_discovery_since']))   : 30);
+               $poco_discovery         = (!empty($_POST['poco_discovery'])         ? intval(trim($_POST['poco_discovery']))         : false);
                $poco_local_search      = !empty($_POST['poco_local_search']);
                $nodeinfo               = !empty($_POST['nodeinfo']);
                $dfrn_only              = !empty($_POST['dfrn_only']);
@@ -308,12 +303,10 @@ class Site extends BaseAdmin
                DI::config()->set('system', 'min_memory'            , $min_memory);
                DI::config()->set('system', 'optimize_max_tablesize', $optimize_max_tablesize);
                DI::config()->set('system', 'optimize_fragmentation', $optimize_fragmentation);
-               DI::config()->set('system', 'poco_completion'       , $poco_completion);
                DI::config()->set('system', 'contact_discovery'     , $contact_discovery);
                DI::config()->set('system', 'synchronize_directory' , $synchronize_directory);
                DI::config()->set('system', 'poco_requery_days'     , $poco_requery_days);
                DI::config()->set('system', 'poco_discovery'        , $poco_discovery);
-               DI::config()->set('system', 'poco_discovery_since'  , $poco_discovery_since);
                DI::config()->set('system', 'poco_local_search'     , $poco_local_search);
                DI::config()->set('system', 'nodeinfo'              , $nodeinfo);
                DI::config()->set('config', 'sitename'              , $sitename);
@@ -490,20 +483,6 @@ class Site extends BaseAdmin
                        CP_USERS_AND_GLOBAL => DI::l10n()->t('Public postings from local users and the federated network')
                ];
 
-               $poco_discovery_choices = [
-                       PortableContact::DISABLED => DI::l10n()->t('Disabled'),
-                       PortableContact::USERS => DI::l10n()->t('Users'),
-                       PortableContact::USERS_GCONTACTS => DI::l10n()->t('Users, Global Contacts'),
-                       PortableContact::USERS_GCONTACTS_FALLBACK => DI::l10n()->t('Users, Global Contacts/fallback'),
-               ];
-
-               $poco_discovery_since_choices = [
-                       '30' => DI::l10n()->t('One month'),
-                       '91' => DI::l10n()->t('Three months'),
-                       '182' => DI::l10n()->t('Half a year'),
-                       '365' => DI::l10n()->t('One year'),
-               ];
-
                /* get user names to make the install a personal install of X */
                // @TODO Move to Model\User::getNames()
                $user_names = [];
@@ -688,10 +667,8 @@ class Site extends BaseAdmin
                                $discovery_choices],
                        '$synchronize_directory'  => ['synchronize_directory', DI::l10n()->t('Synchronize the contacts with the directory server'), DI::config()->get('system', 'synchronize_directory'), DI::l10n()->t('if enabled, the system will check periodically for new contacts on the defined directory server.')],
 
-                       '$poco_completion'        => ['poco_completion', DI::l10n()->t('Periodical check of global contacts'), DI::config()->get('system', 'poco_completion'), DI::l10n()->t('If enabled, the global contacts are checked periodically for missing or outdated data and the vitality of the contacts and servers.')],
                        '$poco_requery_days'      => ['poco_requery_days', DI::l10n()->t('Days between requery'), DI::config()->get('system', 'poco_requery_days'), DI::l10n()->t('Number of days after which a server is requeried for his contacts.')],
-                       '$poco_discovery'         => ['poco_discovery', DI::l10n()->t('Discover contacts from other servers'), DI::config()->get('system', 'poco_discovery'), DI::l10n()->t('Periodically query other servers for contacts. You can choose between "Users": the users on the remote system, "Global Contacts": active contacts that are known on the system. The fallback is meant for Redmatrix servers and older friendica servers, where global contacts weren\'t available. The fallback increases the server load, so the recommended setting is "Users, Global Contacts".'), $poco_discovery_choices],
-                       '$poco_discovery_since'   => ['poco_discovery_since', DI::l10n()->t('Timeframe for fetching global contacts'), DI::config()->get('system', 'poco_discovery_since'), DI::l10n()->t('When the discovery is activated, this value defines the timeframe for the activity of the global contacts that are fetched from other servers.'), $poco_discovery_since_choices],
+                       '$poco_discovery'         => ['poco_discovery', DI::l10n()->t('Discover contacts from other servers'), DI::config()->get('system', 'poco_discovery'), DI::l10n()->t('Periodically query other servers for contacts. The system queries Friendica, Mastodon and Hubzilla servers.')],
                        '$poco_local_search'      => ['poco_local_search', DI::l10n()->t('Search the local directory'), DI::config()->get('system', 'poco_local_search'), DI::l10n()->t('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.')],
 
                        '$nodeinfo'               => ['nodeinfo', DI::l10n()->t('Publish server information'), DI::config()->get('system', 'nodeinfo'), DI::l10n()->t('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.')],
index 40148c50d1e631be7e6d58926fc83313e81bf99c..bf22470ed4babce42aaa88cc81e171da1335db95 100644 (file)
@@ -186,9 +186,6 @@ class Contact extends BaseModule
 
                // Update the entry in the contact table
                Model\Contact::updateFromProbe($contact_id, '', true);
-
-               // Update the entry in the gcontact table
-               Model\GContact::updateFromProbe($contact['url']);
        }
 
        /**
index 1457a1125f2f69101d062d4af54b2d3fc2e8a26e..4ad0e53069effa95dd6c40e93de8425f4558d0b5 100644 (file)
@@ -26,14 +26,13 @@ use Friendica\Core\Protocol;
 use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
-use Friendica\Model\GContact;
 use Friendica\Model\Profile;
 use Friendica\Model\User;
 
 /**
  * Endpoint for getting current user infos
  *
- * @see GContact::updateFromNoScrape() for usage
+ * @see Contact::updateFromNoScrape() for usage
  */
 class NoScrape extends BaseModule
 {
index a7e02f4299bf7ef3cc22c9d1866f948b220663b9..f4c902b829f3bea915e14ef02c016713a2e6fcf8 100644 (file)
@@ -31,7 +31,6 @@ use Friendica\Core\Worker;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Contact;
-use Friendica\Model\GContact;
 use Friendica\Model\Profile;
 use Friendica\Model\ProfileField;
 use Friendica\Model\User;
@@ -151,9 +150,6 @@ class Index extends BaseSettings
                }
 
                Worker::add(PRIORITY_LOW, 'ProfileUpdate', local_user());
-
-               // Update the global contact for the user
-               GContact::updateForUser(local_user());
        }
 
        public static function content(array $parameters = [])
index f213af8db3068299739b33eaf56da5f5253b3b2b..281220bc347224fa72a9e1d99f9e1fa8a97956b4 100644 (file)
@@ -33,7 +33,6 @@ use Friendica\DI;
 use Friendica\Model\Contact;
 use Friendica\Model\Conversation;
 use Friendica\Model\Event;
-use Friendica\Model\GContact;
 use Friendica\Model\Item;
 use Friendica\Model\ItemURI;
 use Friendica\Model\Mail;
@@ -1686,21 +1685,6 @@ class DFRN
                        if (!empty($pcid)) {
                                Contact::updateAvatar($pcid, $author['avatar']);
                        }
-
-                       /*
-                        * The generation is a sign for the reliability of the provided data.
-                        * It is used in the socgraph.php to prevent that old contact data
-                        * that was relayed over several servers can overwrite contact
-                        * data that we received directly.
-                        */
-
-                       $poco["generation"] = 2;
-                       $poco["photo"] = $author["avatar"];
-                       $poco["hide"] = $hide;
-                       $poco["contact-type"] = $contact["contact-type"];
-                       $gcid = GContact::update($poco);
-
-                       GContact::link($gcid, $importer["importer_uid"], $contact["id"]);
                }
 
                return $author;
@@ -1943,15 +1927,6 @@ class DFRN
 
                $old = $r[0];
 
-               // Update the gcontact entry
-               $relocate["server_url"] = preg_replace("=(https?://)(.*)/profile/(.*)=ism", "$1$2", $relocate["url"]);
-
-               $fields = ['name' => $relocate["name"], 'photo' => $relocate["avatar"],
-                       'url' => $relocate["url"], 'nurl' => Strings::normaliseLink($relocate["url"]),
-                       'addr' => $relocate["addr"], 'connect' => $relocate["addr"],
-                       'notify' => $relocate["notify"], 'server_url' => $relocate["server_url"]];
-               DBA::update('gcontact', $fields, ['nurl' => Strings::normaliseLink($old["url"])]);
-
                // Update the contact table. We try to find every entry.
                $fields = ['name' => $relocate["name"], 'avatar' => $relocate["avatar"],
                        'url' => $relocate["url"], 'nurl' => Strings::normaliseLink($relocate["url"]),
index f3b95db68f2fb1c5756cb494e73b96b51b121de5..feb1111443a4bcb06324853eaeb0d3bbc66489e8 100644 (file)
@@ -34,7 +34,6 @@ use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Contact;
 use Friendica\Model\Conversation;
-use Friendica\Model\GContact;
 use Friendica\Model\Item;
 use Friendica\Model\ItemURI;
 use Friendica\Model\Mail;
@@ -1656,7 +1655,7 @@ class Diaspora
                // Update the profile
                self::receiveProfile($importer, $data->profile);
 
-               // change the technical stuff in contact and gcontact
+               // change the technical stuff in contact
                $data = Probe::uri($new_handle);
                if ($data['network'] == Protocol::PHANTOM) {
                        Logger::log('Account for '.$new_handle." couldn't be probed.");
@@ -1671,14 +1670,6 @@ class Diaspora
 
                DBA::update('contact', $fields, ['addr' => $old_handle]);
 
-               $fields = ['url' => $data['url'], 'nurl' => Strings::normaliseLink($data['url']),
-                               'name' => $data['name'], 'nick' => $data['nick'],
-                               'addr' => $data['addr'], 'connect' => $data['addr'],
-                               'notify' => $data['notify'], 'photo' => $data['photo'],
-                               'server_url' => $data['baseurl'], 'network' => $data['network']];
-
-               DBA::update('gcontact', $fields, ['addr' => $old_handle]);
-
                Logger::log('Contacts are updated.');
 
                return true;
@@ -1702,8 +1693,6 @@ class Diaspora
                }
                DBA::close($contacts);
 
-               DBA::delete('gcontact', ['addr' => $author]);
-
                Logger::log('Removed contacts for ' . $author);
 
                return true;
@@ -2438,18 +2427,6 @@ class Diaspora
 
                DBA::update('contact', $fields, ['id' => $contact['id']]);
 
-               // @todo Update the public contact, then update the gcontact from that
-
-               $gcontact = ["url" => $contact["url"], "network" => Protocol::DIASPORA, "generation" => 2,
-                                       "photo" => $image_url, "name" => $name, "location" => $location,
-                                       "about" => $about, "birthday" => $birthday,
-                                       "addr" => $author, "nick" => $nick, "keywords" => $keywords,
-                                       "hide" => !$searchable, "nsfw" => $nsfw];
-
-               $gcid = GContact::update($gcontact);
-
-               GContact::link($gcid, $importer["uid"], $contact["id"]);
-
                Logger::log("Profile of contact ".$contact["id"]." stored for user ".$importer["uid"], Logger::DEBUG);
 
                return true;
index 1cf2894eb548742058e39435a0085579b0027ace..d9e18fa61384b54e0e06c033a6c5ef28e4446518 100644 (file)
@@ -34,7 +34,6 @@ use Friendica\DI;
 use Friendica\Model\APContact;
 use Friendica\Model\Contact;
 use Friendica\Model\Conversation;
-use Friendica\Model\GContact;
 use Friendica\Model\Item;
 use Friendica\Model\ItemURI;
 use Friendica\Model\Tag;
@@ -240,15 +239,6 @@ class OStatus
                                        Contact::updateAvatar($cid, $author["author-avatar"]);
                                }
                        }
-
-                       $contact["generation"] = 2;
-                       $contact["hide"] = false; // OStatus contacts are never hidden
-                       if (!empty($author["author-avatar"])) {
-                               $contact["photo"] = $author["author-avatar"];
-                       }
-                       $gcid = GContact::update($contact);
-
-                       GContact::link($gcid, $contact["uid"], $contact["id"]);
                } elseif (empty($contact["network"]) || ($contact["network"] != Protocol::DFRN)) {
                        $contact = [];
                }
diff --git a/src/Protocol/PortableContact.php b/src/Protocol/PortableContact.php
deleted file mode 100644 (file)
index 8109ef2..0000000
+++ /dev/null
@@ -1,486 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2020, Friendica
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Protocol;
-
-use Exception;
-use Friendica\Content\Text\HTML;
-use Friendica\Core\Logger;
-use Friendica\Core\Protocol;
-use Friendica\Core\Worker;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\GContact;
-use Friendica\Model\GServer;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Strings;
-
-/**
- *
- * @todo Move GNU Social URL schemata (http://server.tld/user/number) to http://server.tld/username
- * @todo Fetch profile data from profile page for Redmatrix users
- * @todo Detect if it is a forum
- */
-class PortableContact
-{
-       const DISABLED = 0;
-       const USERS = 1;
-       const USERS_GCONTACTS = 2;
-       const USERS_GCONTACTS_FALLBACK = 3;
-
-       /**
-        * Fetch POCO data
-        *
-        * @param integer $cid  Contact ID
-        * @param integer $uid  User ID
-        * @param integer $zcid Global Contact ID
-        * @param integer $url  POCO address that should be polled
-        *
-        * Given a contact-id (minimum), load the PortableContacts friend list for that contact,
-        * and add the entries to the gcontact (Global Contact) table, or update existing entries
-        * if anything (name or photo) has changed.
-        * We use normalised urls for comparison which ignore http vs https and www.domain vs domain
-        *
-        * 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)
-       {
-               // Call the function "load" via the worker
-               Worker::add(PRIORITY_LOW, 'FetchPoCo', (int)$cid, (int)$uid, (int)$zcid, $url);
-       }
-
-       /**
-        * Fetch POCO data from the worker
-        *
-        * @param integer $cid  Contact ID
-        * @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)
-       {
-               if ($cid) {
-                       if (!$url || !$uid) {
-                               $contact = DBA::selectFirst('contact', ['poco', 'uid'], ['id' => $cid]);
-                               if (DBA::isResult($contact)) {
-                                       $url = $contact['poco'];
-                                       $uid = $contact['uid'];
-                               }
-                       }
-                       if (!$uid) {
-                               return;
-                       }
-               }
-
-               if (!$url) {
-                       return;
-               }
-
-               $url = $url . (($uid) ? '/@me/@all?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,contactType,generation' : '?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,contactType,generation');
-
-               Logger::log('load: ' . $url, Logger::DEBUG);
-
-               $fetchresult = DI::httpRequest()->fetchFull($url);
-               $s = $fetchresult->getBody();
-
-               Logger::log('load: returns ' . $s, Logger::DATA);
-
-               Logger::log('load: return code: ' . $fetchresult->getReturnCode(), Logger::DEBUG);
-
-               if (($fetchresult->getReturnCode() > 299) || (! $s)) {
-                       return;
-               }
-
-               $j = json_decode($s, true);
-
-               Logger::debug('load', ['json'  => $j]);
-
-               if (!isset($j['entry'])) {
-                       return;
-               }
-
-               $total = 0;
-               foreach ($j['entry'] as $entry) {
-                       $total ++;
-                       $profile_url = '';
-                       $profile_photo = '';
-                       $connect_url = '';
-                       $name = '';
-                       $network = '';
-                       $updated = DBA::NULL_DATETIME;
-                       $location = '';
-                       $about = '';
-                       $keywords = '';
-                       $contact_type = -1;
-                       $generation = 0;
-
-                       if (!empty($entry['displayName'])) {
-                               $name = $entry['displayName'];
-                       }
-
-                       if (isset($entry['urls'])) {
-                               foreach ($entry['urls'] as $url) {
-                                       if ($url['type'] == 'profile') {
-                                               $profile_url = $url['value'];
-                                               continue;
-                                       }
-                                       if ($url['type'] == 'webfinger') {
-                                               $connect_url = str_replace('acct:', '', $url['value']);
-                                               continue;
-                                       }
-                               }
-                       }
-                       if (isset($entry['photos'])) {
-                               foreach ($entry['photos'] as $photo) {
-                                       if ($photo['type'] == 'profile') {
-                                               $profile_photo = $photo['value'];
-                                               continue;
-                                       }
-                               }
-                       }
-
-                       if (isset($entry['updated'])) {
-                               $updated = date(DateTimeFormat::MYSQL, strtotime($entry['updated']));
-                       }
-
-                       if (isset($entry['network'])) {
-                               $network = $entry['network'];
-                       }
-
-                       if (isset($entry['currentLocation'])) {
-                               $location = $entry['currentLocation'];
-                       }
-
-                       if (isset($entry['aboutMe'])) {
-                               $about = HTML::toBBCode($entry['aboutMe']);
-                       }
-
-                       if (isset($entry['generation']) && ($entry['generation'] > 0)) {
-                               $generation = ++$entry['generation'];
-                       }
-
-                       if (isset($entry['tags'])) {
-                               foreach ($entry['tags'] as $tag) {
-                                       $keywords = implode(", ", $tag);
-                               }
-                       }
-
-                       if (isset($entry['contactType']) && ($entry['contactType'] >= 0)) {
-                               $contact_type = $entry['contactType'];
-                       }
-
-                       $gcontact = ["url" => $profile_url,
-                                       "name" => $name,
-                                       "network" => $network,
-                                       "photo" => $profile_photo,
-                                       "about" => $about,
-                                       "location" => $location,
-                                       "keywords" => $keywords,
-                                       "connect" => $connect_url,
-                                       "updated" => $updated,
-                                       "contact-type" => $contact_type,
-                                       "generation" => $generation];
-
-                       try {
-                               $gcontact = GContact::sanitize($gcontact);
-                               $gcid = GContact::update($gcontact);
-
-                               GContact::link($gcid, $uid, $cid, $zcid);
-                       } catch (Exception $e) {
-                               Logger::log($e->getMessage(), Logger::DEBUG);
-                       }
-               }
-               Logger::log("load: loaded $total entries", Logger::DEBUG);
-
-               $condition = ["`cid` = ? AND `uid` = ? AND `zcid` = ? AND `updated` < UTC_TIMESTAMP - INTERVAL 2 DAY", $cid, $uid, $zcid];
-               DBA::delete('glink', $condition);
-       }
-
-       /**
-        * Returns a list of all known servers
-        * @return array List of server urls
-        * @throws Exception
-        */
-       public static function serverlist()
-       {
-               $r = q(
-                       "SELECT `url`, `site_name` AS `displayName`, `network`, `platform`, `version` FROM `gserver`
-                       WHERE `network` IN ('%s', '%s', '%s') AND NOT `failed`
-                       ORDER BY `last_contact`
-                       LIMIT 1000",
-                       DBA::escape(Protocol::DFRN),
-                       DBA::escape(Protocol::DIASPORA),
-                       DBA::escape(Protocol::OSTATUS)
-               );
-
-               if (!DBA::isResult($r)) {
-                       return false;
-               }
-
-               return $r;
-       }
-
-       /**
-        * 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)
-       {
-               $curlResult = DI::httpRequest()->get($poco . "/@server");
-
-               if (!$curlResult->isSuccess()) {
-                       return;
-               }
-
-               $serverlist = json_decode($curlResult->getBody(), true);
-
-               if (!is_array($serverlist)) {
-                       return;
-               }
-
-               foreach ($serverlist as $server) {
-                       $server_url = str_replace("/index.php", "", $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);
-                               Worker::add(PRIORITY_LOW, 'UpdateGServer', $server_url);
-                       }
-               }
-       }
-
-       public static function discoverSingleServer($id)
-       {
-               $server = DBA::selectFirst('gserver', ['poco', 'nurl', 'url', 'network'], ['id' => $id]);
-
-               if (!DBA::isResult($server)) {
-                       return false;
-               }
-
-               // 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,contactType,generation";
-
-               Logger::info("Fetch all users from the server " . $server["url"]);
-
-               $curlResult = DI::httpRequest()->get($url);
-
-               if ($curlResult->isSuccess() && !empty($curlResult->getBody())) {
-                       $data = json_decode($curlResult->getBody(), true);
-
-                       if (!empty($data)) {
-                               self::discoverServer($data, 2);
-                       }
-
-                       if (DI::config()->get('system', 'poco_discovery') >= self::USERS_GCONTACTS) {
-                               $timeframe = DI::config()->get('system', 'poco_discovery_since');
-
-                               if ($timeframe == 0) {
-                                       $timeframe = 30;
-                               }
-
-                               $updatedSince = date(DateTimeFormat::MYSQL, time() - $timeframe * 86400);
-
-                               // Fetch all global contacts from the other server (Not working with Redmatrix and Friendica versions before 3.3)
-                               $url = $server["poco"]."/@global?updatedSince=".$updatedSince."&fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,contactType,generation";
-
-                               $success = false;
-
-                               $curlResult = DI::httpRequest()->get($url);
-
-                               if ($curlResult->isSuccess() && !empty($curlResult->getBody())) {
-                                       Logger::info("Fetch all global contacts from the server " . $server["nurl"]);
-                                       $data = json_decode($curlResult->getBody(), true);
-
-                                       if (!empty($data)) {
-                                               $success = self::discoverServer($data);
-                                       }
-                               }
-
-                               if (!$success && !empty($data) && DI::config()->get('system', 'poco_discovery') >= self::USERS_GCONTACTS_FALLBACK) {
-                                       Logger::info("Fetch contacts from users of the server " . $server["nurl"]);
-                                       self::discoverServerUsers($data, $server);
-                               }
-                       }
-
-                       return true;
-               } else {
-                       // If the server hadn't replied correctly, then force a sanity check
-                       GServer::check($server["url"], $server["network"], true);
-
-                       return false;
-               }
-       }
-
-       private static function discoverServerUsers(array $data, array $server)
-       {
-               if (!isset($data['entry'])) {
-                       return;
-               }
-
-               foreach ($data['entry'] as $entry) {
-                       $username = '';
-
-                       if (isset($entry['urls'])) {
-                               foreach ($entry['urls'] as $url) {
-                                       if ($url['type'] == 'profile') {
-                                               $profile_url = $url['value'];
-                                               $path_array = explode('/', parse_url($profile_url, PHP_URL_PATH));
-                                               $username = end($path_array);
-                                       }
-                               }
-                       }
-
-                       if ($username != '') {
-                               Logger::log('Fetch contacts for the user ' . $username . ' from the server ' . $server['nurl'], Logger::DEBUG);
-
-                               // Fetch all contacts from a given user from the other server
-                               $url = $server['poco'] . '/' . $username . '/?fields=displayName,urls,photos,updated,network,aboutMe,currentLocation,tags,contactType,generation';
-
-                               $curlResult = DI::httpRequest()->get($url);
-
-                               if ($curlResult->isSuccess()) {
-                                       $data = json_decode($curlResult->getBody(), true);
-
-                                       if (!empty($data)) {
-                                               self::discoverServer($data, 3);
-                                       }
-                               }
-                       }
-               }
-       }
-
-       private static function discoverServer(array $data, $default_generation = 0)
-       {
-               if (empty($data['entry'])) {
-                       return false;
-               }
-
-               $success = false;
-
-               foreach ($data['entry'] as $entry) {
-                       $profile_url = '';
-                       $profile_photo = '';
-                       $connect_url = '';
-                       $name = '';
-                       $network = '';
-                       $updated = DBA::NULL_DATETIME;
-                       $location = '';
-                       $about = '';
-                       $keywords = '';
-                       $contact_type = -1;
-                       $generation = $default_generation;
-
-                       if (!empty($entry['displayName'])) {
-                               $name = $entry['displayName'];
-                       }
-
-                       if (isset($entry['urls'])) {
-                               foreach ($entry['urls'] as $url) {
-                                       if ($url['type'] == 'profile') {
-                                               $profile_url = $url['value'];
-                                               continue;
-                                       }
-                                       if ($url['type'] == 'webfinger') {
-                                               $connect_url = str_replace('acct:' , '', $url['value']);
-                                               continue;
-                                       }
-                               }
-                       }
-
-                       if (isset($entry['photos'])) {
-                               foreach ($entry['photos'] as $photo) {
-                                       if ($photo['type'] == 'profile') {
-                                               $profile_photo = $photo['value'];
-                                               continue;
-                                       }
-                               }
-                       }
-
-                       if (isset($entry['updated'])) {
-                               $updated = date(DateTimeFormat::MYSQL, strtotime($entry['updated']));
-                       }
-
-                       if (isset($entry['network'])) {
-                               $network = $entry['network'];
-                       }
-
-                       if (isset($entry['currentLocation'])) {
-                               $location = $entry['currentLocation'];
-                       }
-
-                       if (isset($entry['aboutMe'])) {
-                               $about = HTML::toBBCode($entry['aboutMe']);
-                       }
-
-                       if (isset($entry['generation']) && ($entry['generation'] > 0)) {
-                               $generation = ++$entry['generation'];
-                       }
-
-                       if (isset($entry['contactType']) && ($entry['contactType'] >= 0)) {
-                               $contact_type = $entry['contactType'];
-                       }
-
-                       if (isset($entry['tags'])) {
-                               foreach ($entry['tags'] as $tag) {
-                                       $keywords = implode(", ", $tag);
-                               }
-                       }
-
-                       if ($generation > 0) {
-                               $success = true;
-
-                               Logger::log("Store profile ".$profile_url, Logger::DEBUG);
-
-                               $gcontact = ["url" => $profile_url,
-                                               "name" => $name,
-                                               "network" => $network,
-                                               "photo" => $profile_photo,
-                                               "about" => $about,
-                                               "location" => $location,
-                                               "keywords" => $keywords,
-                                               "connect" => $connect_url,
-                                               "updated" => $updated,
-                                               "contact-type" => $contact_type,
-                                               "generation" => $generation];
-
-                               try {
-                                       $gcontact = GContact::sanitize($gcontact);
-                                       GContact::update($gcontact);
-                               } catch (Exception $e) {
-                                       Logger::log($e->getMessage(), Logger::DEBUG);
-                               }
-
-                               Logger::log("Done for profile ".$profile_url, Logger::DEBUG);
-                       }
-               }
-               return $success;
-       }
-}
index 5bdd22f330b0d707e21853066155ff96915d80fa..4a49103e09efcc1fad8652d2a0bdfc773b6d9616 100644 (file)
@@ -57,9 +57,6 @@ class Cron
                // run the process to update server directories in the background
                Worker::add(PRIORITY_LOW, 'UpdateServerDirectories');
 
-               // run the process to update locally stored global contacts in the background
-               Worker::add(PRIORITY_LOW, 'UpdateGContacts');
-
                // Expire and remove user entries
                Worker::add(PRIORITY_MEDIUM, "CronJobs", "expire_and_remove_users");
 
@@ -88,8 +85,6 @@ class Cron
 
                        Worker::add(PRIORITY_LOW, 'UpdateGServers');
 
-                       Worker::add(PRIORITY_LOW, 'UpdateSuggestions');
-
                        Worker::add(PRIORITY_LOW, 'Expire');
 
                        Worker::add(PRIORITY_MEDIUM, 'DBClean');
index 4f988b6e14392174a02b6aad9f04e52b71d9107b..5b5c01acab0ea8a6f18278cd4ee81e43d2624e44 100644 (file)
@@ -29,7 +29,6 @@ use Friendica\Database\DBA;
 use Friendica\Database\PostUpdate;
 use Friendica\DI;
 use Friendica\Model\Contact;
-use Friendica\Model\GContact;
 use Friendica\Model\Nodeinfo;
 use Friendica\Model\Photo;
 use Friendica\Model\User;
@@ -258,14 +257,6 @@ class CronJobs
                // There was an issue where the nick vanishes from the contact table
                q("UPDATE `contact` INNER JOIN `user` ON `contact`.`uid` = `user`.`uid` SET `nick` = `nickname` WHERE `self` AND `nick`=''");
 
-               // Update the global contacts for local users
-               $r = q("SELECT `uid` FROM `user` WHERE `verified` AND NOT `blocked` AND NOT `account_removed` AND NOT `account_expired`");
-               if (DBA::isResult($r)) {
-                       foreach ($r AS $user) {
-                               GContact::updateForUser($user["uid"]);
-                       }
-               }
-
                /// @todo
                /// - remove thread entries without item
                /// - remove sign entries without item
diff --git a/src/Worker/FetchPoCo.php b/src/Worker/FetchPoCo.php
deleted file mode 100644 (file)
index 477d001..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2020, Friendica
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Worker;
-
-use Friendica\Core\Logger;
-use Friendica\Protocol\PortableContact;
-
-class FetchPoCo
-{
-       /**
-        * Fetch PortableContacts from a given PoCo server address
-        *
-        * @param integer $cid  Contact ID
-        * @param integer $uid  User ID
-        * @param integer $zcid Global Contact ID
-        * @param integer $url  PoCo address that should be polled
-        */
-       public static function execute($cid, $uid, $zcid, $url)
-       {
-               PortableContact::load($cid, $uid, $zcid, $url);
-       }
-}
index fbd1ab4e59f9fd608f2b2330ac087459ec13c3f5..40681175d466eb8e3fd89f29c03d55b3459293fd 100644 (file)
@@ -32,7 +32,6 @@ use Friendica\Protocol\Activity;
 use Friendica\Protocol\ActivityPub;
 use Friendica\Protocol\Email;
 use Friendica\Protocol\Feed;
-use Friendica\Protocol\PortableContact;
 use Friendica\Util\DateTimeFormat;
 use Friendica\Util\Strings;
 use Friendica\Util\XML;
@@ -95,13 +94,6 @@ class OnePoll
                        $contact = DBA::selectFirst('contact', [], ['id' => $contact_id]);
                }
 
-               // load current friends if possible.
-               if (!empty($contact['poco']) && !$contact['failed']) {
-                       if (!DBA::exists('glink', ["`cid` = ? AND updated > UTC_TIMESTAMP() - INTERVAL 1 DAY", $contact['id']])) {
-                               PortableContact::loadWorker($contact['id'], $importer_uid, 0, $contact['poco']);
-                       }
-               }
-
                // Don't poll if polling is deactivated (But we poll feeds and mails anyway)
                if (!in_array($protocol, [Protocol::FEED, Protocol::MAIL]) && DI::config()->get('system', 'disable_polling')) {
                        Logger::log('Polling is disabled');
index a83b0a13be383e7615c03e17a522054c78c5f749..250496009d27ad38a707b96a0c159fa4d85654d8 100644 (file)
@@ -60,22 +60,11 @@ class PullDirectory
                        return;
                }
 
+               $result = Contact::addContactsByArray($contacts['results']);
+
                $now = $contacts['now'] ?? 0;
-               $count = $contacts['count'] ?? 0;
-               $added = 0;
-               $updated = 0;
-               foreach ($contacts['results'] as $url) {
-                       $contact = Contact::getByURL($url, false, ['id']); 
-                       if (empty($contact['id'])) {
-                               Worker::add(PRIORITY_LOW, 'AddContact', 0, $url);
-                               ++$added;
-                       } else {
-                               Worker::add(PRIORITY_LOW, "UpdateContact", $contact['id']);
-                               ++$updated;
-                       }
-               }
                DI::config()->set('system', 'last-directory-sync', $now);
 
-               Logger::info('Synchronization ended.', ['now' => $now, 'count' => $count, 'added' => $added, 'updated' => $updated, 'directory' => $directory]);
+               Logger::info('Synchronization ended', ['now' => $now, 'count' => $result['count'], 'added' => $result['added'], 'updated' => $result['updated'], 'directory' => $directory]);
        }
 }
index 546c369b2c5569952deaed0a663e3f5aa281a789..3bb5f1b8b296ff029edf4be4478ee7521fc3d812 100644 (file)
@@ -23,14 +23,9 @@ namespace Friendica\Worker;
 
 use Friendica\Core\Cache\Duration;
 use Friendica\Core\Logger;
-use Friendica\Core\Protocol;
 use Friendica\Core\Search;
-use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Contact;
-use Friendica\Model\GContact;
-use Friendica\Model\GServer;
-use Friendica\Util\Strings;
 
 class SearchDirectory
 {
@@ -56,43 +51,7 @@ class SearchDirectory
 
                if (!empty($j->results)) {
                        foreach ($j->results as $jj) {
-                               // Check if the contact already exists
-                               $gcontact = DBA::selectFirst('gcontact', ['failed'], ['nurl' => Strings::normaliseLink($jj->url)]);
-                               if (DBA::isResult($gcontact)) {
-                                       Logger::info('Profile already exists', ['profile' => $jj->url, 'search' => $search]);
-
-                                       if ($gcontact['failed']) {
-                                               continue;
-                                       }
-
-                                       // Update the contact
-                                       GContact::updateFromProbe($jj->url);
-                                       continue;
-                               }
-
-                               $server_url = GContact::getBasepath($jj->url, true);
-                               if ($server_url != '') {
-                                       if (!GServer::check($server_url)) {
-                                               Logger::info("Friendica server doesn't answer.", ['server' => $server_url]);
-                                               continue;
-                                       }
-                                       Logger::info('Friendica server seems to be okay.', ['server' => $server_url]);
-                               }
-
-                               $data = Contact::getByURL($jj->url);
-                               if ($data['network'] == Protocol::DFRN) {
-                                       Logger::info('Add profile to local directory', ['profile' => $jj->url]);
-
-                                       if ($jj->tags != '') {
-                                               $data['keywords'] = $jj->tags;
-                                       }
-
-                                       $data['server_url'] = $data['baseurl'];
-
-                                       GContact::update($data);
-                               } else {
-                                       Logger::info('Profile is not responding or no Friendica contact', ['profile' => $jj->url, 'network' => $data['network']]);
-                               }
+                               Contact::getByURL($jj->url);
                        }
                }
                DI::cache()->set('SearchDirectory:' . $search, time(), Duration::DAY);
diff --git a/src/Worker/UpdateGContact.php b/src/Worker/UpdateGContact.php
deleted file mode 100644 (file)
index 3f71241..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2020, Friendica
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Worker;
-
-use Friendica\Core\Logger;
-use Friendica\DI;
-use Friendica\Model\GContact;
-
-class UpdateGContact
-{
-       /**
-        * Update global contact via probe
-        * @param string  $url     Global contact url
-        * @param string  $command
-        */
-       public static function execute(string $url, string $command = '')
-       {
-               $force = ($command == "force");
-               $nodiscover = ($command == "nodiscover");
-
-               $success = GContact::updateFromProbe($url, $force);
-
-               Logger::info('Updated from probe', ['url' => $url, 'force' => $force, 'success' => $success]);
-       }
-}
diff --git a/src/Worker/UpdateGContacts.php b/src/Worker/UpdateGContacts.php
deleted file mode 100644 (file)
index 9d95192..0000000
+++ /dev/null
@@ -1,101 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2020, Friendica
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Worker;
-
-use Friendica\Core\Logger;
-use Friendica\Core\Protocol;
-use Friendica\Core\Worker;
-use Friendica\Database\DBA;
-use Friendica\DI;
-use Friendica\Model\GContact;
-use Friendica\Model\GServer;
-use Friendica\Util\DateTimeFormat;
-use Friendica\Util\Strings;
-
-class UpdateGContacts
-{
-       /**
-        * Updates global contacts
-        */
-       public static function execute()
-       {
-               if (!DI::config()->get('system', 'poco_completion')) {
-                       return;
-               }
-
-               Logger::info('Update global contacts');
-
-               $starttime = time();
-
-               $contacts = DBA::p("SELECT `url`, `created`, `updated`, `last_failure`, `last_contact`, `server_url`, `network` FROM `gcontact`
-                               WHERE `last_contact` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND
-                                       `last_failure` < UTC_TIMESTAMP - INTERVAL 1 MONTH AND
-                                       `network` IN (?, ?, ?, ?, ?, '') ORDER BY rand()",
-                               Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::DIASPORA, Protocol::OSTATUS, Protocol::FEED);
-
-               $checked = 0;
-
-               while ($contact = DBA::fetch($contacts)) {
-                       $urlparts = parse_url($contact['url']);
-                       if (empty($urlparts['scheme'])) {
-                               DBA::update('gcontact', ['network' => Protocol::PHANTOM],
-                                       ['nurl' => Strings::normaliseLink($contact['url'])]);
-                               continue;
-                        }
-
-                       if (in_array($urlparts['host'], ['twitter.com', 'identi.ca'])) {
-                               $networks = ['twitter.com' => Protocol::TWITTER, 'identi.ca' => Protocol::PUMPIO];
-
-                               DBA::update('gcontact', ['network' => $networks[$urlparts['host']]],
-                                       ['nurl' => Strings::normaliseLink($contact['url'])]);
-                               continue;
-                       }
-
-                       $server_url = GContact::getBasepath($contact['url'], true);
-                       $force_update = false;
-
-                       if (!empty($contact['server_url'])) {
-                               $force_update = (Strings::normaliseLink($contact['server_url']) != Strings::normaliseLink($server_url));
-
-                               $server_url = $contact['server_url'];
-                       }
-
-                       if ((empty($server_url) && ($contact['network'] == Protocol::FEED)) || $force_update || GServer::check($server_url, $contact['network'])) {
-                               Logger::info('Check profile', ['profile' => $contact['url']]);
-                               Worker::add(PRIORITY_LOW, 'UpdateGContact', $contact['url'], 'force');
-
-                               if (++$checked > 100) {
-                                       return;
-                               }
-                       } else {
-                               DBA::update('gcontact', ['last_failure' => DateTimeFormat::utcNow()],
-                                       ['nurl' => Strings::normaliseLink($contact['url'])]);
-                       }
-
-                       // Quit the loop after 3 minutes
-                       if (time() > ($starttime + 180)) {
-                               return;
-                       }
-               }
-               DBA::close($contacts);
-       }
-}
index 74f75fcd76ff14cb168fcacb4d3843f6a9ede455..ba5ef1017ec1f32ce3767f0a64ada97d80d0941a 100644 (file)
@@ -22,9 +22,7 @@
 namespace Friendica\Worker;
 
 use Friendica\DI;
-use Friendica\Model\GContact;
 use Friendica\Model\GServer;
-use Friendica\Protocol\PortableContact;
 
 class UpdateServerDirectories
 {
@@ -33,16 +31,10 @@ class UpdateServerDirectories
         */
        public static function execute()
        {
-               if (DI::config()->get('system', 'poco_discovery') == PortableContact::DISABLED) {
+               if (!DI::config()->get('system', 'poco_discovery')) {
                        return;
                }
 
-               // Query Friendica and Hubzilla servers for their users
                GServer::discover();
-
-               // Query GNU Social servers for their users ("statistics" addon has to be enabled on the GS server)
-               if (!DI::config()->get('system', 'ostatus_disabled')) {
-                       GContact::discoverGsUsers();
-               }
        }
 }
index 87bbee7e8c2be4be96b6da2876fff4d9fd9c51cc..2066ce7cb924e31255a97ac2a6ed0cb0e2f532a8 100644 (file)
 namespace Friendica\Worker;
 
 use Friendica\Core\Logger;
+use Friendica\Database\DBA;
+use Friendica\DI;
+use Friendica\Model\Contact;
 use Friendica\Model\GServer;
 
 class UpdateServerDirectory
 {
        /**
         * Query the given server for their users
-        * @param string $gserver Server URL
+        * 
+        * @param array $gserver Server record
         */
-       public static function execute($gserver)
+       public static function execute(array $gserver)
        {
-               GServer::updateDirectory($gserver);
-               return;
+               $gserver = DBA::selectFirst('gserver', [], ['url' => $gserver['url']]);
+               if ($gserver['directory-type'] == GServer::DT_MASTODON) {
+                       self::discoverMastodonDirectory($gserver);
+               } elseif (!empty($gserver['poco'])) {
+                       self::discoverPoCo($gserver);
+               }
+       }
+
+       private static function discoverPoCo(array $gserver)
+       {
+               $result = DI::httpRequest()->fetch($gserver['poco'] . '?fields=urls');
+               if (empty($result)) {
+                       Logger::info('Empty result', ['url' => $gserver['url']]);
+                       return;
+               }
+
+               $contacts = json_decode($result, true);
+               if (empty($contacts['entry'])) {
+                       Logger::info('No contacts', ['url' => $gserver['url']]);
+                       return;
+               }
+
+               Logger::info('PoCo discovery started', ['poco' => $gserver['poco']]);
+
+               $urls = [];
+               foreach ($contacts['entry'] as $entry) {
+                       foreach ($entry['urls'] as $url_entry) {
+                               if (empty($url_entry['type']) || empty($url_entry['value'])) {
+                                       continue;
+                               }
+                               if ($url_entry['type'] == 'profile') {
+                                       $urls[] = $url_entry['value'];
+                               }
+                       }
+               }
+
+               $result = Contact::addContactsByArray($urls);
+
+               Logger::info('PoCo discovery ended', ['count' => $result['count'], 'added' => $result['added'], 'updated' => $result['updated'], 'poco' => $gserver['poco']]);
+       }
+
+       private static function discoverMastodonDirectory(array $gserver)
+       {               
+               $result = DI::httpRequest()->fetch($gserver['url'] . '/api/v1/directory?order=new&local=true&limit=200&offset=0');
+               if (empty($result)) {
+                       Logger::info('Empty result', ['url' => $gserver['url']]);
+                       return;
+               }
+
+               $accounts = json_decode($result, true);
+               if (empty($accounts)) {
+                       Logger::info('No contacts', ['url' => $gserver['url']]);
+                       return;
+               }
+
+               Logger::info('Account discovery started', ['url' => $gserver['url']]);
+
+               $urls = [];
+               foreach ($accounts as $account) {
+                       if (!empty($account['url'])) {
+                               $urls[] = $account['url'];
+                       }
+               }
+
+               $result = Contact::addContactsByArray($urls);
+
+               Logger::info('Account discovery ended', ['count' => $result['count'], 'added' => $result['added'], 'updated' => $result['updated'], 'url' => $gserver['url']]);
        }
 }
index ff0cdfa730d7446cb8dc491908a8b033ee6e137f..ca45344459a299663cd1f0a7ed0f092af3f533ec 100644 (file)
@@ -63,4 +63,41 @@ class UpdateServerPeers
                }
                Logger::info('Server peer update ended', ['total' => $total, 'added' => $added, 'url' => $url]);
        }
+
+       /**
+        * Fetch server list from remote servers and adds them when they are new.
+        *
+        * @param string $poco URL to the POCO endpoint
+        */
+       private static function fetchServerlist($poco)
+       {
+               $curlResult = DI::httpRequest()->get($poco . '/@server');
+               if (!$curlResult->isSuccess()) {
+                       Logger::info('Server is not reachable or does not offer the "poco" endpoint', ['poco' => $poco]);
+                       return;
+               }
+
+               $serverlist = json_decode($curlResult->getBody(), true);
+               if (!is_array($serverlist)) {
+                       Logger::info('Server does not have any servers listed', ['poco' => $poco]);
+                       return;
+               }
+
+               Logger::info('PoCo Server update start', ['poco' => $poco]);
+
+               $total = 0;
+               $added = 0;
+               foreach ($serverlist as $server) {
+                       ++$total;
+                       if (DBA::exists('gserver', ['nurl' => Strings::normaliseLink($server['url'])])) {
+                               // We already know this server
+                               continue;
+                       }
+                       // This endpoint doesn't offer the schema. So we assume that it is HTTPS.
+                       Worker::add(PRIORITY_LOW, 'UpdateGServer', $server['url']);
+                       ++$added;
+               }
+
+               Logger::info('PoCo Server update ended', ['total' => $total, 'added' => $added, 'poco' => $poco]);
+       }
 }
diff --git a/src/Worker/UpdateSuggestions.php b/src/Worker/UpdateSuggestions.php
deleted file mode 100644 (file)
index 103a3cf..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<?php
-/**
- * @copyright Copyright (C) 2020, Friendica
- *
- * @license GNU AGPL version 3 or any later version
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU Affero General Public License for more details.
- *
- * You should have received a copy of the GNU Affero General Public License
- * along with this program.  If not, see <https://www.gnu.org/licenses/>.
- *
- */
-
-namespace Friendica\Worker;
-
-use Friendica\Core\Logger;
-use Friendica\Model\GContact;
-
-class UpdateSuggestions
-{
-       /**
-        * Discover other servers for their contacts.
-        */
-       public static function execute()
-       {
-               GContact::updateSuggestions();
-       }
-}
index a4d71bc4fde2b30f11e3e0a0fe71f7a53439fa44..f335b5292ec9efdaf90ec1c4d06e6c50cf9c1c9b 100644 (file)
@@ -48,7 +48,6 @@ use Friendica\Database\DBA;
 use Friendica\Database\DBStructure;
 use Friendica\DI;
 use Friendica\Model\Contact;
-use Friendica\Model\GContact;
 use Friendica\Model\Item;
 use Friendica\Model\User;
 use Friendica\Model\Storage;
@@ -315,7 +314,6 @@ function update_1298()
                                                'was' => $data[$translateKey]]);
                                        Worker::add(PRIORITY_LOW, 'ProfileUpdate', $data['id']);
                                        Contact::updateSelfFromUserID($data['id']);
-                                       GContact::updateForUser($data['id']);
                                        $success++;
                                }
                        }
@@ -562,16 +560,5 @@ function update_1357()
                return Update::FAILED;
        }
 
-       if (!DBA::e("UPDATE `gcontact` SET `failed` = true WHERE `last_contact` < `last_failure` AND `failed` IS NULL")) {
-               return Update::FAILED;
-       }
-
-       if (!DBA::e("UPDATE `gcontact` SET `failed` = false WHERE `last_contact` > `last_failure` AND `failed` IS NULL")) {
-               return Update::FAILED;
-       }
-
-       if (!DBA::e("UPDATE `gcontact` SET `failed` = false WHERE `updated` > `last_failure` AND `failed` IS NULL")) {
-               return Update::FAILED;
-       }
        return Update::SUCCESS;
 }
index 177d5406f61d1bdf0fe1ec0c7efb6e59c89d295c..37e3cb847a6e9786e45c43e89097af1ab2fac084 100644 (file)
@@ -5,10 +5,6 @@
        <canvas id="FederationChart" class="federation-graph" width="320" height="320"></canvas>
        <p>{{$intro}}</p>
 
-       {{if not $autoactive}}
-       <p class="error-message">{{$hint nofilter}}</p>
-       {{/if}}
-
        <p>{{$legendtext}}</p>
 
        <ul>
index 57e574725d94593c43f92435903136e5ce2a7677..ab97d8218d87746b1361a2c53a86261908d5919a 100644 (file)
                <h2>{{$portable_contacts}}</h2>
                {{include file="field_select.tpl" field=$contact_discovery}}
                {{include file="field_checkbox.tpl" field=$synchronize_directory}}
-               {{include file="field_checkbox.tpl" field=$poco_completion}}
                {{include file="field_input.tpl" field=$poco_requery_days}}
-               {{include file="field_select.tpl" field=$poco_discovery}}
-               {{include file="field_select.tpl" field=$poco_discovery_since}}
+               {{include file="field_checkbox.tpl" field=$poco_discovery}}
                {{include file="field_checkbox.tpl" field=$poco_local_search}}
                <div class="submit"><input type="submit" name="page_site" value="{{$submit}}"/></div>
 
index 61a9d1e500c2342eb0f3a8c00b26ccb2dea83456..c5a24ffd34b109db27e6f0605af9906c2974ba3b 100644 (file)
                                        <div class="panel-body">
                                                {{include file="field_select.tpl" field=$contact_discovery}}
                                                {{include file="field_checkbox.tpl" field=$synchronize_directory}}
-                                               {{include file="field_checkbox.tpl" field=$poco_completion}}
+                                               {{include file="field_checkbox.tpl" field=$poco_discovery}}
                                                {{include file="field_input.tpl" field=$poco_requery_days}}
-                                               {{include file="field_select.tpl" field=$poco_discovery}}
-                                               {{include file="field_select.tpl" field=$poco_discovery_since}}
                                                {{include file="field_checkbox.tpl" field=$poco_local_search}}
                                        </div>
                                        <div class="panel-footer">
index f4452e3c7690f5823056bb92fa405d62d7feb5f2..f38c61ec975a7866f823263a866fab8a23cf2d72 100644 (file)
@@ -17,7 +17,6 @@ use Friendica\Core\Search;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Model\Contact;
-use Friendica\Model\GContact;
 use Friendica\Util\Strings;
 
 function vier_init(App $a)