PluginProbe
The Innovative Form Builder – IvyForms / 0.2
The Innovative Form Builder – IvyForms v0.2
1.5.1 1.5 1.4.1 1.4 trunk 0.1.2 0.2 0.2.1 0.3 0.3.1 0.4 0.5 0.6 0.6.1 0.6.1-backup 0.6.1.1 0.7 0.8 0.8.1 0.8.2 0.9 0.9.1 1.0 1.1 1.1.1 All 27 releases
ivyforms / backend / vendor / php-di / php-di / src / Definition / Helper / CreateDefinitionHelper.php

CreateDefinitionHelper.php in The Innovative Form Builder – IvyForms 0.2, at backend/vendor/php-di/php-di/src/Definition/Helper/CreateDefinitionHelper.php

203 lines 5.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 declare(strict_types=1);
4
5 namespace DI\Definition\Helper;
6
7 use DI\Definition\Definition;
8 use DI\Definition\Exception\InvalidDefinition;
9 use DI\Definition\ObjectDefinition;
10 use DI\Definition\ObjectDefinition\MethodInjection;
11 use DI\Definition\ObjectDefinition\PropertyInjection;
12
13 /**
14 * Helps defining how to create an instance of a class.
15 *
16 * @author Matthieu Napoli <[email protected]>
17 */
18 class CreateDefinitionHelper implements DefinitionHelper
19 {
20 const DEFINITION_CLASS = ObjectDefinition::class;
21
22 /**
23 * @var string|null
24 */
25 private $className;
26
27 /**
28 * @var bool|null
29 */
30 private $lazy;
31
32 /**
33 * Array of constructor parameters.
34 * @var array
35 */
36 protected $constructor = [];
37
38 /**
39 * Array of properties and their value.
40 * @var array
41 */
42 private $properties = [];
43
44 /**
45 * Array of methods and their parameters.
46 * @var array
47 */
48 protected $methods = [];
49
50 /**
51 * Helper for defining an object.
52 *
53 * @param string|null $className Class name of the object.
54 * If null, the name of the entry (in the container) will be used as class name.
55 */
56 public function __construct(string $className = null)
57 {
58 $this->className = $className;
59 }
60
61 /**
62 * Define the entry as lazy.
63 *
64 * A lazy entry is created only when it is used, a proxy is injected instead.
65 *
66 * @return $this
67 */
68 public function lazy()
69 {
70 $this->lazy = true;
71
72 return $this;
73 }
74
75 /**
76 * Defines the arguments to use to call the constructor.
77 *
78 * This method takes a variable number of arguments, example:
79 * ->constructor($param1, $param2, $param3)
80 *
81 * @param mixed... $parameters Parameters to use for calling the constructor of the class.
82 *
83 * @return $this
84 */
85 public function constructor(...$parameters)
86 {
87 $this->constructor = $parameters;
88
89 return $this;
90 }
91
92 /**
93 * Defines a value to inject in a property of the object.
94 *
95 * @param string $property Entry in which to inject the value.
96 * @param mixed $value Value to inject in the property.
97 *
98 * @return $this
99 */
100 public function property(string $property, $value)
101 {
102 $this->properties[$property] = $value;
103
104 return $this;
105 }
106
107 /**
108 * Defines a method to call and the arguments to use.
109 *
110 * This method takes a variable number of arguments after the method name, example:
111 *
112 * ->method('myMethod', $param1, $param2)
113 *
114 * Can be used multiple times to declare multiple calls.
115 *
116 * @param string $method Name of the method to call.
117 * @param mixed... $parameters Parameters to use for calling the method.
118 *
119 * @return $this
120 */
121 public function method(string $method, ...$parameters)
122 {
123 if (! isset($this->methods[$method])) {
124 $this->methods[$method] = [];
125 }
126
127 $this->methods[$method][] = $parameters;
128
129 return $this;
130 }
131
132 /**
133 * @return ObjectDefinition
134 */
135 public function getDefinition(string $entryName) : Definition
136 {
137 $class = $this::DEFINITION_CLASS;
138 /** @var ObjectDefinition $definition */
139 $definition = new $class($entryName, $this->className);
140
141 if ($this->lazy !== null) {
142 $definition->setLazy($this->lazy);
143 }
144
145 if (! empty($this->constructor)) {
146 $parameters = $this->fixParameters($definition, '__construct', $this->constructor);
147 $constructorInjection = MethodInjection::constructor($parameters);
148 $definition->setConstructorInjection($constructorInjection);
149 }
150
151 if (! empty($this->properties)) {
152 foreach ($this->properties as $property => $value) {
153 $definition->addPropertyInjection(
154 new PropertyInjection($property, $value)
155 );
156 }
157 }
158
159 if (! empty($this->methods)) {
160 foreach ($this->methods as $method => $calls) {
161 foreach ($calls as $parameters) {
162 $parameters = $this->fixParameters($definition, $method, $parameters);
163 $methodInjection = new MethodInjection($method, $parameters);
164 $definition->addMethodInjection($methodInjection);
165 }
166 }
167 }
168
169 return $definition;
170 }
171
172 /**
173 * Fixes parameters indexed by the parameter name -> reindex by position.
174 *
175 * This is necessary so that merging definitions between sources is possible.
176 *
177 * @throws InvalidDefinition
178 */
179 private function fixParameters(ObjectDefinition $definition, string $method, array $parameters) : array
180 {
181 $fixedParameters = [];
182
183 foreach ($parameters as $index => $parameter) {
184 // Parameter indexed by the parameter name, we reindex it with its position
185 if (is_string($index)) {
186 $callable = [$definition->getClassName(), $method];
187
188 try {
189 $reflectionParameter = new \ReflectionParameter($callable, $index);
190 } catch (\ReflectionException $e) {
191 throw InvalidDefinition::create($definition, sprintf("Parameter with name '%s' could not be found. %s.", $index, $e->getMessage()));
192 }
193
194 $index = $reflectionParameter->getPosition();
195 }
196
197 $fixedParameters[$index] = $parameter;
198 }
199
200 return $fixedParameters;
201 }
202 }
203