Passed
Pull Request — master (#2064)
by Tarmo
09:38
created

EntityValueResolver::supports()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 3
nop 2
dl 0
loc 5
ccs 4
cts 4
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
declare(strict_types = 1);
3
/**
4
 * /src/ValueResolver/EntityValueResolver.php
5
 *
6
 * @author TLe, Tarmo Leppänen <[email protected]>
7
 */
8
9
namespace App\ValueResolver;
10
11
use App\Entity\Interfaces\EntityInterface;
12
use App\Resource\ResourceCollection;
13
use Generator;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpKernel\Controller\ValueResolverInterface;
16
use Symfony\Component\HttpKernel\ControllerMetadata\ArgumentMetadata;
17
use Throwable;
18
use function is_string;
19
use function is_subclass_of;
20
21
/**
22
 * Class EntityValueResolver
23
 *
24
 * Example how to use this within your controller;
25
 *
26
 *  #[Route(path: 'some_path_to_your_route/{user}/{apikey}')]
27
 *  public function someMethod(\App\Entity\User $user, \App\Entity\ApiKey $apikey): Response
28
 *  {
29
 *      ...
30
 *  }
31
 *
32
 * And when you make your request like `GET /some_path_to_your_route/_user_uuid_/_apikey_uuid`
33
 * you will get those entities to your controller method which are resolved automatically via
34
 * those entity resource classes.
35
 *
36
 * Only thing that you need check is that parameter in your `path` definition matches with
37
 * method argument name.
38
 *
39
 * @package App\ValueResolver
40
 * @author TLe, Tarmo Leppänen <[email protected]>
41
 */
42
class EntityValueResolver implements ValueResolverInterface
43
{
44 325
    public function __construct(
45
        private readonly ResourceCollection $resourceCollection,
46
    ) {
47
    }
48
49 325
    public function supports(Request $request, ArgumentMetadata $argument): bool
50
    {
51 325
        return is_string($this->getUuid($argument, $request))
52 325
            && is_subclass_of((string)$argument->getType(), EntityInterface::class, true)
53 325
            && $this->resourceCollection->hasEntityResource($argument->getType());
54
    }
55
56
    /**
57
     * @throws Throwable
58
     *
59
     * @return Generator<EntityInterface|null>
60
     */
61 321
    public function resolve(Request $request, ArgumentMetadata $argument): Generator
62
    {
63 321
        if (!$this->supports($request, $argument)) {
64 320
            return [];
65
        }
66
67 1
        yield $this->resourceCollection
68 1
            ->getEntityResource((string)$argument->getType())
69 1
            ->findOne((string)($this->getUuid($argument, $request)), !$argument->isNullable());
70
    }
71
72 325
    private function getUuid(ArgumentMetadata $argument, Request $request): mixed
73
    {
74 325
        $argumentName = $argument->getName();
75
76 325
        return $request->attributes->get($argumentName)
77 275
            ?? $request->request->get($argumentName)
78 325
            ?? $request->query->get($argumentName);
79
    }
80
}
81