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\ObjectDefinition;
8
use DI\Definition\ObjectDefinition\MethodInjection;
9
use DI\Definition\Reference;
10
use ReflectionNamedType;
11
 
12
/**
13
 * Reads DI class definitions using reflection.
14
 *
15
 * @author Matthieu Napoli <matthieu@mnapoli.fr>
16
 */
17
class ReflectionBasedAutowiring implements DefinitionSource, Autowiring
18
{
19
    public function autowire(string $name, ObjectDefinition $definition = null) : ObjectDefinition|null
20
    {
21
        $className = $definition ? $definition->getClassName() : $name;
22
 
23
        if (!class_exists($className) && !interface_exists($className)) {
24
            return $definition;
25
        }
26
 
27
        $definition = $definition ?: new ObjectDefinition($name);
28
 
29
        // Constructor
30
        $class = new \ReflectionClass($className);
31
        $constructor = $class->getConstructor();
32
        if ($constructor && $constructor->isPublic()) {
33
            $constructorInjection = MethodInjection::constructor($this->getParametersDefinition($constructor));
34
            $definition->completeConstructorInjection($constructorInjection);
35
        }
36
 
37
        return $definition;
38
    }
39
 
40
    public function getDefinition(string $name) : ObjectDefinition|null
41
    {
42
        return $this->autowire($name);
43
    }
44
 
45
    /**
46
     * Autowiring cannot guess all existing definitions.
47
     */
48
    public function getDefinitions() : array
49
    {
50
        return [];
51
    }
52
 
53
    /**
54
     * Read the type-hinting from the parameters of the function.
55
     */
56
    private function getParametersDefinition(\ReflectionFunctionAbstract $constructor) : array
57
    {
58
        $parameters = [];
59
 
60
        foreach ($constructor->getParameters() as $index => $parameter) {
61
            // Skip optional parameters
62
            if ($parameter->isOptional()) {
63
                continue;
64
            }
65
 
66
            $parameterType = $parameter->getType();
67
            if (!$parameterType) {
68
                // No type
69
                continue;
70
            }
71
            if (!$parameterType instanceof ReflectionNamedType) {
72
                // Union types are not supported
73
                continue;
74
            }
75
            if ($parameterType->isBuiltin()) {
76
                // Primitive types are not supported
77
                continue;
78
            }
79
 
80
            $parameters[$index] = new Reference($parameterType->getName());
81
        }
82
 
83
        return $parameters;
84
    }
85
}