aboutsummaryrefslogtreecommitdiffhomepage
path: root/application
diff options
context:
space:
mode:
authorArthur <arthur@hoa.ro>2016-02-15 21:12:39 +0100
committerArthur <arthur@hoa.ro>2016-02-15 21:12:39 +0100
commit1e7331126d81a5759ab91c221f7e0f164aeebfb5 (patch)
treea5d084066e1e49fae01ae72f102b3eab2fb6d8ac /application
parent6e607ca613b47e17f7516e94adfee930d4f3e1e8 (diff)
parentce354bf1a61ce2478529ad558b24cdf9678c398a (diff)
downloadShaarli-1e7331126d81a5759ab91c221f7e0f164aeebfb5.tar.gz
Shaarli-1e7331126d81a5759ab91c221f7e0f164aeebfb5.tar.zst
Shaarli-1e7331126d81a5759ab91c221f7e0f164aeebfb5.zip
Merge pull request #446 from ArthurHoaro/search-tag-exclude
Add exclusion in tag search
Diffstat (limited to 'application')
-rw-r--r--application/LinkDB.php2
-rw-r--r--application/LinkFilter.php30
-rw-r--r--application/Updater.php15
3 files changed, 38 insertions, 9 deletions
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
340 * 340 *
341 * @return array filtered links 341 * @return array filtered links
342 */ 342 */
343 public function filter($type, $request, $casesensitive = false, $privateonly = false) 343 public function filter($type = '', $request = '', $casesensitive = false, $privateonly = false)
344 { 344 {
345 $linkFilter = new LinkFilter($this->_links); 345 $linkFilter = new LinkFilter($this->_links);
346 $requestFilter = is_array($request) ? implode(' ', $request) : $request; 346 $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
209 */ 209 */
210 public function filterTags($tags, $casesensitive = false, $privateonly = false) 210 public function filterTags($tags, $casesensitive = false, $privateonly = false)
211 { 211 {
212 $searchtags = $this->tagsStrToArray($tags, $casesensitive); 212 $searchtags = self::tagsStrToArray($tags, $casesensitive);
213 $filtered = array(); 213 $filtered = array();
214 if (empty($searchtags)) {
215 return $filtered;
216 }
214 217
215 foreach ($this->links as $l) { 218 foreach ($this->links as $link) {
216 // ignore non private links when 'privatonly' is on. 219 // ignore non private links when 'privatonly' is on.
217 if (! $l['private'] && $privateonly === true) { 220 if (! $link['private'] && $privateonly === true) {
218 continue; 221 continue;
219 } 222 }
220 223
221 $linktags = $this->tagsStrToArray($l['tags'], $casesensitive); 224 $linktags = self::tagsStrToArray($link['tags'], $casesensitive);
222 225
223 if (count(array_intersect($linktags, $searchtags)) == count($searchtags)) { 226 $found = true;
224 $filtered[$l['linkdate']] = $l; 227 for ($i = 0 ; $i < count($searchtags) && $found; $i++) {
228 // Exclusive search, quit if tag found.
229 // Or, tag not found in the link, quit.
230 if (($searchtags[$i][0] == '-' && in_array(substr($searchtags[$i], 1), $linktags))
231 || ($searchtags[$i][0] != '-') && ! in_array($searchtags[$i], $linktags)
232 ) {
233 $found = false;
234 }
235 }
236
237 if ($found) {
238 $filtered[$link['linkdate']] = $link;
225 } 239 }
226 } 240 }
227 krsort($filtered); 241 krsort($filtered);
@@ -266,12 +280,12 @@ class LinkFilter
266 * 280 *
267 * @return array filtered tags string. 281 * @return array filtered tags string.
268 */ 282 */
269 public function tagsStrToArray($tags, $casesensitive) 283 public static function tagsStrToArray($tags, $casesensitive)
270 { 284 {
271 // We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek) 285 // We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
272 $tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8'); 286 $tagsOut = $casesensitive ? $tags : mb_convert_case($tags, MB_CASE_LOWER, 'UTF-8');
273 $tagsOut = str_replace(',', ' ', $tagsOut); 287 $tagsOut = str_replace(',', ' ', $tagsOut);
274 288
275 return explode(' ', trim($tagsOut)); 289 return array_filter(explode(' ', trim($tagsOut)), 'strlen');
276 } 290 }
277} 291}
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
131 131
132 return true; 132 return true;
133 } 133 }
134
135 /**
136 * Rename tags starting with a '-' to work with tag exclusion search.
137 */
138 public function updateMethodRenameDashTags()
139 {
140 $linklist = $this->linkDB->filter();
141 foreach ($linklist as $link) {
142 $link['tags'] = preg_replace('/(^| )\-/', '$1', $link['tags']);
143 $link['tags'] = implode(' ', array_unique(LinkFilter::tagsStrToArray($link['tags'], true)));
144 $this->linkDB[$link['linkdate']] = $link;
145 }
146 $this->linkDB->savedb($this->config['config']['PAGECACHE']);
147 return true;
148 }
134} 149}
135 150
136/** 151/**