]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Merge pull request #841 from ArthurHoaro/feature/search-no-tag
authorArthurHoaro <arthur@hoa.ro>
Thu, 25 May 2017 13:54:20 +0000 (15:54 +0200)
committerGitHub <noreply@github.com>
Thu, 25 May 2017 13:54:20 +0000 (15:54 +0200)
Empty tag search will look for not tagged links

12 files changed:
application/FeedBuilder.php
application/LinkDB.php
application/LinkFilter.php
application/Utils.php
index.php
tests/LinkDBTest.php
tests/LinkFilterTest.php
tests/api/controllers/GetLinksTest.php
tests/api/controllers/InfoTest.php
tests/utils/ReferenceLinkDB.php
tpl/default/linklist.html
tpl/vintage/linklist.html

index a1f4da4810c0b25dceebb8d6698de93cf4eb81e9..7377bcec09c3fa21b92434953661133b386e0829 100644 (file)
@@ -97,6 +97,11 @@ class FeedBuilder
      */
     public function buildData()
     {
+        // Search for untagged links
+        if (isset($this->userInput['searchtags']) && empty($this->userInput['searchtags'])) {
+            $this->userInput['searchtags'] = false;
+        }
+
         // Optionally filter the results:
         $linksToDisplay = $this->linkDB->filterSearch($this->userInput);
 
index 7802cc8a1dd408a022d2471efec794fbca1bbfe7..8ca0fab30d55cbee54501579375e7d0697f48e62 100644 (file)
@@ -423,29 +423,12 @@ You use the community supported version of the original Shaarli project, by Seba
     public function filterSearch($filterRequest = array(), $casesensitive = false, $visibility = 'all')
     {
         // Filter link database according to parameters.
-        $searchtags = !empty($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
-        $searchterm = !empty($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : '';
+        $searchtags = isset($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
+        $searchterm = isset($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : '';
 
-        // Search tags + fullsearch.
-        if (! empty($searchtags) && ! empty($searchterm)) {
-            $type = LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT;
-            $request = array($searchtags, $searchterm);
-        }
-        // Search by tags.
-        elseif (! empty($searchtags)) {
-            $type = LinkFilter::$FILTER_TAG;
-            $request = $searchtags;
-        }
-        // Fulltext search.
-        elseif (! empty($searchterm)) {
-            $type = LinkFilter::$FILTER_TEXT;
-            $request = $searchterm;
-        }
-        // Otherwise, display without filtering.
-        else {
-            $type = '';
-            $request = '';
-        }
+        // Search tags + fullsearch - blank string parameter will return all links.
+        $type = LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT;
+        $request = [$searchtags, $searchterm];
 
         $linkFilter = new LinkFilter($this);
         return $linkFilter->filter($type, $request, $casesensitive, $visibility);
index 81832a4b428f4bc650d3049b8e0ced2a850c1cdc..0e887d3805a2fa7ef2024f5da2d6b155dc4a870e 100644 (file)
@@ -253,6 +253,9 @@ class LinkFilter
     {
         // Implode if array for clean up.
         $tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags;
+        if ($tags === false) {
+            return $this->filterUntagged($visibility);
+        }
         if (empty($tags)) {
             return $this->noFilter($visibility);
         }
@@ -295,6 +298,33 @@ class LinkFilter
         return $filtered;
     }
 
+    /**
+     * Return only links without any tag.
+     *
+     * @param string $visibility return only all/private/public links.
+     *
+     * @return array filtered links.
+     */
+    public function filterUntagged($visibility)
+    {
+        $filtered = [];
+        foreach ($this->links as $key => $link) {
+            if ($visibility !== 'all') {
+                if (! $link['private'] && $visibility === 'private') {
+                    continue;
+                } else if ($link['private'] && $visibility === 'public') {
+                    continue;
+                }
+            }
+
+            if (empty(trim($link['tags']))) {
+                $filtered[$key] = $link;
+            }
+        }
+
+        return $filtered;
+    }
+
     /**
      * Returns the list of articles for a given day, chronologically sorted
      *
index 9d0ebc5ea3a86c68ac7693c9f793855866658d0c..4a2f5561cfdf5dfb38ed9a0a4c0f46b58b27c8c6 100644 (file)
@@ -91,6 +91,10 @@ function endsWith($haystack, $needle, $case = true)
  */
 function escape($input)
 {
+    if (is_bool($input)) {
+        return $input;
+    }
+
     if (is_array($input)) {
         $out = array();
         foreach($input as $key => $value) {
index 61b71129810114d95dbb9697ae5e649de2fa475a..92eb443ba6310477ed04d831a62c72d03f2bcc3c 100644 (file)
--- a/index.php
+++ b/index.php
@@ -1622,7 +1622,15 @@ function renderPage($conf, $pluginManager, $LINKSDB, $history)
 function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager)
 {
     // Used in templates
-    $searchtags = !empty($_GET['searchtags']) ? escape(normalize_spaces($_GET['searchtags'])) : '';
+    if (isset($_GET['searchtags'])) {
+        if (! empty($_GET['searchtags'])) {
+            $searchtags = escape(normalize_spaces($_GET['searchtags']));
+        } else {
+            $searchtags = false;
+        }
+    } else {
+        $searchtags = '';
+    }
     $searchterm = !empty($_GET['searchterm']) ? escape(normalize_spaces($_GET['searchterm'])) : '';
 
     // Smallhash filter
@@ -1637,7 +1645,11 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager)
     } else {
         // Filter links according search parameters.
         $visibility = ! empty($_SESSION['privateonly']) ? 'private' : 'all';
-        $linksToDisplay = $LINKSDB->filterSearch($_GET, false, $visibility);
+        $request = [
+            'searchtags' => $searchtags,
+            'searchterm' => $searchterm,
+        ];
+        $linksToDisplay = $LINKSDB->filterSearch($request, false, $visibility);
     }
 
     // ---- Handle paging.
@@ -1684,7 +1696,7 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager)
     }
 
     // Compute paging navigation
-    $searchtagsUrl = empty($searchtags) ? '' : '&searchtags=' . urlencode($searchtags);
+    $searchtagsUrl = $searchtags === '' ? '' : '&searchtags=' . urlencode($searchtags);
     $searchtermUrl = empty($searchterm) ? '' : '&searchterm=' . urlencode($searchterm);
     $previous_page_url = '';
     if ($i != count($keys)) {
index 2523467d19aeb7e688cbc3e873822bdce51ece94..25438277e5babf1b7850c3dd65fd92972c7c37aa 100644 (file)
@@ -475,7 +475,7 @@ class LinkDBTest extends PHPUnit_Framework_TestCase
     public function testReorderLinksDesc()
     {
         self::$privateLinkDB->reorder('ASC');
-        $linkIds = array(42, 4, 1, 0, 7, 6, 8, 41);
+        $linkIds = array(42, 4, 9, 1, 0, 7, 6, 8, 41);
         $cpt = 0;
         foreach (self::$privateLinkDB as $key => $value) {
             $this->assertEquals($linkIds[$cpt++], $key);
index 37d5ca306e4f128edd350e1f88542fab7880ea84..741623580ce30e0980638675db8f17b9e02d2e70 100644 (file)
@@ -63,6 +63,12 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
             count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, ''))
         );
 
+        // Untagged only
+        $this->assertEquals(
+            self::$refDB->countUntaggedLinks(),
+            count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, false))
+        );
+
         $this->assertEquals(
             ReferenceLinkDB::$NB_LINKS_TOTAL,
             count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, ''))
@@ -146,7 +152,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
     public function testFilterDay()
     {
         $this->assertEquals(
-            3,
+            4,
             count(self::$linkFilter->filter(LinkFilter::$FILTER_DAY, '20121206'))
         );
     }
@@ -339,7 +345,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
         );
 
         $this->assertEquals(
-            7,
+            ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
             count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, '-revolution'))
         );
     }
@@ -399,7 +405,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
         );
 
         $this->assertEquals(
-            7,
+            ReferenceLinkDB::$NB_LINKS_TOTAL - 1,
             count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, '-free'))
         );
     }
@@ -425,6 +431,13 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
                 array('', $terms)
             ))
         );
+        $this->assertEquals(
+            1,
+            count(self::$linkFilter->filter(
+                LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT,
+                array(false, 'PSR-2')
+            ))
+        );
         $this->assertEquals(
             1,
             count(self::$linkFilter->filter(
index 84ae7f7af863dedc7c5e19e9f7b0264e79c2a173..4cb70224ce734318862810e647eabdd52490d452 100644 (file)
@@ -95,7 +95,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals($this->refDB->countLinks(), count($data));
 
         // Check order
-        $order = [41, 8, 6, 7, 0, 1, 4, 42];
+        $order = [41, 8, 6, 7, 0, 1, 9, 4, 42];
         $cpt = 0;
         foreach ($data as $link) {
             $this->assertEquals(self::NB_FIELDS_LINK, count($link));
@@ -164,7 +164,7 @@ class GetLinksTest extends \PHPUnit_Framework_TestCase
         $data = json_decode((string) $response->getBody(), true);
         $this->assertEquals($this->refDB->countLinks(), count($data));
         // Check order
-        $order = [41, 8, 6, 7, 0, 1, 4, 42];
+        $order = [41, 8, 6, 7, 0, 1, 9, 4, 42];
         $cpt = 0;
         foreach ($data as $link) {
             $this->assertEquals(self::NB_FIELDS_LINK, count($link));
index e85eb281ffa5c750c8389f33ea7a8288882c52b0..f7e63bfaf2623e498ce0f9605c76aad7e517975b 100644 (file)
@@ -81,7 +81,7 @@ class InfoTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(200, $response->getStatusCode());
         $data = json_decode((string) $response->getBody(), true);
 
-        $this->assertEquals(8, $data['global_counter']);
+        $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, $data['global_counter']);
         $this->assertEquals(2, $data['private_counter']);
         $this->assertEquals('Shaarli', $data['settings']['title']);
         $this->assertEquals('?', $data['settings']['header_link']);
@@ -104,7 +104,7 @@ class InfoTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals(200, $response->getStatusCode());
         $data = json_decode((string) $response->getBody(), true);
 
-        $this->assertEquals(8, $data['global_counter']);
+        $this->assertEquals(\ReferenceLinkDB::$NB_LINKS_TOTAL, $data['global_counter']);
         $this->assertEquals(2, $data['private_counter']);
         $this->assertEquals($title, $data['settings']['title']);
         $this->assertEquals($headerLink, $data['settings']['header_link']);
index 1f4b306372e9a8dd4959d9e3636c39220ea01202..f09eebc13b26f701ecc8944602794bc22adbc219 100644 (file)
@@ -4,7 +4,7 @@
  */
 class ReferenceLinkDB
 {
-    public static $NB_LINKS_TOTAL = 8;
+    public static $NB_LINKS_TOTAL = 9;
 
     private $_links = array();
     private $_publicCount = 0;
@@ -37,6 +37,16 @@ class ReferenceLinkDB
             'ut'
         );
 
+        $this->addLink(
+            9,
+            'PSR-2: Coding Style Guide',
+            'http://www.php-fig.org/psr/psr-2/',
+            'This guide extends and expands on PSR-1, the basic coding standard.',
+            0,
+            DateTime::createFromFormat(LinkDB::LINK_DATE_FORMAT, '20121206_152312'),
+            ''
+        );
+
         $this->addLink(
             8,
             'Free as in Freedom 2.0 @website',
@@ -161,6 +171,20 @@ class ReferenceLinkDB
         return $this->_privateCount;
     }
 
+    /**
+     * Returns the number of links without tag
+     */
+    public function countUntaggedLinks()
+    {
+        $cpt = 0;
+        foreach ($this->_links as $link) {
+            if (empty($link['tags'])) {
+                ++$cpt;
+            }
+        }
+        return $cpt;
+    }
+
     public function getLinks()
     {
         return $this->_links;
index 6a4e14a6a820b2bf0629b07ab312c642fee2abac..2568a5d6525c1622d77ea9bdadaad9140dadc34a 100644 (file)
@@ -91,7 +91,7 @@
         <div id="searchcriteria">{'Nothing found.'|t}</div>
       </div>
     </div>
-  {elseif="!empty($search_term) or !empty($search_tags) or !empty($visibility)"}
+  {elseif="!empty($search_term) or $search_tags !== '' or !empty($visibility)"}
     <div class="pure-g pure-alert pure-alert-success search-result">
       <div class="pure-u-2-24"></div>
       <div class="pure-u-20-24">
                 <a href="?removetag={function="urlencode($value)"}">{$value}<span class="remove"><i class="fa fa-times"></i></span></a>
               </span>
           {/loop}
+        {elseif="$search_tags === false"}
+          <span class="label label-tag" title="{'Remove tag'|t}">
+            <a href="?">{'untagged'|t}<span class="remove"><i class="fa fa-times"></i></span></a>
+          </span>
         {/if}
         {if="!empty($visibility)"}
           {'with status'|t}
index fc116667aac83dd12bb4d45bbfad8d5744cbb560..8458caa1c89224f377370b34ecfaedeb2ae8b395 100644 (file)
@@ -55,7 +55,7 @@
 
     {if="count($links)==0"}
         <div id="searchcriteria">Nothing found.</div>
-    {elseif="!empty($search_term) or !empty($search_tags)"}
+    {elseif="!empty($search_term) or $search_tags !== ''"}
         <div id="searchcriteria">
             {$result_count} results
             {if="!empty($search_term)"}
                         <a href="?removetag={function="urlencode($value)"}">{$value} <span class="remove">x</span></a>
                     </span>
                 {/loop}
+            {elseif="$search_tags === false"}
+                <span class="linktag" title="Remove tag">
+                    <a href="?">untagged <span class="remove">x</span></a>
+                </span>
             {/if}
         </div>
     {/if}