This commit is contained in:
2024-05-20 15:37:46 +03:00
commit 00b7dbd0b7
10404 changed files with 3285853 additions and 0 deletions

View File

@ -0,0 +1,102 @@
<?php
/* @description Dice - A minimal Dependency Injection Container for PHP *
* @author Tom Butler tom@r.je *
* @copyright 2012-2015 Tom Butler <tom@r.je> | http://r.je/dice.html *
* @license http://www.opensource.org/licenses/bsd-license.php BSD License *
* @version 2.0 */
namespace Dice;
class Dice {
private $rules = [];
private $cache = [];
private $instances = [];
public function addRule($name, array $rule) {
$this->rules[ltrim(strtolower($name), '\\')] = array_merge($this->getRule($name), $rule);
}
public function getRule($name) {
$lcName = strtolower(ltrim($name, '\\'));
if (isset($this->rules[$lcName])) return $this->rules[$lcName];
foreach ($this->rules as $key => $rule) {
if (empty($rule['instanceOf']) && $key !== '*' && is_subclass_of($name, $key) && (!array_key_exists('inherit', $rule) || $rule['inherit'] === true )) return $rule;
}
return isset($this->rules['*']) ? $this->rules['*'] : [];
}
public function create($name, array $args = [], array $share = []) {
if (!empty($this->instances[$name])) return $this->instances[$name];
if (empty($this->cache[$name])) $this->cache[$name] = $this->getClosure($name, $this->getRule($name));
return $this->cache[$name]($args, $share);
}
private function getClosure($name, array $rule) {
$class = new \ReflectionClass(isset($rule['instanceOf']) ? $rule['instanceOf'] : $name);
$constructor = $class->getConstructor();
$params = $constructor ? $this->getParams($constructor, $rule) : null;
if (isset($rule['shared']) && $rule['shared'] === true ) $closure = function (array $args, array $share) use ($class, $name, $constructor, $params) {
try {
$this->instances[$name] = $this->instances[ltrim($name, '\\')] = $class->newInstanceWithoutConstructor();
}
catch (\ReflectionException $e) {
$this->instances[$name] = $this->instances[ltrim($name, '\\')] = $class->newInstanceArgs($params($args, $share));
}
if ($constructor) $constructor->invokeArgs($this->instances[$name], $params($args, $share));
return $this->instances[$name];
};
else if ($params) $closure = function (array $args, array $share) use ($class, $params) { return $class->newInstanceArgs($params($args, $share)); };
else $closure = function () use ($class) { return new $class->name; };
return isset($rule['call']) ? function (array $args, array $share) use ($closure, $class, $rule) {
$object = $closure($args, $share);
foreach ($rule['call'] as $call) call_user_func_array([$object, $call[0]] , $this->getParams($class->getMethod($call[0]), $rule)->__invoke($this->expand($call[1])));
return $object;
} : $closure;
}
/** looks for 'instance' array keys in $param and when found returns an object based on the value see https://r.je/dice.html#example3-1 */
private function expand($param, array $share = [], $createFromString = false) {
if (is_array($param) && isset($param['instance'])) {
if (is_callable($param['instance'])) return call_user_func_array($param['instance'], (isset($param['params']) ? $this->expand($param['params']) : []));
else return $this->create($param['instance'], $share);
}
else if (is_array($param)) foreach ($param as &$value) $value = $this->expand($value, $share);
return is_string($param) && $createFromString ? $this->create($param) : $param;
}
private function getParams(\ReflectionMethod $method, array $rule) {
$paramInfo = [];
foreach ($method->getParameters() as $param) {
if(method_exists($param, 'getType')) {
//php 8 onwards
$type = $param->getType();
$class = $type instanceof \ReflectionNamedType && !$type->isBuiltIn() ? $type->getName() : null;
} else {
$class = $param->getClass() ? $param->getClass()->name : null;
}
$paramInfo[] = [$class, $param, isset($rule['substitutions']) && array_key_exists($class, $rule['substitutions'])];
}
return function (array $args, array $share = []) use ($paramInfo, $rule) {
if (isset($rule['shareInstances'])) $share = array_merge($share, array_map([$this, 'create'], $rule['shareInstances']));
if ($share || isset($rule['constructParams'])) $args = array_merge($args, isset($rule['constructParams']) ? $this->expand($rule['constructParams'], $share) : [], $share);
$parameters = [];
foreach ($paramInfo as $p) {
list($class, $param, $sub) = $p;
if ($args) foreach ($args as $i => $arg) {
if ($class && ($arg instanceof $class || ($arg === null && $param->allowsNull()))) {
$parameters[] = array_splice($args, $i, 1)[0];
continue 2;
}
}
if ($class) $parameters[] = $sub ? $this->expand($rule['substitutions'][$class], $share, true) : $this->create($class, [], $share);
else if ($args) $parameters[] = $this->expand(array_shift($args));
else $parameters[] = $param->isDefaultValueAvailable() ? $param->getDefaultValue() : null;
}
return $parameters;
};
}
}

View File

@ -0,0 +1,21 @@
<?php
/* @description Dice - A minimal Dependency Injection Container for PHP *
* @author Tom Butler tom@r.je *
* @copyright 2012-2015 Tom Butler <tom@r.je> | http://r.je/dice.html *
* @license http://www.opensource.org/licenses/bsd-license.php BSD License *
* @version 1.3.2 */
namespace Dice\Loader;
class Json {
public function load($json, \Dice\Dice $dice = null) {
if ($dice === null) $dice = new \Dice\Dice;
$map = json_decode($json, true);
if (!is_array($map)) throw new \Exception('Could not decode json: ' . json_last_error_msg());
foreach ($map['rules'] as $rule) {
$name = $rule['name'];
unset($rule['name']);
$dice->addRule($name, $rule);
}
return $dice;
}
}

View File

@ -0,0 +1,72 @@
<?php
/* @description Dice - A minimal Dependency Injection Container for PHP
* @author Tom Butler tom@r.je
* @copyright 2012-2014 Tom Butler <tom@r.je>
* @link http://r.je/dice.html
* @license http://www.opensource.org/licenses/bsd-license.php BSD License
* @version 2.0
*/
namespace Dice\Loader;
class Xml {
private function getComponent(\SimpleXmlElement $element, $forceInstance = false) {
if ($forceInstance) return ['instance' => (string) $element];
else if ($element->instance) return ['instance' => (string) $element->instance];
else return (string) $element;
}
private function loadV1(\SimpleXmlElement $xml, \Dice\Dice $dice) {
foreach ($xml as $key => $value) {
$rule = $dice->getRule((string) $value->name);
if (isset($value->shared)) $rule['shared'] = ((string) $value->shared === 'true');
if (isset($value->inherit)) $rule['inherit'] = ($value->inherit == 'false') ? false : true;
if ($value->call) {
foreach ($value->call as $name => $call) {
$callArgs = [];
if ($call->params) foreach ($call->params->children() as $key => $param) $callArgs[] = $this->getComponent($param);
$rule['call'][] = [(string) $call->method, $callArgs];
}
}
if ($value->instanceOf) $rule['instanceOf'] = (string) $value->instanceOf;
if ($value->newInstances) foreach ($value->newInstances as $ni) $rule['newInstances'][] = (string) $ni;
if ($value->substitutions) foreach ($value->substitutions as $use) $rule['substitutions'][(string) $use->as] = $this->getComponent($use->use, true);
if ($value->constructParams) foreach ($value->constructParams->children() as $child) $rule['constructParams'][] = $this->getComponent($child);
if ($value->shareInstances) foreach ($value->shareInstances as $share) $rule['shareInstances'][] = $this->getComponent($share);
$dice->addRule((string) $value->name, $rule);
}
}
private function loadV2(\SimpleXmlElement $xml, \Dice\Dice $dice) {
foreach ($xml as $key => $value) {
$rule = $dice->getRule((string) $value->name);
if ($value->call) {
foreach ($value->call as $name => $call) {
$callArgs = [];
foreach ($call->children() as $key => $param) $callArgs[] = $this->getComponent($param);
$rule['call'][] = [(string) $call['method'], $callArgs];
}
}
if (isset($value['inherit'])) $rule['inherit'] = ($value['inherit'] == 'false') ? false : true;
if ($value['instanceOf']) $rule['instanceOf'] = (string) $value['instanceOf'];
if (isset($value['shared'])) $rule['shared'] = ((string) $value['shared'] === 'true');
if ($value->constructParams) foreach ($value->constructParams->children() as $child) $rule['constructParams'][] = $this->getComponent($child);
if ($value->substitute) foreach ($value->substitute as $use) $rule['substitutions'][(string) $use['as']] = $this->getComponent($use['use'], true);
if ($value->shareInstances) foreach ($value->shareInstances->children() as $share) $rule['shareInstances'][] = $this->getComponent($share);
$dice->addRule((string) $value['name'], $rule);
}
}
public function load($xml, \Dice\Dice $dice = null) {
if ($dice === null) $dice = new \Dice\Dice;
if (!($xml instanceof \SimpleXmlElement)) $xml = simplexml_load_file($xml);
$ns = $xml->getNamespaces();
$nsName = (isset($ns[''])) ? $ns[''] : '';
if ($nsName == 'https://r.je/dice/2.0') $this->loadV2($xml, $dice);
else $this->loadV1($xml, $dice);
}
}

View File

@ -0,0 +1,21 @@
{
"name": "level-2/dice",
"description": "A minimalist Dependency injection container (DIC) for PHP. Please note: This branch is only compatible with PHP5.6. 5.5, 5.4 and 5.3 compatible version is available as a separate branch on github. ",
"license": "BSD-2-Clause",
"homepage": "http://r.je/dice.html",
"keywords": ["Dependency injection", "ioc", "Dependency injection container", "DI"],
"authors": [
{
"name": "Tom Butler",
"email": "tom@r.je"
}
],
"require": {
"php": ">=5.4.0"
},
"autoload": {
"psr-4": {
"Dice\\": "./"
}
}
}