RestDtoValueResolver   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 74
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
eloc 28
dl 0
loc 74
ccs 21
cts 21
cp 1
rs 10
c 0
b 0
f 0
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 4 1
A supports() 0 20 5
A resolve() 0 11 3
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * /src/ValueResolver/RestDtoValueResolver.php
5
 *
6
 * @author TLe, Tarmo Leppänen <[email protected]>
7
 */
8
9
namespace App\ValueResolver;
10
11
use App\DTO\RestDtoInterface;
12
use App\Rest\Controller;
13
use App\Rest\ControllerCollection;
14
use AutoMapperPlus\AutoMapperInterface;
15
use Generator;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
18
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
19
use Throwable;
20
use function count;
21
use function explode;
22
use function in_array;
23
24
/**
25
 * Class RestDtoValueResolver
26
 *
27
 * @package App\ValueResolver
28
 * @author TLe, Tarmo Leppänen <[email protected]>
29
 */
30
class RestDtoValueResolver implements ValueResolverInterface
31
{
32
    private const CONTROLLER_KEY = '_controller';
33
34
    /**
35
     * @var array<int, string>
36
     */
37
    private array $supportedActions = [
38
        Controller::ACTION_CREATE,
39
        Controller::ACTION_UPDATE,
40
        Controller::ACTION_PATCH,
41
    ];
42
43
    /**
44
     * @var array<string, string>
45
     */
46
    private array $actionMethodMap = [
47
        Controller::ACTION_CREATE => Controller::METHOD_CREATE,
48
        Controller::ACTION_UPDATE => Controller::METHOD_UPDATE,
49
        Controller::ACTION_PATCH => Controller::METHOD_PATCH,
50
    ];
51
52
    private ?string $controllerName = null;
53
    private ?string $actionName = null;
54
55
    /**
56
     * RestDtoValueResolver constructor.
57
     *
58
     * @param ControllerCollection<Controller> $controllerCollection
59
     */
60 82
    public function __construct(
61
        private readonly ControllerCollection $controllerCollection,
62
        private readonly AutoMapperInterface $autoMapper,
63
    ) {
64 82
    }
65
66 82
    public function supports(Request $request, ArgumentMetadata $argument): bool
67
    {
68 82
        $bits = explode('::', (string)$request->attributes->get(self::CONTROLLER_KEY, ''));
69
70 82
        if (count($bits) !== 2) {
71 3
            return false;
72
        }
73
74 79
        [$controllerName, $actionName] = $bits;
75
76 79
        $output = $argument->getType() === RestDtoInterface::class
77 79
            && in_array($actionName, $this->supportedActions, true)
78 79
            && $this->controllerCollection->has($controllerName);
79
80 79
        if ($output === true) {
81 76
            $this->controllerName = $controllerName;
82 76
            $this->actionName = $actionName;
83
        }
84
85 79
        return $output;
86
    }
87
88
    /**
89
     * @throws Throwable
90
     *
91
     * @return Generator<RestDtoInterface>
92
     */
93 77
    public function resolve(Request $request, ArgumentMetadata $argument): Generator
94
    {
95 77
        if (!$this->supports($request, $argument) || $this->controllerName === null) {
96 2
            return [];
97
        }
98
99 75
        $dtoClass = $this->controllerCollection
100 75
            ->get($this->controllerName)
101 75
            ->getDtoClass($this->actionMethodMap[$this->actionName] ?? null);
102
103 75
        yield $this->autoMapper->map($request, $dtoClass);
104
    }
105
}
106