aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--application/front/ShaarliMiddleware.php7
-rw-r--r--application/front/controller/admin/LogoutController.php (renamed from application/front/controllers/LogoutController.php)6
-rw-r--r--application/front/controller/admin/SessionFilterController.php (renamed from application/front/controllers/SessionFilterController.php)14
-rw-r--r--application/front/controller/admin/ShaarliAdminController.php21
-rw-r--r--application/front/controller/visitor/DailyController.php (renamed from application/front/controllers/DailyController.php)6
-rw-r--r--application/front/controller/visitor/FeedController.php (renamed from application/front/controllers/FeedController.php)6
-rw-r--r--application/front/controller/visitor/LoginController.php (renamed from application/front/controllers/LoginController.php)6
-rw-r--r--application/front/controller/visitor/OpenSearchController.php (renamed from application/front/controllers/OpenSearchController.php)6
-rw-r--r--application/front/controller/visitor/PictureWallController.php (renamed from application/front/controllers/PictureWallController.php)6
-rw-r--r--application/front/controller/visitor/ShaarliVisitorController.php (renamed from application/front/controllers/ShaarliController.php)15
-rw-r--r--application/front/controller/visitor/TagCloudController.php (renamed from application/front/controllers/TagCloudController.php)6
-rw-r--r--application/front/controller/visitor/TagController.php (renamed from application/front/controllers/TagController.php)6
-rw-r--r--application/front/exceptions/LoginBannedException.php2
-rw-r--r--application/front/exceptions/ShaarliFrontException.php (renamed from application/front/exceptions/ShaarliException.php)2
-rw-r--r--application/front/exceptions/ThumbnailsDisabledException.php2
-rw-r--r--application/front/exceptions/UnauthorizedException.php15
-rw-r--r--composer.json3
-rw-r--r--doc/md/Translations.md2
-rw-r--r--index.php35
-rw-r--r--tests/bootstrap.php3
-rw-r--r--tests/front/controller/admin/FrontAdminControllerMockHelper.php34
-rw-r--r--tests/front/controller/admin/LogoutControllerTest.php (renamed from tests/front/controller/LogoutControllerTest.php)4
-rw-r--r--tests/front/controller/admin/SessionFilterControllerTest.php (renamed from tests/front/controller/SessionFilterControllerTest.php)66
-rw-r--r--tests/front/controller/visitor/DailyControllerTest.php (renamed from tests/front/controller/DailyControllerTest.php)2
-rw-r--r--tests/front/controller/visitor/FeedControllerTest.php (renamed from tests/front/controller/FeedControllerTest.php)2
-rw-r--r--tests/front/controller/visitor/FrontControllerMockHelper.php (renamed from tests/front/controller/FrontControllerMockHelper.php)2
-rw-r--r--tests/front/controller/visitor/LoginControllerTest.php (renamed from tests/front/controller/LoginControllerTest.php)2
-rw-r--r--tests/front/controller/visitor/OpenSearchControllerTest.php (renamed from tests/front/controller/OpenSearchControllerTest.php)4
-rw-r--r--tests/front/controller/visitor/PictureWallControllerTest.php (renamed from tests/front/controller/PictureWallControllerTest.php)2
-rw-r--r--tests/front/controller/visitor/ShaarliPublicControllerTest.php (renamed from tests/front/controller/ShaarliControllerTest.php)42
-rw-r--r--tests/front/controller/visitor/TagCloudControllerTest.php (renamed from tests/front/controller/TagCloudControllerTest.php)2
-rw-r--r--tests/front/controller/visitor/TagControllerTest.php (renamed from tests/front/controller/TagControllerTest.php)5
-rw-r--r--tpl/default/page.header.html2
-rw-r--r--tpl/vintage/daily.html4
-rw-r--r--tpl/vintage/page.header.html2
35 files changed, 239 insertions, 105 deletions
diff --git a/application/front/ShaarliMiddleware.php b/application/front/ShaarliMiddleware.php
index fa6c6467..f8992e0b 100644
--- a/application/front/ShaarliMiddleware.php
+++ b/application/front/ShaarliMiddleware.php
@@ -3,7 +3,8 @@
3namespace Shaarli\Front; 3namespace Shaarli\Front;
4 4
5use Shaarli\Container\ShaarliContainer; 5use Shaarli\Container\ShaarliContainer;
6use Shaarli\Front\Exception\ShaarliException; 6use Shaarli\Front\Exception\ShaarliFrontException;
7use Shaarli\Front\Exception\UnauthorizedException;
7use Slim\Http\Request; 8use Slim\Http\Request;
8use Slim\Http\Response; 9use Slim\Http\Response;
9 10
@@ -39,7 +40,7 @@ class ShaarliMiddleware
39 { 40 {
40 try { 41 try {
41 $response = $next($request, $response); 42 $response = $next($request, $response);
42 } catch (ShaarliException $e) { 43 } catch (ShaarliFrontException $e) {
43 $this->container->pageBuilder->assign('message', $e->getMessage()); 44 $this->container->pageBuilder->assign('message', $e->getMessage());
44 if ($this->container->conf->get('dev.debug', false)) { 45 if ($this->container->conf->get('dev.debug', false)) {
45 $this->container->pageBuilder->assign( 46 $this->container->pageBuilder->assign(
@@ -50,6 +51,8 @@ class ShaarliMiddleware
50 51
51 $response = $response->withStatus($e->getCode()); 52 $response = $response->withStatus($e->getCode());
52 $response = $response->write($this->container->pageBuilder->render('error')); 53 $response = $response->write($this->container->pageBuilder->render('error'));
54 } catch (UnauthorizedException $e) {
55 return $response->withRedirect($request->getUri()->getBasePath() . '/login');
53 } 56 }
54 57
55 return $response; 58 return $response;
diff --git a/application/front/controllers/LogoutController.php b/application/front/controller/admin/LogoutController.php
index aba078c3..41e81984 100644
--- a/application/front/controllers/LogoutController.php
+++ b/application/front/controller/admin/LogoutController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Admin;
6 6
7use Shaarli\Security\LoginManager; 7use Shaarli\Security\LoginManager;
8use Slim\Http\Request; 8use Slim\Http\Request;
@@ -13,10 +13,8 @@ use Slim\Http\Response;
13 * 13 *
14 * Slim controller used to logout the user. 14 * Slim controller used to logout the user.
15 * It invalidates page cache and terminate the user session. Then it redirects to the homepage. 15 * It invalidates page cache and terminate the user session. Then it redirects to the homepage.
16 *
17 * @package Front\Controller
18 */ 16 */
19class LogoutController extends ShaarliController 17class LogoutController extends ShaarliAdminController
20{ 18{
21 public function index(Request $request, Response $response): Response 19 public function index(Request $request, Response $response): Response
22 { 20 {
diff --git a/application/front/controllers/SessionFilterController.php b/application/front/controller/admin/SessionFilterController.php
index a021dc37..69a16ec3 100644
--- a/application/front/controllers/SessionFilterController.php
+++ b/application/front/controller/admin/SessionFilterController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Admin;
6 6
7use Shaarli\Bookmark\BookmarkFilter; 7use Shaarli\Bookmark\BookmarkFilter;
8use Shaarli\Security\SessionManager; 8use Shaarli\Security\SessionManager;
@@ -13,10 +13,8 @@ use Slim\Http\Response;
13 * Class SessionFilterController 13 * Class SessionFilterController
14 * 14 *
15 * Slim controller used to handle filters stored in the user session, such as visibility, links per page, etc. 15 * Slim controller used to handle filters stored in the user session, such as visibility, links per page, etc.
16 *
17 * @package Shaarli\Front\Controller
18 */ 16 */
19class SessionFilterController extends ShaarliController 17class SessionFilterController extends ShaarliAdminController
20{ 18{
21 /** 19 /**
22 * GET /links-per-page: set the number of bookmarks to display per page in homepage 20 * GET /links-per-page: set the number of bookmarks to display per page in homepage
@@ -33,7 +31,7 @@ class SessionFilterController extends ShaarliController
33 abs(intval($linksPerPage)) 31 abs(intval($linksPerPage))
34 ); 32 );
35 33
36 return $this->redirectFromReferer($response, ['linksperpage'], ['nb']); 34 return $this->redirectFromReferer($request, $response, ['linksperpage'], ['nb']);
37 } 35 }
38 36
39 /** 37 /**
@@ -42,7 +40,7 @@ class SessionFilterController extends ShaarliController
42 public function visibility(Request $request, Response $response, array $args): Response 40 public function visibility(Request $request, Response $response, array $args): Response
43 { 41 {
44 if (false === $this->container->loginManager->isLoggedIn()) { 42 if (false === $this->container->loginManager->isLoggedIn()) {
45 return $this->redirectFromReferer($response, ['visibility']); 43 return $this->redirectFromReferer($request, $response, ['visibility']);
46 } 44 }
47 45
48 $newVisibility = $args['visibility'] ?? null; 46 $newVisibility = $args['visibility'] ?? null;
@@ -63,7 +61,7 @@ class SessionFilterController extends ShaarliController
63 $this->container->sessionManager->deleteSessionParameter(SessionManager::KEY_VISIBILITY); 61 $this->container->sessionManager->deleteSessionParameter(SessionManager::KEY_VISIBILITY);
64 } 62 }
65 63
66 return $this->redirectFromReferer($response, ['visibility']); 64 return $this->redirectFromReferer($request, $response, ['visibility']);
67 } 65 }
68 66
69 /** 67 /**
@@ -76,6 +74,6 @@ class SessionFilterController extends ShaarliController
76 empty($this->container->sessionManager->getSessionParameter(SessionManager::KEY_UNTAGGED_ONLY)) 74 empty($this->container->sessionManager->getSessionParameter(SessionManager::KEY_UNTAGGED_ONLY))
77 ); 75 );
78 76
79 return $this->redirectFromReferer($response, ['untaggedonly', 'untagged-only']); 77 return $this->redirectFromReferer($request, $response, ['untaggedonly', 'untagged-only']);
80 } 78 }
81} 79}
diff --git a/application/front/controller/admin/ShaarliAdminController.php b/application/front/controller/admin/ShaarliAdminController.php
new file mode 100644
index 00000000..ea703f62
--- /dev/null
+++ b/application/front/controller/admin/ShaarliAdminController.php
@@ -0,0 +1,21 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller\Admin;
6
7use Shaarli\Container\ShaarliContainer;
8use Shaarli\Front\Controller\Visitor\ShaarliVisitorController;
9use Shaarli\Front\Exception\UnauthorizedException;
10
11abstract class ShaarliAdminController extends ShaarliVisitorController
12{
13 public function __construct(ShaarliContainer $container)
14 {
15 parent::__construct($container);
16
17 if (true !== $this->container->loginManager->isLoggedIn()) {
18 throw new UnauthorizedException();
19 }
20 }
21}
diff --git a/application/front/controllers/DailyController.php b/application/front/controller/visitor/DailyController.php
index 4a0735aa..47e2503a 100644
--- a/application/front/controllers/DailyController.php
+++ b/application/front/controller/visitor/DailyController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use DateTime; 7use DateTime;
8use DateTimeImmutable; 8use DateTimeImmutable;
@@ -14,10 +14,8 @@ use Slim\Http\Response;
14 * Class DailyController 14 * Class DailyController
15 * 15 *
16 * Slim controller used to render the daily page. 16 * Slim controller used to render the daily page.
17 *
18 * @package Front\Controller
19 */ 17 */
20class DailyController extends ShaarliController 18class DailyController extends ShaarliVisitorController
21{ 19{
22 public static $DAILY_RSS_NB_DAYS = 8; 20 public static $DAILY_RSS_NB_DAYS = 8;
23 21
diff --git a/application/front/controllers/FeedController.php b/application/front/controller/visitor/FeedController.php
index 78d826d9..70664635 100644
--- a/application/front/controllers/FeedController.php
+++ b/application/front/controller/visitor/FeedController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Shaarli\Feed\FeedBuilder; 7use Shaarli\Feed\FeedBuilder;
8use Slim\Http\Request; 8use Slim\Http\Request;
@@ -12,10 +12,8 @@ use Slim\Http\Response;
12 * Class FeedController 12 * Class FeedController
13 * 13 *
14 * Slim controller handling ATOM and RSS feed. 14 * Slim controller handling ATOM and RSS feed.
15 *
16 * @package Front\Controller
17 */ 15 */
18class FeedController extends ShaarliController 16class FeedController extends ShaarliVisitorController
19{ 17{
20 public function atom(Request $request, Response $response): Response 18 public function atom(Request $request, Response $response): Response
21 { 19 {
diff --git a/application/front/controllers/LoginController.php b/application/front/controller/visitor/LoginController.php
index ae3599e0..4de2f55d 100644
--- a/application/front/controllers/LoginController.php
+++ b/application/front/controller/visitor/LoginController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Shaarli\Front\Exception\LoginBannedException; 7use Shaarli\Front\Exception\LoginBannedException;
8use Slim\Http\Request; 8use Slim\Http\Request;
@@ -15,10 +15,8 @@ use Slim\Http\Response;
15 * 15 *
16 * The login page is not available if the user is banned 16 * The login page is not available if the user is banned
17 * or if open shaarli setting is enabled. 17 * or if open shaarli setting is enabled.
18 *
19 * @package Front\Controller
20 */ 18 */
21class LoginController extends ShaarliController 19class LoginController extends ShaarliVisitorController
22{ 20{
23 public function index(Request $request, Response $response): Response 21 public function index(Request $request, Response $response): Response
24 { 22 {
diff --git a/application/front/controllers/OpenSearchController.php b/application/front/controller/visitor/OpenSearchController.php
index fa32c5f1..0fd68db6 100644
--- a/application/front/controllers/OpenSearchController.php
+++ b/application/front/controller/visitor/OpenSearchController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Slim\Http\Request; 7use Slim\Http\Request;
8use Slim\Http\Response; 8use Slim\Http\Response;
@@ -12,10 +12,8 @@ use Slim\Http\Response;
12 * 12 *
13 * Slim controller used to render open search template. 13 * Slim controller used to render open search template.
14 * This allows to add Shaarli as a search engine within the browser. 14 * This allows to add Shaarli as a search engine within the browser.
15 *
16 * @package front\controllers
17 */ 15 */
18class OpenSearchController extends ShaarliController 16class OpenSearchController extends ShaarliVisitorController
19{ 17{
20 public function index(Request $request, Response $response): Response 18 public function index(Request $request, Response $response): Response
21 { 19 {
diff --git a/application/front/controllers/PictureWallController.php b/application/front/controller/visitor/PictureWallController.php
index 08d31b29..4e1dce8c 100644
--- a/application/front/controllers/PictureWallController.php
+++ b/application/front/controller/visitor/PictureWallController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Shaarli\Front\Exception\ThumbnailsDisabledException; 7use Shaarli\Front\Exception\ThumbnailsDisabledException;
8use Shaarli\Thumbnailer; 8use Shaarli\Thumbnailer;
@@ -14,10 +14,8 @@ use Slim\Http\Response;
14 * 14 *
15 * Slim controller used to render the pictures wall page. 15 * Slim controller used to render the pictures wall page.
16 * If thumbnails mode is set to NONE, we just render the template without any image. 16 * If thumbnails mode is set to NONE, we just render the template without any image.
17 *
18 * @package Front\Controller
19 */ 17 */
20class PictureWallController extends ShaarliController 18class PictureWallController extends ShaarliVisitorController
21{ 19{
22 public function index(Request $request, Response $response): Response 20 public function index(Request $request, Response $response): Response
23 { 21 {
diff --git a/application/front/controllers/ShaarliController.php b/application/front/controller/visitor/ShaarliVisitorController.php
index bfff5fcf..655b3baa 100644
--- a/application/front/controllers/ShaarliController.php
+++ b/application/front/controller/visitor/ShaarliVisitorController.php
@@ -2,13 +2,14 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Shaarli\Bookmark\BookmarkFilter; 7use Shaarli\Bookmark\BookmarkFilter;
8use Shaarli\Container\ShaarliContainer; 8use Shaarli\Container\ShaarliContainer;
9use Slim\Http\Request;
9use Slim\Http\Response; 10use Slim\Http\Response;
10 11
11abstract class ShaarliController 12abstract class ShaarliVisitorController
12{ 13{
13 /** @var ShaarliContainer */ 14 /** @var ShaarliContainer */
14 protected $container; 15 protected $container;
@@ -89,9 +90,13 @@ abstract class ShaarliController
89 * @param array $loopTerms Terms to remove from path and query string to prevent direction loop. 90 * @param array $loopTerms Terms to remove from path and query string to prevent direction loop.
90 * @param array $clearParams List of parameter to remove from the query string of the referrer. 91 * @param array $clearParams List of parameter to remove from the query string of the referrer.
91 */ 92 */
92 protected function redirectFromReferer(Response $response, array $loopTerms = [], array $clearParams = []): Response 93 protected function redirectFromReferer(
93 { 94 Request $request,
94 $defaultPath = './'; 95 Response $response,
96 array $loopTerms = [],
97 array $clearParams = []
98 ): Response {
99 $defaultPath = $request->getUri()->getBasePath();
95 $referer = $this->container->environment['HTTP_REFERER'] ?? null; 100 $referer = $this->container->environment['HTTP_REFERER'] ?? null;
96 101
97 if (null !== $referer) { 102 if (null !== $referer) {
diff --git a/application/front/controllers/TagCloudController.php b/application/front/controller/visitor/TagCloudController.php
index 1ff7c2e6..15b6d7b7 100644
--- a/application/front/controllers/TagCloudController.php
+++ b/application/front/controller/visitor/TagCloudController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Slim\Http\Request; 7use Slim\Http\Request;
8use Slim\Http\Response; 8use Slim\Http\Response;
@@ -11,10 +11,8 @@ use Slim\Http\Response;
11 * Class TagCloud 11 * Class TagCloud
12 * 12 *
13 * Slim controller used to render the tag cloud and tag list pages. 13 * Slim controller used to render the tag cloud and tag list pages.
14 *
15 * @package Front\Controller
16 */ 14 */
17class TagCloudController extends ShaarliController 15class TagCloudController extends ShaarliVisitorController
18{ 16{
19 protected const TYPE_CLOUD = 'cloud'; 17 protected const TYPE_CLOUD = 'cloud';
20 protected const TYPE_LIST = 'list'; 18 protected const TYPE_LIST = 'list';
diff --git a/application/front/controllers/TagController.php b/application/front/controller/visitor/TagController.php
index a1d5ad5b..a0bc1d1b 100644
--- a/application/front/controllers/TagController.php
+++ b/application/front/controller/visitor/TagController.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use Slim\Http\Request; 7use Slim\Http\Request;
8use Slim\Http\Response; 8use Slim\Http\Response;
@@ -11,10 +11,8 @@ use Slim\Http\Response;
11 * Class TagController 11 * Class TagController
12 * 12 *
13 * Slim controller handle tags. 13 * Slim controller handle tags.
14 *
15 * @package Front\Controller
16 */ 14 */
17class TagController extends ShaarliController 15class TagController extends ShaarliVisitorController
18{ 16{
19 /** 17 /**
20 * Add another tag in the current search through an HTTP redirection. 18 * Add another tag in the current search through an HTTP redirection.
diff --git a/application/front/exceptions/LoginBannedException.php b/application/front/exceptions/LoginBannedException.php
index b31a4a14..79d0ea15 100644
--- a/application/front/exceptions/LoginBannedException.php
+++ b/application/front/exceptions/LoginBannedException.php
@@ -4,7 +4,7 @@ declare(strict_types=1);
4 4
5namespace Shaarli\Front\Exception; 5namespace Shaarli\Front\Exception;
6 6
7class LoginBannedException extends ShaarliException 7class LoginBannedException extends ShaarliFrontException
8{ 8{
9 public function __construct() 9 public function __construct()
10 { 10 {
diff --git a/application/front/exceptions/ShaarliException.php b/application/front/exceptions/ShaarliFrontException.php
index 800bfbec..fc8eb92b 100644
--- a/application/front/exceptions/ShaarliException.php
+++ b/application/front/exceptions/ShaarliFrontException.php
@@ -13,7 +13,7 @@ use Throwable;
13 * 13 *
14 * @package Front\Exception 14 * @package Front\Exception
15 */ 15 */
16abstract class ShaarliException extends \Exception 16abstract class ShaarliFrontException extends \Exception
17{ 17{
18 /** Override parent constructor to force $message and $httpCode parameters to be set. */ 18 /** Override parent constructor to force $message and $httpCode parameters to be set. */
19 public function __construct(string $message, int $httpCode, Throwable $previous = null) 19 public function __construct(string $message, int $httpCode, Throwable $previous = null)
diff --git a/application/front/exceptions/ThumbnailsDisabledException.php b/application/front/exceptions/ThumbnailsDisabledException.php
index 1b9cf5b7..0ed337f5 100644
--- a/application/front/exceptions/ThumbnailsDisabledException.php
+++ b/application/front/exceptions/ThumbnailsDisabledException.php
@@ -4,7 +4,7 @@ declare(strict_types=1);
4 4
5namespace Shaarli\Front\Exception; 5namespace Shaarli\Front\Exception;
6 6
7class ThumbnailsDisabledException extends ShaarliException 7class ThumbnailsDisabledException extends ShaarliFrontException
8{ 8{
9 public function __construct() 9 public function __construct()
10 { 10 {
diff --git a/application/front/exceptions/UnauthorizedException.php b/application/front/exceptions/UnauthorizedException.php
new file mode 100644
index 00000000..4231094a
--- /dev/null
+++ b/application/front/exceptions/UnauthorizedException.php
@@ -0,0 +1,15 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Front\Exception;
6
7/**
8 * Class UnauthorizedException
9 *
10 * Exception raised if the user tries to access a ShaarliAdminController while logged out.
11 */
12class UnauthorizedException extends \Exception
13{
14
15}
diff --git a/composer.json b/composer.json
index 6b670fa2..738d9f58 100644
--- a/composer.json
+++ b/composer.json
@@ -53,7 +53,8 @@
53 "Shaarli\\Feed\\": "application/feed", 53 "Shaarli\\Feed\\": "application/feed",
54 "Shaarli\\Formatter\\": "application/formatter", 54 "Shaarli\\Formatter\\": "application/formatter",
55 "Shaarli\\Front\\": "application/front", 55 "Shaarli\\Front\\": "application/front",
56 "Shaarli\\Front\\Controller\\": "application/front/controllers", 56 "Shaarli\\Front\\Controller\\Admin\\": "application/front/controller/admin",
57 "Shaarli\\Front\\Controller\\Visitor\\": "application/front/controller/visitor",
57 "Shaarli\\Front\\Exception\\": "application/front/exceptions", 58 "Shaarli\\Front\\Exception\\": "application/front/exceptions",
58 "Shaarli\\Http\\": "application/http", 59 "Shaarli\\Http\\": "application/http",
59 "Shaarli\\Legacy\\": "application/legacy", 60 "Shaarli\\Legacy\\": "application/legacy",
diff --git a/doc/md/Translations.md b/doc/md/Translations.md
index c1a2885d..e0e411bb 100644
--- a/doc/md/Translations.md
+++ b/doc/md/Translations.md
@@ -37,7 +37,7 @@ http://<replace_domain>/?do=changepasswd
37http://<replace_domain>/?do=changetag 37http://<replace_domain>/?do=changetag
38http://<replace_domain>/?do=configure 38http://<replace_domain>/?do=configure
39http://<replace_domain>/?do=tools 39http://<replace_domain>/?do=tools
40http://<replace_domain>/?do=daily 40http://<replace_domain>/daily
41http://<replace_domain>/?post 41http://<replace_domain>/?post
42http://<replace_domain>/?do=export 42http://<replace_domain>/?do=export
43http://<replace_domain>/?do=import 43http://<replace_domain>/?do=import
diff --git a/index.php b/index.php
index a31cbeab..4cd6d5f4 100644
--- a/index.php
+++ b/index.php
@@ -1498,30 +1498,33 @@ $app->group('/api/v1', function () {
1498})->add('\Shaarli\Api\ApiMiddleware'); 1498})->add('\Shaarli\Api\ApiMiddleware');
1499 1499
1500$app->group('', function () { 1500$app->group('', function () {
1501 $this->get('/login', '\Shaarli\Front\Controller\LoginController:index')->setName('login'); 1501 /* -- PUBLIC --*/
1502 $this->get('/logout', '\Shaarli\Front\Controller\LogoutController:index')->setName('logout'); 1502 $this->get('/login', '\Shaarli\Front\Controller\Visitor\LoginController:index')->setName('login');
1503 $this->get('/picture-wall', '\Shaarli\Front\Controller\PictureWallController:index')->setName('picwall'); 1503 $this->get('/picture-wall', '\Shaarli\Front\Controller\Visitor\PictureWallController:index')->setName('picwall');
1504 $this->get('/tag-cloud', '\Shaarli\Front\Controller\TagCloudController:cloud')->setName('tagcloud'); 1504 $this->get('/tag-cloud', '\Shaarli\Front\Controller\Visitor\TagCloudController:cloud')->setName('tagcloud');
1505 $this->get('/tag-list', '\Shaarli\Front\Controller\TagCloudController:list')->setName('taglist'); 1505 $this->get('/tag-list', '\Shaarli\Front\Controller\Visitor\TagCloudController:list')->setName('taglist');
1506 $this->get('/daily', '\Shaarli\Front\Controller\DailyController:index')->setName('daily'); 1506 $this->get('/daily', '\Shaarli\Front\Controller\Visitor\DailyController:index')->setName('daily');
1507 $this->get('/daily-rss', '\Shaarli\Front\Controller\DailyController:rss')->setName('dailyrss'); 1507 $this->get('/daily-rss', '\Shaarli\Front\Controller\Visitor\DailyController:rss')->setName('dailyrss');
1508 $this->get('/feed-atom', '\Shaarli\Front\Controller\FeedController:atom')->setName('feedatom'); 1508 $this->get('/feed-atom', '\Shaarli\Front\Controller\Visitor\FeedController:atom')->setName('feedatom');
1509 $this->get('/feed-rss', '\Shaarli\Front\Controller\FeedController:rss')->setName('feedrss'); 1509 $this->get('/feed-rss', '\Shaarli\Front\Controller\Visitor\FeedController:rss')->setName('feedrss');
1510 $this->get('/open-search', '\Shaarli\Front\Controller\OpenSearchController:index')->setName('opensearch'); 1510 $this->get('/open-search', '\Shaarli\Front\Controller\Visitor\OpenSearchController:index')->setName('opensearch');
1511 1511
1512 $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\TagController:addTag')->setName('add-tag'); 1512 $this->get('/add-tag/{newTag}', '\Shaarli\Front\Controller\Visitor\TagController:addTag')->setName('add-tag');
1513 $this->get('/remove-tag/{tag}', '\Shaarli\Front\Controller\TagController:removeTag')->setName('remove-tag'); 1513 $this->get('/remove-tag/{tag}', '\Shaarli\Front\Controller\Visitor\TagController:removeTag')->setName('remove-tag');
1514
1515 /* -- LOGGED IN -- */
1516 $this->get('/logout', '\Shaarli\Front\Controller\Admin\LogoutController:index')->setName('logout');
1514 1517
1515 $this 1518 $this
1516 ->get('/links-per-page', '\Shaarli\Front\Controller\SessionFilterController:linksPerPage') 1519 ->get('/links-per-page', '\Shaarli\Front\Controller\Admin\SessionFilterController:linksPerPage')
1517 ->setName('filter-links-per-page') 1520 ->setName('filter-links-per-page')
1518 ; 1521 ;
1519 $this 1522 $this
1520 ->get('/visibility/{visibility}', '\Shaarli\Front\Controller\SessionFilterController:visibility') 1523 ->get('/visibility/{visibility}', '\Shaarli\Front\Controller\Admin\SessionFilterController:visibility')
1521 ->setName('visibility') 1524 ->setName('visibility')
1522 ; 1525 ;
1523 $this 1526 $this
1524 ->get('/untagged-only', '\Shaarli\Front\Controller\SessionFilterController:untaggedOnly') 1527 ->get('/untagged-only', '\Shaarli\Front\Controller\Admin\SessionFilterController:untaggedOnly')
1525 ->setName('untagged-only') 1528 ->setName('untagged-only')
1526 ; 1529 ;
1527})->add('\Shaarli\Front\ShaarliMiddleware'); 1530})->add('\Shaarli\Front\ShaarliMiddleware');
diff --git a/tests/bootstrap.php b/tests/bootstrap.php
index 6bb345c2..511698ff 100644
--- a/tests/bootstrap.php
+++ b/tests/bootstrap.php
@@ -22,4 +22,5 @@ require_once 'tests/utils/ReferenceLinkDB.php';
22require_once 'tests/utils/ReferenceHistory.php'; 22require_once 'tests/utils/ReferenceHistory.php';
23require_once 'tests/utils/FakeBookmarkService.php'; 23require_once 'tests/utils/FakeBookmarkService.php';
24require_once 'tests/container/ShaarliTestContainer.php'; 24require_once 'tests/container/ShaarliTestContainer.php';
25require_once 'tests/front/controller/FrontControllerMockHelper.php'; 25require_once 'tests/front/controller/visitor/FrontControllerMockHelper.php';
26require_once 'tests/front/controller/admin/FrontAdminControllerMockHelper.php';
diff --git a/tests/front/controller/admin/FrontAdminControllerMockHelper.php b/tests/front/controller/admin/FrontAdminControllerMockHelper.php
new file mode 100644
index 00000000..94581c09
--- /dev/null
+++ b/tests/front/controller/admin/FrontAdminControllerMockHelper.php
@@ -0,0 +1,34 @@
1<?php
2
3declare(strict_types=1);
4
5namespace Shaarli\Front\Controller\Admin;
6
7use Shaarli\Container\ShaarliTestContainer;
8use Shaarli\Front\Controller\Visitor\FrontControllerMockHelper;
9use Shaarli\Security\LoginManager;
10
11/**
12 * Trait FrontControllerMockHelper
13 *
14 * Helper trait used to initialize the ShaarliContainer and mock its services for admin controller tests.
15 *
16 * @property ShaarliTestContainer $container
17 */
18trait FrontAdminControllerMockHelper
19{
20 use FrontControllerMockHelper {
21 FrontControllerMockHelper::createContainer as parentCreateContainer;
22 }
23
24 /**
25 * Mock the container instance
26 */
27 protected function createContainer(): void
28 {
29 $this->parentCreateContainer();
30
31 $this->container->loginManager = $this->createMock(LoginManager::class);
32 $this->container->loginManager->method('isLoggedIn')->willReturn(true);
33 }
34}
diff --git a/tests/front/controller/LogoutControllerTest.php b/tests/front/controller/admin/LogoutControllerTest.php
index 8e01c367..239e39b2 100644
--- a/tests/front/controller/LogoutControllerTest.php
+++ b/tests/front/controller/admin/LogoutControllerTest.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Admin;
6 6
7/** Override PHP builtin setcookie function in the local namespace to mock it... more or less */ 7/** Override PHP builtin setcookie function in the local namespace to mock it... more or less */
8if (!function_exists('Shaarli\Front\Controller\setcookie')) { 8if (!function_exists('Shaarli\Front\Controller\setcookie')) {
@@ -19,7 +19,7 @@ use Slim\Http\Response;
19 19
20class LogoutControllerTest extends TestCase 20class LogoutControllerTest extends TestCase
21{ 21{
22 use FrontControllerMockHelper; 22 use FrontAdminControllerMockHelper;
23 23
24 /** @var LogoutController */ 24 /** @var LogoutController */
25 protected $controller; 25 protected $controller;
diff --git a/tests/front/controller/SessionFilterControllerTest.php b/tests/front/controller/admin/SessionFilterControllerTest.php
index f541de03..f50f2fc2 100644
--- a/tests/front/controller/SessionFilterControllerTest.php
+++ b/tests/front/controller/admin/SessionFilterControllerTest.php
@@ -2,16 +2,18 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Admin;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Security\LoginManager;
8use Shaarli\Security\SessionManager; 9use Shaarli\Security\SessionManager;
9use Slim\Http\Request; 10use Slim\Http\Request;
10use Slim\Http\Response; 11use Slim\Http\Response;
12use Slim\Http\Uri;
11 13
12class SessionFilterControllerTest extends TestCase 14class SessionFilterControllerTest extends TestCase
13{ 15{
14 use FrontControllerMockHelper; 16 use FrontAdminControllerMockHelper;
15 17
16 /** @var SessionFilterController */ 18 /** @var SessionFilterController */
17 protected $controller; 19 protected $controller;
@@ -33,6 +35,12 @@ class SessionFilterControllerTest extends TestCase
33 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; 35 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc'];
34 36
35 $request = $this->createMock(Request::class); 37 $request = $this->createMock(Request::class);
38 $request->method('getUri')->willReturnCallback(function (): Uri {
39 $uri = $this->createMock(Uri::class);
40 $uri->method('getBasePath')->willReturn('/subfolder');
41
42 return $uri;
43 });
36 $request->method('getParam')->with('nb')->willReturn('8'); 44 $request->method('getParam')->with('nb')->willReturn('8');
37 $response = new Response(); 45 $response = new Response();
38 46
@@ -57,6 +65,12 @@ class SessionFilterControllerTest extends TestCase
57 $this->createValidContainerMockSet(); 65 $this->createValidContainerMockSet();
58 66
59 $request = $this->createMock(Request::class); 67 $request = $this->createMock(Request::class);
68 $request->method('getUri')->willReturnCallback(function (): Uri {
69 $uri = $this->createMock(Uri::class);
70 $uri->method('getBasePath')->willReturn('/subfolder');
71
72 return $uri;
73 });
60 $request->method('getParam')->with('nb')->willReturn('test'); 74 $request->method('getParam')->with('nb')->willReturn('test');
61 $response = new Response(); 75 $response = new Response();
62 76
@@ -70,7 +84,7 @@ class SessionFilterControllerTest extends TestCase
70 84
71 static::assertInstanceOf(Response::class, $result); 85 static::assertInstanceOf(Response::class, $result);
72 static::assertSame(302, $result->getStatusCode()); 86 static::assertSame(302, $result->getStatusCode());
73 static::assertSame(['./'], $result->getHeader('location')); 87 static::assertSame(['/subfolder'], $result->getHeader('location'));
74 } 88 }
75 89
76 /** 90 /**
@@ -92,6 +106,12 @@ class SessionFilterControllerTest extends TestCase
92 ; 106 ;
93 107
94 $request = $this->createMock(Request::class); 108 $request = $this->createMock(Request::class);
109 $request->method('getUri')->willReturnCallback(function (): Uri {
110 $uri = $this->createMock(Uri::class);
111 $uri->method('getBasePath')->willReturn('/subfolder');
112
113 return $uri;
114 });
95 $response = new Response(); 115 $response = new Response();
96 116
97 $result = $this->controller->visibility($request, $response, $arg); 117 $result = $this->controller->visibility($request, $response, $arg);
@@ -129,6 +149,12 @@ class SessionFilterControllerTest extends TestCase
129 ; 149 ;
130 150
131 $request = $this->createMock(Request::class); 151 $request = $this->createMock(Request::class);
152 $request->method('getUri')->willReturnCallback(function (): Uri {
153 $uri = $this->createMock(Uri::class);
154 $uri->method('getBasePath')->willReturn('/subfolder');
155
156 return $uri;
157 });
132 $response = new Response(); 158 $response = new Response();
133 159
134 $result = $this->controller->visibility($request, $response, $arg); 160 $result = $this->controller->visibility($request, $response, $arg);
@@ -160,13 +186,19 @@ class SessionFilterControllerTest extends TestCase
160 ; 186 ;
161 187
162 $request = $this->createMock(Request::class); 188 $request = $this->createMock(Request::class);
189 $request->method('getUri')->willReturnCallback(function (): Uri {
190 $uri = $this->createMock(Uri::class);
191 $uri->method('getBasePath')->willReturn('/subfolder');
192
193 return $uri;
194 });
163 $response = new Response(); 195 $response = new Response();
164 196
165 $result = $this->controller->visibility($request, $response, $arg); 197 $result = $this->controller->visibility($request, $response, $arg);
166 198
167 static::assertInstanceOf(Response::class, $result); 199 static::assertInstanceOf(Response::class, $result);
168 static::assertSame(302, $result->getStatusCode()); 200 static::assertSame(302, $result->getStatusCode());
169 static::assertSame(['./'], $result->getHeader('location')); 201 static::assertSame(['/subfolder'], $result->getHeader('location'));
170 } 202 }
171 203
172 /** 204 /**
@@ -192,6 +224,12 @@ class SessionFilterControllerTest extends TestCase
192 ; 224 ;
193 225
194 $request = $this->createMock(Request::class); 226 $request = $this->createMock(Request::class);
227 $request->method('getUri')->willReturnCallback(function (): Uri {
228 $uri = $this->createMock(Uri::class);
229 $uri->method('getBasePath')->willReturn('/subfolder');
230
231 return $uri;
232 });
195 $response = new Response(); 233 $response = new Response();
196 234
197 $result = $this->controller->visibility($request, $response, $arg); 235 $result = $this->controller->visibility($request, $response, $arg);
@@ -212,6 +250,7 @@ class SessionFilterControllerTest extends TestCase
212 250
213 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; 251 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc'];
214 252
253 $this->container->loginManager = $this->createMock(LoginManager::class);
215 $this->container->loginManager->method('isLoggedIn')->willReturn(false); 254 $this->container->loginManager->method('isLoggedIn')->willReturn(false);
216 $this->container->sessionManager 255 $this->container->sessionManager
217 ->expects(static::never()) 256 ->expects(static::never())
@@ -224,6 +263,12 @@ class SessionFilterControllerTest extends TestCase
224 ; 263 ;
225 264
226 $request = $this->createMock(Request::class); 265 $request = $this->createMock(Request::class);
266 $request->method('getUri')->willReturnCallback(function (): Uri {
267 $uri = $this->createMock(Uri::class);
268 $uri->method('getBasePath')->willReturn('/subfolder');
269
270 return $uri;
271 });
227 $response = new Response(); 272 $response = new Response();
228 273
229 $result = $this->controller->visibility($request, $response, $arg); 274 $result = $this->controller->visibility($request, $response, $arg);
@@ -243,6 +288,12 @@ class SessionFilterControllerTest extends TestCase
243 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; 288 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc'];
244 289
245 $request = $this->createMock(Request::class); 290 $request = $this->createMock(Request::class);
291 $request->method('getUri')->willReturnCallback(function (): Uri {
292 $uri = $this->createMock(Uri::class);
293 $uri->method('getBasePath')->willReturn('/subfolder');
294
295 return $uri;
296 });
246 $response = new Response(); 297 $response = new Response();
247 298
248 $this->container->sessionManager 299 $this->container->sessionManager
@@ -268,6 +319,13 @@ class SessionFilterControllerTest extends TestCase
268 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc']; 319 $this->container->environment = ['HTTP_REFERER' => 'http://shaarli/subfolder/controller/?searchtag=abc'];
269 320
270 $request = $this->createMock(Request::class); 321 $request = $this->createMock(Request::class);
322 $request->method('getUri')->willReturnCallback(function (): Uri {
323 $uri = $this->createMock(Uri::class);
324 $uri->method('getBasePath')->willReturn('/subfolder');
325
326 return $uri;
327 });
328
271 $response = new Response(); 329 $response = new Response();
272 330
273 $this->container->sessionManager 331 $this->container->sessionManager
diff --git a/tests/front/controller/DailyControllerTest.php b/tests/front/controller/visitor/DailyControllerTest.php
index 7ec99030..6ff769fc 100644
--- a/tests/front/controller/DailyControllerTest.php
+++ b/tests/front/controller/visitor/DailyControllerTest.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Bookmark\Bookmark; 8use Shaarli\Bookmark\Bookmark;
diff --git a/tests/front/controller/FeedControllerTest.php b/tests/front/controller/visitor/FeedControllerTest.php
index 7e8657e2..fd4679ea 100644
--- a/tests/front/controller/FeedControllerTest.php
+++ b/tests/front/controller/visitor/FeedControllerTest.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Feed\FeedBuilder; 8use Shaarli\Feed\FeedBuilder;
diff --git a/tests/front/controller/FrontControllerMockHelper.php b/tests/front/controller/visitor/FrontControllerMockHelper.php
index b65607e7..bc3266b5 100644
--- a/tests/front/controller/FrontControllerMockHelper.php
+++ b/tests/front/controller/visitor/FrontControllerMockHelper.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\MockObject\MockObject; 7use PHPUnit\Framework\MockObject\MockObject;
8use Shaarli\Bookmark\BookmarkServiceInterface; 8use Shaarli\Bookmark\BookmarkServiceInterface;
diff --git a/tests/front/controller/LoginControllerTest.php b/tests/front/controller/visitor/LoginControllerTest.php
index 21937f3c..9d223316 100644
--- a/tests/front/controller/LoginControllerTest.php
+++ b/tests/front/controller/visitor/LoginControllerTest.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Config\ConfigManager; 8use Shaarli\Config\ConfigManager;
diff --git a/tests/front/controller/OpenSearchControllerTest.php b/tests/front/controller/visitor/OpenSearchControllerTest.php
index f3b6f439..52475318 100644
--- a/tests/front/controller/OpenSearchControllerTest.php
+++ b/tests/front/controller/visitor/OpenSearchControllerTest.php
@@ -2,11 +2,9 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace front\controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Front\Controller\FrontControllerMockHelper;
9use Shaarli\Front\Controller\OpenSearchController;
10use Slim\Http\Request; 8use Slim\Http\Request;
11use Slim\Http\Response; 9use Slim\Http\Response;
12 10
diff --git a/tests/front/controller/PictureWallControllerTest.php b/tests/front/controller/visitor/PictureWallControllerTest.php
index 8160bb38..7ac842cb 100644
--- a/tests/front/controller/PictureWallControllerTest.php
+++ b/tests/front/controller/visitor/PictureWallControllerTest.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Bookmark\Bookmark; 8use Shaarli\Bookmark\Bookmark;
diff --git a/tests/front/controller/ShaarliControllerTest.php b/tests/front/controller/visitor/ShaarliPublicControllerTest.php
index a6011b49..e2e88da3 100644
--- a/tests/front/controller/ShaarliControllerTest.php
+++ b/tests/front/controller/visitor/ShaarliPublicControllerTest.php
@@ -2,11 +2,13 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Bookmark\BookmarkFilter; 8use Shaarli\Bookmark\BookmarkFilter;
9use Slim\Http\Request;
9use Slim\Http\Response; 10use Slim\Http\Response;
11use Slim\Http\Uri;
10 12
11/** 13/**
12 * Class ShaarliControllerTest 14 * Class ShaarliControllerTest
@@ -24,13 +26,16 @@ class ShaarliControllerTest extends TestCase
24 /** @var mixed[] List of variable assigned to the template */ 26 /** @var mixed[] List of variable assigned to the template */
25 protected $assignedValues; 27 protected $assignedValues;
26 28
29 /** @var Request */
30 protected $request;
31
27 public function setUp(): void 32 public function setUp(): void
28 { 33 {
29 $this->createContainer(); 34 $this->createContainer();
30 35
31 $this->controller = new class($this->container) extends ShaarliController 36 $this->controller = new class($this->container) extends ShaarliVisitorController
32 { 37 {
33 public function assignView(string $key, $value): ShaarliController 38 public function assignView(string $key, $value): ShaarliVisitorController
34 { 39 {
35 return parent::assignView($key, $value); 40 return parent::assignView($key, $value);
36 } 41 }
@@ -41,14 +46,23 @@ class ShaarliControllerTest extends TestCase
41 } 46 }
42 47
43 public function redirectFromReferer( 48 public function redirectFromReferer(
49 Request $request,
44 Response $response, 50 Response $response,
45 array $loopTerms = [], 51 array $loopTerms = [],
46 array $clearParams = [] 52 array $clearParams = []
47 ): Response { 53 ): Response {
48 return parent::redirectFromReferer($response, $loopTerms, $clearParams); 54 return parent::redirectFromReferer($request, $response, $loopTerms, $clearParams);
49 } 55 }
50 }; 56 };
51 $this->assignedValues = []; 57 $this->assignedValues = [];
58
59 $this->request = $this->createMock(Request::class);
60 $this->request->method('getUri')->willReturnCallback(function (): Uri {
61 $uri = $this->createMock(Uri::class);
62 $uri->method('getBasePath')->willReturn('/subfolder');
63
64 return $uri;
65 });
52 } 66 }
53 67
54 public function testAssignView(): void 68 public function testAssignView(): void
@@ -59,7 +73,7 @@ class ShaarliControllerTest extends TestCase
59 73
60 $self = $this->controller->assignView('variableName', 'variableValue'); 74 $self = $this->controller->assignView('variableName', 'variableValue');
61 75
62 static::assertInstanceOf(ShaarliController::class, $self); 76 static::assertInstanceOf(ShaarliVisitorController::class, $self);
63 static::assertSame('variableValue', $this->assignedValues['variableName']); 77 static::assertSame('variableValue', $this->assignedValues['variableName']);
64 } 78 }
65 79
@@ -112,7 +126,7 @@ class ShaarliControllerTest extends TestCase
112 126
113 $response = new Response(); 127 $response = new Response();
114 128
115 $result = $this->controller->redirectFromReferer($response); 129 $result = $this->controller->redirectFromReferer($this->request, $response);
116 130
117 static::assertSame(302, $result->getStatusCode()); 131 static::assertSame(302, $result->getStatusCode());
118 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); 132 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location'));
@@ -129,7 +143,7 @@ class ShaarliControllerTest extends TestCase
129 143
130 $response = new Response(); 144 $response = new Response();
131 145
132 $result = $this->controller->redirectFromReferer($response, ['nope']); 146 $result = $this->controller->redirectFromReferer($this->request, $response, ['nope']);
133 147
134 static::assertSame(302, $result->getStatusCode()); 148 static::assertSame(302, $result->getStatusCode());
135 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); 149 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location'));
@@ -146,10 +160,10 @@ class ShaarliControllerTest extends TestCase
146 160
147 $response = new Response(); 161 $response = new Response();
148 162
149 $result = $this->controller->redirectFromReferer($response, ['nope', 'controller']); 163 $result = $this->controller->redirectFromReferer($this->request, $response, ['nope', 'controller']);
150 164
151 static::assertSame(302, $result->getStatusCode()); 165 static::assertSame(302, $result->getStatusCode());
152 static::assertSame(['./'], $result->getHeader('location')); 166 static::assertSame(['/subfolder'], $result->getHeader('location'));
153 } 167 }
154 168
155 /** 169 /**
@@ -163,10 +177,10 @@ class ShaarliControllerTest extends TestCase
163 177
164 $response = new Response(); 178 $response = new Response();
165 179
166 $result = $this->controller->redirectFromReferer($response, ['nope', 'other']); 180 $result = $this->controller->redirectFromReferer($this->request, $response, ['nope', 'other']);
167 181
168 static::assertSame(302, $result->getStatusCode()); 182 static::assertSame(302, $result->getStatusCode());
169 static::assertSame(['./'], $result->getHeader('location')); 183 static::assertSame(['/subfolder'], $result->getHeader('location'));
170 } 184 }
171 185
172 /** 186 /**
@@ -181,7 +195,7 @@ class ShaarliControllerTest extends TestCase
181 195
182 $response = new Response(); 196 $response = new Response();
183 197
184 $result = $this->controller->redirectFromReferer($response, ['nope', 'param']); 198 $result = $this->controller->redirectFromReferer($this->request, $response, ['nope', 'param']);
185 199
186 static::assertSame(302, $result->getStatusCode()); 200 static::assertSame(302, $result->getStatusCode());
187 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); 201 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location'));
@@ -199,7 +213,7 @@ class ShaarliControllerTest extends TestCase
199 213
200 $response = new Response(); 214 $response = new Response();
201 215
202 $result = $this->controller->redirectFromReferer($response, ['shaarli']); 216 $result = $this->controller->redirectFromReferer($this->request, $response, ['shaarli']);
203 217
204 static::assertSame(302, $result->getStatusCode()); 218 static::assertSame(302, $result->getStatusCode());
205 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location')); 219 static::assertSame(['/subfolder/controller?query=param&other=2'], $result->getHeader('location'));
@@ -217,7 +231,7 @@ class ShaarliControllerTest extends TestCase
217 231
218 $response = new Response(); 232 $response = new Response();
219 233
220 $result = $this->controller->redirectFromReferer($response, ['query'], ['query']); 234 $result = $this->controller->redirectFromReferer($this->request, $response, ['query'], ['query']);
221 235
222 static::assertSame(302, $result->getStatusCode()); 236 static::assertSame(302, $result->getStatusCode());
223 static::assertSame(['/subfolder/controller?other=2'], $result->getHeader('location')); 237 static::assertSame(['/subfolder/controller?other=2'], $result->getHeader('location'));
diff --git a/tests/front/controller/TagCloudControllerTest.php b/tests/front/controller/visitor/TagCloudControllerTest.php
index 8c27900d..e636d496 100644
--- a/tests/front/controller/TagCloudControllerTest.php
+++ b/tests/front/controller/visitor/TagCloudControllerTest.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Shaarli\Bookmark\BookmarkFilter; 8use Shaarli\Bookmark\BookmarkFilter;
diff --git a/tests/front/controller/TagControllerTest.php b/tests/front/controller/visitor/TagControllerTest.php
index 2184cb11..9a2b1f71 100644
--- a/tests/front/controller/TagControllerTest.php
+++ b/tests/front/controller/visitor/TagControllerTest.php
@@ -2,7 +2,7 @@
2 2
3declare(strict_types=1); 3declare(strict_types=1);
4 4
5namespace Shaarli\Front\Controller; 5namespace Shaarli\Front\Controller\Visitor;
6 6
7use PHPUnit\Framework\TestCase; 7use PHPUnit\Framework\TestCase;
8use Slim\Http\Request; 8use Slim\Http\Request;
@@ -12,8 +12,7 @@ class TagControllerTest extends TestCase
12{ 12{
13 use FrontControllerMockHelper; 13 use FrontControllerMockHelper;
14 14
15 /** @var TagController */ 15 /** @var TagController */ protected $controller;
16 protected $controller;
17 16
18 public function setUp(): void 17 public function setUp(): void
19 { 18 {
diff --git a/tpl/default/page.header.html b/tpl/default/page.header.html
index 2d015b26..624367e4 100644
--- a/tpl/default/page.header.html
+++ b/tpl/default/page.header.html
@@ -38,7 +38,7 @@
38 </li> 38 </li>
39 {/if} 39 {/if}
40 <li class="pure-menu-item" id="shaarli-menu-daily"> 40 <li class="pure-menu-item" id="shaarli-menu-daily">
41 <a href="./?do=daily" class="pure-menu-link">{'Daily'|t}</a> 41 <a href="./daily" class="pure-menu-link">{'Daily'|t}</a>
42 </li> 42 </li>
43 {loop="$plugins_header.buttons_toolbar"} 43 {loop="$plugins_header.buttons_toolbar"}
44 <li class="pure-menu-item shaarli-menu-plugin"> 44 <li class="pure-menu-item shaarli-menu-plugin">
diff --git a/tpl/vintage/daily.html b/tpl/vintage/daily.html
index adcdf6ab..a459e21a 100644
--- a/tpl/vintage/daily.html
+++ b/tpl/vintage/daily.html
@@ -14,9 +14,9 @@
14 14
15 <div class="dailyAbout"> 15 <div class="dailyAbout">
16 All links of one day<br>in a single page.<br> 16 All links of one day<br>in a single page.<br>
17 {if="$previousday"} <a href="./?do=daily&amp;day={$previousday}"><b>&lt;</b>Previous day</a>{else}<b>&lt;</b>Previous day{/if} 17 {if="$previousday"} <a href="./daily&amp;day={$previousday}"><b>&lt;</b>Previous day</a>{else}<b>&lt;</b>Previous day{/if}
18 - 18 -
19 {if="$nextday"}<a href="./?do=daily&amp;day={$nextday}">Next day<b>&gt;</b></a>{else}Next day<b>&gt;</b>{/if} 19 {if="$nextday"}<a href="./daily&amp;day={$nextday}">Next day<b>&gt;</b></a>{else}Next day<b>&gt;</b>{/if}
20 <br> 20 <br>
21 21
22 {loop="$daily_about_plugin"} 22 {loop="$daily_about_plugin"}
diff --git a/tpl/vintage/page.header.html b/tpl/vintage/page.header.html
index 0a8392b6..9268ced9 100644
--- a/tpl/vintage/page.header.html
+++ b/tpl/vintage/page.header.html
@@ -33,7 +33,7 @@
33 {/if} 33 {/if}
34 <li><a href="./tag-cloud">Tag cloud</a></li> 34 <li><a href="./tag-cloud">Tag cloud</a></li>
35 <li><a href="./picture-wall{function="ltrim($searchcrits, '&')"}">Picture wall</a></li> 35 <li><a href="./picture-wall{function="ltrim($searchcrits, '&')"}">Picture wall</a></li>
36 <li><a href="./?do=daily">Daily</a></li> 36 <li><a href="./daily">Daily</a></li>
37 {loop="$plugins_header.buttons_toolbar"} 37 {loop="$plugins_header.buttons_toolbar"}
38 <li><a 38 <li><a
39 {loop="$value.attr"} 39 {loop="$value.attr"}