diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1cb8687..24e9668 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -11,10 +11,10 @@ jobs: strategy: matrix: include: - - php: '7.2' + - php: '8.0' composer-flags: '--prefer-stable --prefer-lowest' - - php: '7.4' + - php: '8.1' code-coverage: 'yes' steps: diff --git a/.github/workflows/static.yml b/.github/workflows/static.yml index 0508a96..7260ed1 100644 --- a/.github/workflows/static.yml +++ b/.github/workflows/static.yml @@ -16,7 +16,7 @@ jobs: - name: Setup PHP uses: shivammathur/setup-php@v2 with: - php-version: '7.4' + php-version: '8.1' coverage: none extensions: mbstring tools: 'cs2pr' diff --git a/.php-cs-fixer.php b/.php-cs-fixer.php index 0b1e579..362d2db 100644 --- a/.php-cs-fixer.php +++ b/.php-cs-fixer.php @@ -10,25 +10,39 @@ ->setRules([ '@Symfony' => true, '@Symfony:risky' => true, - 'array_syntax' => ['syntax' => 'short'], - 'linebreak_after_opening_tag' => true, - 'native_constant_invocation' => true, - 'native_function_invocation' => true, - 'no_superfluous_phpdoc_tags' => true, - 'no_unreachable_default_argument_value' => true, - 'no_useless_else' => true, - 'no_useless_return' => true, - 'ordered_imports' => true, + 'array_syntax' => [ + 'syntax' => 'short', + ], + 'concat_space' => [ + 'spacing' => 'one', + ], + 'declare_strict_types' => true, + 'global_namespace_import' => [ + 'import_classes' => true, + 'import_constants' => null, + 'import_functions' => true, + ], + 'native_constant_invocation' => [ + 'fix_built_in' => false, + ], + 'ordered_imports' => [ + 'imports_order' => [ + 'class', + 'function', + 'const', + ], + ], 'php_unit_method_casing' => [ 'case' => 'snake_case', ], 'php_unit_test_annotation' => [ 'style' => 'annotation', ], - 'phpdoc_order' => true, - 'semicolon_after_instruction' => true, - 'strict_comparison' => true, - 'strict_param' => true, + 'single_line_throw' => false, + 'trailing_comma_in_multiline' => [ + 'after_heredoc' => true, + 'elements' => ['arrays', 'arguments', 'parameters'], + ], ]) ->setFinder($finder) ; diff --git a/composer.json b/composer.json index 9541712..c0e1b7b 100644 --- a/composer.json +++ b/composer.json @@ -11,9 +11,9 @@ } ], "require": { - "php": "^7.2", - "symfony/http-foundation": "^4.4||^5.0", - "symfony/http-kernel": "^4.4||^5.0", + "php": "^8.0", + "symfony/http-foundation": "^5.4||^6.0", + "symfony/http-kernel": "^5.4||^6.0", "nocarrier/hal": "^0.9.4" }, "suggest": { @@ -25,23 +25,23 @@ "symfony/serializer": "For using RequestBodyDecoder" }, "require-dev": { - "roave/security-advisories": "dev-master", + "roave/security-advisories": "dev-latest", - "psr/log": "^1.0", + "psr/log": "^1.0||^3.0", - "symfony/event-dispatcher": "^4.4||^5.0", + "symfony/event-dispatcher": "^5.4||^6.0", - "symfony/config": "^4.4||^5.0", - "symfony/dependency-injection": "^4.4||^5.0", + "symfony/config": "^5.4||^6.0", + "symfony/dependency-injection": "^5.4||^6.0", - "symfony/form": "^4.4||^5.0", - "symfony/translation": "^4.4||^5.0", - "symfony/validator": "^4.4||^5.0", - "symfony/security-core": "^4.4||^5.0", - "symfony/serializer": "^4.4||^5.0", + "symfony/form": "^5.4||^6.0", + "symfony/translation": "^5.4||^6.0", + "symfony/validator": "^5.4||^6.0", + "symfony/security-core": "^5.4||^6.0", + "symfony/serializer": "^5.4||^6.0", - "willdurand/negotiation": "^2.0", - "phpunit/phpunit": "^8.5", + "willdurand/negotiation": "^3.0", + "phpunit/phpunit": "^9.5", "friendsofphp/php-cs-fixer": "^3.0" }, diff --git a/src/EventListener/ExceptionConversionListener.php b/src/EventListener/ExceptionConversionListener.php index ff8fdde..e22e2de 100644 --- a/src/EventListener/ExceptionConversionListener.php +++ b/src/EventListener/ExceptionConversionListener.php @@ -13,16 +13,16 @@ final class ExceptionConversionListener implements EventSubscriberInterface { - private $logger; - private $prettyPrint; - private $debug; - private $formats; + private ?LoggerInterface $logger; + private bool $prettyPrint; + private bool $debug; + private ?array $formats; public function __construct( LoggerInterface $logger = null, bool $prettyPrint = true, bool $debug = false, - array $formats = null + array $formats = null, ) { $this->logger = $logger; $this->prettyPrint = $prettyPrint; @@ -38,7 +38,7 @@ public function onKernelException(ExceptionEvent $event): void $this->logger, $this->prettyPrint, $this->debug, - $this->formats + $this->formats, ); if ($response instanceof Response) { diff --git a/src/EventListener/RequestFormatNegotiationListener.php b/src/EventListener/RequestFormatNegotiationListener.php index a509530..03a5606 100644 --- a/src/EventListener/RequestFormatNegotiationListener.php +++ b/src/EventListener/RequestFormatNegotiationListener.php @@ -11,12 +11,12 @@ final class RequestFormatNegotiationListener implements EventSubscriberInterface { - private $formats; - private $priorities; + private ?array $formats; + private ?array $priorities; public function __construct( array $formats = null, - array $priorities = null + array $priorities = null, ) { $this->formats = $formats; $this->priorities = $priorities; @@ -27,7 +27,7 @@ public function onKernelRequest(RequestEvent $event): void RequestFormatNegotiator::negotiate( $event->getRequest(), $this->formats, - $this->priorities + $this->priorities, ); } diff --git a/src/EventListener/RequestFormatValidationListener.php b/src/EventListener/RequestFormatValidationListener.php index b233303..eea3f0c 100644 --- a/src/EventListener/RequestFormatValidationListener.php +++ b/src/EventListener/RequestFormatValidationListener.php @@ -12,12 +12,12 @@ final class RequestFormatValidationListener implements EventSubscriberInterface { - private $acceptableFormats; - private $exclude; + private ?array $acceptableFormats; + private array | string | null $exclude; public function __construct( array $acceptableFormats = null, - $exclude = null + array | string | null $exclude = null, ) { $this->acceptableFormats = $acceptableFormats; $this->exclude = $exclude; @@ -28,7 +28,7 @@ public function onKernelRequest(RequestEvent $event): void $response = RequestFormatValidator::intercept( $event->getRequest(), $this->acceptableFormats, - $this->exclude + $this->exclude, ); if ($response instanceof Response) { diff --git a/src/EventListener/ResponseConversionListener.php b/src/EventListener/ResponseConversionListener.php index 8cd5cfe..6b2a880 100644 --- a/src/EventListener/ResponseConversionListener.php +++ b/src/EventListener/ResponseConversionListener.php @@ -12,11 +12,11 @@ final class ResponseConversionListener implements EventSubscriberInterface { - private $prettyPrint; + private bool $prettyPrint; - public function __construct($prettyPrint = true) + public function __construct(bool $prettyPrint = true) { - $this->prettyPrint = (bool) $prettyPrint; + $this->prettyPrint = $prettyPrint; } public function onKernelView(ViewEvent $event): void @@ -25,7 +25,7 @@ public function onKernelView(ViewEvent $event): void if ($hal instanceof Hal) { $event->setResponse( - new HalResponse($hal, 200, [], $this->prettyPrint) + new HalResponse($hal, 200, [], $this->prettyPrint), ); } } diff --git a/src/Exception/ErrorException.php b/src/Exception/ErrorException.php index c2ad60c..87b3ceb 100644 --- a/src/Exception/ErrorException.php +++ b/src/Exception/ErrorException.php @@ -6,18 +6,20 @@ use Nocarrier\Hal; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Throwable; +use function is_array; final class ErrorException extends BadRequestHttpException implements HalException { - private $errors; - private $logref; + private array $errors; + private mixed $logref; public function __construct( array $errors, - $message = null, - $logref = null, - \Throwable $previous = null, - $code = 0 + string $message = '', + mixed $logref = null, + Throwable $previous = null, + int $code = 0, ) { parent::__construct($message, $previous, $code); @@ -45,7 +47,7 @@ public function getHal(): Hal private function appendErrors(Hal $hal, array $errors): void { foreach ($errors as $error) { - if (!\is_array($error)) { + if (!is_array($error)) { $error = [ 'message' => (string) $error, ]; diff --git a/src/Exception/FormErrorException.php b/src/Exception/FormErrorException.php index eb7f68b..debf4cc 100644 --- a/src/Exception/FormErrorException.php +++ b/src/Exception/FormErrorException.php @@ -8,18 +8,19 @@ use Symfony\Component\Form\FormError; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; +use Throwable; final class FormErrorException extends BadRequestHttpException implements HalException { - private $form; - private $logref; + private FormInterface $form; + private mixed $logref; public function __construct( FormInterface $form, - $message = null, - $logref = null, - \Throwable $previous = null, - $code = 0 + string $message = '', + mixed $logref = null, + Throwable $previous = null, + int $code = 0, ) { parent::__construct($message, $previous, $code); @@ -97,6 +98,6 @@ private function getPath(FormInterface $form): string // Remove root form array_shift($path); - return '/'.implode('/', $path); + return '/' . implode('/', $path); } } diff --git a/src/Exception/ValidationErrorException.php b/src/Exception/ValidationErrorException.php index fa48386..3b4c48f 100644 --- a/src/Exception/ValidationErrorException.php +++ b/src/Exception/ValidationErrorException.php @@ -7,18 +7,19 @@ use Nocarrier\Hal; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\Validator\ConstraintViolationListInterface; +use Throwable; final class ValidationErrorException extends BadRequestHttpException implements HalException { - private $violationList; - private $logref; + private ConstraintViolationListInterface $violationList; + private mixed $logref; public function __construct( ConstraintViolationListInterface $violationList, - $message = null, - $logref = null, - \Throwable $previous = null, - $code = 0 + string $message = '', + mixed $logref = null, + Throwable $previous = null, + int $code = 0, ) { parent::__construct($message, $previous, $code); @@ -40,7 +41,7 @@ public function getHal(): Hal foreach ($this->violationList as $violation) { $path = str_replace('][', '/', $violation->getPropertyPath()); - $path = '/'.trim($path, '[]'); + $path = '/' . trim($path, '[]'); $data = [ 'message' => $violation->getMessage(), diff --git a/src/ExceptionConverter.php b/src/ExceptionConverter.php index ac15dbd..65af729 100644 --- a/src/ExceptionConverter.php +++ b/src/ExceptionConverter.php @@ -4,12 +4,16 @@ namespace Jsor\Stack\Hal; +use Exception; use Jsor\Stack\Hal\Response\VndErrorResponse; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\HttpKernel\HttpKernelInterface; +use Throwable; +use function get_class; +use function in_array; /** * Converts to a vnd.error response. @@ -18,12 +22,12 @@ */ final class ExceptionConverter implements HttpKernelInterface { - private $app; - private $logger; - private $prettyPrint; - private $debug; - private $passThroughCatch; - private $formats; + private HttpKernelInterface $app; + private ?LoggerInterface $logger; + private bool $prettyPrint; + private bool $debug; + private bool $passThroughCatch; + private ?array $formats; public function __construct( HttpKernelInterface $app, @@ -31,7 +35,7 @@ public function __construct( bool $prettyPrint = true, bool $debug = false, bool $passThroughCatch = false, - array $formats = null + array $formats = null, ) { $this->app = $app; $this->logger = $logger; @@ -43,16 +47,16 @@ public function __construct( public function handle( Request $request, - $type = HttpKernelInterface::MASTER_REQUEST, - $catch = true - ) { + int $type = HttpKernelInterface::MAIN_REQUEST, + bool $catch = true, + ): Response { try { return $this->app->handle( $request, $type, - $this->passThroughCatch ? $catch : false + $this->passThroughCatch ? $catch : false, ); - } catch (\Exception $exception) { + } catch (Exception $exception) { if (!$catch) { throw $exception; } @@ -63,7 +67,7 @@ public function handle( $this->logger, $this->prettyPrint, $this->debug, - $this->formats + $this->formats, ); if ($response instanceof Response) { @@ -75,12 +79,12 @@ public function handle( } public static function handleThrowable( - \Throwable $throwable, + Throwable $throwable, Request $request, LoggerInterface $logger = null, bool $prettyPrint = true, bool $debug = false, - array $formats = null + array $formats = null, ): ?VndErrorResponse { if (null !== $logger) { self::logThrowable($logger, $throwable); @@ -90,27 +94,27 @@ public static function handleThrowable( $format = $request->getRequestFormat(null); - if (!$format || !\in_array($format, $formats, true)) { + if (!$format || !in_array($format, $formats, true)) { return null; } return VndErrorResponse::fromThrowable( $throwable, $prettyPrint, - $debug + $debug, ); } public static function logThrowable( LoggerInterface $logger, - \Throwable $throwable + Throwable $throwable, ): void { $message = sprintf( 'Uncaught PHP Exception %s: "%s" at %s line %s', - \get_class($throwable), + get_class($throwable), $throwable->getMessage(), $throwable->getFile(), - $throwable->getLine() + $throwable->getLine(), ); $isCritical = !$throwable instanceof HttpExceptionInterface || diff --git a/src/RequestBodyDecoder.php b/src/RequestBodyDecoder.php index 4e7643c..ba22d87 100644 --- a/src/RequestBodyDecoder.php +++ b/src/RequestBodyDecoder.php @@ -4,12 +4,17 @@ namespace Jsor\Stack\Hal; +use Exception; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; use Symfony\Component\HttpKernel\HttpKernelInterface; use Symfony\Component\Serializer\Encoder\JsonEncoder; use Symfony\Component\Serializer\Encoder\XmlEncoder; +use function call_user_func; +use function in_array; +use function is_array; +use function is_callable; /** * Adapted from the FOSRestBundle BodyListener. @@ -18,15 +23,15 @@ */ final class RequestBodyDecoder implements HttpKernelInterface { - private $app; - private $decoders; + private HttpKernelInterface $app; + private ?array $decoders; /** * @param callable[] $decoders */ public function __construct( HttpKernelInterface $app, - array $decoders = null + array $decoders = null, ) { $this->app = $app; $this->decoders = $decoders; @@ -34,9 +39,9 @@ public function __construct( public function handle( Request $request, - $type = HttpKernelInterface::MASTER_REQUEST, - $catch = true - ) { + int $type = HttpKernelInterface::MAIN_REQUEST, + bool $catch = true, + ): Response { try { self::decode($request, $this->decoders); } catch (BadRequestHttpException $exception) { @@ -46,7 +51,7 @@ public function handle( return new Response( $exception->getMessage(), - Response::HTTP_BAD_REQUEST + Response::HTTP_BAD_REQUEST, ); } @@ -58,19 +63,15 @@ public function handle( */ public static function decode( Request $request, - array $decoders = null + array $decoders = null, ): void { if (null === $decoders) { $decoders = [ 'json' => static function ($content) { - $encoder = new JsonEncoder(); - - return $encoder->decode($content, 'json'); + return (new JsonEncoder())->decode($content, 'json'); }, 'xml' => static function ($content) { - $encoder = new XmlEncoder(); - - return $encoder->decode($content, 'xml'); + return (new XmlEncoder())->decode($content, 'xml'); }, ]; } @@ -89,7 +90,7 @@ public static function decode( return; } - if (!\is_callable($decoders[$format])) { + if (!is_callable($decoders[$format])) { return; } @@ -100,13 +101,13 @@ public static function decode( } try { - $data = \call_user_func($decoders[$format], $content); - } catch (\Exception $e) { - throw new BadRequestHttpException('Invalid '.$format.' message received', $e); + $data = call_user_func($decoders[$format], $content); + } catch (Exception $e) { + throw new BadRequestHttpException('Invalid ' . $format . ' message received', $e); } - if (!\is_array($data)) { - throw new BadRequestHttpException('Invalid '.$format.' message received'); + if (!is_array($data)) { + throw new BadRequestHttpException('Invalid ' . $format . ' message received'); } $request->request->replace($data); @@ -114,7 +115,7 @@ public static function decode( private static function isDecodeable(Request $request): bool { - if (!\in_array($request->getMethod(), ['POST', 'PUT', 'PATCH', 'DELETE'], true)) { + if (!in_array($request->getMethod(), ['POST', 'PUT', 'PATCH', 'DELETE'], true)) { return false; } @@ -133,10 +134,10 @@ private static function isFormRequest(Request $request): bool return false; } - return \in_array( + return in_array( strtolower($contentTypeParts[0]), ['multipart/form-data', 'application/x-www-form-urlencoded'], - true + true, ); } } diff --git a/src/RequestFormatNegotiator.php b/src/RequestFormatNegotiator.php index ded8725..cd2c116 100644 --- a/src/RequestFormatNegotiator.php +++ b/src/RequestFormatNegotiator.php @@ -7,13 +7,14 @@ use Negotiation\Accept; use Negotiation\Negotiator; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; final class RequestFormatNegotiator implements HttpKernelInterface { - private $app; - private $formats; - private $priorities; + private HttpKernelInterface $app; + private ?array $formats; + private ?array $priorities; private const DEFAULT_FORMATS = [ 'json' => ['application/hal+json', 'application/json', 'application/x-json'], @@ -23,7 +24,7 @@ final class RequestFormatNegotiator implements HttpKernelInterface public function __construct( HttpKernelInterface $app, array $formats = null, - array $priorities = null + array $priorities = null, ) { $this->app = $app; $this->formats = $formats; @@ -32,9 +33,9 @@ public function __construct( public function handle( Request $request, - $type = HttpKernelInterface::MASTER_REQUEST, - $catch = true - ) { + int $type = HttpKernelInterface::MAIN_REQUEST, + bool $catch = true, + ): Response { self::negotiate($request, $this->formats, $this->priorities); return $this->app->handle($request, $type, $catch); @@ -43,7 +44,7 @@ public function handle( public static function negotiate( Request $request, array $formats = null, - array $priorities = null + array $priorities = null, ): void { $formats = $formats ?: self::DEFAULT_FORMATS; @@ -74,12 +75,12 @@ public static function negotiate( private static function extendRequestFormats( Request $request, - array $formats + array $formats, ): void { foreach ($formats as $format => $mimeTypes) { $allMimeTypes = array_merge( $mimeTypes, - Request::getMimeTypes($format) + Request::getMimeTypes($format), ); $request->setFormat($format, array_unique($allMimeTypes)); diff --git a/src/RequestFormatValidator.php b/src/RequestFormatValidator.php index 5c11f53..e6e2899 100644 --- a/src/RequestFormatValidator.php +++ b/src/RequestFormatValidator.php @@ -9,12 +9,13 @@ use Symfony\Component\HttpFoundation\RequestMatcherInterface; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; +use function is_array; final class RequestFormatValidator implements HttpKernelInterface { - private $app; - private $acceptableFormats; - private $exclude; + private HttpKernelInterface $app; + private ?array $acceptableFormats; + private array | string | null $exclude; /** * @param array|string|null $exclude @@ -22,7 +23,7 @@ final class RequestFormatValidator implements HttpKernelInterface public function __construct( HttpKernelInterface $app, array $acceptableFormats = null, - $exclude = null + array | string | null $exclude = null, ) { $this->app = $app; $this->acceptableFormats = $acceptableFormats; @@ -31,13 +32,13 @@ public function __construct( public function handle( Request $request, - $type = HttpKernelInterface::MASTER_REQUEST, - $catch = true - ) { + int $type = HttpKernelInterface::MAIN_REQUEST, + bool $catch = true, + ): Response { $response = self::intercept( $request, $this->acceptableFormats, - $this->exclude + $this->exclude, ); if ($response instanceof Response) { @@ -47,13 +48,10 @@ public function handle( return $this->app->handle($request, $type, $catch); } - /** - * @param array|string|null $exclude - */ public static function intercept( Request $request, array $acceptableFormats = null, - $exclude = null + array | string | null $exclude = null, ): ?Response { $acceptableFormats = $acceptableFormats ?: [ 'json' => ['application/hal+json', 'application/json', 'application/x-json'], @@ -83,15 +81,15 @@ public static function intercept( return new Response( sprintf( 'Mime type%s "%s" %s not supported. Supported mime types are: %s.', - false !== strpos($mimeType, ',') ? 's' : '', + str_contains($mimeType, ',') ? 's' : '', $mimeType, - false !== strpos($mimeType, ',') ? 'are' : 'is', - implode(', ', $acceptableMimeTypes) + str_contains($mimeType, ',') ? 'are' : 'is', + implode(', ', $acceptableMimeTypes), ), 406, [ 'Content-Type' => 'text/plain', - ] + ], ); } @@ -99,12 +97,12 @@ public static function intercept( return new Response( sprintf( 'Could not detect supported mime type. Supported mime types are: %s.', - implode(', ', $acceptableMimeTypes) + implode(', ', $acceptableMimeTypes), ), 406, [ 'Content-Type' => 'text/plain', - ] + ], ); } @@ -112,25 +110,24 @@ public static function intercept( sprintf( 'Format "%s" is not supported. Supported mime types are: %s.', $format, - implode(', ', $acceptableMimeTypes) + implode(', ', $acceptableMimeTypes), ), 406, [ 'Content-Type' => 'text/plain', - ] + ], ); } - /** - * @param array|string|null $exclude - */ - private static function isExcluded(Request $request, $exclude): bool - { + private static function isExcluded( + Request $request, + array | string | null $exclude, + ): bool { if (!$exclude) { return false; } - if (!\is_array($exclude) || 0 !== key($exclude)) { + if (!is_array($exclude) || 0 !== key($exclude)) { $exclude = [$exclude]; } @@ -146,17 +143,14 @@ private static function isExcluded(Request $request, $exclude): bool return false; } - /** - * @param RequestMatcherInterface|array|string $arguments - */ private static function createRequestMatcher( - $arguments + array | string | RequestMatcherInterface $arguments, ): RequestMatcherInterface { if ($arguments instanceof RequestMatcherInterface) { return $arguments; } - if (!\is_array($arguments)) { + if (!is_array($arguments)) { return new RequestMatcher($arguments); } @@ -175,7 +169,7 @@ private static function createRequestMatcher( $arguments['methods'], $arguments['ips'], $arguments['attributes'], - $arguments['schemes'] + $arguments['schemes'], ); } } diff --git a/src/Response/CreatedResponse.php b/src/Response/CreatedResponse.php index cb99073..f0fede3 100644 --- a/src/Response/CreatedResponse.php +++ b/src/Response/CreatedResponse.php @@ -8,7 +8,7 @@ final class CreatedResponse extends HalResponse { - public function __construct(Hal $hal, $headers = [], $prettyPrint = true) + public function __construct(Hal $hal, array $headers = [], bool $prettyPrint = true) { parent::__construct($hal, 201, $headers, $prettyPrint); diff --git a/src/Response/HalResponse.php b/src/Response/HalResponse.php index 16e41b6..1aa08a7 100644 --- a/src/Response/HalResponse.php +++ b/src/Response/HalResponse.php @@ -4,6 +4,7 @@ namespace Jsor\Stack\Hal\Response; +use LogicException; use Nocarrier\Hal; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -18,7 +19,7 @@ public function __construct( Hal $hal, int $status = 200, array $headers = [], - bool $prettyPrint = true + bool $prettyPrint = true, ) { parent::__construct(null, $status, $headers); @@ -29,7 +30,7 @@ public function __construct( $this->headers->set('Content-Type', 'application/hal+json'); } - public function prepare(Request $request): Response + public function prepare(Request $request): static { if ('xml' === $request->getRequestFormat()) { $this->requestFormat = 'xml'; @@ -39,20 +40,22 @@ public function prepare(Request $request): Response return parent::prepare($request); } - public function sendContent(): self + public function sendContent(): static { echo $this->getContent(); return $this; } - public function setContent($content): void + public function setContent($content): static { if (null !== $content && !$content instanceof Hal) { - throw new \LogicException('The content must be a Hal instance.'); + throw new LogicException('The content must be a Hal instance.'); } $this->hal = $content; + + return $this; } public function getContent(): string diff --git a/src/Response/VndErrorResponse.php b/src/Response/VndErrorResponse.php index 9a05287..d57bb79 100644 --- a/src/Response/VndErrorResponse.php +++ b/src/Response/VndErrorResponse.php @@ -10,6 +10,7 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Exception\HttpExceptionInterface; use Symfony\Component\Security\Core\Exception\AccessDeniedException; +use Throwable; final class VndErrorResponse extends HalResponse { @@ -17,7 +18,7 @@ public function __construct( Hal $hal, int $status = 500, array $headers = [], - bool $prettyPrint = true + bool $prettyPrint = true, ) { parent::__construct($hal, $status, $headers, $prettyPrint); @@ -25,9 +26,9 @@ public function __construct( } public static function fromThrowable( - \Throwable $throwable, + Throwable $throwable, bool $prettyPrint = true, - bool $debug = false + bool $debug = false, ): self { $statusCode = self::extractStatus($throwable); $headers = self::extractHeaders($throwable); @@ -54,7 +55,7 @@ public static function fromThrowable( return new self($hal, $statusCode, $headers, $prettyPrint); } - public function prepare(Request $request): Response + public function prepare(Request $request): static { parent::prepare($request); @@ -65,7 +66,7 @@ public function prepare(Request $request): Response return $this; } - private static function extractStatus(\Throwable $throwable) + private static function extractStatus(Throwable $throwable) { if ($throwable instanceof HttpExceptionInterface) { return $throwable->getStatusCode(); @@ -78,7 +79,7 @@ private static function extractStatus(\Throwable $throwable) return 500; } - private static function extractHeaders(\Throwable $throwable) + private static function extractHeaders(Throwable $throwable) { if ($throwable instanceof HttpExceptionInterface) { return $throwable->getHeaders(); @@ -87,7 +88,7 @@ private static function extractHeaders(\Throwable $throwable) return []; } - private static function extractMessage(\Throwable $throwable, $debug) + private static function extractMessage(Throwable $throwable, $debug) { if ($throwable instanceof HttpExceptionInterface) { return $throwable->getMessage(); diff --git a/tests/Exception/ErrorExceptionTest.php b/tests/Exception/ErrorExceptionTest.php index 06b80b1..af50ae5 100644 --- a/tests/Exception/ErrorExceptionTest.php +++ b/tests/Exception/ErrorExceptionTest.php @@ -30,9 +30,9 @@ public function it_serializes_exception_to_json(): void ], ], ], - ] + ], ), - $exception->getHal()->asJson() + $exception->getHal()->asJson(), ); } @@ -62,9 +62,9 @@ public function it_alllows_errors_to_be_arrays(): void ], ], ], - ] + ], ), - $exception->getHal()->asJson() + $exception->getHal()->asJson(), ); } } diff --git a/tests/Exception/FormErrorExceptionTest.php b/tests/Exception/FormErrorExceptionTest.php index 310bc04..2b9b18a 100644 --- a/tests/Exception/FormErrorExceptionTest.php +++ b/tests/Exception/FormErrorExceptionTest.php @@ -79,7 +79,7 @@ public function it_serializes_exception_to_json(): void ], ], ], - json_decode($exception->getHal()->asJson(), true) + json_decode($exception->getHal()->asJson(), true), ); } } diff --git a/tests/Exception/ValidationErrorExceptionTest.php b/tests/Exception/ValidationErrorExceptionTest.php index c4edee8..8a0a2e8 100644 --- a/tests/Exception/ValidationErrorExceptionTest.php +++ b/tests/Exception/ValidationErrorExceptionTest.php @@ -61,9 +61,9 @@ public function it_serializes_exception_to_json(): void ], ], ], - ] + ], ), - $exception->getHal()->asJson() + $exception->getHal()->asJson(), ); } } diff --git a/tests/ExceptionConverterTest.php b/tests/ExceptionConverterTest.php index ffbc8b7..0f8139d 100644 --- a/tests/ExceptionConverterTest.php +++ b/tests/ExceptionConverterTest.php @@ -4,6 +4,7 @@ namespace Jsor\Stack\Hal; +use Exception; use PHPUnit\Framework\TestCase; use Psr\Log\LoggerInterface; use Symfony\Component\HttpFoundation\Request; @@ -21,7 +22,7 @@ public function it_serializes_exception_to_json(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception())); + ->will($this->throwException(new Exception())); $app = new ExceptionConverter($kernel); @@ -35,9 +36,9 @@ public function it_serializes_exception_to_json(): void json_encode( [ 'message' => 'Internal Server Error', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -63,9 +64,9 @@ public function it_serializes_http_exception_with_default_message_to_json(): voi json_encode( [ 'message' => 'Not Found', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -91,9 +92,9 @@ public function it_serializes_http_exception_with_custom_message_to_json(): void json_encode( [ 'message' => 'Resource not found', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -119,9 +120,9 @@ public function it_serializes_access_denied_exception_to_json(): void json_encode( [ 'message' => 'Access Denied', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -133,7 +134,7 @@ public function it_serializes_exception_to_xml(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception())); + ->will($this->throwException(new Exception())); $app = new ExceptionConverter($kernel); @@ -145,7 +146,7 @@ public function it_serializes_exception_to_xml(): void $this->assertSame(500, $response->getStatusCode()); $this->assertXmlStringEqualsXmlString( 'Internal Server Error', - $response->getContent() + $response->getContent(), ); } @@ -169,7 +170,7 @@ public function it_serializes_http_exception_with_default_message_to_xml(): void $this->assertSame(404, $response->getStatusCode()); $this->assertXmlStringEqualsXmlString( 'Not Found', - $response->getContent() + $response->getContent(), ); } @@ -193,7 +194,7 @@ public function it_serializes_http_exception_with_custom_message_to_xml(): void $this->assertSame(404, $response->getStatusCode()); $this->assertXmlStringEqualsXmlString( 'Resource not found', - $response->getContent() + $response->getContent(), ); } @@ -217,7 +218,7 @@ public function it_serializes_access_denied_exception_to_xml(): void $this->assertSame(403, $response->getStatusCode()); $this->assertXmlStringEqualsXmlString( 'Access Denied', - $response->getContent() + $response->getContent(), ); } @@ -229,7 +230,7 @@ public function it_discards_standard_exception_message(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception('Error'))); + ->will($this->throwException(new Exception('Error'))); $app = new ExceptionConverter($kernel); @@ -243,9 +244,9 @@ public function it_discards_standard_exception_message(): void json_encode( [ 'message' => 'Internal Server Error', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -257,7 +258,7 @@ public function it_exposes_standard_exception_message_when_debug_is_true(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception('Custom error message'))); + ->will($this->throwException(new Exception('Custom error message'))); $app = new ExceptionConverter($kernel, null, false, true); @@ -271,9 +272,9 @@ public function it_exposes_standard_exception_message_when_debug_is_true(): void json_encode( [ 'message' => 'Custom error message', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -288,7 +289,7 @@ public function it_rethrows_exception_if_catch_is_false(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception('Error'))); + ->will($this->throwException(new Exception('Error'))); $app = new ExceptionConverter($kernel); @@ -309,7 +310,7 @@ public function it_rethrows_exception_for_default_request_format(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception('Error'))); + ->will($this->throwException(new Exception('Error'))); $app = new ExceptionConverter($kernel); @@ -329,7 +330,7 @@ public function it_rethrows_exception_for_invalid_request_format(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception('Error'))); + ->will($this->throwException(new Exception('Error'))); $app = new ExceptionConverter($kernel); @@ -371,7 +372,7 @@ public function it_logs_critical_exceptions(): void $kernel ->expects($this->once()) ->method('handle') - ->will($this->throwException(new \Exception())); + ->will($this->throwException(new Exception())); $logger = $this->createMock(LoggerInterface::class); diff --git a/tests/Fixtures/KernelForTest.php b/tests/Fixtures/KernelForTest.php index f2552d2..18333af 100644 --- a/tests/Fixtures/KernelForTest.php +++ b/tests/Fixtures/KernelForTest.php @@ -9,12 +9,7 @@ final class KernelForTest extends Kernel { - public function getBundleMap() - { - return $this->bundleMap; - } - - public function registerBundles() + public function registerBundles(): iterable { return []; } @@ -22,9 +17,4 @@ public function registerBundles() public function registerContainerConfiguration(LoaderInterface $loader) { } - - public function isBooted() - { - return $this->booted; - } } diff --git a/tests/Fixtures/TestHttpKernel.php b/tests/Fixtures/TestHttpKernel.php index 7d4a6a8..d5624bf 100644 --- a/tests/Fixtures/TestHttpKernel.php +++ b/tests/Fixtures/TestHttpKernel.php @@ -22,7 +22,7 @@ public function __construct(EventDispatcherInterface $eventDispatcher, callable parent::__construct($eventDispatcher, $this, null, $this); } - public function getController(Request $request) + public function getController(Request $request): callable | false { if ($this->controller) { return $this->controller; @@ -38,6 +38,6 @@ public function getArguments(Request $request, $controller): array public function callController(Request $request) { - return new Response('Request: '.$request->getRequestUri()); + return new Response('Request: ' . $request->getRequestUri()); } } diff --git a/tests/Integration/HttpKernelInterfaceTest.php b/tests/Integration/HttpKernelInterfaceTest.php index b5d1416..3bf3470 100644 --- a/tests/Integration/HttpKernelInterfaceTest.php +++ b/tests/Integration/HttpKernelInterfaceTest.php @@ -71,9 +71,9 @@ public function it_converts_response_to_json(): void 'href' => '/', ], ], - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -102,7 +102,7 @@ public function it_converts_response_to_xml(): void $this->assertSame('application/hal+xml', $response->headers->get('Content-Type')); $this->assertXmlStringEqualsXmlString( '', - $response->getContent() + $response->getContent(), ); } @@ -137,9 +137,9 @@ public function it_converts_exception_to_json(): void json_encode( [ 'message' => 'Not Found', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -172,7 +172,7 @@ public function it_converts_exception_to_xml(): void $this->assertSame('application/vnd.error+xml', $response->headers->get('Content-Type')); $this->assertXmlStringEqualsXmlString( 'Not Found', - $response->getContent() + $response->getContent(), ); } } diff --git a/tests/Integration/HttpKernelTest.php b/tests/Integration/HttpKernelTest.php index 3390783..f6ce31b 100644 --- a/tests/Integration/HttpKernelTest.php +++ b/tests/Integration/HttpKernelTest.php @@ -71,9 +71,9 @@ public function it_converts_response_to_json(): void 'href' => '/', ], ], - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -109,9 +109,9 @@ public function it_converts_exception_to_json(): void json_encode( [ 'message' => 'Not Found', - ] + ], ), - $response->getContent() + $response->getContent(), ); } } diff --git a/tests/Integration/KernelTest.php b/tests/Integration/KernelTest.php index af4495a..650593e 100644 --- a/tests/Integration/KernelTest.php +++ b/tests/Integration/KernelTest.php @@ -80,9 +80,9 @@ public function it_converts_response_to_json(): void 'href' => '/', ], ], - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -122,9 +122,9 @@ public function it_converts_exception_to_json(): void json_encode( [ 'message' => 'Not Found', - ] + ], ), - $response->getContent() + $response->getContent(), ); } } diff --git a/tests/RequestBodyDecoderTest.php b/tests/RequestBodyDecoderTest.php index 2520bee..1305d74 100644 --- a/tests/RequestBodyDecoderTest.php +++ b/tests/RequestBodyDecoderTest.php @@ -4,6 +4,7 @@ namespace Jsor\Stack\Hal; +use Exception; use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; @@ -21,7 +22,7 @@ public function it_decodes_request_body( string $method, array $expectedParameters, string $contentType = null, - array $decoders = null + array $decoders = null, ): void { $kernel = $this->createMock(HttpKernelInterface::class); @@ -73,11 +74,10 @@ public function it_returns_bad_request_response_when_decoder_throws(): void $kernel ->expects($this->never()) - ->method('handle') - ->willReturn(new Response()); + ->method('handle'); $app = new RequestBodyDecoder($kernel, ['json' => static function () { - throw new \Exception('Foo'); + throw new Exception('Foo'); }]); $request = new Request([], [], [], [], [], [], '["foo"]'); @@ -100,11 +100,10 @@ public function it_throws_bad_request_exception_when_decoder_throws_and_catch_is $kernel ->expects($this->never()) - ->method('handle') - ->willReturn(new Response()); + ->method('handle'); $app = new RequestBodyDecoder($kernel, ['json' => static function () { - throw new \Exception('Foo'); + throw new Exception('Foo'); }]); $request = new Request([], [], [], [], [], [], '["foo"]'); @@ -123,8 +122,7 @@ public function it_returns_bad_request_response_when_decoder_returns_non_array() $kernel ->expects($this->never()) - ->method('handle') - ->willReturn(new Response()); + ->method('handle'); $app = new RequestBodyDecoder($kernel, ['json' => static function () { return ''; @@ -150,8 +148,7 @@ public function it_throws_bad_request_exception_when_decoder_returns_non_array_a $kernel ->expects($this->never()) - ->method('handle') - ->willReturn(new Response()); + ->method('handle'); $app = new RequestBodyDecoder($kernel, ['json' => static function () { return ''; diff --git a/tests/RequestFormatNegotiatorTest.php b/tests/RequestFormatNegotiatorTest.php index 5a1a9ad..052c5e1 100644 --- a/tests/RequestFormatNegotiatorTest.php +++ b/tests/RequestFormatNegotiatorTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use Symfony\Component\HttpFoundation\Request; +use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\HttpKernelInterface; final class RequestFormatNegotiatorTest extends TestCase @@ -17,13 +18,14 @@ final class RequestFormatNegotiatorTest extends TestCase public function it_accepts_hal_headers( ?string $acceptHeader, ?string $type, - ?string $format + ?string $format, ): void { $kernel = $this->createMock(HttpKernelInterface::class); $kernel ->expects($this->once()) - ->method('handle'); + ->method('handle') + ->willReturn(new Response()); $app = new RequestFormatNegotiator($kernel); diff --git a/tests/RequestFormatValidatorTest.php b/tests/RequestFormatValidatorTest.php index 362473a..4684a61 100644 --- a/tests/RequestFormatValidatorTest.php +++ b/tests/RequestFormatValidatorTest.php @@ -244,7 +244,7 @@ public function it_ignores_with_exclude_as_array_with_request_matcher(): void ->method('handle') ->willReturn($expectedResponse); - $app = new RequestFormatValidator($kernel, [], new RequestMatcher('/ignore')); + $app = new RequestFormatValidator($kernel, [], [new RequestMatcher('/ignore')]); $request = Request::create('/ignore'); diff --git a/tests/Response/CreatedResponseTest.php b/tests/Response/CreatedResponseTest.php index 474f238..dc44c12 100644 --- a/tests/Response/CreatedResponseTest.php +++ b/tests/Response/CreatedResponseTest.php @@ -1,5 +1,7 @@ 'test', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -56,9 +58,9 @@ public function is_sends_hal_content(): void json_encode( [ 'message' => 'test', - ] + ], ), - $string + $string, ); } diff --git a/tests/Response/VndErrorResponseTest.php b/tests/Response/VndErrorResponseTest.php index e9f7409..99fde73 100644 --- a/tests/Response/VndErrorResponseTest.php +++ b/tests/Response/VndErrorResponseTest.php @@ -1,7 +1,10 @@ getContent() + $response->getContent(), ); } /** @test */ public function it_hides_message_from_unknown_exceptions_by_default(): void { - $exception = new \Exception('Unknown Error'); + $exception = new Exception('Unknown Error'); $response = VndErrorResponse::fromThrowable($exception); @@ -73,16 +76,16 @@ public function it_hides_message_from_unknown_exceptions_by_default(): void json_encode( [ 'message' => 'Internal Server Error', - ] + ], ), - $response->getContent() + $response->getContent(), ); } /** @test */ public function it_exposes_message_from_unknown_exceptions_in_debug_mode(): void { - $exception = new \Exception('Unknown Error'); + $exception = new Exception('Unknown Error'); $response = VndErrorResponse::fromThrowable($exception, true, true); @@ -91,9 +94,9 @@ public function it_exposes_message_from_unknown_exceptions_in_debug_mode(): void json_encode( [ 'message' => 'Unknown Error', - ] + ], ), - $response->getContent() + $response->getContent(), ); } @@ -108,14 +111,14 @@ public function it_exposes_message_from_hal_exceptions_in_debug_mode(): void json_encode( [ 'message' => 'Message', - ] + ], ), - $response->getContent() + $response->getContent(), ); } } -final class EmptyHalException extends \Exception implements HalException +final class EmptyHalException extends Exception implements HalException { public function getHal(): Hal {