2023-03-11 12:04:29 +03:00
|
|
|
<?php
|
|
|
|
/**
|
|
|
|
* Zend Framework (http://framework.zend.com/)
|
|
|
|
*
|
|
|
|
* @link http://github.com/zendframework/zf2 for the canonical source repository
|
2023-04-01 09:03:34 +03:00
|
|
|
* @copyright Copyright (c) 2005-2015 Zend Technologies USA Inc. (http://www.zend.com)
|
2023-03-11 12:04:29 +03:00
|
|
|
* @license http://framework.zend.com/license/new-bsd New BSD License
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace Zend\Di;
|
|
|
|
|
|
|
|
use SplDoublyLinkedList;
|
2023-04-01 09:03:34 +03:00
|
|
|
use Zend\Di\Definition\RuntimeDefinition;
|
2023-03-11 12:04:29 +03:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Class definition based on multiple definitions
|
|
|
|
*/
|
|
|
|
class DefinitionList extends SplDoublyLinkedList implements Definition\DefinitionInterface
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
protected $classes = array();
|
|
|
|
protected $runtimeDefinitions;
|
|
|
|
|
2023-03-11 12:04:29 +03:00
|
|
|
/**
|
|
|
|
* @param Definition\DefinitionInterface|Definition\DefinitionInterface[] $definitions
|
|
|
|
*/
|
|
|
|
public function __construct($definitions)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
$this->runtimeDefinitions = new SplDoublyLinkedList();
|
2023-03-11 12:04:29 +03:00
|
|
|
if (!is_array($definitions)) {
|
|
|
|
$definitions = array($definitions);
|
|
|
|
}
|
|
|
|
foreach ($definitions as $definition) {
|
2023-04-01 09:03:34 +03:00
|
|
|
$this->addDefinition($definition, true);
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Add definitions
|
|
|
|
*
|
|
|
|
* @param Definition\DefinitionInterface $definition
|
|
|
|
* @param bool $addToBackOfList
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function addDefinition(Definition\DefinitionInterface $definition, $addToBackOfList = true)
|
|
|
|
{
|
|
|
|
if ($addToBackOfList) {
|
|
|
|
$this->push($definition);
|
|
|
|
} else {
|
|
|
|
$this->unshift($definition);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-04-01 09:03:34 +03:00
|
|
|
protected function getDefinitionClassMap(Definition\DefinitionInterface $definition)
|
|
|
|
{
|
|
|
|
$definitionClasses = $definition->getClasses();
|
|
|
|
if (empty($definitionClasses)) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
return array_combine(array_values($definitionClasses), array_fill(0, count($definitionClasses), $definition));
|
|
|
|
}
|
|
|
|
|
|
|
|
public function unshift($definition)
|
|
|
|
{
|
|
|
|
$result = parent::unshift($definition);
|
|
|
|
if ($definition instanceof RuntimeDefinition) {
|
|
|
|
$this->runtimeDefinitions->unshift($definition);
|
|
|
|
}
|
|
|
|
$this->classes = array_merge($this->classes, $this->getDefinitionClassMap($definition));
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function push($definition)
|
|
|
|
{
|
|
|
|
$result = parent::push($definition);
|
|
|
|
if ($definition instanceof RuntimeDefinition) {
|
|
|
|
$this->runtimeDefinitions->push($definition);
|
|
|
|
}
|
|
|
|
$this->classes = array_merge($this->getDefinitionClassMap($definition), $this->classes);
|
|
|
|
return $result;
|
|
|
|
}
|
|
|
|
|
2023-03-11 12:04:29 +03:00
|
|
|
/**
|
|
|
|
* @param string $type
|
|
|
|
* @return Definition\DefinitionInterface[]
|
|
|
|
*/
|
|
|
|
public function getDefinitionsByType($type)
|
|
|
|
{
|
|
|
|
$definitions = array();
|
|
|
|
foreach ($this as $definition) {
|
|
|
|
if ($definition instanceof $type) {
|
|
|
|
$definitions[] = $definition;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $definitions;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Get definition by type
|
|
|
|
*
|
|
|
|
* @param string $type
|
|
|
|
* @return Definition\DefinitionInterface
|
|
|
|
*/
|
|
|
|
public function getDefinitionByType($type)
|
|
|
|
{
|
|
|
|
foreach ($this as $definition) {
|
|
|
|
if ($definition instanceof $type) {
|
|
|
|
return $definition;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $class
|
|
|
|
* @return bool|Definition\DefinitionInterface
|
|
|
|
*/
|
|
|
|
public function getDefinitionForClass($class)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (array_key_exists($class, $this->classes)) {
|
|
|
|
return $this->classes[$class];
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
2023-04-01 09:03:34 +03:00
|
|
|
foreach ($this->runtimeDefinitions as $definition) {
|
2023-03-11 12:04:29 +03:00
|
|
|
if ($definition->hasClass($class)) {
|
|
|
|
return $definition;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $class
|
|
|
|
* @return bool|Definition\DefinitionInterface
|
|
|
|
*/
|
|
|
|
public function forClass($class)
|
|
|
|
{
|
|
|
|
return $this->getDefinitionForClass($class);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function getClasses()
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
return array_keys($this->classes);
|
2023-03-11 12:04:29 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function hasClass($class)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (array_key_exists($class, $this->classes)) {
|
|
|
|
return true;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
2023-04-01 09:03:34 +03:00
|
|
|
foreach ($this->runtimeDefinitions as $definition) {
|
2023-03-11 12:04:29 +03:00
|
|
|
if ($definition->hasClass($class)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function getClassSupertypes($class)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (false === ($classDefinition = $this->getDefinitionForClass($class))) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
$supertypes = $classDefinition->getClassSupertypes($class);
|
|
|
|
if (! $classDefinition instanceof Definition\PartialMarker) {
|
|
|
|
return $supertypes;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
|
|
|
foreach ($this as $definition) {
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($definition === $classDefinition) {
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
if ($definition->hasClass($class)) {
|
|
|
|
$supertypes = array_merge($supertypes, $definition->getClassSupertypes($class));
|
|
|
|
if ($definition instanceof Definition\PartialMarker) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $supertypes;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return $supertypes;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function getInstantiator($class)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (! $classDefinition = $this->getDefinitionForClass($class)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
$value = $classDefinition->getInstantiator($class);
|
|
|
|
if (!is_null($value)) {
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
if (! $classDefinition instanceof Definition\PartialMarker) {
|
|
|
|
return false;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
|
|
|
foreach ($this as $definition) {
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($definition === $classDefinition) {
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
if ($definition->hasClass($class)) {
|
|
|
|
$value = $definition->getInstantiator($class);
|
|
|
|
if ($value === null && $definition instanceof Definition\PartialMarker) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function hasMethods($class)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (! $classDefinition = $this->getDefinitionForClass($class)) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (false !== ($methods = $classDefinition->hasMethods($class))) {
|
|
|
|
return $methods;
|
|
|
|
}
|
|
|
|
if (! $classDefinition instanceof Definition\PartialMarker) {
|
|
|
|
return false;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
|
|
|
foreach ($this as $definition) {
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($definition === $classDefinition) {
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
if ($definition->hasClass($class)) {
|
|
|
|
if ($definition->hasMethods($class) === false && $definition instanceof Definition\PartialMarker) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
return $definition->hasMethods($class);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function hasMethod($class, $method)
|
|
|
|
{
|
|
|
|
if (!$this->hasMethods($class)) {
|
|
|
|
return false;
|
|
|
|
}
|
2023-04-01 09:03:34 +03:00
|
|
|
$classDefinition = $this->getDefinitionForClass($class);
|
|
|
|
if ($classDefinition->hasMethod($class, $method)) {
|
|
|
|
return true;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
2023-04-01 09:03:34 +03:00
|
|
|
foreach ($this->runtimeDefinitions as $definition) {
|
|
|
|
if ($definition === $classDefinition) {
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
if ($definition->hasClass($class) && $definition->hasMethod($class, $method)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function getMethods($class)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (false === ($classDefinition = $this->getDefinitionForClass($class))) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
$methods = $classDefinition->getMethods($class);
|
|
|
|
if (! $classDefinition instanceof Definition\PartialMarker) {
|
|
|
|
return $methods;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
|
|
|
foreach ($this as $definition) {
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($definition === $classDefinition) {
|
|
|
|
continue;
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
if ($definition->hasClass($class)) {
|
|
|
|
if (!$definition instanceof Definition\PartialMarker) {
|
|
|
|
return array_merge($definition->getMethods($class), $methods);
|
|
|
|
}
|
|
|
|
|
|
|
|
$methods = array_merge($definition->getMethods($class), $methods);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return $methods;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function hasMethodParameters($class, $method)
|
|
|
|
{
|
|
|
|
$methodParameters = $this->getMethodParameters($class, $method);
|
|
|
|
|
|
|
|
return ($methodParameters !== array());
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* {@inheritDoc}
|
|
|
|
*/
|
|
|
|
public function getMethodParameters($class, $method)
|
|
|
|
{
|
2023-04-01 09:03:34 +03:00
|
|
|
if (false === ($classDefinition = $this->getDefinitionForClass($class))) {
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
if ($classDefinition->hasMethod($class, $method) && $classDefinition->hasMethodParameters($class, $method)) {
|
|
|
|
return $classDefinition->getMethodParameters($class, $method);
|
|
|
|
}
|
2023-03-11 12:04:29 +03:00
|
|
|
/** @var $definition Definition\DefinitionInterface */
|
|
|
|
foreach ($this as $definition) {
|
2023-04-01 09:03:34 +03:00
|
|
|
if ($definition === $classDefinition) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ($definition->hasClass($class)
|
|
|
|
&& $definition->hasMethod($class, $method)
|
|
|
|
&& $definition->hasMethodParameters($class, $method)
|
|
|
|
) {
|
2023-03-11 12:04:29 +03:00
|
|
|
return $definition->getMethodParameters($class, $method);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return array();
|
|
|
|
}
|
|
|
|
}
|