From 311881fb6ff54cd293596fb70ae45a1378287558 Mon Sep 17 00:00:00 2001 From: Mokhtar Tlili Date: Sat, 19 Nov 2022 00:34:13 +0100 Subject: [PATCH 1/4] Register services in bundle extension file --- composer.json | 6 +- .../InputArgumentResolver.php | 9 +-- .../RequestInputExtension.php | 58 +++++++++++++++---- src/EventListener/ReadInputListener.php | 17 ++---- src/Resources/config/services.yaml | 30 ---------- .../InputArgumentResolverTest.php | 25 +++----- .../RequestInputExtensionTest.php | 20 +------ tests/EventListener/ReadInputListenerTest.php | 45 ++++---------- 8 files changed, 76 insertions(+), 134 deletions(-) delete mode 100644 src/Resources/config/services.yaml diff --git a/composer.json b/composer.json index 054b44c..fbede90 100644 --- a/composer.json +++ b/composer.json @@ -24,16 +24,14 @@ "symfony/serializer": "^4.4 || ^5.0 || ^6.0", "symfony/validator": "^4.4 || ^5.0 || ^6.0", "symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0", - "symfony/property-access": "^4.4 || ^5.0 || ^6.0", - "symfony/config": "^4.4 || ^5.0 || ^6.0" + "symfony/property-access": "^4.4 || ^5.0 || ^6.0" }, "require-dev": { "phpunit/phpunit": "^9", "symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0", "phpspec/prophecy-phpunit": "^2.0", "friendsofphp/php-cs-fixer": "^3.13", - "phpstan/phpstan": "^1.9", - "symfony/yaml": "^4.4 || ^5.4 || ^6.0" + "phpstan/phpstan": "^1.9" }, "autoload": { "psr-4": { diff --git a/src/ArgumentResolver/InputArgumentResolver.php b/src/ArgumentResolver/InputArgumentResolver.php index 0af8c01..19d79af 100644 --- a/src/ArgumentResolver/InputArgumentResolver.php +++ b/src/ArgumentResolver/InputArgumentResolver.php @@ -13,16 +13,13 @@ class InputArgumentResolver implements ArgumentValueResolverInterface { - public function __construct( - private InputFactoryInterface $inputFactory, - private array $inputFormats, - private bool $enabled = true - ) { + public function __construct(private InputFactoryInterface $inputFactory, private array $inputFormats) + { } public function supports(Request $request, ArgumentMetadata $argument): bool { - if (!$this->enabled || !is_subclass_of($argument->getType(), InputInterface::class)) { + if (!is_subclass_of($argument->getType(), InputInterface::class)) { return false; } diff --git a/src/DependencyInjection/RequestInputExtension.php b/src/DependencyInjection/RequestInputExtension.php index d1fbbe5..2c220b9 100644 --- a/src/DependencyInjection/RequestInputExtension.php +++ b/src/DependencyInjection/RequestInputExtension.php @@ -4,10 +4,18 @@ namespace Sfmok\RequestInput\DependencyInjection; -use Symfony\Component\Config\FileLocator; +use Sfmok\RequestInput\ArgumentResolver\InputArgumentResolver; +use Sfmok\RequestInput\Factory\InputFactory; +use Sfmok\RequestInput\Factory\InputFactoryInterface; +use Sfmok\RequestInput\Metadata\InputMetadataFactory; +use Sfmok\RequestInput\Metadata\InputMetadataFactoryInterface; +use Sfmok\RequestInput\EventListener\ReadInputListener; +use Sfmok\RequestInput\EventListener\ExceptionListener; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Loader\YamlFileLoader; +use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\HttpKernel\DependencyInjection\Extension; +use Symfony\Component\Serializer\SerializerInterface; +use Symfony\Component\Validator\Validator\ValidatorInterface; /** * @internal @@ -19,17 +27,43 @@ public function load(array $configs, ContainerBuilder $container): void $configuration = new Configuration(); $config = $this->processConfiguration($configuration, $configs); - # define a few parameters - $container->setParameter('request_input.enabled', $config['enabled']); - $container->setParameter('request_input.formats', $config['formats']); - $container->setParameter('request_input.skip_validation', $config['skip_validation']); + if (!$config['enabled']) { + return; + } - $this->loadServicesFiles($container); - } + $container->register(InputFactory::class) + ->setArguments([ + '$serializer' => new Reference(SerializerInterface::class), + '$validator' => new Reference(ValidatorInterface::class), + '$skipValidation' => $config['skip_validation'], + ]) + ->setPublic(false) + ; - protected function loadServicesFiles(ContainerBuilder $container): void - { - $loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config')); - $loader->load('services.yaml'); + $container->register(InputMetadataFactory::class)->setPublic(false); + + $container->setAlias(InputFactoryInterface::class, InputFactory::class)->setPublic(false); + $container->setAlias(InputMetadataFactoryInterface::class, InputMetadataFactory::class)->setPublic(false); + + $container->register(InputArgumentResolver::class) + ->setArguments([ + '$inputFactory' => new Reference(InputFactoryInterface::class), + '$inputFormats' => $config['formats'], + ]) + ->addTag('controller.argument_value_resolver', ['priority' => 40]) + ->setPublic(false) + ; + + $container->register(ExceptionListener::class) + ->setArguments(['$serializer' => new Reference(SerializerInterface::class)]) + ->addTag('kernel.event_listener', ['event' => 'kernel.exception']) + ->setPublic(false) + ; + + $container->register(ReadInputListener::class) + ->setArguments(['$inputMetadataFactory' => new Reference(InputMetadataFactoryInterface::class)]) + ->addTag('kernel.event_listener', ['event' => 'kernel.controller']) + ->setPublic(false) + ; } } diff --git a/src/EventListener/ReadInputListener.php b/src/EventListener/ReadInputListener.php index bd28b2b..eb9b79c 100644 --- a/src/EventListener/ReadInputListener.php +++ b/src/EventListener/ReadInputListener.php @@ -10,25 +10,18 @@ class ReadInputListener { - public function __construct( - private InputMetadataFactoryInterface $inputMetadataFactory, - private bool $enabled = true - ) { + public function __construct(private InputMetadataFactoryInterface $inputMetadataFactory) + { } public function onKernelController(ControllerEvent $event): void { - if (!$this->enabled) { - return; - } - - $request = $event->getRequest(); - $input = $this->inputMetadataFactory->createInputMetadata($event->getController()); + $inputMetadata = $this->inputMetadataFactory->createInputMetadata($event->getController()); - if (!$input instanceof Input) { + if (!$inputMetadata instanceof Input) { return; } - $request->attributes->set('_input', $input); + $event->getRequest()->attributes->set('_input', $inputMetadata); } } diff --git a/src/Resources/config/services.yaml b/src/Resources/config/services.yaml deleted file mode 100644 index 694237a..0000000 --- a/src/Resources/config/services.yaml +++ /dev/null @@ -1,30 +0,0 @@ -services: - _defaults: - autowire: true - - Sfmok\RequestInput\Factory\InputFactory: - arguments: - $skipValidation: '%request_input.skip_validation%' - - Sfmok\RequestInput\Metadata\InputMetadataFactory: ~ - - Sfmok\RequestInput\Factory\InputFactoryInterface: '@Sfmok\RequestInput\Factory\InputFactory' - - Sfmok\RequestInput\Metadata\InputMetadataFactoryInterface: '@Sfmok\RequestInput\Metadata\InputMetadataFactory' - - Sfmok\RequestInput\ArgumentResolver\InputArgumentResolver: - arguments: - $inputFormats: '%request_input.formats%' - $enabled: '%request_input.enabled%' - tags: - - { name: controller.argument_value_resolver, priority: 40 } - - Sfmok\RequestInput\EventListener\ExceptionListener: - tags: - - { name: kernel.event_listener, event: kernel.exception } - - Sfmok\RequestInput\EventListener\ReadInputListener: - arguments: - $enabled: '%request_input.enabled%' - tags: - - { name: kernel.event_listener, event: kernel.controller } \ No newline at end of file diff --git a/tests/ArgumentResolver/InputArgumentResolverTest.php b/tests/ArgumentResolver/InputArgumentResolverTest.php index f5338cd..d83471f 100644 --- a/tests/ArgumentResolver/InputArgumentResolverTest.php +++ b/tests/ArgumentResolver/InputArgumentResolverTest.php @@ -25,21 +25,13 @@ protected function setUp(): void $this->inputFactory = $this->prophesize(InputFactoryInterface::class); } - public function testSupportsWithNonEnabledInput(): void - { - $request = new Request(); - $argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null); - - $resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, false); - $this->assertFalse($resolver->supports($request, $argument)); - } - public function testSupportsWithArgumentTypeNotInput(): void { $request = new Request(); + $request->headers->set('Content-Type', 'application/json'); $argument = new ArgumentMetadata('foo', \stdClass::class, false, false, null); - $resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, true); + $resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS); $this->assertFalse($resolver->supports($request, $argument)); } @@ -50,10 +42,9 @@ public function testSupportsWithDefaultGlobalFormats(bool $expected, ?string $co { $request = new Request(); $request->headers->set('Content-Type', $contentType); - $argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null); - $resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, true); + $resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS); $this->assertSame($expected, $resolver->supports($request, $argument)); } @@ -67,7 +58,7 @@ public function testSupportsWithCustomGlobalFormats(bool $expected, ?string $con $argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null); - $resolver = $this->createArgumentResolver(['json'], true); + $resolver = $this->createArgumentResolver(['json']); $this->assertSame($expected, $resolver->supports($request, $argument)); } @@ -82,7 +73,7 @@ public function testSupportsWithCustomFormatsInInputAttribute(bool $expected, ?s $argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null); - $resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, true); + $resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS); $this->assertSame($expected, $resolver->supports($request, $argument)); } @@ -95,7 +86,7 @@ public function testResolveSucceeds(): void $argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null); - $resolver = $this->createArgumentResolver([Input::INPUT_SUPPORTED_FORMATS], true); + $resolver = $this->createArgumentResolver([Input::INPUT_SUPPORTED_FORMATS]); $this->inputFactory ->createFromRequest($request, $argument->getType(), $request->getContentType()) @@ -145,8 +136,8 @@ public function provideSupportsWithCustomFormatsInInputAttribute(): iterable yield [false, 'multipart/form-data']; } - private function createArgumentResolver(array $formats, bool $enabled): InputArgumentResolver + private function createArgumentResolver(array $formats): InputArgumentResolver { - return new InputArgumentResolver($this->inputFactory->reveal(), $formats , $enabled); + return new InputArgumentResolver($this->inputFactory->reveal(), $formats); } } \ No newline at end of file diff --git a/tests/DependencyInjection/RequestInputExtensionTest.php b/tests/DependencyInjection/RequestInputExtensionTest.php index 075967f..eeba8ed 100644 --- a/tests/DependencyInjection/RequestInputExtensionTest.php +++ b/tests/DependencyInjection/RequestInputExtensionTest.php @@ -50,20 +50,14 @@ public function testLoadConfiguration(): void InputMetadataFactoryInterface::class ]; - $parameters = [ - 'request_input.enabled' => $config['request_input']['enabled'], - 'request_input.formats' => $config['request_input']['formats'], - 'request_input.skip_validation' => $config['request_input']['skip_validation'], - ]; - - $this->assertContainerHas($services, $aliases, $parameters); + $this->assertContainerHas($services, $aliases); $this->assertServiceHasTags(InputArgumentResolver::class, ['controller.argument_value_resolver']); $this->assertServiceHasTags(ExceptionListener::class, ['kernel.event_listener']); $this->assertServiceHasTags(ReadInputListener::class, ['kernel.event_listener']); } - private function assertContainerHas(array $services, array $aliases = [], array $parameters = []): void + private function assertContainerHas(array $services, array $aliases = []): void { foreach ($services as $service) { $this->assertTrue($this->container->hasDefinition($service), sprintf('Definition "%s" not found.', $service)); @@ -72,10 +66,6 @@ private function assertContainerHas(array $services, array $aliases = [], array foreach ($aliases as $alias) { $this->assertContainerHasAlias($alias); } - - foreach ($parameters as $parameterKey => $parameterValue) { - $this->assertContainerHasParameter($parameterKey, $parameterValue); - } } private function assertContainerHasAlias(string $alias): void @@ -83,12 +73,6 @@ private function assertContainerHasAlias(string $alias): void $this->assertTrue($this->container->hasAlias($alias), sprintf('Alias "%s" not found.', $alias)); } - private function assertContainerHasParameter(string $parameterKey, $parameterValue): void - { - $this->assertTrue($this->container->hasParameter($parameterKey), sprintf('Parameter "%s" not found.', $parameterKey)); - $this->assertSame($this->container->getParameter($parameterKey), $parameterValue); - } - private function assertServiceHasTags(string $service, array $tags = []): void { $serviceTags = $this->container->getDefinition($service)->getTags(); diff --git a/tests/EventListener/ReadInputListenerTest.php b/tests/EventListener/ReadInputListenerTest.php index 993eff1..d86d8a2 100644 --- a/tests/EventListener/ReadInputListenerTest.php +++ b/tests/EventListener/ReadInputListenerTest.php @@ -9,7 +9,7 @@ use Prophecy\Prophecy\ObjectProphecy; use Sfmok\RequestInput\Attribute\Input; use Sfmok\RequestInput\EventListener\ReadInputListener; -use Sfmok\RequestInput\Metadata\InputMetadataFactoryInterface; +use Sfmok\RequestInput\Metadata\InputMetadataFactory; use Sfmok\RequestInput\Tests\Fixtures\Controller\TestController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpKernel\Event\ControllerEvent; @@ -19,64 +19,39 @@ class ReadInputListenerTest extends TestCase { use ProphecyTrait; - private ObjectProphecy $inputMetadataFactory; private ObjectProphecy $httpKernel; protected function setUp(): void { - $this->inputMetadataFactory = $this->prophesize(InputMetadataFactoryInterface::class); $this->httpKernel = $this->prophesize(HttpKernelInterface::class); } public function testOnKernelController(): void { $request = new Request(); - $inputMetadata = new Input(); - $event = $this->getControllerEvent($request); - $this->inputMetadataFactory - ->createInputMetadata($event->getController()) - ->willReturn($inputMetadata) - ->shouldBeCalledOnce() - ; - - $listener = new ReadInputListener($this->inputMetadataFactory->reveal(), true); - + $event = $this->getControllerEvent($request, 'testWithInput'); + $listener = new ReadInputListener(new InputMetadataFactory()); $listener->onKernelController($event); - $this->assertSame($inputMetadata, $request->attributes->get('_input')); + self::assertTrue($request->attributes->has('_input')); + self::assertInstanceOf(Input::class, $request->attributes->get('_input')); } public function testOnKernelControllerWithoutInput(): void { $request = new Request(); - $event = $this->getControllerEvent($request); - $this->inputMetadataFactory - ->createInputMetadata($event->getController()) - ->willReturn(null) - ->shouldBeCalledOnce() - ; - - $listener = new ReadInputListener($this->inputMetadataFactory->reveal(), true); - + $event = $this->getControllerEvent($request, 'testWithoutInput'); + $listener = new ReadInputListener(new InputMetadataFactory()); $listener->onKernelController($event); - $this->assertFalse($request->attributes->has('_input')); - } - - public function testOnKernelControllerWithNonEnabled(): void - { - $event = $this->getControllerEvent(new Request()); - $this->inputMetadataFactory->createInputMetadata()->shouldNotBeCalled(); - $listener = new ReadInputListener($this->inputMetadataFactory->reveal(), false); - - $listener->onKernelController($event); + self::assertFalse($request->attributes->has('_input')); } - private function getControllerEvent(Request $request): ControllerEvent + private function getControllerEvent(Request $request, string $method): ControllerEvent { return new ControllerEvent( $this->httpKernel->reveal(), - [new TestController(), 'testWithInput'], + [new TestController(), $method], $request, HttpKernelInterface::MAIN_REQUEST ); From 800529eff8a996f8180ac7a61d54b0c67cad3700 Mon Sep 17 00:00:00 2001 From: Mokhtar Tlili Date: Sat, 19 Nov 2022 11:49:15 +0100 Subject: [PATCH 2/4] Fix exceptions issues --- src/DependencyInjection/Configuration.php | 2 +- src/EventListener/ExceptionListener.php | 1 - src/EventListener/ReadInputListener.php | 9 +++++++++ src/Exception/UnexpectedFormatException.php | 2 +- src/Factory/InputFactory.php | 6 +++--- tests/DependencyInjection/ConfigurationTest.php | 4 ++-- tests/EventListener/ReadInputListenerTest.php | 12 ++++++++++++ tests/Fixtures/Controller/TestController.php | 5 +++++ 8 files changed, 33 insertions(+), 8 deletions(-) diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index e18e280..9167d11 100755 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -40,7 +40,7 @@ public function getConfigTreeBuilder(): TreeBuilder } return false; }) - ->thenInvalid(sprintf('Only the formats %s are supported. Got %s.', implode(', ', Input::INPUT_SUPPORTED_FORMATS), '%s')) + ->thenInvalid(sprintf('Only the formats [%s] are supported. Got %s.', implode(', ', Input::INPUT_SUPPORTED_FORMATS), '%s')) ->end() ->end() ->booleanNode('skip_validation') diff --git a/src/EventListener/ExceptionListener.php b/src/EventListener/ExceptionListener.php index 2358093..9254faf 100644 --- a/src/EventListener/ExceptionListener.php +++ b/src/EventListener/ExceptionListener.php @@ -9,7 +9,6 @@ use Symfony\Component\HttpFoundation\Response; use Symfony\Component\HttpKernel\Event\ExceptionEvent; use Symfony\Component\Serializer\Exception\NotNormalizableValueException; -use Symfony\Component\Serializer\Exception\PartialDenormalizationException; use Symfony\Component\Serializer\SerializerInterface; class ExceptionListener diff --git a/src/EventListener/ReadInputListener.php b/src/EventListener/ReadInputListener.php index eb9b79c..81cba02 100644 --- a/src/EventListener/ReadInputListener.php +++ b/src/EventListener/ReadInputListener.php @@ -5,6 +5,7 @@ namespace Sfmok\RequestInput\EventListener; use Sfmok\RequestInput\Attribute\Input; +use Sfmok\RequestInput\Exception\UnexpectedFormatException; use Sfmok\RequestInput\Metadata\InputMetadataFactoryInterface; use Symfony\Component\HttpKernel\Event\ControllerEvent; @@ -22,6 +23,14 @@ public function onKernelController(ControllerEvent $event): void return; } + if (!\in_array($inputMetadata->getFormat(), Input::INPUT_SUPPORTED_FORMATS)) { + throw new UnexpectedFormatException(sprintf( + 'Only the formats [%s] are supported. Got %s.', + implode(', ', Input::INPUT_SUPPORTED_FORMATS), + $inputMetadata->getFormat() + )); + } + $event->getRequest()->attributes->set('_input', $inputMetadata); } } diff --git a/src/Exception/UnexpectedFormatException.php b/src/Exception/UnexpectedFormatException.php index d5f9e7b..6311b8b 100644 --- a/src/Exception/UnexpectedFormatException.php +++ b/src/Exception/UnexpectedFormatException.php @@ -6,6 +6,6 @@ use Symfony\Component\HttpKernel\Exception\BadRequestHttpException; -class UnexpectedFormatException extends BadRequestHttpException implements ExceptionInterface +class UnexpectedFormatException extends BadRequestHttpException { } diff --git a/src/Factory/InputFactory.php b/src/Factory/InputFactory.php index ffce861..4ab6ccc 100644 --- a/src/Factory/InputFactory.php +++ b/src/Factory/InputFactory.php @@ -32,9 +32,9 @@ public function createFromRequest(Request $request, string $type, string $format { if (!\in_array($format, Input::INPUT_SUPPORTED_FORMATS)) { throw new UnexpectedFormatException(sprintf( - 'Only the formats %s are supported. Got %s.', - $format, - implode(', ', Input::INPUT_SUPPORTED_FORMATS) + 'Only the formats [%s] are supported. Got %s.', + implode(', ', Input::INPUT_SUPPORTED_FORMATS), + $format )); } diff --git a/tests/DependencyInjection/ConfigurationTest.php b/tests/DependencyInjection/ConfigurationTest.php index 90b0907..3fea119 100644 --- a/tests/DependencyInjection/ConfigurationTest.php +++ b/tests/DependencyInjection/ConfigurationTest.php @@ -50,8 +50,8 @@ public function invalidFormatsProvider(): iterable */ public function testInvalidFormatsConfig(array $formats): void { - $this->expectException(InvalidConfigurationException::class); - $this->expectExceptionMessageMatches('/Only the formats .+ are supported. Got .+./'); + self::expectException(InvalidConfigurationException::class); + self::expectExceptionMessageMatches('/Only the formats .+ are supported. Got .+./'); $this->processor->processConfiguration($this->configuration, [ 'request_input' => [ diff --git a/tests/EventListener/ReadInputListenerTest.php b/tests/EventListener/ReadInputListenerTest.php index d86d8a2..36c47ba 100644 --- a/tests/EventListener/ReadInputListenerTest.php +++ b/tests/EventListener/ReadInputListenerTest.php @@ -9,6 +9,7 @@ use Prophecy\Prophecy\ObjectProphecy; use Sfmok\RequestInput\Attribute\Input; use Sfmok\RequestInput\EventListener\ReadInputListener; +use Sfmok\RequestInput\Exception\UnexpectedFormatException; use Sfmok\RequestInput\Metadata\InputMetadataFactory; use Sfmok\RequestInput\Tests\Fixtures\Controller\TestController; use Symfony\Component\HttpFoundation\Request; @@ -47,6 +48,17 @@ public function testOnKernelControllerWithoutInput(): void self::assertFalse($request->attributes->has('_input')); } + public function testOnKernelControllerWithUnsupportedFormat(): void + { + self::expectException(UnexpectedFormatException::class); + self::expectExceptionMessageMatches('/Only the formats .+ are supported. Got .+./'); + + $request = new Request(); + $event = $this->getControllerEvent($request, 'testWithInputUnsupportedFormat'); + $listener = new ReadInputListener(new InputMetadataFactory()); + $listener->onKernelController($event); + } + private function getControllerEvent(Request $request, string $method): ControllerEvent { return new ControllerEvent( diff --git a/tests/Fixtures/Controller/TestController.php b/tests/Fixtures/Controller/TestController.php index 6bb63a8..765cac1 100644 --- a/tests/Fixtures/Controller/TestController.php +++ b/tests/Fixtures/Controller/TestController.php @@ -21,4 +21,9 @@ public function testWithInput(): void public function testWithoutInput(): void { } + + #[Input(format: 'unsupported')] + public function testWithInputUnsupportedFormat(): void + { + } } \ No newline at end of file From 5c1e0933826e3218a3f974a4192eb46b7ce132bc Mon Sep 17 00:00:00 2001 From: Mokhtar Tlili Date: Sat, 19 Nov 2022 12:10:12 +0100 Subject: [PATCH 3/4] Add .gitattributes --- .gitattributes | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .gitattributes diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..d79dec1 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,5 @@ +/.github export-ignore +.gitattributes export-ignore +.gitignore export-ignore +phpunit.xml export-ignore +/tests export-ignore \ No newline at end of file From 55f5d701bf0f6f9404103eb64377fadc9362b142 Mon Sep 17 00:00:00 2001 From: Mokhtar Tlili Date: Sat, 19 Nov 2022 12:43:56 +0100 Subject: [PATCH 4/4] update changelog/readme files --- CHANGELOG.md | 5 +++++ README.md | 31 ++++++++++++++++++++++++++++++- 2 files changed, 35 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 0ee51f2..03b7cb3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,10 @@ # Changelog +## 1.2.3 +- Register services in bundle extension file +- Fix exceptions issues +- Add .gitattributes + ## 1.2.2 - Handle deserialization exceptions - Update composer.json minimum-stability diff --git a/README.md b/README.md index 3c87e7b..13b6de2 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ - Request data supported: `json`, `xml` and `form` based on header content type. - Resolve inputs arguments for controllers actions. +- Create DTO inputs outside controllers - Validate DTO inputs objects. - Global YAML configuration. - Custom Configuration via Input Attribute per controller action. @@ -86,7 +87,7 @@ Content-Type: application/problem+json; charset=utf-8 } ``` -### Deserialization (v1.2.2) +### Deserialization Whether the request data contains invalid syntax or invalid attributes types a clear 400 json response will return: @@ -126,6 +127,34 @@ request_input: You can also override the format using attribute input and specify the format explicitly. +### Create DTO input outside controller + +You just need to inject `InputFactoryInterface` e.g: +```php +inputFactory->createFromRequest($request, PostInput::class, 'json'); + } +} +``` + ## License The MIT License (MIT). Please see [License File](LICENSE.md) for more information. pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy