]> git.mxchange.org Git - friendica.git/commitdiff
Issue 11553: Reliably return the user's contacts
authorMichael <heluecht@pirati.ca>
Sat, 3 Dec 2022 13:49:29 +0000 (13:49 +0000)
committerMichael <heluecht@pirati.ca>
Sat, 3 Dec 2022 14:19:48 +0000 (14:19 +0000)
src/Model/Contact.php
src/Model/Contact/Relation.php
src/Module/Api/Mastodon/Accounts/Followers.php
src/Module/Api/Mastodon/Accounts/Following.php
src/Worker/ContactDiscoveryForUser.php [new file with mode: 0644]

index eabe378a46253b553529e4123155300350194511..34ce8e684e7272c91c482922c5315a8d656ad689 100644 (file)
@@ -136,6 +136,18 @@ class Contact
                return $contact;
        }
 
                return $contact;
        }
 
+       /**
+        * @param array $fields    Array of selected fields, empty for all
+        * @param array $condition Array of fields for condition
+        * @param array $params    Array of several parameters
+        * @return array
+        * @throws \Exception
+        */
+       public static function selectAccountToArray(array $fields = [], array $condition = [], array $params = []): array
+       {
+               return DBA::selectToArray('account-user-view', $fields, $condition, $params);
+       }
+
        /**
         * @param array $fields    Array of selected fields, empty for all
         * @param array $condition Array of fields for condition
        /**
         * @param array $fields    Array of selected fields, empty for all
         * @param array $condition Array of fields for condition
@@ -3154,6 +3166,8 @@ class Contact
                        return;
                }
 
                        return;
                }
 
+               Worker::add(Worker::PRIORITY_LOW, 'ContactDiscoveryForUser', $contact['uid']);
+
                self::clearFollowerFollowingEndpointCache($contact['uid']);
 
                $cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
                self::clearFollowerFollowingEndpointCache($contact['uid']);
 
                $cdata = self::getPublicAndUserContactID($contact['id'], $contact['uid']);
@@ -3177,6 +3191,8 @@ class Contact
                } else {
                        self::update(['rel' => self::FOLLOWER], ['id' => $contact['id']]);
                }
                } else {
                        self::update(['rel' => self::FOLLOWER], ['id' => $contact['id']]);
                }
+
+               Worker::add(Worker::PRIORITY_LOW, 'ContactDiscoveryForUser', $contact['uid']);
        }
 
        /**
        }
 
        /**
index 5616148fa0183e2d774d3c70f585c80218faced9..3db882bb94c0c9ed3e474fab4a63357f2ea60bff 100644 (file)
@@ -68,6 +68,26 @@ class Relation
                DBA::insert('contact-relation', ['last-interaction' => $interaction_date, 'cid' => $target, 'relation-cid' => $actor], Database::INSERT_UPDATE);
        }
 
                DBA::insert('contact-relation', ['last-interaction' => $interaction_date, 'cid' => $target, 'relation-cid' => $actor], Database::INSERT_UPDATE);
        }
 
+       /**
+        * Fetch the followers of a given user
+        *
+        * @param integer $uid User ID
+        * @return void
+        */
+       public static function discoverByUser(int $uid)
+       {
+               $contact = Contact::selectFirst(['id', 'url'], ['uid' => $uid, 'self' => true]);
+               if (empty($contact)) {
+                       Logger::warning('Self contact for user not found', ['uid' => $uid]);
+                       return;
+               }
+
+               $followers = self::getContacts($uid, [Contact::FOLLOWER, Contact::FRIEND]);
+               $followings = self::getContacts($uid, [Contact::SHARING, Contact::FRIEND]);
+
+               self::updateFollowersFollowings($contact, $followers, $followings);
+       }
+
        /**
         * Fetches the followers of a given profile and adds them
         *
        /**
         * Fetches the followers of a given profile and adds them
         *
@@ -113,13 +133,27 @@ class Relation
                        $followings = [];
                }
 
                        $followings = [];
                }
 
+               self::updateFollowersFollowings($contact, $followers, $followings);
+       }
+
+       /**
+        * Update followers and followings for the given contact
+        *
+        * @param array $contact
+        * @param array $followers
+        * @param array $followings
+        * @return void
+        */
+       private static function updateFollowersFollowings(array $contact, array $followers, array $followings)
+       {
                if (empty($followers) && empty($followings)) {
                        Contact::update(['last-discovery' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
                if (empty($followers) && empty($followings)) {
                        Contact::update(['last-discovery' => DateTimeFormat::utcNow()], ['id' => $contact['id']]);
-                       Logger::info('The contact does not offer discoverable data', ['id' => $contact['id'], 'url' => $url, 'network' => $contact['network']]);
+                       Logger::info('The contact does not offer discoverable data', ['id' => $contact['id'], 'url' => $contact['url'], 'network' => $contact['network']]);
                        return;
                }
 
                $target = $contact['id'];
                        return;
                }
 
                $target = $contact['id'];
+               $url    = $contact['url'];
 
                if (!empty($followers)) {
                        // Clear the follower list, since it will be recreated in the next step
 
                if (!empty($followers)) {
                        // Clear the follower list, since it will be recreated in the next step
index 58d1f7d8348dddd85a12cc97accc3bca76b1d5f7..cd03a0176a190a82f45b9b3a05548135aa45c41c 100644 (file)
@@ -24,6 +24,7 @@ namespace Friendica\Module\Api\Mastodon\Accounts;
 use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
+use Friendica\Model\Contact;
 use Friendica\Module\BaseApi;
 
 /**
 use Friendica\Module\BaseApi;
 
 /**
@@ -55,32 +56,59 @@ class Followers extends BaseApi
                        'limit'    => 40, // Maximum number of results to return. Defaults to 40.
                ], $request);
 
                        'limit'    => 40, // Maximum number of results to return. Defaults to 40.
                ], $request);
 
-               $params = ['order' => ['relation-cid' => true], 'limit' => $request['limit']];
-
-               $condition = ['cid' => $id, 'follows' => true];
-
-               if (!empty($request['max_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`relation-cid` < ?", $request['max_id']]);
-               }
-
-               if (!empty($request['since_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $request['since_id']]);
-               }
-
-               if (!empty($request['min_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $request['min_id']]);
-
-                       $params['order'] = ['cid'];
-               }
-
-               $accounts = [];
-
-               $followers = DBA::select('contact-relation', ['relation-cid'], $condition, $params);
-               while ($follower = DBA::fetch($followers)) {
-                       self::setBoundaries($follower['relation-cid']);
-                       $accounts[] = DI::mstdnAccount()->createFromContactId($follower['relation-cid'], $uid);
+               if (false && $id == Contact::getPublicIdByUserId($uid)) {
+                       $params = ['order' => ['pid' => true], 'limit' => $request['limit']];
+
+                       $condition = ['uid' => $uid, 'self' => false, 'rel' => [Contact::FOLLOWER, Contact::FRIEND]];
+       
+                       if (!empty($request['max_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`pid` < ?", $request['max_id']]);
+                       }
+       
+                       if (!empty($request['since_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`pid` > ?", $request['since_id']]);
+                       }
+       
+                       if (!empty($request['min_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`pid` > ?", $request['min_id']]);
+       
+                               $params['order'] = ['pid'];
+                       }
+       
+                       $accounts = [];
+       
+                       foreach (Contact::selectAccountToArray(['pid'], $condition, $params) as $follower) {
+                               self::setBoundaries($follower['pid']);
+                               $accounts[] = DI::mstdnAccount()->createFromContactId($follower['pid'], $uid);
+                       }
+               } else {
+                       $params = ['order' => ['relation-cid' => true], 'limit' => $request['limit']];
+
+                       $condition = ['cid' => $id, 'follows' => true];
+       
+                       if (!empty($request['max_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`relation-cid` < ?", $request['max_id']]);
+                       }
+       
+                       if (!empty($request['since_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $request['since_id']]);
+                       }
+       
+                       if (!empty($request['min_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`relation-cid` > ?", $request['min_id']]);
+       
+                               $params['order'] = ['relation-cid'];
+                       }
+       
+                       $accounts = [];
+       
+                       $followers = DBA::select('contact-relation', ['relation-cid'], $condition, $params);
+                       while ($follower = DBA::fetch($followers)) {
+                               self::setBoundaries($follower['relation-cid']);
+                               $accounts[] = DI::mstdnAccount()->createFromContactId($follower['relation-cid'], $uid);
+                       }
+                       DBA::close($followers);
                }
                }
-               DBA::close($followers);
 
                if (!empty($request['min_id'])) {
                        $accounts = array_reverse($accounts);
 
                if (!empty($request['min_id'])) {
                        $accounts = array_reverse($accounts);
index 8e05a9b717baa96adfc2cafc61bb688f27e48776..aca6bd5a886997a92a1681fb6bb94b763896cd1d 100644 (file)
@@ -24,6 +24,7 @@ namespace Friendica\Module\Api\Mastodon\Accounts;
 use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
 use Friendica\Core\System;
 use Friendica\Database\DBA;
 use Friendica\DI;
+use Friendica\Model\Contact;
 use Friendica\Module\BaseApi;
 
 /**
 use Friendica\Module\BaseApi;
 
 /**
@@ -55,32 +56,59 @@ class Following extends BaseApi
                        'limit'    => 40, // Maximum number of results to return. Defaults to 40.
                ], $request);
 
                        'limit'    => 40, // Maximum number of results to return. Defaults to 40.
                ], $request);
 
-               $params = ['order' => ['cid' => true], 'limit' => $request['limit']];
-
-               $condition = ['relation-cid' => $id, 'follows' => true];
-
-               if (!empty($request['max_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`cid` < ?", $request['max_id']]);
-               }
-
-               if (!empty($request['since_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`cid` > ?", $request['since_id']]);
-               }
-
-               if (!empty($request['min_id'])) {
-                       $condition = DBA::mergeConditions($condition, ["`cid` > ?", $request['min_id']]);
-
-                       $params['order'] = ['cid'];
-               }
-
-               $accounts = [];
-
-               $followers = DBA::select('contact-relation', ['cid'], $condition, $params);
-               while ($follower = DBA::fetch($followers)) {
-                       self::setBoundaries($follower['cid']);
-                       $accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
+               if ($id == Contact::getPublicIdByUserId($uid)) {
+                       $params = ['order' => ['pid' => true], 'limit' => $request['limit']];
+
+                       $condition = ['uid' => $uid, 'self' => false, 'rel' => [Contact::SHARING, Contact::FRIEND]];
+       
+                       if (!empty($request['max_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`pid` < ?", $request['max_id']]);
+                       }
+       
+                       if (!empty($request['since_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`pid` > ?", $request['since_id']]);
+                       }
+       
+                       if (!empty($request['min_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`pid` > ?", $request['min_id']]);
+       
+                               $params['order'] = ['pid'];
+                       }
+       
+                       $accounts = [];
+       
+                       foreach (Contact::selectAccountToArray(['pid'], $condition, $params) as $follower) {
+                               self::setBoundaries($follower['pid']);
+                               $accounts[] = DI::mstdnAccount()->createFromContactId($follower['pid'], $uid);
+                       }
+               } else {
+                       $params = ['order' => ['cid' => true], 'limit' => $request['limit']];
+
+                       $condition = ['relation-cid' => $id, 'follows' => true];
+
+                       if (!empty($request['max_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`cid` < ?", $request['max_id']]);
+                       }
+
+                       if (!empty($request['since_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`cid` > ?", $request['since_id']]);
+                       }
+
+                       if (!empty($request['min_id'])) {
+                               $condition = DBA::mergeConditions($condition, ["`cid` > ?", $request['min_id']]);
+
+                               $params['order'] = ['cid'];
+                       }
+
+                       $accounts = [];
+
+                       $followers = DBA::select('contact-relation', ['cid'], $condition, $params);
+                       while ($follower = DBA::fetch($followers)) {
+                               self::setBoundaries($follower['cid']);
+                               $accounts[] = DI::mstdnAccount()->createFromContactId($follower['cid'], $uid);
+                       }
+                       DBA::close($followers);
                }
                }
-               DBA::close($followers);
 
                if (!empty($request['min_id'])) {
                        $accounts = array_reverse($accounts);
 
                if (!empty($request['min_id'])) {
                        $accounts = array_reverse($accounts);
diff --git a/src/Worker/ContactDiscoveryForUser.php b/src/Worker/ContactDiscoveryForUser.php
new file mode 100644 (file)
index 0000000..d02f430
--- /dev/null
@@ -0,0 +1,36 @@
+<?php
+/**
+ * @copyright Copyright (C) 2010-2022, the Friendica project
+ *
+ * @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\Model\Contact;
+
+class ContactDiscoveryForUser
+{
+       /**
+        * Discover contact relations
+        * @param string $url
+        */
+       public static function execute(int $uid)
+       {
+               Contact\Relation::discoverByUser($uid);
+       }
+}