]> git.immae.eu Git - github/shaarli/Shaarli.git/blob - application/front/controller/visitor/TagController.php
de4e7ea28861daabb8c742aeeddd7725930cb95f
[github/shaarli/Shaarli.git] / application / front / controller / visitor / TagController.php
1 <?php
2
3 declare(strict_types=1);
4
5 namespace Shaarli\Front\Controller\Visitor;
6
7 use Slim\Http\Request;
8 use Slim\Http\Response;
9
10 /**
11 * Class TagController
12 *
13 * Slim controller handle tags.
14 */
15 class TagController extends ShaarliVisitorController
16 {
17 /**
18 * Add another tag in the current search through an HTTP redirection.
19 *
20 * @param array $args Should contain `newTag` key as tag to add to current search
21 */
22 public function addTag(Request $request, Response $response, array $args): Response
23 {
24 $newTag = $args['newTag'] ?? null;
25 $referer = $this->container->environment['HTTP_REFERER'] ?? null;
26
27 // In case browser does not send HTTP_REFERER, we search a single tag
28 if (null === $referer) {
29 if (null !== $newTag) {
30 return $this->redirect($response, '/?searchtags='. urlencode($newTag));
31 }
32
33 return $this->redirect($response, '/');
34 }
35
36 $currentUrl = parse_url($referer);
37 parse_str($currentUrl['query'] ?? '', $params);
38
39 if (null === $newTag) {
40 return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params));
41 }
42
43 // Prevent redirection loop
44 if (isset($params['addtag'])) {
45 unset($params['addtag']);
46 }
47
48 // Check if this tag is already in the search query and ignore it if it is.
49 // Each tag is always separated by a space
50 $currentTags = isset($params['searchtags']) ? explode(' ', $params['searchtags']) : [];
51
52 $addtag = true;
53 foreach ($currentTags as $value) {
54 if ($value === $newTag) {
55 $addtag = false;
56 break;
57 }
58 }
59
60 // Append the tag if necessary
61 if (true === $addtag) {
62 $currentTags[] = trim($newTag);
63 }
64
65 $params['searchtags'] = trim(implode(' ', $currentTags));
66
67 // We also remove page (keeping the same page has no sense, since the results are different)
68 unset($params['page']);
69
70 return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params));
71 }
72
73 /**
74 * Remove a tag from the current search through an HTTP redirection.
75 *
76 * @param array $args Should contain `tag` key as tag to remove from current search
77 */
78 public function removeTag(Request $request, Response $response, array $args): Response
79 {
80 $referer = $this->container->environment['HTTP_REFERER'] ?? null;
81
82 // If the referrer is not provided, we can update the search, so we failback on the bookmark list
83 if (empty($referer)) {
84 return $this->redirect($response, '/');
85 }
86
87 $tagToRemove = $args['tag'] ?? null;
88 $currentUrl = parse_url($referer);
89 parse_str($currentUrl['query'] ?? '', $params);
90
91 if (null === $tagToRemove) {
92 return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params));
93 }
94
95 // Prevent redirection loop
96 if (isset($params['removetag'])) {
97 unset($params['removetag']);
98 }
99
100 if (isset($params['searchtags'])) {
101 $tags = explode(' ', $params['searchtags']);
102 // Remove value from array $tags.
103 $tags = array_diff($tags, [$tagToRemove]);
104 $params['searchtags'] = implode(' ', $tags);
105
106 if (empty($params['searchtags'])) {
107 unset($params['searchtags']);
108 }
109
110 // We also remove page (keeping the same page has no sense, since the results are different)
111 unset($params['page']);
112 }
113
114 $queryParams = count($params) > 0 ? '?' . http_build_query($params) : '';
115
116 return $response->withRedirect(($currentUrl['path'] ?? './') . $queryParams);
117 }
118 }