PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.8.0
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.8.0
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 / ObjectDefinition.php

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

247 lines 6.1 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;
6
7 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\Dumper\ObjectDefinitionDumper;
8 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\ObjectDefinition\MethodInjection;
9 use WPDeveloper\BetterDocs\Dependencies\DI\Definition\ObjectDefinition\PropertyInjection;
10 use ReflectionClass;
11
12 /**
13 * Defines how an object can be instantiated.
14 *
15 * @author Matthieu Napoli <matthieu@mnapoli.fr>
16 */
17 class ObjectDefinition implements Definition
18 {
19 /**
20 * Entry name (most of the time, same as $classname).
21 * @var string
22 */
23 private $name;
24
25 /**
26 * Class name (if null, then the class name is $name).
27 * @var string|null
28 */
29 protected $className;
30
31 /**
32 * Constructor parameter injection.
33 * @var MethodInjection|null
34 */
35 protected $constructorInjection;
36
37 /**
38 * Property injections.
39 * @var PropertyInjection[]
40 */
41 protected $propertyInjections = [];
42
43 /**
44 * Method calls.
45 * @var MethodInjection[][]
46 */
47 protected $methodInjections = [];
48
49 /**
50 * @var bool|null
51 */
52 protected $lazy;
53
54 /**
55 * Store if the class exists. Storing it (in cache) avoids recomputing this.
56 *
57 * @var bool
58 */
59 private $classExists;
60
61 /**
62 * Store if the class is instantiable. Storing it (in cache) avoids recomputing this.
63 *
64 * @var bool
65 */
66 private $isInstantiable;
67
68 /**
69 * @param string $name Entry name
70 */
71 public function __construct(string $name, ?string $className = null)
72 {
73 $this->name = $name;
74 $this->setClassName($className);
75 }
76
77 public function getName() : string
78 {
79 return $this->name;
80 }
81
82 public function setName(string $name)
83 {
84 $this->name = $name;
85 }
86
87 public function setClassName(?string $className = null)
88 {
89 $this->className = $className;
90
91 $this->updateCache();
92 }
93
94 public function getClassName() : string
95 {
96 if ($this->className !== null) {
97 return $this->className;
98 }
99
100 return $this->name;
101 }
102
103 /**
104 * @return MethodInjection|null
105 */
106 public function getConstructorInjection()
107 {
108 return $this->constructorInjection;
109 }
110
111 public function setConstructorInjection(MethodInjection $constructorInjection)
112 {
113 $this->constructorInjection = $constructorInjection;
114 }
115
116 public function completeConstructorInjection(MethodInjection $injection)
117 {
118 if ($this->constructorInjection !== null) {
119 // Merge
120 $this->constructorInjection->merge($injection);
121 } else {
122 // Set
123 $this->constructorInjection = $injection;
124 }
125 }
126
127 /**
128 * @return PropertyInjection[] Property injections
129 */
130 public function getPropertyInjections() : array
131 {
132 return $this->propertyInjections;
133 }
134
135 public function addPropertyInjection(PropertyInjection $propertyInjection)
136 {
137 $className = $propertyInjection->getClassName();
138 if ($className) {
139 // Index with the class name to avoid collisions between parent and
140 // child private properties with the same name
141 $key = $className . '::' . $propertyInjection->getPropertyName();
142 } else {
143 $key = $propertyInjection->getPropertyName();
144 }
145
146 $this->propertyInjections[$key] = $propertyInjection;
147 }
148
149 /**
150 * @return MethodInjection[] Method injections
151 */
152 public function getMethodInjections() : array
153 {
154 // Return array leafs
155 $injections = [];
156 array_walk_recursive($this->methodInjections, function ($injection) use (&$injections) {
157 $injections[] = $injection;
158 });
159
160 return $injections;
161 }
162
163 public function addMethodInjection(MethodInjection $methodInjection)
164 {
165 $method = $methodInjection->getMethodName();
166 if (! isset($this->methodInjections[$method])) {
167 $this->methodInjections[$method] = [];
168 }
169 $this->methodInjections[$method][] = $methodInjection;
170 }
171
172 public function completeFirstMethodInjection(MethodInjection $injection)
173 {
174 $method = $injection->getMethodName();
175
176 if (isset($this->methodInjections[$method][0])) {
177 // Merge
178 $this->methodInjections[$method][0]->merge($injection);
179 } else {
180 // Set
181 $this->addMethodInjection($injection);
182 }
183 }
184
185 public function setLazy(?bool $lazy = null)
186 {
187 $this->lazy = $lazy;
188 }
189
190 public function isLazy() : bool
191 {
192 if ($this->lazy !== null) {
193 return $this->lazy;
194 }
195 // Default value
196 return false;
197 }
198
199 public function classExists() : bool
200 {
201 return $this->classExists;
202 }
203
204 public function isInstantiable() : bool
205 {
206 return $this->isInstantiable;
207 }
208
209 public function replaceNestedDefinitions(callable $replacer)
210 {
211 array_walk($this->propertyInjections, function (PropertyInjection $propertyInjection) use ($replacer) {
212 $propertyInjection->replaceNestedDefinition($replacer);
213 });
214
215 if ($this->constructorInjection) {
216 $this->constructorInjection->replaceNestedDefinitions($replacer);
217 }
218
219 array_walk($this->methodInjections, function ($injectionArray) use ($replacer) {
220 array_walk($injectionArray, function (MethodInjection $methodInjection) use ($replacer) {
221 $methodInjection->replaceNestedDefinitions($replacer);
222 });
223 });
224 }
225
226 public function __toString()
227 {
228 return (new ObjectDefinitionDumper)->dump($this);
229 }
230
231 private function updateCache()
232 {
233 $className = $this->getClassName();
234
235 $this->classExists = class_exists($className) || interface_exists($className);
236
237 if (! $this->classExists) {
238 $this->isInstantiable = false;
239
240 return;
241 }
242
243 $class = new ReflectionClass($className);
244 $this->isInstantiable = $class->isInstantiable();
245 }
246 }
247