]> git.immae.eu Git - github/shaarli/Shaarli.git/commitdiff
Process remove tag endpoint through Slim controller
authorArthurHoaro <arthur@hoa.ro>
Wed, 20 May 2020 12:38:31 +0000 (14:38 +0200)
committerArthurHoaro <arthur@hoa.ro>
Thu, 23 Jul 2020 19:19:21 +0000 (21:19 +0200)
application/front/controllers/TagController.php
index.php
tests/front/controller/TagControllerTest.php
tpl/default/linklist.html
tpl/vintage/linklist.html

index 598275b04bf5384f1b9041b854bc8b7c0229dfd6..a1d5ad5b0150a176ed320b658953cdec5016425e 100644 (file)
@@ -35,7 +35,7 @@ class TagController extends ShaarliController
             return $response->withRedirect('./');
         }
 
-        $currentUrl = parse_url($this->container->environment['HTTP_REFERER']);
+        $currentUrl = parse_url($referer);
         parse_str($currentUrl['query'] ?? '', $params);
 
         if (null === $newTag) {
@@ -71,4 +71,50 @@ class TagController extends ShaarliController
 
         return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params));
     }
+
+    /**
+     * Remove a tag from the current search through an HTTP redirection.
+     *
+     * @param array $args Should contain `tag` key as tag to remove from current search
+     */
+    public function removeTag(Request $request, Response $response, array $args): Response
+    {
+        $referer = $this->container->environment['HTTP_REFERER'] ?? null;
+
+        // If the referrer is not provided, we can update the search, so we failback on the bookmark list
+        if (empty($referer)) {
+            return $response->withRedirect('./');
+        }
+
+        $tagToRemove = $args['tag'] ?? null;
+        $currentUrl = parse_url($referer);
+        parse_str($currentUrl['query'] ?? '', $params);
+
+        if (null === $tagToRemove) {
+            return $response->withRedirect(($currentUrl['path'] ?? './') .'?'. http_build_query($params));
+        }
+
+        // Prevent redirection loop
+        if (isset($params['removetag'])) {
+            unset($params['removetag']);
+        }
+
+        if (isset($params['searchtags'])) {
+            $tags = explode(' ', $params['searchtags']);
+            // Remove value from array $tags.
+            $tags = array_diff($tags, [$tagToRemove]);
+            $params['searchtags'] = implode(' ', $tags);
+
+            if (empty($params['searchtags'])) {
+                unset($params['searchtags']);
+            }
+
+            // We also remove page (keeping the same page has no sense, since the results are different)
+            unset($params['page']);
+        }
+
+        $queryParams = count($params) > 0 ? '?' . http_build_query($params) : '';
+
+        return $response->withRedirect(($currentUrl['path'] ?? './') . $queryParams);
+    }
 }
index 04ec0d731358d147eccec5860f9b34eceef4d39a..c0e0c66dcc90441a68ffe2dfc3641779ce912ce6 100644 (file)
--- a/index.php
+++ b/index.php
@@ -451,35 +451,7 @@ function renderPage($conf, $pluginManager, $bookmarkService, $history, $sessionM
 
     // -------- User clicks on a tag in result count: Remove the tag from the list of searched tags (searchtags=...)
     if (isset($_GET['removetag'])) {
-        // Get previous URL (http_referer) and remove the tag from the searchtags parameters in query.
-        if (empty($_SERVER['HTTP_REFERER'])) {
-            header('Location: ?');
-            exit;
-        }
-
-        // In case browser does not send HTTP_REFERER
-        parse_str(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_QUERY), $params);
-
-        // Prevent redirection loop
-        if (isset($params['removetag'])) {
-            unset($params['removetag']);
-        }
-
-        if (isset($params['searchtags'])) {
-            $tags = explode(' ', $params['searchtags']);
-            // Remove value from array $tags.
-            $tags = array_diff($tags, array($_GET['removetag']));
-            $params['searchtags'] = implode(' ', $tags);
-
-            if (empty($params['searchtags'])) {
-                unset($params['searchtags']);
-            }
-
-            // We also remove page (keeping the same page has no sense, since
-            // the results are different)
-            unset($params['page']);
-        }
-        header('Location: ?'.http_build_query($params));
+        header('Location: ./remove-tag/'. $_GET['removetag']);
         exit;
     }
 
@@ -1576,6 +1548,7 @@ $app->group('', function () {
     $this->get('/open-search', '\Shaarli\Front\Controller\OpenSearchController:index')->setName('opensearch');
 
     $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\TagController:addTag')->setName('add-tag');
+    $this->get('/remove-tag/{tag}', '\Shaarli\Front\Controller\TagController:removeTag')->setName('remove-tag');
 })->add('\Shaarli\Front\ShaarliMiddleware');
 
 $response = $app->run(true);
index 5eea537be0d50f8ebbc6606e4e54aed724b8e62c..2184cb11f9ba1bbd757e7b8b617c26de4f9d890e 100644 (file)
@@ -157,4 +157,86 @@ class TagControllerTest extends TestCase
         static::assertSame(302, $result->getStatusCode());
         static::assertSame(['./'], $result->getHeader('location'));
     }
+
+    public function testRemoveTagWithoutMatchingTag(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/controller/?searchtags=def'];
+
+        $request = $this->createMock(Request::class);
+        $response = new Response();
+
+        $tags = ['tag' => 'abc'];
+
+        $result = $this->controller->removeTag($request, $response, $tags);
+
+        static::assertInstanceOf(Response::class, $result);
+        static::assertSame(302, $result->getStatusCode());
+        static::assertSame(['/controller/?searchtags=def'], $result->getHeader('location'));
+    }
+
+    public function testRemoveTagWithoutTagsearch(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/controller/'];
+
+        $request = $this->createMock(Request::class);
+        $response = new Response();
+
+        $tags = ['tag' => 'abc'];
+
+        $result = $this->controller->removeTag($request, $response, $tags);
+
+        static::assertInstanceOf(Response::class, $result);
+        static::assertSame(302, $result->getStatusCode());
+        static::assertSame(['/controller/'], $result->getHeader('location'));
+    }
+
+    public function testRemoveTagWithoutReferer(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $request = $this->createMock(Request::class);
+        $response = new Response();
+
+        $tags = ['tag' => 'abc'];
+
+        $result = $this->controller->removeTag($request, $response, $tags);
+
+        static::assertInstanceOf(Response::class, $result);
+        static::assertSame(302, $result->getStatusCode());
+        static::assertSame(['./'], $result->getHeader('location'));
+    }
+
+    public function testRemoveTagWithoutTag(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/controller/?searchtag=abc'];
+
+        $request = $this->createMock(Request::class);
+        $response = new Response();
+
+        $result = $this->controller->removeTag($request, $response, []);
+
+        static::assertInstanceOf(Response::class, $result);
+        static::assertSame(302, $result->getStatusCode());
+        static::assertSame(['/controller/?searchtag=abc'], $result->getHeader('location'));
+    }
+
+    public function testRemoveTagWithoutTagWithoutReferer(): void
+    {
+        $this->createValidContainerMockSet();
+
+        $request = $this->createMock(Request::class);
+        $response = new Response();
+
+        $result = $this->controller->removeTag($request, $response, []);
+
+        static::assertInstanceOf(Response::class, $result);
+        static::assertSame(302, $result->getStatusCode());
+        static::assertSame(['./'], $result->getHeader('location'));
+    }
 }
index d8a15823892a57ae14be1c67f0502aa89daa31ff..e574a109678cc1d03b40c738f6ea8a7e776728e2 100644 (file)
@@ -94,7 +94,9 @@
           {'tagged'|t}
           {loop="$exploded_tags"}
               <span class="label label-tag" title="{'Remove tag'|t}">
-                <a href="?removetag={function="urlencode($value)"}" aria-label="{'Remove tag'|t}">{$value}<span class="remove"><i class="fa fa-times" aria-hidden="true"></i></span></a>
+                <a href="./remove-tag/{function="urlencode($value)"}" aria-label="{'Remove tag'|t}">
+                  {$value}<span class="remove"><i class="fa fa-times" aria-hidden="true"></i></span>
+                </a>
               </span>
           {/loop}
         {/if}
index 8f1ded95303b5204cef5954443fb58a3901d94cf..502abcf9e878003365fac33bce19f8b9021e7d63 100644 (file)
@@ -66,7 +66,7 @@
                 tagged
                 {loop="$exploded_tags"}
                     <span class="linktag" title="Remove tag">
-                        <a href="?removetag={function="urlencode($value)"}">{$value} <span class="remove">x</span></a>
+                        <a href="./remove-tag/{function="urlencode($value)"}">{$value} <span class="remove">x</span></a>
                     </span>
                 {/loop}
             {elseif="$search_tags === false"}