]> git.mxchange.org Git - friendica.git/blobdiff - src/Model/Contact.php
Use the function from the contact template instead
[friendica.git] / src / Model / Contact.php
index bb876405421e0e723457e2bb302cf3e786579937..7443d32a2efcb39958ae0a4c508ea41db16bddae 100644 (file)
@@ -22,6 +22,7 @@
 namespace Friendica\Model;
 
 use Friendica\App\BaseURL;
+use Friendica\Content\ContactSelector;
 use Friendica\Content\Pager;
 use Friendica\Core\Hook;
 use Friendica\Core\Logger;
@@ -207,7 +208,12 @@ class Contact
                        if (empty($cid)) {
                                return [];
                        }
-                       return self::getById($cid, $fields);
+
+                       $contact = self::getById($cid, $fields);
+                       if (empty($contact)) {
+                               return [];
+                       }
+                       return $contact;
                }
 
                // Add internal fields
@@ -238,6 +244,10 @@ class Contact
                        $contact = DBA::selectFirst('contact', $fields, $condition, $options);
                }
                
+               if (!DBA::isResult($contact)) {
+                       return [];
+               }
+
                // Update the contact in the background if needed
                if ((($contact['updated'] < DateTimeFormat::utc('now -7 days')) || empty($contact['avatar'])) &&
                        in_array($contact['network'], Protocol::FEDERATED)) {
@@ -2075,7 +2085,7 @@ class Contact
         * @throws HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
-       public static function updateFromProbe($id, $network = '', $force = false)
+       public static function updateFromProbe(int $id, string $network = '', bool $force = false)
        {
                /*
                  Warning: Never ever fetch the public key via Probe::uri and write it into the contacts.
@@ -2123,6 +2133,10 @@ class Contact
                        return false;
                }
 
+               if (ContactRelation::isDiscoverable($ret['url'])) {
+                       Worker::add(PRIORITY_LOW, 'ContactDiscovery', $ret['url']);
+               }
+
                if (isset($ret['hide']) && is_bool($ret['hide'])) {
                        $ret['unsearchable'] = $ret['hide'];
                }
@@ -2147,8 +2161,6 @@ class Contact
                        GContact::updateFromPublicContactID($id);
                }
 
-               ContactRelation::discoverByUrl($ret['url']);
-
                $update = false;
 
                // make sure to not overwrite existing values with blank entries except some technical fields
@@ -2904,4 +2916,157 @@ class Contact
 
                return in_array($protocol, [Protocol::DFRN, Protocol::DIASPORA, Protocol::ACTIVITYPUB]) && !$self;
        }
+
+       /**
+        * Search contact table by nick or name
+        *
+        * @param string $search Name or nick
+        * @param string $mode   Search mode (e.g. "community")
+        *
+        * @return array with search results
+        * @throws \Friendica\Network\HTTPException\InternalServerErrorException
+        */
+       public static function searchByName($search, $mode = '')
+       {
+               if (empty($search)) {
+                       return [];
+               }
+
+               // check supported networks
+               if (DI::config()->get('system', 'diaspora_enabled')) {
+                       $diaspora = Protocol::DIASPORA;
+               } else {
+                       $diaspora = Protocol::DFRN;
+               }
+
+               if (!DI::config()->get('system', 'ostatus_disabled')) {
+                       $ostatus = Protocol::OSTATUS;
+               } else {
+                       $ostatus = Protocol::DFRN;
+               }
+
+               // check if we search only communities or every contact
+               if ($mode === 'community') {
+                       $extra_sql = sprintf(' AND `contact-type` = %d', Contact::TYPE_COMMUNITY);
+               } else {
+                       $extra_sql = '';
+               }
+
+               $search .= '%';
+
+               $results = DBA::p("SELECT * FROM `contact`
+                       WHERE NOT `unsearchable` AND `network` IN (?, ?, ?, ?) AND
+                               NOT `failed` AND `uid` = ? AND
+                               (`addr` LIKE ? OR `name` LIKE ? OR `nick` LIKE ?) $extra_sql
+                               ORDER BY `nurl` DESC LIMIT 1000",
+                       Protocol::DFRN, Protocol::ACTIVITYPUB, $ostatus, $diaspora, 0, $search, $search, $search
+               );
+
+               $contacts = DBA::toArray($results);
+               return $contacts;
+       }
+
+       /**
+        * @param int $uid   user
+        * @param int $start optional, default 0
+        * @param int $limit optional, default 80
+        * @return array
+        */
+       static public function getSuggestions(int $uid, int $start = 0, int $limit = 80)
+       {
+               $cid = self::getPublicIdByUserId($uid);
+               $totallimit = $start + $limit;
+               $contacts = [];
+
+               Logger::info('Collecting suggestions', ['uid' => $uid, 'cid' => $cid, 'start' => $start, 'limit' => $limit]);
+
+               $diaspora = DI::config()->get('system', 'diaspora_enabled') ? Protocol::DIASPORA : Protocol::ACTIVITYPUB;
+               $ostatus = !DI::config()->get('system', 'ostatus_disabled') ? Protocol::OSTATUS : Protocol::ACTIVITYPUB;
+
+               // The query returns contacts where contacts interacted with who the given user follows.
+               // Contacts who already are in the user's contact table are ignored.
+               $results = DBA::select('contact', [],
+                       ["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` IN
+                               (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` = ?)
+                               AND NOT `cid` IN (SELECT `id` FROM `contact` WHERE `uid` = ? AND `nurl` IN
+                                       (SELECT `nurl` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?))))
+                       AND NOT `hidden` AND `network` IN (?, ?, ?, ?)",
+                       $cid, 0, $uid, Contact::FRIEND, Contact::SHARING,
+                       Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus],
+                       ['order' => ['last-item' => true], 'limit' => $totallimit]
+               );
+
+               while ($contact = DBA::fetch($results)) {
+                       $contacts[$contact['id']] = $contact;
+               }
+               DBA::close($results);
+
+               Logger::info('Contacts of contacts who are followed by the given user', ['uid' => $uid, 'cid' => $cid, 'count' => count($contacts)]);
+
+               if (count($contacts) >= $totallimit) {
+                       return array_slice($contacts, $start, $limit);
+               }
+
+               // The query returns contacts where contacts interacted with who also interacted with the given user.
+               // Contacts who already are in the user's contact table are ignored.
+               $results = DBA::select('contact', [],
+                       ["`id` IN (SELECT `cid` FROM `contact-relation` WHERE `relation-cid` IN
+                               (SELECT `relation-cid` FROM `contact-relation` WHERE `cid` = ?)
+                               AND NOT `cid` IN (SELECT `id` FROM `contact` WHERE `uid` = ? AND `nurl` IN
+                                       (SELECT `nurl` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?))))
+                       AND NOT `hidden` AND `network` IN (?, ?, ?, ?)",
+                       $cid, 0, $uid, Contact::FRIEND, Contact::SHARING,
+                       Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus],
+                       ['order' => ['last-item' => true], 'limit' => $totallimit]
+               );
+
+               while ($contact = DBA::fetch($results)) {
+                       $contacts[$contact['id']] = $contact;
+               }
+               DBA::close($results);
+
+               Logger::info('Contacts of contacts who are following the given user', ['uid' => $uid, 'cid' => $cid, 'count' => count($contacts)]);
+
+               if (count($contacts) >= $totallimit) {
+                       return array_slice($contacts, $start, $limit);
+               }
+
+               // The query returns contacts that follow the given user but aren't followed by that user.
+               $results = DBA::select('contact', [],
+                       ["`nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = ? AND `rel` = ?)
+                       AND NOT `hidden` AND `uid` = ? AND `network` IN (?, ?, ?, ?)",
+                       $uid, Contact::FOLLOWER, 0, 
+                       Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus],
+                       ['order' => ['last-item' => true], 'limit' => $totallimit]
+               );
+
+               while ($contact = DBA::fetch($results)) {
+                       $contacts[$contact['id']] = $contact;
+               }
+               DBA::close($results);
+
+               Logger::info('Followers that are not followed by the given user', ['uid' => $uid, 'cid' => $cid, 'count' => count($contacts)]);
+
+               if (count($contacts) >= $totallimit) {
+                       return array_slice($contacts, $start, $limit);
+               }
+
+               // The query returns any contact that isn't followed by that user.
+               $results = DBA::select('contact', [],
+                       ["NOT `nurl` IN (SELECT `nurl` FROM `contact` WHERE `uid` = ? AND `rel` IN (?, ?))
+                       AND NOT `hidden` AND `uid` = ? AND `network` IN (?, ?, ?, ?)",
+                       $uid, Contact::FRIEND, Contact::SHARING, 0, 
+                       Protocol::ACTIVITYPUB, Protocol::DFRN, $diaspora, $ostatus],
+                       ['order' => ['last-item' => true], 'limit' => $totallimit]
+               );
+
+               while ($contact = DBA::fetch($results)) {
+                       $contacts[$contact['id']] = $contact;
+               }
+               DBA::close($results);
+
+               Logger::info('Any contact', ['uid' => $uid, 'cid' => $cid, 'count' => count($contacts)]);
+
+               return array_slice($contacts, $start, $limit);
+       }
 }