diff options
Diffstat (limited to 'application')
-rw-r--r-- | application/FeedBuilder.php | 5 | ||||
-rw-r--r-- | application/LinkDB.php | 38 | ||||
-rw-r--r-- | application/LinkFilter.php | 30 | ||||
-rw-r--r-- | application/PageBuilder.php | 2 | ||||
-rw-r--r-- | application/Router.php | 12 | ||||
-rw-r--r-- | application/Utils.php | 35 |
6 files changed, 95 insertions, 27 deletions
diff --git a/application/FeedBuilder.php b/application/FeedBuilder.php index a1f4da48..7377bcec 100644 --- a/application/FeedBuilder.php +++ b/application/FeedBuilder.php | |||
@@ -97,6 +97,11 @@ class FeedBuilder | |||
97 | */ | 97 | */ |
98 | public function buildData() | 98 | public function buildData() |
99 | { | 99 | { |
100 | // Search for untagged links | ||
101 | if (isset($this->userInput['searchtags']) && empty($this->userInput['searchtags'])) { | ||
102 | $this->userInput['searchtags'] = false; | ||
103 | } | ||
104 | |||
100 | // Optionally filter the results: | 105 | // Optionally filter the results: |
101 | $linksToDisplay = $this->linkDB->filterSearch($this->userInput); | 106 | $linksToDisplay = $this->linkDB->filterSearch($this->userInput); |
102 | 107 | ||
diff --git a/application/LinkDB.php b/application/LinkDB.php index 0d3c85bd..8ca0fab3 100644 --- a/application/LinkDB.php +++ b/application/LinkDB.php | |||
@@ -423,43 +423,29 @@ You use the community supported version of the original Shaarli project, by Seba | |||
423 | public function filterSearch($filterRequest = array(), $casesensitive = false, $visibility = 'all') | 423 | public function filterSearch($filterRequest = array(), $casesensitive = false, $visibility = 'all') |
424 | { | 424 | { |
425 | // Filter link database according to parameters. | 425 | // Filter link database according to parameters. |
426 | $searchtags = !empty($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : ''; | 426 | $searchtags = isset($filterRequest['searchtags']) ? escape($filterRequest['searchtags']) : ''; |
427 | $searchterm = !empty($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : ''; | 427 | $searchterm = isset($filterRequest['searchterm']) ? escape($filterRequest['searchterm']) : ''; |
428 | 428 | ||
429 | // Search tags + fullsearch. | 429 | // Search tags + fullsearch - blank string parameter will return all links. |
430 | if (! empty($searchtags) && ! empty($searchterm)) { | 430 | $type = LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT; |
431 | $type = LinkFilter::$FILTER_TAG | LinkFilter::$FILTER_TEXT; | 431 | $request = [$searchtags, $searchterm]; |
432 | $request = array($searchtags, $searchterm); | ||
433 | } | ||
434 | // Search by tags. | ||
435 | elseif (! empty($searchtags)) { | ||
436 | $type = LinkFilter::$FILTER_TAG; | ||
437 | $request = $searchtags; | ||
438 | } | ||
439 | // Fulltext search. | ||
440 | elseif (! empty($searchterm)) { | ||
441 | $type = LinkFilter::$FILTER_TEXT; | ||
442 | $request = $searchterm; | ||
443 | } | ||
444 | // Otherwise, display without filtering. | ||
445 | else { | ||
446 | $type = ''; | ||
447 | $request = ''; | ||
448 | } | ||
449 | 432 | ||
450 | $linkFilter = new LinkFilter($this); | 433 | $linkFilter = new LinkFilter($this); |
451 | return $linkFilter->filter($type, $request, $casesensitive, $visibility); | 434 | return $linkFilter->filter($type, $request, $casesensitive, $visibility); |
452 | } | 435 | } |
453 | 436 | ||
454 | /** | 437 | /** |
455 | * Returns the list of all tags | 438 | * Returns the list tags appearing in the links with the given tags |
456 | * Output: associative array key=tags, value=0 | 439 | * @param $filteringTags: tags selecting the links to consider |
440 | * @param $visibility: process only all/private/public links | ||
441 | * @return: a tag=>linksCount array | ||
457 | */ | 442 | */ |
458 | public function allTags() | 443 | public function linksCountPerTag($filteringTags = [], $visibility = 'all') |
459 | { | 444 | { |
445 | $links = empty($filteringTags) ? $this->links : $this->filterSearch(['searchtags' => $filteringTags], false, $visibility); | ||
460 | $tags = array(); | 446 | $tags = array(); |
461 | $caseMapping = array(); | 447 | $caseMapping = array(); |
462 | foreach ($this->links as $link) { | 448 | foreach ($links as $link) { |
463 | foreach (preg_split('/\s+/', $link['tags'], 0, PREG_SPLIT_NO_EMPTY) as $tag) { | 449 | foreach (preg_split('/\s+/', $link['tags'], 0, PREG_SPLIT_NO_EMPTY) as $tag) { |
464 | if (empty($tag)) { | 450 | if (empty($tag)) { |
465 | continue; | 451 | continue; |
diff --git a/application/LinkFilter.php b/application/LinkFilter.php index 81832a4b..0e887d38 100644 --- a/application/LinkFilter.php +++ b/application/LinkFilter.php | |||
@@ -253,6 +253,9 @@ class LinkFilter | |||
253 | { | 253 | { |
254 | // Implode if array for clean up. | 254 | // Implode if array for clean up. |
255 | $tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags; | 255 | $tags = is_array($tags) ? trim(implode(' ', $tags)) : $tags; |
256 | if ($tags === false) { | ||
257 | return $this->filterUntagged($visibility); | ||
258 | } | ||
256 | if (empty($tags)) { | 259 | if (empty($tags)) { |
257 | return $this->noFilter($visibility); | 260 | return $this->noFilter($visibility); |
258 | } | 261 | } |
@@ -296,6 +299,33 @@ class LinkFilter | |||
296 | } | 299 | } |
297 | 300 | ||
298 | /** | 301 | /** |
302 | * Return only links without any tag. | ||
303 | * | ||
304 | * @param string $visibility return only all/private/public links. | ||
305 | * | ||
306 | * @return array filtered links. | ||
307 | */ | ||
308 | public function filterUntagged($visibility) | ||
309 | { | ||
310 | $filtered = []; | ||
311 | foreach ($this->links as $key => $link) { | ||
312 | if ($visibility !== 'all') { | ||
313 | if (! $link['private'] && $visibility === 'private') { | ||
314 | continue; | ||
315 | } else if ($link['private'] && $visibility === 'public') { | ||
316 | continue; | ||
317 | } | ||
318 | } | ||
319 | |||
320 | if (empty(trim($link['tags']))) { | ||
321 | $filtered[$key] = $link; | ||
322 | } | ||
323 | } | ||
324 | |||
325 | return $filtered; | ||
326 | } | ||
327 | |||
328 | /** | ||
299 | * Returns the list of articles for a given day, chronologically sorted | 329 | * Returns the list of articles for a given day, chronologically sorted |
300 | * | 330 | * |
301 | * Day must be in the form 'YYYYMMDD' (e.g. '20120125'), e.g. | 331 | * Day must be in the form 'YYYYMMDD' (e.g. '20120125'), e.g. |
diff --git a/application/PageBuilder.php b/application/PageBuilder.php index 50e3f124..c86621a2 100644 --- a/application/PageBuilder.php +++ b/application/PageBuilder.php | |||
@@ -89,7 +89,7 @@ class PageBuilder | |||
89 | $this->tpl->assign('hide_timestamps', $this->conf->get('privacy.hide_timestamps', false)); | 89 | $this->tpl->assign('hide_timestamps', $this->conf->get('privacy.hide_timestamps', false)); |
90 | $this->tpl->assign('token', getToken($this->conf)); | 90 | $this->tpl->assign('token', getToken($this->conf)); |
91 | if ($this->linkDB !== null) { | 91 | if ($this->linkDB !== null) { |
92 | $this->tpl->assign('tags', $this->linkDB->allTags()); | 92 | $this->tpl->assign('tags', $this->linkDB->linksCountPerTag()); |
93 | } | 93 | } |
94 | // To be removed with a proper theme configuration. | 94 | // To be removed with a proper theme configuration. |
95 | $this->tpl->assign('conf', $this->conf); | 95 | $this->tpl->assign('conf', $this->conf); |
diff --git a/application/Router.php b/application/Router.php index c9a51912..4df0387c 100644 --- a/application/Router.php +++ b/application/Router.php | |||
@@ -13,6 +13,8 @@ class Router | |||
13 | 13 | ||
14 | public static $PAGE_TAGCLOUD = 'tagcloud'; | 14 | public static $PAGE_TAGCLOUD = 'tagcloud'; |
15 | 15 | ||
16 | public static $PAGE_TAGLIST = 'taglist'; | ||
17 | |||
16 | public static $PAGE_DAILY = 'daily'; | 18 | public static $PAGE_DAILY = 'daily'; |
17 | 19 | ||
18 | public static $PAGE_FEED_ATOM = 'atom'; | 20 | public static $PAGE_FEED_ATOM = 'atom'; |
@@ -45,6 +47,8 @@ class Router | |||
45 | 47 | ||
46 | public static $PAGE_SAVE_PLUGINSADMIN = 'save_pluginadmin'; | 48 | public static $PAGE_SAVE_PLUGINSADMIN = 'save_pluginadmin'; |
47 | 49 | ||
50 | public static $GET_TOKEN = 'token'; | ||
51 | |||
48 | /** | 52 | /** |
49 | * Reproducing renderPage() if hell, to avoid regression. | 53 | * Reproducing renderPage() if hell, to avoid regression. |
50 | * | 54 | * |
@@ -77,6 +81,10 @@ class Router | |||
77 | return self::$PAGE_TAGCLOUD; | 81 | return self::$PAGE_TAGCLOUD; |
78 | } | 82 | } |
79 | 83 | ||
84 | if (startsWith($query, 'do='. self::$PAGE_TAGLIST)) { | ||
85 | return self::$PAGE_TAGLIST; | ||
86 | } | ||
87 | |||
80 | if (startsWith($query, 'do='. self::$PAGE_OPENSEARCH)) { | 88 | if (startsWith($query, 'do='. self::$PAGE_OPENSEARCH)) { |
81 | return self::$PAGE_OPENSEARCH; | 89 | return self::$PAGE_OPENSEARCH; |
82 | } | 90 | } |
@@ -142,6 +150,10 @@ class Router | |||
142 | return self::$PAGE_SAVE_PLUGINSADMIN; | 150 | return self::$PAGE_SAVE_PLUGINSADMIN; |
143 | } | 151 | } |
144 | 152 | ||
153 | if (startsWith($query, 'do='. self::$GET_TOKEN)) { | ||
154 | return self::$GET_TOKEN; | ||
155 | } | ||
156 | |||
145 | return self::$PAGE_LINKLIST; | 157 | return self::$PAGE_LINKLIST; |
146 | } | 158 | } |
147 | } | 159 | } |
diff --git a/application/Utils.php b/application/Utils.php index ab463af9..4a2f5561 100644 --- a/application/Utils.php +++ b/application/Utils.php | |||
@@ -91,6 +91,10 @@ function endsWith($haystack, $needle, $case = true) | |||
91 | */ | 91 | */ |
92 | function escape($input) | 92 | function escape($input) |
93 | { | 93 | { |
94 | if (is_bool($input)) { | ||
95 | return $input; | ||
96 | } | ||
97 | |||
94 | if (is_array($input)) { | 98 | if (is_array($input)) { |
95 | $out = array(); | 99 | $out = array(); |
96 | foreach($input as $key => $value) { | 100 | foreach($input as $key => $value) { |
@@ -435,3 +439,34 @@ function get_max_upload_size($limitPost, $limitUpload, $format = true) | |||
435 | $maxsize = min($size1, $size2); | 439 | $maxsize = min($size1, $size2); |
436 | return $format ? human_bytes($maxsize) : $maxsize; | 440 | return $format ? human_bytes($maxsize) : $maxsize; |
437 | } | 441 | } |
442 | |||
443 | /** | ||
444 | * Sort the given array alphabetically using php-intl if available. | ||
445 | * Case sensitive. | ||
446 | * | ||
447 | * Note: doesn't support multidimensional arrays | ||
448 | * | ||
449 | * @param array $data Input array, passed by reference | ||
450 | * @param bool $reverse Reverse sort if set to true | ||
451 | * @param bool $byKeys Sort the array by keys if set to true, by value otherwise. | ||
452 | */ | ||
453 | function alphabetical_sort(&$data, $reverse = false, $byKeys = false) | ||
454 | { | ||
455 | $callback = function($a, $b) use ($reverse) { | ||
456 | // Collator is part of PHP intl. | ||
457 | if (class_exists('Collator')) { | ||
458 | $collator = new Collator(setlocale(LC_COLLATE, 0)); | ||
459 | if (!intl_is_failure(intl_get_error_code())) { | ||
460 | return $collator->compare($a, $b) * ($reverse ? -1 : 1); | ||
461 | } | ||
462 | } | ||
463 | |||
464 | return strcasecmp($a, $b) * ($reverse ? -1 : 1); | ||
465 | }; | ||
466 | |||
467 | if ($byKeys) { | ||
468 | uksort($data, $callback); | ||
469 | } else { | ||
470 | usort($data, $callback); | ||
471 | } | ||
472 | } | ||