]> git.mxchange.org Git - friendica.git/blobdiff - src/Core/Search.php
Allow nullable UID in PConfigCache
[friendica.git] / src / Core / Search.php
index c08d4ebcc92f2d63af1de572904694f7b7073307..9f8375da12f66e539a25d1da0954a3c14b34ca1a 100644 (file)
@@ -5,44 +5,56 @@ namespace Friendica\Core;
 use Friendica\BaseObject;
 use Friendica\Database\DBA;
 use Friendica\Model\Contact;
-use Friendica\Network\Probe;
 use Friendica\Network\HTTPException;
+use Friendica\Network\Probe;
 use Friendica\Object\Search\ContactResult;
 use Friendica\Object\Search\ResultList;
 use Friendica\Protocol\PortableContact;
 use Friendica\Util\Network;
 use Friendica\Util\Strings;
 
+/**
+ * Specific class to perform searches for different systems. Currently:
+ * - Probe for contacts
+ * - Search in the local directory
+ * - Search in the global directory
+ */
 class Search extends BaseObject
 {
        const DEFAULT_DIRECTORY = 'https://dir.friendica.social';
 
+       const TYPE_PEOPLE = 0;
+       const TYPE_FORUM  = 1;
+       const TYPE_ALL    = 2;
+
        /**
         * Search a user based on his/her profile address
         * pattern: @username@domain.tld
         *
         * @param string $user The user to search for
         *
-        * @return ResultList|null
+        * @return ResultList
         * @throws HTTPException\InternalServerErrorException
         * @throws \ImagickException
         */
        public static function getContactsFromProbe($user)
        {
+               $emptyResultList = new ResultList(1, 0, 1);
+
                if ((filter_var($user, FILTER_VALIDATE_EMAIL) && Network::isEmailDomainValid($user)) ||
                    (substr(Strings::normaliseLink($user), 0, 7) == "http://")) {
 
                        $user_data = Probe::uri($user);
                        if (empty($user_data)) {
-                               return null;
+                               return $emptyResultList;
                        }
 
-                       if (!(in_array($user_data["network"], [Protocol::ACTIVITYPUB, Protocol::DFRN, Protocol::OSTATUS, Protocol::DIASPORA]))) {
-                               return null;
+                       if (!(in_array($user_data["network"], Protocol::FEDERATED))) {
+                               return $emptyResultList;
                        }
 
                        $contactDetails = Contact::getDetailsByURL(defaults($user_data, 'url', ''), local_user());
-                       $itemUrl = (($contactDetails["addr"] != "") ? $contactDetails["addr"] : defaults($user_data, 'url', ''));
+                       $itemUrl        = defaults($contactDetails, 'addr', defaults($user_data, 'url', ''));
 
                        $result = new ContactResult(
                                defaults($user_data, 'name', ''),
@@ -57,49 +69,59 @@ class Search extends BaseObject
                        );
 
                        return new ResultList(1, 1, 1, [$result]);
-
                } else {
-                       return null;
+                       return $emptyResultList;
                }
        }
 
        /**
         * Search in the global directory for occurrences of the search string
-        * This is mainly based on the JSON results of https://dir.friendica.social
+        *
+        * @see https://github.com/friendica/friendica-directory/blob/master/docs/Protocol.md#search
         *
         * @param string $search
+        * @param int    $type specific type of searching
         * @param int    $page
         *
-        * @return ResultList|null
+        * @return ResultList
         * @throws HTTPException\InternalServerErrorException
         */
-       public static function getContactsFromGlobalDirectory($search, $page = 1)
+       public static function getContactsFromGlobalDirectory($search, $type = self::TYPE_ALL, $page = 1)
        {
                $config = self::getApp()->getConfig();
                $server = $config->get('system', 'directory', self::DEFAULT_DIRECTORY);
 
-               $searchUrl = $server . '/search?q=' . urlencode($search);
+               $searchUrl = $server . '/search';
+
+               switch ($type) {
+                       case self::TYPE_FORUM:
+                               $searchUrl .= '/forum';
+                               break;
+                       case self::TYPE_PEOPLE:
+                               $searchUrl .= '/people';
+                               break;
+               }
+               $searchUrl .= '?q=' . urlencode($search);
 
                if ($page > 1) {
                        $searchUrl .= '&page=' . $page;
                }
 
-               $red = 0;
-               $resultJson = Network::fetchUrl($searchUrl, false,$red, 0, 'application/json');
+               $resultJson = Network::fetchUrl($searchUrl, false, 0, 'application/json');
 
-               $results    = json_decode($resultJson, true);
+               $results = json_decode($resultJson, true);
 
                $resultList = new ResultList(
                        defaults($results, 'page', 1),
-                       defaults($results, 'count', 1),
-                       defaults($results, 'itemsperpage', 1)
+                       defaults($results, 'count', 0),
+                       defaults($results, 'itemsperpage', 30)
                );
 
                $profiles = defaults($results, 'profiles', []);
 
                foreach ($profiles as $profile) {
                        $contactDetails = Contact::getDetailsByURL(defaults($profile, 'profile_url', ''), local_user());
-                       $itemUrl = (!empty($contactDetails['addr']) ? $contactDetails['addr'] : defaults($profile, 'profile_url', ''));
+                       $itemUrl        = defaults($contactDetails, 'addr', defaults($profile, 'profile_url', ''));
 
                        $result = new ContactResult(
                                defaults($profile, 'name', ''),
@@ -122,14 +144,14 @@ class Search extends BaseObject
         * Search in the local database for occurrences of the search string
         *
         * @param string $search
+        * @param int    $type
         * @param int    $start
         * @param int    $itemPage
-        * @param bool   $community
         *
-        * @return ResultList|null
+        * @return ResultList
         * @throws HTTPException\InternalServerErrorException
         */
-       public static function getContactsFromLocalDirectory($search, $start = 0, $itemPage = 80, $community = false)
+       public static function getContactsFromLocalDirectory($search, $type = self::TYPE_ALL, $start = 0, $itemPage = 80)
        {
                $config = self::getApp()->getConfig();
 
@@ -148,11 +170,13 @@ class Search extends BaseObject
                        Protocol::ACTIVITYPUB, Protocol::DFRN, $ostatus, $diaspora,
                        $wildcard, $wildcard, $wildcard,
                        $wildcard, $wildcard, $wildcard,
-                       $community,
+                       ($type === self::TYPE_FORUM),
                ]);
 
+               $resultList = new ResultList($start, $itemPage, $count);
+
                if (empty($count)) {
-                       return null;
+                       return $resultList;
                }
 
                $data = DBA::select('gcontact', ['nurl'], [
@@ -165,19 +189,17 @@ class Search extends BaseObject
                        Protocol::ACTIVITYPUB, Protocol::DFRN, $ostatus, $diaspora,
                        $wildcard, $wildcard, $wildcard,
                        $wildcard, $wildcard, $wildcard,
-                       $community,
+                       ($type === self::TYPE_FORUM),
                ], [
                        'group_by' => ['nurl', 'updated'],
-                       'limit' => [$start, $itemPage],
-                       'order' => ['updated' => 'DESC']
+                       'limit'    => [$start, $itemPage],
+                       'order'    => ['updated' => 'DESC']
                ]);
 
                if (!DBA::isResult($data)) {
-                       return null;
+                       return $resultList;
                }
 
-               $resultList = new ResultList($start, $itemPage, $count);
-
                while ($row = DBA::fetch($data)) {
                        if (PortableContact::alternateOStatusUrl($row["nurl"])) {
                                continue;