From 58b7c4437e2a4f46f6977be91045fa6f73aa7d47 Mon Sep 17 00:00:00 2001 From: gabrielzigo Date: Fri, 3 Jul 2026 13:20:58 +0200 Subject: [PATCH 1/4] feat: add standardized HttpExceptionHandler and priority-based exception handler ordering --- README.md | 1 + .../AnzuSystemsCommonExtension.php | 8 +++ .../ExceptionHandlerCompilerPass.php | 14 ++-- src/DependencyInjection/Configuration.php | 2 + .../Handler/HttpExceptionHandler.php | 40 +++++++++++ src/Resources/doc/exception_handlers.md | 12 ++++ .../ExceptionHandlerCompilerPassTest.php | 69 +++++++++++++++++++ .../Handler/HttpExceptionHandlerTest.php | 69 +++++++++++++++++++ 8 files changed, 208 insertions(+), 7 deletions(-) create mode 100644 src/Exception/Handler/HttpExceptionHandler.php create mode 100644 tests/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPassTest.php create mode 100644 tests/Exception/Handler/HttpExceptionHandlerTest.php diff --git a/README.md b/README.md index 01aebac..61a174a 100644 --- a/README.md +++ b/README.md @@ -137,6 +137,7 @@ anzu_common: - AnzuSystems\CommonBundle\Exception\Handler\ValidationExceptionHandler - AnzuSystems\CommonBundle\Exception\Handler\AppReadOnlyModeExceptionHandler - AnzuSystems\CommonBundle\Exception\Handler\AccessDeniedExceptionHandler + - AnzuSystems\CommonBundle\Exception\Handler\HttpExceptionHandler logs: enabled: true # Logs are sent through Symfony Messenger. diff --git a/src/DependencyInjection/AnzuSystemsCommonExtension.php b/src/DependencyInjection/AnzuSystemsCommonExtension.php index efbc734..8e0e24d 100644 --- a/src/DependencyInjection/AnzuSystemsCommonExtension.php +++ b/src/DependencyInjection/AnzuSystemsCommonExtension.php @@ -53,6 +53,7 @@ use AnzuSystems\CommonBundle\Exception\Handler\AppReadOnlyModeExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\DefaultExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\ExceptionHandlerInterface; +use AnzuSystems\CommonBundle\Exception\Handler\HttpExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\NotFoundExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\ValidationExceptionHandler; use AnzuSystems\CommonBundle\HealthCheck\HealthChecker; @@ -372,6 +373,13 @@ private function loadErrors(ContainerBuilder $container): void $container->setDefinition(SerializerExceptionHandler::class, $definition); } + if ($hasHandler(HttpExceptionHandler::class)) { + $definition = new Definition(HttpExceptionHandler::class); + $definition->addArgument($debug); + $definition->addTag(AnzuSystemsCommonBundle::TAG_EXCEPTION_HANDLER, ['priority' => -100]); + $container->setDefinition(HttpExceptionHandler::class, $definition); + } + $container ->getDefinition(ExceptionListener::class) ->replaceArgument('$defaultExceptionHandler', new Reference($errors['default_exception_handler'])) diff --git a/src/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPass.php b/src/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPass.php index 6e6fa01..8ccb79d 100644 --- a/src/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPass.php +++ b/src/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPass.php @@ -8,25 +8,25 @@ use AnzuSystems\CommonBundle\Event\Listener\ExceptionListener; use Symfony\Component\DependencyInjection\Argument\IteratorArgument; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; +use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Reference; final class ExceptionHandlerCompilerPass implements CompilerPassInterface { + use PriorityTaggedServiceTrait; + public function process(ContainerBuilder $container): void { if (false === $container->hasDefinition(ExceptionListener::class)) { return; } - $references = []; - foreach (array_keys($container->findTaggedServiceIds(AnzuSystemsCommonBundle::TAG_EXCEPTION_HANDLER)) as $service) { - $references[] = new Reference($service); - } - $container ->getDefinition(ExceptionListener::class) - ->replaceArgument('$exceptionHandlers', new IteratorArgument($references)) + ->replaceArgument( + '$exceptionHandlers', + new IteratorArgument($this->findAndSortTaggedServices(AnzuSystemsCommonBundle::TAG_EXCEPTION_HANDLER, $container)) + ) ; } } diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 72fd012..3364286 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -28,6 +28,7 @@ use AnzuSystems\CommonBundle\Exception\Handler\AppReadOnlyModeExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\DefaultExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\ExceptionHandlerInterface; +use AnzuSystems\CommonBundle\Exception\Handler\HttpExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\NotFoundExceptionHandler; use AnzuSystems\CommonBundle\Exception\Handler\ValidationExceptionHandler; use AnzuSystems\CommonBundle\HealthCheck\Module\DataMountModule; @@ -67,6 +68,7 @@ final class Configuration implements ConfigurationInterface AppReadOnlyModeExceptionHandler::class, AccessDeniedExceptionHandler::class, SerializerExceptionHandler::class, + HttpExceptionHandler::class, ]; private const array HEALTH_CHECK_MODULES = [ MysqlModule::class, diff --git a/src/Exception/Handler/HttpExceptionHandler.php b/src/Exception/Handler/HttpExceptionHandler.php new file mode 100644 index 0000000..f355aae --- /dev/null +++ b/src/Exception/Handler/HttpExceptionHandler.php @@ -0,0 +1,40 @@ + self::ERROR, + 'detail' => $this->debug ? $exception->getMessage() : 'An error occurred', + 'contextId' => AnzuApp::getContextId(), + ], + $exception->getStatusCode() + ); + } + + public function getSupportedExceptionClasses(): array + { + return [HttpException::class]; + } +} diff --git a/src/Resources/doc/exception_handlers.md b/src/Resources/doc/exception_handlers.md index 19a9578..a152dc5 100644 --- a/src/Resources/doc/exception_handlers.md +++ b/src/Resources/doc/exception_handlers.md @@ -46,8 +46,20 @@ anzu_systems_common: - AnzuSystems\CommonBundle\Exception\Handler\AppReadOnlyModeExceptionHandler - AnzuSystems\CommonBundle\Exception\Handler\AccessDeniedExceptionHandler - AnzuSystems\CommonBundle\Serializer\Exception\SerializerExceptionHandler + - AnzuSystems\CommonBundle\Exception\Handler\HttpExceptionHandler ``` #### Register your own exception handler To register your own handler, just implement [ExceptionHandlerInterface](https://github.com/anzusystems/common-bundle/blob/main/src/Exception/Handler/ExceptionHandlerInterface.php). If your application is using autoconfiguration, it will autoconfigure your service with tag `anzu_systems_common.logs.exception_handler` and `ExceptionListener` will use your own handler. In case you are not using autoconfiguration, tag your service on your own. + +#### Handler ordering + +Handlers are sorted by the `priority` attribute of the `anzu_systems_common.logs.exception_handler` tag (higher priority first, default is `0`) and the first handler supporting the thrown exception class wins. [HttpExceptionHandler](https://github.com/anzusystems/common-bundle/blob/main/src/Exception/Handler/HttpExceptionHandler.php) is registered with priority `-100`, so more specific handlers (e.g. [AccessDeniedExceptionHandler](https://github.com/anzusystems/common-bundle/blob/main/src/Exception/Handler/AccessDeniedExceptionHandler.php), [NotFoundExceptionHandler](https://github.com/anzusystems/common-bundle/blob/main/src/Exception/Handler/NotFoundExceptionHandler.php) or your own handlers) always take precedence for their exception classes: + +```yaml +services: + App\Exception\Handler\YourExceptionHandler: + tags: + - { name: anzu_systems_common.logs.exception_handler, priority: 10 } +``` diff --git a/tests/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPassTest.php b/tests/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPassTest.php new file mode 100644 index 0000000..9cbab8f --- /dev/null +++ b/tests/DependencyInjection/CompilerPass/ExceptionHandlerCompilerPassTest.php @@ -0,0 +1,69 @@ +setArgument('$exceptionHandlers', new IteratorArgument([])); + $container->setDefinition(ExceptionListener::class, $listener); + + $httpHandler = new Definition(HttpExceptionHandler::class); + $httpHandler->addTag(AnzuSystemsCommonBundle::TAG_EXCEPTION_HANDLER, ['priority' => -100]); + $container->setDefinition(HttpExceptionHandler::class, $httpHandler); + + $accessDeniedHandler = new Definition(AccessDeniedExceptionHandler::class); + $accessDeniedHandler->addTag(AnzuSystemsCommonBundle::TAG_EXCEPTION_HANDLER); + $container->setDefinition(AccessDeniedExceptionHandler::class, $accessDeniedHandler); + + $notFoundHandler = new Definition(NotFoundExceptionHandler::class); + $notFoundHandler->addTag(AnzuSystemsCommonBundle::TAG_EXCEPTION_HANDLER); + $container->setDefinition(NotFoundExceptionHandler::class, $notFoundHandler); + + $container->setDefinition(DefaultExceptionHandler::class, new Definition(DefaultExceptionHandler::class)); + + (new ExceptionHandlerCompilerPass())->process($container); + + $argument = $container->getDefinition(ExceptionListener::class)->getArgument('$exceptionHandlers'); + self::assertInstanceOf(IteratorArgument::class, $argument); + self::assertSame( + [ + AccessDeniedExceptionHandler::class, + NotFoundExceptionHandler::class, + HttpExceptionHandler::class, + ], + array_map( + static fn (Reference $reference): string => (string) $reference, + $argument->getValues() + ) + ); + } + + public function testProcessSkipsContainerWithoutListener(): void + { + $container = new ContainerBuilder(); + + (new ExceptionHandlerCompilerPass())->process($container); + + self::assertFalse($container->hasDefinition(ExceptionListener::class)); + } +} diff --git a/tests/Exception/Handler/HttpExceptionHandlerTest.php b/tests/Exception/Handler/HttpExceptionHandlerTest.php new file mode 100644 index 0000000..910150e --- /dev/null +++ b/tests/Exception/Handler/HttpExceptionHandlerTest.php @@ -0,0 +1,69 @@ +getErrorResponse($exception); + $content = json_decode((string) $response->getContent(), true); + + self::assertSame($expectedStatusCode, $response->getStatusCode()); + self::assertSame(HttpExceptionHandler::ERROR, $content['error']); + self::assertSame($expectedDetail, $content['detail']); + self::assertNotEmpty($content['contextId']); + } + + /** + * @return array + */ + public static function getErrorResponseDataProvider(): array + { + return [ + 'conflict with debug enabled' => [ + 'exception' => new ConflictHttpException('Conflict detail message'), + 'debug' => true, + 'expectedStatusCode' => JsonResponse::HTTP_CONFLICT, + 'expectedDetail' => 'Conflict detail message', + ], + 'conflict with debug disabled' => [ + 'exception' => new ConflictHttpException('Conflict detail message'), + 'debug' => false, + 'expectedStatusCode' => JsonResponse::HTTP_CONFLICT, + 'expectedDetail' => 'An error occurred', + ], + 'service unavailable keeps status code' => [ + 'exception' => new ServiceUnavailableHttpException(message: 'Service down'), + 'debug' => true, + 'expectedStatusCode' => JsonResponse::HTTP_SERVICE_UNAVAILABLE, + 'expectedDetail' => 'Service down', + ], + 'plain http exception keeps custom status code' => [ + 'exception' => new HttpException(JsonResponse::HTTP_METHOD_NOT_ALLOWED, 'Method not allowed here'), + 'debug' => false, + 'expectedStatusCode' => JsonResponse::HTTP_METHOD_NOT_ALLOWED, + 'expectedDetail' => 'An error occurred', + ], + ]; + } + + public function testGetSupportedExceptionClasses(): void + { + self::assertSame([HttpException::class], (new HttpExceptionHandler())->getSupportedExceptionClasses()); + } +} From f84f0f0807c93fcb756c27172e5927b9d6248a81 Mon Sep 17 00:00:00 2001 From: gabrielzigo Date: Fri, 3 Jul 2026 13:31:40 +0200 Subject: [PATCH 2/4] docs: add 11.2.0 changelog entry --- CHANGELOG.md | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index a297d08..b3887bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [11.2.0](https://github.com/anzusystems/common-bundle/compare/11.1.1...11.2.0) (2026-07-03) + +### Features +* New `HttpExceptionHandler` — standardized JSON error response (`error`, `detail`, `contextId`) for any unhandled `HttpException`, preserving the exception's original status code (429, 503, ...) instead of falling through to the default handler as 500. Registered after the more specific handlers (`AccessDeniedExceptionHandler`, `NotFoundExceptionHandler`, ...). +* `ExceptionHandlerCompilerPass` now sorts exception handlers by the `priority` attribute of the `anzu_systems_common.logs.exception_handler` tag (high → low). Handlers without an explicit priority keep the default `0`; the built-in `HttpExceptionHandler` registers with `-100`, so more specific handlers always take precedence: +```php +$definition->addTag(AnzuSystemsCommonBundle::TAG_EXCEPTION_HANDLER, ['priority' => -100]); +``` + ## [10.0.0](https://github.com/anzusystems/common-bundle/compare/9.4.0...10.0.0) (2024-10-30) ### Features From 264acf03e3c4e7dc3ac8f531e3f72e0faa3d6a52 Mon Sep 17 00:00:00 2001 From: gabrielzigo Date: Fri, 3 Jul 2026 13:40:26 +0200 Subject: [PATCH 3/4] style: apply ecs fixes from updated fixer ruleset --- src/AnzuTap/AnzuTapEditor.php | 9 +- .../Transformer/Node/TextNodeTransformer.php | 2 +- .../Transformer/Traits/TextNodeTrait.php | 2 +- .../AnzuTapNodeTransformerProvider.php | 2 +- .../MarkTransformerProviderInterface.php | 2 +- .../NodeTransformerProviderInterface.php | 2 +- src/ApiFilter/ApiQuery.php | 15 +- src/ApiFilter/ApiQueryMongo.php | 9 +- src/ApiFilter/CustomFilterInterface.php | 2 +- src/ApiFilter/FieldCallbackInterface.php | 2 +- .../Fixer/MigrationPrimaryKeyFirstFixer.php | 3 +- src/Controller/AbstractAnzuApiController.php | 7 +- src/Controller/DebugController.php | 3 - src/Controller/HealthCheckController.php | 2 - src/Controller/LogController.php | 2 - .../Fixtures/AbstractFixtures.php | 17 ++- src/DependencyInjection/Configuration.php | 130 +++++++++++++----- src/Doctrine/Walker/ForceIndexWalker.php | 6 +- src/Domain/AbstractManager.php | 3 +- src/Domain/User/CurrentAnzuUserProvider.php | 3 +- src/Event/Subscriber/AuditLogSubscriber.php | 3 +- .../Subscriber/CommandLockSubscriber.php | 2 +- src/HealthCheck/HealthChecker.php | 3 +- src/Log/Factory/LogContextFactory.php | 2 +- src/Log/LogFacade.php | 9 +- .../Middleware/ContextIdentityMiddleware.php | 6 +- src/Repository/AbstractAnzuRepository.php | 6 +- src/Repository/AnzuRepositoryInterface.php | 6 +- src/Security/Voter/AbstractVoter.php | 10 +- src/Traits/LoggerAwareRequest.php | 4 +- src/Util/ResourceLocker.php | 11 +- .../Constraints/UniqueEntityDtoValidator.php | 3 +- .../Constraints/UniqueEntityValidator.php | 3 +- src/Validator/Validator.php | 3 +- tests/Controller/AbstractControllerTest.php | 6 +- .../Walker/ForceIndexWalkerQueryTest.php | 2 +- tests/bootstrap.php | 10 +- tests/config/services/services.php | 3 +- .../Model/DataObject/SerializerTestDto.php | 3 +- 39 files changed, 199 insertions(+), 119 deletions(-) diff --git a/src/AnzuTap/AnzuTapEditor.php b/src/AnzuTap/AnzuTapEditor.php index 5b25ce9..9d65e7b 100644 --- a/src/AnzuTap/AnzuTapEditor.php +++ b/src/AnzuTap/AnzuTapEditor.php @@ -56,7 +56,8 @@ public function transform(string $data): AnzuTapBody $document = new DOMDocument(); $document->loadHTML($data); - $bodyNode = $document->getElementsByTagName('body')->item(0); + $bodyNode = $document->getElementsByTagName('body') + ->item(0); $body = new AnzuTapDocNode(); if (false === (null === $bodyNode)) { @@ -70,7 +71,7 @@ public function transform(string $data): AnzuTapBody ); } - public function getMarkTransformer(DOMElement | DOMText $element): ?AnzuMarkTransformerInterface + public function getMarkTransformer(DOMElement|DOMText $element): ?AnzuMarkTransformerInterface { $key = $this->markTransformerProvider->getMarkTransformerKey($element); if ($this->resolvedMarkTransformers->has($key)) { @@ -80,7 +81,7 @@ public function getMarkTransformer(DOMElement | DOMText $element): ?AnzuMarkTran return null; } - public function getNodeTransformer(DOMElement | DOMText $element): AnzuNodeTransformerInterface + public function getNodeTransformer(DOMElement|DOMText $element): AnzuNodeTransformerInterface { $key = $this->transformerProvider->getNodeTransformerKey($element); @@ -173,7 +174,7 @@ private function getUniqueMarks(): array } private function processNode( - DOMElement | DOMText $node, + DOMElement|DOMText $node, AnzuNodeTransformerInterface $nodeTransformer, AnzuTapNodeInterface $anzuTapParentNode, ): ?AnzuTapNodeInterface { diff --git a/src/AnzuTap/Transformer/Node/TextNodeTransformer.php b/src/AnzuTap/Transformer/Node/TextNodeTransformer.php index b6cd5a5..2095f6f 100644 --- a/src/AnzuTap/Transformer/Node/TextNodeTransformer.php +++ b/src/AnzuTap/Transformer/Node/TextNodeTransformer.php @@ -27,7 +27,7 @@ public static function getSupportedNodeNames(): array ]; } - public function transform(DOMElement | DOMText $element, EmbedContainer $embedContainer, ?AnzuTapNodeInterface $parent = null): ?AnzuTapNodeInterface + public function transform(DOMElement|DOMText $element, EmbedContainer $embedContainer, ?AnzuTapNodeInterface $parent = null): ?AnzuTapNodeInterface { $text = $this->getText( $element, diff --git a/src/AnzuTap/Transformer/Traits/TextNodeTrait.php b/src/AnzuTap/Transformer/Traits/TextNodeTrait.php index d361aa4..a8abd69 100644 --- a/src/AnzuTap/Transformer/Traits/TextNodeTrait.php +++ b/src/AnzuTap/Transformer/Traits/TextNodeTrait.php @@ -9,7 +9,7 @@ trait TextNodeTrait { - protected function getText(DOMText | DOMElement $element, bool $allowEmpty = false): ?string + protected function getText(DOMText|DOMElement $element, bool $allowEmpty = false): ?string { $text = $element->textContent; $textToTrim = $text; diff --git a/src/AnzuTap/TransformerProvider/AnzuTapNodeTransformerProvider.php b/src/AnzuTap/TransformerProvider/AnzuTapNodeTransformerProvider.php index 5c22afd..a5b8c91 100644 --- a/src/AnzuTap/TransformerProvider/AnzuTapNodeTransformerProvider.php +++ b/src/AnzuTap/TransformerProvider/AnzuTapNodeTransformerProvider.php @@ -9,7 +9,7 @@ final readonly class AnzuTapNodeTransformerProvider implements NodeTransformerProviderInterface { - public function getNodeTransformerKey(DOMElement | DOMText $element): string + public function getNodeTransformerKey(DOMElement|DOMText $element): string { return $element->nodeName; } diff --git a/src/AnzuTap/TransformerProvider/MarkTransformerProviderInterface.php b/src/AnzuTap/TransformerProvider/MarkTransformerProviderInterface.php index 3106c07..c2a6557 100644 --- a/src/AnzuTap/TransformerProvider/MarkTransformerProviderInterface.php +++ b/src/AnzuTap/TransformerProvider/MarkTransformerProviderInterface.php @@ -9,5 +9,5 @@ interface MarkTransformerProviderInterface { - public function getMarkTransformerKey(DOMElement | DOMText $element): string; + public function getMarkTransformerKey(DOMElement|DOMText $element): string; } diff --git a/src/AnzuTap/TransformerProvider/NodeTransformerProviderInterface.php b/src/AnzuTap/TransformerProvider/NodeTransformerProviderInterface.php index 88e1bd3..cc0e4f2 100644 --- a/src/AnzuTap/TransformerProvider/NodeTransformerProviderInterface.php +++ b/src/AnzuTap/TransformerProvider/NodeTransformerProviderInterface.php @@ -9,5 +9,5 @@ interface NodeTransformerProviderInterface { - public function getNodeTransformerKey(DOMElement | DOMText $element): string; + public function getNodeTransformerKey(DOMElement|DOMText $element): string; } diff --git a/src/ApiFilter/ApiQuery.php b/src/ApiFilter/ApiQuery.php index 240e51b..04b5643 100644 --- a/src/ApiFilter/ApiQuery.php +++ b/src/ApiFilter/ApiQuery.php @@ -83,7 +83,8 @@ public function getTotalCount(): int return (int) $this->dqb ->select('count(t)') - ->getQuery()->getSingleScalarResult() + ->getQuery() + ->getSingleScalarResult() ; } @@ -100,7 +101,8 @@ public function getData(): array ->select('t') ->setFirstResult($this->apiParams->getOffset()) ->setMaxResults($limit) - ->getQuery()->getResult() + ->getQuery() + ->getResult() ; } @@ -168,10 +170,11 @@ private function applyFilters(): void break; default: $this->dqb->andWhere( - $this->dqb->expr()->{$filterVariant}( - 't.' . $field, - ':' . $paramName - ) + $this->dqb->expr() + ->{$filterVariant}( + 't.' . $field, + ':' . $paramName + ) ); $this->dqb->setParameter( $paramName, diff --git a/src/ApiFilter/ApiQueryMongo.php b/src/ApiFilter/ApiQueryMongo.php index 0000cbb..3262021 100644 --- a/src/ApiFilter/ApiQueryMongo.php +++ b/src/ApiFilter/ApiQueryMongo.php @@ -111,7 +111,8 @@ public function getOptions(): array private function getPersistedName(string $field): string { - $fieldAttributes = $this->getPropertyByField($field)->getAttributes(PersistedName::class); + $fieldAttributes = $this->getPropertyByField($field) + ->getAttributes(PersistedName::class); if (array_key_exists(0, $fieldAttributes)) { $persistedNameAttribute = $fieldAttributes[0]->newInstance(); /** @psalm-suppress RedundantConditionGivenDocblockType */ @@ -142,7 +143,8 @@ private function getPropertyType(string $field): string return 'oid'; } - return (string) $this->getPropertyByField($field)->getType(); + return (string) $this->getPropertyByField($field) + ->getType(); } /** @@ -156,7 +158,8 @@ private function getPropertyByField(string $field): ReflectionProperty $class = $this->classReflection; foreach ($propertyPath as $curPropName) { /** @psalm-var class-string $curClassType */ - $curClassType = (string) $class->getProperty($curPropName)->getType(); + $curClassType = (string) $class->getProperty($curPropName) + ->getType(); $class = new ReflectionClass($curClassType); } diff --git a/src/ApiFilter/CustomFilterInterface.php b/src/ApiFilter/CustomFilterInterface.php index 49a7d29..50e5213 100644 --- a/src/ApiFilter/CustomFilterInterface.php +++ b/src/ApiFilter/CustomFilterInterface.php @@ -8,5 +8,5 @@ interface CustomFilterInterface { - public function apply(QueryBuilder $dqb, string $field, string | int $value): QueryBuilder; + public function apply(QueryBuilder $dqb, string $field, string|int $value): QueryBuilder; } diff --git a/src/ApiFilter/FieldCallbackInterface.php b/src/ApiFilter/FieldCallbackInterface.php index 2f492b9..1df5b41 100644 --- a/src/ApiFilter/FieldCallbackInterface.php +++ b/src/ApiFilter/FieldCallbackInterface.php @@ -6,6 +6,6 @@ interface FieldCallbackInterface { - public function __invoke(string | int $value): void; + public function __invoke(string|int $value): void; public function field(): string; } diff --git a/src/CodingStandard/Fixer/MigrationPrimaryKeyFirstFixer.php b/src/CodingStandard/Fixer/MigrationPrimaryKeyFirstFixer.php index 40a2e77..1905b26 100644 --- a/src/CodingStandard/Fixer/MigrationPrimaryKeyFirstFixer.php +++ b/src/CodingStandard/Fixer/MigrationPrimaryKeyFirstFixer.php @@ -122,7 +122,8 @@ private function fixColumns(string $fullMatch, string $columnsString): string array_diff_key($columns, [$pkIndex => true]) )]; - return (new UnicodeString($fullMatch))->replace($columnsString, implode(', ', $reordered))->toString(); + return (new UnicodeString($fullMatch))->replace($columnsString, implode(', ', $reordered)) + ->toString(); } /** diff --git a/src/Controller/AbstractAnzuApiController.php b/src/Controller/AbstractAnzuApiController.php index 8f4f67e..16082c8 100644 --- a/src/Controller/AbstractAnzuApiController.php +++ b/src/Controller/AbstractAnzuApiController.php @@ -45,7 +45,7 @@ protected function okResponse( /** * Get newly created entity. */ - protected function createdResponse(array | object $data): JsonResponse + protected function createdResponse(array|object $data): JsonResponse { return $this->getResponse($data, JsonResponse::HTTP_CREATED); } @@ -59,7 +59,7 @@ protected function noContentResponse(): JsonResponse } protected function getResponse( - array | object $data, + array|object $data, int $statusCode = JsonResponse::HTTP_OK, ): JsonResponse { return new JsonResponse( @@ -73,7 +73,8 @@ protected function getResponse( protected function lockApi(bool $blocking = false): void { $this->resourceLocker->lock( - (string) $this->container->get('request_stack')->getCurrentRequest()?->get('_route'), + (string) $this->container->get('request_stack') + ->getCurrentRequest()?->get('_route'), $blocking ); } diff --git a/src/Controller/DebugController.php b/src/Controller/DebugController.php index 864bde3..47f8d45 100644 --- a/src/Controller/DebugController.php +++ b/src/Controller/DebugController.php @@ -15,9 +15,6 @@ #[OA\Tag('Debug')] final class DebugController extends AbstractAnzuApiController { - /** - * Get lead time. - */ #[OAResponse(description: 'Lead time')] public function getLeadTime(): JsonResponse { diff --git a/src/Controller/HealthCheckController.php b/src/Controller/HealthCheckController.php index 0f7ff48..1e11d50 100644 --- a/src/Controller/HealthCheckController.php +++ b/src/Controller/HealthCheckController.php @@ -19,8 +19,6 @@ public function __construct( } /** - * Health check. - * * @throws SerializerException */ #[OAResponse(description: 'Health check')] diff --git a/src/Controller/LogController.php b/src/Controller/LogController.php index 6b04462..09eb152 100644 --- a/src/Controller/LogController.php +++ b/src/Controller/LogController.php @@ -73,8 +73,6 @@ public function getOneJournalLog(string $id): JsonResponse } /** - * Get one audit log. - * * @throws SerializerException */ #[OAParameterPath('id'), OAResponse(Log::class)] diff --git a/src/DataFixtures/Fixtures/AbstractFixtures.php b/src/DataFixtures/Fixtures/AbstractFixtures.php index b0bc17a..e4069a1 100644 --- a/src/DataFixtures/Fixtures/AbstractFixtures.php +++ b/src/DataFixtures/Fixtures/AbstractFixtures.php @@ -67,9 +67,10 @@ public function getRegistry(): ArrayCollection * * @throws InvalidArgumentException */ - public function getOneFromRegistry(string | int $key): object + public function getOneFromRegistry(string|int $key): object { - $object = $this->getRegistry()->get($key); + $object = $this->getRegistry() + ->get($key); if (null === $object) { throw new InvalidArgumentException(sprintf('Object key "%s" not found in registry!', $key)); } @@ -80,14 +81,16 @@ public function getOneFromRegistry(string | int $key): object /** * @param E $object */ - public function addToRegistry(object $object, string | int | null $key = null): self + public function addToRegistry(object $object, string|int|null $key = null): self { if ($key) { - $this->getRegistry()->set($key, $object); + $this->getRegistry() + ->set($key, $object); return $this; } - $this->getRegistry()->add($object); + $this->getRegistry() + ->add($object); return $this; } @@ -99,7 +102,9 @@ public function addToRegistry(object $object, string | int | null $key = null): */ public function findOneRegistryRecord(Closure $filter): ?object { - return $this->getRegistry()->filter($filter)->first() ?: null; + return $this->getRegistry() + ->filter($filter) + ->first() ?: null; } public function useCustomId(): bool diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 3364286..27e2abc 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -137,11 +137,13 @@ private function addPermissionsSection(): NodeDefinition ->children() ->arrayNode(PermissionConfig::PRM_DEFAULT_GRANTS) ->defaultValue([Grant::ALLOW, Grant::DENY]) - ->integerPrototype()->end() + ->integerPrototype() +->end() ->end() ->arrayNode(PermissionConfig::PRM_ROLES) ->defaultValue([AnzuUser::ROLE_USER, AnzuUser::ROLE_ADMIN]) - ->scalarPrototype()->end() + ->scalarPrototype() +->end() ->end() ->arrayNode(PermissionConfig::PRM_CONFIG) ->arrayPrototype() @@ -150,7 +152,8 @@ private function addPermissionsSection(): NodeDefinition ->useAttributeAsKey('name') ->arrayPrototype() ->useAttributeAsKey('grants') - ->scalarPrototype()->end() + ->scalarPrototype() +->end() ->end() ->end() ->end() @@ -160,19 +163,22 @@ private function addPermissionsSection(): NodeDefinition ->arrayNode('subjects') ->arrayPrototype() ->useAttributeAsKey('name') - ->scalarPrototype()->end() + ->scalarPrototype() +->end() ->end() ->end() ->arrayNode('actions') ->arrayPrototype() ->useAttributeAsKey('name') - ->scalarPrototype()->end() + ->scalarPrototype() +->end() ->end() ->end() ->arrayNode('roles') ->arrayPrototype() ->useAttributeAsKey('name') - ->scalarPrototype()->end() + ->scalarPrototype() +->end() ->end() ->end() ->end() @@ -186,14 +192,29 @@ private function addSettingsSection(): NodeDefinition return (new TreeBuilder('settings'))->getRootNode() ->addDefaultsIfNotSet() ->children() - ->scalarNode('app_redis')->cannotBeEmpty()->end() - ->scalarNode('app_cache_proxy_enabled')->defaultTrue()->end() - ->scalarNode('user_entity_class')->defaultValue('App\\Entity\\User')->end() - ->scalarNode('app_entity_namespace')->defaultValue('App\\Entity')->end() - ->scalarNode('app_value_object_namespace')->defaultValue('App\\Model\\ValueObject')->end() - ->scalarNode('app_enum_namespace')->defaultValue('App\\Model\\Enum')->end() - ->integerNode('mongo_query_max_time_ms')->defaultValue(ApiQueryMongo::DEFAULT_QUERY_MAX_TIME_MS)->end() - ->booleanNode('send_context_id_with_response')->defaultFalse()->end() + ->scalarNode('app_redis') +->cannotBeEmpty() +->end() + ->scalarNode('app_cache_proxy_enabled') +->defaultTrue() +->end() + ->scalarNode('user_entity_class') +->defaultValue('App\\Entity\\User') +->end() + ->scalarNode('app_entity_namespace') +->defaultValue('App\\Entity') +->end() + ->scalarNode('app_value_object_namespace') +->defaultValue('App\\Model\\ValueObject') +->end() + ->scalarNode('app_enum_namespace') +->defaultValue('App\\Model\\Enum') +->end() + ->integerNode('mongo_query_max_time_ms') +->defaultValue(ApiQueryMongo::DEFAULT_QUERY_MAX_TIME_MS)->end() + ->booleanNode('send_context_id_with_response') +->defaultFalse() +->end() ->arrayNode('unlocked_commands') ->defaultValue(self::DEFAULT_UNLOCKED_COMMANDS) ->validate() @@ -208,7 +229,8 @@ private function addSettingsSection(): NodeDefinition }) ->thenInvalid('Invalid unlocked_commands "%s".') ->end() - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->end() ; @@ -220,13 +242,16 @@ private function addHealthCheckSection(): NodeDefinition ->addDefaultsIfNotSet() ->canBeDisabled() ->children() - ->scalarNode('mysql_table_name')->defaultValue('_doctrine_migration_versions')->end() + ->scalarNode('mysql_table_name') +->defaultValue('_doctrine_migration_versions') +->end() ->arrayNode('mongo_collections') ->defaultValue([ 'anzu_mongo_journal_log_collection', 'anzu_mongo_audit_log_collection', ]) - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->arrayNode('modules') ->defaultValue(self::HEALTH_CHECK_MODULES) @@ -242,7 +267,8 @@ private function addHealthCheckSection(): NodeDefinition }) ->thenInvalid('Invalid health_check_modules "%s".') ->end() - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->end() ; @@ -257,7 +283,8 @@ private function addErrorsSection(): NodeDefinition ->arrayNode('only_uri_match') ->defaultValue([]) ->info('List of regexes for which are errors handled.') - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->scalarNode('default_exception_handler') ->cannotBeEmpty() @@ -281,7 +308,8 @@ private function addErrorsSection(): NodeDefinition }) ->thenInvalid('Invalid exception_handlers "%s".') ->end() - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->end() ; @@ -295,8 +323,12 @@ private function addLogSection(): NodeDefinition ->children() ->arrayNode('messenger_transport') ->children() - ->scalarNode('name')->isRequired()->end() - ->scalarNode('dsn')->isRequired()->end() + ->scalarNode('name') +->isRequired() +->end() + ->scalarNode('dsn') +->isRequired() +->end() ->end() ->end() ->arrayNode('app') @@ -304,7 +336,8 @@ private function addLogSection(): NodeDefinition ->children() ->arrayNode('ignored_exceptions') ->defaultValue([]) - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->end() ->end() @@ -327,7 +360,8 @@ private function addLogSection(): NodeDefinition Request::METHOD_PATCH, Request::METHOD_DELETE, ]) - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->end() ->end() @@ -340,12 +374,24 @@ private function addMongoConnectionSubSection(string $collection): NodeDefinitio return (new TreeBuilder('mongo'))->getRootNode() ->addDefaultsIfNotSet() ->children() - ->scalarNode('uri')->isRequired()->end() - ->scalarNode('username')->isRequired()->end() - ->scalarNode('password')->isRequired()->end() - ->scalarNode('database')->isRequired()->end() - ->scalarNode('ssl')->defaultFalse()->end() - ->scalarNode('collection')->defaultValue($collection)->end() + ->scalarNode('uri') +->isRequired() +->end() + ->scalarNode('username') +->isRequired() +->end() + ->scalarNode('password') +->isRequired() +->end() + ->scalarNode('database') +->isRequired() +->end() + ->scalarNode('ssl') +->defaultFalse() +->end() + ->scalarNode('collection') +->defaultValue($collection) +->end() ->end() ; } @@ -355,9 +401,15 @@ private function addJobsSection(): NodeDefinition return (new TreeBuilder('jobs'))->getRootNode() ->addDefaultsIfNotSet() ->children() - ->scalarNode('max_exec_time')->defaultValue(50)->end() - ->scalarNode('max_memory')->defaultValue(100_000_000)->end() - ->scalarNode('no_job_idle_time')->defaultValue(10)->end() + ->scalarNode('max_exec_time') +->defaultValue(50) +->end() + ->scalarNode('max_memory') +->defaultValue(100_000_000) +->end() + ->scalarNode('no_job_idle_time') +->defaultValue(10) +->end() ->end() ; } @@ -389,19 +441,23 @@ private function addEditorSection(): NodeDefinition ->end() ->arrayNode(self::EDITOR_ALLOWED_NODE_TRANSFORMERS) ->defaultValue(self::DEFAULT_ALLOWED_NODE_TRANSFORMERS) - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->arrayNode(self::EDITOR_ALLOWED_MARK_TRANSFORMERS) ->defaultValue(self::DEFAULT_ALLOWED_MARK_TRANSFORMERS) - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->arrayNode(self::EDITOR_REMOVE_NODES) ->defaultValue([]) - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->arrayNode(self::EDITOR_SKIP_NODES) ->defaultValue(self::DEFAULT_SKIP_NODES) - ->prototype('scalar')->end() + ->prototype('scalar') +->end() ->end() ->end() ->end(); diff --git a/src/Doctrine/Walker/ForceIndexWalker.php b/src/Doctrine/Walker/ForceIndexWalker.php index 6f844d0..1f12e4c 100644 --- a/src/Doctrine/Walker/ForceIndexWalker.php +++ b/src/Doctrine/Walker/ForceIndexWalker.php @@ -16,13 +16,15 @@ public function walkFromClause(FromClause $fromClause): string { $result = parent::walkFromClause($fromClause); - $index = $this->getQuery()->getHint(self::HINT_FORCE_INDEX_FOR_FROM); + $index = $this->getQuery() + ->getHint(self::HINT_FORCE_INDEX_FOR_FROM); if ($index) { /** @var string $result */ $result = preg_replace('~(\bFROM\s*\w+\s*\w+)~', sprintf('$1 FORCE INDEX (%s)', $index), $result); } - $indexJoin = $this->getQuery()->getHint(self::HINT_FORCE_INDEX_FOR_JOIN); + $indexJoin = $this->getQuery() + ->getHint(self::HINT_FORCE_INDEX_FOR_JOIN); foreach ($indexJoin ?: [] as $joinName => $indexName) { /** @var string $result */ $result = preg_replace("~(\bJOIN\s*{$joinName}\s*\w+)~", sprintf('$1 FORCE INDEX (%s)', $indexName), $result); diff --git a/src/Domain/AbstractManager.php b/src/Domain/AbstractManager.php index 355a38a..8af888d 100644 --- a/src/Domain/AbstractManager.php +++ b/src/Domain/AbstractManager.php @@ -65,7 +65,8 @@ public function rollback(): void public function isTransactionActive(): bool { - return $this->entityManager->getConnection()->isTransactionActive(); + return $this->entityManager->getConnection() + ->isTransactionActive(); } public function clear(): void diff --git a/src/Domain/User/CurrentAnzuUserProvider.php b/src/Domain/User/CurrentAnzuUserProvider.php index 7d1932a..cdb4228 100644 --- a/src/Domain/User/CurrentAnzuUserProvider.php +++ b/src/Domain/User/CurrentAnzuUserProvider.php @@ -84,6 +84,7 @@ public function setCurrentUserById(int $userId): AnzuUser public function isCurrentUser(AnzuUser $user): bool { - return $user->getId() === $this->getCurrentUser()->getId(); + return $user->getId() === $this->getCurrentUser() + ->getId(); } } diff --git a/src/Event/Subscriber/AuditLogSubscriber.php b/src/Event/Subscriber/AuditLogSubscriber.php index 07fdcae..2ee57bf 100644 --- a/src/Event/Subscriber/AuditLogSubscriber.php +++ b/src/Event/Subscriber/AuditLogSubscriber.php @@ -41,7 +41,8 @@ public function onTerminate(TerminateEvent $event): void } $this->auditLogger->info( - message: (string) $event->getRequest()->attributes->get('_route'), + message: (string) $event->getRequest() + ->attributes->get('_route'), context: $this->logContextFactory->buildFromRequestToArray( $event->getRequest(), $event->getResponse() diff --git a/src/Event/Subscriber/CommandLockSubscriber.php b/src/Event/Subscriber/CommandLockSubscriber.php index 3b2e76c..ce0cc1c 100644 --- a/src/Event/Subscriber/CommandLockSubscriber.php +++ b/src/Event/Subscriber/CommandLockSubscriber.php @@ -59,7 +59,7 @@ public function acquireLock(ConsoleCommandEvent $event): void } } - public function releaseLock(ConsoleTerminateEvent | ConsoleErrorEvent $event): void + public function releaseLock(ConsoleTerminateEvent|ConsoleErrorEvent $event): void { if ($this->lock && $this->lock->isAcquired()) { $this->lock->release(); diff --git a/src/HealthCheck/HealthChecker.php b/src/HealthCheck/HealthChecker.php index 990a454..adfc8b8 100644 --- a/src/HealthCheck/HealthChecker.php +++ b/src/HealthCheck/HealthChecker.php @@ -45,7 +45,8 @@ public function check(): SummarizeResult ->setLeadTime( $this->formatDuration( $this->getDiffSecondsFromCurrentToStart( - (float) $this->requestStack->getMainRequest()?->server->get('REQUEST_TIME_FLOAT') + (float) $this->requestStack->getMainRequest()?->server + ->get('REQUEST_TIME_FLOAT') ) ) ); diff --git a/src/Log/Factory/LogContextFactory.php b/src/Log/Factory/LogContextFactory.php index 8023bde..8fced8d 100644 --- a/src/Log/Factory/LogContextFactory.php +++ b/src/Log/Factory/LogContextFactory.php @@ -43,7 +43,7 @@ public function buildForRequest( string $url, ?array $json, ?array $query, - array | string $body, + array|string $body, ?int $timeout ): LogContext { $content = $body ?: $json; diff --git a/src/Log/LogFacade.php b/src/Log/LogFacade.php index 4b07f3d..bc863d2 100644 --- a/src/Log/LogFacade.php +++ b/src/Log/LogFacade.php @@ -28,10 +28,11 @@ public function __construct( public function create(Request $request, LogDto $logDto): Log { $context = $this->logContextFactory->buildCustomFromRequest($request, $logDto); - $this->journalLogger->{$logDto->getLevel()->logMethodName()}( - $logDto->getMessage(), - $this->serializer->toArray($context) - ); + $this->journalLogger->{$logDto->getLevel() + ->logMethodName()}( + $logDto->getMessage(), + $this->serializer->toArray($context) + ); return LogFactory::buildCustomLog($logDto, $context); } diff --git a/src/Messenger/Middleware/ContextIdentityMiddleware.php b/src/Messenger/Middleware/ContextIdentityMiddleware.php index b90ca83..31ec9f4 100644 --- a/src/Messenger/Middleware/ContextIdentityMiddleware.php +++ b/src/Messenger/Middleware/ContextIdentityMiddleware.php @@ -22,11 +22,13 @@ public function handle(Envelope $envelope, StackInterface $stack): Envelope if (null === $contextIdentityStamp) { $envelope = $envelope->with(ContextIdentityStamp::create()); - return $stack->next()->handle($envelope, $stack); + return $stack->next() + ->handle($envelope, $stack); } AnzuApp::setContextId($contextIdentityStamp->getContextId()); - return $stack->next()->handle($envelope, $stack); + return $stack->next() + ->handle($envelope, $stack); } } diff --git a/src/Repository/AbstractAnzuRepository.php b/src/Repository/AbstractAnzuRepository.php index d5c8563..2e0e524 100644 --- a/src/Repository/AbstractAnzuRepository.php +++ b/src/Repository/AbstractAnzuRepository.php @@ -38,7 +38,7 @@ public function __construct(ManagerRegistry $registry) /** * @return ArrayCollection */ - public function getAllById(int | string ...$ids): ArrayCollection + public function getAllById(int|string ...$ids): ArrayCollection { return new ArrayCollection( $this->createQueryBuilder('entity') @@ -53,7 +53,7 @@ public function getAllById(int | string ...$ids): ArrayCollection /** * @return ArrayCollection */ - public function getAllByIdIndexed(int | string ...$id): ArrayCollection + public function getAllByIdIndexed(int|string ...$id): ArrayCollection { return new ArrayCollection( $this->createQueryBuilder('entity', 'entity.id') @@ -170,7 +170,7 @@ public function findByApiParamsWithInfiniteListing( ; } - public function exists(int | string $id): bool + public function exists(int|string $id): bool { return (bool) $this->count([ 'id' => $id, diff --git a/src/Repository/AnzuRepositoryInterface.php b/src/Repository/AnzuRepositoryInterface.php index 87b421f..513ed29 100644 --- a/src/Repository/AnzuRepositoryInterface.php +++ b/src/Repository/AnzuRepositoryInterface.php @@ -12,9 +12,9 @@ interface AnzuRepositoryInterface { - public function getAllById(int | string ...$ids): Collection; + public function getAllById(int|string ...$ids): Collection; - public function getAllByIdIndexed(int | string ...$id): Collection; + public function getAllByIdIndexed(int|string ...$id): Collection; public function findByApiParams(ApiParams $apiParams, ?CustomFilterInterface $customFilter = null): ApiResponseList; @@ -27,5 +27,5 @@ public function findByApiParamsWithInfiniteListing( ?CustomFilterInterface $customFilter = null, ): ApiInfiniteResponseList; - public function exists(int | string $id): bool; + public function exists(int|string $id): bool; } diff --git a/src/Security/Voter/AbstractVoter.php b/src/Security/Voter/AbstractVoter.php index 5c4753a..d5cd5df 100644 --- a/src/Security/Voter/AbstractVoter.php +++ b/src/Security/Voter/AbstractVoter.php @@ -72,12 +72,14 @@ protected function permissionVote(string $attribute, mixed $subject, AnzuUser $u protected function resolveAllowOwner(mixed $subject, AnzuUser $user): bool { if ($subject instanceof OwnersAwareInterface) { - return $subject->getOwners()->exists( - fn (int $key, AnzuUser $owner): bool => $owner->is($user) - ); + return $subject->getOwners() + ->exists( + fn (int $key, AnzuUser $owner): bool => $owner->is($user) + ); } if ($subject instanceof UserTrackingInterface) { - return $subject->getCreatedBy()->is($user); + return $subject->getCreatedBy() + ->is($user); } return false; diff --git a/src/Traits/LoggerAwareRequest.php b/src/Traits/LoggerAwareRequest.php index c0f1176..1ee506c 100644 --- a/src/Traits/LoggerAwareRequest.php +++ b/src/Traits/LoggerAwareRequest.php @@ -39,12 +39,12 @@ protected function loggedRequest( array $headers = [], array $json = [], array $query = [], - array | string $body = [], + array|string $body = [], string $authBearer = '', int $timeout = 5, bool $logSuccess = true, array $notLogErrorResponseCodes = [], - callable $contentValidator = null, + ?callable $contentValidator = null, ): HttpClientResponse { $context = $this->contextFactory->buildForRequest($method, $url, $json, $query, $body, $timeout); if (!$this->journalLogger) { diff --git a/src/Util/ResourceLocker.php b/src/Util/ResourceLocker.php index 5a123c4..4223152 100644 --- a/src/Util/ResourceLocker.php +++ b/src/Util/ResourceLocker.php @@ -29,7 +29,7 @@ public function __construct( ) { } - public function lock(BaseIdentifiableInterface | string $resource, bool $blocking = true): bool + public function lock(BaseIdentifiableInterface|string $resource, bool $blocking = true): bool { $lock = $this->createLock($resource); $acquired = $lock->acquire(); @@ -49,7 +49,7 @@ public function lock(BaseIdentifiableInterface | string $resource, bool $blockin return $acquired; } - public function unLock(BaseIdentifiableInterface | string $resource): void + public function unLock(BaseIdentifiableInterface|string $resource): void { $lockName = $this->getLockName($resource); if (array_key_exists($lockName, $this->locks)) { @@ -66,7 +66,7 @@ public function unlockAll(): void } } - private function getLockName(BaseIdentifiableInterface | string $resource): string + private function getLockName(BaseIdentifiableInterface|string $resource): string { if ($resource instanceof BaseIdentifiableInterface) { return self::REDIS_LOCK_PREFIX . $resource::getResourceName() . '_' . ((string) $resource->getId()); @@ -75,9 +75,10 @@ private function getLockName(BaseIdentifiableInterface | string $resource): stri return self::REDIS_LOCK_PREFIX . $resource; } - private function createLock(BaseIdentifiableInterface | string $resource): LockInterface + private function createLock(BaseIdentifiableInterface|string $resource): LockInterface { - return $this->getLockFactory()->createLock($this->getLockName($resource), 60); + return $this->getLockFactory() + ->createLock($this->getLockName($resource), 60); } private function getRedisStore(): RedisStore diff --git a/src/Validator/Constraints/UniqueEntityDtoValidator.php b/src/Validator/Constraints/UniqueEntityDtoValidator.php index d6e5de6..3332470 100644 --- a/src/Validator/Constraints/UniqueEntityDtoValidator.php +++ b/src/Validator/Constraints/UniqueEntityDtoValidator.php @@ -47,7 +47,8 @@ public function validate(mixed $value, Constraint $constraint): void $fields[$fieldName] = $this->propertyAccessor->getValue($value, $fieldName); } /** @var BaseIdentifiableInterface|null $existingEntity */ - $existingEntity = $this->entityManager->getRepository($entityClass)->findOneBy($fields); + $existingEntity = $this->entityManager->getRepository($entityClass) + ->findOneBy($fields); if (null === $existingEntity) { return; } diff --git a/src/Validator/Constraints/UniqueEntityValidator.php b/src/Validator/Constraints/UniqueEntityValidator.php index 2e1213e..744163b 100644 --- a/src/Validator/Constraints/UniqueEntityValidator.php +++ b/src/Validator/Constraints/UniqueEntityValidator.php @@ -46,7 +46,8 @@ public function validate(mixed $value, Constraint $constraint): void $entityClass = $this->resolveEntityClass(ClassUtils::getRealClass($value::class)); /** @var BaseIdentifiableInterface|null $existingEntity */ - $existingEntity = $this->entityManager->getRepository($entityClass)->findOneBy($fields); + $existingEntity = $this->entityManager->getRepository($entityClass) + ->findOneBy($fields); if (null === $existingEntity) { return; } diff --git a/src/Validator/Validator.php b/src/Validator/Validator.php index 91d534f..b2b9f51 100644 --- a/src/Validator/Validator.php +++ b/src/Validator/Validator.php @@ -54,7 +54,8 @@ private function validateIdentity( } if ($object instanceof IdentifiableByUuidInterface && $oldObject instanceof IdentifiableByUuidInterface - && $object->getId()->equals($oldObject->getId())) { + && $object->getId() + ->equals($oldObject->getId())) { return; } diff --git a/tests/Controller/AbstractControllerTest.php b/tests/Controller/AbstractControllerTest.php index c5a00fe..92a4046 100644 --- a/tests/Controller/AbstractControllerTest.php +++ b/tests/Controller/AbstractControllerTest.php @@ -76,7 +76,7 @@ protected function getList(string $uri, string $deserializationClass, array $par * * @throws JsonException */ - protected function get(string $uri, string $deserializationClass = null, array $params = []): object | array + protected function get(string $uri, ?string $deserializationClass = null, array $params = []): object|array { self::$client->request(method: Request::METHOD_GET, uri: $uri, parameters: $params); @@ -92,7 +92,7 @@ protected function get(string $uri, string $deserializationClass = null, array $ * * @throws JsonException */ - protected function post(string $uri, object $content = null, string $deserializationClass = null, array $params = []): object | array + protected function post(string $uri, ?object $content = null, ?string $deserializationClass = null, array $params = []): object|array { self::$client->request( method: Request::METHOD_POST, @@ -113,7 +113,7 @@ protected function post(string $uri, object $content = null, string $deserializa * * @throws JsonException */ - protected function deserializeResponse(string $deserializationClass = null): object | array + protected function deserializeResponse(?string $deserializationClass = null): object|array { if (null === $deserializationClass) { return json_decode( diff --git a/tests/Doctrine/Walker/ForceIndexWalkerQueryTest.php b/tests/Doctrine/Walker/ForceIndexWalkerQueryTest.php index 35184bf..a88dd23 100644 --- a/tests/Doctrine/Walker/ForceIndexWalkerQueryTest.php +++ b/tests/Doctrine/Walker/ForceIndexWalkerQueryTest.php @@ -18,7 +18,7 @@ final class ForceIndexWalkerQueryTest extends AbstractDoctrineQueryTestCase public function testForceIndexWalkerFunction( string $dql, string $type, - string | array $index, + string|array $index, string $expectedSql ): void { $this->query diff --git a/tests/bootstrap.php b/tests/bootstrap.php index 1f3899b..d66f10b 100644 --- a/tests/bootstrap.php +++ b/tests/bootstrap.php @@ -27,7 +27,7 @@ $output = new ConsoleOutput(); -# Clear cache +// Clear cache $input = new ArrayInput([ 'command' => 'cache:clear', '--no-warmup' => true, @@ -36,7 +36,7 @@ $input->setInteractive(false); $app->run($input, $output); -# Database drop +// Database drop $input = new ArrayInput([ 'command' => 'doctrine:database:drop', '--force' => true, @@ -45,14 +45,14 @@ $input->setInteractive(false); $app->run($input, $output); -# Database create +// Database create $input = new ArrayInput([ 'command' => 'doctrine:database:create', ]); $input->setInteractive(false); $app->run($input, $output); -# Update schema +// Update schema $input = new ArrayInput([ 'command' => 'doctrine:schema:update', '--force' => true, @@ -61,7 +61,7 @@ $input->setInteractive(false); $app->run($input, $output); -# Database fixtures +// Database fixtures $input = new ArrayInput([ 'command' => 'anzusystems:fixtures:generate', ]); diff --git a/tests/config/services/services.php b/tests/config/services/services.php index 0330f15..d16b261 100644 --- a/tests/config/services/services.php +++ b/tests/config/services/services.php @@ -75,7 +75,8 @@ ->public() ; - $configurator->services()->set(TestAnzuTapEditor::class) + $configurator->services() + ->set(TestAnzuTapEditor::class) ->autowire() ->public(); }; diff --git a/tests/data/Model/DataObject/SerializerTestDto.php b/tests/data/Model/DataObject/SerializerTestDto.php index a01e688..d757a3a 100644 --- a/tests/data/Model/DataObject/SerializerTestDto.php +++ b/tests/data/Model/DataObject/SerializerTestDto.php @@ -60,7 +60,8 @@ public function __construct() #[Serialize] public function getCreatedAtTimestamp(): int { - return $this->getCreatedAt()->getTimestamp(); + return $this->getCreatedAt() + ->getTimestamp(); } public function getName(): string From c04e663b6dbf9150d6c4b8066cbd6e9dbee3c87c Mon Sep 17 00:00:00 2001 From: gabrielzigo Date: Fri, 3 Jul 2026 14:01:43 +0200 Subject: [PATCH 4/4] style: revert Configuration.php chain formatting, skip MethodChainingNewlineFixer for configuration tree builders --- ecs.php | 2 + src/DependencyInjection/Configuration.php | 130 ++++++---------------- 2 files changed, 39 insertions(+), 93 deletions(-) diff --git a/ecs.php b/ecs.php index 84c2785..e995902 100644 --- a/ecs.php +++ b/ecs.php @@ -38,6 +38,7 @@ use SlevomatCodingStandard\Sniffs\PHP\UselessParenthesesSniff; use Symplify\CodingStandard\Fixer\ArrayNotation\ArrayListItemNewlineFixer; use Symplify\CodingStandard\Fixer\ArrayNotation\ArrayOpenerAndCloserNewlineFixer; +use Symplify\CodingStandard\Fixer\Spacing\MethodChainingNewlineFixer; use Symplify\EasyCodingStandard\Config\ECSConfig; return ECSConfig::configure() @@ -62,6 +63,7 @@ NotOperatorWithSuccessorSpaceFixer::class => null, UselessParenthesesSniff::class => null, MethodChainingIndentationFixer::class => ['src/DependencyInjection/*Configuration.php'], + MethodChainingNewlineFixer::class => ['src/DependencyInjection/*Configuration.php'], 'SlevomatCodingStandard\Sniffs\Classes\UnusedPrivateElementsSniff.WriteOnlyProperty' => ['src/Entity/User.php'], 'SlevomatCodingStandard\Sniffs\Whitespaces\DuplicateSpacesSniff.DuplicateSpaces' => null, 'SlevomatCodingStandard\Sniffs\Commenting\DisallowCommentAfterCodeSniff.DisallowedCommentAfterCode' => null, diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 27e2abc..3364286 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -137,13 +137,11 @@ private function addPermissionsSection(): NodeDefinition ->children() ->arrayNode(PermissionConfig::PRM_DEFAULT_GRANTS) ->defaultValue([Grant::ALLOW, Grant::DENY]) - ->integerPrototype() -->end() + ->integerPrototype()->end() ->end() ->arrayNode(PermissionConfig::PRM_ROLES) ->defaultValue([AnzuUser::ROLE_USER, AnzuUser::ROLE_ADMIN]) - ->scalarPrototype() -->end() + ->scalarPrototype()->end() ->end() ->arrayNode(PermissionConfig::PRM_CONFIG) ->arrayPrototype() @@ -152,8 +150,7 @@ private function addPermissionsSection(): NodeDefinition ->useAttributeAsKey('name') ->arrayPrototype() ->useAttributeAsKey('grants') - ->scalarPrototype() -->end() + ->scalarPrototype()->end() ->end() ->end() ->end() @@ -163,22 +160,19 @@ private function addPermissionsSection(): NodeDefinition ->arrayNode('subjects') ->arrayPrototype() ->useAttributeAsKey('name') - ->scalarPrototype() -->end() + ->scalarPrototype()->end() ->end() ->end() ->arrayNode('actions') ->arrayPrototype() ->useAttributeAsKey('name') - ->scalarPrototype() -->end() + ->scalarPrototype()->end() ->end() ->end() ->arrayNode('roles') ->arrayPrototype() ->useAttributeAsKey('name') - ->scalarPrototype() -->end() + ->scalarPrototype()->end() ->end() ->end() ->end() @@ -192,29 +186,14 @@ private function addSettingsSection(): NodeDefinition return (new TreeBuilder('settings'))->getRootNode() ->addDefaultsIfNotSet() ->children() - ->scalarNode('app_redis') -->cannotBeEmpty() -->end() - ->scalarNode('app_cache_proxy_enabled') -->defaultTrue() -->end() - ->scalarNode('user_entity_class') -->defaultValue('App\\Entity\\User') -->end() - ->scalarNode('app_entity_namespace') -->defaultValue('App\\Entity') -->end() - ->scalarNode('app_value_object_namespace') -->defaultValue('App\\Model\\ValueObject') -->end() - ->scalarNode('app_enum_namespace') -->defaultValue('App\\Model\\Enum') -->end() - ->integerNode('mongo_query_max_time_ms') -->defaultValue(ApiQueryMongo::DEFAULT_QUERY_MAX_TIME_MS)->end() - ->booleanNode('send_context_id_with_response') -->defaultFalse() -->end() + ->scalarNode('app_redis')->cannotBeEmpty()->end() + ->scalarNode('app_cache_proxy_enabled')->defaultTrue()->end() + ->scalarNode('user_entity_class')->defaultValue('App\\Entity\\User')->end() + ->scalarNode('app_entity_namespace')->defaultValue('App\\Entity')->end() + ->scalarNode('app_value_object_namespace')->defaultValue('App\\Model\\ValueObject')->end() + ->scalarNode('app_enum_namespace')->defaultValue('App\\Model\\Enum')->end() + ->integerNode('mongo_query_max_time_ms')->defaultValue(ApiQueryMongo::DEFAULT_QUERY_MAX_TIME_MS)->end() + ->booleanNode('send_context_id_with_response')->defaultFalse()->end() ->arrayNode('unlocked_commands') ->defaultValue(self::DEFAULT_UNLOCKED_COMMANDS) ->validate() @@ -229,8 +208,7 @@ private function addSettingsSection(): NodeDefinition }) ->thenInvalid('Invalid unlocked_commands "%s".') ->end() - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->end() ; @@ -242,16 +220,13 @@ private function addHealthCheckSection(): NodeDefinition ->addDefaultsIfNotSet() ->canBeDisabled() ->children() - ->scalarNode('mysql_table_name') -->defaultValue('_doctrine_migration_versions') -->end() + ->scalarNode('mysql_table_name')->defaultValue('_doctrine_migration_versions')->end() ->arrayNode('mongo_collections') ->defaultValue([ 'anzu_mongo_journal_log_collection', 'anzu_mongo_audit_log_collection', ]) - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->arrayNode('modules') ->defaultValue(self::HEALTH_CHECK_MODULES) @@ -267,8 +242,7 @@ private function addHealthCheckSection(): NodeDefinition }) ->thenInvalid('Invalid health_check_modules "%s".') ->end() - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->end() ; @@ -283,8 +257,7 @@ private function addErrorsSection(): NodeDefinition ->arrayNode('only_uri_match') ->defaultValue([]) ->info('List of regexes for which are errors handled.') - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->scalarNode('default_exception_handler') ->cannotBeEmpty() @@ -308,8 +281,7 @@ private function addErrorsSection(): NodeDefinition }) ->thenInvalid('Invalid exception_handlers "%s".') ->end() - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->end() ; @@ -323,12 +295,8 @@ private function addLogSection(): NodeDefinition ->children() ->arrayNode('messenger_transport') ->children() - ->scalarNode('name') -->isRequired() -->end() - ->scalarNode('dsn') -->isRequired() -->end() + ->scalarNode('name')->isRequired()->end() + ->scalarNode('dsn')->isRequired()->end() ->end() ->end() ->arrayNode('app') @@ -336,8 +304,7 @@ private function addLogSection(): NodeDefinition ->children() ->arrayNode('ignored_exceptions') ->defaultValue([]) - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->end() ->end() @@ -360,8 +327,7 @@ private function addLogSection(): NodeDefinition Request::METHOD_PATCH, Request::METHOD_DELETE, ]) - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->end() ->end() @@ -374,24 +340,12 @@ private function addMongoConnectionSubSection(string $collection): NodeDefinitio return (new TreeBuilder('mongo'))->getRootNode() ->addDefaultsIfNotSet() ->children() - ->scalarNode('uri') -->isRequired() -->end() - ->scalarNode('username') -->isRequired() -->end() - ->scalarNode('password') -->isRequired() -->end() - ->scalarNode('database') -->isRequired() -->end() - ->scalarNode('ssl') -->defaultFalse() -->end() - ->scalarNode('collection') -->defaultValue($collection) -->end() + ->scalarNode('uri')->isRequired()->end() + ->scalarNode('username')->isRequired()->end() + ->scalarNode('password')->isRequired()->end() + ->scalarNode('database')->isRequired()->end() + ->scalarNode('ssl')->defaultFalse()->end() + ->scalarNode('collection')->defaultValue($collection)->end() ->end() ; } @@ -401,15 +355,9 @@ private function addJobsSection(): NodeDefinition return (new TreeBuilder('jobs'))->getRootNode() ->addDefaultsIfNotSet() ->children() - ->scalarNode('max_exec_time') -->defaultValue(50) -->end() - ->scalarNode('max_memory') -->defaultValue(100_000_000) -->end() - ->scalarNode('no_job_idle_time') -->defaultValue(10) -->end() + ->scalarNode('max_exec_time')->defaultValue(50)->end() + ->scalarNode('max_memory')->defaultValue(100_000_000)->end() + ->scalarNode('no_job_idle_time')->defaultValue(10)->end() ->end() ; } @@ -441,23 +389,19 @@ private function addEditorSection(): NodeDefinition ->end() ->arrayNode(self::EDITOR_ALLOWED_NODE_TRANSFORMERS) ->defaultValue(self::DEFAULT_ALLOWED_NODE_TRANSFORMERS) - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->arrayNode(self::EDITOR_ALLOWED_MARK_TRANSFORMERS) ->defaultValue(self::DEFAULT_ALLOWED_MARK_TRANSFORMERS) - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->arrayNode(self::EDITOR_REMOVE_NODES) ->defaultValue([]) - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->arrayNode(self::EDITOR_SKIP_NODES) ->defaultValue(self::DEFAULT_SKIP_NODES) - ->prototype('scalar') -->end() + ->prototype('scalar')->end() ->end() ->end() ->end();