From 295caf6b6c5c10f3df77aa7138e2d6f576361f8f Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 08:48:29 +0200 Subject: [PATCH 01/11] Set PHPStan level to 6 --- phpstan.neon | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/phpstan.neon b/phpstan.neon index 1c1d972a..4a08b7dd 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -1,5 +1,7 @@ parameters: - level: 5 + level: 6 + checkMissingIterableValueType: false + checkGenericClassInNonGenericObjectType: false paths: - app - src From e98b0c3f498a87585c5b9877478d263216006384 Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 08:49:06 +0200 Subject: [PATCH 02/11] Add void return type --- app/Console/AbstractReindexCommand.php | 5 +---- src/ElasticSearch/IndexationStrategy/IndexationStrategy.php | 2 +- .../Validation/ElasticSearchResponseValidatorInterface.php | 2 +- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/app/Console/AbstractReindexCommand.php b/app/Console/AbstractReindexCommand.php index 4bbc9ca3..2e68c91f 100644 --- a/app/Console/AbstractReindexCommand.php +++ b/app/Console/AbstractReindexCommand.php @@ -63,14 +63,11 @@ public function __construct( $this->indexationStrategy = $indexationStrategy; } - /** - * @inheritdoc - */ protected function runOperation( InputInterface $input, OutputInterface $output, AbstractReindexUDB3CoreOperation $operation - ) { + ): void { $indexationStrategy = $this->getIndexationStrategy(); $logger = $this->getLogger($output); diff --git a/src/ElasticSearch/IndexationStrategy/IndexationStrategy.php b/src/ElasticSearch/IndexationStrategy/IndexationStrategy.php index cce60dd4..dd8b6398 100644 --- a/src/ElasticSearch/IndexationStrategy/IndexationStrategy.php +++ b/src/ElasticSearch/IndexationStrategy/IndexationStrategy.php @@ -12,7 +12,7 @@ public function indexDocument( string $indexName, string $documentType, JsonDocument $jsonDocument - ); + ): void; public function finish(): void; } diff --git a/src/ElasticSearch/Validation/ElasticSearchResponseValidatorInterface.php b/src/ElasticSearch/Validation/ElasticSearchResponseValidatorInterface.php index ed45520a..5761cada 100644 --- a/src/ElasticSearch/Validation/ElasticSearchResponseValidatorInterface.php +++ b/src/ElasticSearch/Validation/ElasticSearchResponseValidatorInterface.php @@ -12,5 +12,5 @@ interface ElasticSearchResponseValidatorInterface * * @throws InvalidElasticSearchResponseException */ - public function validate(array $responseData); + public function validate(array $responseData): void; } From 51fff5c098f60bc8abaff5e724c33559995d4f09 Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 08:50:04 +0200 Subject: [PATCH 03/11] Typehint `AbstractMappingCommand` constructor --- app/Console/AbstractMappingCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/Console/AbstractMappingCommand.php b/app/Console/AbstractMappingCommand.php index 87cdda0f..10ea985f 100644 --- a/app/Console/AbstractMappingCommand.php +++ b/app/Console/AbstractMappingCommand.php @@ -18,7 +18,7 @@ abstract class AbstractMappingCommand extends AbstractElasticSearchCommand */ protected $documentType; - public function __construct(Client $client, $indexName, $documentType) + public function __construct(Client $client, string $indexName, string $documentType) { parent::__construct($client); $this->indexName = $indexName; From 6061036ea528c11737ccaf7b1451a471f7561762 Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 08:51:09 +0200 Subject: [PATCH 04/11] Typehint `getReadableEventType` from `AbstractReindexUDB3CoreOperation` --- .../Operations/AbstractReindexUDB3CoreOperation.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/ElasticSearch/Operations/AbstractReindexUDB3CoreOperation.php b/src/ElasticSearch/Operations/AbstractReindexUDB3CoreOperation.php index 7f47e13d..a4b4f237 100644 --- a/src/ElasticSearch/Operations/AbstractReindexUDB3CoreOperation.php +++ b/src/ElasticSearch/Operations/AbstractReindexUDB3CoreOperation.php @@ -4,6 +4,7 @@ namespace CultuurNet\UDB3\Search\ElasticSearch\Operations; +use Broadway\Serializer\Serializable; use Exception; use Broadway\Domain\DomainEventStream; use Broadway\Domain\DomainMessage; @@ -166,7 +167,7 @@ private function dispatchEventForHit(array $hit): void } - private function getReadableEventType($event): string + private function getReadableEventType(Serializable $event): string { $parts = explode('\\', get_class($event)); return end($parts); From 9caa06e1f158d983d85af8061337391e74dd9dd6 Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 08:51:55 +0200 Subject: [PATCH 05/11] Typehint `DocumentGone` constructor --- src/ReadModel/DocumentGone.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/ReadModel/DocumentGone.php b/src/ReadModel/DocumentGone.php index 19dab42a..ee14ebb2 100644 --- a/src/ReadModel/DocumentGone.php +++ b/src/ReadModel/DocumentGone.php @@ -9,7 +9,7 @@ final class DocumentGone extends RuntimeException { - public function __construct($message = '', $code = 410, Exception $previous = null) + public function __construct(string $message = '', int $code = 410, Exception $previous = null) { parent::__construct($message, $code, $previous); } From 51a641339569f4d018d8f41d67d8275dbcda565d Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 08:56:21 +0200 Subject: [PATCH 06/11] Improve doc blocks --- app/BaseServiceProvider.php | 4 ++-- src/ElasticSearch/AbstractElasticSearchQueryBuilder.php | 4 ++++ src/Http/ApiRequestInterface.php | 8 ++++++++ src/Http/ResponseFactory.php | 3 +++ src/ReadModel/JsonDocument.php | 3 +++ tests/Http/OfferSearchControllerTest.php | 3 +++ tests/Http/Parameters/ArrayParameterBagAdapterTest.php | 2 +- 7 files changed, 24 insertions(+), 3 deletions(-) diff --git a/app/BaseServiceProvider.php b/app/BaseServiceProvider.php index 9c5ba00c..a0a626ca 100644 --- a/app/BaseServiceProvider.php +++ b/app/BaseServiceProvider.php @@ -31,7 +31,7 @@ protected function addShared(string $serviceName, callable $function, ?string $t /** * Get parameter from config - * + * @return mixed|null */ protected function parameter(string $parameter) { @@ -40,7 +40,7 @@ protected function parameter(string $parameter) /** * Get service from container - * + * @return object */ protected function get(string $name) { diff --git a/src/ElasticSearch/AbstractElasticSearchQueryBuilder.php b/src/ElasticSearch/AbstractElasticSearchQueryBuilder.php index c18f4c51..12683056 100644 --- a/src/ElasticSearch/AbstractElasticSearchQueryBuilder.php +++ b/src/ElasticSearch/AbstractElasticSearchQueryBuilder.php @@ -276,6 +276,10 @@ protected function withRangeQuery(string $fieldName, $from = null, $to = null) return $c; } + /** + * @param string|int|null $from + * @param string|int|null $to + */ protected function createRangeQuery(string $fieldName, $from = null, $to = null): ?RangeQuery { $parameters = array_filter( diff --git a/src/Http/ApiRequestInterface.php b/src/Http/ApiRequestInterface.php index 4db50515..a9fe7965 100644 --- a/src/Http/ApiRequestInterface.php +++ b/src/Http/ApiRequestInterface.php @@ -17,6 +17,10 @@ */ interface ApiRequestInterface extends ServerRequestInterface { + /** + * @param mixed|null $default + * @return mixed|null + */ public function getQueryParam(string $name, $default = null); public function hasQueryParam(string $name): bool; @@ -25,5 +29,9 @@ public function getQueryParamsKeys(): ?array; public function getQueryParameterBag(): ParameterBagInterface; + /** + * @param mixed|null $default + * @return mixed|null + */ public function getServerParam(string $name, $default = null); } diff --git a/src/Http/ResponseFactory.php b/src/Http/ResponseFactory.php index d1399c5d..dcf6aabe 100644 --- a/src/Http/ResponseFactory.php +++ b/src/Http/ResponseFactory.php @@ -30,6 +30,9 @@ public static function apiProblem($data, int $code = StatusCodeInterface::STATUS return self::jsonWithCustomContentType('application/problem+json', $data, $code); } + /** + * @param array|object $data + */ private static function jsonWithCustomContentType( string $contentType, $data, diff --git a/src/ReadModel/JsonDocument.php b/src/ReadModel/JsonDocument.php index eaabe681..822c4267 100644 --- a/src/ReadModel/JsonDocument.php +++ b/src/ReadModel/JsonDocument.php @@ -35,6 +35,9 @@ public function getRawBody(): string return $this->body; } + /** + * @param object|array $body + */ public function withBody($body): JsonDocument { return new self($this->id, Json::encode($body)); diff --git a/tests/Http/OfferSearchControllerTest.php b/tests/Http/OfferSearchControllerTest.php index dbd6c43f..e360cf55 100644 --- a/tests/Http/OfferSearchControllerTest.php +++ b/tests/Http/OfferSearchControllerTest.php @@ -675,6 +675,7 @@ public function it_works_with_a_min_price_and_max_price_if_no_exact_price_is_set /** * @test + * @param bool|string|int $stringValue * @dataProvider booleanStringDataProvider */ public function it_converts_the_media_objects_toggle_parameter_to_a_correct_boolean( @@ -704,6 +705,7 @@ public function it_converts_the_media_objects_toggle_parameter_to_a_correct_bool /** * @test + * @param bool|string|int $stringValue * @dataProvider booleanStringDataProvider */ public function it_converts_the_uitpas_toggle_parameter_to_a_correct_boolean( @@ -907,6 +909,7 @@ public function it_transforms_the_request_address_country_to_uppercase(): void /** * @test * @dataProvider malformedDateTimeProvider + * @param bool|string|int $malformedDateTimeAsString * @todo PHP8 upgrade: change Type hint to string|bool */ public function it_throws_an_exception_for_a_malformed_date_from($malformedDateTimeAsString): void diff --git a/tests/Http/Parameters/ArrayParameterBagAdapterTest.php b/tests/Http/Parameters/ArrayParameterBagAdapterTest.php index e7670ee6..63c2039f 100644 --- a/tests/Http/Parameters/ArrayParameterBagAdapterTest.php +++ b/tests/Http/Parameters/ArrayParameterBagAdapterTest.php @@ -308,8 +308,8 @@ public function it_should_return_an_empty_array_for_a_delimited_string_parameter /** * @test + * @param bool|string|int $parameterValue * @dataProvider booleanDataProvider - * */ public function it_should_parse_a_boolean_value_from_a_parameter( $parameterValue, From e6cd4ec2fcf46602905a7e6403fc92993cc91649 Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 08:56:55 +0200 Subject: [PATCH 07/11] Improve `ArrayParameterBagAdapter` type hinting --- src/Http/Parameters/ArrayParameterBagAdapter.php | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/src/Http/Parameters/ArrayParameterBagAdapter.php b/src/Http/Parameters/ArrayParameterBagAdapter.php index a091ccf6..8e124c99 100644 --- a/src/Http/Parameters/ArrayParameterBagAdapter.php +++ b/src/Http/Parameters/ArrayParameterBagAdapter.php @@ -85,10 +85,10 @@ public function getIntegerFromParameter( } public function getExplodedStringFromParameter( - $parameterName, - $defaultValueAsString = null, + string $parameterName, + ?string $defaultValueAsString = null, callable $callback = null, - $delimiter = ',' + string $delimiter = ',' ): array { $callback = $this->ensureCallback($callback); @@ -148,10 +148,13 @@ public function getDateTimeFromParameter(string $queryParameter, ?string $defaul return $this->getStringFromParameter($queryParameter, $defaultValueAsString, $callback); } - private function get(string $queryParameter, $default = null) + /** + * @return mixed|null + */ + private function get(string $queryParameter) { if (!isset($this->parameterBag[$queryParameter])) { - return $default; + return null; } return $this->parameterBag[$queryParameter]; From 71a3ae879206313492cb05859ef9cad697f5eae6 Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 09:07:44 +0200 Subject: [PATCH 08/11] Avoid using `LoggerAwareTrait` which needs update to be compatible --- .../Authentication/Auth0/Auth0MetadataGenerator.php | 11 ++++++++--- .../Keycloak/KeycloakMetadataGenerator.php | 10 +++++++--- src/Http/Authentication/MetadataGenerator.php | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/src/Http/Authentication/Auth0/Auth0MetadataGenerator.php b/src/Http/Authentication/Auth0/Auth0MetadataGenerator.php index 3558683c..7f5e0de7 100644 --- a/src/Http/Authentication/Auth0/Auth0MetadataGenerator.php +++ b/src/Http/Authentication/Auth0/Auth0MetadataGenerator.php @@ -9,17 +9,17 @@ use GuzzleHttp\Client; use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Psr7\Request; -use Psr\Log\LoggerAwareTrait; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; final class Auth0MetadataGenerator implements MetadataGenerator { - use LoggerAwareTrait; - private Client $client; private string $domain; + private LoggerInterface $logger; + public function __construct( Client $client, string $domain @@ -56,4 +56,9 @@ public function get(string $clientId, string $token): ?array $res = Json::decodeAssociatively($response->getBody()->getContents()); return $res['client_metadata'] ?? []; } + + public function setLogger(LoggerInterface $logger): void + { + $this->logger = $logger; + } } diff --git a/src/Http/Authentication/Keycloak/KeycloakMetadataGenerator.php b/src/Http/Authentication/Keycloak/KeycloakMetadataGenerator.php index 30a12e52..5f8ce069 100644 --- a/src/Http/Authentication/Keycloak/KeycloakMetadataGenerator.php +++ b/src/Http/Authentication/Keycloak/KeycloakMetadataGenerator.php @@ -10,16 +10,15 @@ use GuzzleHttp\Exception\ConnectException; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Uri; -use Psr\Log\LoggerAwareTrait; +use Psr\Log\LoggerInterface; use Psr\Log\NullLogger; final class KeycloakMetadataGenerator implements MetadataGenerator { - use LoggerAwareTrait; - private Client $client; private string $domain; private string $realm; + private LoggerInterface $logger; public function __construct( Client $client, @@ -94,4 +93,9 @@ private function convertDefaultScopes(array $defaultScopes): array $result['publiq-apis'] = implode(' ', $scopes); return $result; } + + public function setLogger(LoggerInterface $logger): void + { + $this->logger = $logger; + } } diff --git a/src/Http/Authentication/MetadataGenerator.php b/src/Http/Authentication/MetadataGenerator.php index 62dcc702..678fceec 100644 --- a/src/Http/Authentication/MetadataGenerator.php +++ b/src/Http/Authentication/MetadataGenerator.php @@ -10,5 +10,5 @@ interface MetadataGenerator { public function get(string $clientId, string $token): ?array; - public function setLogger(LoggerInterface $logger); + public function setLogger(LoggerInterface $logger): void; } From ec74d2bdb600f071c3647de497c45ced9e1d0d3e Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 09:14:08 +0200 Subject: [PATCH 09/11] Fix type hinting on Json helper class --- src/Json.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Json.php b/src/Json.php index 57848b57..834e79bf 100644 --- a/src/Json.php +++ b/src/Json.php @@ -65,7 +65,7 @@ public static function encodeForHttpResponse($value): string * @param string $data * Encoded JSON data. * - * @returns mixed + * @return mixed|null * Decoded data, usually as an array or stdClass object but can also be a string, integer, boolean, etc depending * on the encoded data. * @@ -81,7 +81,7 @@ public static function decode(string $data) * @param string $data * Encoded JSON data. * - * @returns mixed + * @return mixed|null * Decoded data, usually as an array but can also be a string, integer, boolean, etc depending on the encoded * data. * From afb2d724d1886da1385a3b40bbb86edffa5efe0a Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 09:24:18 +0200 Subject: [PATCH 10/11] Ignore PHPStan warning because run method has different implementations --- tests/ElasticSearch/Operations/AbstractOperationTestCase.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/ElasticSearch/Operations/AbstractOperationTestCase.php b/tests/ElasticSearch/Operations/AbstractOperationTestCase.php index 7e20688f..8768fbd3 100644 --- a/tests/ElasticSearch/Operations/AbstractOperationTestCase.php +++ b/tests/ElasticSearch/Operations/AbstractOperationTestCase.php @@ -27,7 +27,7 @@ abstract class AbstractOperationTestCase extends TestCase */ protected $logger; - + // @phpstan-ignore-next-line protected $operation; protected function setUp(): void @@ -43,5 +43,6 @@ protected function setUp(): void $this->operation = $this->createOperation($this->client, $this->logger); } + // @phpstan-ignore-next-line abstract protected function createOperation(Client $client, LoggerInterface $logger); } From 9a5f47254cff63097995fd52c592941849b1f5ac Mon Sep 17 00:00:00 2001 From: Luc Wollants Date: Fri, 16 Aug 2024 09:25:47 +0200 Subject: [PATCH 11/11] Ignore PHPStan error because this would require a rewrite of the AMQP Forwarder --- src/Deserializer/DeserializerInterface.php | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Deserializer/DeserializerInterface.php b/src/Deserializer/DeserializerInterface.php index f536bab2..c84338c7 100644 --- a/src/Deserializer/DeserializerInterface.php +++ b/src/Deserializer/DeserializerInterface.php @@ -6,5 +6,6 @@ interface DeserializerInterface { + // @phpstan-ignore-next-line public function deserialize(string $data); }