]> git.immae.eu Git - github/shaarli/Shaarli.git/blobdiff - application/front/controllers/TagCloudController.php
Process session filters through Slim controllers
[github/shaarli/Shaarli.git] / application / front / controllers / TagCloudController.php
index 9389c2b03ad3ea783a1171190cbbac45869d4f39..1ff7c2e696792d4442388900a5eac0aeadf3a5b0 100644 (file)
@@ -10,51 +10,70 @@ use Slim\Http\Response;
 /**
  * Class TagCloud
  *
- * Slim controller used to render the tag cloud page.
+ * Slim controller used to render the tag cloud and tag list pages.
  *
  * @package Front\Controller
  */
 class TagCloudController extends ShaarliController
 {
-    public function index(Request $request, Response $response): Response
+    protected const TYPE_CLOUD = 'cloud';
+    protected const TYPE_LIST = 'list';
+
+    /**
+     * Display the tag cloud through the template engine.
+     * This controller a few filters:
+     *   - Visibility stored in the session for logged in users
+     *   - `searchtags` query parameter: will return tags associated with filter in at least one bookmark
+     */
+    public function cloud(Request $request, Response $response): Response
+    {
+        return $this->processRequest(static::TYPE_CLOUD, $request, $response);
+    }
+
+    /**
+     * Display the tag list through the template engine.
+     * This controller a few filters:
+     *   - Visibility stored in the session for logged in users
+     *   - `searchtags` query parameter: will return tags associated with filter in at least one bookmark
+     *   - `sort` query parameters:
+     *       + `usage` (default): most used tags first
+     *       + `alpha`: alphabetical order
+     */
+    public function list(Request $request, Response $response): Response
+    {
+        return $this->processRequest(static::TYPE_LIST, $request, $response);
+    }
+
+    /**
+     * Process the request for both tag cloud and tag list endpoints.
+     */
+    protected function processRequest(string $type, Request $request, Response $response): Response
     {
         if ($this->container->loginManager->isLoggedIn() === true) {
             $visibility = $this->container->sessionManager->getSessionParameter('visibility');
         }
 
+        $sort = $request->getQueryParam('sort');
         $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);
+        if (static::TYPE_CLOUD === $type || 'alpha' === $sort) {
+            // TODO: the sorting should be handled by bookmarkService instead of the controller
+            alphabetical_sort($tags, false, true);
         }
 
-        alphabetical_sort($tags, false, true);
-
-        $logMaxCount = $maxCount > 1 ? log($maxCount, 30) : 1;
-        $tagList = [];
-        foreach ($tags as $key => $value) {
-            // 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, '.', ''),
-            ];
+        if (static::TYPE_CLOUD === $type) {
+            $tags = $this->formatTagsForCloud($tags);
         }
 
         $searchTags = implode(' ', escape($filteringTags));
         $data = [
             'search_tags' => $searchTags,
-            'tags' => $tagList,
+            'tags' => $tags,
         ];
-        $data = $this->executeHooks($data);
+        $data = $this->executeHooks('tag' . $type, $data);
         foreach ($data as $key => $value) {
             $this->assignView($key, $value);
         }
@@ -62,21 +81,49 @@ class TagCloudController extends ShaarliController
         $searchTags = !empty($searchTags) ? $searchTags .' - ' : '';
         $this->assignView(
             'pagetitle',
-            $searchTags. t('Tag cloud') .' - '. $this->container->conf->get('general.title', 'Shaarli')
+            $searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli')
         );
 
-        return $response->write($this->render('tag.cloud'));
+        return $response->write($this->render('tag.'. $type));
+    }
+
+    /**
+     * Format the tags array for the tag cloud template.
+     *
+     * @param array<string, int> $tags List of tags as key with count as value
+     *
+     * @return mixed[] List of tags as key, with count and expected font size in a subarray
+     */
+    protected function formatTagsForCloud(array $tags): array
+    {
+        // We sort tags alphabetically, then choose a font size according to count.
+        // First, find max value.
+        $maxCount = count($tags) > 0 ? max($tags) : 0;
+        $logMaxCount = $maxCount > 1 ? log($maxCount, 30) : 1;
+        $tagList = [];
+        foreach ($tags as $key => $value) {
+            // 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, '.', ''),
+            ];
+        }
+
+        return $tagList;
     }
 
     /**
      * @param mixed[] $data Template data
      *
-     * @return mixed[] Template data after active plugins render_picwall hook execution.
+     * @return mixed[] Template data after active plugins hook execution.
      */
-    protected function executeHooks(array $data): array
+    protected function executeHooks(string $template, array $data): array
     {
         $this->container->pluginManager->executeHooks(
-            'render_tagcloud',
+            'render_'. $template,
             $data,
             ['loggedin' => $this->container->loginManager->isLoggedIn()]
         );