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\Dumper;
6
 
7
use DI\Definition\Definition;
8
use DI\Definition\ObjectDefinition;
9
use DI\Definition\ObjectDefinition\MethodInjection;
10
use ReflectionException;
11
 
12
/**
13
 * Dumps object definitions to string for debugging purposes.
14
 *
15
 * @since 4.1
16
 * @author Matthieu Napoli <matthieu@mnapoli.fr>
17
 */
18
class ObjectDefinitionDumper
19
{
20
    /**
21
     * Returns the definition as string representation.
22
     */
23
    public function dump(ObjectDefinition $definition) : string
24
    {
25
        $className = $definition->getClassName();
26
        $classExist = class_exists($className) || interface_exists($className);
27
 
28
        // Class
29
        if (! $classExist) {
30
            $warning = '#UNKNOWN# ';
31
        } else {
32
            $class = new \ReflectionClass($className);
33
            $warning = $class->isInstantiable() ? '' : '#NOT INSTANTIABLE# ';
34
        }
35
        $str = sprintf('    class = %s%s', $warning, $className);
36
 
37
        // Lazy
38
        $str .= \PHP_EOL . '    lazy = ' . var_export($definition->isLazy(), true);
39
 
40
        if ($classExist) {
41
            // Constructor
42
            $str .= $this->dumpConstructor($className, $definition);
43
 
44
            // Properties
45
            $str .= $this->dumpProperties($definition);
46
 
47
            // Methods
48
            $str .= $this->dumpMethods($className, $definition);
49
        }
50
 
51
        return sprintf('Object (' . \PHP_EOL . '%s' . \PHP_EOL . ')', $str);
52
    }
53
 
54
    /**
55
     * @param class-string $className
56
     */
57
    private function dumpConstructor(string $className, ObjectDefinition $definition) : string
58
    {
59
        $str = '';
60
 
61
        $constructorInjection = $definition->getConstructorInjection();
62
 
63
        if ($constructorInjection !== null) {
64
            $parameters = $this->dumpMethodParameters($className, $constructorInjection);
65
 
66
            $str .= sprintf(\PHP_EOL . '    __construct(' . \PHP_EOL . '        %s' . \PHP_EOL . '    )', $parameters);
67
        }
68
 
69
        return $str;
70
    }
71
 
72
    private function dumpProperties(ObjectDefinition $definition) : string
73
    {
74
        $str = '';
75
 
76
        foreach ($definition->getPropertyInjections() as $propertyInjection) {
77
            $value = $propertyInjection->getValue();
78
            $valueStr = $value instanceof Definition ? (string) $value : var_export($value, true);
79
 
80
            $str .= sprintf(\PHP_EOL . '    $%s = %s', $propertyInjection->getPropertyName(), $valueStr);
81
        }
82
 
83
        return $str;
84
    }
85
 
86
    /**
87
     * @param class-string $className
88
     */
89
    private function dumpMethods(string $className, ObjectDefinition $definition) : string
90
    {
91
        $str = '';
92
 
93
        foreach ($definition->getMethodInjections() as $methodInjection) {
94
            $parameters = $this->dumpMethodParameters($className, $methodInjection);
95
 
96
            $str .= sprintf(\PHP_EOL . '    %s(' . \PHP_EOL . '        %s' . \PHP_EOL . '    )', $methodInjection->getMethodName(), $parameters);
97
        }
98
 
99
        return $str;
100
    }
101
 
102
    /**
103
     * @param class-string $className
104
     */
105
    private function dumpMethodParameters(string $className, MethodInjection $methodInjection) : string
106
    {
107
        $methodReflection = new \ReflectionMethod($className, $methodInjection->getMethodName());
108
 
109
        $args = [];
110
 
111
        $definitionParameters = $methodInjection->getParameters();
112
 
113
        foreach ($methodReflection->getParameters() as $index => $parameter) {
114
            if (array_key_exists($index, $definitionParameters)) {
115
                $value = $definitionParameters[$index];
116
                $valueStr = $value instanceof Definition ? (string) $value : var_export($value, true);
117
 
118
                $args[] = sprintf('$%s = %s', $parameter->getName(), $valueStr);
119
 
120
                continue;
121
            }
122
 
123
            // If the parameter is optional and wasn't specified, we take its default value
124
            if ($parameter->isOptional()) {
125
                try {
126
                    $value = $parameter->getDefaultValue();
127
 
128
                    $args[] = sprintf(
129
                        '$%s = (default value) %s',
130
                        $parameter->getName(),
131
                        var_export($value, true)
132
                    );
133
                    continue;
134
                } catch (ReflectionException) {
135
                    // The default value can't be read through Reflection because it is a PHP internal class
136
                }
137
            }
138
 
139
            $args[] = sprintf('$%s = #UNDEFINED#', $parameter->getName());
140
        }
141
 
142
        return implode(\PHP_EOL . '        ', $args);
143
    }
144
}