Sindbad~EG File Manager
<?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]);
}
}
}
Sindbad File Manager Version 1.0, Coded By Sindbad EG ~ The Terrorists