diff options
-rw-r--r-- | application/Utils.php | 2 | ||||
-rw-r--r-- | application/front/controllers/TagCloudController.php | 89 | ||||
-rw-r--r-- | application/security/SessionManager.php | 10 | ||||
-rw-r--r-- | doc/md/Translations.md | 2 | ||||
-rw-r--r-- | index.php | 45 | ||||
-rw-r--r-- | tpl/default/page.header.html | 2 | ||||
-rw-r--r-- | tpl/default/tag.cloud.html | 2 | ||||
-rw-r--r-- | tpl/default/tag.sort.html | 2 | ||||
-rw-r--r-- | tpl/vintage/page.header.html | 2 |
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 | */ |
92 | function escape($input) | 92 | function 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 | |||
3 | declare(strict_types=1); | ||
4 | |||
5 | namespace Shaarli\Front\Controller; | ||
6 | |||
7 | use Slim\Http\Request; | ||
8 | use 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 | */ | ||
17 | class 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 | |||
44 | http://<replace_domain>/login | 44 | http://<replace_domain>/login |
45 | http://<replace_domain>/picture-wall | 45 | http://<replace_domain>/picture-wall |
46 | http://<replace_domain>/?do=pluginadmin | 46 | http://<replace_domain>/?do=pluginadmin |
47 | http://<replace_domain>/?do=tagcloud | 47 | http://<replace_domain>/tag-cloud |
48 | http://<replace_domain>/?do=taglist | 48 | http://<replace_domain>/?do=taglist |
49 | ``` | 49 | ``` |
50 | 50 | ||
@@ -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> · | 4 | <a href="./tag-cloud">{'Cloud'|t}</a> · |
5 | <a href="./?do=taglist&sort=usage">{'Most used'|t}</a> · | 5 | <a href="./?do=taglist&sort=usage">{'Most used'|t}</a> · |
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"} |