aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--application/Utils.php2
-rw-r--r--application/front/controllers/TagCloudController.php89
-rw-r--r--application/security/SessionManager.php10
-rw-r--r--doc/md/Translations.md2
-rw-r--r--index.php45
-rw-r--r--tpl/default/page.header.html2
-rw-r--r--tpl/default/tag.cloud.html2
-rw-r--r--tpl/default/tag.sort.html2
-rw-r--r--tpl/vintage/page.header.html2
9 files changed, 107 insertions, 49 deletions
diff --git a/application/Utils.php b/application/Utils.php
index 4b7fc546..4e97cdda 100644
--- a/application/Utils.php
+++ b/application/Utils.php
@@ -87,7 +87,7 @@ function endsWith($haystack, $needle, $case = true)
87 * 87 *
88 * @param mixed $input Data to escape: a single string or an array of strings. 88 * @param mixed $input Data to escape: a single string or an array of strings.
89 * 89 *
90 * @return string escaped. 90 * @return string|array escaped.
91 */ 91 */
92function escape($input) 92function escape($input)
93{ 93{
diff --git a/application/front/controllers/TagCloudController.php b/application/front/controllers/TagCloudController.php
new file mode 100644
index 00000000..b6f4a0ce
--- /dev/null
+++ b/application/front/controllers/TagCloudController.php
@@ -0,0 +1,89 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller;
6
7use Slim\Http\Request;
8use Slim\Http\Response;
9
10/**
11 * Class TagCloud
12 *
13 * Slim controller used to render the tag cloud page.
14 *
15 * @package Front\Controller
16 */
17class TagCloudController extends ShaarliController
18{
19 public function index(Request $request, Response $response): Response
20 {
21 if ($this->container->loginManager->isLoggedIn() === true) {
22 $visibility = $this->container->sessionManager->getSessionParameter('visibility');
23 }
24
25 $searchTags = $request->getQueryParam('searchtags');
26 $filteringTags = $searchTags !== null ? explode(' ', $searchTags) : [];
27
28 $tags = $this->container->bookmarkService->bookmarksCountPerTag($filteringTags, $visibility ?? null);
29
30 // We sort tags alphabetically, then choose a font size according to count.
31 // First, find max value.
32 $maxCount = 0;
33 foreach ($tags as $count) {
34 $maxCount = max($maxCount, $count);
35 }
36
37 alphabetical_sort($tags, false, true);
38
39 $logMaxCount = $maxCount > 1 ? log($maxCount, 30) : 1;
40 $tagList = [];
41 foreach ($tags as $key => $value) {
42 if (in_array($key, $filteringTags)) {
43 continue;
44 }
45 // Tag font size scaling:
46 // default 15 and 30 logarithm bases affect scaling,
47 // 2.2 and 0.8 are arbitrary font sizes in em.
48 $size = log($value, 15) / $logMaxCount * 2.2 + 0.8;
49 $tagList[$key] = [
50 'count' => $value,
51 'size' => number_format($size, 2, '.', ''),
52 ];
53 }
54
55 $searchTags = implode(' ', escape($filteringTags));
56 $data = [
57 'search_tags' => $searchTags,
58 'tags' => $tagList,
59 ];
60 $data = $this->executeHooks($data);
61 foreach ($data as $key => $value) {
62 $this->assignView($key, $value);
63 }
64
65 $searchTags = !empty($searchTags) ? $searchTags .' - ' : '';
66 $this->assignView(
67 'pagetitle',
68 $searchTags. t('Tag cloud') .' - '. $this->container->conf->get('general.title', 'Shaarli')
69 );
70
71 return $response->write($this->render('tag.cloud'));
72 }
73
74 /**
75 * @param mixed[] $data Template data
76 *
77 * @return mixed[] Template data after active plugins render_picwall hook execution.
78 */
79 protected function executeHooks(array $data): array
80 {
81 $this->container->pluginManager->executeHooks(
82 'render_tagcloud',
83 $data,
84 ['loggedin' => $this->container->loginManager->isLoggedIn()]
85 );
86
87 return $data;
88 }
89}
diff --git a/application/security/SessionManager.php b/application/security/SessionManager.php
index 994fcbe5..4ae99168 100644
--- a/application/security/SessionManager.php
+++ b/application/security/SessionManager.php
@@ -202,4 +202,14 @@ class SessionManager
202 { 202 {
203 return $this->session; 203 return $this->session;
204 } 204 }
205
206 /**
207 * @param mixed $default value which will be returned if the $key is undefined
208 *
209 * @return mixed Content stored in session
210 */
211 public function getSessionParameter(string $key, $default = null)
212 {
213 return $this->session[$key] ?? $default;
214 }
205} 215}
diff --git a/doc/md/Translations.md b/doc/md/Translations.md
index dfdd021e..b8b7053f 100644
--- a/doc/md/Translations.md
+++ b/doc/md/Translations.md
@@ -44,7 +44,7 @@ http://<replace_domain>/?do=import
44http://<replace_domain>/login 44http://<replace_domain>/login
45http://<replace_domain>/picture-wall 45http://<replace_domain>/picture-wall
46http://<replace_domain>/?do=pluginadmin 46http://<replace_domain>/?do=pluginadmin
47http://<replace_domain>/?do=tagcloud 47http://<replace_domain>/tag-cloud
48http://<replace_domain>/?do=taglist 48http://<replace_domain>/?do=taglist
49``` 49```
50 50
diff --git a/index.php b/index.php
index a42c844a..83f1264f 100644
--- a/index.php
+++ b/index.php
@@ -616,49 +616,7 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM
616 616
617 // -------- Tag cloud 617 // -------- Tag cloud
618 if ($targetPage == Router::$PAGE_TAGCLOUD) { 618 if ($targetPage == Router::$PAGE_TAGCLOUD) {
619 $visibility = ! empty($_SESSION['visibility']) ? $_SESSION['visibility'] : ''; 619 header('Location: ./tag-cloud');
620 $filteringTags = isset($_GET['searchtags']) ? explode(' ', $_GET['searchtags']) : [];
621 $tags = $bookmarkService->bookmarksCountPerTag($filteringTags, $visibility);
622
623 // We sort tags alphabetically, then choose a font size according to count.
624 // First, find max value.
625 $maxcount = 0;
626 foreach ($tags as $value) {
627 $maxcount = max($maxcount, $value);
628 }
629
630 alphabetical_sort($tags, false, true);
631
632 $logMaxCount = $maxcount > 1 ? log($maxcount, 30) : 1;
633 $tagList = array();
634 foreach ($tags as $key => $value) {
635 if (in_array($key, $filteringTags)) {
636 continue;
637 }
638 // Tag font size scaling:
639 // default 15 and 30 logarithm bases affect scaling,
640 // 2.2 and 0.8 are arbitrary font sizes in em.
641 $size = log($value, 15) / $logMaxCount * 2.2 + 0.8;
642 $tagList[$key] = array(
643 'count' => $value,
644 'size' => number_format($size, 2, '.', ''),
645 );
646 }
647
648 $searchTags = implode(' ', escape($filteringTags));
649 $data = array(
650 'search_tags' => $searchTags,
651 'tags' => $tagList,
652 );
653 $pluginManager->executeHooks('render_tagcloud', $data, array('loggedin' => $loginManager->isLoggedIn()));
654
655 foreach ($data as $key => $value) {
656 $PAGE->assign($key, $value);
657 }
658
659 $searchTags = ! empty($searchTags) ? $searchTags .' - ' : '';
660 $PAGE->assign('pagetitle', $searchTags. t('Tag cloud') .' - '. $conf->get('general.title', 'Shaarli'));
661 $PAGE->renderPage('tag.cloud');
662 exit; 620 exit;
663 } 621 }
664 622
@@ -1916,6 +1874,7 @@ $app->group('', function () {
1916 $this->get('/login', '\Shaarli\Front\Controller\LoginController:index')->setName('login'); 1874 $this->get('/login', '\Shaarli\Front\Controller\LoginController:index')->setName('login');
1917 $this->get('/logout', '\Shaarli\Front\Controller\LogoutController:index')->setName('logout'); 1875 $this->get('/logout', '\Shaarli\Front\Controller\LogoutController:index')->setName('logout');
1918 $this->get('/picture-wall', '\Shaarli\Front\Controller\PictureWallController:index')->setName('picwall'); 1876 $this->get('/picture-wall', '\Shaarli\Front\Controller\PictureWallController:index')->setName('picwall');
1877 $this->get('/tag-cloud', '\Shaarli\Front\Controller\TagCloudController:index')->setName('tagcloud');
1919 $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\TagController:addTag')->setName('add-tag'); 1878 $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\TagController:addTag')->setName('add-tag');
1920})->add('\Shaarli\Front\ShaarliMiddleware'); 1879})->add('\Shaarli\Front\ShaarliMiddleware');
1921 1880
diff --git a/tpl/default/page.header.html b/tpl/default/page.header.html
index 2086aeb0..ea89a209 100644
--- a/tpl/default/page.header.html
+++ b/tpl/default/page.header.html
@@ -30,7 +30,7 @@
30 </li> 30 </li>
31 {/if} 31 {/if}
32 <li class="pure-menu-item" id="shaarli-menu-tags"> 32 <li class="pure-menu-item" id="shaarli-menu-tags">
33 <a href="./?do=tagcloud" class="pure-menu-link">{'Tag cloud'|t}</a> 33 <a href="./tag-cloud" class="pure-menu-link">{'Tag cloud'|t}</a>
34 </li> 34 </li>
35 {if="$thumbnails_enabled"} 35 {if="$thumbnails_enabled"}
36 <li class="pure-menu-item" id="shaarli-menu-picwall"> 36 <li class="pure-menu-item" id="shaarli-menu-picwall">
diff --git a/tpl/default/tag.cloud.html b/tpl/default/tag.cloud.html
index 80dcebf5..547d5018 100644
--- a/tpl/default/tag.cloud.html
+++ b/tpl/default/tag.cloud.html
@@ -15,7 +15,7 @@
15 <h2 class="window-title">{'Tag cloud'|t} - {$countTags} {'tags'|t}</h2> 15 <h2 class="window-title">{'Tag cloud'|t} - {$countTags} {'tags'|t}</h2>
16 {if="!empty($search_tags)"} 16 {if="!empty($search_tags)"}
17 <p class="center"> 17 <p class="center">
18 <a href="?searchtags={$search_tags|urlencode}" class="pure-button pure-button-shaarli"> 18 <a href="./?searchtags={$search_tags|urlencode}" class="pure-button pure-button-shaarli">
19 {'List all links with those tags'|t} 19 {'List all links with those tags'|t}
20 </a> 20 </a>
21 </p> 21 </p>
diff --git a/tpl/default/tag.sort.html b/tpl/default/tag.sort.html
index 7af4723d..b7aa7d80 100644
--- a/tpl/default/tag.sort.html
+++ b/tpl/default/tag.sort.html
@@ -1,7 +1,7 @@
1<div class="pure-g"> 1<div class="pure-g">
2 <div class="pure-u-1 pure-alert pure-alert-success tag-sort"> 2 <div class="pure-u-1 pure-alert pure-alert-success tag-sort">
3 {'Sort by:'|t} 3 {'Sort by:'|t}
4 <a href="./?do=tagcloud">{'Cloud'|t}</a> &middot; 4 <a href="./tag-cloud">{'Cloud'|t}</a> &middot;
5 <a href="./?do=taglist&sort=usage">{'Most used'|t}</a> &middot; 5 <a href="./?do=taglist&sort=usage">{'Most used'|t}</a> &middot;
6 <a href="./?do=taglist&sort=alpha">{'Alphabetical'|t}</a> 6 <a href="./?do=taglist&sort=alpha">{'Alphabetical'|t}</a>
7 </div> 7 </div>
diff --git a/tpl/vintage/page.header.html b/tpl/vintage/page.header.html
index 8b9db353..971fac9a 100644
--- a/tpl/vintage/page.header.html
+++ b/tpl/vintage/page.header.html
@@ -31,7 +31,7 @@
31 {if="$showatom"} 31 {if="$showatom"}
32 <li><a href="{$feedurl}?do=atom{$searchcrits}" class="nomobile">ATOM Feed</a></li> 32 <li><a href="{$feedurl}?do=atom{$searchcrits}" class="nomobile">ATOM Feed</a></li>
33 {/if} 33 {/if}
34 <li><a href="./?do=tagcloud">Tag cloud</a></li> 34 <li><a href="./tag-cloud">Tag cloud</a></li>
35 <li><a href="./picture-wall{function="ltrim($searchcrits, '&')"}">Picture wall</a></li> 35 <li><a href="./picture-wall{function="ltrim($searchcrits, '&')"}">Picture wall</a></li>
36 <li><a href="./?do=daily">Daily</a></li> 36 <li><a href="./?do=daily">Daily</a></li>
37 {loop="$plugins_header.buttons_toolbar"} 37 {loop="$plugins_header.buttons_toolbar"}