PluginProbe
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder / 3.6.2
Fluent Forms – Customizable Contact Forms, Survey, Quiz, & Conversational Form Builder v3.6.2
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 3.6.2, at framework/Foundation/Container.php

411 lines 10.4 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 try {
210 if ($class = $parameter->getClass()) {
211 return $this->make($class->name);
212 }
213 throw new Exception("The [".$parameter->name."] is not instantiable.");
214 } catch (Exception $exception) {
215 if ($parameter->isOptional()) {
216 return $parameter->getDefaultValue();
217 } elseif (!$class) {
218 $name = $parameter->getName();
219 $cls = $parameter->getDeclaringClass();
220 throw new UnResolveableEntityException(
221 "The [".$cls->name."] is not instantiable, $".$name." is required."
222 );
223 }
224
225 throw $exception;
226 }
227 }
228
229 /**
230 * Get the alias for a key if available.
231 * @param string $key
232 * @return string
233 */
234 public function getAlias($key)
235 {
236 if (isset(static::$container['aliases'][$key])) {
237 return static::$container['aliases'][$key];
238 }
239
240 return $key;
241 }
242
243 /**
244 * Check if a given class/interface exists
245 * @param string $key
246 * @return bool
247 */
248 protected function classExists($key)
249 {
250 return is_string($key) && (class_exists($key) || interface_exists($key));
251 }
252
253 /**
254 * Check if an item exists at a given offset
255 * @param string $offset
256 * @return bool
257 */
258 public function bound($offset)
259 {
260 return isset(static::$container['resolved'][$offset]) ||
261 isset(static::$container['singletons'][$offset]) ||
262 isset(static::$container['bindings'][$offset]);
263 }
264
265 /**
266 * Check if an item exists at a given offset
267 * @param string $offset
268 * @return bool
269 */
270 public function has($offset)
271 {
272 return $this->bound($offset);
273 }
274
275 /**
276 * Check if an item exists at a given offset
277 * @param string $offset
278 * @return bool
279 */
280 public function offsetExists($offset)
281 {
282 return $this->bound($offset);
283 }
284
285 /**
286 * Get the value from given offset
287 * @param string $offset
288 * @param mixed $value
289 * @return void
290 */
291 public function offsetGet($offset)
292 {
293 return $this->make($offset);
294 }
295
296 /**
297 * Set the value at a given offset
298 * @param string $offset
299 * @param mixed $value
300 * @return void
301 */
302 public function offsetSet($offset, $value)
303 {
304 $this->bindInstance($offset, $value);
305 }
306
307 /**
308 * Unset the value at a given offset
309 * @param string $offset
310 * @return void
311 */
312 public function offsetUnset($offset)
313 {
314 unset(
315 static::$container['bindings'][$offset],
316 static::$container['resolved'][$offset],
317 static::$container['singletons'][$offset]
318 );
319
320 if(array_key_exists($offset, $aliases = array_flip(static::$container['aliases']))) {
321 unset(static::$container['aliases'][$aliases[$offset]]);
322 }
323
324 if(array_key_exists($offset, $facades = array_flip(static::$container['facades']))) {
325 unset(static::$container['facades'][$facades[$offset]]);
326 }
327 }
328
329 /**
330 * Determine whether a shared entity is resolved.
331 * @param string $key
332 * @return bool
333 */
334 public function resolved($key)
335 {
336 return array_key_exists($key, static::$container['resolved']);
337 }
338
339 /**
340 * Get one or all resolved instance(s)
341 * @param string $key
342 * @return mixed
343 */
344 public function getResolved($key = null)
345 {
346 return static::$container['resolved'];
347 }
348
349 /**
350 * Clear one or all resolved instance(s)
351 * @param string $key
352 * @return void
353 */
354 public function clearResolved($key = null)
355 {
356 if (!$key) {
357 static::$container['resolved'] = [];
358 } else {
359 unset(static::$container['resolved'][$key]);
360 }
361 }
362
363 /**
364 * Get one or all binding(s)
365 * @param string $key
366 * @return void
367 */
368 public function getBindings($key = null)
369 {
370 return static::$container['bindings'];
371 }
372
373 /**
374 * Clear one or all binding(s)
375 * @param string $key
376 * @return void
377 */
378 public function clearBindings($key = null)
379 {
380 if (!$key) {
381 static::$container['bindings'] = [];
382 } else {
383 unset(static::$container['bindings'][$key]);
384 }
385 }
386
387 /**
388 * Get one or all singletons(s)
389 * @param string $key
390 * @return void
391 */
392 public function getSingletons($key = null)
393 {
394 return static::$container['singletons'];
395 }
396
397 /**
398 * Clear one or all singletons(s)
399 * @param string $key
400 * @return void
401 */
402 public function clearSingletons($key = null)
403 {
404 if (!$key) {
405 static::$container['singletons'] = [];
406 } else {
407 unset(static::$container['singletons'][$key]);
408 }
409 }
410 }
411