aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--application/LinkDB.php6
-rw-r--r--application/LinkFilter.php60
-rw-r--r--application/api/controllers/Links.php3
-rw-r--r--index.php4
-rw-r--r--tests/LinkFilterTest.php73
5 files changed, 107 insertions, 39 deletions
diff --git a/application/LinkDB.php b/application/LinkDB.php
index 1e13286a..4cee2af9 100644
--- a/application/LinkDB.php
+++ b/application/LinkDB.php
@@ -443,11 +443,11 @@ You use the community supported version of the original Shaarli project, by Seba
443 * - searchtags: list of tags 443 * - searchtags: list of tags
444 * - searchterm: term search 444 * - searchterm: term search
445 * @param bool $casesensitive Optional: Perform case sensitive filter 445 * @param bool $casesensitive Optional: Perform case sensitive filter
446 * @param bool $privateonly Optional: Returns private links only if true. 446 * @param string $visibility return only all/private/public links
447 * 447 *
448 * @return array filtered links, all links if no suitable filter was provided. 448 * @return array filtered links, all links if no suitable filter was provided.
449 */ 449 */
450 public function filterSearch($filterRequest = array(), $casesensitive = false, $privateonly = false) 450 public function filterSearch($filterRequest = array(), $casesensitive = false, $visibility = 'all')
451 { 451 {
452 // Filter link database according to parameters. 452 // Filter link database according to parameters.
453 $searchtags = !empty($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : ''; 453 $searchtags = !empty($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : '';
@@ -475,7 +475,7 @@ You use the community supported version of the original Shaarli project, by Seba
475 } 475 }
476 476
477 $linkFilter = new LinkFilter($this); 477 $linkFilter = new LinkFilter($this);
478 return $linkFilter->filter($type, $request, $casesensitive, $privateonly); 478 return $linkFilter->filter($type, $request, $casesensitive, $visibility);
479 } 479 }
480 480
481 /** 481 /**
diff --git a/application/LinkFilter.php b/application/LinkFilter.php
index 57ebfd5c..81832a4b 100644
--- a/application/LinkFilter.php
+++ b/application/LinkFilter.php
@@ -51,12 +51,16 @@ class LinkFilter
51 * @param string $type Type of filter (eg. tags, permalink, etc.). 51 * @param string $type Type of filter (eg. tags, permalink, etc.).
52 * @param mixed $request Filter content. 52 * @param mixed $request Filter content.
53 * @param bool $casesensitive Optional: Perform case sensitive filter if true. 53 * @param bool $casesensitive Optional: Perform case sensitive filter if true.
54 * @param bool $privateonly Optional: Only returns private links if true. 54 * @param string $visibility Optional: return only all/private/public links
55 * 55 *
56 * @return array filtered link list. 56 * @return array filtered link list.
57 */ 57 */
58 public function filter($type, $request, $casesensitive = false, $privateonly = false) 58 public function filter($type, $request, $casesensitive = false, $visibility = 'all')
59 { 59 {
60 if (! in_array($visibility, ['all', 'public', 'private'])) {
61 $visibility = 'all';
62 }
63
60 switch($type) { 64 switch($type) {
61 case self::$FILTER_HASH: 65 case self::$FILTER_HASH:
62 return $this->filterSmallHash($request); 66 return $this->filterSmallHash($request);
@@ -64,42 +68,44 @@ class LinkFilter
64 if (!empty($request)) { 68 if (!empty($request)) {
65 $filtered = $this->links; 69 $filtered = $this->links;
66 if (isset($request[0])) { 70 if (isset($request[0])) {
67 $filtered = $this->filterTags($request[0], $casesensitive, $privateonly); 71 $filtered = $this->filterTags($request[0], $casesensitive, $visibility);
68 } 72 }
69 if (isset($request[1])) { 73 if (isset($request[1])) {
70 $lf = new LinkFilter($filtered); 74 $lf = new LinkFilter($filtered);
71 $filtered = $lf->filterFulltext($request[1], $privateonly); 75 $filtered = $lf->filterFulltext($request[1], $visibility);
72 } 76 }
73 return $filtered; 77 return $filtered;
74 } 78 }
75 return $this->noFilter($privateonly); 79 return $this->noFilter($visibility);
76 case self::$FILTER_TEXT: 80 case self::$FILTER_TEXT:
77 return $this->filterFulltext($request, $privateonly); 81 return $this->filterFulltext($request, $visibility);
78 case self::$FILTER_TAG: 82 case self::$FILTER_TAG:
79 return $this->filterTags($request, $casesensitive, $privateonly); 83 return $this->filterTags($request, $casesensitive, $visibility);
80 case self::$FILTER_DAY: 84 case self::$FILTER_DAY:
81 return $this->filterDay($request); 85 return $this->filterDay($request);
82 default: 86 default:
83 return $this->noFilter($privateonly); 87 return $this->noFilter($visibility);
84 } 88 }
85 } 89 }
86 90
87 /** 91 /**
88 * Unknown filter, but handle private only. 92 * Unknown filter, but handle private only.
89 * 93 *
90 * @param bool $privateonly returns private link only if true. 94 * @param string $visibility Optional: return only all/private/public links
91 * 95 *
92 * @return array filtered links. 96 * @return array filtered links.
93 */ 97 */
94 private function noFilter($privateonly = false) 98 private function noFilter($visibility = 'all')
95 { 99 {
96 if (! $privateonly) { 100 if ($visibility === 'all') {
97 return $this->links; 101 return $this->links;
98 } 102 }
99 103
100 $out = array(); 104 $out = array();
101 foreach ($this->links as $key => $value) { 105 foreach ($this->links as $key => $value) {
102 if ($value['private']) { 106 if ($value['private'] && $visibility === 'private') {
107 $out[$key] = $value;
108 } else if (! $value['private'] && $visibility === 'public') {
103 $out[$key] = $value; 109 $out[$key] = $value;
104 } 110 }
105 } 111 }
@@ -151,14 +157,14 @@ class LinkFilter
151 * - see https://github.com/shaarli/Shaarli/issues/75 for examples 157 * - see https://github.com/shaarli/Shaarli/issues/75 for examples
152 * 158 *
153 * @param string $searchterms search query. 159 * @param string $searchterms search query.
154 * @param bool $privateonly return only private links if true. 160 * @param string $visibility Optional: return only all/private/public links.
155 * 161 *
156 * @return array search results. 162 * @return array search results.
157 */ 163 */
158 private function filterFulltext($searchterms, $privateonly = false) 164 private function filterFulltext($searchterms, $visibility = 'all')
159 { 165 {
160 if (empty($searchterms)) { 166 if (empty($searchterms)) {
161 return $this->links; 167 return $this->noFilter($visibility);
162 } 168 }
163 169
164 $filtered = array(); 170 $filtered = array();
@@ -189,8 +195,12 @@ class LinkFilter
189 foreach ($this->links as $id => $link) { 195 foreach ($this->links as $id => $link) {
190 196
191 // ignore non private links when 'privatonly' is on. 197 // ignore non private links when 'privatonly' is on.
192 if (! $link['private'] && $privateonly === true) { 198 if ($visibility !== 'all') {
193 continue; 199 if (! $link['private'] && $visibility === 'private') {
200 continue;
201 } else if ($link['private'] && $visibility === 'public') {
202 continue;
203 }
194 } 204 }
195 205
196 // Concatenate link fields to search across fields. 206 // Concatenate link fields to search across fields.
@@ -235,16 +245,16 @@ class LinkFilter
235 * 245 *
236 * @param string $tags list of tags separated by commas or blank spaces. 246 * @param string $tags list of tags separated by commas or blank spaces.
237 * @param bool $casesensitive ignore case if false. 247 * @param bool $casesensitive ignore case if false.
238 * @param bool $privateonly returns private links only. 248 * @param string $visibility Optional: return only all/private/public links.
239 * 249 *
240 * @return array filtered links. 250 * @return array filtered links.
241 */ 251 */
242 public function filterTags($tags, $casesensitive = false, $privateonly = false) 252 public function filterTags($tags, $casesensitive = false, $visibility = 'all')
243 { 253 {
244 // Implode if array for clean up. 254 // Implode if array for clean up.
245 $tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags; 255 $tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags;
246 if (empty($tags)) { 256 if (empty($tags)) {
247 return $this->links; 257 return $this->noFilter($visibility);
248 } 258 }
249 259
250 $searchtags = self::tagsStrToArray($tags, $casesensitive); 260 $searchtags = self::tagsStrToArray($tags, $casesensitive);
@@ -255,8 +265,12 @@ class LinkFilter
255 265
256 foreach ($this->links as $key => $link) { 266 foreach ($this->links as $key => $link) {
257 // ignore non private links when 'privatonly' is on. 267 // ignore non private links when 'privatonly' is on.
258 if (! $link['private'] && $privateonly === true) { 268 if ($visibility !== 'all') {
259 continue; 269 if (! $link['private'] && $visibility === 'private') {
270 continue;
271 } else if ($link['private'] && $visibility === 'public') {
272 continue;
273 }
260 } 274 }
261 275
262 $linktags = self::tagsStrToArray($link['tags'], $casesensitive); 276 $linktags = self::tagsStrToArray($link['tags'], $casesensitive);
@@ -341,7 +355,7 @@ class LinkFilter
341 * @param bool $casesensitive will convert everything to lowercase if false. 355 * @param bool $casesensitive will convert everything to lowercase if false.
342 * 356 *
343 * @return array filtered tags string. 357 * @return array filtered tags string.
344 */ 358 */
345 public static function tagsStrToArray($tags, $casesensitive) 359 public static function tagsStrToArray($tags, $casesensitive)
346 { 360 {
347 // We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek) 361 // We use UTF-8 conversion to handle various graphemes (i.e. cyrillic, or greek)
diff --git a/application/api/controllers/Links.php b/application/api/controllers/Links.php
index 1c7b41cd..01b7e783 100644
--- a/application/api/controllers/Links.php
+++ b/application/api/controllers/Links.php
@@ -41,7 +41,8 @@ class Links extends ApiController
41 'searchterm' => $request->getParam('searchterm', ''), 41 'searchterm' => $request->getParam('searchterm', ''),
42 ], 42 ],
43 false, 43 false,
44 $private === 'true' || $private === '1' 44 // to updated in another PR depending on the API doc
45 ($private === 'true' || $private === '1') ? 'private' : 'all'
45 ); 46 );
46 47
47 // Return links from the {offset}th link, starting from 0. 48 // Return links from the {offset}th link, starting from 0.
diff --git a/index.php b/index.php
index 145ea3f6..4f07a013 100644
--- a/index.php
+++ b/index.php
@@ -1630,8 +1630,8 @@ function buildLinkList($PAGE,$LINKSDB, $conf, $pluginManager)
1630 } 1630 }
1631 } else { 1631 } else {
1632 // Filter links according search parameters. 1632 // Filter links according search parameters.
1633 $privateonly = !empty($_SESSION['privateonly']); 1633 $visibility = ! empty($_SESSION['privateonly']) ? 'private' : 'all';
1634 $linksToDisplay = $LINKSDB->filterSearch($_GET, false, $privateonly); 1634 $linksToDisplay = $LINKSDB->filterSearch($_GET, false, $visibility);
1635 } 1635 }
1636 1636
1637 // ---- Handle paging. 1637 // ---- Handle paging.
diff --git a/tests/LinkFilterTest.php b/tests/LinkFilterTest.php
index 21d680a5..37d5ca30 100644
--- a/tests/LinkFilterTest.php
+++ b/tests/LinkFilterTest.php
@@ -13,12 +13,17 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
13 protected static $linkFilter; 13 protected static $linkFilter;
14 14
15 /** 15 /**
16 * @var ReferenceLinkDB instance
17 */
18 protected static $refDB;
19
20 /**
16 * Instanciate linkFilter with ReferenceLinkDB data. 21 * Instanciate linkFilter with ReferenceLinkDB data.
17 */ 22 */
18 public static function setUpBeforeClass() 23 public static function setUpBeforeClass()
19 { 24 {
20 $refDB = new ReferenceLinkDB(); 25 self::$refDB = new ReferenceLinkDB();
21 self::$linkFilter = new LinkFilter($refDB->getLinks()); 26 self::$linkFilter = new LinkFilter(self::$refDB->getLinks());
22 } 27 }
23 28
24 /** 29 /**
@@ -27,14 +32,30 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
27 public function testFilter() 32 public function testFilter()
28 { 33 {
29 $this->assertEquals( 34 $this->assertEquals(
30 ReferenceLinkDB::$NB_LINKS_TOTAL, 35 self::$refDB->countLinks(),
31 count(self::$linkFilter->filter('', '')) 36 count(self::$linkFilter->filter('', ''))
32 ); 37 );
33 38
39 $this->assertEquals(
40 self::$refDB->countLinks(),
41 count(self::$linkFilter->filter('', '', 'all'))
42 );
43
44 $this->assertEquals(
45 self::$refDB->countLinks(),
46 count(self::$linkFilter->filter('', '', 'randomstr'))
47 );
48
34 // Private only. 49 // Private only.
35 $this->assertEquals( 50 $this->assertEquals(
36 2, 51 self::$refDB->countPrivateLinks(),
37 count(self::$linkFilter->filter('', '', false, true)) 52 count(self::$linkFilter->filter('', '', false, 'private'))
53 );
54
55 // Public only.
56 $this->assertEquals(
57 self::$refDB->countPublicLinks(),
58 count(self::$linkFilter->filter('', '', false, 'public'))
38 ); 59 );
39 60
40 $this->assertEquals( 61 $this->assertEquals(
@@ -58,10 +79,26 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
58 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false)) 79 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false))
59 ); 80 );
60 81
82 $this->assertEquals(
83 4,
84 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'all'))
85 );
86
87 $this->assertEquals(
88 4,
89 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'default-blabla'))
90 );
91
61 // Private only. 92 // Private only.
62 $this->assertEquals( 93 $this->assertEquals(
63 1, 94 1,
64 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, true)) 95 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'private'))
96 );
97
98 // Public only.
99 $this->assertEquals(
100 3,
101 count(self::$linkFilter->filter(LinkFilter::$FILTER_TAG, 'web', false, 'public'))
65 ); 102 );
66 } 103 }
67 104
@@ -253,14 +290,30 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
253 public function testFilterFullTextTags() 290 public function testFilterFullTextTags()
254 { 291 {
255 $this->assertEquals( 292 $this->assertEquals(
256 2, 293 6,
257 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'gnu')) 294 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web'))
295 );
296
297 $this->assertEquals(
298 6,
299 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'all'))
300 );
301
302 $this->assertEquals(
303 6,
304 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', 'bla'))
258 ); 305 );
259 306
260 // Private only. 307 // Private only.
261 $this->assertEquals( 308 $this->assertEquals(
262 1, 309 1,
263 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, true)) 310 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'private'))
311 );
312
313 // Public only.
314 $this->assertEquals(
315 5,
316 count(self::$linkFilter->filter(LinkFilter::$FILTER_TEXT, 'web', false, 'public'))
264 ); 317 );
265 } 318 }
266 319
@@ -409,7 +462,7 @@ class LinkFilterTest extends PHPUnit_Framework_TestCase
409 LinkFilter::$FILTER_TAG, 462 LinkFilter::$FILTER_TAG,
410 $hashtag, 463 $hashtag,
411 false, 464 false,
412 true 465 'private'
413 )) 466 ))
414 ); 467 );
415 } 468 }