Skip to content

Commit 311881f

Browse files
Mokhtar Tlilisfmok
authored andcommitted
Register services in bundle extension file
1 parent 4a648a1 commit 311881f

File tree

8 files changed

+76
-134
lines changed

8 files changed

+76
-134
lines changed

composer.json

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,14 @@
2424
"symfony/serializer": "^4.4 || ^5.0 || ^6.0",
2525
"symfony/validator": "^4.4 || ^5.0 || ^6.0",
2626
"symfony/dependency-injection": "^4.4 || ^5.0 || ^6.0",
27-
"symfony/property-access": "^4.4 || ^5.0 || ^6.0",
28-
"symfony/config": "^4.4 || ^5.0 || ^6.0"
27+
"symfony/property-access": "^4.4 || ^5.0 || ^6.0"
2928
},
3029
"require-dev": {
3130
"phpunit/phpunit": "^9",
3231
"symfony/framework-bundle": "^4.4 || ^5.0 || ^6.0",
3332
"phpspec/prophecy-phpunit": "^2.0",
3433
"friendsofphp/php-cs-fixer": "^3.13",
35-
"phpstan/phpstan": "^1.9",
36-
"symfony/yaml": "^4.4 || ^5.4 || ^6.0"
34+
"phpstan/phpstan": "^1.9"
3735
},
3836
"autoload": {
3937
"psr-4": {

src/ArgumentResolver/InputArgumentResolver.php

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,13 @@
1313

1414
class InputArgumentResolver implements ArgumentValueResolverInterface
1515
{
16-
public function __construct(
17-
private InputFactoryInterface $inputFactory,
18-
private array $inputFormats,
19-
private bool $enabled = true
20-
) {
16+
public function __construct(private InputFactoryInterface $inputFactory, private array $inputFormats)
17+
{
2118
}
2219

2320
public function supports(Request $request, ArgumentMetadata $argument): bool
2421
{
25-
if (!$this->enabled || !is_subclass_of($argument->getType(), InputInterface::class)) {
22+
if (!is_subclass_of($argument->getType(), InputInterface::class)) {
2623
return false;
2724
}
2825

src/DependencyInjection/RequestInputExtension.php

Lines changed: 46 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@
44

55
namespace Sfmok\RequestInput\DependencyInjection;
66

7-
use Symfony\Component\Config\FileLocator;
7+
use Sfmok\RequestInput\ArgumentResolver\InputArgumentResolver;
8+
use Sfmok\RequestInput\Factory\InputFactory;
9+
use Sfmok\RequestInput\Factory\InputFactoryInterface;
10+
use Sfmok\RequestInput\Metadata\InputMetadataFactory;
11+
use Sfmok\RequestInput\Metadata\InputMetadataFactoryInterface;
12+
use Sfmok\RequestInput\EventListener\ReadInputListener;
13+
use Sfmok\RequestInput\EventListener\ExceptionListener;
814
use Symfony\Component\DependencyInjection\ContainerBuilder;
9-
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
15+
use Symfony\Component\DependencyInjection\Reference;
1016
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
17+
use Symfony\Component\Serializer\SerializerInterface;
18+
use Symfony\Component\Validator\Validator\ValidatorInterface;
1119

1220
/**
1321
* @internal
@@ -19,17 +27,43 @@ public function load(array $configs, ContainerBuilder $container): void
1927
$configuration = new Configuration();
2028
$config = $this->processConfiguration($configuration, $configs);
2129

22-
# define a few parameters
23-
$container->setParameter('request_input.enabled', $config['enabled']);
24-
$container->setParameter('request_input.formats', $config['formats']);
25-
$container->setParameter('request_input.skip_validation', $config['skip_validation']);
30+
if (!$config['enabled']) {
31+
return;
32+
}
2633

27-
$this->loadServicesFiles($container);
28-
}
34+
$container->register(InputFactory::class)
35+
->setArguments([
36+
'$serializer' => new Reference(SerializerInterface::class),
37+
'$validator' => new Reference(ValidatorInterface::class),
38+
'$skipValidation' => $config['skip_validation'],
39+
])
40+
->setPublic(false)
41+
;
2942

30-
protected function loadServicesFiles(ContainerBuilder $container): void
31-
{
32-
$loader = new YamlFileLoader($container, new FileLocator(__DIR__ . '/../Resources/config'));
33-
$loader->load('services.yaml');
43+
$container->register(InputMetadataFactory::class)->setPublic(false);
44+
45+
$container->setAlias(InputFactoryInterface::class, InputFactory::class)->setPublic(false);
46+
$container->setAlias(InputMetadataFactoryInterface::class, InputMetadataFactory::class)->setPublic(false);
47+
48+
$container->register(InputArgumentResolver::class)
49+
->setArguments([
50+
'$inputFactory' => new Reference(InputFactoryInterface::class),
51+
'$inputFormats' => $config['formats'],
52+
])
53+
->addTag('controller.argument_value_resolver', ['priority' => 40])
54+
->setPublic(false)
55+
;
56+
57+
$container->register(ExceptionListener::class)
58+
->setArguments(['$serializer' => new Reference(SerializerInterface::class)])
59+
->addTag('kernel.event_listener', ['event' => 'kernel.exception'])
60+
->setPublic(false)
61+
;
62+
63+
$container->register(ReadInputListener::class)
64+
->setArguments(['$inputMetadataFactory' => new Reference(InputMetadataFactoryInterface::class)])
65+
->addTag('kernel.event_listener', ['event' => 'kernel.controller'])
66+
->setPublic(false)
67+
;
3468
}
3569
}

src/EventListener/ReadInputListener.php

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,25 +10,18 @@
1010

1111
class ReadInputListener
1212
{
13-
public function __construct(
14-
private InputMetadataFactoryInterface $inputMetadataFactory,
15-
private bool $enabled = true
16-
) {
13+
public function __construct(private InputMetadataFactoryInterface $inputMetadataFactory)
14+
{
1715
}
1816

1917
public function onKernelController(ControllerEvent $event): void
2018
{
21-
if (!$this->enabled) {
22-
return;
23-
}
24-
25-
$request = $event->getRequest();
26-
$input = $this->inputMetadataFactory->createInputMetadata($event->getController());
19+
$inputMetadata = $this->inputMetadataFactory->createInputMetadata($event->getController());
2720

28-
if (!$input instanceof Input) {
21+
if (!$inputMetadata instanceof Input) {
2922
return;
3023
}
3124

32-
$request->attributes->set('_input', $input);
25+
$event->getRequest()->attributes->set('_input', $inputMetadata);
3326
}
3427
}

src/Resources/config/services.yaml

Lines changed: 0 additions & 30 deletions
This file was deleted.

tests/ArgumentResolver/InputArgumentResolverTest.php

Lines changed: 8 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,21 +25,13 @@ protected function setUp(): void
2525
$this->inputFactory = $this->prophesize(InputFactoryInterface::class);
2626
}
2727

28-
public function testSupportsWithNonEnabledInput(): void
29-
{
30-
$request = new Request();
31-
$argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null);
32-
33-
$resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, false);
34-
$this->assertFalse($resolver->supports($request, $argument));
35-
}
36-
3728
public function testSupportsWithArgumentTypeNotInput(): void
3829
{
3930
$request = new Request();
31+
$request->headers->set('Content-Type', 'application/json');
4032
$argument = new ArgumentMetadata('foo', \stdClass::class, false, false, null);
4133

42-
$resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, true);
34+
$resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS);
4335
$this->assertFalse($resolver->supports($request, $argument));
4436
}
4537

@@ -50,10 +42,9 @@ public function testSupportsWithDefaultGlobalFormats(bool $expected, ?string $co
5042
{
5143
$request = new Request();
5244
$request->headers->set('Content-Type', $contentType);
53-
5445
$argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null);
5546

56-
$resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, true);
47+
$resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS);
5748
$this->assertSame($expected, $resolver->supports($request, $argument));
5849
}
5950

@@ -67,7 +58,7 @@ public function testSupportsWithCustomGlobalFormats(bool $expected, ?string $con
6758

6859
$argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null);
6960

70-
$resolver = $this->createArgumentResolver(['json'], true);
61+
$resolver = $this->createArgumentResolver(['json']);
7162
$this->assertSame($expected, $resolver->supports($request, $argument));
7263
}
7364

@@ -82,7 +73,7 @@ public function testSupportsWithCustomFormatsInInputAttribute(bool $expected, ?s
8273

8374
$argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null);
8475

85-
$resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS, true);
76+
$resolver = $this->createArgumentResolver(Input::INPUT_SUPPORTED_FORMATS);
8677
$this->assertSame($expected, $resolver->supports($request, $argument));
8778
}
8879

@@ -95,7 +86,7 @@ public function testResolveSucceeds(): void
9586

9687
$argument = new ArgumentMetadata('foo', DummyInput::class, false, false, null);
9788

98-
$resolver = $this->createArgumentResolver([Input::INPUT_SUPPORTED_FORMATS], true);
89+
$resolver = $this->createArgumentResolver([Input::INPUT_SUPPORTED_FORMATS]);
9990

10091
$this->inputFactory
10192
->createFromRequest($request, $argument->getType(), $request->getContentType())
@@ -145,8 +136,8 @@ public function provideSupportsWithCustomFormatsInInputAttribute(): iterable
145136
yield [false, 'multipart/form-data'];
146137
}
147138

148-
private function createArgumentResolver(array $formats, bool $enabled): InputArgumentResolver
139+
private function createArgumentResolver(array $formats): InputArgumentResolver
149140
{
150-
return new InputArgumentResolver($this->inputFactory->reveal(), $formats , $enabled);
141+
return new InputArgumentResolver($this->inputFactory->reveal(), $formats);
151142
}
152143
}

tests/DependencyInjection/RequestInputExtensionTest.php

Lines changed: 2 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -50,20 +50,14 @@ public function testLoadConfiguration(): void
5050
InputMetadataFactoryInterface::class
5151
];
5252

53-
$parameters = [
54-
'request_input.enabled' => $config['request_input']['enabled'],
55-
'request_input.formats' => $config['request_input']['formats'],
56-
'request_input.skip_validation' => $config['request_input']['skip_validation'],
57-
];
58-
59-
$this->assertContainerHas($services, $aliases, $parameters);
53+
$this->assertContainerHas($services, $aliases);
6054

6155
$this->assertServiceHasTags(InputArgumentResolver::class, ['controller.argument_value_resolver']);
6256
$this->assertServiceHasTags(ExceptionListener::class, ['kernel.event_listener']);
6357
$this->assertServiceHasTags(ReadInputListener::class, ['kernel.event_listener']);
6458
}
6559

66-
private function assertContainerHas(array $services, array $aliases = [], array $parameters = []): void
60+
private function assertContainerHas(array $services, array $aliases = []): void
6761
{
6862
foreach ($services as $service) {
6963
$this->assertTrue($this->container->hasDefinition($service), sprintf('Definition "%s" not found.', $service));
@@ -72,23 +66,13 @@ private function assertContainerHas(array $services, array $aliases = [], array
7266
foreach ($aliases as $alias) {
7367
$this->assertContainerHasAlias($alias);
7468
}
75-
76-
foreach ($parameters as $parameterKey => $parameterValue) {
77-
$this->assertContainerHasParameter($parameterKey, $parameterValue);
78-
}
7969
}
8070

8171
private function assertContainerHasAlias(string $alias): void
8272
{
8373
$this->assertTrue($this->container->hasAlias($alias), sprintf('Alias "%s" not found.', $alias));
8474
}
8575

86-
private function assertContainerHasParameter(string $parameterKey, $parameterValue): void
87-
{
88-
$this->assertTrue($this->container->hasParameter($parameterKey), sprintf('Parameter "%s" not found.', $parameterKey));
89-
$this->assertSame($this->container->getParameter($parameterKey), $parameterValue);
90-
}
91-
9276
private function assertServiceHasTags(string $service, array $tags = []): void
9377
{
9478
$serviceTags = $this->container->getDefinition($service)->getTags();

tests/EventListener/ReadInputListenerTest.php

Lines changed: 10 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
use Prophecy\Prophecy\ObjectProphecy;
1010
use Sfmok\RequestInput\Attribute\Input;
1111
use Sfmok\RequestInput\EventListener\ReadInputListener;
12-
use Sfmok\RequestInput\Metadata\InputMetadataFactoryInterface;
12+
use Sfmok\RequestInput\Metadata\InputMetadataFactory;
1313
use Sfmok\RequestInput\Tests\Fixtures\Controller\TestController;
1414
use Symfony\Component\HttpFoundation\Request;
1515
use Symfony\Component\HttpKernel\Event\ControllerEvent;
@@ -19,64 +19,39 @@ class ReadInputListenerTest extends TestCase
1919
{
2020
use ProphecyTrait;
2121

22-
private ObjectProphecy $inputMetadataFactory;
2322
private ObjectProphecy $httpKernel;
2423

2524
protected function setUp(): void
2625
{
27-
$this->inputMetadataFactory = $this->prophesize(InputMetadataFactoryInterface::class);
2826
$this->httpKernel = $this->prophesize(HttpKernelInterface::class);
2927
}
3028

3129
public function testOnKernelController(): void
3230
{
3331
$request = new Request();
34-
$inputMetadata = new Input();
35-
$event = $this->getControllerEvent($request);
36-
$this->inputMetadataFactory
37-
->createInputMetadata($event->getController())
38-
->willReturn($inputMetadata)
39-
->shouldBeCalledOnce()
40-
;
41-
42-
$listener = new ReadInputListener($this->inputMetadataFactory->reveal(), true);
43-
32+
$event = $this->getControllerEvent($request, 'testWithInput');
33+
$listener = new ReadInputListener(new InputMetadataFactory());
4434
$listener->onKernelController($event);
4535

46-
$this->assertSame($inputMetadata, $request->attributes->get('_input'));
36+
self::assertTrue($request->attributes->has('_input'));
37+
self::assertInstanceOf(Input::class, $request->attributes->get('_input'));
4738
}
4839

4940
public function testOnKernelControllerWithoutInput(): void
5041
{
5142
$request = new Request();
52-
$event = $this->getControllerEvent($request);
53-
$this->inputMetadataFactory
54-
->createInputMetadata($event->getController())
55-
->willReturn(null)
56-
->shouldBeCalledOnce()
57-
;
58-
59-
$listener = new ReadInputListener($this->inputMetadataFactory->reveal(), true);
60-
43+
$event = $this->getControllerEvent($request, 'testWithoutInput');
44+
$listener = new ReadInputListener(new InputMetadataFactory());
6145
$listener->onKernelController($event);
6246

63-
$this->assertFalse($request->attributes->has('_input'));
64-
}
65-
66-
public function testOnKernelControllerWithNonEnabled(): void
67-
{
68-
$event = $this->getControllerEvent(new Request());
69-
$this->inputMetadataFactory->createInputMetadata()->shouldNotBeCalled();
70-
$listener = new ReadInputListener($this->inputMetadataFactory->reveal(), false);
71-
72-
$listener->onKernelController($event);
47+
self::assertFalse($request->attributes->has('_input'));
7348
}
7449

75-
private function getControllerEvent(Request $request): ControllerEvent
50+
private function getControllerEvent(Request $request, string $method): ControllerEvent
7651
{
7752
return new ControllerEvent(
7853
$this->httpKernel->reveal(),
79-
[new TestController(), 'testWithInput'],
54+
[new TestController(), $method],
8055
$request,
8156
HttpKernelInterface::MAIN_REQUEST
8257
);

0 commit comments

Comments
 (0)