]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - application/front/controllers/TagCloudController.php
93e3ae27c46ff2b423c1250f3b5b2fc2faa73346
[github/shaarli/Shaarli.git] / application / front / controllers / TagCloudController.php
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 /**
20 * Display the tag cloud through the template engine.
21 * This controller a few filters:
22 * - Visibility stored in the session for logged in users
23 * - `searchtags` query parameter: will return tags associated with filter in at least one bookmark
24 */
25 public function cloud(Request $request, Response $response): Response
26 {
27 if ($this->container->loginManager->isLoggedIn() === true) {
28 $visibility = $this->container->sessionManager->getSessionParameter('visibility');
29 }
30
31 $searchTags = $request->getQueryParam('searchtags');
32 $filteringTags = $searchTags !== null ? explode(' ', $searchTags) : [];
33
34 $tags = $this->container->bookmarkService->bookmarksCountPerTag($filteringTags, $visibility ?? null);
35
36 // TODO: the sorting should be handled by bookmarkService instead of the controller
37 alphabetical_sort($tags, false, true);
38
39 $tagList = $this->formatTagsForCloud($tags);
40
41 $searchTags = implode(' ', escape($filteringTags));
42 $data = [
43 'search_tags' => $searchTags,
44 'tags' => $tagList,
45 ];
46 $data = $this->executeHooks($data);
47 foreach ($data as $key => $value) {
48 $this->assignView($key, $value);
49 }
50
51 $searchTags = !empty($searchTags) ? $searchTags .' - ' : '';
52 $this->assignView(
53 'pagetitle',
54 $searchTags . t('Tag cloud') .' - '. $this->container->conf->get('general.title', 'Shaarli')
55 );
56
57 return $response->write($this->render('tag.cloud'));
58 }
59
60 protected function formatTagsForCloud(array $tags): array
61 {
62 // We sort tags alphabetically, then choose a font size according to count.
63 // First, find max value.
64 $maxCount = count($tags) > 0 ? max($tags) : 0;
65 $logMaxCount = $maxCount > 1 ? log($maxCount, 30) : 1;
66 $tagList = [];
67 foreach ($tags as $key => $value) {
68 // Tag font size scaling:
69 // default 15 and 30 logarithm bases affect scaling,
70 // 2.2 and 0.8 are arbitrary font sizes in em.
71 $size = log($value, 15) / $logMaxCount * 2.2 + 0.8;
72 $tagList[$key] = [
73 'count' => $value,
74 'size' => number_format($size, 2, '.', ''),
75 ];
76 }
77
78 return $tagList;
79 }
80
81 /**
82 * @param mixed[] $data Template data
83 *
84 * @return mixed[] Template data after active plugins render_picwall hook execution.
85 */
86 protected function executeHooks(array $data): array
87 {
88 $this->container->pluginManager->executeHooks(
89 'render_tagcloud',
90 $data,
91 ['loggedin' => $this->container->loginManager->isLoggedIn()]
92 );
93
94 return $data;
95 }
96 }