From 68421d2a5da114ffe334b7782700ac50900b2485 Mon Sep 17 00:00:00 2001 From: James Read Date: Thu, 29 Feb 2024 21:37:03 +0800 Subject: [PATCH 1/8] Bumping PHP Version Bumping PHP versionn to 8.3 --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 2110c07b..d3d54326 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": "^7.4 || ^8.0", + "php": "^8.3", "ext-json": "*", "monolog/monolog": "^2.9", "php-di/php-di": "^6.4", From b703cf162cbfe758ba700021646924d54c2237bc Mon Sep 17 00:00:00 2001 From: James Read Date: Thu, 29 Feb 2024 21:45:42 +0800 Subject: [PATCH 2/8] Constructor property promotion changing constructors to user new syntax where it makes sense --- src/Application/Actions/Action.php | 10 +++--- src/Application/Actions/ActionError.php | 34 +++--------------- src/Application/Actions/ActionPayload.php | 36 ++----------------- src/Application/Actions/User/UserAction.php | 9 +++-- src/Application/Handlers/HttpErrorHandler.php | 23 ++++++------ src/Application/Handlers/ShutdownHandler.php | 12 ++----- src/Application/Settings/Settings.php | 7 ++-- src/Domain/User/User.php | 11 +++--- 8 files changed, 40 insertions(+), 102 deletions(-) diff --git a/src/Application/Actions/Action.php b/src/Application/Actions/Action.php index 1021c202..ebd4f190 100644 --- a/src/Application/Actions/Action.php +++ b/src/Application/Actions/Action.php @@ -13,17 +13,17 @@ abstract class Action { - protected LoggerInterface $logger; - protected Request $request; protected Response $response; + /** + * @var array + */ protected array $args; - public function __construct(LoggerInterface $logger) + public function __construct(protected LoggerInterface $logger) { - $this->logger = $logger; } /** @@ -87,6 +87,6 @@ protected function respond(ActionPayload $payload): Response return $this->response ->withHeader('Content-Type', 'application/json') - ->withStatus($payload->getStatusCode()); + ->withStatus($payload->statusCode); } } diff --git a/src/Application/Actions/ActionError.php b/src/Application/Actions/ActionError.php index 3a81cc53..8b36f36c 100644 --- a/src/Application/Actions/ActionError.php +++ b/src/Application/Actions/ActionError.php @@ -18,36 +18,10 @@ class ActionError implements JsonSerializable public const VALIDATION_ERROR = 'VALIDATION_ERROR'; public const VERIFICATION_ERROR = 'VERIFICATION_ERROR'; - private string $type; - - private ?string $description; - - public function __construct(string $type, ?string $description = null) - { - $this->type = $type; - $this->description = $description; - } - - public function getType(): string - { - return $this->type; - } - - public function setType(string $type): self - { - $this->type = $type; - return $this; - } - - public function getDescription(): ?string - { - return $this->description; - } - - public function setDescription(?string $description = null): self - { - $this->description = $description; - return $this; + public function __construct( + public readonly string $type, + public readonly ?string $description = null + ) { } #[\ReturnTypeWillChange] diff --git a/src/Application/Actions/ActionPayload.php b/src/Application/Actions/ActionPayload.php index cbf51104..6137e4a2 100644 --- a/src/Application/Actions/ActionPayload.php +++ b/src/Application/Actions/ActionPayload.php @@ -8,41 +8,11 @@ class ActionPayload implements JsonSerializable { - private int $statusCode; - - /** - * @var array|object|null - */ - private $data; - - private ?ActionError $error; - public function __construct( - int $statusCode = 200, - $data = null, - ?ActionError $error = null + public readonly int $statusCode = 200, + public readonly array|object|null $data = null, + public ?ActionError $error = null ) { - $this->statusCode = $statusCode; - $this->data = $data; - $this->error = $error; - } - - public function getStatusCode(): int - { - return $this->statusCode; - } - - /** - * @return array|null|object - */ - public function getData() - { - return $this->data; - } - - public function getError(): ?ActionError - { - return $this->error; } #[\ReturnTypeWillChange] diff --git a/src/Application/Actions/User/UserAction.php b/src/Application/Actions/User/UserAction.php index 4ea2d8ca..dbc7ae8f 100644 --- a/src/Application/Actions/User/UserAction.php +++ b/src/Application/Actions/User/UserAction.php @@ -10,11 +10,10 @@ abstract class UserAction extends Action { - protected UserRepository $userRepository; - - public function __construct(LoggerInterface $logger, UserRepository $userRepository) - { + public function __construct( + LoggerInterface $logger, + protected UserRepository $userRepository + ) { parent::__construct($logger); - $this->userRepository = $userRepository; } } diff --git a/src/Application/Handlers/HttpErrorHandler.php b/src/Application/Handlers/HttpErrorHandler.php index 64e02b1e..275bbad9 100644 --- a/src/Application/Handlers/HttpErrorHandler.php +++ b/src/Application/Handlers/HttpErrorHandler.php @@ -26,27 +26,25 @@ protected function respond(): Response { $exception = $this->exception; $statusCode = 500; - $error = new ActionError( - ActionError::SERVER_ERROR, - 'An internal error has occurred while processing your request.' - ); + $errorType = ActionError::SERVER_ERROR; + $description = 'An internal error has occurred while processing your request.'; if ($exception instanceof HttpException) { $statusCode = $exception->getCode(); - $error->setDescription($exception->getMessage()); + $description = $exception->getMessage(); if ($exception instanceof HttpNotFoundException) { - $error->setType(ActionError::RESOURCE_NOT_FOUND); + $errorType = ActionError::RESOURCE_NOT_FOUND; } elseif ($exception instanceof HttpMethodNotAllowedException) { - $error->setType(ActionError::NOT_ALLOWED); + $errorType = ActionError::NOT_ALLOWED; } elseif ($exception instanceof HttpUnauthorizedException) { - $error->setType(ActionError::UNAUTHENTICATED); + $errorType = ActionError::UNAUTHENTICATED; } elseif ($exception instanceof HttpForbiddenException) { - $error->setType(ActionError::INSUFFICIENT_PRIVILEGES); + $errorType = ActionError::INSUFFICIENT_PRIVILEGES; } elseif ($exception instanceof HttpBadRequestException) { - $error->setType(ActionError::BAD_REQUEST); + $errorType = ActionError::BAD_REQUEST; } elseif ($exception instanceof HttpNotImplementedException) { - $error->setType(ActionError::NOT_IMPLEMENTED); + $errorType = ActionError::NOT_IMPLEMENTED; } } @@ -55,9 +53,10 @@ protected function respond(): Response && $exception instanceof Throwable && $this->displayErrorDetails ) { - $error->setDescription($exception->getMessage()); + $description = $exception->getMessage(); } + $error = new ActionError($errorType, $description); $payload = new ActionPayload($statusCode, null, $error); $encodedPayload = json_encode($payload, JSON_PRETTY_PRINT); diff --git a/src/Application/Handlers/ShutdownHandler.php b/src/Application/Handlers/ShutdownHandler.php index 72b6d46e..20cecbdb 100644 --- a/src/Application/Handlers/ShutdownHandler.php +++ b/src/Application/Handlers/ShutdownHandler.php @@ -10,16 +10,10 @@ class ShutdownHandler { - private Request $request; - - private HttpErrorHandler $errorHandler; - - private bool $displayErrorDetails; - public function __construct( - Request $request, - HttpErrorHandler $errorHandler, - bool $displayErrorDetails + private Request $request, + private HttpErrorHandler $errorHandler, + private bool $displayErrorDetails ) { $this->request = $request; $this->errorHandler = $errorHandler; diff --git a/src/Application/Settings/Settings.php b/src/Application/Settings/Settings.php index 6da55e4e..09318f8e 100644 --- a/src/Application/Settings/Settings.php +++ b/src/Application/Settings/Settings.php @@ -6,9 +6,10 @@ class Settings implements SettingsInterface { - private array $settings; - - public function __construct(array $settings) + /** + * @param array $settings + */ + public function __construct(private array $settings) { $this->settings = $settings; } diff --git a/src/Domain/User/User.php b/src/Domain/User/User.php index 217bb9eb..8bbf7cd7 100644 --- a/src/Domain/User/User.php +++ b/src/Domain/User/User.php @@ -8,17 +8,18 @@ class User implements JsonSerializable { - private ?int $id; - private string $username; private string $firstName; private string $lastName; - public function __construct(?int $id, string $username, string $firstName, string $lastName) - { - $this->id = $id; + public function __construct( + private readonly int|null $id, + string $username, + string $firstName, + string $lastName + ) { $this->username = strtolower($username); $this->firstName = ucfirst($firstName); $this->lastName = ucfirst($lastName); From f2a6c52cd8d7965c1bf8d96e0211517b8f2ed3d0 Mon Sep 17 00:00:00 2001 From: James Read Date: Thu, 29 Feb 2024 22:18:16 +0800 Subject: [PATCH 3/8] replace if else with match using match to get get error message --- src/Application/Handlers/ShutdownHandler.php | 18 +++++------------- 1 file changed, 5 insertions(+), 13 deletions(-) diff --git a/src/Application/Handlers/ShutdownHandler.php b/src/Application/Handlers/ShutdownHandler.php index 20cecbdb..e3615242 100644 --- a/src/Application/Handlers/ShutdownHandler.php +++ b/src/Application/Handlers/ShutdownHandler.php @@ -52,18 +52,10 @@ private function getErrorMessage(array $error): string $errorMessage = $error['message']; $errorType = $error['type']; - if ($errorType === E_USER_ERROR) { - return "FATAL ERROR: {$errorMessage}. on line {$errorLine} in file {$errorFile}."; - } - - if ($errorType === E_USER_WARNING) { - return "WARNING: {$errorMessage}"; - } - - if ($errorType === E_USER_NOTICE) { - return "NOTICE: {$errorMessage}"; - } - - return "FATAL ERROR: {$errorMessage}. on line {$errorLine} in file {$errorFile}."; + return match ($errorType) { + E_USER_WARNING => "WARNING: {$errorMessage}", + E_USER_NOTICE => "NOTICE: {$errorMessage}", + default => "FATAL ERROR: {$errorMessage}. on line {$errorLine} in file {$errorFile}." + }; } } From b6f8cd6b41c90aa92803c02e07e4bd7778a58757 Mon Sep 17 00:00:00 2001 From: James Read Date: Thu, 29 Feb 2024 22:20:46 +0800 Subject: [PATCH 4/8] Union Types Adding union types for better type hinting --- src/Application/Actions/Action.php | 10 ++-------- src/Application/Handlers/ShutdownHandler.php | 8 ++++---- src/Application/Settings/Settings.php | 7 ++----- src/Application/Settings/SettingsInterface.php | 6 +----- 4 files changed, 9 insertions(+), 22 deletions(-) diff --git a/src/Application/Actions/Action.php b/src/Application/Actions/Action.php index ebd4f190..bd146cbb 100644 --- a/src/Application/Actions/Action.php +++ b/src/Application/Actions/Action.php @@ -49,10 +49,7 @@ public function __invoke(Request $request, Response $response, array $args): Res */ abstract protected function action(): Response; - /** - * @return array|object - */ - protected function getFormData() + protected function getFormData(): array|object|null { return $this->request->getParsedBody(); } @@ -70,10 +67,7 @@ protected function resolveArg(string $name) return $this->args[$name]; } - /** - * @param array|object|null $data - */ - protected function respondWithData($data = null, int $statusCode = 200): Response + protected function respondWithData(array|object|null $data = null, int $statusCode = 200): Response { $payload = new ActionPayload($statusCode, $data); diff --git a/src/Application/Handlers/ShutdownHandler.php b/src/Application/Handlers/ShutdownHandler.php index e3615242..2f9b58eb 100644 --- a/src/Application/Handlers/ShutdownHandler.php +++ b/src/Application/Handlers/ShutdownHandler.php @@ -15,9 +15,6 @@ public function __construct( private HttpErrorHandler $errorHandler, private bool $displayErrorDetails ) { - $this->request = $request; - $this->errorHandler = $errorHandler; - $this->displayErrorDetails = $displayErrorDetails; } public function __invoke() @@ -41,7 +38,10 @@ public function __invoke() $responseEmitter->emit($response); } - private function getErrorMessage(array $error): string + /** + * @param array{type: int, message: string, file: string, line: int} $error + */ + private function getErrorMessage(array $error = null): string { if (!$this->displayErrorDetails) { return 'An error while processing your request. Please try again later.'; diff --git a/src/Application/Settings/Settings.php b/src/Application/Settings/Settings.php index 09318f8e..40017532 100644 --- a/src/Application/Settings/Settings.php +++ b/src/Application/Settings/Settings.php @@ -14,11 +14,8 @@ public function __construct(private array $settings) $this->settings = $settings; } - /** - * @return mixed - */ - public function get(string $key = '') + public function get(string $key = ''): mixed { - return (empty($key)) ? $this->settings : $this->settings[$key]; + return empty($key) ? $this->settings : $this->settings[$key]; } } diff --git a/src/Application/Settings/SettingsInterface.php b/src/Application/Settings/SettingsInterface.php index 557d98b8..7867c592 100644 --- a/src/Application/Settings/SettingsInterface.php +++ b/src/Application/Settings/SettingsInterface.php @@ -6,9 +6,5 @@ interface SettingsInterface { - /** - * @param string $key - * @return mixed - */ - public function get(string $key = ''); + public function get(string $key = ''): mixed; } From 31b291b9c3ad21f3fa36022e9cd60537085d8155 Mon Sep 17 00:00:00 2001 From: James Read Date: Fri, 1 Mar 2024 00:55:35 +0800 Subject: [PATCH 5/8] Removing readonly from entity --- src/Domain/User/User.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Domain/User/User.php b/src/Domain/User/User.php index 8bbf7cd7..e01e8366 100644 --- a/src/Domain/User/User.php +++ b/src/Domain/User/User.php @@ -15,7 +15,7 @@ class User implements JsonSerializable private string $lastName; public function __construct( - private readonly int|null $id, + private int|null $id, string $username, string $firstName, string $lastName From 0ef17a1e407c6ebd9ed726fc95da3945a5a5a221 Mon Sep 17 00:00:00 2001 From: James Read Date: Fri, 1 Mar 2024 00:56:23 +0800 Subject: [PATCH 6/8] Updating README Updating the php version in README --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 63f99725..09681f18 100644 --- a/README.md +++ b/README.md @@ -8,7 +8,7 @@ This skeleton application was built for Composer. This makes setting up a new Sl ## Install the Application -Run this command from the directory in which you want to install your new Slim Framework application. You will require PHP 7.4 or newer. +Run this command from the directory in which you want to install your new Slim Framework application. You will require PHP 8.3 or newer. ```bash composer create-project slim/slim-skeleton [my-app-name] From 2702b5f2581579494aa476c0208b3211d9361186 Mon Sep 17 00:00:00 2001 From: James Read Date: Sun, 12 May 2024 14:18:03 +0800 Subject: [PATCH 7/8] chore: Updating CI for PHP 8.3 only --- .github/workflows/tests.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index cd83ec5e..4cc5b096 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,10 +10,10 @@ jobs: strategy: fail-fast: false matrix: - php: [7.4, 8.0, 8.1, 8.2] + php: [8.3] experimental: [false] include: - - php: 8.1 + - php: 8.3 analysis: true steps: From 5bc06a7a125cdfa147f5a409a6e0790a4cd276c1 Mon Sep 17 00:00:00 2001 From: James Read Date: Sun, 19 May 2024 19:24:23 +0800 Subject: [PATCH 8/8] chore: supporting PHP 8.2 Supporting all supported versions of PHP 8.2 and 8.3 --- .github/workflows/tests.yml | 2 +- composer.json | 2 +- public/index.php | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 4cc5b096..2d0533e9 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -10,7 +10,7 @@ jobs: strategy: fail-fast: false matrix: - php: [8.3] + php: [8.2, 8.3] experimental: [false] include: - php: 8.3 diff --git a/composer.json b/composer.json index d3d54326..a6d3badd 100644 --- a/composer.json +++ b/composer.json @@ -22,7 +22,7 @@ } ], "require": { - "php": "^8.3", + "php": "^8.2", "ext-json": "*", "monolog/monolog": "^2.9", "php-di/php-di": "^6.4", diff --git a/public/index.php b/public/index.php index bc583c82..75a37322 100644 --- a/public/index.php +++ b/public/index.php @@ -16,7 +16,7 @@ $containerBuilder = new ContainerBuilder(); if (false) { // Should be set to true in production - $containerBuilder->enableCompilation(__DIR__ . '/../var/cache'); + $containerBuilder->enableCompilation(__DIR__ . '/../var/cache'); } // Set up settings