Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrading Skeleton to PHP 8.2 #345

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ jobs:
strategy:
fail-fast: false
matrix:
php: [7.4, 8.0, 8.1, 8.2]
php: [8.2, 8.3]
experimental: [false]
include:
- php: 8.1
- php: 8.3
analysis: true

steps:
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@
}
],
"require": {
"php": "^7.4 || ^8.0",
"php": "^8.2",
"ext-json": "*",
"monolog/monolog": "^2.9",
"php-di/php-di": "^6.4",
Expand Down
2 changes: 1 addition & 1 deletion public/index.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
20 changes: 7 additions & 13 deletions src/Application/Actions/Action.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,17 +13,17 @@

abstract class Action
{
protected LoggerInterface $logger;

protected Request $request;

protected Response $response;

/**
* @var array<string, mixed>
*/
protected array $args;

public function __construct(LoggerInterface $logger)
public function __construct(protected LoggerInterface $logger)
{
$this->logger = $logger;
}

/**
Expand All @@ -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();
}
Expand All @@ -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);

Expand All @@ -87,6 +81,6 @@ protected function respond(ActionPayload $payload): Response

return $this->response
->withHeader('Content-Type', 'application/json')
->withStatus($payload->getStatusCode());
->withStatus($payload->statusCode);
}
}
34 changes: 4 additions & 30 deletions src/Application/Actions/ActionError.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
36 changes: 3 additions & 33 deletions src/Application/Actions/ActionPayload.php
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down
9 changes: 4 additions & 5 deletions src/Application/Actions/User/UserAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
23 changes: 11 additions & 12 deletions src/Application/Handlers/HttpErrorHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand All @@ -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);

Expand Down
38 changes: 12 additions & 26 deletions src/Application/Handlers/ShutdownHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,11 @@

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;
$this->displayErrorDetails = $displayErrorDetails;
}

public function __invoke()
Expand All @@ -47,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.';
Expand All @@ -58,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}."
};
}
}
14 changes: 6 additions & 8 deletions src/Application/Settings/Settings.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,16 @@

class Settings implements SettingsInterface
{
private array $settings;

public function __construct(array $settings)
/**
* @param array<string, mixed> $settings
*/
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];
}
}
6 changes: 1 addition & 5 deletions src/Application/Settings/SettingsInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,5 @@

interface SettingsInterface
{
/**
* @param string $key
* @return mixed
*/
public function get(string $key = '');
public function get(string $key = ''): mixed;
}
11 changes: 6 additions & 5 deletions src/Domain/User/User.php
Original file line number Diff line number Diff line change
Expand Up @@ -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 int|null $id,
string $username,
string $firstName,
string $lastName
) {
$this->username = strtolower($username);
$this->firstName = ucfirst($firstName);
$this->lastName = ucfirst($lastName);
Expand Down