From 17594333965c70947f9f582b1b39ea7b36a5cb6c Mon Sep 17 00:00:00 2001 From: Olivier Laviale Date: Sat, 2 Nov 2024 01:22:15 +0100 Subject: [PATCH] Support PHP 8.4+ --- .github/workflows/test.yml | 1 + Makefile | 5 +++++ README.md | 2 +- lib/AuthenticationRequired.php | 2 +- lib/ClientError.php | 4 ++-- lib/File.php | 19 ++++--------------- lib/FileInfo.php | 2 +- lib/FileResponse.php | 16 +--------------- lib/ForceRedirect.php | 2 +- lib/Headers/CacheControl.php | 6 ++---- lib/Headers/ContentDisposition.php | 2 +- lib/Headers/ContentType.php | 2 +- lib/Headers/Date.php | 14 ++------------ lib/MethodNotAllowed.php | 2 +- lib/NotFound.php | 2 +- lib/PermissionRequired.php | 2 +- lib/RecoverEvent.php | 2 +- .../WithEvent/BeforeRespondEvent.php | 2 +- lib/Responder/WithEvent/RespondEvent.php | 2 +- lib/ServerError.php | 4 ++-- lib/ServiceUnavailable.php | 2 +- lib/Status.php | 2 +- lib/StatusCodeNotValid.php | 4 ++-- phpunit.xml | 5 +++++ tests/FileResponseTest.php | 11 +---------- tests/Headers/HeaderTest.php | 2 +- tests/ResponderProvider/ChainTest.php | 2 +- 27 files changed, 43 insertions(+), 78 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 71ad2c8..83b4554 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -13,6 +13,7 @@ jobs: php-version: - "8.2" - "8.3" + - "8.4" steps: - name: Checkout uses: actions/checkout@v4 diff --git a/Makefile b/Makefile index c162fdd..0aaf8d9 100644 --- a/Makefile +++ b/Makefile @@ -43,6 +43,11 @@ test-container-83: @-docker-compose run --rm app83 bash @docker-compose down -v +.PHONY: test-container-84 +test-container-84: + @-docker-compose run --rm app84 bash + @docker-compose down -v + .PHONY: lint lint: @XDEBUG_MODE=off phpcs -s diff --git a/README.md b/README.md index 9bd47a0..d2bce53 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ [![Release](https://img.shields.io/packagist/v/icanboogie/http.svg)](https://packagist.org/packages/icanboogie/http) [![Code Quality](https://img.shields.io/scrutinizer/g/ICanBoogie/HTTP/6.0.svg)](https://scrutinizer-ci.com/g/ICanBoogie/HTTP) -[![Code Coverage](https://img.shields.io/coveralls/ICanBoogie/HTTP.svg)](https://coveralls.io/r/ICanBoogie/HTTP) +[![Code Coverage](https://coveralls.io/repos/github/ICanBoogie/HTTP/badge.svg?branch6.0)](https://coveralls.io/r/ICanBoogie/HTTP?branch=6.0) [![Packagist](https://img.shields.io/packagist/dt/icanboogie/http.svg)](https://packagist.org/packages/icanboogie/http) The **icanboogie/http** package provides a foundation to handle HTTP requests, with representations diff --git a/lib/AuthenticationRequired.php b/lib/AuthenticationRequired.php index 48688e5..0f21776 100644 --- a/lib/AuthenticationRequired.php +++ b/lib/AuthenticationRequired.php @@ -28,7 +28,7 @@ class AuthenticationRequired extends ClientError implements SecurityError public function __construct( string $message = self::DEFAULT_MESSAGE, int $code = ResponseStatus::STATUS_UNAUTHORIZED, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($message, $code, $previous); } diff --git a/lib/ClientError.php b/lib/ClientError.php index bf49cc8..1a10afc 100644 --- a/lib/ClientError.php +++ b/lib/ClientError.php @@ -24,9 +24,9 @@ class ClientError extends \Exception implements Exception * @inheritdoc */ public function __construct( - string $message = null, + ?string $message = null, int $code = ResponseStatus::STATUS_BAD_REQUEST, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($message, $code, $previous); } diff --git a/lib/File.php b/lib/File.php index 4717b36..a4b782f 100644 --- a/lib/File.php +++ b/lib/File.php @@ -1,14 +1,5 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace ICanBoogie\HTTP; use ICanBoogie\Accessor\AccessorTrait; @@ -37,8 +28,8 @@ * * @property-read string $name Name of the file. * @property-read string $type MIME type of the file. - * @property-read string $size Size of the file. - * @property-read string $error Error code, one of `UPLOAD_ERR_*`. + * @property-read int|false $size Size of the file. + * @property-read int|null $error Error code, one of `UPLOAD_ERR_*`. * @property-read string $error_message A formatted message representing the error. * @property-read string $pathname Pathname of the file. * @property-read string $extension The extension of the file. If any, the dot is included e.g. @@ -116,17 +107,15 @@ private static function filter_initial_properties(array $properties): array * * @param string $format The format of the string. * @param array $args The arguments. - * @param array $options Some options. * * @return FormattedString|string */ private static function format( string $format, array $args = [], - array $options = [] ): string|FormattedString { - if (class_exists(FormattedString::class, true)) { - return new FormattedString($format, $args, $options); + if (class_exists(FormattedString::class)) { + return new FormattedString($format, $args); } return format($format, $args); // @codeCoverageIgnore diff --git a/lib/FileInfo.php b/lib/FileInfo.php index 2df8b53..b12e711 100644 --- a/lib/FileInfo.php +++ b/lib/FileInfo.php @@ -64,7 +64,7 @@ class FileInfo * @return string The MIME type of the file, or `application/octet-stream` if it could not * be determined. */ - public static function resolve_type(string $pathname, string &$extension = null): string + public static function resolve_type(string $pathname, ?string &$extension = null): string { $extension = '.' . \strtolower(\pathinfo($pathname, PATHINFO_EXTENSION)); $types = self::TYPES; diff --git a/lib/FileResponse.php b/lib/FileResponse.php index 3dc12c5..ac39540 100644 --- a/lib/FileResponse.php +++ b/lib/FileResponse.php @@ -1,14 +1,5 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace ICanBoogie\HTTP; use ICanBoogie\DateTime; @@ -332,11 +323,6 @@ private function make_etag(): string return self::hash_file($this->file->getPathname()); } - private function ensure_etag(): string - { - return $this->headers->etag ??= $this->make_etag(); - } - /** * If the date returned by the parent is empty the method returns a date created from * {@link DEFAULT_EXPIRES}. @@ -349,7 +335,7 @@ protected function get_expires(): Headers\Date return $expires; } - return Headers\Date::from(self::DEFAULT_EXPIRES); // @phpstan-ignore-line + return Headers\Date::from(self::DEFAULT_EXPIRES); } /** diff --git a/lib/ForceRedirect.php b/lib/ForceRedirect.php index baa4f9c..12437b8 100644 --- a/lib/ForceRedirect.php +++ b/lib/ForceRedirect.php @@ -25,7 +25,7 @@ class ForceRedirect extends \Exception implements Exception public function __construct( public readonly string $location, int $code = ResponseStatus::STATUS_FOUND, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($this->format_message($location), $code, $previous); } diff --git a/lib/Headers/CacheControl.php b/lib/Headers/CacheControl.php index 4018c06..51162fd 100644 --- a/lib/Headers/CacheControl.php +++ b/lib/Headers/CacheControl.php @@ -45,7 +45,7 @@ * echo $cc; // no-cache, no-store, must-revalidate * * - * @property bool $cacheable + * @property bool|string|null $cacheable * * @see http://tools.ietf.org/html/rfc2616#section-14.9 */ @@ -169,8 +169,6 @@ public static function from(string|self|null $source): self * Scope: request, response. * * @see http://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.9.1 - * - * @var string|null */ private ?string $cacheable = null; @@ -290,7 +288,7 @@ private function set_cacheable(bool|string|null $value): void /** * If they are defined, the object is initialized with the cache directives. */ - public function __construct(string $cache_directives = null) + public function __construct(?string $cache_directives = null) { if ($cache_directives) { $this->modify($cache_directives); diff --git a/lib/Headers/ContentDisposition.php b/lib/Headers/ContentDisposition.php index c4dda60..e8dc451 100644 --- a/lib/Headers/ContentDisposition.php +++ b/lib/Headers/ContentDisposition.php @@ -41,7 +41,7 @@ class ContentDisposition extends Header * * @inheritdoc */ - public function __construct(string $value = null, array $attributes = []) + public function __construct(?string $value = null, array $attributes = []) { $this->parameters['filename'] = new HeaderParameter('filename'); diff --git a/lib/Headers/ContentType.php b/lib/Headers/ContentType.php index a0304ca..7569e49 100644 --- a/lib/Headers/ContentType.php +++ b/lib/Headers/ContentType.php @@ -43,7 +43,7 @@ class ContentType extends Header * * @inheritdoc */ - public function __construct(string $value = null, array $attributes = []) + public function __construct(?string $value = null, array $attributes = []) { $this->parameters['charset'] = new HeaderParameter('charset'); diff --git a/lib/Headers/Date.php b/lib/Headers/Date.php index 908431e..17db066 100644 --- a/lib/Headers/Date.php +++ b/lib/Headers/Date.php @@ -1,14 +1,5 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace ICanBoogie\HTTP\Headers; use DateTimeInterface; @@ -27,8 +18,7 @@ class Date extends DateTime public static function from( self|\DateTime|string|null $source, DateTimeZone|string|null $timezone = null - ): static - { + ): static { if ($source === null) { return static::none(); } @@ -62,7 +52,7 @@ public function __construct($time = 'now', $timezone = null) * * @inheritdoc */ - public function __toString() + public function __toString(): string { return $this->is_empty ? '' : $this->utc->as_rfc1123; } diff --git a/lib/MethodNotAllowed.php b/lib/MethodNotAllowed.php index b09868d..c2d9928 100644 --- a/lib/MethodNotAllowed.php +++ b/lib/MethodNotAllowed.php @@ -20,7 +20,7 @@ class MethodNotAllowed extends ClientError implements Exception { public function __construct( public readonly string $method, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct( "Method not allowed: $method.", diff --git a/lib/NotFound.php b/lib/NotFound.php index c9e5f68..c70f87d 100644 --- a/lib/NotFound.php +++ b/lib/NotFound.php @@ -26,7 +26,7 @@ class NotFound extends ClientError implements Exception public function __construct( string $message = self::DEFAULT_MESSAGE, int $code = ResponseStatus::STATUS_NOT_FOUND, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($message, $code, $previous); } diff --git a/lib/PermissionRequired.php b/lib/PermissionRequired.php index 8866257..c942c9e 100644 --- a/lib/PermissionRequired.php +++ b/lib/PermissionRequired.php @@ -26,7 +26,7 @@ class PermissionRequired extends ClientError implements SecurityError public function __construct( string $message = self::DEFAULT_MESSAGE, int $code = ResponseStatus::STATUS_UNAUTHORIZED, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($message, $code, $previous); } diff --git a/lib/RecoverEvent.php b/lib/RecoverEvent.php index f6fb316..e4aee4e 100644 --- a/lib/RecoverEvent.php +++ b/lib/RecoverEvent.php @@ -25,7 +25,7 @@ class RecoverEvent extends Event public function __construct( Throwable &$sender, public readonly Request $request, - Response &$response = null + ?Response &$response = null ) { $this->response = &$response; $this->exception = &$sender; diff --git a/lib/Responder/WithEvent/BeforeRespondEvent.php b/lib/Responder/WithEvent/BeforeRespondEvent.php index c810ff5..86cbd30 100644 --- a/lib/Responder/WithEvent/BeforeRespondEvent.php +++ b/lib/Responder/WithEvent/BeforeRespondEvent.php @@ -24,7 +24,7 @@ class BeforeRespondEvent extends Event public function __construct( public readonly Request $request, - Response &$response = null + ?Response &$response = null ) { $this->response = &$response; diff --git a/lib/Responder/WithEvent/RespondEvent.php b/lib/Responder/WithEvent/RespondEvent.php index f93be1f..2395356 100644 --- a/lib/Responder/WithEvent/RespondEvent.php +++ b/lib/Responder/WithEvent/RespondEvent.php @@ -24,7 +24,7 @@ class RespondEvent extends Event public function __construct( public readonly Request $request, - Response &$response = null + ?Response &$response = null ) { $this->response = &$response; diff --git a/lib/ServerError.php b/lib/ServerError.php index 9e187c3..64e44f8 100644 --- a/lib/ServerError.php +++ b/lib/ServerError.php @@ -24,9 +24,9 @@ class ServerError extends \Exception implements Exception * @inheritdoc */ public function __construct( - string $message = null, + ?string $message = null, int $code = ResponseStatus::STATUS_INTERNAL_SERVER_ERROR, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($message, $code, $previous); } diff --git a/lib/ServiceUnavailable.php b/lib/ServiceUnavailable.php index 5b50f29..9fdef95 100644 --- a/lib/ServiceUnavailable.php +++ b/lib/ServiceUnavailable.php @@ -28,7 +28,7 @@ class ServiceUnavailable extends ServerError implements Exception public function __construct( string $message = self::DEFAULT_MESSAGE, int $code = ResponseStatus::STATUS_SERVICE_UNAVAILABLE, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($message, $code, $previous); } diff --git a/lib/Status.php b/lib/Status.php index 803c856..df9fb80 100644 --- a/lib/Status.php +++ b/lib/Status.php @@ -521,7 +521,7 @@ protected function get_message(): string return $message; } - public function __construct(int $code = ResponseStatus::STATUS_OK, string $message = null) + public function __construct(int $code = ResponseStatus::STATUS_OK, ?string $message = null) { self::assert_code_is_valid($code); diff --git a/lib/StatusCodeNotValid.php b/lib/StatusCodeNotValid.php index ef72209..2204c4d 100644 --- a/lib/StatusCodeNotValid.php +++ b/lib/StatusCodeNotValid.php @@ -23,9 +23,9 @@ class StatusCodeNotValid extends InvalidArgumentException implements Exception { public function __construct( public readonly int $status_code, - string $message = null, + ?string $message = null, int $code = ResponseStatus::STATUS_INTERNAL_SERVER_ERROR, - Throwable $previous = null + ?Throwable $previous = null ) { parent::__construct($message ?: $this->format_message($status_code), $code, $previous); } diff --git a/phpunit.xml b/phpunit.xml index 345d767..569681c 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -16,4 +16,9 @@ ./tests + + + lib + + diff --git a/tests/FileResponseTest.php b/tests/FileResponseTest.php index 431fbdf..125f604 100644 --- a/tests/FileResponseTest.php +++ b/tests/FileResponseTest.php @@ -1,14 +1,5 @@ - * - * For the full copyright and license information, please view the LICENSE - * file that was distributed with this source code. - */ - namespace ICanBoogie\HTTP; use ICanBoogie\DateTime; @@ -259,7 +250,7 @@ public function test_get_is_modified( bool $expected, array $request_headers, false|int $modified_time = false, - string $etag = null + ?string $etag = null ): void { $file = create_file(); if ($modified_time) { diff --git a/tests/Headers/HeaderTest.php b/tests/Headers/HeaderTest.php index 84a5288..1032fc6 100644 --- a/tests/Headers/HeaderTest.php +++ b/tests/Headers/HeaderTest.php @@ -152,7 +152,7 @@ class A extends Header { public const VALUE_ALIAS = 'type'; - public function __construct($value = null, array $attributes = []) + public function __construct(mixed $value = null, array $attributes = []) { $this->parameters['p'] = new HeaderParameter('p'); diff --git a/tests/ResponderProvider/ChainTest.php b/tests/ResponderProvider/ChainTest.php index a6f142c..c72a2a2 100644 --- a/tests/ResponderProvider/ChainTest.php +++ b/tests/ResponderProvider/ChainTest.php @@ -47,7 +47,7 @@ public function test_chain_with_no_match(): void $this->assertNull($chain->responder_for_request(Request::from())); } - public function makeProvider(Responder $responder = null, bool $shouldNotBeCalled = false): ResponderProvider + public function makeProvider(?Responder $responder = null, bool $shouldNotBeCalled = false): ResponderProvider { $provider = $this->createMock(ResponderProvider::class); $provider