diff --git a/.htaccess b/.htaccess
index 659993ef..16764177 100644
--- a/.htaccess
+++ b/.htaccess
@@ -1,3 +1,6 @@
+# Turn on the rewrite engine
RewriteEngine on
+# If the URL path is empty, rewrite to the 'public/' directory
RewriteRule ^$ public/ [L]
+# For any requested URL path, rewrite to the 'public/' directory followed by the requested path
RewriteRule (.*) public/$1 [L]
diff --git a/src/Application/Action/Authentication/Ajax/AccountUnlockProcessAction.php b/src/Application/Action/Authentication/Ajax/AccountUnlockProcessAction.php
index aab62a82..cc767a1b 100644
--- a/src/Application/Action/Authentication/Ajax/AccountUnlockProcessAction.php
+++ b/src/Application/Action/Authentication/Ajax/AccountUnlockProcessAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Authentication\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
use App\Domain\Authentication\Exception\InvalidTokenException;
use App\Domain\Authentication\Exception\UserAlreadyVerifiedException;
use App\Domain\Authentication\Service\AccountUnlockTokenVerifier;
@@ -17,7 +17,7 @@ final class AccountUnlockProcessAction
{
public function __construct(
private readonly LoggerInterface $logger,
- private readonly Responder $responder,
+ private readonly RedirectHandler $redirectHandler,
private readonly SessionManagerInterface $sessionManager,
private readonly SessionInterface $session,
private readonly AccountUnlockTokenVerifier $accountUnlockTokenVerifier
@@ -52,10 +52,10 @@ public function __invoke(ServerRequest $request, Response $response): Response
)
);
- return $this->responder->redirectToUrl($response, $queryParams['redirect']);
+ return $this->redirectHandler->redirectToUrl($response, $queryParams['redirect']);
}
- return $this->responder->redirectToRouteName($response, 'home-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'home-page');
} catch (InvalidTokenException $ite) {
$flash->add(
'error',
@@ -65,7 +65,7 @@ public function __invoke(ServerRequest $request, Response $response): Response
$newQueryParam = isset($queryParams['redirect']) ? ['redirect' => $queryParams['redirect']] : [];
// Redirect to login page with redirect query param if set
- return $this->responder->redirectToRouteName($response, 'login-page', [], $newQueryParam);
+ return $this->redirectHandler->redirectToRouteName($response, 'login-page', [], $newQueryParam);
} catch (UserAlreadyVerifiedException $uave) {
$flash->add('info', $uave->getMessage());
$this->logger->info(
@@ -73,7 +73,7 @@ public function __invoke(ServerRequest $request, Response $response): Response
);
$newQueryParam = isset($queryParams['redirect']) ? ['redirect' => $queryParams['redirect']] : [];
- return $this->responder->redirectToRouteName(
+ return $this->redirectHandler->redirectToRouteName(
$response,
'login-page',
[],
diff --git a/src/Application/Action/Authentication/Ajax/LoginSubmitAction.php b/src/Application/Action/Authentication/Ajax/LoginSubmitAction.php
index c37fb790..951339db 100644
--- a/src/Application/Action/Authentication/Ajax/LoginSubmitAction.php
+++ b/src/Application/Action/Authentication/Ajax/LoginSubmitAction.php
@@ -2,7 +2,8 @@
namespace App\Application\Action\Authentication\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\Authentication\Exception\InvalidCredentialsException;
use App\Domain\Authentication\Exception\UnableToLoginStatusNotActiveException;
use App\Domain\Authentication\Service\LoginVerifier;
@@ -18,7 +19,8 @@
final class LoginSubmitAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly RedirectHandler $redirectHandler,
+ private readonly TemplateRenderer $templateRenderer,
private readonly LoggerInterface $logger,
private readonly LoginVerifier $loginVerifier,
private readonly SessionManagerInterface $sessionManager,
@@ -57,17 +59,17 @@ public function __invoke(ServerRequest $request, Response $response): Response
// After register and login success, check if user should be redirected
if (isset($queryParams['redirect'])) {
- return $this->responder->redirectToUrl(
+ return $this->redirectHandler->redirectToUrl(
$response,
$request->getQueryParams()['redirect'],
$themeQueryParams
);
}
- return $this->responder->redirectToRouteName($response, 'home-page', [], $themeQueryParams);
+ return $this->redirectHandler->redirectToRouteName($response, 'home-page', [], $themeQueryParams);
} // When the response is not JSON but rendered, the validation exception has to be caught in action
catch (ValidationException $ve) {
- return $this->responder->renderOnValidationError(
+ return $this->templateRenderer->renderOnValidationError(
$response,
'authentication/login.html.php',
$ve,
@@ -79,10 +81,10 @@ public function __invoke(ServerRequest $request, Response $response): Response
'InvalidCredentialsException thrown with message: "' . $e->getMessage() . '" user "' .
$e->getUserEmail() . '"'
);
- $this->responder->addPhpViewAttribute('formError', true);
- $this->responder->addPhpViewAttribute('formErrorMessage', __('Invalid credentials. Please try again.'));
+ $this->templateRenderer->addPhpViewAttribute('formError', true);
+ $this->templateRenderer->addPhpViewAttribute('formErrorMessage', __('Invalid credentials. Please try again.'));
- return $this->responder->render(
+ return $this->templateRenderer->render(
$response->withStatus(401),
'authentication/login.html.php',
// Provide same query params passed to login page to be added to the login submit request
@@ -94,7 +96,7 @@ public function __invoke(ServerRequest $request, Response $response): Response
throw $securityException;
}
- return $this->responder->respondWithFormThrottle(
+ return $this->templateRenderer->respondWithFormThrottle(
$response,
'authentication/login.html.php',
$securityException,
@@ -103,11 +105,11 @@ public function __invoke(ServerRequest $request, Response $response): Response
);
} catch (UnableToLoginStatusNotActiveException $unableToLoginException) {
// When user doesn't have status active
- $this->responder->addPhpViewAttribute('formError', true);
+ $this->templateRenderer->addPhpViewAttribute('formError', true);
// Add form error message
- $this->responder->addPhpViewAttribute('formErrorMessage', $unableToLoginException->getMessage());
+ $this->templateRenderer->addPhpViewAttribute('formErrorMessage', $unableToLoginException->getMessage());
- return $this->responder->render(
+ return $this->templateRenderer->render(
$response->withStatus(401),
'authentication/login.html.php',
// Provide same query params passed to login page to be added to the login submit request
diff --git a/src/Application/Action/Authentication/Ajax/NewPasswordResetSubmitAction.php b/src/Application/Action/Authentication/Ajax/NewPasswordResetSubmitAction.php
index 93a693cf..70e0bee5 100644
--- a/src/Application/Action/Authentication/Ajax/NewPasswordResetSubmitAction.php
+++ b/src/Application/Action/Authentication/Ajax/NewPasswordResetSubmitAction.php
@@ -2,7 +2,8 @@
namespace App\Application\Action\Authentication\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\Authentication\Exception\InvalidTokenException;
use App\Domain\Authentication\Service\PasswordResetterWithToken;
use App\Domain\Validation\ValidationException;
@@ -14,7 +15,8 @@
class NewPasswordResetSubmitAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
+ private readonly RedirectHandler $redirectHandler,
private readonly SessionInterface $session,
private readonly PasswordResetterWithToken $passwordResetterWithToken,
private readonly LoggerInterface $logger,
@@ -44,9 +46,9 @@ public function __invoke(ServerRequest $request, Response $response): Response
sprintf(__('Successfully changed password. %s'), __('Please log in.'))
);
- return $this->responder->redirectToRouteName($response, 'login-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'login-page');
} catch (InvalidTokenException $ite) {
- $this->responder->addPhpViewAttribute(
+ $this->templateRenderer->addPhpViewAttribute(
'formErrorMessage',
__(
'Invalid, used or expired link.
Please request a new link below and make
@@ -55,7 +57,7 @@ public function __invoke(ServerRequest $request, Response $response): Response
);
// Pre-fill email input field for more user comfort.
if ($ite->userData->email !== null) {
- $this->responder->addPhpViewAttribute('preloadValues', ['email' => $ite->userData->email]);
+ $this->templateRenderer->addPhpViewAttribute('preloadValues', ['email' => $ite->userData->email]);
}
$this->logger->error(
@@ -64,15 +66,15 @@ public function __invoke(ServerRequest $request, Response $response): Response
// The login page is rendered but the url is reset-password. In login-main.js the url is replaced and
// the password forgotten form is shown instead of the login form.
- return $this->responder->render($response, 'authentication/login.html.php');
+ return $this->templateRenderer->render($response, 'authentication/login.html.php');
} // Validation Exception has to be caught here and not middleware as we need to add token and id to php view
catch (ValidationException $validationException) {
$flash->add('error', $validationException->getMessage());
// Add token and id to php view attribute like PasswordResetAction does
- $this->responder->addPhpViewAttribute('token', $parsedBody['token']);
- $this->responder->addPhpViewAttribute('id', $parsedBody['id']);
+ $this->templateRenderer->addPhpViewAttribute('token', $parsedBody['token']);
+ $this->templateRenderer->addPhpViewAttribute('id', $parsedBody['id']);
- return $this->responder->renderOnValidationError(
+ return $this->templateRenderer->renderOnValidationError(
$response,
'authentication/reset-password.html.php',
$validationException,
diff --git a/src/Application/Action/Authentication/Ajax/PasswordForgottenEmailSubmitAction.php b/src/Application/Action/Authentication/Ajax/PasswordForgottenEmailSubmitAction.php
index 82b954a5..1ede6d82 100644
--- a/src/Application/Action/Authentication/Ajax/PasswordForgottenEmailSubmitAction.php
+++ b/src/Application/Action/Authentication/Ajax/PasswordForgottenEmailSubmitAction.php
@@ -2,7 +2,8 @@
namespace App\Application\Action\Authentication\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\Authentication\Service\PasswordRecoveryEmailSender;
use App\Domain\Exception\DomainRecordNotFoundException;
use App\Domain\Security\Exception\SecurityException;
@@ -16,7 +17,8 @@
final class PasswordForgottenEmailSubmitAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
+ private readonly RedirectHandler $redirectHandler,
private readonly SessionInterface $session,
private readonly PasswordRecoveryEmailSender $passwordRecoveryEmailSender,
private readonly LoggerInterface $logger,
@@ -46,14 +48,14 @@ public function __invoke(ServerRequest $request, Response $response): Response
);
} catch (ValidationException $validationException) {
// Form error messages set in function below
- return $this->responder->renderOnValidationError(
+ return $this->templateRenderer->renderOnValidationError(
$response,
'authentication/login.html.php',
$validationException,
$request->getQueryParams(),
);
} catch (SecurityException $securityException) {
- return $this->responder->respondWithFormThrottle(
+ return $this->templateRenderer->respondWithFormThrottle(
$response,
'authentication/login.html.php',
$securityException,
@@ -63,7 +65,7 @@ public function __invoke(ServerRequest $request, Response $response): Response
} catch (TransportExceptionInterface $transportException) {
$flash->add('error', __('There was an error when sending the email.'));
- return $this->responder->render(
+ return $this->templateRenderer->render(
$response,
'authentication/login.html.php',
$request->getQueryParams(),
@@ -77,6 +79,6 @@ public function __invoke(ServerRequest $request, Response $response): Response
)
);
- return $this->responder->redirectToRouteName($response, 'login-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'login-page');
}
}
diff --git a/src/Application/Action/Authentication/Ajax/RegisterVerifyProcessAction.php b/src/Application/Action/Authentication/Ajax/RegisterVerifyProcessAction.php
index dcfb5019..e1cf0dbb 100644
--- a/src/Application/Action/Authentication/Ajax/RegisterVerifyProcessAction.php
+++ b/src/Application/Action/Authentication/Ajax/RegisterVerifyProcessAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Authentication\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
use App\Domain\Authentication\Exception\InvalidTokenException;
use App\Domain\Authentication\Exception\UserAlreadyVerifiedException;
use App\Domain\Authentication\Service\RegisterTokenVerifier;
@@ -12,12 +12,14 @@
use Psr\Http\Message\ServerRequestInterface as ServerRequest;
use Psr\Log\LoggerInterface;
use Slim\Exception\HttpBadRequestException;
+use Slim\Interfaces\RouteParserInterface;
final class RegisterVerifyProcessAction
{
public function __construct(
private readonly LoggerInterface $logger,
- private readonly Responder $responder,
+ private readonly RedirectHandler $redirectHandler,
+ private readonly RouteParserInterface $routeParser,
private readonly SessionManagerInterface $sessionManager,
private readonly SessionInterface $session,
private readonly RegisterTokenVerifier $registerTokenVerifier
@@ -51,17 +53,17 @@ public function __invoke(ServerRequest $request, Response $response): Response
$this->session->set('user_id', $userId);
if (isset($queryParams['redirect'])) {
- return $this->responder->redirectToUrl($response, $queryParams['redirect']);
+ return $this->redirectHandler->redirectToUrl($response, $queryParams['redirect']);
}
- return $this->responder->redirectToRouteName($response, 'home-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'home-page');
} catch (InvalidTokenException $ite) {
$flash->add('error', __('Invalid or expired link. Please log in to receive a new link.'));
$this->logger->error('Invalid or expired token user_verification id: ' . $queryParams['id']);
$newQueryParam = isset($queryParams['redirect']) ? ['redirect' => $queryParams['redirect']] : [];
// Redirect to login page with redirect query param if set
- return $this->responder->redirectToRouteName($response, 'login-page', [], $newQueryParam);
+ return $this->redirectHandler->redirectToRouteName($response, 'login-page', [], $newQueryParam);
} catch (UserAlreadyVerifiedException $uave) {
// Check if already logged in
if ($this->session->get('user_id') === null) {
@@ -69,23 +71,23 @@ public function __invoke(ServerRequest $request, Response $response): Response
$flash->add('info', __('You are already verified. Please log in.'));
$newQueryParam = isset($queryParams['redirect']) ? ['redirect' => $queryParams['redirect']] : [];
- return $this->responder->redirectToRouteName($response, 'login-page', [], $newQueryParam);
+ return $this->redirectHandler->redirectToRouteName($response, 'login-page', [], $newQueryParam);
}
// Already logged in
$flash->add(
'info',
sprintf(
__('You are already logged-in.
Would you like to %slogout%s?'),
- '',
+ '',
''
)
);
if (isset($queryParams['redirect'])) {
- return $this->responder->redirectToUrl($response, $queryParams['redirect']);
+ return $this->redirectHandler->redirectToUrl($response, $queryParams['redirect']);
}
- return $this->responder->redirectToRouteName($response, 'home-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'home-page');
}
}
diff --git a/src/Application/Action/Authentication/Page/LoginPageAction.php b/src/Application/Action/Authentication/Page/LoginPageAction.php
index 7556e0b4..1f70aaf1 100644
--- a/src/Application/Action/Authentication/Page/LoginPageAction.php
+++ b/src/Application/Action/Authentication/Page/LoginPageAction.php
@@ -2,15 +2,19 @@
namespace App\Application\Action\Authentication\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
+use App\Application\Responder\TemplateRenderer;
use Odan\Session\SessionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use Slim\Interfaces\RouteParserInterface;
final class LoginPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly RedirectHandler $redirectHandler,
+ private readonly RouteParserInterface $routeParser,
+ private readonly TemplateRenderer $templateRenderer,
private readonly SessionInterface $session,
) {
}
@@ -34,20 +38,20 @@ public function __invoke(ServerRequestInterface $request, ResponseInterface $res
'info',
sprintf(
__('You are already logged-in.
Would you like to %slogout%s?'),
- '',
+ '',
''
)
);
// If redirect param set, redirect to this url
if (isset($queryParams['redirect'])) {
- return $this->responder->redirectToUrl($response, $queryParams['redirect']);
+ return $this->redirectHandler->redirectToUrl($response, $queryParams['redirect']);
}
// Otherwise, go to home page
- return $this->responder->redirectToRouteName($response, 'home-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'home-page');
}
- return $this->responder->render(
+ return $this->templateRenderer->render(
$response,
'authentication/login.html.php',
// Provide same query params passed to login page to be added to the login submit request
diff --git a/src/Application/Action/Authentication/Page/LogoutPageAction.php b/src/Application/Action/Authentication/Page/LogoutPageAction.php
index 490d9956..274db8f6 100644
--- a/src/Application/Action/Authentication/Page/LogoutPageAction.php
+++ b/src/Application/Action/Authentication/Page/LogoutPageAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Authentication\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
use Odan\Session\SessionInterface;
use Odan\Session\SessionManagerInterface;
use Psr\Http\Message\ResponseInterface as Response;
@@ -13,7 +13,7 @@ final class LogoutPageAction
public function __construct(
private readonly SessionManagerInterface $sessionManager,
private readonly SessionInterface $session,
- private readonly Responder $responder,
+ private readonly RedirectHandler $redirectHandler,
) {
}
@@ -26,6 +26,6 @@ public function __invoke(ServerRequest $request, Response $response): Response
// Add flash message to inform user of the success
$this->session->getFlash()->add('success', __('Logged out successfully.'));
- return $this->responder->redirectToRouteName($response, 'login-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'login-page');
}
}
diff --git a/src/Application/Action/Authentication/Page/PasswordResetPageAction.php b/src/Application/Action/Authentication/Page/PasswordResetPageAction.php
index 111edf36..048ade35 100644
--- a/src/Application/Action/Authentication/Page/PasswordResetPageAction.php
+++ b/src/Application/Action/Authentication/Page/PasswordResetPageAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Authentication\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\TemplateRenderer;
use Odan\Session\SessionInterface;
use Psr\Http\Message\ResponseInterface as Response;
use Psr\Http\Message\ServerRequestInterface as ServerRequest;
@@ -11,7 +11,7 @@
class PasswordResetPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
private readonly SessionInterface $session,
private readonly LoggerInterface $logger,
) {
@@ -34,7 +34,7 @@ public function __invoke(ServerRequest $request, Response $response): Response
// There may be other query params e.g. redirect
if (isset($queryParams['id'], $queryParams['token'])) {
- return $this->responder->render($response, 'authentication/reset-password.html.php', [
+ return $this->templateRenderer->render($response, 'authentication/reset-password.html.php', [
'token' => $queryParams['token'],
'id' => $queryParams['id'],
]);
@@ -47,7 +47,7 @@ public function __invoke(ServerRequest $request, Response $response): Response
// If the user clicks on the link and the token's missing, load page with 400 Bad request status
$response = $response->withStatus(400);
- return $this->responder->render($response, 'authentication/reset-password.html.php', [
+ return $this->templateRenderer->render($response, 'authentication/reset-password.html.php', [
'formErrorMessage' => __('Token not found. Please click on the link you received via email.'),
]);
}
diff --git a/src/Application/Action/Client/Ajax/ApiClientCreateAction.php b/src/Application/Action/Client/Ajax/ApiClientCreateAction.php
index 0d918bbd..ad65709f 100644
--- a/src/Application/Action/Client/Ajax/ApiClientCreateAction.php
+++ b/src/Application/Action/Client/Ajax/ApiClientCreateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Client\Service\ClientCreatorFromApi;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -13,7 +13,7 @@
final class ApiClientCreateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly ClientCreatorFromApi $clientCreatorFromClientSubmit,
) {
}
@@ -37,10 +37,10 @@ public function __invoke(
$insertId = $this->clientCreatorFromClientSubmit->createClientFromClientSubmit($clientValues);
if (0 !== $insertId) {
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null], 201);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null], 201);
}
- $response = $this->responder->respondWithJson($response, [
+ $response = $this->jsonResponder->respondWithJson($response, [
'status' => 'warning',
'message' => 'Client not created',
]);
diff --git a/src/Application/Action/Client/Ajax/ClientCreateAction.php b/src/Application/Action/Client/Ajax/ClientCreateAction.php
index 354a7778..ae9db634 100644
--- a/src/Application/Action/Client/Ajax/ClientCreateAction.php
+++ b/src/Application/Action/Client/Ajax/ClientCreateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Client\Service\ClientCreator;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -10,7 +10,7 @@
final class ClientCreateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly ClientCreator $clientCreator,
) {
}
@@ -35,9 +35,9 @@ public function __invoke(
$insertId = $this->clientCreator->createClient($clientValues);
if (0 !== $insertId) {
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null], 201);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null], 201);
}
- $response = $this->responder->respondWithJson($response, [
+ $response = $this->jsonResponder->respondWithJson($response, [
'status' => 'warning',
'message' => 'Client not created',
]);
diff --git a/src/Application/Action/Client/Ajax/ClientDeleteAction.php b/src/Application/Action/Client/Ajax/ClientDeleteAction.php
index 30c61cb6..9d32627e 100644
--- a/src/Application/Action/Client/Ajax/ClientDeleteAction.php
+++ b/src/Application/Action/Client/Ajax/ClientDeleteAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Client\Service\ClientDeleter;
use Odan\Session\SessionInterface;
use Psr\Http\Message\ResponseInterface;
@@ -11,7 +11,7 @@
final class ClientDeleteAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly ClientDeleter $clientDeleter,
private readonly SessionInterface $session,
) {
@@ -42,10 +42,10 @@ public function __invoke(
// Add flash here as user gets redirected to client list after deletion
$flash->add('success', __('Successfully deleted client.'));
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null]);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null]);
}
- $response = $this->responder->respondWithJson(
+ $response = $this->jsonResponder->respondWithJson(
$response,
['status' => 'warning', 'message' => 'Client not deleted.']
);
diff --git a/src/Application/Action/Client/Ajax/ClientFetchListAction.php b/src/Application/Action/Client/Ajax/ClientFetchListAction.php
index c4294ce0..dfa3a68d 100644
--- a/src/Application/Action/Client/Ajax/ClientFetchListAction.php
+++ b/src/Application/Action/Client/Ajax/ClientFetchListAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Client\Exception\InvalidClientFilterException;
use App\Domain\Client\Service\ClientFinderWithFilter;
use App\Test\Integration\Client\ClientListActionTest;
@@ -13,7 +13,7 @@
final class ClientFetchListAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly ClientFinderWithFilter $clientFilterFinder,
) {
}
@@ -36,9 +36,9 @@ public function __invoke(
// Retrieve posts with given filter values (or none)
$clientResultCollection = $this->clientFilterFinder->findClientsWithFilter($request->getQueryParams());
- return $this->responder->respondWithJson($response, $clientResultCollection);
+ return $this->jsonResponder->respondWithJson($response, $clientResultCollection);
} catch (InvalidClientFilterException $invalidClientFilterException) {
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
/** @see ClientListActionTest::testClientListActionInvalidFilters() */
[
diff --git a/src/Application/Action/Client/Ajax/ClientUpdateAction.php b/src/Application/Action/Client/Ajax/ClientUpdateAction.php
index c78f29a8..6a1daf1e 100644
--- a/src/Application/Action/Client/Ajax/ClientUpdateAction.php
+++ b/src/Application/Action/Client/Ajax/ClientUpdateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Client\Service\ClientUpdater;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -10,7 +10,7 @@
final class ClientUpdateAction
{
public function __construct(
- protected readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly ClientUpdater $clientUpdater,
) {
}
@@ -34,12 +34,12 @@ public function __invoke(
$updateData = $this->clientUpdater->updateClient($clientId, $clientValues);
if ($updateData['updated']) {
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
['status' => 'success', 'data' => $updateData['data']]
);
}
- $response = $this->responder->respondWithJson($response, [
+ $response = $this->jsonResponder->respondWithJson($response, [
'status' => 'warning',
'message' => 'The client was not updated.',
'data' => $updateData['data'],
diff --git a/src/Application/Action/Client/Ajax/FetchDropdownOptionsForClientCreateAction.php b/src/Application/Action/Client/Ajax/FetchDropdownOptionsForClientCreateAction.php
index 1672cfb2..33dce79e 100644
--- a/src/Application/Action/Client/Ajax/FetchDropdownOptionsForClientCreateAction.php
+++ b/src/Application/Action/Client/Ajax/FetchDropdownOptionsForClientCreateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Client\Exception\InvalidClientFilterException;
use App\Domain\Client\Service\ClientUtilFinder;
use Fig\Http\Message\StatusCodeInterface;
@@ -12,7 +12,7 @@
class FetchDropdownOptionsForClientCreateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly ClientUtilFinder $clientUtilFinder,
) {
}
@@ -34,7 +34,7 @@ public function __invoke(
try {
$dropdownOptions = $this->clientUtilFinder->findClientDropdownValues();
} catch (InvalidClientFilterException $invalidClientFilterException) {
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
// Response format tested in PostFilterProvider.php
[
@@ -45,6 +45,6 @@ public function __invoke(
);
}
- return $this->responder->respondWithJson($response, $dropdownOptions);
+ return $this->jsonResponder->respondWithJson($response, $dropdownOptions);
}
}
diff --git a/src/Application/Action/Client/Page/ClientListPageAction.php b/src/Application/Action/Client/Page/ClientListPageAction.php
index d30465e1..831f2810 100644
--- a/src/Application/Action/Client/Page/ClientListPageAction.php
+++ b/src/Application/Action/Client/Page/ClientListPageAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\Authorization\Privilege;
use App\Domain\Client\Authorization\ClientAuthorizationChecker;
use App\Domain\Client\Service\ClientListFilter\ClientListFilterChipProvider;
@@ -12,7 +12,7 @@
final class ClientListPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
private readonly ClientListFilterChipProvider $clientListFilterChipGetter,
private readonly ClientAuthorizationChecker $clientAuthorizationChecker
) {
@@ -38,12 +38,12 @@ public function __invoke(
// Retrieving available filters
$clientListFilters = $this->clientListFilterChipGetter->getActiveAndInactiveClientListFilters();
- $this->responder->addPhpViewAttribute('clientListFilters', $clientListFilters);
- $this->responder->addPhpViewAttribute(
+ $this->templateRenderer->addPhpViewAttribute('clientListFilters', $clientListFilters);
+ $this->templateRenderer->addPhpViewAttribute(
'clientCreatePrivilege',
$this->clientAuthorizationChecker->isGrantedToCreate() ? Privilege::CREATE : Privilege::NONE
);
- return $this->responder->render($response, 'client/clients-list.html.php');
+ return $this->templateRenderer->render($response, 'client/clients-list.html.php');
}
}
diff --git a/src/Application/Action/Client/Page/ClientReadPageAction.php b/src/Application/Action/Client/Page/ClientReadPageAction.php
index 6abfca3b..5bd333ef 100644
--- a/src/Application/Action/Client/Page/ClientReadPageAction.php
+++ b/src/Application/Action/Client/Page/ClientReadPageAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Client\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\Client\Service\ClientFinder;
use App\Domain\Client\Service\ClientUtilFinder;
use Psr\Http\Message\ResponseInterface;
@@ -11,9 +11,9 @@
final class ClientReadPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
private readonly ClientFinder $clientFinder,
- protected readonly ClientUtilFinder $clientUtilFinder,
+ private readonly ClientUtilFinder $clientUtilFinder,
) {
}
@@ -36,7 +36,7 @@ public function __invoke(
$clientAggregate = $this->clientFinder->findClientReadAggregate((int)$args['client_id'], false);
$dropdownValues = $this->clientUtilFinder->findClientDropdownValues($clientAggregate->userId);
- return $this->responder->render(
+ return $this->templateRenderer->render(
$response,
'client/client-read.html.php',
['clientAggregate' => $clientAggregate, 'dropdownValues' => $dropdownValues]
diff --git a/src/Application/Action/Common/TranslateAction.php b/src/Application/Action/Common/TranslateAction.php
index 6aff8e81..593b4746 100644
--- a/src/Application/Action/Common/TranslateAction.php
+++ b/src/Application/Action/Common/TranslateAction.php
@@ -2,14 +2,14 @@
namespace App\Application\Action\Common;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
final class TranslateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
) {
}
@@ -34,9 +34,9 @@ public function __invoke(
$translatedStrings[$string] = __($string);
}
- return $this->responder->respondWithJson($response, $translatedStrings);
+ return $this->jsonResponder->respondWithJson($response, $translatedStrings);
}
- return $this->responder->respondWithJson($response, ['error' => 'Wrong request body format.'], 400);
+ return $this->jsonResponder->respondWithJson($response, ['error' => 'Wrong request body format.'], 400);
}
}
diff --git a/src/Application/Action/Dashboard/DashboardPageAction.php b/src/Application/Action/Dashboard/DashboardPageAction.php
index 95601c69..80736cb7 100644
--- a/src/Application/Action/Dashboard/DashboardPageAction.php
+++ b/src/Application/Action/Dashboard/DashboardPageAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Dashboard;
-use App\Application\Responder\Responder;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\Dashboard\DashboardPanelProvider;
use App\Domain\FilterSetting\FilterModule;
use App\Domain\FilterSetting\FilterSettingFinder;
@@ -13,7 +13,7 @@
final class DashboardPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
private readonly SessionInterface $session,
private readonly FilterSettingFinder $filterSettingFinder,
private readonly DashboardPanelProvider $dashboardGetter,
@@ -38,7 +38,7 @@ public function __invoke(
): ResponseInterface {
$dashboards = $this->dashboardGetter->getAuthorizedDashboards();
- return $this->responder->render(
+ return $this->templateRenderer->render(
$response,
'dashboard/dashboard.html.php',
[
diff --git a/src/Application/Action/Dashboard/DashboardTogglePanelProcessAction.php b/src/Application/Action/Dashboard/DashboardTogglePanelProcessAction.php
index ce36d8fb..fad7610c 100644
--- a/src/Application/Action/Dashboard/DashboardTogglePanelProcessAction.php
+++ b/src/Application/Action/Dashboard/DashboardTogglePanelProcessAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Dashboard;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Application\Validation\MalformedRequestBodyChecker;
use App\Domain\FilterSetting\FilterModule;
use App\Domain\FilterSetting\FilterSettingSaver;
@@ -14,7 +14,7 @@
final class DashboardTogglePanelProcessAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly SessionInterface $session,
private readonly FilterSettingSaver $filterSettingSaver,
private readonly MalformedRequestBodyChecker $malformedRequestBodyChecker,
@@ -43,7 +43,7 @@ public function __invoke(
FilterModule::DASHBOARD_PANEL
);
- return $this->responder->respondWithJson($response, ['success' => true]);
+ return $this->jsonResponder->respondWithJson($response, ['success' => true]);
}
$flash = $this->session->getFlash();
$flash->add('error', __('Malformed request body syntax. Please contact an administrator.'));
diff --git a/src/Application/Action/Dashboard/PhpDevTestAction.php b/src/Application/Action/Dashboard/PhpDevTestAction.php
index 95081768..e231acf4 100644
--- a/src/Application/Action/Dashboard/PhpDevTestAction.php
+++ b/src/Application/Action/Dashboard/PhpDevTestAction.php
@@ -2,7 +2,6 @@
namespace App\Application\Action\Dashboard;
-use App\Application\Responder\Responder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -12,7 +11,6 @@
class PhpDevTestAction
{
public function __construct(
- private readonly Responder $responder,
) {
}
@@ -30,6 +28,6 @@ public function __invoke(
ResponseInterface $response,
array $args
): ResponseInterface {
- return $this->responder->createResponse();
+ return $response;
}
}
diff --git a/src/Application/Action/Note/Ajax/NoteCreateAction.php b/src/Application/Action/Note/Ajax/NoteCreateAction.php
index 205a8811..c30383da 100644
--- a/src/Application/Action/Note/Ajax/NoteCreateAction.php
+++ b/src/Application/Action/Note/Ajax/NoteCreateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Note\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Note\Service\NoteCreator;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -10,7 +10,7 @@
final class NoteCreateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly NoteCreator $noteCreator,
) {
}
@@ -36,7 +36,7 @@ public function __invoke(
if (0 !== $noteCreationData['note_id']) {
// camelCase according to Google recommendation
- return $this->responder->respondWithJson($response, [
+ return $this->jsonResponder->respondWithJson($response, [
'status' => 'success',
'data' => [
'userFullName' => $noteCreationData['user_full_name'],
@@ -45,7 +45,7 @@ public function __invoke(
],
], 201);
}
- $response = $this->responder->respondWithJson($response, [
+ $response = $this->jsonResponder->respondWithJson($response, [
'status' => 'warning',
'message' => 'Note not created',
]);
diff --git a/src/Application/Action/Note/Ajax/NoteDeleteAction.php b/src/Application/Action/Note/Ajax/NoteDeleteAction.php
index 9c3c5f79..3e04e14a 100644
--- a/src/Application/Action/Note/Ajax/NoteDeleteAction.php
+++ b/src/Application/Action/Note/Ajax/NoteDeleteAction.php
@@ -2,19 +2,17 @@
namespace App\Application\Action\Note\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Note\Service\NoteDeleter;
use Odan\Session\SessionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
-use Psr\Log\LoggerInterface;
final class NoteDeleteAction
{
- protected LoggerInterface $logger;
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly NoteDeleter $noteDeleter,
private readonly SessionInterface $session,
) {
@@ -40,10 +38,10 @@ public function __invoke(
$deleted = $this->noteDeleter->deleteNote($noteId);
if ($deleted) {
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null]);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null]);
}
- $response = $this->responder->respondWithJson(
+ $response = $this->jsonResponder->respondWithJson(
$response,
['status' => 'warning', 'message' => 'Note not deleted.']
);
diff --git a/src/Application/Action/Note/Ajax/NoteFetchListAction.php b/src/Application/Action/Note/Ajax/NoteFetchListAction.php
index 0447183e..a243d6fb 100644
--- a/src/Application/Action/Note/Ajax/NoteFetchListAction.php
+++ b/src/Application/Action/Note/Ajax/NoteFetchListAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Note\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Note\Exception\InvalidNoteFilterException;
use App\Domain\Note\Service\NoteFilterFinder;
use Fig\Http\Message\StatusCodeInterface;
@@ -12,7 +12,7 @@
final class NoteFetchListAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly NoteFilterFinder $noteFilterFinder,
) {
}
@@ -35,7 +35,7 @@ public function __invoke(
// Retrieve notes with given filter values (or none)
$filteredNotes = $this->noteFilterFinder->findNotesWithFilter($request->getQueryParams());
} catch (InvalidNoteFilterException $invalidNoteFilterException) {
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
// Response format tested in NoteFilterProvider.php
[
@@ -46,6 +46,6 @@ public function __invoke(
);
}
- return $this->responder->respondWithJson($response, $filteredNotes);
+ return $this->jsonResponder->respondWithJson($response, $filteredNotes);
}
}
diff --git a/src/Application/Action/Note/Ajax/NoteUpdateAction.php b/src/Application/Action/Note/Ajax/NoteUpdateAction.php
index a1acf440..eb3fc528 100644
--- a/src/Application/Action/Note/Ajax/NoteUpdateAction.php
+++ b/src/Application/Action/Note/Ajax/NoteUpdateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\Note\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Note\Service\NoteUpdater;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -10,7 +10,7 @@
final class NoteUpdateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly NoteUpdater $noteUpdater,
) {
}
@@ -35,9 +35,9 @@ public function __invoke(
$updated = $this->noteUpdater->updateNote($noteIdToChange, $noteValues);
if ($updated) {
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null]);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null]);
}
- $response = $this->responder->respondWithJson($response, [
+ $response = $this->jsonResponder->respondWithJson($response, [
'status' => 'warning',
'message' => 'The note was not updated.',
]);
diff --git a/src/Application/Action/Note/Page/NoteReadPageAction.php b/src/Application/Action/Note/Page/NoteReadPageAction.php
index abe61247..078a7d23 100644
--- a/src/Application/Action/Note/Page/NoteReadPageAction.php
+++ b/src/Application/Action/Note/Page/NoteReadPageAction.php
@@ -2,16 +2,18 @@
namespace App\Application\Action\Note\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\RedirectHandler;
use App\Domain\Note\Service\NoteFinder;
use Odan\Session\SessionInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
+use Slim\Interfaces\RouteParserInterface;
final class NoteReadPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly RedirectHandler $redirectHandler,
+ private readonly RouteParserInterface $routeParser,
private readonly NoteFinder $noteFinder,
private readonly SessionInterface $session,
) {
@@ -34,9 +36,9 @@ public function __invoke(
$noteData = $this->noteFinder->findNote((int)$args['note_id']);
if ($noteData->id) {
// Redirect to client read page with hash anchor to the correct note container
- return $this->responder->redirectToUrl(
+ return $this->redirectHandler->redirectToUrl(
$response,
- $this->responder->urlFor('client-read-page', ['client_id' => (string)$noteData->clientId]) .
+ $this->routeParser->urlFor('client-read-page', ['client_id' => (string)$noteData->clientId]) .
"#note-$noteData->id-container"
);
}
@@ -45,6 +47,6 @@ public function __invoke(
$flash->add('error', __('The note was not not found.'));
// When note does not exist link to client list page
- return $this->responder->redirectToRouteName($response, 'client-list-page');
+ return $this->redirectHandler->redirectToRouteName($response, 'client-list-page');
}
}
diff --git a/src/Application/Action/User/Ajax/FetchDropdownOptionsForUserCreateAction.php b/src/Application/Action/User/Ajax/FetchDropdownOptionsForUserCreateAction.php
index 04dd4b33..2b448c4d 100644
--- a/src/Application/Action/User/Ajax/FetchDropdownOptionsForUserCreateAction.php
+++ b/src/Application/Action/User/Ajax/FetchDropdownOptionsForUserCreateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\User\Service\UserUtilFinder;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -10,7 +10,7 @@
class FetchDropdownOptionsForUserCreateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly UserUtilFinder $userUtilFinder,
) {
}
@@ -31,6 +31,6 @@ public function __invoke(
): ResponseInterface {
$dropdownOptions = $this->userUtilFinder->findUserDropdownValues();
- return $this->responder->respondWithJson($response, $dropdownOptions);
+ return $this->jsonResponder->respondWithJson($response, $dropdownOptions);
}
}
diff --git a/src/Application/Action/User/Ajax/PasswordChangeSubmitAction.php b/src/Application/Action/User/Ajax/PasswordChangeSubmitAction.php
index 58eb34ba..db1e7127 100644
--- a/src/Application/Action/User/Ajax/PasswordChangeSubmitAction.php
+++ b/src/Application/Action/User/Ajax/PasswordChangeSubmitAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Authentication\Service\PasswordChanger;
use Odan\Session\SessionInterface;
use Odan\Session\SessionManagerInterface;
@@ -15,8 +15,8 @@
class PasswordChangeSubmitAction
{
public function __construct(
- private readonly Responder $responder,
- protected readonly SessionManagerInterface $sessionManager,
+ private readonly JsonResponder $jsonResponder,
+ private readonly SessionManagerInterface $sessionManager,
private readonly SessionInterface $session,
private readonly PasswordChanger $passwordChanger
) {
@@ -43,6 +43,6 @@ public function __invoke(ServerRequest $request, Response $response, array $args
$this->sessionManager->regenerateId();
}
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null]);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null]);
}
}
diff --git a/src/Application/Action/User/Ajax/UserActivityFetchListAction.php b/src/Application/Action/User/Ajax/UserActivityFetchListAction.php
index a6a1eccd..8cd6a078 100644
--- a/src/Application/Action/User/Ajax/UserActivityFetchListAction.php
+++ b/src/Application/Action/User/Ajax/UserActivityFetchListAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\FilterSetting\FilterModule;
use App\Domain\FilterSetting\FilterSettingSaver;
use App\Domain\UserActivity\Service\UserActivityFinder;
@@ -12,7 +12,7 @@
class UserActivityFetchListAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly UserActivityFinder $userActivityFinder,
private readonly FilterSettingSaver $filterSettingSaver,
) {
@@ -47,6 +47,6 @@ public function __invoke(
);
}
- return $this->responder->respondWithJson($response, $userResultDataArray);
+ return $this->jsonResponder->respondWithJson($response, $userResultDataArray);
}
}
diff --git a/src/Application/Action/User/Ajax/UserCreateAction.php b/src/Application/Action/User/Ajax/UserCreateAction.php
index fdc13965..c1ed9933 100644
--- a/src/Application/Action/User/Ajax/UserCreateAction.php
+++ b/src/Application/Action/User/Ajax/UserCreateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\User\Service\UserCreator;
use Odan\Session\SessionInterface;
use Psr\Http\Message\ResponseInterface as Response;
@@ -14,8 +14,8 @@ final class UserCreateAction
{
public function __construct(
private readonly LoggerInterface $logger,
- protected Responder $responder,
- protected UserCreator $userCreator,
+ private readonly JsonResponder $jsonResponder,
+ private readonly UserCreator $userCreator,
private readonly SessionInterface $session,
) {
}
@@ -45,12 +45,12 @@ public function __invoke(ServerRequest $request, Response $response): Response
$response = $response->withAddedHeader('Warning', 'The post could not be created');
}
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null], 201);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null], 201);
} catch (TransportExceptionInterface $e) {
// Flash message has to be added in the frontend as form is submitted via Ajax
$this->logger->error('Mailer exception: ' . $e->getMessage());
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
['status' => 'error', 'message' => __('Email error. Please contact an administrator.')]
);
diff --git a/src/Application/Action/User/Ajax/UserDeleteAction.php b/src/Application/Action/User/Ajax/UserDeleteAction.php
index cb21f2cd..2f1cd624 100644
--- a/src/Application/Action/User/Ajax/UserDeleteAction.php
+++ b/src/Application/Action/User/Ajax/UserDeleteAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\User\Service\UserDeleter;
use Odan\Session\SessionInterface;
use Odan\Session\SessionManagerInterface;
@@ -12,7 +12,7 @@
final class UserDeleteAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly UserDeleter $userDeleter,
private readonly SessionManagerInterface $sessionManager,
private readonly SessionInterface $session,
@@ -58,10 +58,10 @@ public function __invoke(
);
}
- return $this->responder->respondWithJson($response, ['status' => 'success']);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success']);
}
- $response = $this->responder->respondWithJson(
+ $response = $this->jsonResponder->respondWithJson(
$response,
// response json body asserted in UserDeleteActionTest
['status' => 'warning', 'message' => 'User not deleted.']
diff --git a/src/Application/Action/User/Ajax/UserFetchListAction.php b/src/Application/Action/User/Ajax/UserFetchListAction.php
index 7cfc2e4a..0b8cfca2 100644
--- a/src/Application/Action/User/Ajax/UserFetchListAction.php
+++ b/src/Application/Action/User/Ajax/UserFetchListAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\User\Enum\UserStatus;
use App\Domain\User\Service\UserFinder;
use Psr\Http\Message\ResponseInterface;
@@ -11,8 +11,8 @@
final class UserFetchListAction
{
public function __construct(
- private readonly Responder $responder,
- protected readonly UserFinder $userFinder,
+ private readonly JsonResponder $jsonResponder,
+ private readonly UserFinder $userFinder,
) {
}
@@ -36,7 +36,7 @@ public function __invoke(
// $clientResultCollection = $this->clientFilterFinder->findClientsWithFilter($request->getQueryParams());
$userResultDataArray = $this->userFinder->findAllUsersResultDataForList();
- return $this->responder->respondWithJson($response, [
+ return $this->jsonResponder->respondWithJson($response, [
'userResultDataArray' => $userResultDataArray,
'statuses' => UserStatus::toTranslatedNamesArray(),
]);
diff --git a/src/Application/Action/User/Ajax/UserUpdateAction.php b/src/Application/Action/User/Ajax/UserUpdateAction.php
index 2762c92e..c3d16ee1 100644
--- a/src/Application/Action/User/Ajax/UserUpdateAction.php
+++ b/src/Application/Action/User/Ajax/UserUpdateAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Ajax;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\User\Service\UserUpdater;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -10,7 +10,7 @@
final class UserUpdateAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
private readonly UserUpdater $userUpdater,
) {
}
@@ -35,11 +35,11 @@ public function __invoke(
$updated = $this->userUpdater->updateUser($userIdToChange, $userValuesToChange);
if ($updated) {
- return $this->responder->respondWithJson($response, ['status' => 'success', 'data' => null]);
+ return $this->jsonResponder->respondWithJson($response, ['status' => 'success', 'data' => null]);
}
// If for example values didn't change
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
['status' => 'warning', 'message' => 'User wasn\'t updated']
);
diff --git a/src/Application/Action/User/Page/UserListPageAction.php b/src/Application/Action/User/Page/UserListPageAction.php
index 8cc3272c..4181d197 100644
--- a/src/Application/Action/User/Page/UserListPageAction.php
+++ b/src/Application/Action/User/Page/UserListPageAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\User\Authorization\UserAuthorizationChecker;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
@@ -11,7 +11,7 @@
final class UserListPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
private readonly UserAuthorizationChecker $userAuthorizationChecker,
) {
}
@@ -23,9 +23,6 @@ public function __construct(
* @param ResponseInterface $response The response
* @param array $args
*
- * @throws \JsonException
- * @throws \Throwable
- *
* @return ResponseInterface The response
*/
public function __invoke(
@@ -34,7 +31,7 @@ public function __invoke(
array $args
): ResponseInterface {
if ($this->userAuthorizationChecker->isGrantedToRead()) {
- return $this->responder->render($response, 'user/user-list.html.php');
+ return $this->templateRenderer->render($response, 'user/user-list.html.php');
}
throw new HttpForbiddenException($request, 'Not allowed to see this page.');
diff --git a/src/Application/Action/User/Page/UserReadPageAction.php b/src/Application/Action/User/Page/UserReadPageAction.php
index 064f5450..5b705701 100644
--- a/src/Application/Action/User/Page/UserReadPageAction.php
+++ b/src/Application/Action/User/Page/UserReadPageAction.php
@@ -2,7 +2,7 @@
namespace App\Application\Action\User\Page;
-use App\Application\Responder\Responder;
+use App\Application\Responder\TemplateRenderer;
use App\Domain\Exception\DomainRecordNotFoundException;
use App\Domain\User\Enum\UserStatus;
use App\Domain\User\Service\UserFinder;
@@ -14,7 +14,7 @@
final class UserReadPageAction
{
public function __construct(
- private readonly Responder $responder,
+ private readonly TemplateRenderer $templateRenderer,
private readonly UserFinder $userFinder,
private readonly SessionInterface $session,
) {
@@ -38,7 +38,7 @@ public function __invoke(
$userId = (int)($args['user_id'] ?? $authenticatedUserId);
try {
// Retrieve user infos
- return $this->responder->render($response, 'user/user-read.html.php', [
+ return $this->templateRenderer->render($response, 'user/user-read.html.php', [
'user' => $this->userFinder->findUserReadResult($userId),
'isOwnProfile' => $userId === $authenticatedUserId,
// Get all user status cases as enums
diff --git a/src/Application/Middleware/ForbiddenExceptionMiddleware.php b/src/Application/Middleware/ForbiddenExceptionMiddleware.php
index d1d77419..84bfe1ed 100644
--- a/src/Application/Middleware/ForbiddenExceptionMiddleware.php
+++ b/src/Application/Middleware/ForbiddenExceptionMiddleware.php
@@ -2,9 +2,10 @@
namespace App\Application\Middleware;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Authentication\Exception\ForbiddenException;
use Fig\Http\Message\StatusCodeInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
@@ -13,7 +14,8 @@
class ForbiddenExceptionMiddleware implements MiddlewareInterface
{
public function __construct(
- private readonly Responder $responder,
+ private readonly ResponseFactoryInterface $responseFactory,
+ private readonly JsonResponder $jsonResponder,
) {
}
@@ -23,9 +25,9 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $handler->handle($request);
} catch (ForbiddenException $forbiddenException) {
// Create response (status code and header are added later)
- $response = $this->responder->createResponse();
+ $response = $this->responseFactory->createResponse();
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
[
'status' => 'error',
diff --git a/src/Application/Middleware/InvalidOperationExceptionMiddleware.php b/src/Application/Middleware/InvalidOperationExceptionMiddleware.php
index 0d707f84..1efb955a 100644
--- a/src/Application/Middleware/InvalidOperationExceptionMiddleware.php
+++ b/src/Application/Middleware/InvalidOperationExceptionMiddleware.php
@@ -3,9 +3,10 @@
namespace App\Application\Middleware;
use App\Application\Data\UserNetworkSessionData;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Exception\InvalidOperationException;
use Fig\Http\Message\StatusCodeInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
@@ -15,7 +16,8 @@
class InvalidOperationExceptionMiddleware implements MiddlewareInterface
{
public function __construct(
- private readonly Responder $responder,
+ private readonly ResponseFactoryInterface $responseFactory,
+ private readonly JsonResponder $jsonResponder,
private readonly UserNetworkSessionData $userNetworkSessionData,
private readonly LoggerInterface $logger,
) {
@@ -26,14 +28,14 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
try {
return $handler->handle($request);
} catch (InvalidOperationException $exception) {
- $response = $this->responder->createResponse();
+ $response = $this->responseFactory->createResponse();
$this->logger->notice(
'Invalid operation from user ' . $this->userNetworkSessionData->userId . ' on ' .
$request->getUri()->getPath() . ' with message: ' . $exception->getMessage()
);
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
[
'status' => 'error',
diff --git a/src/Application/Middleware/UserAuthenticationMiddleware.php b/src/Application/Middleware/UserAuthenticationMiddleware.php
index 7c3df4c1..777adfae 100644
--- a/src/Application/Middleware/UserAuthenticationMiddleware.php
+++ b/src/Application/Middleware/UserAuthenticationMiddleware.php
@@ -2,22 +2,28 @@
namespace App\Application\Middleware;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
+use App\Application\Responder\RedirectHandler;
use App\Domain\User\Enum\UserStatus;
use App\Domain\User\Service\UserFinder;
use Odan\Session\SessionInterface;
use Odan\Session\SessionManagerInterface;
+use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;
+use Slim\Interfaces\RouteParserInterface;
final class UserAuthenticationMiddleware implements MiddlewareInterface
{
public function __construct(
private readonly SessionManagerInterface $sessionManager,
private readonly SessionInterface $session,
- private readonly Responder $responder,
+ private readonly JsonResponder $jsonResponder,
+ private readonly RedirectHandler $redirectHandler,
+ private readonly RouteParserInterface $routeParser,
+ private readonly ResponseFactoryInterface $responseFactory,
private readonly UserFinder $userFinder,
) {
}
@@ -47,7 +53,7 @@ public function process(
$this->sessionManager->regenerateId();
}
- $response = $this->responder->createResponse();
+ $response = $this->responseFactory->createResponse();
// Inform user that he/she has to login first
$this->session->getFlash()->add('info', 'Please login to access this page.');
@@ -56,7 +62,7 @@ public function process(
// If header Redirect-to-route-name-if-unauthorized is set, add it to the query params of the login route
if (($routeName = $request->getHeaderLine('Redirect-to-route-name-if-unauthorized')) !== '') {
// Redirect to after login
- $queryParams['redirect'] = $this->responder->urlFor($routeName);
+ $queryParams['redirect'] = $this->routeParser->urlFor($routeName);
}
// If header Redirect-to-route-name-if-unauthorized is set, add it to the query params of the login route
if (($routeName = $request->getHeaderLine('Redirect-to-url-if-unauthorized')) !== '') {
@@ -66,15 +72,15 @@ public function process(
// If it's a JSON request return 401 with the login url and its possible query params
if ($request->getHeaderLine('Content-Type') === 'application/json') {
- return $this->responder->respondWithJson(
+ return $this->jsonResponder->respondWithJson(
$response,
- ['loginUrl' => $this->responder->urlFor('login-page', [], $queryParams)],
+ ['loginUrl' => $this->routeParser->urlFor('login-page', [], $queryParams)],
401
);
}
// If no redirect header is set, and it's not a JSON request, redirect to same url as the request after login
$queryParams = ['redirect' => $request->getUri()->getPath()];
- return $this->responder->redirectToRouteName($response, 'login-page', [], $queryParams);
+ return $this->redirectHandler->redirectToRouteName($response, 'login-page', [], $queryParams);
}
}
diff --git a/src/Application/Middleware/ValidationExceptionMiddleware.php b/src/Application/Middleware/ValidationExceptionMiddleware.php
index 4dd4e9bb..ffc74fd2 100644
--- a/src/Application/Middleware/ValidationExceptionMiddleware.php
+++ b/src/Application/Middleware/ValidationExceptionMiddleware.php
@@ -2,8 +2,9 @@
namespace App\Application\Middleware;
-use App\Application\Responder\Responder;
+use App\Application\Responder\JsonResponder;
use App\Domain\Validation\ValidationException;
+use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
@@ -12,7 +13,8 @@
class ValidationExceptionMiddleware implements MiddlewareInterface
{
public function __construct(
- private readonly Responder $responder,
+ private readonly ResponseFactoryInterface $responseFactory,
+ private readonly JsonResponder $jsonResponder,
) {
}
@@ -22,7 +24,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
return $handler->handle($request);
} catch (ValidationException $validationException) {
// Create response (status code and header are added later)
- $response = $this->responder->createResponse();
+ $response = $this->responseFactory->createResponse();
$responseData = [
'status' => 'error',
@@ -31,7 +33,7 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
'data' => ['errors' => $validationException->validationErrors],
];
- return $this->responder->respondWithJson($response, $responseData, 422);
+ return $this->jsonResponder->respondWithJson($response, $responseData, 422);
}
}
}
diff --git a/src/Application/Responder/JsonResponder.php b/src/Application/Responder/JsonResponder.php
new file mode 100644
index 00000000..59d47fad
--- /dev/null
+++ b/src/Application/Responder/JsonResponder.php
@@ -0,0 +1,32 @@
+getBody()->write((string)json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR));
+ $response = $response->withStatus($status);
+
+ return $response->withHeader('Content-Type', 'application/json');
+ }
+}
\ No newline at end of file
diff --git a/src/Application/Responder/RedirectHandler.php b/src/Application/Responder/RedirectHandler.php
new file mode 100644
index 00000000..fd5b58d7
--- /dev/null
+++ b/src/Application/Responder/RedirectHandler.php
@@ -0,0 +1,68 @@
+routeParser = $routeParser;
+ }
+ /**
+ * Creates a redirect for the given url.
+ *
+ * This method prepares the response object to return an HTTP Redirect
+ * response to the client.
+ *
+ * @param ResponseInterface $response The response
+ * @param string $destination The redirect destination (url or route name)
+ * @param array $queryParams Optional query string parameters
+ *
+ * @return ResponseInterface The response
+ */
+ public function redirectToUrl(
+ ResponseInterface $response,
+ string $destination,
+ array $queryParams = []
+ ): ResponseInterface {
+ if ($queryParams) {
+ $destination = sprintf('%s?%s', $destination, http_build_query($queryParams));
+ }
+
+ return $response->withStatus(302)->withHeader('Location', $destination);
+ }
+
+ /**
+ * Creates a redirect for the given route name.
+ *
+ * This method prepares the response object to return an HTTP Redirect
+ * response to the client.
+ *
+ * @param ResponseInterface $response The response
+ * @param string $routeName The redirect route name
+ * @param array $data Named argument replacement data
+ * @param array $queryParams Optional query string parameters
+ *
+ * @return ResponseInterface The response
+ */
+ public function redirectToRouteName(
+ ResponseInterface $response,
+ string $routeName,
+ array $data = [],
+ array $queryParams = []
+ ): ResponseInterface {
+ return $this->redirectToUrl($response, $this->routeParser->urlFor($routeName, $data, $queryParams));
+ }
+
+}
diff --git a/src/Application/Responder/Responder.php b/src/Application/Responder/Responder.php
deleted file mode 100644
index 400caabb..00000000
--- a/src/Application/Responder/Responder.php
+++ /dev/null
@@ -1,236 +0,0 @@
-responseFactory->createResponse()->withHeader('Content-Type', 'text/html; charset=utf-8');
- }
-
- /**
- * Output rendered template.
- *
- * @param ResponseInterface $response The response
- * @param string $template Template pathname relative to templates directory
- * @param array $data Associative array of template variables
- *
- * @return ResponseInterface The response
- */
- public function render(
- ResponseInterface $response,
- string $template,
- array $data = []
- ): ResponseInterface {
- return $this->phpRenderer->render($response, $template, $data);
- }
-
- /**
- * Add global variable accessible in templates.
- *
- * @param string $key
- * @param mixed $value
- *
- * @return void
- */
- public function addPhpViewAttribute(string $key, mixed $value): void
- {
- $this->phpRenderer->addAttribute($key, $value);
- }
-
- /**
- * Creates a redirect for the given url.
- *
- * This method prepares the response object to return an HTTP Redirect
- * response to the client.
- *
- * @param ResponseInterface $response The response
- * @param string $destination The redirect destination (url or route name)
- * @param array $queryParams Optional query string parameters
- *
- * @return ResponseInterface The response
- */
- public function redirectToUrl(
- ResponseInterface $response,
- string $destination,
- array $queryParams = []
- ): ResponseInterface {
- if ($queryParams) {
- $destination = sprintf('%s?%s', $destination, http_build_query($queryParams));
- }
-
- return $response->withStatus(302)->withHeader('Location', $destination);
- }
-
- /**
- * Creates a redirect for the given route name.
- *
- * This method prepares the response object to return an HTTP Redirect
- * response to the client.
- *
- * @param ResponseInterface $response The response
- * @param string $routeName The redirect route name
- * @param array $data Named argument replacement data
- * @param array $queryParams Optional query string parameters
- *
- * @return ResponseInterface The response
- */
- public function redirectToRouteName(
- ResponseInterface $response,
- string $routeName,
- array $data = [],
- array $queryParams = []
- ): ResponseInterface {
- return $this->redirectToUrl($response, $this->routeParser->urlFor($routeName, $data, $queryParams));
- }
-
- /**
- * Build the path for a named route including the base path.
- *
- * @param string $routeName Route name
- * @param array $data Named argument replacement data
- * @param array $queryParams Optional query string parameters
- *
- * @return string
- */
- public function urlFor(string $routeName, array $data = [], array $queryParams = []): string
- {
- return $this->routeParser->urlFor($routeName, $data, $queryParams);
- }
-
- /**
- * Render template with validation errors.
- *
- * @param ResponseInterface $response
- * @param string $template
- * @param ValidationException $validationException
- * @param array $queryParams same query params passed to page to be added again to form after validation error
- * @param array|null $preloadValues
- *
- * @return ResponseInterface
- */
- public function renderOnValidationError(
- ResponseInterface $response,
- string $template,
- ValidationException $validationException,
- array $queryParams = [],
- ?array $preloadValues = null,
- ): ResponseInterface {
- $this->phpRenderer->addAttribute('preloadValues', $preloadValues);
-
- // Add the validation errors to phpRender attributes
- $this->phpRenderer->addAttribute('validation', $validationException->validationErrors);
- $this->phpRenderer->addAttribute('formError', true);
- // Provide same query params passed to page to be added again after validation error (e.g. redirect)
- $this->phpRenderer->addAttribute('queryParams', $queryParams);
-
- // Render template with status code
- return $this->render($response->withStatus(422), $template);
- }
-
- /**
- * Respond with delay user has to wait or action that needs to be made before repeating the action.
- *
- * @param ResponseInterface $response
- * @param int|string $remainingDelay
- * @param string $template
- * @param array|null $preloadValues
- * @param array $queryParams same query params passed to page to be added again to form after validation error
- *
- * @throws \Throwable
- *
- * @return ResponseInterface
- */
- public function respondWithThrottle(
- ResponseInterface $response,
- int|string $remainingDelay,
- string $template,
- ?array $preloadValues = null,
- array $queryParams = []
- ): ResponseInterface {
- $this->phpRenderer->addAttribute('throttleDelay', $remainingDelay);
- $this->phpRenderer->addAttribute('preloadValues', $preloadValues);
- $this->phpRenderer->addAttribute('formError', true);
- // Provide same query params passed to page to be added again after validation error (e.g. redirect)
- $this->phpRenderer->addAttribute('queryParams', $queryParams);
-
- return $this->render($response->withStatus(422), $template);
- }
-
- /**
- * Respond with delay user has to wait or action that needs to be made before repeating the action.
- * Specifically for form errors.
- *
- * @param ResponseInterface $response
- * @param string $template
- * @param SecurityException $securityException
- * @param array|null $preloadValues
- * @param array $queryParams same query params passed to page to be added again to form after validation error
- *
- * @throws \Throwable
- *
- * @return ResponseInterface
- */
- public function respondWithFormThrottle(
- ResponseInterface $response,
- string $template,
- SecurityException $securityException,
- array $queryParams = [],
- ?array $preloadValues = null,
- ): ResponseInterface {
- $this->phpRenderer->addAttribute('throttleDelay', $securityException->getRemainingDelay());
- $this->phpRenderer->addAttribute('formErrorMessage', $securityException->getPublicMessage());
- $this->phpRenderer->addAttribute('preloadValues', $preloadValues);
- $this->phpRenderer->addAttribute('formError', true);
-
- // Provide same query params passed to page to be added again after validation error (e.g. redirect)
- $this->phpRenderer->addAttribute('queryParams', $queryParams);
-
- return $this->render($response->withStatus(422), $template);
- }
-
- /**
- * Write JSON to the response body.
- *
- * This method prepares the response object to return an HTTP JSON
- * response to the client.
- *
- * @param ResponseInterface $response The response
- * @param mixed $data The data
- * @param int $status
- *
- * @return ResponseInterface The response
- */
- public function respondWithJson(
- ResponseInterface $response,
- mixed $data = null,
- int $status = 200
- ): ResponseInterface {
- $response->getBody()->write((string)json_encode($data, JSON_UNESCAPED_SLASHES | JSON_PARTIAL_OUTPUT_ON_ERROR));
- $response = $response->withStatus($status);
-
- return $response->withHeader('Content-Type', 'application/json');
- }
-}
diff --git a/src/Application/Responder/TemplateRenderer.php b/src/Application/Responder/TemplateRenderer.php
new file mode 100644
index 00000000..df9fa749
--- /dev/null
+++ b/src/Application/Responder/TemplateRenderer.php
@@ -0,0 +1,111 @@
+phpRenderer->render($response, $template, $data);
+ }
+
+ /**
+ * Add global variable accessible in templates.
+ *
+ * @param string $key
+ * @param mixed $value
+ *
+ * @return void
+ */
+ public function addPhpViewAttribute(string $key, mixed $value): void
+ {
+ $this->phpRenderer->addAttribute($key, $value);
+ }
+
+ /**
+ * Render template with validation errors.
+ *
+ * @param ResponseInterface $response
+ * @param string $template
+ * @param ValidationException $validationException
+ * @param array $queryParams same query params passed to page to be added again to form after validation error
+ * @param array|null $preloadValues
+ *
+ * @return ResponseInterface
+ */
+ public function renderOnValidationError(
+ ResponseInterface $response,
+ string $template,
+ ValidationException $validationException,
+ array $queryParams = [],
+ ?array $preloadValues = null,
+ ): ResponseInterface {
+ $this->phpRenderer->addAttribute('preloadValues', $preloadValues);
+
+ // Add the validation errors to phpRender attributes
+ $this->phpRenderer->addAttribute('validation', $validationException->validationErrors);
+ $this->phpRenderer->addAttribute('formError', true);
+ // Provide same query params passed to page to be added again after validation error (e.g. redirect)
+ $this->phpRenderer->addAttribute('queryParams', $queryParams);
+
+ // Render template with status code
+ return $this->render($response->withStatus(422), $template);
+ }
+
+
+ /**
+ * Respond with delay user has to wait or action that needs to be made before repeating the action.
+ * Specifically for form errors.
+ *
+ * @param ResponseInterface $response
+ * @param string $template
+ * @param SecurityException $securityException
+ * @param array|null $preloadValues
+ * @param array $queryParams same query params passed to page to be added again to form after validation error
+ *
+ * @return ResponseInterface
+ * @throws \Throwable
+ *
+ */
+ public function respondWithFormThrottle(
+ ResponseInterface $response,
+ string $template,
+ SecurityException $securityException,
+ array $queryParams = [],
+ ?array $preloadValues = null,
+ ): ResponseInterface {
+ $this->phpRenderer->addAttribute('throttleDelay', $securityException->getRemainingDelay());
+ $this->phpRenderer->addAttribute('formErrorMessage', $securityException->getPublicMessage());
+ $this->phpRenderer->addAttribute('preloadValues', $preloadValues);
+ $this->phpRenderer->addAttribute('formError', true);
+
+ // Provide same query params passed to page to be added again after validation error (e.g. redirect)
+ $this->phpRenderer->addAttribute('queryParams', $queryParams);
+
+ return $this->render($response->withStatus(422), $template);
+ }
+}
\ No newline at end of file