Skip to content

Commit 787f1dd

Browse files
committed
Major changes: restructure the whole mapping strategy
1 parent 4bfbc4b commit 787f1dd

32 files changed

+851
-486
lines changed

README.md

Lines changed: 267 additions & 67 deletions
Large diffs are not rendered by default.

src/Attribute/AsInput.php

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sfmok\RequestInput\Attribute;
6+
7+
use Sfmok\RequestInput\Enum\Source;
8+
use Sfmok\RequestInput\Metadata\SerializationMetadata;
9+
use Sfmok\RequestInput\Metadata\ValidationMetadata;
10+
11+
#[\Attribute(\Attribute::TARGET_CLASS)]
12+
final class AsInput
13+
{
14+
public function __construct(
15+
public ?Source $source = null,
16+
public ?ValidationMetadata $validation = null,
17+
public ?SerializationMetadata $serialization = null,
18+
) {}
19+
}

src/Attribute/Input.php

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

src/DependencyInjection/Configuration.php

Lines changed: 24 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,10 @@
44

55
namespace Sfmok\RequestInput\DependencyInjection;
66

7-
use Sfmok\RequestInput\Attribute\Input;
87
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
98
use Symfony\Component\Config\Definition\ConfigurationInterface;
109

1110
/**
12-
* Configuration.
13-
*
1411
* @internal
1512
*/
1613
class Configuration implements ConfigurationInterface
@@ -21,32 +18,32 @@ public function getConfigTreeBuilder(): TreeBuilder
2118
$root = $treeBuilder->getRootNode();
2219

2320
$root
24-
->fixXmlConfig('format', 'formats')
2521
->addDefaultsIfNotSet()
2622
->children()
27-
->booleanNode('enabled')
28-
->defaultTrue()
29-
->end()
30-
->arrayNode('formats')
31-
->defaultValue(Input::INPUT_SUPPORTED_FORMATS)
32-
->requiresAtLeastOneElement()
33-
->scalarPrototype()->end()
34-
->validate()
35-
->ifTrue(function ($values) {
36-
foreach ($values as $value) {
37-
if (!\in_array($value, Input::INPUT_SUPPORTED_FORMATS)) {
38-
return true;
39-
}
40-
}
41-
42-
return false;
43-
})
44-
->thenInvalid(sprintf('Only the formats [%s] are supported. Got %s.', implode(', ', Input::INPUT_SUPPORTED_FORMATS), '%s'))
45-
->end()
46-
->end()
47-
->booleanNode('skip_validation')
48-
->defaultFalse()
49-
->end()
23+
->booleanNode('enabled')
24+
->defaultTrue()
25+
->end()
26+
->arrayNode('validation')
27+
->addDefaultsIfNotSet()
28+
->children()
29+
->booleanNode('skip')
30+
->defaultFalse()
31+
->end()
32+
->integerNode('status_code')
33+
->min(100)
34+
->max(599)
35+
->defaultValue(400)
36+
->end()
37+
->end()
38+
->end()
39+
->arrayNode('serialization')
40+
->addDefaultsIfNotSet()
41+
->children()
42+
->variableNode('context')
43+
->defaultValue([])
44+
->end()
45+
->end()
46+
->end()
5047
->end()
5148
;
5249

src/DependencyInjection/RequestInputExtension.php

Lines changed: 42 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,15 @@
55
namespace Sfmok\RequestInput\DependencyInjection;
66

77
use Sfmok\RequestInput\EventListener\ExceptionListener;
8-
use Sfmok\RequestInput\EventListener\ReadInputListener;
98
use Sfmok\RequestInput\Factory\InputFactory;
109
use Sfmok\RequestInput\Factory\InputFactoryInterface;
11-
use Sfmok\RequestInput\Metadata\InputMetadataFactory;
12-
use Sfmok\RequestInput\Metadata\InputMetadataFactoryInterface;
10+
use Sfmok\RequestInput\Metadata\InputMetadataResolver;
11+
use Sfmok\RequestInput\Metadata\InputMetadataResolverInterface;
12+
use Sfmok\RequestInput\Metadata\SerializationMetadata;
13+
use Sfmok\RequestInput\Metadata\ValidationMetadata;
1314
use Sfmok\RequestInput\ValueResolver\InputValueResolver;
1415
use Symfony\Component\DependencyInjection\ContainerBuilder;
16+
use Symfony\Component\DependencyInjection\Definition;
1517
use Symfony\Component\DependencyInjection\Extension\Extension;
1618
use Symfony\Component\DependencyInjection\Reference;
1719
use Symfony\Component\Serializer\SerializerInterface;
@@ -31,20 +33,29 @@ public function load(array $configs, ContainerBuilder $container): void
3133
return;
3234
}
3335

36+
$globalValidation = $this->createGlobalValidationDefinition($config['validation']);
37+
$globalSerialization = $this->createGlobalSerializationDefinition($config['serialization']);
38+
39+
$container->register(InputMetadataResolver::class)
40+
->setArguments([
41+
'$globalValidation' => $globalValidation,
42+
'$globalSerialization' => $globalSerialization,
43+
])
44+
->setPublic(false)
45+
;
46+
47+
$container->setAlias(InputMetadataResolverInterface::class, InputMetadataResolver::class)->setPublic(false);
48+
3449
$container->register(InputFactory::class)
3550
->setArguments([
3651
'$serializer' => new Reference(SerializerInterface::class),
3752
'$validator' => new Reference(ValidatorInterface::class),
38-
'$skipValidation' => $config['skip_validation'],
39-
'$inputFormats' => $config['formats'],
53+
'$inputMetadataResolver' => new Reference(InputMetadataResolverInterface::class),
4054
])
4155
->setPublic(false)
4256
;
4357

44-
$container->register(InputMetadataFactory::class)->setPublic(false);
45-
4658
$container->setAlias(InputFactoryInterface::class, InputFactory::class)->setPublic(false);
47-
$container->setAlias(InputMetadataFactoryInterface::class, InputMetadataFactory::class)->setPublic(false);
4859

4960
$container->register(InputValueResolver::class)
5061
->setArguments([
@@ -59,11 +70,29 @@ public function load(array $configs, ContainerBuilder $container): void
5970
->addTag('kernel.event_listener', ['event' => 'kernel.exception'])
6071
->setPublic(false)
6172
;
73+
}
6274

63-
$container->register(ReadInputListener::class)
64-
->setArguments(['$inputMetadataFactory' => new Reference(InputMetadataFactoryInterface::class)])
65-
->addTag('kernel.event_listener', ['event' => 'kernel.controller'])
66-
->setPublic(false)
67-
;
75+
/**
76+
* @param array{skip: bool, status_code: int} $validation
77+
*/
78+
private function createGlobalValidationDefinition(array $validation): Definition
79+
{
80+
return (new Definition(ValidationMetadata::class))
81+
->setArguments([
82+
$validation['skip'],
83+
$validation['status_code'],
84+
null,
85+
]);
86+
}
87+
88+
/**
89+
* @param array<string, mixed> $serialization
90+
*/
91+
private function createGlobalSerializationDefinition(array $serialization): Definition
92+
{
93+
return (new Definition(SerializationMetadata::class))
94+
->setArguments([
95+
$serialization['context'],
96+
]);
6897
}
6998
}

src/Enum/Format.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sfmok\RequestInput\Enum;
6+
7+
enum Format: string
8+
{
9+
case Json = 'json';
10+
case Xml = 'xml';
11+
}

src/Enum/Source.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Sfmok\RequestInput\Enum;
6+
7+
enum Source: string
8+
{
9+
case BodyPayload = 'body_payload';
10+
case QueryString = 'query_string';
11+
12+
public function isQueryString(): bool
13+
{
14+
return $this === self::QueryString;
15+
}
16+
}

src/EventListener/ReadInputListener.php

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

src/Exception/ValidationException.php

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,16 @@
44

55
namespace Sfmok\RequestInput\Exception;
66

7-
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
7+
use Symfony\Component\HttpKernel\Exception\HttpException;
88
use Symfony\Component\Validator\ConstraintViolationListInterface;
99

10-
class ValidationException extends BadRequestHttpException implements ExceptionInterface
10+
class ValidationException extends HttpException implements ExceptionInterface
1111
{
12-
private ConstraintViolationListInterface $violationList;
13-
14-
public function __construct(ConstraintViolationListInterface $violationList)
15-
{
16-
$this->violationList = $violationList;
17-
18-
parent::__construct();
12+
public function __construct(
13+
private ConstraintViolationListInterface $violationList,
14+
int $statusCode = 400,
15+
) {
16+
parent::__construct($statusCode);
1917
}
2018

2119
public function getViolationList(): ConstraintViolationListInterface

0 commit comments

Comments
 (0)