PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 4.3.6
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v4.3.6
6.2.13 6.2.12 6.2.10 6.2.11 6.2.9 6.2.8 6.2.7 6.2.6 6.2.5 6.2.4 6.2.3 6.2.2 3.6.22 3.6.31 3.6.40 3.6.41 3.6.42 3.6.50 3.6.51 3.6.60 3.6.61 3.6.62 3.6.64 3.6.65 3.6.66 All 195 releases
fluentform / framework / Foundation / Container.php

Container.php in Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder 4.3.6, at framework/Foundation/Container.php

443 lines 11.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace FluentForm\Framework\Foundation;
4
5 use Closure;
6 use Exception;
7 use ArrayAccess;
8 use ReflectionClass;
9 use ReflectionParameter;
10 use FluentForm\Framework\Exception\UnResolveableEntityException;
11
12 class Container implements ArrayAccess
13 {
14 /**
15 * $container The service container
16 * @var array
17 */
18 protected static $container = array(
19 'facades' => array(),
20 'aliases' => array(),
21 'resolved' => array(),
22 'bindings' => array(),
23 'singletons' => array(),
24 );
25
26 /**
27 * Bind an instance into service container
28 * @param string $key identifier
29 * @param mixed $concrete
30 * @param string $facade [optional facade]
31 * @param string $alias [optional alias]
32 * @return void
33 */
34 public function bind($key, $concrete = null, $facade = null, $alias = null, $shared = false)
35 {
36 $concrete = is_null($concrete) ? $key : $concrete;
37
38 if (!$shared) {
39 static::$container['bindings'][$key] = $concrete;
40 } else {
41 static::$container['singletons'][$key] = $concrete;
42 if ($this->resolved($key)) {
43 $this->clearResolved($key);
44 }
45 }
46
47 if ($facade) {
48 $this->facade($key, $facade);
49 }
50
51 if ($alias) {
52 $this->alias($key, $alias);
53 }
54 }
55
56 /**
57 * Bind a singleton instance into service container
58 * @param string $key identifier
59 * @param mixed $concrete
60 * @param string $facade [optional facade]
61 * @param string $alias [optional alias]
62 * @return void
63 */
64 public function bindSingleton($key, $concrete = null, $facade = null, $alias = null)
65 {
66 $this->bind($key, $concrete, $facade, $alias, true);
67 }
68
69 /**
70 * Bind a singleton instance into service container
71 * @param string $key identifier
72 * @param mixed $concrete
73 * @param string $facade [optional facade]
74 * @param string $alias [optional alias]
75 * @return void
76 */
77 public function bindInstance($key, $concrete, $facade = null, $alias = null)
78 {
79 $this->bind($key, function () use ($concrete) {
80 return $concrete;
81 }, $facade, $alias, true);
82 }
83
84 /**
85 * Register a facade for a registered instance
86 * @param string $key
87 * @param string $facade
88 * @return string
89 */
90 public function facade($key, $facade)
91 {
92 static::$container['facades'][$facade] = $key;
93 }
94
95 /**
96 * Register an alias for a registered instance
97 * @param string $key
98 * @param string $alias
99 * @return string
100 */
101 public function alias($key, $aliases)
102 {
103 foreach ((array)$aliases as $alias) {
104 static::$container['aliases'][$alias] = $key;
105 }
106 }
107
108 /**
109 * Resolve an instance from container
110 * @param string $key
111 * @return mixed
112 * @throws \FluentForm\Framework\Exception\UnResolveableEntityException
113 */
114 public function make($key = null, array $params = [])
115 {
116 if (is_null($key)) {
117 return AppFacade::getApplication();
118 }
119
120 $key = $this->getAlias($key);
121
122 if (isset(static::$container['resolved'][$key])) {
123 return static::$container['resolved'][$key];
124 }
125
126 if (isset(static::$container['singletons'][$key])) {
127 return static::$container['resolved'][$key] = $this->resolve(
128 static::$container['singletons'][$key], $params
129 );
130 }
131
132 if (isset(static::$container['bindings'][$key])) {
133 return $this->resolve(static::$container['bindings'][$key], $params);
134 }
135
136 if ($this->classExists($key)) {
137 return $this->resolve($key, $params);
138 }
139
140 throw new UnResolveableEntityException('The service [' . $key . '] doesn\'t exist.');
141 }
142
143 /**
144 * Resolve an item from the container
145 * @param mixed $value
146 * @return mixed
147 */
148 protected function resolve($value, $params = [])
149 {
150 if ($value instanceof Closure) {
151 return $value($this, $params);
152 }
153
154 return $this->build($value, $params);
155 }
156
157 /**
158 * Build a concrete class with all dependencies
159 * @param string $value FQN class name
160 * @return mixed resolved instance
161 */
162 protected function build($value, $params = [])
163 {
164 if (is_object($value)) return $value;
165
166 $reflector = new ReflectionClass($value);
167
168 if (!$reflector->isInstantiable()) {
169 throw new UnResolveableEntityException(
170 "The [$value] is not instantiable."
171 );
172 }
173
174 if (!($constructor = $reflector->getConstructor())) {
175 return new $value;
176 }
177
178 $dependencies = $params ? $params : $this->resolveDependencies(
179 $constructor->getParameters()
180 );
181
182 return $reflector->newInstanceArgs($dependencies);
183 }
184
185 /**
186 * Resolve all dependencies of a single class
187 * @param array $dependencies Constructor Parameters
188 * @return array An array of all the resolved dependencies of one class
189 */
190 protected function resolveDependencies(array $dependencies)
191 {
192 $results = [];
193
194 foreach ($dependencies as $dependency) {
195 $results[] = $this->resolveClass($dependency);
196 }
197
198 return $results;
199 }
200
201 /**
202 * Resolves a single class instance
203 * @param ReflectionParameter $parameter
204 * @return mixed
205 * @throws Exception
206 */
207 protected function resolveClass(ReflectionParameter $parameter)
208 {
209 $types = ['bool', 'int', 'float', 'string', 'array', 'resource'];
210
211 try {
212 if ($class = $this->getParameterType($parameter)) {
213
214 $phpVersion = phpversion();
215 if (version_compare($phpVersion, '7', '>=') && version_compare($phpVersion, '7.1', '<')) {
216 if ($class instanceof \ReflectionType) {
217 $class = (string)$class;
218 return $this->make($class);
219 }
220 }
221
222 $class = $class->getName();
223 if ($class && in_array($class, $types)) {
224 $class = null;
225 }
226 }
227
228 if ($class) {
229 return $this->make($class);
230 }
231
232 throw new Exception("The [" . $parameter->name . "] is not instantiable.");
233 } catch (Exception $exception) {
234 if ($parameter->isOptional()) {
235 return $parameter->getDefaultValue();
236 } elseif (!$class) {
237 $name = $parameter->getName();
238 $cls = $parameter->getDeclaringClass();
239 throw new UnResolveableEntityException(
240 "The [" . $cls->name . "] is not instantiable, $" . $name . " is required."
241 );
242 }
243
244 throw $exception;
245 }
246 }
247
248 /**
249 * Get the parameter type for the given parameter.
250 *
251 * @return object ReflectionClass|ReflectionNamedType
252 */
253 protected function getParameterType($parameter)
254 {
255 if (method_exists($parameter, 'getType')) {
256 return $parameter->getType();
257 }
258
259 return $parameter->getClass();
260 }
261
262 /**
263 * Get the alias for a key if available.
264 * @param string $key
265 * @return string
266 */
267 public function getAlias($key)
268 {
269 if (isset(static::$container['aliases'][$key])) {
270 return static::$container['aliases'][$key];
271 }
272
273 return $key;
274 }
275
276 /**
277 * Check if a given class/interface exists
278 * @param string $key
279 * @return bool
280 */
281 protected function classExists($key)
282 {
283 return is_string($key) && (class_exists($key) || interface_exists($key));
284 }
285
286 /**
287 * Check if an item exists at a given offset
288 * @param string $offset
289 * @return bool
290 */
291 public function bound($offset)
292 {
293 return isset(static::$container['resolved'][$offset]) ||
294 isset(static::$container['singletons'][$offset]) ||
295 isset(static::$container['bindings'][$offset]);
296 }
297
298 /**
299 * Check if an item exists at a given offset
300 * @param string $offset
301 * @return bool
302 */
303 public function has($offset)
304 {
305 return $this->bound($offset);
306 }
307
308 /**
309 * Check if an item exists at a given offset
310 * @param string $offset
311 * @return bool
312 */
313 public function offsetExists($offset)
314 {
315 return $this->bound($offset);
316 }
317
318 /**
319 * Get the value from given offset
320 * @param string $offset
321 * @param mixed $value
322 * @return void
323 */
324 public function offsetGet($offset)
325 {
326 return $this->make($offset);
327 }
328
329 /**
330 * Set the value at a given offset
331 * @param string $offset
332 * @param mixed $value
333 * @return void
334 */
335 public function offsetSet($offset, $value)
336 {
337 $this->bindInstance($offset, $value);
338 }
339
340 /**
341 * Unset the value at a given offset
342 * @param string $offset
343 * @return void
344 */
345 public function offsetUnset($offset)
346 {
347 unset(
348 static::$container['bindings'][$offset],
349 static::$container['resolved'][$offset],
350 static::$container['singletons'][$offset]
351 );
352
353 if (array_key_exists($offset, $aliases = array_flip(static::$container['aliases']))) {
354 unset(static::$container['aliases'][$aliases[$offset]]);
355 }
356
357 if (array_key_exists($offset, $facades = array_flip(static::$container['facades']))) {
358 unset(static::$container['facades'][$facades[$offset]]);
359 }
360 }
361
362 /**
363 * Determine whether a shared entity is resolved.
364 * @param string $key
365 * @return bool
366 */
367 public function resolved($key)
368 {
369 return array_key_exists($key, static::$container['resolved']);
370 }
371
372 /**
373 * Get one or all resolved instance(s)
374 * @param string $key
375 * @return mixed
376 */
377 public function getResolved($key = null)
378 {
379 return static::$container['resolved'];
380 }
381
382 /**
383 * Clear one or all resolved instance(s)
384 * @param string $key
385 * @return void
386 */
387 public function clearResolved($key = null)
388 {
389 if (!$key) {
390 static::$container['resolved'] = [];
391 } else {
392 unset(static::$container['resolved'][$key]);
393 }
394 }
395
396 /**
397 * Get one or all binding(s)
398 * @param string $key
399 * @return void
400 */
401 public function getBindings($key = null)
402 {
403 return static::$container['bindings'];
404 }
405
406 /**
407 * Clear one or all binding(s)
408 * @param string $key
409 * @return void
410 */
411 public function clearBindings($key = null)
412 {
413 if (!$key) {
414 static::$container['bindings'] = [];
415 } else {
416 unset(static::$container['bindings'][$key]);
417 }
418 }
419
420 /**
421 * Get one or all singletons(s)
422 * @param string $key
423 * @return void
424 */
425 public function getSingletons($key = null)
426 {
427 return static::$container['singletons'];
428 }
429
430 /**
431 * Clear one or all singletons(s)
432 * @param string $key
433 * @return void
434 */
435 public function clearSingletons($key = null)
436 {
437 if (!$key) {
438 static::$container['singletons'] = [];
439 } else {
440 unset(static::$container['singletons'][$key]);
441 }
442 }
443 }