Issues (11)

Compiler/AbstractRegisterAttributePass.php (1 issue)

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
7
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
9
 *
10
 * Copyright (c) 2024 Mykhailo Shtanko [email protected]
11
 *
12
 * For the full copyright and license information, please view the LICENSE.MD
13
 * file that was distributed with this source code.
14
 */
15
16
namespace FRZB\Component\DependencyInjection\Compiler;
17
18
use Fp\Collections\ArrayList;
19
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
20
use Symfony\Component\DependencyInjection\ContainerBuilder;
21
use Symfony\Component\DependencyInjection\Definition;
22
23
/**
24
 * @internal
25
 *
26
 * Registers services by attributes in DI
27
 *
28
 * @author Mykhailo Shtanko <[email protected]>
29
 *
30
 * @method void register(ContainerBuilder $container, \ReflectionClass $reflectionClass, \Attribute $attribute)
31
 */
32
abstract class AbstractRegisterAttributePass implements CompilerPassInterface
33
{
34
    /** @var class-string */
0 ignored issues
show
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
35
    private string $attributeClass;
36
37
    public function __construct(string $attributeClass)
38
    {
39
        $this->attributeClass = $attributeClass;
40
    }
41
42
    /** @throws \ReflectionException */
43
    public function process(ContainerBuilder $container): void
44
    {
45
        foreach ($container->getDefinitions() as $definition) {
46
            if ($this->accept($definition) && $reflectionClass = $container->getReflectionClass($definition->getClass(), false)) {
47
                $this->processClass($container, $reflectionClass);
48
            }
49
        }
50
    }
51
52
    protected function processClass(ContainerBuilder $container, \ReflectionClass $reflectionClass): void
53
    {
54
        ArrayList::collect($reflectionClass->getAttributes($this->attributeClass, \ReflectionAttribute::IS_INSTANCEOF))
55
            ->tap(fn (\ReflectionAttribute $attribute) => $this->register($container, $reflectionClass, $attribute->newInstance()))
56
        ;
57
    }
58
59
    protected function accept(Definition $definition): bool
60
    {
61
        return $definition->isAutoconfigured() && $this->isAttributesIgnored($definition);
62
    }
63
64
    protected function isAttributesIgnored(Definition $definition): bool
65
    {
66
        return !$definition->hasTag('container.ignore_attributes');
67
    }
68
}
69