return $response->withRedirect('./');
}
- $currentUrl = parse_url($this->container->environment['HTTP_REFERER']);
+ $currentUrl = parse_url($referer);
parse_str($currentUrl['query'] ?? '', $params);
if (null === $newTag) {
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);
+ }
}
// -------- 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;
}
$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);
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'));
+ }
}
{'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}
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"}