OwlCyberSecurity - MANAGER
Edit File: Container.php
<?php namespace FluentForm\Framework\Foundation; use Closure; use Exception; use ArrayAccess; use ReflectionClass; use ReflectionParameter; use FluentForm\Framework\Exception\UnResolveableEntityException; class Container implements ArrayAccess { /** * $container The service container * @var array */ protected static $container = array( 'facades' => array(), 'aliases' => array(), 'resolved' => array(), 'bindings' => array(), 'singletons' => array(), ); /** * Bind an instance into service container * @param string $key identifier * @param mixed $concrete * @param string $facade [optional facade] * @param string $alias [optional alias] * @return void */ public function bind($key, $concrete = null, $facade = null, $alias = null, $shared = false) { $concrete = is_null($concrete) ? $key : $concrete; if (!$shared) { static::$container['bindings'][$key] = $concrete; } else { static::$container['singletons'][$key] = $concrete; if ($this->resolved($key)) { $this->clearResolved($key); } } if ($facade) { $this->facade($key, $facade); } if ($alias) { $this->alias($key, $alias); } } /** * Bind a singleton instance into service container * @param string $key identifier * @param mixed $concrete * @param string $facade [optional facade] * @param string $alias [optional alias] * @return void */ public function bindSingleton($key, $concrete = null, $facade = null, $alias = null) { $this->bind($key, $concrete, $facade, $alias, true); } /** * Bind a singleton instance into service container * @param string $key identifier * @param mixed $concrete * @param string $facade [optional facade] * @param string $alias [optional alias] * @return void */ public function bindInstance($key, $concrete, $facade = null, $alias = null) { $this->bind($key, function () use ($concrete) { return $concrete; }, $facade, $alias, true); } /** * Register a facade for a registered instance * @param string $key * @param string $facade * @return string */ public function facade($key, $facade) { static::$container['facades'][$facade] = $key; } /** * Register an alias for a registered instance * @param string $key * @param string $alias * @return string */ public function alias($key, $aliases) { foreach ((array)$aliases as $alias) { static::$container['aliases'][$alias] = $key; } } /** * Resolve an instance from container * @param string $key * @return mixed * @throws \FluentForm\Framework\Exception\UnResolveableEntityException */ public function make($key = null, array $params = []) { if (is_null($key)) { return AppFacade::getApplication(); } $key = $this->getAlias($key); if (isset(static::$container['resolved'][$key])) { return static::$container['resolved'][$key]; } if (isset(static::$container['singletons'][$key])) { return static::$container['resolved'][$key] = $this->resolve( static::$container['singletons'][$key], $params ); } if (isset(static::$container['bindings'][$key])) { return $this->resolve(static::$container['bindings'][$key], $params); } if ($this->classExists($key)) { return $this->resolve($key, $params); } throw new UnResolveableEntityException('The service [' . $key . '] doesn\'t exist.'); } /** * Resolve an item from the container * @param mixed $value * @return mixed */ protected function resolve($value, $params = []) { if ($value instanceof Closure) { return $value($this, $params); } return $this->build($value, $params); } /** * Build a concrete class with all dependencies * @param string $value FQN class name * @return mixed resolved instance */ protected function build($value, $params = []) { if (is_object($value)) return $value; $reflector = new ReflectionClass($value); if (!$reflector->isInstantiable()) { throw new UnResolveableEntityException( "The [$value] is not instantiable." ); } if (!($constructor = $reflector->getConstructor())) { return new $value; } $dependencies = $params ? $params : $this->resolveDependencies( $constructor->getParameters() ); return $reflector->newInstanceArgs($dependencies); } /** * Resolve all dependencies of a single class * @param array $dependencies Constructor Parameters * @return array An array of all the resolved dependencies of one class */ protected function resolveDependencies(array $dependencies) { $results = []; foreach ($dependencies as $dependency) { $results[] = $this->resolveClass($dependency); } return $results; } /** * Resolves a single class instance * @param ReflectionParameter $parameter * @return mixed * @throws Exception */ protected function resolveClass(ReflectionParameter $parameter) { $types = ['bool', 'int', 'float', 'string', 'array', 'resource']; try { if ($class = $this->getParameterType($parameter)) { $phpVersion = phpversion(); if (version_compare($phpVersion, '7', '>=') && version_compare($phpVersion, '7.1', '<')) { if ($class instanceof \ReflectionType) { $class = (string)$class; return $this->make($class); } } $class = $class->getName(); if ($class && in_array($class, $types)) { $class = null; } } if ($class) { return $this->make($class); } throw new Exception("The [" . $parameter->name . "] is not instantiable."); } catch (Exception $exception) { if ($parameter->isOptional()) { return $parameter->getDefaultValue(); } elseif (!$class) { $name = $parameter->getName(); $cls = $parameter->getDeclaringClass(); throw new UnResolveableEntityException( "The [" . $cls->name . "] is not instantiable, $" . $name . " is required." ); } throw $exception; } } /** * Get the parameter type for the given parameter. * * @return object ReflectionClass|ReflectionNamedType */ protected function getParameterType($parameter) { if (method_exists($parameter, 'getType')) { return $parameter->getType(); } return $parameter->getClass(); } /** * Get the alias for a key if available. * @param string $key * @return string */ public function getAlias($key) { if (isset(static::$container['aliases'][$key])) { return static::$container['aliases'][$key]; } return $key; } /** * Check if a given class/interface exists * @param string $key * @return bool */ protected function classExists($key) { return is_string($key) && (class_exists($key) || interface_exists($key)); } /** * Check if an item exists at a given offset * @param string $offset * @return bool */ public function bound($offset) { return isset(static::$container['resolved'][$offset]) || isset(static::$container['singletons'][$offset]) || isset(static::$container['bindings'][$offset]); } /** * Check if an item exists at a given offset * @param string $offset * @return bool */ public function has($offset) { return $this->bound($offset); } /** * Check if an item exists at a given offset * @param string $offset * @return bool */ #[\ReturnTypeWillChange] public function offsetExists($offset) { return $this->bound($offset); } /** * Get the value from given offset * @param string $offset * @param mixed $value * @return void */ #[\ReturnTypeWillChange] public function offsetGet($offset) { return $this->make($offset); } /** * Set the value at a given offset * @param string $offset * @param mixed $value * @return void */ #[\ReturnTypeWillChange] public function offsetSet($offset, $value) { $this->bindInstance($offset, $value); } /** * Unset the value at a given offset * @param string $offset * @return void */ #[\ReturnTypeWillChange] public function offsetUnset($offset) { unset( static::$container['bindings'][$offset], static::$container['resolved'][$offset], static::$container['singletons'][$offset] ); if (array_key_exists($offset, $aliases = array_flip(static::$container['aliases']))) { unset(static::$container['aliases'][$aliases[$offset]]); } if (array_key_exists($offset, $facades = array_flip(static::$container['facades']))) { unset(static::$container['facades'][$facades[$offset]]); } } /** * Determine whether a shared entity is resolved. * @param string $key * @return bool */ public function resolved($key) { return array_key_exists($key, static::$container['resolved']); } /** * Get one or all resolved instance(s) * @param string $key * @return mixed */ public function getResolved($key = null) { return static::$container['resolved']; } /** * Clear one or all resolved instance(s) * @param string $key * @return void */ public function clearResolved($key = null) { if (!$key) { static::$container['resolved'] = []; } else { unset(static::$container['resolved'][$key]); } } /** * Get one or all binding(s) * @param string $key * @return void */ public function getBindings($key = null) { return static::$container['bindings']; } /** * Clear one or all binding(s) * @param string $key * @return void */ public function clearBindings($key = null) { if (!$key) { static::$container['bindings'] = []; } else { unset(static::$container['bindings'][$key]); } } /** * Get one or all singletons(s) * @param string $key * @return void */ public function getSingletons($key = null) { return static::$container['singletons']; } /** * Clear one or all singletons(s) * @param string $key * @return void */ public function clearSingletons($key = null) { if (!$key) { static::$container['singletons'] = []; } else { unset(static::$container['singletons'][$key]); } } }