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

317 lines 8.2 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 }
43
44 if ($facade) {
45 $this->facade($key, $facade);
46 }
47
48 if ($alias) {
49 $this->alias($key, $alias);
50 }
51 }
52
53 /**
54 * Bind a singleton instance into service container
55 * @param string $key identifier
56 * @param mixed $concrete
57 * @param string $facade [optional facade]
58 * @param string $alias [optional alias]
59 * @return void
60 */
61 public function bindSingleton($key, $concrete = null, $facade = null, $alias = null)
62 {
63 $this->bind($key, $concrete, $facade, $alias, true);
64 }
65
66 /**
67 * Bind a singleton instance into service container
68 * @param string $key identifier
69 * @param mixed $concrete
70 * @param string $facade [optional facade]
71 * @param string $alias [optional alias]
72 * @return void
73 */
74 public function bindInstance($key, $concrete, $facade = null, $alias = null)
75 {
76 $this->bind($key, function($app) use ($concrete) {
77 return $concrete;
78 }, $facade, $alias, true);
79 }
80
81 /**
82 * Register a facade for a registered instance
83 * @param string $key
84 * @param string $facade
85 * @return string
86 */
87 public function facade($key, $facade)
88 {
89 static::$container['facades'][$facade] = $key;
90 }
91
92 /**
93 * Register an alias for a registered instance
94 * @param string $key
95 * @param string $alias
96 * @return string
97 */
98 public function alias($key, $aliases)
99 {
100 foreach ((array) $aliases as $alias) {
101 static::$container['aliases'][$alias] = $key;
102 }
103 }
104
105 /**
106 * Resolve an instance from container
107 * @param string $key
108 * @return mixed
109 * @throws \FluentForm\Framework\Exception\UnResolveableEntityException
110 */
111 public function make($key = null, array $params = [])
112 {
113 if (is_null($key)) {
114 return AppFacade::getApplication();
115 }
116
117 $key = $this->getAlias($key);
118
119 if (isset(static::$container['resolved'][$key])) {
120 return static::$container['resolved'][$key];
121 }
122
123 if (isset(static::$container['singletons'][$key])) {
124 return static::$container['resolved'][$key] = $this->resolve(
125 static::$container['singletons'][$key], $params
126 );
127 }
128
129 if (isset(static::$container['bindings'][$key])) {
130 return $this->resolve(static::$container['bindings'][$key], $params);
131 }
132
133 if ($this->classExists($key)) {
134 return $this->resolve($key, $params);
135 }
136
137 throw new UnResolveableEntityException(
138 'The service ['.$key.'] doesn\'t exist.'
139 );
140 }
141
142 /**
143 * Resolve an item from the container
144 * @param mixed $value
145 * @return mixed
146 */
147 protected function resolve($value, $params = [])
148 {
149 if ($value instanceof Closure) {
150 return $value($this, $params);
151 }
152
153 return $this->build($value, $params);
154 }
155
156 /**
157 * Build a concrete class with all dependencies
158 * @param string $value FQN class name
159 * @return mixed resolved instance
160 */
161 protected function build($value, $params = [])
162 {
163 if (is_object($value)) return $value;
164
165 $reflector = new ReflectionClass($value);
166
167 if (!$reflector->isInstantiable()) {
168 throw new UnResolveableEntityException(
169 "The [$value] is not instantiable."
170 );
171 }
172
173 if (!$constructor = $reflector->getConstructor()) {
174 return new $value;
175 }
176
177 $dependencies = $params ? $params : $this->resolveDependencies(
178 $constructor->getParameters()
179 );
180
181 return $reflector->newInstanceArgs($dependencies);
182 }
183
184 /**
185 * Resolve all dependencies of a single class
186 * @param array $dependencies Constructor Parameters
187 * @return array An array of all the resolved dependencies of one class
188 */
189 protected function resolveDependencies(array $dependencies)
190 {
191 $results = [];
192 foreach ($dependencies as $dependency) {
193 $results[] = $this->resolveClass($dependency);
194 }
195 return $results;
196 }
197
198 /**
199 * Resolves a single class instance
200 * @param ReflectionParameter $parameter
201 * @return mixed
202 * @throws Exception
203 */
204 protected function resolveClass(ReflectionParameter $parameter)
205 {
206 try {
207 return $this->make($parameter->getClass()->name);
208 }
209 catch (Exception $exception) {
210 if ($parameter->isOptional()) {
211 return $parameter->getDefaultValue();
212 } elseif (!$parameter->getClass()) {
213 $name = $parameter->getName();
214 $cls = $parameter->getDeclaringClass();
215 throw new UnResolveableEntityException(
216 "The [".$cls->name."] is not instantiable, $".$name." is required."
217 );
218 }
219 throw $exception;
220 }
221 }
222
223 /**
224 * Get the alias for a key if available.
225 * @param string $key
226 * @return string
227 */
228 public function getAlias($key)
229 {
230 if (isset(static::$container['aliases'][$key])) {
231 return static::$container['aliases'][$key];
232 }
233
234 return $key;
235 }
236
237 /**
238 * Check if a given class/interface exists
239 * @param string $key
240 * @return bool
241 */
242 protected function classExists($key)
243 {
244 return is_string($key) && (class_exists($key) || interface_exists($key));
245 }
246
247 /**
248 * Check if an item exists at a given offset
249 * @param string $offset
250 * @return bool
251 */
252 public function bound($offset)
253 {
254 return isset(static::$container['resolved'][$offset]) ||
255 isset(static::$container['bindings'][$offset]) ||
256 isset(static::$container['singletons'][$offset]);
257 }
258
259 /**
260 * Check if an item exists at a given offset
261 * @param string $offset
262 * @return bool
263 */
264 public function has($offset)
265 {
266 return $this->bound($offset);
267 }
268
269 /**
270 * Check if an item exists at a given offset
271 * @param string $offset
272 * @return bool
273 */
274 public function offsetExists($offset)
275 {
276 return $this->bound($offset);
277 }
278
279 /**
280 * Get the value from given offset
281 * @param string $offset
282 * @param mixed $value
283 * @return void
284 */
285 public function offsetGet($offset)
286 {
287 return $this->make($offset);
288 }
289
290 /**
291 * Set the value at a given offset
292 * @param string $offset
293 * @param mixed $value
294 * @return void
295 */
296 public function offsetSet($offset, $value)
297 {
298 static::$container['singletons'][$offset] = function() use ($value) {
299 return $value;
300 };
301 }
302
303 /**
304 * Unset the value at a given offset
305 * @param string $offset
306 * @return void
307 */
308 public function offsetUnset($offset)
309 {
310 unset(
311 static::$container['resolved'][$offset],
312 static::$container['bindings'][$offset],
313 static::$container['singletons'][$offset]
314 );
315 }
316 }
317