From 21979ff11ceee0042642ac17147858a4155d54c5 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Wed, 20 Jan 2016 23:34:33 +0100 Subject: Add exclusion in tag search * Searching '-mytag' will now exlude all shaares with 'mytag' tag. * All tags starting with a '-' are renamed without it (through the Updater). * Unit tests. Minor code changes: * LinkDB->filter() can now take no parameters (get all link depending on logged status). * tagsStrToArray() is now static and filters blank tags. --- application/LinkDB.php | 2 +- application/LinkFilter.php | 30 ++++++++++++++++++++++-------- application/Updater.php | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 9 deletions(-) (limited to 'application') diff --git a/application/LinkDB.php b/application/LinkDB.php index a95b3f36..416aa0d3 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php @@ -340,7 +340,7 @@ You use the community supported version of the original Shaarli project, by Seba * * @return array filtered links */ - public function filter($type, $request, $casesensitive = false, $privateonly = false) + public function filter($type = '', $request = '', $casesensitive = false, $privateonly = false) { $linkFilter = new LinkFilter($this->_links); $requestFilter = is_array($request) ? implode(' ', $request) : $request; diff --git a/application/LinkFilter.php b/application/LinkFilter.php index 096d3b04..ceb47d16 100644 --- a/application/LinkFilter.php +++ b/application/LinkFilter.php @@ -209,19 +209,33 @@ class LinkFilter */ public function filterTags($tags, $casesensitive = false, $privateonly = false) { - $searchtags = $this->tagsStrToArray($tags, $casesensitive); + $searchtags = self::tagsStrToArray($tags, $casesensitive); $filtered = array(); + if (empty($searchtags)) { + return $filtered; + } - foreach ($this->links as $l) { + foreach ($this->links as $link) { // ignore non private links when 'privatonly' is on. - if (! $l['private'] && $privateonly === true) { + if (! $link['private'] && $privateonly === true) { continue; } - $linktags = $this->tagsStrToArray($l['tags'], $casesensitive); + $linktags = self::tagsStrToArray($link['tags'], $casesensitive); - if (count(array_intersect($linktags, $searchtags)) == count($searchtags)) { - $filtered[$l['linkdate']] = $l; + $found = true; + for ($i = 0 ; $i < count($searchtags) && $found; $i++) { + // Exclusive search, quit if tag found. + // Or, tag not found in the link, quit. + if (($searchtags[$i][0] == '-' && in_array(substr($searchtags[$i], 1), $linktags)) + || ($searchtags[$i][0] != '-') && ! in_array($searchtags[$i], $linktags) + ) { + $found = false; + } + } + + if ($found) { + $filtered[$link['linkdate']] = $link; } } krsort($filtered); @@ -266,12 +280,12 @@ class LinkFilter * * @return array filtered tags string. */ - public function tagsStrToArray($tags, $casesensitive) + public static function tagsStrToArray($tags, $casesensitive) { // We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek) $tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8'); $tagsOut = str_replace(',', ' ', $tagsOut); - return explode(' ', trim($tagsOut)); + return array_filter(explode(' ', trim($tagsOut)), 'strlen'); } } diff --git a/application/Updater.php b/application/Updater.php index 20ae0c4d..773a1ffa 100644 --- a/application/Updater.php +++ b/application/Updater.php @@ -131,6 +131,21 @@ class Updater return true; } + + /** + * Rename tags starting with a '-' to work with tag exclusion search. + */ + public function updateMethodRenameDashTags() + { + $linklist = $this->linkDB->filter(); + foreach ($linklist as $link) { + $link['tags'] = preg_replace('/(^| )\-/', '$1', $link['tags']); + $link['tags'] = implode(' ', array_unique(LinkFilter::tagsStrToArray($link['tags'], true))); + $this->linkDB[$link['linkdate']] = $link; + } + $this->linkDB->savedb($this->config['config']['PAGECACHE']); + return true; + } } /** -- cgit v1.2.3