From c266a89d0fbb0d60d2d7df0ec171b7cb022224f6 Mon Sep 17 00:00:00 2001
From: ArthurHoaro <arthur@hoa.ro>
Date: Sun, 26 Jan 2020 14:35:25 +0100
Subject: Process tag cloud page through Slim controller

---
 application/Utils.php                              |  2 +-
 .../front/controllers/TagCloudController.php       | 89 ++++++++++++++++++++++
 application/security/SessionManager.php            | 10 +++
 3 files changed, 100 insertions(+), 1 deletion(-)
 create mode 100644 application/front/controllers/TagCloudController.php

(limited to 'application')

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)
  *
  * @param mixed $input Data to escape: a single string or an array of strings.
  *
- * @return string escaped.
+ * @return string|array escaped.
  */
 function escape($input)
 {
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 @@
+<?php
+
+declare(strict_types=1);
+
+namespace Shaarli\Front\Controller;
+
+use Slim\Http\Request;
+use Slim\Http\Response;
+
+/**
+ * Class TagCloud
+ *
+ * Slim controller used to render the tag cloud page.
+ *
+ * @package Front\Controller
+ */
+class TagCloudController extends ShaarliController
+{
+    public function index(Request $request, Response $response): Response
+    {
+        if ($this->container->loginManager->isLoggedIn() === true) {
+            $visibility = $this->container->sessionManager->getSessionParameter('visibility');
+        }
+
+        $searchTags = $request->getQueryParam('searchtags');
+        $filteringTags = $searchTags !== null ? explode(' ', $searchTags) : [];
+
+        $tags = $this->container->bookmarkService->bookmarksCountPerTag($filteringTags, $visibility ?? null);
+
+        // We sort tags alphabetically, then choose a font size according to count.
+        // First, find max value.
+        $maxCount = 0;
+        foreach ($tags as $count) {
+            $maxCount = max($maxCount, $count);
+        }
+
+        alphabetical_sort($tags, false, true);
+
+        $logMaxCount = $maxCount > 1 ? log($maxCount, 30) : 1;
+        $tagList = [];
+        foreach ($tags as $key => $value) {
+            if (in_array($key, $filteringTags)) {
+                continue;
+            }
+            // Tag font size scaling:
+            //   default 15 and 30 logarithm bases affect scaling,
+            //   2.2 and 0.8 are arbitrary font sizes in em.
+            $size = log($value, 15) / $logMaxCount * 2.2 + 0.8;
+            $tagList[$key] = [
+                'count' => $value,
+                'size' => number_format($size, 2, '.', ''),
+            ];
+        }
+
+        $searchTags = implode(' ', escape($filteringTags));
+        $data = [
+            'search_tags' => $searchTags,
+            'tags' => $tagList,
+        ];
+        $data = $this->executeHooks($data);
+        foreach ($data as $key => $value) {
+            $this->assignView($key, $value);
+        }
+
+        $searchTags = !empty($searchTags) ? $searchTags .' - ' : '';
+        $this->assignView(
+            'pagetitle',
+            $searchTags. t('Tag cloud') .' - '. $this->container->conf->get('general.title', 'Shaarli')
+        );
+
+        return $response->write($this->render('tag.cloud'));
+    }
+
+    /**
+     * @param mixed[] $data Template data
+     *
+     * @return mixed[] Template data after active plugins render_picwall hook execution.
+     */
+    protected function executeHooks(array $data): array
+    {
+        $this->container->pluginManager->executeHooks(
+            'render_tagcloud',
+            $data,
+            ['loggedin' => $this->container->loginManager->isLoggedIn()]
+        );
+
+        return $data;
+    }
+}
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
     {
         return $this->session;
     }
+
+    /**
+     * @param mixed $default value which will be returned if the $key is undefined
+     *
+     * @return mixed Content stored in session
+     */
+    public function getSessionParameter(string $key, $default = null)
+    {
+        return $this->session[$key] ?? $default;
+    }
 }
-- 
cgit v1.2.3