Passed
Push — master ( b6ddb2...6e9ccf )
by Kévin
18:24 queued 13:31
created

Compiler/AnnotationFilterPass.php (1 issue)

Labels
Severity
1
<?php
2
3
/*
4
 * This file is part of the API Platform project.
5
 *
6
 * (c) Kévin Dunglas <[email protected]>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace ApiPlatform\Core\Bridge\Symfony\Bundle\DependencyInjection\Compiler;
15
16
use ApiPlatform\Core\Util\AnnotationFilterExtractorTrait;
17
use ApiPlatform\Core\Util\ReflectionClassRecursiveIterator;
18
use Doctrine\Common\Annotations\Reader;
19
use Symfony\Component\DependencyInjection\ChildDefinition;
20
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
21
use Symfony\Component\DependencyInjection\ContainerBuilder;
22
use Symfony\Component\DependencyInjection\Definition;
23
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
24
25
/**
26
 * Injects filters.
27
 *
28
 * @internal
29
 *
30
 * @author Antoine Bluchet <[email protected]>
31
 */
32
final class AnnotationFilterPass implements CompilerPassInterface
33
{
34
    use AnnotationFilterExtractorTrait;
35
36
    private const TAG_FILTER_NAME = 'api_platform.filter';
37
38
    /**
39
     * @var Reader|null
40
     */
41
    private $reader;
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    public function process(ContainerBuilder $container)
47
    {
48
        $resourceClassDirectories = $container->getParameter('api_platform.resource_class_directories');
49
50
        foreach (ReflectionClassRecursiveIterator::getReflectionClassesFromDirectories($resourceClassDirectories) as $className => $reflectionClass) {
51
            $this->createFilterDefinitions($reflectionClass, $container);
52
        }
53
    }
54
55
    /**
56
     * @throws InvalidArgumentException
57
     */
58
    private function createFilterDefinitions(\ReflectionClass $reflectionClass, ContainerBuilder $container): void
59
    {
60
        $reader = $this->reader ?? $this->reader = $container->get('annotation_reader');
61
62
        foreach ($this->readFilterAnnotations($reflectionClass, $reader) as $id => [$arguments, $filterClass]) {
0 ignored issues
show
It seems like $reader can also be of type null; however, parameter $reader of ApiPlatform\Core\Bridge\...readFilterAnnotations() does only seem to accept Doctrine\Common\Annotations\Reader, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

62
        foreach ($this->readFilterAnnotations($reflectionClass, /** @scrutinizer ignore-type */ $reader) as $id => [$arguments, $filterClass]) {
Loading history...
63
            if ($container->has($id)) {
64
                continue;
65
            }
66
67
            if ($container->has($filterClass) && ($definition = $container->findDefinition($filterClass))->isAbstract()) {
68
                $definition = new ChildDefinition($definition->getClass());
69
            } elseif ($reflectionClass = $container->getReflectionClass($filterClass, false)) {
70
                $definition = new Definition($reflectionClass->getName());
71
                $definition->setAutoconfigured(true);
72
            } else {
73
                throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $filterClass, $id));
74
            }
75
76
            $definition->addTag(self::TAG_FILTER_NAME);
77
            $definition->setAutowired(true);
78
79
            foreach ($arguments as $key => $value) {
80
                $definition->setArgument("$$key", $value);
81
            }
82
83
            $container->setDefinition($id, $definition);
84
        }
85
    }
86
}
87