From 2899ebb5b5e82890c877151f5c02045266ac9973 Mon Sep 17 00:00:00 2001 From: ArthurHoaro Date: Fri, 22 May 2020 13:20:31 +0200 Subject: Initialize admin Slim controllers - Reorganize visitor controllers - Fix redirection with Slim's requests base path - Fix daily links --- .../controller/visitor/TagCloudController.php | 131 +++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 application/front/controller/visitor/TagCloudController.php (limited to 'application/front/controller/visitor/TagCloudController.php') diff --git a/application/front/controller/visitor/TagCloudController.php b/application/front/controller/visitor/TagCloudController.php new file mode 100644 index 00000000..15b6d7b7 --- /dev/null +++ b/application/front/controller/visitor/TagCloudController.php @@ -0,0 +1,131 @@ +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); + + if (static::TYPE_CLOUD === $type || 'alpha' === $sort) { + // TODO: the sorting should be handled by bookmarkService instead of the controller + alphabetical_sort($tags, false, true); + } + + if (static::TYPE_CLOUD === $type) { + $tags = $this->formatTagsForCloud($tags); + } + + $searchTags = implode(' ', escape($filteringTags)); + $data = [ + 'search_tags' => $searchTags, + 'tags' => $tags, + ]; + $data = $this->executeHooks('tag' . $type, $data); + foreach ($data as $key => $value) { + $this->assignView($key, $value); + } + + $searchTags = !empty($searchTags) ? $searchTags .' - ' : ''; + $this->assignView( + 'pagetitle', + $searchTags . t('Tag '. $type) .' - '. $this->container->conf->get('general.title', 'Shaarli') + ); + + return $response->write($this->render('tag.'. $type)); + } + + /** + * Format the tags array for the tag cloud template. + * + * @param array $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 hook execution. + */ + protected function executeHooks(string $template, array $data): array + { + $this->container->pluginManager->executeHooks( + 'render_'. $template, + $data, + ['loggedin' => $this->container->loginManager->isLoggedIn()] + ); + + return $data; + } +} -- cgit v1.2.3