]> git.immae.eu Git - github/shaarli/Shaarli.git/blame - application/front/controllers/TagCloudController.php
Process session filters through Slim controllers
[github/shaarli/Shaarli.git] / application / front / controllers / TagCloudController.php
CommitLineData
c266a89d
A
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 *
60ae2412 13 * Slim controller used to render the tag cloud and tag list pages.
c266a89d
A
14 *
15 * @package Front\Controller
16 */
17class TagCloudController extends ShaarliController
18{
60ae2412
A
19 protected const TYPE_CLOUD = 'cloud';
20 protected const TYPE_LIST = 'list';
21
3772298e
A
22 /**
23 * Display the tag cloud through the template engine.
24 * This controller a few filters:
25 * - Visibility stored in the session for logged in users
26 * - `searchtags` query parameter: will return tags associated with filter in at least one bookmark
27 */
28 public function cloud(Request $request, Response $response): Response
60ae2412
A
29 {
30 return $this->processRequest(static::TYPE_CLOUD, $request, $response);
31 }
32
33 /**
34 * Display the tag list through the template engine.
35 * This controller a few filters:
36 * - Visibility stored in the session for logged in users
37 * - `searchtags` query parameter: will return tags associated with filter in at least one bookmark
38 * - `sort` query parameters:
39 * + `usage` (default): most used tags first
40 * + `alpha`: alphabetical order
41 */
42 public function list(Request $request, Response $response): Response
43 {
44 return $this->processRequest(static::TYPE_LIST, $request, $response);
45 }
46
47 /**
48 * Process the request for both tag cloud and tag list endpoints.
49 */
50 protected function processRequest(string $type, Request $request, Response $response): Response
c266a89d
A
51 {
52 if ($this->container->loginManager->isLoggedIn() === true) {
53 $visibility = $this->container->sessionManager->getSessionParameter('visibility');
54 }
55
60ae2412 56 $sort = $request->getQueryParam('sort');
c266a89d
A
57 $searchTags = $request->getQueryParam('searchtags');
58 $filteringTags = $searchTags !== null ? explode(' ', $searchTags) : [];
59
60 $tags = $this->container->bookmarkService->bookmarksCountPerTag($filteringTags, $visibility ?? null);
61
60ae2412
A
62 if (static::TYPE_CLOUD === $type || 'alpha' === $sort) {
63 // TODO: the sorting should be handled by bookmarkService instead of the controller
64 alphabetical_sort($tags, false, true);
65 }
c266a89d 66
60ae2412
A
67 if (static::TYPE_CLOUD === $type) {
68 $tags = $this->formatTagsForCloud($tags);
69 }
c266a89d
A
70
71 $searchTags = implode(' ', escape($filteringTags));
72 $data = [
73 'search_tags' => $searchTags,
60ae2412 74 'tags' => $tags,
c266a89d 75 ];
60ae2412 76 $data = $this->executeHooks('tag' . $type, $data);
c266a89d
A
77 foreach ($data as $key => $value) {
78 $this->assignView($key, $value);
79 }
80
81 $searchTags = !empty($searchTags) ? $searchTags .' - ' : '';
82 $this->assignView(
83 'pagetitle',
60ae2412 84 $searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli')
c266a89d
A
85 );
86
60ae2412 87 return $response->write($this->render('tag.'. $type));
c266a89d
A
88 }
89
60ae2412
A
90 /**
91 * Format the tags array for the tag cloud template.
92 *
93 * @param array<string, int> $tags List of tags as key with count as value
94 *
95 * @return mixed[] List of tags as key, with count and expected font size in a subarray
96 */
3772298e
A
97 protected function formatTagsForCloud(array $tags): array
98 {
99 // We sort tags alphabetically, then choose a font size according to count.
100 // First, find max value.
101 $maxCount = count($tags) > 0 ? max($tags) : 0;
102 $logMaxCount = $maxCount > 1 ? log($maxCount, 30) : 1;
103 $tagList = [];
104 foreach ($tags as $key => $value) {
105 // Tag font size scaling:
106 // default 15 and 30 logarithm bases affect scaling,
107 // 2.2 and 0.8 are arbitrary font sizes in em.
108 $size = log($value, 15) / $logMaxCount * 2.2 + 0.8;
109 $tagList[$key] = [
110 'count' => $value,
111 'size' => number_format($size, 2, '.', ''),
112 ];
113 }
114
115 return $tagList;
116 }
117
c266a89d
A
118 /**
119 * @param mixed[] $data Template data
120 *
60ae2412 121 * @return mixed[] Template data after active plugins hook execution.
c266a89d 122 */
60ae2412 123 protected function executeHooks(string $template, array $data): array
c266a89d
A
124 {
125 $this->container->pluginManager->executeHooks(
60ae2412 126 'render_'. $template,
c266a89d
A
127 $data,
128 ['loggedin' => $this->container->loginManager->isLoggedIn()]
129 );
130
131 return $data;
132 }
133}