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

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