PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 3.4.2
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v3.4.2
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Dependencies / DI / Definition / Helper / CreateDefinitionHelper.php

CreateDefinitionHelper.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 3.4.2, at includes/Dependencies/DI/Definition/Helper/CreateDefinitionHelper.php

203 lines 5.7 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 WPDeveloper\BetterDocs\Dependencies\DI\Definition\Helper;
6
7 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\Definition;
8 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\Exception\InvalidDefinition;
9 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\ObjectDefinition;
10 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\ObjectDefinition\MethodInjection;
11 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\ObjectDefinition\PropertyInjection;
12
13 /**
14 * Helps defining how to create an instance of a class.
15 *
16 * @author Matthieu Napoli <matthieu@mnapoli.fr>
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 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 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