Proyectos de Subversion Moodle

Rev

| Ultima modificación | Ver Log |

Rev Autor Línea Nro. Línea
1 efrain 1
<?php
2
 
3
declare(strict_types=1);
4
 
5
namespace DI\Definition\Source;
6
 
7
use DI\Definition\ArrayDefinition;
8
use DI\Definition\AutowireDefinition;
9
use DI\Definition\DecoratorDefinition;
10
use DI\Definition\Definition;
11
use DI\Definition\Exception\InvalidDefinition;
12
use DI\Definition\FactoryDefinition;
13
use DI\Definition\Helper\DefinitionHelper;
14
use DI\Definition\ObjectDefinition;
15
use DI\Definition\ValueDefinition;
16
 
17
/**
18
 * Turns raw definitions/definition helpers into definitions ready
19
 * to be resolved or compiled.
20
 *
21
 * @author Matthieu Napoli <matthieu@mnapoli.fr>
22
 */
23
class DefinitionNormalizer
24
{
25
    public function __construct(
26
        private Autowiring $autowiring,
27
    ) {
28
    }
29
 
30
    /**
31
     * Normalize a definition that is *not* nested in another one.
32
     *
33
     * This is usually a definition declared at the root of a definition array.
34
     *
35
     * @param string $name The definition name.
36
     * @param string[] $wildcardsReplacements Replacements for wildcard definitions.
37
     *
38
     * @throws InvalidDefinition
39
     */
40
    public function normalizeRootDefinition(mixed $definition, string $name, array $wildcardsReplacements = null) : Definition
41
    {
42
        if ($definition instanceof DefinitionHelper) {
43
            $definition = $definition->getDefinition($name);
44
        } elseif (is_array($definition)) {
45
            $definition = new ArrayDefinition($definition);
46
        } elseif ($definition instanceof \Closure) {
47
            $definition = new FactoryDefinition($name, $definition);
48
        } elseif (! $definition instanceof Definition) {
49
            $definition = new ValueDefinition($definition);
50
        }
51
 
52
        // For a class definition, we replace * in the class name with the matches
53
        // *Interface -> *Impl => FooInterface -> FooImpl
54
        if ($wildcardsReplacements && $definition instanceof ObjectDefinition) {
55
            $definition->replaceWildcards($wildcardsReplacements);
56
        }
57
 
58
        if ($definition instanceof AutowireDefinition) {
59
            /** @var AutowireDefinition $definition */
60
            $definition = $this->autowiring->autowire($name, $definition);
61
        }
62
 
63
        $definition->setName($name);
64
 
65
        try {
66
            $definition->replaceNestedDefinitions([$this, 'normalizeNestedDefinition']);
67
        } catch (InvalidDefinition $e) {
68
            throw InvalidDefinition::create($definition, sprintf(
69
                'Definition "%s" contains an error: %s',
70
                $definition->getName(),
71
                $e->getMessage()
72
            ), $e);
73
        }
74
 
75
        return $definition;
76
    }
77
 
78
    /**
79
     * Normalize a definition that is nested in another one.
80
     *
81
     * @throws InvalidDefinition
82
     */
83
    public function normalizeNestedDefinition(mixed $definition) : mixed
84
    {
85
        $name = '<nested definition>';
86
 
87
        if ($definition instanceof DefinitionHelper) {
88
            $definition = $definition->getDefinition($name);
89
        } elseif (is_array($definition)) {
90
            $definition = new ArrayDefinition($definition);
91
        } elseif ($definition instanceof \Closure) {
92
            $definition = new FactoryDefinition($name, $definition);
93
        }
94
 
95
        if ($definition instanceof DecoratorDefinition) {
96
            throw new InvalidDefinition('Decorators cannot be nested in another definition');
97
        }
98
 
99
        if ($definition instanceof AutowireDefinition) {
100
            $definition = $this->autowiring->autowire($name, $definition);
101
        }
102
 
103
        if ($definition instanceof Definition) {
104
            $definition->setName($name);
105
 
106
            // Recursively traverse nested definitions
107
            $definition->replaceNestedDefinitions([$this, 'normalizeNestedDefinition']);
108
        }
109
 
110
        return $definition;
111
    }
112
}