]> git.mxchange.org Git - friendica.git/commitdiff
Add profile URL search
authorHypolite Petovan <hypolite@mrpetovan.com>
Tue, 24 Dec 2019 22:38:04 +0000 (17:38 -0500)
committerHypolite Petovan <hypolite@mrpetovan.com>
Fri, 27 Dec 2019 01:17:12 +0000 (20:17 -0500)
- Move post URL search to private method in Module\Search\Index

src/Module/Search/Index.php

index 29ebeffd06571a2d71f833f1eafd2ecfdf11631e..010f0a790aa5e3a2e1f4fd32e4696edacfab1772 100644 (file)
@@ -16,6 +16,7 @@ use Friendica\Core\Logger;
 use Friendica\Core\Renderer;
 use Friendica\Core\Session;
 use Friendica\Database\DBA;
+use Friendica\Model\Contact;
 use Friendica\Model\Item;
 use Friendica\Model\Term;
 use Friendica\Module\BaseSearchModule;
@@ -38,6 +39,9 @@ class Index extends BaseSearchModule
                        throw $e;
                }
 
+               /** @var BaseURL $baseURL */
+               $baseURL = self::getClass(BaseURL::class);
+
                if (Config::get('system', 'permit_crawling') && !Session::isAuthenticated()) {
                        // Default values:
                        // 10 requests are "free", after the 11th only a call per minute is allowed
@@ -92,23 +96,13 @@ class Index extends BaseSearchModule
                        $search = substr($search, 1);
                }
 
+               self::tryRedirectToProfile($baseURL, $search);
+
                if (strpos($search, '@') === 0 || strpos($search, '!') === 0) {
                        return self::performContactSearch($search);
                }
 
-               if (parse_url($search, PHP_URL_SCHEME) != '') {
-                       /** @var BaseURL $baseURL */
-                       $baseURL = self::getClass(BaseURL::class);
-
-                       // Post URL search
-                       $item_id = Item::fetchByLink($search);
-                       if (!empty($item_id)) {
-                               $item = Item::selectFirst(['guid'], ['id' => $item_id]);
-                               if (DBA::isResult($item)) {
-                                       $baseURL->redirect('display/' . $item['guid']);
-                               }
-                       }
-               }
+               self::tryRedirectToPost($baseURL, $search);
 
                if (!empty($_GET['search-option'])) {
                        switch ($_GET['search-option']) {
@@ -202,4 +196,91 @@ class Index extends BaseSearchModule
 
                return $o;
        }
+
+       /**
+        * Tries to redirect to a local profile page based on the input.
+        *
+        * This method separates logged in and anonymous users. Logged in users can trigger contact probes to import
+        * non-existing contacts while anonymous users can only trigger a local lookup.
+        *
+        * Formats matched:
+        * - @user@domain
+        * - user@domain
+        * - Any fully-formed URL
+        *
+        * @param BaseURL $baseURL
+        * @param string  $search
+        * @throws HTTPException\InternalServerErrorException
+        * @throws \ImagickException
+        */
+       private static function tryRedirectToProfile(BaseURL $baseURL, string $search)
+       {
+               $isUrl = parse_url($search, PHP_URL_SCHEME) !== '';
+               $isAddr = preg_match('/^@?([a-z0-9.-_]+@[a-z0-9.-_:]+)$/i', trim($search), $matches);
+
+               if (!$isUrl && !$isAddr) {
+                       return;
+               }
+
+               if ($isAddr) {
+                       $search = $matches[1];
+               }
+
+               if (local_user()) {
+                       // User-specific contact URL/address search
+                       $contact_id = Contact::getIdForURL($search, local_user());
+                       if (!$contact_id) {
+                               // User-specific contact URL/address search and probe
+                               $contact_id = Contact::getIdForURL($search);
+                       }
+               } else {
+                       // Cheaper local lookup for anonymous users, no probe
+                       if ($isAddr) {
+                               $contact = Contact::selectFirst(['id' => 'cid'], ['addr' => $search, 'uid' => 0]);
+                       } else {
+                               $contact = Contact::getDetailsByURL($search, 0, ['cid' => 0]);
+                       }
+
+                       if (DBA::isResult($contact)) {
+                               $contact_id = $contact['cid'];
+                       }
+               }
+
+               if (!empty($contact_id)) {
+                       $baseURL->redirect('contact/' . $contact_id);
+               }
+       }
+
+       /**
+        * Fetch/search a post by URL and redirects to its local representation if it was found.
+        *
+        * @param BaseURL $baseURL
+        * @param string  $search
+        * @throws HTTPException\InternalServerErrorException
+        */
+       private static function tryRedirectToPost(BaseURL $baseURL, string $search)
+       {
+               if (parse_url($search, PHP_URL_SCHEME) == '') {
+                       return;
+               }
+
+               if (local_user()) {
+                       // Post URL search
+                       $item_id = Item::fetchByLink($search, local_user());
+                       if (!$item_id) {
+                               // If the user-specific search failed, we search and probe a public post
+                               $item_id = Item::fetchByLink($search);
+                       }
+               } else {
+                       // Cheaper local lookup for anonymous users, no probe
+                       $item_id = Item::searchByLink($search);
+               }
+
+               if (!empty($item_id)) {
+                       $item = Item::selectFirst(['guid'], ['id' => $item_id]);
+                       if (DBA::isResult($item)) {
+                               $baseURL->redirect('display/' . $item['guid']);
+                       }
+               }
+       }
 }