Augmentation vers version 3.3.0
This commit is contained in:
38
vendor/symfony/dependency-injection/Alias.php
vendored
38
vendor/symfony/dependency-injection/Alias.php
vendored
@@ -15,6 +15,7 @@ class Alias
|
||||
{
|
||||
private $id;
|
||||
private $public;
|
||||
private $private;
|
||||
|
||||
/**
|
||||
* @param string $id Alias identifier
|
||||
@@ -22,8 +23,9 @@ class Alias
|
||||
*/
|
||||
public function __construct($id, $public = true)
|
||||
{
|
||||
$this->id = strtolower($id);
|
||||
$this->id = (string) $id;
|
||||
$this->public = $public;
|
||||
$this->private = 2 > \func_num_args();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -40,10 +42,44 @@ class Alias
|
||||
* Sets if this Alias is public.
|
||||
*
|
||||
* @param bool $boolean If this Alias should be public
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPublic($boolean)
|
||||
{
|
||||
$this->public = (bool) $boolean;
|
||||
$this->private = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets if this Alias is private.
|
||||
*
|
||||
* When set, the "private" state has a higher precedence than "public".
|
||||
* In version 3.4, a "private" alias always remains publicly accessible,
|
||||
* but triggers a deprecation notice when accessed from the container,
|
||||
* so that the alias can be made really private in 4.0.
|
||||
*
|
||||
* @param bool $boolean
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setPrivate($boolean)
|
||||
{
|
||||
$this->private = (bool) $boolean;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this alias is private.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isPrivate()
|
||||
{
|
||||
return $this->private;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
27
vendor/symfony/dependency-injection/Argument/ArgumentInterface.php
vendored
Normal file
27
vendor/symfony/dependency-injection/Argument/ArgumentInterface.php
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Argument;
|
||||
|
||||
/**
|
||||
* Represents a complex argument containing nested values.
|
||||
*
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
*/
|
||||
interface ArgumentInterface
|
||||
{
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getValues();
|
||||
|
||||
public function setValues(array $values);
|
||||
}
|
||||
46
vendor/symfony/dependency-injection/Argument/BoundArgument.php
vendored
Normal file
46
vendor/symfony/dependency-injection/Argument/BoundArgument.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Argument;
|
||||
|
||||
/**
|
||||
* @author Guilhem Niot <guilhem.niot@gmail.com>
|
||||
*/
|
||||
final class BoundArgument implements ArgumentInterface
|
||||
{
|
||||
private static $sequence = 0;
|
||||
|
||||
private $value;
|
||||
private $identifier;
|
||||
private $used;
|
||||
|
||||
public function __construct($value)
|
||||
{
|
||||
$this->value = $value;
|
||||
$this->identifier = ++self::$sequence;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return [$this->value, $this->identifier, $this->used];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setValues(array $values)
|
||||
{
|
||||
list($this->value, $this->identifier, $this->used) = $values;
|
||||
}
|
||||
}
|
||||
55
vendor/symfony/dependency-injection/Argument/IteratorArgument.php
vendored
Normal file
55
vendor/symfony/dependency-injection/Argument/IteratorArgument.php
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Argument;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Represents a collection of values to lazily iterate over.
|
||||
*
|
||||
* @author Titouan Galopin <galopintitouan@gmail.com>
|
||||
*/
|
||||
class IteratorArgument implements ArgumentInterface
|
||||
{
|
||||
private $values;
|
||||
|
||||
/**
|
||||
* @param Reference[] $values
|
||||
*/
|
||||
public function __construct(array $values)
|
||||
{
|
||||
$this->setValues($values);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array The values to lazily iterate over
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Reference[] $values The service references to lazily iterate over
|
||||
*/
|
||||
public function setValues(array $values)
|
||||
{
|
||||
foreach ($values as $k => $v) {
|
||||
if (null !== $v && !$v instanceof Reference) {
|
||||
throw new InvalidArgumentException(sprintf('An IteratorArgument must hold only Reference instances, "%s" given.', \is_object($v) ? \get_class($v) : \gettype($v)));
|
||||
}
|
||||
}
|
||||
|
||||
$this->values = $values;
|
||||
}
|
||||
}
|
||||
46
vendor/symfony/dependency-injection/Argument/RewindableGenerator.php
vendored
Normal file
46
vendor/symfony/dependency-injection/Argument/RewindableGenerator.php
vendored
Normal file
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Argument;
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class RewindableGenerator implements \IteratorAggregate, \Countable
|
||||
{
|
||||
private $generator;
|
||||
private $count;
|
||||
|
||||
/**
|
||||
* @param int|callable $count
|
||||
*/
|
||||
public function __construct(callable $generator, $count)
|
||||
{
|
||||
$this->generator = $generator;
|
||||
$this->count = $count;
|
||||
}
|
||||
|
||||
public function getIterator()
|
||||
{
|
||||
$g = $this->generator;
|
||||
|
||||
return $g();
|
||||
}
|
||||
|
||||
public function count()
|
||||
{
|
||||
if (\is_callable($count = $this->count)) {
|
||||
$this->count = $count();
|
||||
}
|
||||
|
||||
return $this->count;
|
||||
}
|
||||
}
|
||||
50
vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php
vendored
Normal file
50
vendor/symfony/dependency-injection/Argument/ServiceClosureArgument.php
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Argument;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Represents a service wrapped in a memoizing closure.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ServiceClosureArgument implements ArgumentInterface
|
||||
{
|
||||
private $values;
|
||||
|
||||
public function __construct(Reference $reference)
|
||||
{
|
||||
$this->values = [$reference];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getValues()
|
||||
{
|
||||
return $this->values;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setValues(array $values)
|
||||
{
|
||||
if ([0] !== array_keys($values) || !($values[0] instanceof Reference || null === $values[0])) {
|
||||
throw new InvalidArgumentException('A ServiceClosureArgument must hold one and only one Reference.');
|
||||
}
|
||||
|
||||
$this->values = $values;
|
||||
}
|
||||
}
|
||||
37
vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php
vendored
Normal file
37
vendor/symfony/dependency-injection/Argument/TaggedIteratorArgument.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Argument;
|
||||
|
||||
/**
|
||||
* Represents a collection of services found by tag name to lazily iterate over.
|
||||
*
|
||||
* @author Roland Franssen <franssen.roland@gmail.com>
|
||||
*/
|
||||
class TaggedIteratorArgument extends IteratorArgument
|
||||
{
|
||||
private $tag;
|
||||
|
||||
/**
|
||||
* @param string $tag
|
||||
*/
|
||||
public function __construct($tag)
|
||||
{
|
||||
parent::__construct([]);
|
||||
|
||||
$this->tag = (string) $tag;
|
||||
}
|
||||
|
||||
public function getTag()
|
||||
{
|
||||
return $this->tag;
|
||||
}
|
||||
}
|
||||
126
vendor/symfony/dependency-injection/ChildDefinition.php
vendored
Normal file
126
vendor/symfony/dependency-injection/ChildDefinition.php
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
|
||||
|
||||
/**
|
||||
* This definition extends another definition.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ChildDefinition extends Definition
|
||||
{
|
||||
private $parent;
|
||||
|
||||
/**
|
||||
* @param string $parent The id of Definition instance to decorate
|
||||
*/
|
||||
public function __construct($parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->setPrivate(false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Definition to inherit from.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Definition to inherit from.
|
||||
*
|
||||
* @param string $parent
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setParent($parent)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* If replaceArgument() has been used to replace an argument, this method
|
||||
* will return the replacement value.
|
||||
*
|
||||
* @param int|string $index
|
||||
*
|
||||
* @return mixed The argument value
|
||||
*
|
||||
* @throws OutOfBoundsException When the argument does not exist
|
||||
*/
|
||||
public function getArgument($index)
|
||||
{
|
||||
if (\array_key_exists('index_'.$index, $this->arguments)) {
|
||||
return $this->arguments['index_'.$index];
|
||||
}
|
||||
|
||||
return parent::getArgument($index);
|
||||
}
|
||||
|
||||
/**
|
||||
* You should always use this method when overwriting existing arguments
|
||||
* of the parent definition.
|
||||
*
|
||||
* If you directly call setArguments() keep in mind that you must follow
|
||||
* certain conventions when you want to overwrite the arguments of the
|
||||
* parent definition, otherwise your arguments will only be appended.
|
||||
*
|
||||
* @param int|string $index
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when $index isn't an integer
|
||||
*/
|
||||
public function replaceArgument($index, $value)
|
||||
{
|
||||
if (\is_int($index)) {
|
||||
$this->arguments['index_'.$index] = $value;
|
||||
} elseif (0 === strpos($index, '$')) {
|
||||
$this->arguments[$index] = $value;
|
||||
} else {
|
||||
throw new InvalidArgumentException('The argument must be an existing index or the name of a constructor\'s parameter.');
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function setAutoconfigured($autoconfigured)
|
||||
{
|
||||
throw new BadMethodCallException('A ChildDefinition cannot be autoconfigured.');
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function setInstanceofConditionals(array $instanceof)
|
||||
{
|
||||
throw new BadMethodCallException('A ChildDefinition cannot have instanceof conditionals set on it.');
|
||||
}
|
||||
}
|
||||
|
||||
class_alias(ChildDefinition::class, DefinitionDecorator::class);
|
||||
174
vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php
vendored
Normal file
174
vendor/symfony/dependency-injection/Compiler/AbstractRecursivePass.php
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
abstract class AbstractRecursivePass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* @var ContainerBuilder
|
||||
*/
|
||||
protected $container;
|
||||
protected $currentId;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
try {
|
||||
$this->processValue($container->getDefinitions(), true);
|
||||
} finally {
|
||||
$this->container = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a value found in a definition tree.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param bool $isRoot
|
||||
*
|
||||
* @return mixed The processed value
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (\is_array($value)) {
|
||||
foreach ($value as $k => $v) {
|
||||
if ($isRoot) {
|
||||
$this->currentId = $k;
|
||||
}
|
||||
if ($v !== $processedValue = $this->processValue($v, $isRoot)) {
|
||||
$value[$k] = $processedValue;
|
||||
}
|
||||
}
|
||||
} elseif ($value instanceof ArgumentInterface) {
|
||||
$value->setValues($this->processValue($value->getValues()));
|
||||
} elseif ($value instanceof Definition) {
|
||||
$value->setArguments($this->processValue($value->getArguments()));
|
||||
$value->setProperties($this->processValue($value->getProperties()));
|
||||
$value->setMethodCalls($this->processValue($value->getMethodCalls()));
|
||||
|
||||
$changes = $value->getChanges();
|
||||
if (isset($changes['factory'])) {
|
||||
$value->setFactory($this->processValue($value->getFactory()));
|
||||
}
|
||||
if (isset($changes['configurator'])) {
|
||||
$value->setConfigurator($this->processValue($value->getConfigurator()));
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $required
|
||||
*
|
||||
* @return \ReflectionFunctionAbstract|null
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
protected function getConstructor(Definition $definition, $required)
|
||||
{
|
||||
if ($definition->isSynthetic()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (\is_string($factory = $definition->getFactory())) {
|
||||
if (!\function_exists($factory)) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": function "%s" does not exist.', $this->currentId, $factory));
|
||||
}
|
||||
$r = new \ReflectionFunction($factory);
|
||||
if (false !== $r->getFileName() && file_exists($r->getFileName())) {
|
||||
$this->container->fileExists($r->getFileName());
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
if ($factory) {
|
||||
list($class, $method) = $factory;
|
||||
if ($class instanceof Reference) {
|
||||
$class = $this->container->findDefinition((string) $class)->getClass();
|
||||
} elseif (null === $class) {
|
||||
$class = $definition->getClass();
|
||||
}
|
||||
if ('__construct' === $method) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": "__construct()" cannot be used as a factory method.', $this->currentId));
|
||||
}
|
||||
|
||||
return $this->getReflectionMethod(new Definition($class), $method);
|
||||
}
|
||||
|
||||
$class = $definition->getClass();
|
||||
|
||||
try {
|
||||
if (!$r = $this->container->getReflectionClass($class)) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class));
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": %s.', $this->currentId, lcfirst(rtrim($e->getMessage(), '.'))));
|
||||
}
|
||||
if (!$r = $r->getConstructor()) {
|
||||
if ($required) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": class%s has no constructor.', $this->currentId, sprintf($class !== $this->currentId ? ' "%s"' : '', $class)));
|
||||
}
|
||||
} elseif (!$r->isPublic()) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": %s must be public.', $this->currentId, sprintf($class !== $this->currentId ? 'constructor of class "%s"' : 'its constructor', $class)));
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $method
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*
|
||||
* @return \ReflectionFunctionAbstract
|
||||
*/
|
||||
protected function getReflectionMethod(Definition $definition, $method)
|
||||
{
|
||||
if ('__construct' === $method) {
|
||||
return $this->getConstructor($definition, true);
|
||||
}
|
||||
|
||||
if (!$class = $definition->getClass()) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": the class is not set.', $this->currentId));
|
||||
}
|
||||
|
||||
if (!$r = $this->container->getReflectionClass($class)) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": class "%s" does not exist.', $this->currentId, $class));
|
||||
}
|
||||
|
||||
if (!$r->hasMethod($method)) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" does not exist.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method));
|
||||
}
|
||||
|
||||
$r = $r->getMethod($method);
|
||||
if (!$r->isPublic()) {
|
||||
throw new RuntimeException(sprintf('Invalid service "%s": method "%s()" must be public.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method));
|
||||
}
|
||||
|
||||
return $r;
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\ExpressionLanguage;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
/**
|
||||
* Run this pass before passes that need to know more about the relation of
|
||||
@@ -24,20 +29,23 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class AnalyzeServiceReferencesPass implements RepeatablePassInterface
|
||||
class AnalyzeServiceReferencesPass extends AbstractRecursivePass implements RepeatablePassInterface
|
||||
{
|
||||
private $graph;
|
||||
private $container;
|
||||
private $currentId;
|
||||
private $currentDefinition;
|
||||
private $onlyConstructorArguments;
|
||||
private $hasProxyDumper;
|
||||
private $lazy;
|
||||
private $expressionLanguage;
|
||||
private $byConstructor;
|
||||
|
||||
/**
|
||||
* @param bool $onlyConstructorArguments Sets this Service Reference pass to ignore method calls
|
||||
*/
|
||||
public function __construct($onlyConstructorArguments = false)
|
||||
public function __construct($onlyConstructorArguments = false, $hasProxyDumper = true)
|
||||
{
|
||||
$this->onlyConstructorArguments = (bool) $onlyConstructorArguments;
|
||||
$this->hasProxyDumper = (bool) $hasProxyDumper;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,68 +64,77 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface
|
||||
$this->container = $container;
|
||||
$this->graph = $container->getCompiler()->getServiceReferenceGraph();
|
||||
$this->graph->clear();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->currentId = $id;
|
||||
$this->currentDefinition = $definition;
|
||||
|
||||
$this->processArguments($definition->getArguments());
|
||||
if ($definition->getFactoryService(false)) {
|
||||
$this->processArguments(array(new Reference($definition->getFactoryService(false))));
|
||||
}
|
||||
if (\is_array($definition->getFactory())) {
|
||||
$this->processArguments($definition->getFactory());
|
||||
}
|
||||
|
||||
if (!$this->onlyConstructorArguments) {
|
||||
$this->processArguments($definition->getMethodCalls());
|
||||
$this->processArguments($definition->getProperties());
|
||||
if ($definition->getConfigurator()) {
|
||||
$this->processArguments(array($definition->getConfigurator()));
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->lazy = false;
|
||||
$this->byConstructor = false;
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
$this->graph->connect($id, $alias, (string) $alias, $this->getDefinition((string) $alias), null);
|
||||
$targetId = $this->getDefinitionId((string) $alias);
|
||||
$this->graph->connect($id, $alias, $targetId, $this->getDefinition($targetId), null);
|
||||
}
|
||||
|
||||
parent::process($container);
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes service definitions for arguments to find relationships for the service graph.
|
||||
*
|
||||
* @param array $arguments An array of Reference or Definition objects relating to service definitions
|
||||
*/
|
||||
private function processArguments(array $arguments)
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
foreach ($arguments as $argument) {
|
||||
if (\is_array($argument)) {
|
||||
$this->processArguments($argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$this->graph->connect(
|
||||
$this->currentId,
|
||||
$this->currentDefinition,
|
||||
$this->getDefinitionId((string) $argument),
|
||||
$this->getDefinition((string) $argument),
|
||||
$argument
|
||||
);
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$this->processArguments($argument->getArguments());
|
||||
$this->processArguments($argument->getMethodCalls());
|
||||
$this->processArguments($argument->getProperties());
|
||||
$lazy = $this->lazy;
|
||||
|
||||
if (\is_array($argument->getFactory())) {
|
||||
$this->processArguments($argument->getFactory());
|
||||
}
|
||||
if ($argument->getFactoryService(false)) {
|
||||
$this->processArguments(array(new Reference($argument->getFactoryService(false))));
|
||||
}
|
||||
}
|
||||
if ($value instanceof ArgumentInterface) {
|
||||
$this->lazy = true;
|
||||
parent::processValue($value->getValues());
|
||||
$this->lazy = $lazy;
|
||||
|
||||
return $value;
|
||||
}
|
||||
if ($value instanceof Expression) {
|
||||
$this->getExpressionLanguage()->compile((string) $value, ['this' => 'container']);
|
||||
|
||||
return $value;
|
||||
}
|
||||
if ($value instanceof Reference) {
|
||||
$targetId = $this->getDefinitionId((string) $value);
|
||||
$targetDefinition = $this->getDefinition($targetId);
|
||||
|
||||
$this->graph->connect(
|
||||
$this->currentId,
|
||||
$this->currentDefinition,
|
||||
$targetId,
|
||||
$targetDefinition,
|
||||
$value,
|
||||
$this->lazy || ($this->hasProxyDumper && $targetDefinition && $targetDefinition->isLazy()),
|
||||
ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE === $value->getInvalidBehavior(),
|
||||
$this->byConstructor
|
||||
);
|
||||
|
||||
return $value;
|
||||
}
|
||||
if (!$value instanceof Definition) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
if ($isRoot) {
|
||||
if ($value->isSynthetic() || $value->isAbstract()) {
|
||||
return $value;
|
||||
}
|
||||
$this->currentDefinition = $value;
|
||||
} elseif ($this->currentDefinition === $value) {
|
||||
return $value;
|
||||
}
|
||||
$this->lazy = false;
|
||||
|
||||
$byConstructor = $this->byConstructor;
|
||||
$this->byConstructor = $isRoot || $byConstructor;
|
||||
$this->processValue($value->getFactory());
|
||||
$this->processValue($value->getArguments());
|
||||
$this->byConstructor = $byConstructor;
|
||||
|
||||
if (!$this->onlyConstructorArguments) {
|
||||
$this->processValue($value->getProperties());
|
||||
$this->processValue($value->getMethodCalls());
|
||||
$this->processValue($value->getConfigurator());
|
||||
}
|
||||
$this->lazy = $lazy;
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -129,8 +146,6 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface
|
||||
*/
|
||||
private function getDefinition($id)
|
||||
{
|
||||
$id = $this->getDefinitionId($id);
|
||||
|
||||
return null === $id ? null : $this->container->getDefinition($id);
|
||||
}
|
||||
|
||||
@@ -141,9 +156,37 @@ class AnalyzeServiceReferencesPass implements RepeatablePassInterface
|
||||
}
|
||||
|
||||
if (!$this->container->hasDefinition($id)) {
|
||||
return;
|
||||
return null;
|
||||
}
|
||||
|
||||
return $id;
|
||||
return $this->container->normalizeId($id);
|
||||
}
|
||||
|
||||
private function getExpressionLanguage()
|
||||
{
|
||||
if (null === $this->expressionLanguage) {
|
||||
if (!class_exists(ExpressionLanguage::class)) {
|
||||
throw new RuntimeException('Unable to use expressions as the Symfony ExpressionLanguage component is not installed.');
|
||||
}
|
||||
|
||||
$providers = $this->container->getExpressionLanguageProviders();
|
||||
$this->expressionLanguage = new ExpressionLanguage(null, $providers, function ($arg) {
|
||||
if ('""' === substr_replace($arg, '', 1, -1)) {
|
||||
$id = stripcslashes(substr($arg, 1, -1));
|
||||
$id = $this->getDefinitionId($id);
|
||||
|
||||
$this->graph->connect(
|
||||
$this->currentId,
|
||||
$this->currentDefinition,
|
||||
$id,
|
||||
$this->getDefinition($id)
|
||||
);
|
||||
}
|
||||
|
||||
return sprintf('$this->get(%s)', $arg);
|
||||
});
|
||||
}
|
||||
|
||||
return $this->expressionLanguage;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ class AutoAliasServicePass implements CompilerPassInterface
|
||||
|
||||
$aliasId = $container->getParameterBag()->resolveValue($tag['format']);
|
||||
if ($container->hasDefinition($aliasId) || $container->hasAlias($aliasId)) {
|
||||
$container->setAlias($serviceId, new Alias($aliasId));
|
||||
$container->setAlias($serviceId, new Alias($aliasId, true));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
74
vendor/symfony/dependency-injection/Compiler/AutowireExceptionPass.php
vendored
Normal file
74
vendor/symfony/dependency-injection/Compiler/AutowireExceptionPass.php
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\AutowireExceptionPass class is deprecated since Symfony 3.4 and will be removed in 4.0. Use the DefinitionErrorExceptionPass class instead.', E_USER_DEPRECATED);
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* Throws autowire exceptions from AutowirePass for definitions that still exist.
|
||||
*
|
||||
* @deprecated since version 3.4, will be removed in 4.0.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
*/
|
||||
class AutowireExceptionPass implements CompilerPassInterface
|
||||
{
|
||||
private $autowirePass;
|
||||
private $inlineServicePass;
|
||||
|
||||
public function __construct(AutowirePass $autowirePass, InlineServiceDefinitionsPass $inlineServicePass)
|
||||
{
|
||||
$this->autowirePass = $autowirePass;
|
||||
$this->inlineServicePass = $inlineServicePass;
|
||||
}
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
// the pass should only be run once
|
||||
if (null === $this->autowirePass || null === $this->inlineServicePass) {
|
||||
return;
|
||||
}
|
||||
|
||||
$inlinedIds = $this->inlineServicePass->getInlinedServiceIds();
|
||||
$exceptions = $this->autowirePass->getAutowiringExceptions();
|
||||
|
||||
// free up references
|
||||
$this->autowirePass = null;
|
||||
$this->inlineServicePass = null;
|
||||
|
||||
foreach ($exceptions as $exception) {
|
||||
if ($this->doesServiceExistInTheContainer($exception->getServiceId(), $container, $inlinedIds)) {
|
||||
throw $exception;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function doesServiceExistInTheContainer($serviceId, ContainerBuilder $container, array $inlinedIds)
|
||||
{
|
||||
if ($container->hasDefinition($serviceId)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// was the service inlined? Of so, does its parent service exist?
|
||||
if (isset($inlinedIds[$serviceId])) {
|
||||
foreach ($inlinedIds[$serviceId] as $parentId) {
|
||||
if ($this->doesServiceExistInTheContainer($parentId, $container, $inlinedIds)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -11,143 +11,249 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\Config\Resource\ClassExistenceResource;
|
||||
use Symfony\Component\DependencyInjection\Config\AutowireServiceResource;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\AutowiringFailedException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper;
|
||||
use Symfony\Component\DependencyInjection\TypedReference;
|
||||
|
||||
/**
|
||||
* Guesses constructor arguments of services definitions and try to instantiate services if necessary.
|
||||
* Inspects existing service definitions and wires the autowired ones using the type hints of their classes.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class AutowirePass implements CompilerPassInterface
|
||||
class AutowirePass extends AbstractRecursivePass
|
||||
{
|
||||
private $container;
|
||||
private $reflectionClasses = array();
|
||||
private $definedTypes = array();
|
||||
private $definedTypes = [];
|
||||
private $types;
|
||||
private $notGuessableTypes = array();
|
||||
private $autowired = array();
|
||||
private $ambiguousServiceTypes;
|
||||
private $autowired = [];
|
||||
private $lastFailure;
|
||||
private $throwOnAutowiringException;
|
||||
private $autowiringExceptions = [];
|
||||
private $strictMode;
|
||||
|
||||
/**
|
||||
* @param bool $throwOnAutowireException Errors can be retrieved via Definition::getErrors()
|
||||
*/
|
||||
public function __construct($throwOnAutowireException = true)
|
||||
{
|
||||
$this->throwOnAutowiringException = $throwOnAutowireException;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.4, to be removed in 4.0.
|
||||
*
|
||||
* @return AutowiringFailedException[]
|
||||
*/
|
||||
public function getAutowiringExceptions()
|
||||
{
|
||||
@trigger_error('Calling AutowirePass::getAutowiringExceptions() is deprecated since Symfony 3.4 and will be removed in 4.0. Use Definition::getErrors() instead.', E_USER_DEPRECATED);
|
||||
|
||||
return $this->autowiringExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$throwingAutoloader = function ($class) { throw new \ReflectionException(sprintf('Class %s does not exist', $class)); };
|
||||
spl_autoload_register($throwingAutoloader);
|
||||
// clear out any possibly stored exceptions from before
|
||||
$this->autowiringExceptions = [];
|
||||
$this->strictMode = $container->hasParameter('container.autowiring.strict_mode') && $container->getParameter('container.autowiring.strict_mode');
|
||||
|
||||
try {
|
||||
$this->container = $container;
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isAutowired()) {
|
||||
$this->completeDefinition($id, $definition);
|
||||
}
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
|
||||
spl_autoload_unregister($throwingAutoloader);
|
||||
|
||||
// Free memory and remove circular reference to container
|
||||
$this->container = null;
|
||||
$this->reflectionClasses = array();
|
||||
$this->definedTypes = array();
|
||||
$this->types = null;
|
||||
$this->notGuessableTypes = array();
|
||||
$this->autowired = array();
|
||||
|
||||
if (isset($e)) {
|
||||
throw $e;
|
||||
parent::process($container);
|
||||
} finally {
|
||||
$this->definedTypes = [];
|
||||
$this->types = null;
|
||||
$this->ambiguousServiceTypes = null;
|
||||
$this->autowired = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Wires the given definition.
|
||||
* Creates a resource to help know if this service has changed.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
* @return AutowireServiceResource
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @deprecated since version 3.3, to be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.
|
||||
*/
|
||||
private function completeDefinition($id, Definition $definition)
|
||||
public static function createResourceForClass(\ReflectionClass $reflectionClass)
|
||||
{
|
||||
if ($definition->getFactory() || $definition->getFactoryClass(false) || $definition->getFactoryService(false)) {
|
||||
throw new RuntimeException(sprintf('Service "%s" can use either autowiring or a factory, not both.', $id));
|
||||
@trigger_error('The '.__METHOD__.'() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.', E_USER_DEPRECATED);
|
||||
|
||||
$metadata = [];
|
||||
|
||||
foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflectionMethod) {
|
||||
if (!$reflectionMethod->isStatic()) {
|
||||
$metadata[$reflectionMethod->name] = self::getResourceMetadataForMethod($reflectionMethod);
|
||||
}
|
||||
}
|
||||
|
||||
if (!$reflectionClass = $this->getReflectionClass($id, $definition)) {
|
||||
return;
|
||||
return new AutowireServiceResource($reflectionClass->name, $reflectionClass->getFileName(), $metadata);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
try {
|
||||
return $this->doProcessValue($value, $isRoot);
|
||||
} catch (AutowiringFailedException $e) {
|
||||
if ($this->throwOnAutowiringException) {
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$this->autowiringExceptions[] = $e;
|
||||
$this->container->getDefinition($this->currentId)->addError($e->getMessage());
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
}
|
||||
|
||||
private function doProcessValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof TypedReference) {
|
||||
if ($ref = $this->getAutowiredReference($value, $value->getRequiringClass() ? sprintf('for "%s" in "%s"', $value->getType(), $value->getRequiringClass()) : '')) {
|
||||
return $ref;
|
||||
}
|
||||
$this->container->log($this, $this->createTypeNotFoundMessage($value, 'it'));
|
||||
}
|
||||
$value = parent::processValue($value, $isRoot);
|
||||
|
||||
if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
|
||||
return $value;
|
||||
}
|
||||
if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) {
|
||||
$this->container->log($this, sprintf('Skipping service "%s": Class or interface "%s" cannot be loaded.', $this->currentId, $value->getClass()));
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
$this->container->addClassResource($reflectionClass);
|
||||
$methodCalls = $value->getMethodCalls();
|
||||
|
||||
if (!$constructor = $reflectionClass->getConstructor()) {
|
||||
return;
|
||||
try {
|
||||
$constructor = $this->getConstructor($value, false);
|
||||
} catch (RuntimeException $e) {
|
||||
throw new AutowiringFailedException($this->currentId, $e->getMessage(), 0, $e);
|
||||
}
|
||||
$parameters = $constructor->getParameters();
|
||||
if (method_exists('ReflectionMethod', 'isVariadic') && $constructor->isVariadic()) {
|
||||
|
||||
if ($constructor) {
|
||||
array_unshift($methodCalls, [$constructor, $value->getArguments()]);
|
||||
}
|
||||
|
||||
$methodCalls = $this->autowireCalls($reflectionClass, $methodCalls);
|
||||
|
||||
if ($constructor) {
|
||||
list(, $arguments) = array_shift($methodCalls);
|
||||
|
||||
if ($arguments !== $value->getArguments()) {
|
||||
$value->setArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
if ($methodCalls !== $value->getMethodCalls()) {
|
||||
$value->setMethodCalls($methodCalls);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function autowireCalls(\ReflectionClass $reflectionClass, array $methodCalls)
|
||||
{
|
||||
foreach ($methodCalls as $i => $call) {
|
||||
list($method, $arguments) = $call;
|
||||
|
||||
if ($method instanceof \ReflectionFunctionAbstract) {
|
||||
$reflectionMethod = $method;
|
||||
} else {
|
||||
$definition = new Definition($reflectionClass->name);
|
||||
try {
|
||||
$reflectionMethod = $this->getReflectionMethod($definition, $method);
|
||||
} catch (RuntimeException $e) {
|
||||
if ($definition->getFactory()) {
|
||||
continue;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
$arguments = $this->autowireMethod($reflectionMethod, $arguments);
|
||||
|
||||
if ($arguments !== $call[1]) {
|
||||
$methodCalls[$i][1] = $arguments;
|
||||
}
|
||||
}
|
||||
|
||||
return $methodCalls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Autowires the constructor or a method.
|
||||
*
|
||||
* @return array The autowired arguments
|
||||
*
|
||||
* @throws AutowiringFailedException
|
||||
*/
|
||||
private function autowireMethod(\ReflectionFunctionAbstract $reflectionMethod, array $arguments)
|
||||
{
|
||||
$class = $reflectionMethod instanceof \ReflectionMethod ? $reflectionMethod->class : $this->currentId;
|
||||
$method = $reflectionMethod->name;
|
||||
$parameters = $reflectionMethod->getParameters();
|
||||
if (method_exists('ReflectionMethod', 'isVariadic') && $reflectionMethod->isVariadic()) {
|
||||
array_pop($parameters);
|
||||
}
|
||||
|
||||
$arguments = $definition->getArguments();
|
||||
foreach ($parameters as $index => $parameter) {
|
||||
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
|
||||
if (\array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$typeHint = $parameter->getClass()) {
|
||||
if (isset($arguments[$index])) {
|
||||
$type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true);
|
||||
|
||||
if (!$type) {
|
||||
if (isset($arguments[$index])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// no default value? Then fail
|
||||
if (!$parameter->isDefaultValueAvailable()) {
|
||||
// For core classes, isDefaultValueAvailable() can
|
||||
// be false when isOptional() returns true. If the
|
||||
// argument *is* optional, allow it to be missing
|
||||
if ($parameter->isOptional()) {
|
||||
continue;
|
||||
}
|
||||
$type = ProxyHelper::getTypeHint($reflectionMethod, $parameter, false);
|
||||
$type = $type ? sprintf('is type-hinted "%s"', $type) : 'has no type-hint';
|
||||
|
||||
// no default value? Then fail
|
||||
if (!$parameter->isOptional()) {
|
||||
throw new RuntimeException(sprintf('Unable to autowire argument index %d ($%s) for the service "%s". If this is an object, give it a type-hint. Otherwise, specify this argument\'s value explicitly.', $index, $parameter->name, $id));
|
||||
}
|
||||
|
||||
// specifically pass the default value
|
||||
$arguments[$index] = $parameter->getDefaultValue();
|
||||
|
||||
continue;
|
||||
throw new AutowiringFailedException($this->currentId, sprintf('Cannot autowire service "%s": argument "$%s" of method "%s()" %s, you should configure its value explicitly.', $this->currentId, $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method, $type));
|
||||
}
|
||||
|
||||
if (isset($this->autowired[$typeHint->name])) {
|
||||
$arguments[$index] = $this->autowired[$typeHint->name] ? new Reference($this->autowired[$typeHint->name]) : null;
|
||||
continue;
|
||||
}
|
||||
// specifically pass the default value
|
||||
$arguments[$index] = $parameter->getDefaultValue();
|
||||
|
||||
if (null === $this->types) {
|
||||
$this->populateAvailableTypes();
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
if (isset($this->types[$typeHint->name]) && !isset($this->notGuessableTypes[$typeHint->name])) {
|
||||
$value = new Reference($this->types[$typeHint->name]);
|
||||
} else {
|
||||
try {
|
||||
$value = $this->createAutowiredDefinition($typeHint, $id);
|
||||
} catch (RuntimeException $e) {
|
||||
if ($parameter->isDefaultValueAvailable()) {
|
||||
$value = $parameter->getDefaultValue();
|
||||
} elseif ($parameter->allowsNull()) {
|
||||
$value = null;
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
$this->autowired[$typeHint->name] = false;
|
||||
}
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
// Typehint against a non-existing class
|
||||
if (!$value = $this->getAutowiredReference($ref = new TypedReference($type, $type, !$parameter->isOptional() ? $class : ''), 'for '.sprintf('argument "$%s" of method "%s()"', $parameter->name, $class.'::'.$method))) {
|
||||
$failureMessage = $this->createTypeNotFoundMessage($ref, sprintf('argument "$%s" of method "%s()"', $parameter->name, $class !== $this->currentId ? $class.'::'.$method : $method));
|
||||
|
||||
if (!$parameter->isDefaultValueAvailable()) {
|
||||
throw new RuntimeException(sprintf('Cannot autowire argument %s for %s because the type-hinted class does not exist (%s).', $index + 1, $definition->getClass(), $e->getMessage()), 0, $e);
|
||||
if ($parameter->isDefaultValueAvailable()) {
|
||||
$value = $parameter->getDefaultValue();
|
||||
} elseif (!$parameter->allowsNull()) {
|
||||
throw new AutowiringFailedException($this->currentId, $failureMessage);
|
||||
}
|
||||
|
||||
$value = $parameter->getDefaultValue();
|
||||
$this->container->log($this, $failureMessage);
|
||||
}
|
||||
|
||||
$arguments[$index] = $value;
|
||||
@@ -166,41 +272,96 @@ class AutowirePass implements CompilerPassInterface
|
||||
// it's possible index 1 was set, then index 0, then 2, etc
|
||||
// make sure that we re-order so they're injected as expected
|
||||
ksort($arguments);
|
||||
$definition->setArguments($arguments);
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return TypedReference|null A reference to the service matching the given type, if any
|
||||
*/
|
||||
private function getAutowiredReference(TypedReference $reference, $deprecationMessage)
|
||||
{
|
||||
$this->lastFailure = null;
|
||||
$type = $reference->getType();
|
||||
|
||||
if ($type !== $this->container->normalizeId($reference) || ($this->container->has($type) && !$this->container->findDefinition($type)->isAbstract())) {
|
||||
return $reference;
|
||||
}
|
||||
|
||||
if (null === $this->types) {
|
||||
$this->populateAvailableTypes($this->strictMode);
|
||||
}
|
||||
|
||||
if (isset($this->definedTypes[$type])) {
|
||||
return new TypedReference($this->types[$type], $type);
|
||||
}
|
||||
|
||||
if (!$this->strictMode && isset($this->types[$type])) {
|
||||
$message = 'Autowiring services based on the types they implement is deprecated since Symfony 3.3 and won\'t be supported in version 4.0.';
|
||||
if ($aliasSuggestion = $this->getAliasesSuggestionForType($type = $reference->getType(), $deprecationMessage)) {
|
||||
$message .= ' '.$aliasSuggestion;
|
||||
} else {
|
||||
$message .= sprintf(' You should %s the "%s" service to "%s" instead.', isset($this->types[$this->types[$type]]) ? 'alias' : 'rename (or alias)', $this->types[$type], $type);
|
||||
}
|
||||
|
||||
@trigger_error($message, E_USER_DEPRECATED);
|
||||
|
||||
return new TypedReference($this->types[$type], $type);
|
||||
}
|
||||
|
||||
if (!$reference->canBeAutoregistered() || isset($this->types[$type]) || isset($this->ambiguousServiceTypes[$type])) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isset($this->autowired[$type])) {
|
||||
return $this->autowired[$type] ? new TypedReference($this->autowired[$type], $type) : null;
|
||||
}
|
||||
|
||||
if (!$this->strictMode) {
|
||||
return $this->createAutowiredDefinition($type);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the list of available types.
|
||||
*/
|
||||
private function populateAvailableTypes()
|
||||
private function populateAvailableTypes($onlyAutowiringTypes = false)
|
||||
{
|
||||
$this->types = array();
|
||||
$this->types = [];
|
||||
if (!$onlyAutowiringTypes) {
|
||||
$this->ambiguousServiceTypes = [];
|
||||
}
|
||||
|
||||
foreach ($this->container->getDefinitions() as $id => $definition) {
|
||||
$this->populateAvailableType($id, $definition);
|
||||
$this->populateAvailableType($id, $definition, $onlyAutowiringTypes);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the list of available types for a given definition.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
* @param string $id
|
||||
*/
|
||||
private function populateAvailableType($id, Definition $definition)
|
||||
private function populateAvailableType($id, Definition $definition, $onlyAutowiringTypes)
|
||||
{
|
||||
// Never use abstract services
|
||||
if ($definition->isAbstract()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($definition->getAutowiringTypes() as $type) {
|
||||
foreach ($definition->getAutowiringTypes(false) as $type) {
|
||||
$this->definedTypes[$type] = true;
|
||||
$this->types[$type] = $id;
|
||||
unset($this->notGuessableTypes[$type]);
|
||||
unset($this->ambiguousServiceTypes[$type]);
|
||||
}
|
||||
|
||||
if (!$reflectionClass = $this->getReflectionClass($id, $definition)) {
|
||||
if ($onlyAutowiringTypes) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (preg_match('/^\d+_[^~]++~[._a-zA-Z\d]{7}$/', $id) || $definition->isDeprecated() || !$reflectionClass = $this->container->getReflectionClass($definition->getClass(), false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -225,110 +386,186 @@ class AutowirePass implements CompilerPassInterface
|
||||
return;
|
||||
}
|
||||
|
||||
if (!isset($this->types[$type])) {
|
||||
// is this already a type/class that is known to match multiple services?
|
||||
if (isset($this->ambiguousServiceTypes[$type])) {
|
||||
$this->ambiguousServiceTypes[$type][] = $id;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// check to make sure the type doesn't match multiple services
|
||||
if (!isset($this->types[$type]) || $this->types[$type] === $id) {
|
||||
$this->types[$type] = $id;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->types[$type] === $id) {
|
||||
return;
|
||||
// keep an array of all services matching this type
|
||||
if (!isset($this->ambiguousServiceTypes[$type])) {
|
||||
$this->ambiguousServiceTypes[$type] = [$this->types[$type]];
|
||||
unset($this->types[$type]);
|
||||
}
|
||||
|
||||
if (!isset($this->notGuessableTypes[$type])) {
|
||||
$this->notGuessableTypes[$type] = true;
|
||||
$this->types[$type] = (array) $this->types[$type];
|
||||
}
|
||||
|
||||
$this->types[$type][] = $id;
|
||||
$this->ambiguousServiceTypes[$type][] = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a definition for the type if possible or throws an exception.
|
||||
*
|
||||
* @param \ReflectionClass $typeHint
|
||||
* @param string $id
|
||||
* @param string $type
|
||||
*
|
||||
* @return Reference A reference to the registered definition
|
||||
*
|
||||
* @throws RuntimeException
|
||||
* @return TypedReference|null A reference to the registered definition
|
||||
*/
|
||||
private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
|
||||
private function createAutowiredDefinition($type)
|
||||
{
|
||||
if (isset($this->notGuessableTypes[$typeHint->name])) {
|
||||
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
|
||||
$matchingServices = implode(', ', $this->types[$typeHint->name]);
|
||||
|
||||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". Multiple services exist for this %s (%s).', $typeHint->name, $id, $classOrInterface, $matchingServices));
|
||||
if (!($typeHint = $this->container->getReflectionClass($type, false)) || !$typeHint->isInstantiable()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!$typeHint->isInstantiable()) {
|
||||
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
|
||||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface));
|
||||
}
|
||||
|
||||
$this->autowired[$typeHint->name] = $argumentId = sprintf('autowired.%s', $typeHint->name);
|
||||
|
||||
$argumentDefinition = $this->container->register($argumentId, $typeHint->name);
|
||||
$currentId = $this->currentId;
|
||||
$this->currentId = $type;
|
||||
$this->autowired[$type] = $argumentId = sprintf('autowired.%s', $type);
|
||||
$argumentDefinition = new Definition($type);
|
||||
$argumentDefinition->setPublic(false);
|
||||
$argumentDefinition->setAutowired(true);
|
||||
|
||||
try {
|
||||
$this->completeDefinition($argumentId, $argumentDefinition);
|
||||
} catch (RuntimeException $e) {
|
||||
$classOrInterface = $typeHint->isInterface() ? 'interface' : 'class';
|
||||
$message = sprintf('Unable to autowire argument of type "%s" for the service "%s". No services were found matching this %s and it cannot be auto-registered.', $typeHint->name, $id, $classOrInterface);
|
||||
throw new RuntimeException($message, 0, $e);
|
||||
$originalThrowSetting = $this->throwOnAutowiringException;
|
||||
$this->throwOnAutowiringException = true;
|
||||
$this->processValue($argumentDefinition, true);
|
||||
$this->container->setDefinition($argumentId, $argumentDefinition);
|
||||
} catch (AutowiringFailedException $e) {
|
||||
$this->autowired[$type] = false;
|
||||
$this->lastFailure = $e->getMessage();
|
||||
$this->container->log($this, $this->lastFailure);
|
||||
|
||||
return null;
|
||||
} finally {
|
||||
$this->throwOnAutowiringException = $originalThrowSetting;
|
||||
$this->currentId = $currentId;
|
||||
}
|
||||
|
||||
return new Reference($argumentId);
|
||||
@trigger_error(sprintf('Relying on service auto-registration for type "%s" is deprecated since Symfony 3.4 and won\'t be supported in 4.0. Create a service named "%s" instead.', $type, $type), E_USER_DEPRECATED);
|
||||
|
||||
$this->container->log($this, sprintf('Type "%s" has been auto-registered for service "%s".', $type, $this->currentId));
|
||||
|
||||
return new TypedReference($argumentId, $type);
|
||||
}
|
||||
|
||||
private function createTypeNotFoundMessage(TypedReference $reference, $label)
|
||||
{
|
||||
$trackResources = $this->container->isTrackingResources();
|
||||
$this->container->setResourceTracking(false);
|
||||
try {
|
||||
if ($r = $this->container->getReflectionClass($type = $reference->getType(), false)) {
|
||||
$alternatives = $this->createTypeAlternatives($reference);
|
||||
}
|
||||
} finally {
|
||||
$this->container->setResourceTracking($trackResources);
|
||||
}
|
||||
|
||||
if (!$r) {
|
||||
// either $type does not exist or a parent class does not exist
|
||||
try {
|
||||
$resource = new ClassExistenceResource($type, false);
|
||||
// isFresh() will explode ONLY if a parent class/trait does not exist
|
||||
$resource->isFresh(0);
|
||||
$parentMsg = false;
|
||||
} catch (\ReflectionException $e) {
|
||||
$parentMsg = $e->getMessage();
|
||||
}
|
||||
|
||||
$message = sprintf('has type "%s" but this class %s.', $type, $parentMsg ? sprintf('is missing a parent class (%s)', $parentMsg) : 'was not found');
|
||||
} else {
|
||||
$message = $this->container->has($type) ? 'this service is abstract' : 'no such service exists';
|
||||
$message = sprintf('references %s "%s" but %s.%s', $r->isInterface() ? 'interface' : 'class', $type, $message, $alternatives);
|
||||
|
||||
if ($r->isInterface() && !$alternatives) {
|
||||
$message .= ' Did you create a class that implements this interface?';
|
||||
}
|
||||
}
|
||||
|
||||
$message = sprintf('Cannot autowire service "%s": %s %s', $this->currentId, $label, $message);
|
||||
|
||||
if (null !== $this->lastFailure) {
|
||||
$message = $this->lastFailure."\n".$message;
|
||||
$this->lastFailure = null;
|
||||
}
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
private function createTypeAlternatives(TypedReference $reference)
|
||||
{
|
||||
// try suggesting available aliases first
|
||||
if ($message = $this->getAliasesSuggestionForType($type = $reference->getType())) {
|
||||
return ' '.$message;
|
||||
}
|
||||
if (null === $this->ambiguousServiceTypes) {
|
||||
$this->populateAvailableTypes();
|
||||
}
|
||||
|
||||
if (isset($this->ambiguousServiceTypes[$type])) {
|
||||
$message = sprintf('one of these existing services: "%s"', implode('", "', $this->ambiguousServiceTypes[$type]));
|
||||
} elseif (isset($this->types[$type])) {
|
||||
$message = sprintf('the existing "%s" service', $this->types[$type]);
|
||||
} elseif ($reference->getRequiringClass() && !$reference->canBeAutoregistered() && !$this->strictMode) {
|
||||
return ' It cannot be auto-registered because it is from a different root namespace.';
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
|
||||
return sprintf(' You should maybe alias this %s to %s.', class_exists($type, false) ? 'class' : 'interface', $message);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the reflection class associated with the given service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return \ReflectionClass|false
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
private function getReflectionClass($id, Definition $definition)
|
||||
private static function getResourceMetadataForMethod(\ReflectionMethod $method)
|
||||
{
|
||||
if (isset($this->reflectionClasses[$id])) {
|
||||
return $this->reflectionClasses[$id];
|
||||
}
|
||||
|
||||
// Cannot use reflection if the class isn't set
|
||||
if (!$class = $definition->getClass()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$class = $this->container->getParameterBag()->resolveValue($class);
|
||||
|
||||
if ($deprecated = $definition->isDeprecated()) {
|
||||
$prevErrorHandler = set_error_handler(function ($level, $message, $file, $line) use (&$prevErrorHandler) {
|
||||
return (E_USER_DEPRECATED === $level || !$prevErrorHandler) ? false : $prevErrorHandler($level, $message, $file, $line);
|
||||
});
|
||||
}
|
||||
|
||||
$e = null;
|
||||
|
||||
try {
|
||||
$reflector = new \ReflectionClass($class);
|
||||
} catch (\Exception $e) {
|
||||
} catch (\Throwable $e) {
|
||||
}
|
||||
|
||||
if ($deprecated) {
|
||||
restore_error_handler();
|
||||
}
|
||||
|
||||
if (null !== $e) {
|
||||
if (!$e instanceof \ReflectionException) {
|
||||
throw $e;
|
||||
$methodArgumentsMetadata = [];
|
||||
foreach ($method->getParameters() as $parameter) {
|
||||
try {
|
||||
$class = $parameter->getClass();
|
||||
} catch (\ReflectionException $e) {
|
||||
// type-hint is against a non-existent class
|
||||
$class = false;
|
||||
}
|
||||
$reflector = false;
|
||||
|
||||
$isVariadic = method_exists($parameter, 'isVariadic') && $parameter->isVariadic();
|
||||
$methodArgumentsMetadata[] = [
|
||||
'class' => $class,
|
||||
'isOptional' => $parameter->isOptional(),
|
||||
'defaultValue' => ($parameter->isOptional() && !$isVariadic) ? $parameter->getDefaultValue() : null,
|
||||
];
|
||||
}
|
||||
|
||||
return $this->reflectionClasses[$id] = $reflector;
|
||||
return $methodArgumentsMetadata;
|
||||
}
|
||||
|
||||
private function getAliasesSuggestionForType($type, $extraContext = null)
|
||||
{
|
||||
$aliases = [];
|
||||
foreach (class_parents($type) + class_implements($type) as $parent) {
|
||||
if ($this->container->has($parent) && !$this->container->findDefinition($parent)->isAbstract()) {
|
||||
$aliases[] = $parent;
|
||||
}
|
||||
}
|
||||
|
||||
$extraContext = $extraContext ? ' '.$extraContext : '';
|
||||
if (1 < $len = \count($aliases)) {
|
||||
$message = sprintf('Try changing the type-hint%s to one of its parents: ', $extraContext);
|
||||
for ($i = 0, --$len; $i < $len; ++$i) {
|
||||
$message .= sprintf('%s "%s", ', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||
}
|
||||
$message .= sprintf('or %s "%s".', class_exists($aliases[$i], false) ? 'class' : 'interface', $aliases[$i]);
|
||||
|
||||
return $message;
|
||||
}
|
||||
|
||||
if ($aliases) {
|
||||
return sprintf('Try changing the type-hint%s to "%s" instead.', $extraContext, $aliases[0]);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
70
vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php
vendored
Normal file
70
vendor/symfony/dependency-injection/Compiler/AutowireRequiredMethodsPass.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Looks for definitions with autowiring enabled and registers their corresponding "@required" methods as setters.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class AutowireRequiredMethodsPass extends AbstractRecursivePass
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
$value = parent::processValue($value, $isRoot);
|
||||
|
||||
if (!$value instanceof Definition || !$value->isAutowired() || $value->isAbstract() || !$value->getClass()) {
|
||||
return $value;
|
||||
}
|
||||
if (!$reflectionClass = $this->container->getReflectionClass($value->getClass(), false)) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$alreadyCalledMethods = [];
|
||||
|
||||
foreach ($value->getMethodCalls() as list($method)) {
|
||||
$alreadyCalledMethods[strtolower($method)] = true;
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getMethods() as $reflectionMethod) {
|
||||
$r = $reflectionMethod;
|
||||
|
||||
if ($r->isConstructor() || isset($alreadyCalledMethods[strtolower($r->name)])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
while (true) {
|
||||
if (false !== $doc = $r->getDocComment()) {
|
||||
if (false !== stripos($doc, '@required') && preg_match('#(?:^/\*\*|\n\s*+\*)\s*+@required(?:\s|\*/$)#i', $doc)) {
|
||||
$value->addMethodCall($reflectionMethod->name);
|
||||
break;
|
||||
}
|
||||
if (false === stripos($doc, '@inheritdoc') || !preg_match('#(?:^/\*\*|\n\s*+\*)\s*+(?:\{@inheritdoc\}|@inheritdoc)(?:\s|\*/$)#i', $doc)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
try {
|
||||
$r = $r->getPrototype();
|
||||
} catch (\ReflectionException $e) {
|
||||
break; // method has no prototype
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
87
vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php
vendored
Normal file
87
vendor/symfony/dependency-injection/Compiler/CheckArgumentsValidityPass.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Checks if arguments of methods are properly configured.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class CheckArgumentsValidityPass extends AbstractRecursivePass
|
||||
{
|
||||
private $throwExceptions;
|
||||
|
||||
public function __construct($throwExceptions = true)
|
||||
{
|
||||
$this->throwExceptions = $throwExceptions;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
foreach ($value->getArguments() as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
if (!\is_int($k)) {
|
||||
$msg = sprintf('Invalid constructor argument for service "%s": integer expected but found string "%s". Check your service definition.', $this->currentId, $k);
|
||||
$value->addError($msg);
|
||||
if ($this->throwExceptions) {
|
||||
throw new RuntimeException($msg);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$msg = sprintf('Invalid constructor argument %d for service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $this->currentId, $i);
|
||||
$value->addError($msg);
|
||||
if ($this->throwExceptions) {
|
||||
throw new RuntimeException($msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($value->getMethodCalls() as $methodCall) {
|
||||
$i = 0;
|
||||
foreach ($methodCall[1] as $k => $v) {
|
||||
if ($k !== $i++) {
|
||||
if (!\is_int($k)) {
|
||||
$msg = sprintf('Invalid argument for method call "%s" of service "%s": integer expected but found string "%s". Check your service definition.', $methodCall[0], $this->currentId, $k);
|
||||
$value->addError($msg);
|
||||
if ($this->throwExceptions) {
|
||||
throw new RuntimeException($msg);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$msg = sprintf('Invalid argument %d for method call "%s" of service "%s": argument %d must be defined before. Check your service definition.', 1 + $k, $methodCall[0], $this->currentId, $i);
|
||||
$value->addError($msg);
|
||||
if ($this->throwExceptions) {
|
||||
throw new RuntimeException($msg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -36,9 +36,9 @@ class CheckCircularReferencesPass implements CompilerPassInterface
|
||||
{
|
||||
$graph = $container->getCompiler()->getServiceReferenceGraph();
|
||||
|
||||
$this->checkedNodes = array();
|
||||
$this->checkedNodes = [];
|
||||
foreach ($graph->getNodes() as $id => $node) {
|
||||
$this->currentPath = array($id);
|
||||
$this->currentPath = [$id];
|
||||
|
||||
$this->checkOutEdges($node->getOutEdges());
|
||||
}
|
||||
@@ -58,8 +58,8 @@ class CheckCircularReferencesPass implements CompilerPassInterface
|
||||
$id = $node->getId();
|
||||
|
||||
if (empty($this->checkedNodes[$id])) {
|
||||
// don't check circular dependencies for lazy services
|
||||
if (!$node->getValue() || !$node->getValue()->isLazy()) {
|
||||
// Don't check circular references for lazy edges
|
||||
if (!$node->getValue() || (!$edge->isLazy() && !$edge->isWeak())) {
|
||||
$searchKey = array_search($id, $this->currentPath);
|
||||
$this->currentPath[] = $id;
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\EnvParameterException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
@@ -24,8 +24,6 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
*
|
||||
* - non synthetic, non abstract services always have a class set
|
||||
* - synthetic services are always public
|
||||
* - synthetic services are always of non-prototype scope
|
||||
* - shared services are always of non-prototype scope
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
@@ -40,29 +38,33 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
|
||||
{
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
// synthetic service is public
|
||||
if ($definition->isSynthetic() && !$definition->isPublic()) {
|
||||
if ($definition->isSynthetic() && !($definition->isPublic() || $definition->isPrivate())) {
|
||||
throw new RuntimeException(sprintf('A synthetic service ("%s") must be public.', $id));
|
||||
}
|
||||
|
||||
// synthetic service has non-prototype scope
|
||||
if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
|
||||
throw new RuntimeException(sprintf('A synthetic service ("%s") cannot be of scope "prototype".', $id));
|
||||
}
|
||||
|
||||
// shared service has non-prototype scope
|
||||
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
|
||||
throw new RuntimeException(sprintf('A shared service ("%s") cannot be of scope "prototype".', $id));
|
||||
}
|
||||
|
||||
if ($definition->getFactory() && ($definition->getFactoryClass(false) || $definition->getFactoryService(false) || $definition->getFactoryMethod(false))) {
|
||||
throw new RuntimeException(sprintf('A service ("%s") can use either the old or the new factory syntax, not both.', $id));
|
||||
}
|
||||
|
||||
// non-synthetic, non-abstract service has class
|
||||
if (!$definition->isAbstract() && !$definition->isSynthetic() && !$definition->getClass()) {
|
||||
if ($definition->getFactory() || $definition->getFactoryClass(false) || $definition->getFactoryService(false)) {
|
||||
if ($definition->getFactory()) {
|
||||
throw new RuntimeException(sprintf('Please add the class to service "%s" even if it is constructed by a factory since we might need to add method calls based on compile-time checks.', $id));
|
||||
}
|
||||
if (class_exists($id) || interface_exists($id, false)) {
|
||||
if (0 === strpos($id, '\\') && 1 < substr_count($id, '\\')) {
|
||||
throw new RuntimeException(sprintf(
|
||||
'The definition for "%s" has no class attribute, and appears to reference a class or interface. '
|
||||
.'Please specify the class attribute explicitly or remove the leading backslash by renaming '
|
||||
.'the service to "%s" to get rid of this error.',
|
||||
$id, substr($id, 1)
|
||||
));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf(
|
||||
'The definition for "%s" has no class attribute, and appears to reference a '
|
||||
.'class or interface in the global namespace. Leaving out the "class" attribute '
|
||||
.'is only allowed for namespaced classes. Please specify the class attribute '
|
||||
.'explicitly to get rid of this error.',
|
||||
$id
|
||||
));
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('The definition for "%s" has no class. If you intend to inject this service dynamically at runtime, please mark it as synthetic=true. If this is an abstract definition solely used by child definitions, please add abstract=true, otherwise specify a class to get rid of this error.', $id));
|
||||
}
|
||||
@@ -77,6 +79,22 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($definition->isPublic() && !$definition->isPrivate()) {
|
||||
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
|
||||
if (null !== $usedEnvs) {
|
||||
throw new EnvParameterException([$resolvedId], null, 'A service name ("%s") cannot contain dynamic values.');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
if ($alias->isPublic() && !$alias->isPrivate()) {
|
||||
$resolvedId = $container->resolveEnvPlaceholders($id, null, $usedEnvs);
|
||||
if (null !== $usedEnvs) {
|
||||
throw new EnvParameterException([$resolvedId], null, 'An alias name ("%s") cannot contain dynamic values.');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,9 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
@@ -22,42 +20,17 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class CheckExceptionOnInvalidReferenceBehaviorPass implements CompilerPassInterface
|
||||
class CheckExceptionOnInvalidReferenceBehaviorPass extends AbstractRecursivePass
|
||||
{
|
||||
private $container;
|
||||
private $sourceId;
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$this->sourceId = $id;
|
||||
$this->processDefinition($definition);
|
||||
if (!$value instanceof Reference) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
}
|
||||
|
||||
private function processDefinition(Definition $definition)
|
||||
{
|
||||
$this->processReferences($definition->getArguments());
|
||||
$this->processReferences($definition->getMethodCalls());
|
||||
$this->processReferences($definition->getProperties());
|
||||
}
|
||||
|
||||
private function processReferences(array $arguments)
|
||||
{
|
||||
foreach ($arguments as $argument) {
|
||||
if (\is_array($argument)) {
|
||||
$this->processReferences($argument);
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$this->processDefinition($argument);
|
||||
} elseif ($argument instanceof Reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $argument->getInvalidBehavior()) {
|
||||
$destId = (string) $argument;
|
||||
|
||||
if (!$this->container->has($destId)) {
|
||||
throw new ServiceNotFoundException($destId, $this->sourceId);
|
||||
}
|
||||
}
|
||||
if (ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE === $value->getInvalidBehavior() && !$this->container->has($id = (string) $value)) {
|
||||
throw new ServiceNotFoundException($id, $this->currentId);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,12 +11,8 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ScopeCrossingInjectionException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ScopeWideningInjectionException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
@@ -24,132 +20,24 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*
|
||||
* The following checks are performed by this pass:
|
||||
* - target definitions are not abstract
|
||||
* - target definitions are of equal or wider scope
|
||||
* - target definitions are in the same scope hierarchy
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class CheckReferenceValidityPass implements CompilerPassInterface
|
||||
class CheckReferenceValidityPass extends AbstractRecursivePass
|
||||
{
|
||||
private $container;
|
||||
private $currentId;
|
||||
private $currentScope;
|
||||
private $currentScopeAncestors;
|
||||
private $currentScopeChildren;
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder to validate References.
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
$this->container = $container;
|
||||
if ($isRoot && $value instanceof Definition && ($value->isSynthetic() || $value->isAbstract())) {
|
||||
return $value;
|
||||
}
|
||||
if ($value instanceof Reference && $this->container->hasDefinition((string) $value)) {
|
||||
$targetDefinition = $this->container->getDefinition((string) $value);
|
||||
|
||||
$children = $this->container->getScopeChildren(false);
|
||||
$ancestors = array();
|
||||
|
||||
$scopes = $this->container->getScopes(false);
|
||||
foreach ($scopes as $name => $parent) {
|
||||
$ancestors[$name] = array($parent);
|
||||
|
||||
while (isset($scopes[$parent])) {
|
||||
$ancestors[$name][] = $parent = $scopes[$parent];
|
||||
if ($targetDefinition->isAbstract()) {
|
||||
throw new RuntimeException(sprintf('The definition "%s" has a reference to an abstract definition "%s". Abstract definitions cannot be the target of references.', $this->currentId, $value));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$this->currentId = $id;
|
||||
$this->currentScope = $scope = $definition->getScope(false);
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER === $scope) {
|
||||
$this->currentScopeChildren = array_keys($scopes);
|
||||
$this->currentScopeAncestors = array();
|
||||
} elseif (ContainerInterface::SCOPE_PROTOTYPE !== $scope) {
|
||||
$this->currentScopeChildren = isset($children[$scope]) ? $children[$scope] : array();
|
||||
$this->currentScopeAncestors = isset($ancestors[$scope]) ? $ancestors[$scope] : array();
|
||||
}
|
||||
|
||||
$this->validateReferences($definition->getArguments());
|
||||
$this->validateReferences($definition->getMethodCalls());
|
||||
$this->validateReferences($definition->getProperties());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates an array of References.
|
||||
*
|
||||
* @param array $arguments An array of Reference objects
|
||||
*
|
||||
* @throws RuntimeException when there is a reference to an abstract definition
|
||||
*/
|
||||
private function validateReferences(array $arguments)
|
||||
{
|
||||
foreach ($arguments as $argument) {
|
||||
if (\is_array($argument)) {
|
||||
$this->validateReferences($argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$targetDefinition = $this->getDefinition((string) $argument);
|
||||
|
||||
if (null !== $targetDefinition && $targetDefinition->isAbstract()) {
|
||||
throw new RuntimeException(sprintf('The definition "%s" has a reference to an abstract definition "%s". Abstract definitions cannot be the target of references.', $this->currentId, $argument));
|
||||
}
|
||||
|
||||
$this->validateScope($argument, $targetDefinition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the scope of a single Reference.
|
||||
*
|
||||
* @throws ScopeWideningInjectionException when the definition references a service of a narrower scope
|
||||
* @throws ScopeCrossingInjectionException when the definition references a service of another scope hierarchy
|
||||
*/
|
||||
private function validateScope(Reference $reference, Definition $definition = null)
|
||||
{
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $this->currentScope) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!$reference->isStrict(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (null === $definition) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->currentScope === $scope = $definition->getScope(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$id = (string) $reference;
|
||||
|
||||
if (\in_array($scope, $this->currentScopeChildren, true)) {
|
||||
throw new ScopeWideningInjectionException($this->currentId, $this->currentScope, $id, $scope);
|
||||
}
|
||||
|
||||
if (!\in_array($scope, $this->currentScopeAncestors, true)) {
|
||||
throw new ScopeCrossingInjectionException($this->currentId, $this->currentScope, $id, $scope);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Definition given an id.
|
||||
*
|
||||
* @param string $id Definition identifier
|
||||
*
|
||||
* @return Definition
|
||||
*/
|
||||
private function getDefinition($id)
|
||||
{
|
||||
if (!$this->container->hasDefinition($id)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->container->getDefinition($id);
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\EnvParameterException;
|
||||
|
||||
/**
|
||||
* This class is used to remove circular dependencies between individual passes.
|
||||
@@ -21,7 +22,7 @@ use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
class Compiler
|
||||
{
|
||||
private $passConfig;
|
||||
private $log = array();
|
||||
private $log = [];
|
||||
private $loggingFormatter;
|
||||
private $serviceReferenceGraph;
|
||||
|
||||
@@ -29,7 +30,6 @@ class Compiler
|
||||
{
|
||||
$this->passConfig = new PassConfig();
|
||||
$this->serviceReferenceGraph = new ServiceReferenceGraph();
|
||||
$this->loggingFormatter = new LoggingFormatter();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -56,9 +56,17 @@ class Compiler
|
||||
* Returns the logging formatter which can be used by compilation passes.
|
||||
*
|
||||
* @return LoggingFormatter
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead.
|
||||
*/
|
||||
public function getLoggingFormatter()
|
||||
{
|
||||
if (null === $this->loggingFormatter) {
|
||||
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$this->loggingFormatter = new LoggingFormatter();
|
||||
}
|
||||
|
||||
return $this->loggingFormatter;
|
||||
}
|
||||
|
||||
@@ -68,21 +76,50 @@ class Compiler
|
||||
* @param CompilerPassInterface $pass A compiler pass
|
||||
* @param string $type The type of the pass
|
||||
*/
|
||||
public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION)
|
||||
public function addPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
|
||||
{
|
||||
$this->passConfig->addPass($pass, $type);
|
||||
if (\func_num_args() >= 3) {
|
||||
$priority = func_get_arg(2);
|
||||
} else {
|
||||
if (__CLASS__ !== \get_class($this)) {
|
||||
$r = new \ReflectionMethod($this, __FUNCTION__);
|
||||
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
||||
@trigger_error(sprintf('Method %s() will have a third `int $priority = 0` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', __METHOD__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
$priority = 0;
|
||||
}
|
||||
|
||||
$this->passConfig->addPass($pass, $type, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a log message.
|
||||
*
|
||||
* @param string $string The log message
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead.
|
||||
*/
|
||||
public function addLogMessage($string)
|
||||
{
|
||||
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
$this->log[] = $string;
|
||||
}
|
||||
|
||||
/**
|
||||
* @final
|
||||
*/
|
||||
public function log(CompilerPassInterface $pass, $message)
|
||||
{
|
||||
if (false !== strpos($message, "\n")) {
|
||||
$message = str_replace("\n", "\n".\get_class($pass).': ', trim($message));
|
||||
}
|
||||
|
||||
$this->log[] = \get_class($pass).': '.$message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the log.
|
||||
*
|
||||
@@ -98,8 +135,31 @@ class Compiler
|
||||
*/
|
||||
public function compile(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($this->passConfig->getPasses() as $pass) {
|
||||
$pass->process($container);
|
||||
try {
|
||||
foreach ($this->passConfig->getPasses() as $pass) {
|
||||
$pass->process($container);
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
$usedEnvs = [];
|
||||
$prev = $e;
|
||||
|
||||
do {
|
||||
$msg = $prev->getMessage();
|
||||
|
||||
if ($msg !== $resolvedMsg = $container->resolveEnvPlaceholders($msg, null, $usedEnvs)) {
|
||||
$r = new \ReflectionProperty($prev, 'message');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($prev, $resolvedMsg);
|
||||
}
|
||||
} while ($prev = $prev->getPrevious());
|
||||
|
||||
if ($usedEnvs) {
|
||||
$e = new EnvParameterException($usedEnvs, $e);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
} finally {
|
||||
$this->getServiceReferenceGraph()->clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,11 +32,11 @@ class DecoratorServicePass implements CompilerPassInterface
|
||||
if (!$decorated = $definition->getDecoratedService()) {
|
||||
continue;
|
||||
}
|
||||
$definitions->insert(array($id, $definition), array($decorated[2], --$order));
|
||||
$definitions->insert([$id, $definition], [$decorated[2], --$order]);
|
||||
}
|
||||
$decoratingDefinitions = [];
|
||||
|
||||
foreach ($definitions as $arr) {
|
||||
list($id, $definition) = $arr;
|
||||
foreach ($definitions as list($id, $definition)) {
|
||||
list($inner, $renamedId) = $definition->getDecoratedService();
|
||||
|
||||
$definition->setDecoratedService(null);
|
||||
@@ -50,19 +50,32 @@ class DecoratorServicePass implements CompilerPassInterface
|
||||
if ($container->hasAlias($inner)) {
|
||||
$alias = $container->getAlias($inner);
|
||||
$public = $alias->isPublic();
|
||||
$container->setAlias($renamedId, new Alias((string) $alias, false));
|
||||
$private = $alias->isPrivate();
|
||||
$container->setAlias($renamedId, new Alias($container->normalizeId($alias), false));
|
||||
} else {
|
||||
$decoratedDefinition = $container->getDefinition($inner);
|
||||
$definition->setTags(array_merge($decoratedDefinition->getTags(), $definition->getTags()));
|
||||
$definition->setAutowiringTypes(array_merge($decoratedDefinition->getAutowiringTypes(), $definition->getAutowiringTypes()));
|
||||
$public = $decoratedDefinition->isPublic();
|
||||
$private = $decoratedDefinition->isPrivate();
|
||||
$decoratedDefinition->setPublic(false);
|
||||
$decoratedDefinition->setTags(array());
|
||||
$decoratedDefinition->setAutowiringTypes(array());
|
||||
$container->setDefinition($renamedId, $decoratedDefinition);
|
||||
$decoratingDefinitions[$inner] = $decoratedDefinition;
|
||||
}
|
||||
|
||||
$container->setAlias($inner, new Alias($id, $public));
|
||||
if (isset($decoratingDefinitions[$inner])) {
|
||||
$decoratingDefinition = $decoratingDefinitions[$inner];
|
||||
$definition->setTags(array_merge($decoratingDefinition->getTags(), $definition->getTags()));
|
||||
$autowiringTypes = $decoratingDefinition->getAutowiringTypes(false);
|
||||
if ($types = array_merge($autowiringTypes, $definition->getAutowiringTypes(false))) {
|
||||
$definition->setAutowiringTypes($types);
|
||||
}
|
||||
$decoratingDefinition->setTags([]);
|
||||
if ($autowiringTypes) {
|
||||
$decoratingDefinition->setAutowiringTypes([]);
|
||||
}
|
||||
$decoratingDefinitions[$inner] = $definition;
|
||||
}
|
||||
|
||||
$container->setAlias($inner, $id)->setPublic($public)->setPrivate($private);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
39
vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php
vendored
Normal file
39
vendor/symfony/dependency-injection/Compiler/DefinitionErrorExceptionPass.php
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Throws an exception for any Definitions that have errors and still exist.
|
||||
*
|
||||
* @author Ryan Weaver <ryan@knpuniversity.com>
|
||||
*/
|
||||
class DefinitionErrorExceptionPass extends AbstractRecursivePass
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition || empty($value->getErrors())) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
// only show the first error so the user can focus on it
|
||||
$errors = $value->getErrors();
|
||||
$message = reset($errors);
|
||||
|
||||
throw new RuntimeException($message);
|
||||
}
|
||||
}
|
||||
112
vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php
vendored
Normal file
112
vendor/symfony/dependency-injection/Compiler/FactoryReturnTypePass.php
vendored
Normal file
@@ -0,0 +1,112 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* @author Guilhem N. <egetick@gmail.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
class FactoryReturnTypePass implements CompilerPassInterface
|
||||
{
|
||||
private $resolveClassPass;
|
||||
|
||||
public function __construct(ResolveClassPass $resolveClassPass = null)
|
||||
{
|
||||
if (null === $resolveClassPass) {
|
||||
@trigger_error('The '.__CLASS__.' class is deprecated since Symfony 3.3 and will be removed in 4.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
$this->resolveClassPass = $resolveClassPass;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
// works only since php 7.0 and hhvm 3.11
|
||||
if (!method_exists(\ReflectionMethod::class, 'getReturnType')) {
|
||||
return;
|
||||
}
|
||||
$resolveClassPassChanges = null !== $this->resolveClassPass ? $this->resolveClassPass->getChanges() : [];
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$this->updateDefinition($container, $id, $definition, $resolveClassPassChanges);
|
||||
}
|
||||
}
|
||||
|
||||
private function updateDefinition(ContainerBuilder $container, $id, Definition $definition, array $resolveClassPassChanges, array $previous = [])
|
||||
{
|
||||
// circular reference
|
||||
if (isset($previous[$id])) {
|
||||
return;
|
||||
}
|
||||
|
||||
$factory = $definition->getFactory();
|
||||
if (null === $factory || (!isset($resolveClassPassChanges[$id]) && null !== $definition->getClass())) {
|
||||
return;
|
||||
}
|
||||
|
||||
$class = null;
|
||||
if (\is_string($factory)) {
|
||||
try {
|
||||
$m = new \ReflectionFunction($factory);
|
||||
if (false !== $m->getFileName() && file_exists($m->getFileName())) {
|
||||
$container->fileExists($m->getFileName());
|
||||
}
|
||||
} catch (\ReflectionException $e) {
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
if ($factory[0] instanceof Reference) {
|
||||
$previous[$id] = true;
|
||||
$factoryId = $container->normalizeId($factory[0]);
|
||||
$factoryDefinition = $container->findDefinition($factoryId);
|
||||
$this->updateDefinition($container, $factoryId, $factoryDefinition, $resolveClassPassChanges, $previous);
|
||||
$class = $factoryDefinition->getClass();
|
||||
} else {
|
||||
$class = $factory[0];
|
||||
}
|
||||
|
||||
if (!$m = $container->getReflectionClass($class, false)) {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
$m = $m->getMethod($factory[1]);
|
||||
} catch (\ReflectionException $e) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
$returnType = $m->getReturnType();
|
||||
if (null !== $returnType && !$returnType->isBuiltin()) {
|
||||
$returnType = $returnType instanceof \ReflectionNamedType ? $returnType->getName() : $returnType->__toString();
|
||||
if (null !== $class) {
|
||||
$declaringClass = $m->getDeclaringClass()->getName();
|
||||
if ('self' === strtolower($returnType)) {
|
||||
$returnType = $declaringClass;
|
||||
} elseif ('parent' === strtolower($returnType)) {
|
||||
$returnType = get_parent_class($declaringClass) ?: null;
|
||||
}
|
||||
}
|
||||
|
||||
if (null !== $returnType && (!isset($resolveClassPassChanges[$id]) || $returnType !== $resolveClassPassChanges[$id])) {
|
||||
@trigger_error(sprintf('Relying on its factory\'s return-type to define the class of service "%s" is deprecated since Symfony 3.3 and won\'t work in 4.0. Set the "class" attribute to "%s" on the service definition instead.', $id, $returnType), E_USER_DEPRECATED);
|
||||
}
|
||||
$definition->setClass($returnType);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,9 +11,9 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
@@ -21,12 +21,10 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||
class InlineServiceDefinitionsPass extends AbstractRecursivePass implements RepeatablePassInterface
|
||||
{
|
||||
private $graph;
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
private $currentId;
|
||||
private $cloningIds = [];
|
||||
private $inlinedServiceIds = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
@@ -37,88 +35,90 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder for inline service definitions.
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
$this->graph = $this->compiler->getServiceReferenceGraph();
|
||||
|
||||
$container->setDefinitions($this->inlineArguments($container, $container->getDefinitions(), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes inline arguments.
|
||||
* Returns an array of all services inlined by this pass.
|
||||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param array $arguments An array of arguments
|
||||
* @param bool $isRoot If we are processing the root definitions or not
|
||||
* The key is the inlined service id and its value is the list of services it was inlined into.
|
||||
*
|
||||
* @deprecated since version 3.4, to be removed in 4.0.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function inlineArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
|
||||
public function getInlinedServiceIds()
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if ($isRoot) {
|
||||
$this->currentId = $k;
|
||||
}
|
||||
if (\is_array($argument)) {
|
||||
$arguments[$k] = $this->inlineArguments($container, $argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
if (!$container->hasDefinition($id = (string) $argument)) {
|
||||
continue;
|
||||
}
|
||||
@trigger_error('Calling InlineServiceDefinitionsPass::getInlinedServiceIds() is deprecated since Symfony 3.4 and will be removed in 4.0.', E_USER_DEPRECATED);
|
||||
|
||||
if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
||||
$this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
|
||||
return $this->inlinedServiceIds;
|
||||
}
|
||||
|
||||
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false)) {
|
||||
$arguments[$k] = $definition;
|
||||
} else {
|
||||
$arguments[$k] = clone $definition;
|
||||
}
|
||||
}
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$argument->setArguments($this->inlineArguments($container, $argument->getArguments()));
|
||||
$argument->setMethodCalls($this->inlineArguments($container, $argument->getMethodCalls()));
|
||||
$argument->setProperties($this->inlineArguments($container, $argument->getProperties()));
|
||||
|
||||
$configurator = $this->inlineArguments($container, array($argument->getConfigurator()));
|
||||
$argument->setConfigurator($configurator[0]);
|
||||
|
||||
$factory = $this->inlineArguments($container, array($argument->getFactory()));
|
||||
$argument->setFactory($factory[0]);
|
||||
}
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof ArgumentInterface) {
|
||||
// Reference found in ArgumentInterface::getValues() are not inlineable
|
||||
return $value;
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
if ($value instanceof Definition && $this->cloningIds) {
|
||||
if ($value->isShared()) {
|
||||
return $value;
|
||||
}
|
||||
$value = clone $value;
|
||||
}
|
||||
|
||||
if (!$value instanceof Reference || !$this->container->hasDefinition($id = $this->container->normalizeId($value))) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$definition = $this->container->getDefinition($id);
|
||||
|
||||
if (!$this->isInlineableDefinition($id, $definition, $this->container->getCompiler()->getServiceReferenceGraph())) {
|
||||
return $value;
|
||||
}
|
||||
|
||||
$this->container->log($this, sprintf('Inlined service "%s" to "%s".', $id, $this->currentId));
|
||||
$this->inlinedServiceIds[$id][] = $this->currentId;
|
||||
|
||||
if ($definition->isShared()) {
|
||||
return $definition;
|
||||
}
|
||||
|
||||
if (isset($this->cloningIds[$id])) {
|
||||
$ids = array_keys($this->cloningIds);
|
||||
$ids[] = $id;
|
||||
|
||||
throw new ServiceCircularReferenceException($id, \array_slice($ids, array_search($id, $ids)));
|
||||
}
|
||||
|
||||
$this->cloningIds[$id] = true;
|
||||
try {
|
||||
return $this->processValue($definition);
|
||||
} finally {
|
||||
unset($this->cloningIds[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the definition is inlineable.
|
||||
*
|
||||
* @param ContainerBuilder $container
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return bool If the definition is inlineable
|
||||
*/
|
||||
private function isInlineableDefinition(ContainerBuilder $container, $id, Definition $definition)
|
||||
private function isInlineableDefinition($id, Definition $definition, ServiceReferenceGraph $graph)
|
||||
{
|
||||
if ($definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic()) {
|
||||
if ($definition->getErrors() || $definition->isDeprecated() || $definition->isLazy() || $definition->isSynthetic()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$definition->isShared() || ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
|
||||
if (!$definition->isShared()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ($definition->isPublic()) {
|
||||
if ($definition->isPublic() || $definition->isPrivate()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$this->graph->hasNode($id)) {
|
||||
if (!$graph->hasNode($id)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -126,11 +126,20 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
$ids = array();
|
||||
foreach ($this->graph->getNode($id)->getInEdges() as $edge) {
|
||||
$ids = [];
|
||||
$isReferencedByConstructor = false;
|
||||
foreach ($graph->getNode($id)->getInEdges() as $edge) {
|
||||
$isReferencedByConstructor = $isReferencedByConstructor || $edge->isReferencedByConstructor();
|
||||
if ($edge->isWeak() || $edge->isLazy()) {
|
||||
return false;
|
||||
}
|
||||
$ids[] = $edge->getSourceNode()->getId();
|
||||
}
|
||||
|
||||
if (!$ids) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (\count(array_unique($ids)) > 1) {
|
||||
return false;
|
||||
}
|
||||
@@ -139,10 +148,6 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
||||
return false;
|
||||
}
|
||||
|
||||
if (\count($ids) > 1 && $definition->getFactoryService(false)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return $container->getDefinition(reset($ids))->getScope(false) === $definition->getScope(false);
|
||||
return $this->container->getDefinition($ids[0])->isShared();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,10 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\LoggingFormatter class is deprecated since Symfony 3.3 and will be removed in 4.0. Use the ContainerBuilder::log() method instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* Used to format logging messages during the compilation.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0. Use the ContainerBuilder::log() method instead.
|
||||
*/
|
||||
class LoggingFormatter
|
||||
{
|
||||
@@ -38,6 +42,11 @@ class LoggingFormatter
|
||||
return $this->format($pass, sprintf('Resolving inheritance for "%s" (parent: %s).', $childId, $parentId));
|
||||
}
|
||||
|
||||
public function formatUnusedAutowiringPatterns(CompilerPassInterface $pass, $id, array $patterns)
|
||||
{
|
||||
return $this->format($pass, sprintf('Autowiring\'s patterns "%s" for service "%s" don\'t match any method.', implode('", "', $patterns), $id));
|
||||
}
|
||||
|
||||
public function format(CompilerPassInterface $pass, $message)
|
||||
{
|
||||
return sprintf('%s: %s', \get_class($pass), $message);
|
||||
|
||||
@@ -12,8 +12,14 @@
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\Extension\Extension;
|
||||
use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
|
||||
/**
|
||||
* Merges extension configs into the container builder.
|
||||
@@ -43,21 +49,39 @@ class MergeExtensionConfigurationPass implements CompilerPassInterface
|
||||
// this extension was not called
|
||||
continue;
|
||||
}
|
||||
$config = $container->getParameterBag()->resolveValue($config);
|
||||
$resolvingBag = $container->getParameterBag();
|
||||
if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) {
|
||||
// create a dedicated bag so that we can track env vars per-extension
|
||||
$resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag);
|
||||
}
|
||||
$config = $resolvingBag->resolveValue($config);
|
||||
|
||||
$tmpContainer = new ContainerBuilder($container->getParameterBag());
|
||||
$tmpContainer->setResourceTracking($container->isTrackingResources());
|
||||
$tmpContainer->addObjectResource($extension);
|
||||
if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
|
||||
$tmpContainer->addObjectResource($configuration);
|
||||
try {
|
||||
$tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag);
|
||||
$tmpContainer->setResourceTracking($container->isTrackingResources());
|
||||
$tmpContainer->addObjectResource($extension);
|
||||
if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
|
||||
$tmpContainer->addObjectResource($configuration);
|
||||
}
|
||||
|
||||
foreach ($exprLangProviders as $provider) {
|
||||
$tmpContainer->addExpressionLanguageProvider($provider);
|
||||
}
|
||||
|
||||
$extension->load($config, $tmpContainer);
|
||||
} catch (\Exception $e) {
|
||||
if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
|
||||
$container->getParameterBag()->mergeEnvPlaceholders($resolvingBag);
|
||||
}
|
||||
|
||||
throw $e;
|
||||
}
|
||||
|
||||
foreach ($exprLangProviders as $provider) {
|
||||
$tmpContainer->addExpressionLanguageProvider($provider);
|
||||
if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
|
||||
// don't keep track of env vars that are *overridden* when configs are merged
|
||||
$resolvingBag->freezeAfterProcessing($extension, $tmpContainer);
|
||||
}
|
||||
|
||||
$extension->load($config, $tmpContainer);
|
||||
|
||||
$container->merge($tmpContainer);
|
||||
$container->getParameterBag()->add($parameters);
|
||||
}
|
||||
@@ -66,3 +90,117 @@ class MergeExtensionConfigurationPass implements CompilerPassInterface
|
||||
$container->addAliases($aliases);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag
|
||||
{
|
||||
private $processedEnvPlaceholders;
|
||||
|
||||
public function __construct(parent $parameterBag)
|
||||
{
|
||||
parent::__construct($parameterBag->all());
|
||||
$this->mergeEnvPlaceholders($parameterBag);
|
||||
}
|
||||
|
||||
public function freezeAfterProcessing(Extension $extension, ContainerBuilder $container)
|
||||
{
|
||||
if (!$config = $extension->getProcessedConfigs()) {
|
||||
// Extension::processConfiguration() wasn't called, we cannot know how configs were merged
|
||||
return;
|
||||
}
|
||||
$this->processedEnvPlaceholders = [];
|
||||
|
||||
// serialize config and container to catch env vars nested in object graphs
|
||||
$config = serialize($config).serialize($container->getDefinitions()).serialize($container->getAliases()).serialize($container->getParameterBag()->all());
|
||||
|
||||
foreach (parent::getEnvPlaceholders() as $env => $placeholders) {
|
||||
foreach ($placeholders as $placeholder) {
|
||||
if (false !== stripos($config, $placeholder)) {
|
||||
$this->processedEnvPlaceholders[$env] = $placeholders;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEnvPlaceholders()
|
||||
{
|
||||
return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A container builder preventing using methods that wouldn't have any effect from extensions.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder
|
||||
{
|
||||
private $extensionClass;
|
||||
|
||||
public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null)
|
||||
{
|
||||
parent::__construct($parameterBag);
|
||||
|
||||
$this->extensionClass = \get_class($extension);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
|
||||
{
|
||||
throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', \get_class($pass), $this->extensionClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function registerExtension(ExtensionInterface $extension)
|
||||
{
|
||||
throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', \get_class($extension), $this->extensionClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function compile($resolveEnvPlaceholders = false)
|
||||
{
|
||||
throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass));
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null)
|
||||
{
|
||||
if (true !== $format || !\is_string($value)) {
|
||||
return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
|
||||
}
|
||||
|
||||
$bag = $this->getParameterBag();
|
||||
$value = $bag->resolveValue($value);
|
||||
|
||||
if (!$bag instanceof EnvPlaceholderParameterBag) {
|
||||
return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
|
||||
}
|
||||
|
||||
foreach ($bag->getEnvPlaceholders() as $env => $placeholders) {
|
||||
if (false === strpos($env, ':')) {
|
||||
continue;
|
||||
}
|
||||
foreach ($placeholders as $placeholder) {
|
||||
if (false !== stripos($value, $placeholder)) {
|
||||
throw new RuntimeException(sprintf('Using a cast in "env(%s)" is incompatible with resolution at compile time in "%s". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.', $env, $this->extensionClass));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,9 +29,9 @@ class PassConfig
|
||||
const TYPE_REMOVE = 'removing';
|
||||
|
||||
private $mergePass;
|
||||
private $afterRemovingPasses = array();
|
||||
private $beforeOptimizationPasses = array();
|
||||
private $beforeRemovingPasses = array();
|
||||
private $afterRemovingPasses = [];
|
||||
private $beforeOptimizationPasses = [];
|
||||
private $beforeRemovingPasses = [];
|
||||
private $optimizationPasses;
|
||||
private $removingPasses;
|
||||
|
||||
@@ -39,48 +39,74 @@ class PassConfig
|
||||
{
|
||||
$this->mergePass = new MergeExtensionConfigurationPass();
|
||||
|
||||
$this->optimizationPasses = array(
|
||||
new ExtensionCompilerPass(),
|
||||
new ResolveDefinitionTemplatesPass(),
|
||||
$this->beforeOptimizationPasses = [
|
||||
100 => [
|
||||
$resolveClassPass = new ResolveClassPass(),
|
||||
new ResolveInstanceofConditionalsPass(),
|
||||
new RegisterEnvVarProcessorsPass(),
|
||||
],
|
||||
-1000 => [new ExtensionCompilerPass()],
|
||||
];
|
||||
|
||||
$this->optimizationPasses = [[
|
||||
new ResolveChildDefinitionsPass(),
|
||||
new ServiceLocatorTagPass(),
|
||||
new RegisterServiceSubscribersPass(),
|
||||
new DecoratorServicePass(),
|
||||
new ResolveParameterPlaceHoldersPass(),
|
||||
new ResolveParameterPlaceHoldersPass(false),
|
||||
new ResolveFactoryClassPass(),
|
||||
new FactoryReturnTypePass($resolveClassPass),
|
||||
new CheckDefinitionValidityPass(),
|
||||
new ResolveNamedArgumentsPass(),
|
||||
new AutowireRequiredMethodsPass(),
|
||||
new ResolveBindingsPass(),
|
||||
new AutowirePass(false),
|
||||
new ResolveTaggedIteratorArgumentPass(),
|
||||
new ResolveServiceSubscribersPass(),
|
||||
new ResolveReferencesToAliasesPass(),
|
||||
new ResolveInvalidReferencesPass(),
|
||||
new AutowirePass(),
|
||||
new AnalyzeServiceReferencesPass(true),
|
||||
new CheckCircularReferencesPass(),
|
||||
new CheckReferenceValidityPass(),
|
||||
);
|
||||
new CheckArgumentsValidityPass(false),
|
||||
]];
|
||||
|
||||
$this->removingPasses = array(
|
||||
$this->beforeRemovingPasses = [
|
||||
-100 => [
|
||||
new ResolvePrivatesPass(),
|
||||
],
|
||||
];
|
||||
|
||||
$this->removingPasses = [[
|
||||
new RemovePrivateAliasesPass(),
|
||||
new ReplaceAliasByActualDefinitionPass(),
|
||||
new RemoveAbstractDefinitionsPass(),
|
||||
new RepeatedPass(array(
|
||||
new RepeatedPass([
|
||||
new AnalyzeServiceReferencesPass(),
|
||||
new InlineServiceDefinitionsPass(),
|
||||
new AnalyzeServiceReferencesPass(),
|
||||
new RemoveUnusedDefinitionsPass(),
|
||||
)),
|
||||
]),
|
||||
new DefinitionErrorExceptionPass(),
|
||||
new CheckExceptionOnInvalidReferenceBehaviorPass(),
|
||||
);
|
||||
new ResolveHotPathPass(),
|
||||
]];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all passes in order to be processed.
|
||||
*
|
||||
* @return array An array of all passes to process
|
||||
* @return CompilerPassInterface[]
|
||||
*/
|
||||
public function getPasses()
|
||||
{
|
||||
return array_merge(
|
||||
array($this->mergePass),
|
||||
$this->beforeOptimizationPasses,
|
||||
$this->optimizationPasses,
|
||||
$this->beforeRemovingPasses,
|
||||
$this->removingPasses,
|
||||
$this->afterRemovingPasses
|
||||
[$this->mergePass],
|
||||
$this->getBeforeOptimizationPasses(),
|
||||
$this->getOptimizationPasses(),
|
||||
$this->getBeforeRemovingPasses(),
|
||||
$this->getRemovingPasses(),
|
||||
$this->getAfterRemovingPasses()
|
||||
);
|
||||
}
|
||||
|
||||
@@ -92,70 +118,88 @@ class PassConfig
|
||||
*
|
||||
* @throws InvalidArgumentException when a pass type doesn't exist
|
||||
*/
|
||||
public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION)
|
||||
public function addPass(CompilerPassInterface $pass, $type = self::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
|
||||
{
|
||||
if (\func_num_args() >= 3) {
|
||||
$priority = func_get_arg(2);
|
||||
} else {
|
||||
if (__CLASS__ !== \get_class($this)) {
|
||||
$r = new \ReflectionMethod($this, __FUNCTION__);
|
||||
if (__CLASS__ !== $r->getDeclaringClass()->getName()) {
|
||||
@trigger_error(sprintf('Method %s() will have a third `int $priority = 0` argument in version 4.0. Not defining it is deprecated since Symfony 3.2.', __METHOD__), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
$priority = 0;
|
||||
}
|
||||
|
||||
$property = $type.'Passes';
|
||||
if (!isset($this->$property)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid type "%s".', $type));
|
||||
}
|
||||
|
||||
$this->{$property}[] = $pass;
|
||||
$passes = &$this->$property;
|
||||
|
||||
if (!isset($passes[$priority])) {
|
||||
$passes[$priority] = [];
|
||||
}
|
||||
$passes[$priority][] = $pass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the AfterRemoving pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
* @return CompilerPassInterface[]
|
||||
*/
|
||||
public function getAfterRemovingPasses()
|
||||
{
|
||||
return $this->afterRemovingPasses;
|
||||
return $this->sortPasses($this->afterRemovingPasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the BeforeOptimization pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
* @return CompilerPassInterface[]
|
||||
*/
|
||||
public function getBeforeOptimizationPasses()
|
||||
{
|
||||
return $this->beforeOptimizationPasses;
|
||||
return $this->sortPasses($this->beforeOptimizationPasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the BeforeRemoving pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
* @return CompilerPassInterface[]
|
||||
*/
|
||||
public function getBeforeRemovingPasses()
|
||||
{
|
||||
return $this->beforeRemovingPasses;
|
||||
return $this->sortPasses($this->beforeRemovingPasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the Optimization pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
* @return CompilerPassInterface[]
|
||||
*/
|
||||
public function getOptimizationPasses()
|
||||
{
|
||||
return $this->optimizationPasses;
|
||||
return $this->sortPasses($this->optimizationPasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all passes for the Removing pass.
|
||||
*
|
||||
* @return array An array of passes
|
||||
* @return CompilerPassInterface[]
|
||||
*/
|
||||
public function getRemovingPasses()
|
||||
{
|
||||
return $this->removingPasses;
|
||||
return $this->sortPasses($this->removingPasses);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the Merge pass.
|
||||
*
|
||||
* @return CompilerPassInterface The merge pass
|
||||
* @return CompilerPassInterface
|
||||
*/
|
||||
public function getMergePass()
|
||||
{
|
||||
@@ -170,50 +214,69 @@ class PassConfig
|
||||
/**
|
||||
* Sets the AfterRemoving passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
* @param CompilerPassInterface[] $passes
|
||||
*/
|
||||
public function setAfterRemovingPasses(array $passes)
|
||||
{
|
||||
$this->afterRemovingPasses = $passes;
|
||||
$this->afterRemovingPasses = [$passes];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the BeforeOptimization passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
* @param CompilerPassInterface[] $passes
|
||||
*/
|
||||
public function setBeforeOptimizationPasses(array $passes)
|
||||
{
|
||||
$this->beforeOptimizationPasses = $passes;
|
||||
$this->beforeOptimizationPasses = [$passes];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the BeforeRemoving passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
* @param CompilerPassInterface[] $passes
|
||||
*/
|
||||
public function setBeforeRemovingPasses(array $passes)
|
||||
{
|
||||
$this->beforeRemovingPasses = $passes;
|
||||
$this->beforeRemovingPasses = [$passes];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Optimization passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
* @param CompilerPassInterface[] $passes
|
||||
*/
|
||||
public function setOptimizationPasses(array $passes)
|
||||
{
|
||||
$this->optimizationPasses = $passes;
|
||||
$this->optimizationPasses = [$passes];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the Removing passes.
|
||||
*
|
||||
* @param array $passes An array of passes
|
||||
* @param CompilerPassInterface[] $passes
|
||||
*/
|
||||
public function setRemovingPasses(array $passes)
|
||||
{
|
||||
$this->removingPasses = $passes;
|
||||
$this->removingPasses = [$passes];
|
||||
}
|
||||
|
||||
/**
|
||||
* Sort passes by priority.
|
||||
*
|
||||
* @param array $passes CompilerPassInterface instances with their priority as key
|
||||
*
|
||||
* @return CompilerPassInterface[]
|
||||
*/
|
||||
private function sortPasses(array $passes)
|
||||
{
|
||||
if (0 === \count($passes)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
krsort($passes);
|
||||
|
||||
// Flatten the array
|
||||
return \call_user_func_array('array_merge', $passes);
|
||||
}
|
||||
}
|
||||
|
||||
54
vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php
vendored
Normal file
54
vendor/symfony/dependency-injection/Compiler/PriorityTaggedServiceTrait.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Trait that allows a generic method to find and sort service by priority option in the tag.
|
||||
*
|
||||
* @author Iltar van der Berg <kjarli@gmail.com>
|
||||
*/
|
||||
trait PriorityTaggedServiceTrait
|
||||
{
|
||||
/**
|
||||
* Finds all services with the given tag name and order them by their priority.
|
||||
*
|
||||
* The order of additions must be respected for services having the same priority,
|
||||
* and knowing that the \SplPriorityQueue class does not respect the FIFO method,
|
||||
* we should not use that class.
|
||||
*
|
||||
* @see https://bugs.php.net/53710
|
||||
* @see https://bugs.php.net/60926
|
||||
*
|
||||
* @param string $tagName
|
||||
*
|
||||
* @return Reference[]
|
||||
*/
|
||||
private function findAndSortTaggedServices($tagName, ContainerBuilder $container)
|
||||
{
|
||||
$services = [];
|
||||
|
||||
foreach ($container->findTaggedServiceIds($tagName, true) as $serviceId => $attributes) {
|
||||
$priority = isset($attributes[0]['priority']) ? $attributes[0]['priority'] : 0;
|
||||
$services[$priority][] = new Reference($serviceId);
|
||||
}
|
||||
|
||||
if ($services) {
|
||||
krsort($services);
|
||||
$services = \call_user_func_array('array_merge', $services);
|
||||
}
|
||||
|
||||
return $services;
|
||||
}
|
||||
}
|
||||
78
vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php
vendored
Normal file
78
vendor/symfony/dependency-injection/Compiler/RegisterEnvVarProcessorsPass.php
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\EnvVarProcessor;
|
||||
use Symfony\Component\DependencyInjection\EnvVarProcessorInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||
|
||||
/**
|
||||
* Creates the container.env_var_processors_locator service.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class RegisterEnvVarProcessorsPass implements CompilerPassInterface
|
||||
{
|
||||
private static $allowedTypes = ['array', 'bool', 'float', 'int', 'string'];
|
||||
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$bag = $container->getParameterBag();
|
||||
$types = [];
|
||||
$processors = [];
|
||||
foreach ($container->findTaggedServiceIds('container.env_var_processor') as $id => $tags) {
|
||||
if (!$r = $container->getReflectionClass($class = $container->getDefinition($id)->getClass())) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $id));
|
||||
} elseif (!$r->isSubclassOf(EnvVarProcessorInterface::class)) {
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $id, EnvVarProcessorInterface::class));
|
||||
}
|
||||
foreach ($class::getProvidedTypes() as $prefix => $type) {
|
||||
$processors[$prefix] = new ServiceClosureArgument(new Reference($id));
|
||||
$types[$prefix] = self::validateProvidedTypes($type, $class);
|
||||
}
|
||||
}
|
||||
|
||||
if ($bag instanceof EnvPlaceholderParameterBag) {
|
||||
foreach (EnvVarProcessor::getProvidedTypes() as $prefix => $type) {
|
||||
if (!isset($types[$prefix])) {
|
||||
$types[$prefix] = self::validateProvidedTypes($type, EnvVarProcessor::class);
|
||||
}
|
||||
}
|
||||
$bag->setProvidedTypes($types);
|
||||
}
|
||||
|
||||
if ($processors) {
|
||||
$container->register('container.env_var_processors_locator', ServiceLocator::class)
|
||||
->setPublic(true)
|
||||
->setArguments([$processors])
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
private static function validateProvidedTypes($types, $class)
|
||||
{
|
||||
$types = explode('|', $types);
|
||||
|
||||
foreach ($types as $type) {
|
||||
if (!\in_array($type, self::$allowedTypes)) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid type "%s" returned by "%s::getProvidedTypes()", expected one of "%s".', $type, $class, implode('", "', self::$allowedTypes)));
|
||||
}
|
||||
}
|
||||
|
||||
return $types;
|
||||
}
|
||||
}
|
||||
101
vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php
vendored
Normal file
101
vendor/symfony/dependency-injection/Compiler/RegisterServiceSubscribersPass.php
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ServiceSubscriberInterface;
|
||||
use Symfony\Component\DependencyInjection\TypedReference;
|
||||
|
||||
/**
|
||||
* Compiler pass to register tagged services that require a service locator.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class RegisterServiceSubscribersPass extends AbstractRecursivePass
|
||||
{
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition || $value->isAbstract() || $value->isSynthetic() || !$value->hasTag('container.service_subscriber')) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$serviceMap = [];
|
||||
$autowire = $value->isAutowired();
|
||||
|
||||
foreach ($value->getTag('container.service_subscriber') as $attributes) {
|
||||
if (!$attributes) {
|
||||
$autowire = true;
|
||||
continue;
|
||||
}
|
||||
ksort($attributes);
|
||||
if ([] !== array_diff(array_keys($attributes), ['id', 'key'])) {
|
||||
throw new InvalidArgumentException(sprintf('The "container.service_subscriber" tag accepts only the "key" and "id" attributes, "%s" given for service "%s".', implode('", "', array_keys($attributes)), $this->currentId));
|
||||
}
|
||||
if (!\array_key_exists('id', $attributes)) {
|
||||
throw new InvalidArgumentException(sprintf('Missing "id" attribute on "container.service_subscriber" tag with key="%s" for service "%s".', $attributes['key'], $this->currentId));
|
||||
}
|
||||
if (!\array_key_exists('key', $attributes)) {
|
||||
$attributes['key'] = $attributes['id'];
|
||||
}
|
||||
if (isset($serviceMap[$attributes['key']])) {
|
||||
continue;
|
||||
}
|
||||
$serviceMap[$attributes['key']] = new Reference($attributes['id']);
|
||||
}
|
||||
$class = $value->getClass();
|
||||
|
||||
if (!$r = $this->container->getReflectionClass($class)) {
|
||||
throw new InvalidArgumentException(sprintf('Class "%s" used for service "%s" cannot be found.', $class, $this->currentId));
|
||||
}
|
||||
if (!$r->isSubclassOf(ServiceSubscriberInterface::class)) {
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" must implement interface "%s".', $this->currentId, ServiceSubscriberInterface::class));
|
||||
}
|
||||
$class = $r->name;
|
||||
|
||||
$subscriberMap = [];
|
||||
$declaringClass = (new \ReflectionMethod($class, 'getSubscribedServices'))->class;
|
||||
|
||||
foreach ($class::getSubscribedServices() as $key => $type) {
|
||||
if (!\is_string($type) || !preg_match('/^\??[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)*+$/', $type)) {
|
||||
throw new InvalidArgumentException(sprintf('"%s::getSubscribedServices()" must return valid PHP types for service "%s" key "%s", "%s" returned.', $class, $this->currentId, $key, \is_string($type) ? $type : \gettype($type)));
|
||||
}
|
||||
if ($optionalBehavior = '?' === $type[0]) {
|
||||
$type = substr($type, 1);
|
||||
$optionalBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
|
||||
}
|
||||
if (\is_int($key)) {
|
||||
$key = $type;
|
||||
}
|
||||
if (!isset($serviceMap[$key])) {
|
||||
if (!$autowire) {
|
||||
throw new InvalidArgumentException(sprintf('Service "%s" misses a "container.service_subscriber" tag with "key"/"id" attributes corresponding to entry "%s" as returned by "%s::getSubscribedServices()".', $this->currentId, $key, $class));
|
||||
}
|
||||
$serviceMap[$key] = new Reference($type);
|
||||
}
|
||||
|
||||
$subscriberMap[$key] = new TypedReference($this->container->normalizeId($serviceMap[$key]), $type, $declaringClass, $optionalBehavior ?: ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE);
|
||||
unset($serviceMap[$key]);
|
||||
}
|
||||
|
||||
if ($serviceMap = array_keys($serviceMap)) {
|
||||
$message = sprintf(1 < \count($serviceMap) ? 'keys "%s" do' : 'key "%s" does', str_replace('%', '%%', implode('", "', $serviceMap)));
|
||||
throw new InvalidArgumentException(sprintf('Service %s not exist in the map returned by "%s::getSubscribedServices()" for service "%s".', $message, $class, $this->currentId));
|
||||
}
|
||||
|
||||
$value->addTag('container.service_subscriber.locator', ['id' => (string) ServiceLocatorTagPass::register($this->container, $subscriberMap, $this->currentId)]);
|
||||
|
||||
return parent::processValue($value);
|
||||
}
|
||||
}
|
||||
@@ -23,13 +23,10 @@ class RemoveAbstractDefinitionsPass implements CompilerPassInterface
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$compiler = $container->getCompiler();
|
||||
$formatter = $compiler->getLoggingFormatter();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isAbstract()) {
|
||||
$container->removeDefinition($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'abstract'));
|
||||
$container->log($this, sprintf('Removed service "%s"; reason: abstract.', $id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,16 +27,13 @@ class RemovePrivateAliasesPass implements CompilerPassInterface
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$compiler = $container->getCompiler();
|
||||
$formatter = $compiler->getLoggingFormatter();
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
if ($alias->isPublic()) {
|
||||
if ($alias->isPublic() || $alias->isPrivate()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$container->removeAlias($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'private alias'));
|
||||
$container->log($this, sprintf('Removed service "%s"; reason: private alias.', $id));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -35,21 +35,22 @@ class RemoveUnusedDefinitionsPass implements RepeatablePassInterface
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$compiler = $container->getCompiler();
|
||||
$formatter = $compiler->getLoggingFormatter();
|
||||
$graph = $compiler->getServiceReferenceGraph();
|
||||
$graph = $container->getCompiler()->getServiceReferenceGraph();
|
||||
|
||||
$hasChanged = false;
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isPublic()) {
|
||||
if ($definition->isPublic() || $definition->isPrivate()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($graph->hasNode($id)) {
|
||||
$edges = $graph->getNode($id)->getInEdges();
|
||||
$referencingAliases = array();
|
||||
$sourceIds = array();
|
||||
$referencingAliases = [];
|
||||
$sourceIds = [];
|
||||
foreach ($edges as $edge) {
|
||||
if ($edge->isWeak()) {
|
||||
continue;
|
||||
}
|
||||
$node = $edge->getSourceNode();
|
||||
$sourceIds[] = $node->getId();
|
||||
|
||||
@@ -59,18 +60,20 @@ class RemoveUnusedDefinitionsPass implements RepeatablePassInterface
|
||||
}
|
||||
$isReferenced = (\count(array_unique($sourceIds)) - \count($referencingAliases)) > 0;
|
||||
} else {
|
||||
$referencingAliases = array();
|
||||
$referencingAliases = [];
|
||||
$isReferenced = false;
|
||||
}
|
||||
|
||||
if (1 === \count($referencingAliases) && false === $isReferenced) {
|
||||
$container->setDefinition((string) reset($referencingAliases), $definition);
|
||||
$definition->setPublic(true);
|
||||
$definition->setPublic(!$definition->isPrivate());
|
||||
$definition->setPrivate(reset($referencingAliases)->isPrivate());
|
||||
$container->removeDefinition($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'replaces alias '.reset($referencingAliases)));
|
||||
$container->log($this, sprintf('Removed service "%s"; reason: replaces alias %s.', $id, reset($referencingAliases)));
|
||||
} elseif (0 === \count($referencingAliases) && false === $isReferenced) {
|
||||
$container->removeDefinition($id);
|
||||
$compiler->addLogMessage($formatter->formatRemoveService($this, $id, 'unused'));
|
||||
$container->resolveEnvPlaceholders(serialize($definition));
|
||||
$container->log($this, sprintf('Removed service "%s"; reason: unused.', $id));
|
||||
$hasChanged = true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,10 +21,9 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
|
||||
class ReplaceAliasByActualDefinitionPass extends AbstractRecursivePass
|
||||
{
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
private $replacements;
|
||||
|
||||
/**
|
||||
* Process the Container to replace aliases with service definitions.
|
||||
@@ -33,21 +32,18 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
// Setup
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
// First collect all alias targets that need to be replaced
|
||||
$seenAliasTargets = array();
|
||||
$replacements = array();
|
||||
$seenAliasTargets = [];
|
||||
$replacements = [];
|
||||
foreach ($container->getAliases() as $definitionId => $target) {
|
||||
$targetId = (string) $target;
|
||||
$targetId = $container->normalizeId($target);
|
||||
// Special case: leave this target alone
|
||||
if ('service_container' === $targetId) {
|
||||
continue;
|
||||
}
|
||||
// Check if target needs to be replaces
|
||||
if (isset($replacements[$targetId])) {
|
||||
$container->setAlias($definitionId, $replacements[$targetId]);
|
||||
$container->setAlias($definitionId, $replacements[$targetId])->setPublic($target->isPublic())->setPrivate($target->isPrivate());
|
||||
}
|
||||
// No need to process the same target twice
|
||||
if (isset($seenAliasTargets[$targetId])) {
|
||||
@@ -60,83 +56,34 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $definitionId, $targetId), null, $e);
|
||||
}
|
||||
if ($definition->isPublic()) {
|
||||
if ($definition->isPublic() || $definition->isPrivate()) {
|
||||
continue;
|
||||
}
|
||||
// Remove private definition and schedule for replacement
|
||||
$definition->setPublic(true);
|
||||
$definition->setPublic(!$target->isPrivate());
|
||||
$definition->setPrivate($target->isPrivate());
|
||||
$container->setDefinition($definitionId, $definition);
|
||||
$container->removeDefinition($targetId);
|
||||
$replacements[$targetId] = $definitionId;
|
||||
}
|
||||
$this->replacements = $replacements;
|
||||
|
||||
// Now replace target instances in all definitions
|
||||
foreach ($container->getDefinitions() as $definitionId => $definition) {
|
||||
$definition->setArguments($this->updateArgumentReferences($replacements, $definitionId, $definition->getArguments()));
|
||||
$definition->setMethodCalls($this->updateArgumentReferences($replacements, $definitionId, $definition->getMethodCalls()));
|
||||
$definition->setProperties($this->updateArgumentReferences($replacements, $definitionId, $definition->getProperties()));
|
||||
$definition->setFactoryService($this->updateFactoryReferenceId($replacements, $definition->getFactoryService(false)), false);
|
||||
$definition->setFactory($this->updateFactoryReference($replacements, $definition->getFactory()));
|
||||
}
|
||||
parent::process($container);
|
||||
$this->replacements = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively updates references in an array.
|
||||
*
|
||||
* @param array $replacements Table of aliases to replace
|
||||
* @param string $definitionId Identifier of this definition
|
||||
* @param array $arguments Where to replace the aliases
|
||||
*
|
||||
* @return array
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
private function updateArgumentReferences(array $replacements, $definitionId, array $arguments)
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
// Handle recursion step
|
||||
if (\is_array($argument)) {
|
||||
$arguments[$k] = $this->updateArgumentReferences($replacements, $definitionId, $argument);
|
||||
continue;
|
||||
}
|
||||
// Skip arguments that don't need replacement
|
||||
if (!$argument instanceof Reference) {
|
||||
continue;
|
||||
}
|
||||
$referenceId = (string) $argument;
|
||||
if (!isset($replacements[$referenceId])) {
|
||||
continue;
|
||||
}
|
||||
if ($value instanceof Reference && isset($this->replacements[$referenceId = $this->container->normalizeId($value)])) {
|
||||
// Perform the replacement
|
||||
$newId = $replacements[$referenceId];
|
||||
$arguments[$k] = new Reference($newId, $argument->getInvalidBehavior());
|
||||
$this->compiler->addLogMessage($this->formatter->formatUpdateReference($this, $definitionId, $referenceId, $newId));
|
||||
$newId = $this->replacements[$referenceId];
|
||||
$value = new Reference($newId, $value->getInvalidBehavior());
|
||||
$this->container->log($this, sprintf('Changed reference of service "%s" previously pointing to "%s" to "%s".', $this->currentId, $referenceId, $newId));
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the updated reference for the factory service.
|
||||
*
|
||||
* @param array $replacements Table of aliases to replace
|
||||
* @param string|null $referenceId Factory service reference identifier
|
||||
*
|
||||
* @return string|null
|
||||
*/
|
||||
private function updateFactoryReferenceId(array $replacements, $referenceId)
|
||||
{
|
||||
if (null === $referenceId) {
|
||||
return;
|
||||
}
|
||||
|
||||
return isset($replacements[$referenceId]) ? $replacements[$referenceId] : $referenceId;
|
||||
}
|
||||
|
||||
private function updateFactoryReference(array $replacements, $factory)
|
||||
{
|
||||
if (\is_array($factory) && $factory[0] instanceof Reference && isset($replacements[$referenceId = (string) $factory[0]])) {
|
||||
$factory[0] = new Reference($replacements[$referenceId], $factory[0]->getInvalidBehavior());
|
||||
}
|
||||
|
||||
return $factory;
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
}
|
||||
|
||||
180
vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php
vendored
Normal file
180
vendor/symfony/dependency-injection/Compiler/ResolveBindingsPass.php
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\TypedReference;
|
||||
|
||||
/**
|
||||
* @author Guilhem Niot <guilhem.niot@gmail.com>
|
||||
*/
|
||||
class ResolveBindingsPass extends AbstractRecursivePass
|
||||
{
|
||||
private $usedBindings = [];
|
||||
private $unusedBindings = [];
|
||||
private $errorMessages = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->usedBindings = $container->getRemovedBindingIds();
|
||||
|
||||
try {
|
||||
parent::process($container);
|
||||
|
||||
foreach ($this->unusedBindings as list($key, $serviceId)) {
|
||||
$message = sprintf('Unused binding "%s" in service "%s".', $key, $serviceId);
|
||||
if ($this->errorMessages) {
|
||||
$message .= sprintf("\nCould be related to%s:", 1 < \count($this->errorMessages) ? ' one of' : '');
|
||||
}
|
||||
foreach ($this->errorMessages as $m) {
|
||||
$message .= "\n - ".$m;
|
||||
}
|
||||
throw new InvalidArgumentException($message);
|
||||
}
|
||||
} finally {
|
||||
$this->usedBindings = [];
|
||||
$this->unusedBindings = [];
|
||||
$this->errorMessages = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof TypedReference && $value->getType() === $this->container->normalizeId($value)) {
|
||||
// Already checked
|
||||
$bindings = $this->container->getDefinition($this->currentId)->getBindings();
|
||||
|
||||
if (isset($bindings[$value->getType()])) {
|
||||
return $this->getBindingValue($bindings[$value->getType()]);
|
||||
}
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
if (!$value instanceof Definition || !$bindings = $value->getBindings()) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
foreach ($bindings as $key => $binding) {
|
||||
list($bindingValue, $bindingId, $used) = $binding->getValues();
|
||||
if ($used) {
|
||||
$this->usedBindings[$bindingId] = true;
|
||||
unset($this->unusedBindings[$bindingId]);
|
||||
} elseif (!isset($this->usedBindings[$bindingId])) {
|
||||
$this->unusedBindings[$bindingId] = [$key, $this->currentId];
|
||||
}
|
||||
|
||||
if (isset($key[0]) && '$' === $key[0]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null !== $bindingValue && !$bindingValue instanceof Reference && !$bindingValue instanceof Definition) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid value for binding key "%s" for service "%s": expected null, an instance of %s or an instance of %s, %s given.', $key, $this->currentId, Reference::class, Definition::class, \gettype($bindingValue)));
|
||||
}
|
||||
}
|
||||
|
||||
if ($value->isAbstract()) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$calls = $value->getMethodCalls();
|
||||
|
||||
try {
|
||||
if ($constructor = $this->getConstructor($value, false)) {
|
||||
$calls[] = [$constructor, $value->getArguments()];
|
||||
}
|
||||
} catch (RuntimeException $e) {
|
||||
$this->errorMessages[] = $e->getMessage();
|
||||
$this->container->getDefinition($this->currentId)->addError($e->getMessage());
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
foreach ($calls as $i => $call) {
|
||||
list($method, $arguments) = $call;
|
||||
|
||||
if ($method instanceof \ReflectionFunctionAbstract) {
|
||||
$reflectionMethod = $method;
|
||||
} else {
|
||||
try {
|
||||
$reflectionMethod = $this->getReflectionMethod($value, $method);
|
||||
} catch (RuntimeException $e) {
|
||||
if ($value->getFactory()) {
|
||||
continue;
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($reflectionMethod->getParameters() as $key => $parameter) {
|
||||
if (\array_key_exists($key, $arguments) && '' !== $arguments[$key]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (\array_key_exists('$'.$parameter->name, $bindings)) {
|
||||
$arguments[$key] = $this->getBindingValue($bindings['$'.$parameter->name]);
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
$typeHint = ProxyHelper::getTypeHint($reflectionMethod, $parameter, true);
|
||||
|
||||
if (!isset($bindings[$typeHint])) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$arguments[$key] = $this->getBindingValue($bindings[$typeHint]);
|
||||
}
|
||||
|
||||
if ($arguments !== $call[1]) {
|
||||
ksort($arguments);
|
||||
$calls[$i][1] = $arguments;
|
||||
}
|
||||
}
|
||||
|
||||
if ($constructor) {
|
||||
list(, $arguments) = array_pop($calls);
|
||||
|
||||
if ($arguments !== $value->getArguments()) {
|
||||
$value->setArguments($arguments);
|
||||
}
|
||||
}
|
||||
|
||||
if ($calls !== $value->getMethodCalls()) {
|
||||
$value->setMethodCalls($calls);
|
||||
}
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
private function getBindingValue(BoundArgument $binding)
|
||||
{
|
||||
list($bindingValue, $bindingId) = $binding->getValues();
|
||||
|
||||
$this->usedBindings[$bindingId] = true;
|
||||
unset($this->unusedBindings[$bindingId]);
|
||||
|
||||
return $bindingValue;
|
||||
}
|
||||
}
|
||||
198
vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php
vendored
Normal file
198
vendor/symfony/dependency-injection/Compiler/ResolveChildDefinitionsPass.php
vendored
Normal file
@@ -0,0 +1,198 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ExceptionInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
|
||||
/**
|
||||
* This replaces all ChildDefinition instances with their equivalent fully
|
||||
* merged Definition instance.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveChildDefinitionsPass extends AbstractRecursivePass
|
||||
{
|
||||
private $currentPath;
|
||||
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
if ($isRoot) {
|
||||
// yes, we are specifically fetching the definition from the
|
||||
// container to ensure we are not operating on stale data
|
||||
$value = $this->container->getDefinition($this->currentId);
|
||||
}
|
||||
if ($value instanceof ChildDefinition) {
|
||||
$this->currentPath = [];
|
||||
$value = $this->resolveDefinition($value);
|
||||
if ($isRoot) {
|
||||
$this->container->setDefinition($this->currentId, $value);
|
||||
}
|
||||
}
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the definition.
|
||||
*
|
||||
* @return Definition
|
||||
*
|
||||
* @throws RuntimeException When the definition is invalid
|
||||
*/
|
||||
private function resolveDefinition(ChildDefinition $definition)
|
||||
{
|
||||
try {
|
||||
return $this->doResolveDefinition($definition);
|
||||
} catch (ServiceCircularReferenceException $e) {
|
||||
throw $e;
|
||||
} catch (ExceptionInterface $e) {
|
||||
$r = new \ReflectionProperty($e, 'message');
|
||||
$r->setAccessible(true);
|
||||
$r->setValue($e, sprintf('Service "%s": %s', $this->currentId, $e->getMessage()));
|
||||
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
||||
private function doResolveDefinition(ChildDefinition $definition)
|
||||
{
|
||||
if (!$this->container->has($parent = $definition->getParent())) {
|
||||
throw new RuntimeException(sprintf('Parent definition "%s" does not exist.', $parent));
|
||||
}
|
||||
|
||||
$searchKey = array_search($parent, $this->currentPath);
|
||||
$this->currentPath[] = $parent;
|
||||
|
||||
if (false !== $searchKey) {
|
||||
throw new ServiceCircularReferenceException($parent, \array_slice($this->currentPath, $searchKey));
|
||||
}
|
||||
|
||||
$parentDef = $this->container->findDefinition($parent);
|
||||
if ($parentDef instanceof ChildDefinition) {
|
||||
$id = $this->currentId;
|
||||
$this->currentId = $parent;
|
||||
$parentDef = $this->resolveDefinition($parentDef);
|
||||
$this->container->setDefinition($parent, $parentDef);
|
||||
$this->currentId = $id;
|
||||
}
|
||||
|
||||
$this->container->log($this, sprintf('Resolving inheritance for "%s" (parent: %s).', $this->currentId, $parent));
|
||||
$def = new Definition();
|
||||
|
||||
// merge in parent definition
|
||||
// purposely ignored attributes: abstract, shared, tags, autoconfigured
|
||||
$def->setClass($parentDef->getClass());
|
||||
$def->setArguments($parentDef->getArguments());
|
||||
$def->setMethodCalls($parentDef->getMethodCalls());
|
||||
$def->setProperties($parentDef->getProperties());
|
||||
if ($parentDef->getAutowiringTypes(false)) {
|
||||
$def->setAutowiringTypes($parentDef->getAutowiringTypes(false));
|
||||
}
|
||||
if ($parentDef->isDeprecated()) {
|
||||
$def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%'));
|
||||
}
|
||||
$def->setFactory($parentDef->getFactory());
|
||||
$def->setConfigurator($parentDef->getConfigurator());
|
||||
$def->setFile($parentDef->getFile());
|
||||
$def->setPublic($parentDef->isPublic());
|
||||
$def->setLazy($parentDef->isLazy());
|
||||
$def->setAutowired($parentDef->isAutowired());
|
||||
$def->setChanges($parentDef->getChanges());
|
||||
|
||||
$def->setBindings($definition->getBindings() + $parentDef->getBindings());
|
||||
|
||||
// overwrite with values specified in the decorator
|
||||
$changes = $definition->getChanges();
|
||||
if (isset($changes['class'])) {
|
||||
$def->setClass($definition->getClass());
|
||||
}
|
||||
if (isset($changes['factory'])) {
|
||||
$def->setFactory($definition->getFactory());
|
||||
}
|
||||
if (isset($changes['configurator'])) {
|
||||
$def->setConfigurator($definition->getConfigurator());
|
||||
}
|
||||
if (isset($changes['file'])) {
|
||||
$def->setFile($definition->getFile());
|
||||
}
|
||||
if (isset($changes['public'])) {
|
||||
$def->setPublic($definition->isPublic());
|
||||
} else {
|
||||
$def->setPrivate($definition->isPrivate() || $parentDef->isPrivate());
|
||||
}
|
||||
if (isset($changes['lazy'])) {
|
||||
$def->setLazy($definition->isLazy());
|
||||
}
|
||||
if (isset($changes['deprecated'])) {
|
||||
$def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%'));
|
||||
}
|
||||
if (isset($changes['autowired'])) {
|
||||
$def->setAutowired($definition->isAutowired());
|
||||
}
|
||||
if (isset($changes['shared'])) {
|
||||
$def->setShared($definition->isShared());
|
||||
}
|
||||
if (isset($changes['decorated_service'])) {
|
||||
$decoratedService = $definition->getDecoratedService();
|
||||
if (null === $decoratedService) {
|
||||
$def->setDecoratedService($decoratedService);
|
||||
} else {
|
||||
$def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// merge arguments
|
||||
foreach ($definition->getArguments() as $k => $v) {
|
||||
if (is_numeric($k)) {
|
||||
$def->addArgument($v);
|
||||
} elseif (0 === strpos($k, 'index_')) {
|
||||
$def->replaceArgument((int) substr($k, \strlen('index_')), $v);
|
||||
} else {
|
||||
$def->setArgument($k, $v);
|
||||
}
|
||||
}
|
||||
|
||||
// merge properties
|
||||
foreach ($definition->getProperties() as $k => $v) {
|
||||
$def->setProperty($k, $v);
|
||||
}
|
||||
|
||||
// append method calls
|
||||
if ($calls = $definition->getMethodCalls()) {
|
||||
$def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
|
||||
}
|
||||
|
||||
// merge autowiring types
|
||||
foreach ($definition->getAutowiringTypes(false) as $autowiringType) {
|
||||
$def->addAutowiringType($autowiringType);
|
||||
}
|
||||
|
||||
// these attributes are always taken from the child
|
||||
$def->setAbstract($definition->isAbstract());
|
||||
$def->setTags($definition->getTags());
|
||||
// autoconfigure is never taken from parent (on purpose)
|
||||
// and it's not legal on an instanceof
|
||||
$def->setAutoconfigured($definition->isAutoconfigured());
|
||||
|
||||
return $def;
|
||||
}
|
||||
}
|
||||
|
||||
class_alias(ResolveChildDefinitionsPass::class, ResolveDefinitionTemplatesPass::class);
|
||||
56
vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php
vendored
Normal file
56
vendor/symfony/dependency-injection/Compiler/ResolveClassPass.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveClassPass implements CompilerPassInterface
|
||||
{
|
||||
private $changes = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isSynthetic() || null !== $definition->getClass()) {
|
||||
continue;
|
||||
}
|
||||
if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+(?:\\\\[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+)++$/', $id)) {
|
||||
if ($definition instanceof ChildDefinition && !class_exists($id)) {
|
||||
throw new InvalidArgumentException(sprintf('Service definition "%s" has a parent but no class, and its name looks like a FQCN. Either the class is missing or you want to inherit it from the parent service. To resolve this ambiguity, please rename this service to a non-FQCN (e.g. using dots), or create the missing class.', $id));
|
||||
}
|
||||
$this->changes[strtolower($id)] = $id;
|
||||
$definition->setClass($id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*
|
||||
* @deprecated since 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function getChanges()
|
||||
{
|
||||
$changes = $this->changes;
|
||||
$this->changes = [];
|
||||
|
||||
return $changes;
|
||||
}
|
||||
}
|
||||
@@ -11,211 +11,19 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\DefinitionDecorator;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
@trigger_error('The '.__NAMESPACE__.'\ResolveDefinitionTemplatesPass class is deprecated since Symfony 3.4 and will be removed in 4.0. Use the ResolveChildDefinitionsPass class instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* This replaces all DefinitionDecorator instances with their equivalent fully
|
||||
* merged Definition instance.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
{
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
private $currentId;
|
||||
class_exists(ResolveChildDefinitionsPass::class);
|
||||
|
||||
if (false) {
|
||||
/**
|
||||
* Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
|
||||
* This definition decorates another definition.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @deprecated The ResolveDefinitionTemplatesPass class is deprecated since version 3.4 and will be removed in 4.0. Use the ResolveChildDefinitionsPass class instead.
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
class ResolveDefinitionTemplatesPass extends AbstractRecursivePass
|
||||
{
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
|
||||
$container->setDefinitions($this->resolveArguments($container, $container->getDefinitions(), true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves definition decorator arguments.
|
||||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param array $arguments An array of arguments
|
||||
* @param bool $isRoot If we are processing the root definitions or not
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function resolveArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if ($isRoot) {
|
||||
// yes, we are specifically fetching the definition from the
|
||||
// container to ensure we are not operating on stale data
|
||||
$arguments[$k] = $argument = $container->getDefinition($k);
|
||||
$this->currentId = $k;
|
||||
}
|
||||
if (\is_array($argument)) {
|
||||
$arguments[$k] = $this->resolveArguments($container, $argument);
|
||||
} elseif ($argument instanceof Definition) {
|
||||
if ($argument instanceof DefinitionDecorator) {
|
||||
$arguments[$k] = $argument = $this->resolveDefinition($container, $argument);
|
||||
if ($isRoot) {
|
||||
$container->setDefinition($k, $argument);
|
||||
}
|
||||
}
|
||||
$argument->setArguments($this->resolveArguments($container, $argument->getArguments()));
|
||||
$argument->setMethodCalls($this->resolveArguments($container, $argument->getMethodCalls()));
|
||||
$argument->setProperties($this->resolveArguments($container, $argument->getProperties()));
|
||||
|
||||
$configurator = $this->resolveArguments($container, array($argument->getConfigurator()));
|
||||
$argument->setConfigurator($configurator[0]);
|
||||
|
||||
$factory = $this->resolveArguments($container, array($argument->getFactory()));
|
||||
$argument->setFactory($factory[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves the definition.
|
||||
*
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param DefinitionDecorator $definition
|
||||
*
|
||||
* @return Definition
|
||||
*
|
||||
* @throws \RuntimeException When the definition is invalid
|
||||
*/
|
||||
private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
|
||||
{
|
||||
if (!$container->hasDefinition($parent = $definition->getParent())) {
|
||||
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $this->currentId));
|
||||
}
|
||||
|
||||
$parentDef = $container->getDefinition($parent);
|
||||
if ($parentDef instanceof DefinitionDecorator) {
|
||||
$id = $this->currentId;
|
||||
$this->currentId = $parent;
|
||||
$parentDef = $this->resolveDefinition($container, $parentDef);
|
||||
$container->setDefinition($parent, $parentDef);
|
||||
$this->currentId = $id;
|
||||
}
|
||||
|
||||
$this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $this->currentId, $parent));
|
||||
$def = new Definition();
|
||||
|
||||
// merge in parent definition
|
||||
// purposely ignored attributes: scope, abstract, tags
|
||||
$def->setClass($parentDef->getClass());
|
||||
$def->setArguments($parentDef->getArguments());
|
||||
$def->setMethodCalls($parentDef->getMethodCalls());
|
||||
$def->setProperties($parentDef->getProperties());
|
||||
$def->setAutowiringTypes($parentDef->getAutowiringTypes());
|
||||
if ($parentDef->getFactoryClass(false)) {
|
||||
$def->setFactoryClass($parentDef->getFactoryClass(false));
|
||||
}
|
||||
if ($parentDef->getFactoryMethod(false)) {
|
||||
$def->setFactoryMethod($parentDef->getFactoryMethod(false));
|
||||
}
|
||||
if ($parentDef->getFactoryService(false)) {
|
||||
$def->setFactoryService($parentDef->getFactoryService(false));
|
||||
}
|
||||
if ($parentDef->isDeprecated()) {
|
||||
$def->setDeprecated(true, $parentDef->getDeprecationMessage('%service_id%'));
|
||||
}
|
||||
$def->setFactory($parentDef->getFactory());
|
||||
$def->setConfigurator($parentDef->getConfigurator());
|
||||
$def->setFile($parentDef->getFile());
|
||||
$def->setPublic($parentDef->isPublic());
|
||||
$def->setLazy($parentDef->isLazy());
|
||||
$def->setAutowired($parentDef->isAutowired());
|
||||
|
||||
// overwrite with values specified in the decorator
|
||||
$changes = $definition->getChanges();
|
||||
if (isset($changes['class'])) {
|
||||
$def->setClass($definition->getClass());
|
||||
}
|
||||
if (isset($changes['factory_class'])) {
|
||||
$def->setFactoryClass($definition->getFactoryClass(false));
|
||||
}
|
||||
if (isset($changes['factory_method'])) {
|
||||
$def->setFactoryMethod($definition->getFactoryMethod(false));
|
||||
}
|
||||
if (isset($changes['factory_service'])) {
|
||||
$def->setFactoryService($definition->getFactoryService(false));
|
||||
}
|
||||
if (isset($changes['factory'])) {
|
||||
$def->setFactory($definition->getFactory());
|
||||
}
|
||||
if (isset($changes['configurator'])) {
|
||||
$def->setConfigurator($definition->getConfigurator());
|
||||
}
|
||||
if (isset($changes['file'])) {
|
||||
$def->setFile($definition->getFile());
|
||||
}
|
||||
if (isset($changes['public'])) {
|
||||
$def->setPublic($definition->isPublic());
|
||||
}
|
||||
if (isset($changes['lazy'])) {
|
||||
$def->setLazy($definition->isLazy());
|
||||
}
|
||||
if (isset($changes['deprecated'])) {
|
||||
$def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%'));
|
||||
}
|
||||
if (isset($changes['autowire'])) {
|
||||
$def->setAutowired($definition->isAutowired());
|
||||
}
|
||||
if (isset($changes['decorated_service'])) {
|
||||
$decoratedService = $definition->getDecoratedService();
|
||||
if (null === $decoratedService) {
|
||||
$def->setDecoratedService($decoratedService);
|
||||
} else {
|
||||
$def->setDecoratedService($decoratedService[0], $decoratedService[1], $decoratedService[2]);
|
||||
}
|
||||
}
|
||||
|
||||
// merge arguments
|
||||
foreach ($definition->getArguments() as $k => $v) {
|
||||
if (is_numeric($k)) {
|
||||
$def->addArgument($v);
|
||||
continue;
|
||||
}
|
||||
|
||||
if (0 !== strpos($k, 'index_')) {
|
||||
throw new RuntimeException(sprintf('Invalid argument key "%s" found.', $k));
|
||||
}
|
||||
|
||||
$index = (int) substr($k, \strlen('index_'));
|
||||
$def->replaceArgument($index, $v);
|
||||
}
|
||||
|
||||
// merge properties
|
||||
foreach ($definition->getProperties() as $k => $v) {
|
||||
$def->setProperty($k, $v);
|
||||
}
|
||||
|
||||
// append method calls
|
||||
if (\count($calls = $definition->getMethodCalls()) > 0) {
|
||||
$def->setMethodCalls(array_merge($def->getMethodCalls(), $calls));
|
||||
}
|
||||
|
||||
// merge autowiring types
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringType) {
|
||||
$def->addAutowiringType($autowiringType);
|
||||
}
|
||||
|
||||
// these attributes are always taken from the child
|
||||
$def->setAbstract($definition->isAbstract());
|
||||
$def->setScope($definition->getScope(false), false);
|
||||
$def->setShared($definition->isShared());
|
||||
$def->setTags($definition->getTags());
|
||||
|
||||
return $def;
|
||||
}
|
||||
}
|
||||
|
||||
44
vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php
vendored
Normal file
44
vendor/symfony/dependency-injection/Compiler/ResolveEnvPlaceholdersPass.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* Replaces env var placeholders by their current values.
|
||||
*/
|
||||
class ResolveEnvPlaceholdersPass extends AbstractRecursivePass
|
||||
{
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (\is_string($value)) {
|
||||
return $this->container->resolveEnvPlaceholders($value, true);
|
||||
}
|
||||
if ($value instanceof Definition) {
|
||||
$changes = $value->getChanges();
|
||||
if (isset($changes['class'])) {
|
||||
$value->setClass($this->container->resolveEnvPlaceholders($value->getClass(), true));
|
||||
}
|
||||
if (isset($changes['file'])) {
|
||||
$value->setFile($this->container->resolveEnvPlaceholders($value->getFile(), true));
|
||||
}
|
||||
}
|
||||
|
||||
$value = parent::processValue($value, $isRoot);
|
||||
|
||||
if ($value && \is_array($value) && !$isRoot) {
|
||||
$value = array_combine($this->container->resolveEnvPlaceholders(array_keys($value), true), $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
38
vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php
vendored
Normal file
38
vendor/symfony/dependency-injection/Compiler/ResolveFactoryClassPass.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
|
||||
*/
|
||||
class ResolveFactoryClassPass extends AbstractRecursivePass
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof Definition && \is_array($factory = $value->getFactory()) && null === $factory[0]) {
|
||||
if (null === $class = $value->getClass()) {
|
||||
throw new RuntimeException(sprintf('The "%s" service is defined to be created by a factory, but is missing the factory class. Did you forget to define the factory or service class?', $this->currentId));
|
||||
}
|
||||
|
||||
$factory[0] = $class;
|
||||
$value->setFactory($factory);
|
||||
}
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
}
|
||||
71
vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php
vendored
Normal file
71
vendor/symfony/dependency-injection/Compiler/ResolveHotPathPass.php
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Propagate "container.hot_path" tags to referenced services.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveHotPathPass extends AbstractRecursivePass
|
||||
{
|
||||
private $tagName;
|
||||
private $resolvedIds = [];
|
||||
|
||||
public function __construct($tagName = 'container.hot_path')
|
||||
{
|
||||
$this->tagName = $tagName;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
try {
|
||||
parent::process($container);
|
||||
$container->getDefinition('service_container')->clearTag($this->tagName);
|
||||
} finally {
|
||||
$this->resolvedIds = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof ArgumentInterface) {
|
||||
return $value;
|
||||
}
|
||||
if ($value instanceof Definition && $isRoot && (isset($this->resolvedIds[$this->currentId]) || !$value->hasTag($this->tagName) || $value->isDeprecated())) {
|
||||
return $value->isDeprecated() ? $value->clearTag($this->tagName) : $value;
|
||||
}
|
||||
if ($value instanceof Reference && ContainerBuilder::IGNORE_ON_UNINITIALIZED_REFERENCE !== $value->getInvalidBehavior() && $this->container->has($id = $this->container->normalizeId($value))) {
|
||||
$definition = $this->container->findDefinition($id);
|
||||
if (!$definition->hasTag($this->tagName) && !$definition->isDeprecated()) {
|
||||
$this->resolvedIds[$id] = true;
|
||||
$definition->addTag($this->tagName);
|
||||
parent::processValue($definition, false);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
}
|
||||
155
vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php
vendored
Normal file
155
vendor/symfony/dependency-injection/Compiler/ResolveInstanceofConditionalsPass.php
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* Applies instanceof conditionals to definitions.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveInstanceofConditionalsPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) {
|
||||
if ($definition->getArguments()) {
|
||||
throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface));
|
||||
}
|
||||
if ($definition->getMethodCalls()) {
|
||||
throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface));
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition instanceof ChildDefinition) {
|
||||
// don't apply "instanceof" to children: it will be applied to their parent
|
||||
continue;
|
||||
}
|
||||
$container->setDefinition($id, $this->processDefinition($container, $id, $definition));
|
||||
}
|
||||
}
|
||||
|
||||
private function processDefinition(ContainerBuilder $container, $id, Definition $definition)
|
||||
{
|
||||
$instanceofConditionals = $definition->getInstanceofConditionals();
|
||||
$autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
|
||||
if (!$instanceofConditionals && !$autoconfiguredInstanceof) {
|
||||
return $definition;
|
||||
}
|
||||
|
||||
if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) {
|
||||
return $definition;
|
||||
}
|
||||
|
||||
$conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container);
|
||||
|
||||
$definition->setInstanceofConditionals([]);
|
||||
$parent = $shared = null;
|
||||
$instanceofTags = [];
|
||||
|
||||
foreach ($conditionals as $interface => $instanceofDefs) {
|
||||
if ($interface !== $class && (!$container->getReflectionClass($class, false))) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ($interface !== $class && !is_subclass_of($class, $interface)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($instanceofDefs as $key => $instanceofDef) {
|
||||
/** @var ChildDefinition $instanceofDef */
|
||||
$instanceofDef = clone $instanceofDef;
|
||||
$instanceofDef->setAbstract(true)->setParent($parent ?: 'abstract.instanceof.'.$id);
|
||||
$parent = 'instanceof.'.$interface.'.'.$key.'.'.$id;
|
||||
$container->setDefinition($parent, $instanceofDef);
|
||||
$instanceofTags[] = $instanceofDef->getTags();
|
||||
$instanceofDef->setTags([]);
|
||||
|
||||
if (isset($instanceofDef->getChanges()['shared'])) {
|
||||
$shared = $instanceofDef->isShared();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ($parent) {
|
||||
$bindings = $definition->getBindings();
|
||||
$abstract = $container->setDefinition('abstract.instanceof.'.$id, $definition);
|
||||
|
||||
// cast Definition to ChildDefinition
|
||||
$definition->setBindings([]);
|
||||
$definition = serialize($definition);
|
||||
$definition = substr_replace($definition, '53', 2, 2);
|
||||
$definition = substr_replace($definition, 'Child', 44, 0);
|
||||
$definition = unserialize($definition);
|
||||
$definition->setParent($parent);
|
||||
|
||||
if (null !== $shared && !isset($definition->getChanges()['shared'])) {
|
||||
$definition->setShared($shared);
|
||||
}
|
||||
|
||||
$i = \count($instanceofTags);
|
||||
while (0 <= --$i) {
|
||||
foreach ($instanceofTags[$i] as $k => $v) {
|
||||
foreach ($v as $v) {
|
||||
if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) {
|
||||
continue;
|
||||
}
|
||||
$definition->addTag($k, $v);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$definition->setBindings($bindings);
|
||||
|
||||
// reset fields with "merge" behavior
|
||||
$abstract
|
||||
->setBindings([])
|
||||
->setArguments([])
|
||||
->setMethodCalls([])
|
||||
->setDecoratedService(null)
|
||||
->setTags([])
|
||||
->setAbstract(true);
|
||||
}
|
||||
|
||||
return $definition;
|
||||
}
|
||||
|
||||
private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container)
|
||||
{
|
||||
// make each value an array of ChildDefinition
|
||||
$conditionals = array_map(function ($childDef) { return [$childDef]; }, $autoconfiguredInstanceof);
|
||||
|
||||
foreach ($instanceofConditionals as $interface => $instanceofDef) {
|
||||
// make sure the interface/class exists (but don't validate automaticInstanceofConditionals)
|
||||
if (!$container->getReflectionClass($interface)) {
|
||||
throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface));
|
||||
}
|
||||
|
||||
if (!isset($autoconfiguredInstanceof[$interface])) {
|
||||
$conditionals[$interface] = [];
|
||||
}
|
||||
|
||||
$conditionals[$interface][] = $instanceofDef;
|
||||
}
|
||||
|
||||
return $conditionals;
|
||||
}
|
||||
}
|
||||
@@ -11,8 +11,11 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
@@ -25,6 +28,7 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
class ResolveInvalidReferencesPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
private $signalingException;
|
||||
|
||||
/**
|
||||
* Process the ContainerBuilder to resolve invalid references.
|
||||
@@ -32,72 +36,76 @@ class ResolveInvalidReferencesPass implements CompilerPassInterface
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
foreach ($container->getDefinitions() as $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
$this->signalingException = new RuntimeException('Invalid reference.');
|
||||
|
||||
$definition->setArguments(
|
||||
$this->processArguments($definition->getArguments())
|
||||
);
|
||||
|
||||
$calls = array();
|
||||
foreach ($definition->getMethodCalls() as $call) {
|
||||
try {
|
||||
$calls[] = array($call[0], $this->processArguments($call[1], true));
|
||||
} catch (RuntimeException $e) {
|
||||
// this call is simply removed
|
||||
}
|
||||
}
|
||||
$definition->setMethodCalls($calls);
|
||||
|
||||
$properties = array();
|
||||
foreach ($definition->getProperties() as $name => $value) {
|
||||
try {
|
||||
$value = $this->processArguments(array($value), true);
|
||||
$properties[$name] = reset($value);
|
||||
} catch (RuntimeException $e) {
|
||||
// ignore property
|
||||
}
|
||||
}
|
||||
$definition->setProperties($properties);
|
||||
try {
|
||||
$this->processValue($container->getDefinitions(), 1);
|
||||
} finally {
|
||||
$this->container = $this->signalingException = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes arguments to determine invalid references.
|
||||
*
|
||||
* @param array $arguments An array of Reference objects
|
||||
* @param bool $inMethodCall
|
||||
*
|
||||
* @return array
|
||||
*
|
||||
* @throws RuntimeException When the config is invalid
|
||||
* @throws RuntimeException When an invalid reference is found
|
||||
*/
|
||||
private function processArguments(array $arguments, $inMethodCall = false)
|
||||
private function processValue($value, $rootLevel = 0, $level = 0)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if (\is_array($argument)) {
|
||||
$arguments[$k] = $this->processArguments($argument, $inMethodCall);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$id = (string) $argument;
|
||||
if ($value instanceof ServiceClosureArgument) {
|
||||
$value->setValues($this->processValue($value->getValues(), 1, 1));
|
||||
} elseif ($value instanceof ArgumentInterface) {
|
||||
$value->setValues($this->processValue($value->getValues(), $rootLevel, 1 + $level));
|
||||
} elseif ($value instanceof Definition) {
|
||||
if ($value->isSynthetic() || $value->isAbstract()) {
|
||||
return $value;
|
||||
}
|
||||
$value->setArguments($this->processValue($value->getArguments(), 0));
|
||||
$value->setProperties($this->processValue($value->getProperties(), 1));
|
||||
$value->setMethodCalls($this->processValue($value->getMethodCalls(), 2));
|
||||
} elseif (\is_array($value)) {
|
||||
$i = 0;
|
||||
|
||||
$invalidBehavior = $argument->getInvalidBehavior();
|
||||
$exists = $this->container->has($id);
|
||||
|
||||
// resolve invalid behavior
|
||||
if (!$exists && ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
$arguments[$k] = null;
|
||||
} elseif (!$exists && ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
if ($inMethodCall) {
|
||||
throw new RuntimeException('Method shouldn\'t be called.');
|
||||
foreach ($value as $k => $v) {
|
||||
try {
|
||||
if (false !== $i && $k !== $i++) {
|
||||
$i = false;
|
||||
}
|
||||
if ($v !== $processedValue = $this->processValue($v, $rootLevel, 1 + $level)) {
|
||||
$value[$k] = $processedValue;
|
||||
}
|
||||
} catch (RuntimeException $e) {
|
||||
if ($rootLevel < $level || ($rootLevel && !$level)) {
|
||||
unset($value[$k]);
|
||||
} elseif ($rootLevel) {
|
||||
throw $e;
|
||||
} else {
|
||||
$value[$k] = null;
|
||||
}
|
||||
|
||||
$arguments[$k] = null;
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure numerically indexed arguments have sequential numeric keys.
|
||||
if (false !== $i) {
|
||||
$value = array_values($value);
|
||||
}
|
||||
} elseif ($value instanceof Reference) {
|
||||
if ($this->container->has($value)) {
|
||||
return $value;
|
||||
}
|
||||
$invalidBehavior = $value->getInvalidBehavior();
|
||||
|
||||
// resolve invalid behavior
|
||||
if (ContainerInterface::NULL_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
$value = null;
|
||||
} elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
if (0 < $level || $rootLevel) {
|
||||
throw $this->signalingException;
|
||||
}
|
||||
$value = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
102
vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php
vendored
Normal file
102
vendor/symfony/dependency-injection/Compiler/ResolveNamedArgumentsPass.php
vendored
Normal file
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\LazyProxy\ProxyHelper;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Resolves named arguments to their corresponding numeric index.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class ResolveNamedArgumentsPass extends AbstractRecursivePass
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$calls = $value->getMethodCalls();
|
||||
$calls[] = ['__construct', $value->getArguments()];
|
||||
|
||||
foreach ($calls as $i => $call) {
|
||||
list($method, $arguments) = $call;
|
||||
$parameters = null;
|
||||
$resolvedArguments = [];
|
||||
|
||||
foreach ($arguments as $key => $argument) {
|
||||
if (\is_int($key)) {
|
||||
$resolvedArguments[$key] = $argument;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (null === $parameters) {
|
||||
$r = $this->getReflectionMethod($value, $method);
|
||||
$class = $r instanceof \ReflectionMethod ? $r->class : $this->currentId;
|
||||
$method = $r->getName();
|
||||
$parameters = $r->getParameters();
|
||||
}
|
||||
|
||||
if (isset($key[0]) && '$' === $key[0]) {
|
||||
foreach ($parameters as $j => $p) {
|
||||
if ($key === '$'.$p->name) {
|
||||
$resolvedArguments[$j] = $argument;
|
||||
|
||||
continue 2;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument named "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key));
|
||||
}
|
||||
|
||||
if (null !== $argument && !$argument instanceof Reference && !$argument instanceof Definition) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid service "%s": the value of argument "%s" of method "%s()" must be null, an instance of %s or an instance of %s, %s given.', $this->currentId, $key, $class !== $this->currentId ? $class.'::'.$method : $method, Reference::class, Definition::class, \gettype($argument)));
|
||||
}
|
||||
|
||||
$typeFound = false;
|
||||
foreach ($parameters as $j => $p) {
|
||||
if (!\array_key_exists($j, $resolvedArguments) && ProxyHelper::getTypeHint($r, $p, true) === $key) {
|
||||
$resolvedArguments[$j] = $argument;
|
||||
$typeFound = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!$typeFound) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid service "%s": method "%s()" has no argument type-hinted as "%s". Check your service definition.', $this->currentId, $class !== $this->currentId ? $class.'::'.$method : $method, $key));
|
||||
}
|
||||
}
|
||||
|
||||
if ($resolvedArguments !== $call[1]) {
|
||||
ksort($resolvedArguments);
|
||||
$calls[$i][1] = $resolvedArguments;
|
||||
}
|
||||
}
|
||||
|
||||
list(, $arguments) = array_pop($calls);
|
||||
|
||||
if ($arguments !== $value->getArguments()) {
|
||||
$value->setArguments($arguments);
|
||||
}
|
||||
if ($calls !== $value->getMethodCalls()) {
|
||||
$value->setMethodCalls($calls);
|
||||
}
|
||||
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,7 @@
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
|
||||
|
||||
/**
|
||||
@@ -19,53 +20,68 @@ use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ResolveParameterPlaceHoldersPass implements CompilerPassInterface
|
||||
class ResolveParameterPlaceHoldersPass extends AbstractRecursivePass
|
||||
{
|
||||
private $bag;
|
||||
private $resolveArrays;
|
||||
|
||||
public function __construct($resolveArrays = true)
|
||||
{
|
||||
$this->resolveArrays = $resolveArrays;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder to resolve parameter placeholders.
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* @throws ParameterNotFoundException
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$parameterBag = $container->getParameterBag();
|
||||
$this->bag = $container->getParameterBag();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
try {
|
||||
$definition->setClass($parameterBag->resolveValue($definition->getClass()));
|
||||
$definition->setFile($parameterBag->resolveValue($definition->getFile()));
|
||||
$definition->setArguments($parameterBag->resolveValue($definition->getArguments()));
|
||||
if ($definition->getFactoryClass(false)) {
|
||||
$definition->setFactoryClass($parameterBag->resolveValue($definition->getFactoryClass(false)));
|
||||
}
|
||||
try {
|
||||
parent::process($container);
|
||||
|
||||
$factory = $definition->getFactory();
|
||||
$aliases = [];
|
||||
foreach ($container->getAliases() as $name => $target) {
|
||||
$this->currentId = $name;
|
||||
$aliases[$this->bag->resolveValue($name)] = $target;
|
||||
}
|
||||
$container->setAliases($aliases);
|
||||
} catch (ParameterNotFoundException $e) {
|
||||
$e->setSourceId($this->currentId);
|
||||
|
||||
if (\is_array($factory) && isset($factory[0])) {
|
||||
$factory[0] = $parameterBag->resolveValue($factory[0]);
|
||||
$definition->setFactory($factory);
|
||||
}
|
||||
throw $e;
|
||||
}
|
||||
|
||||
$calls = array();
|
||||
foreach ($definition->getMethodCalls() as $name => $arguments) {
|
||||
$calls[$parameterBag->resolveValue($name)] = $parameterBag->resolveValue($arguments);
|
||||
}
|
||||
$definition->setMethodCalls($calls);
|
||||
$this->bag->resolve();
|
||||
$this->bag = null;
|
||||
}
|
||||
|
||||
$definition->setProperties($parameterBag->resolveValue($definition->getProperties()));
|
||||
} catch (ParameterNotFoundException $e) {
|
||||
$e->setSourceId($id);
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (\is_string($value)) {
|
||||
$v = $this->bag->resolveValue($value);
|
||||
|
||||
throw $e;
|
||||
return $this->resolveArrays || !$v || !\is_array($v) ? $v : $value;
|
||||
}
|
||||
if ($value instanceof Definition) {
|
||||
$value->setBindings($this->processValue($value->getBindings()));
|
||||
$changes = $value->getChanges();
|
||||
if (isset($changes['class'])) {
|
||||
$value->setClass($this->bag->resolveValue($value->getClass()));
|
||||
}
|
||||
if (isset($changes['file'])) {
|
||||
$value->setFile($this->bag->resolveValue($value->getFile()));
|
||||
}
|
||||
}
|
||||
|
||||
$aliases = array();
|
||||
foreach ($container->getAliases() as $name => $target) {
|
||||
$aliases[$parameterBag->resolveValue($name)] = $target;
|
||||
}
|
||||
$container->setAliases($aliases);
|
||||
$value = parent::processValue($value, $isRoot);
|
||||
|
||||
$parameterBag->resolve();
|
||||
if ($value && \is_array($value)) {
|
||||
$value = array_combine($this->bag->resolveValue(array_keys($value)), $value);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
40
vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php
vendored
Normal file
40
vendor/symfony/dependency-injection/Compiler/ResolvePrivatesPass.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolvePrivatesPass implements CompilerPassInterface
|
||||
{
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isPrivate()) {
|
||||
$definition->setPublic(false);
|
||||
$definition->setPrivate(true);
|
||||
}
|
||||
}
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
if ($alias->isPrivate()) {
|
||||
$alias->setPublic(false);
|
||||
$alias->setPrivate(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,6 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
@@ -21,83 +20,37 @@ use Symfony\Component\DependencyInjection\Reference;
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
||||
class ResolveReferencesToAliasesPass extends AbstractRecursivePass
|
||||
{
|
||||
private $container;
|
||||
|
||||
/**
|
||||
* Processes the ContainerBuilder to replace references to aliases with actual service references.
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
foreach ($container->getDefinitions() as $definition) {
|
||||
if ($definition->isSynthetic() || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$definition->setArguments($this->processArguments($definition->getArguments()));
|
||||
$definition->setMethodCalls($this->processArguments($definition->getMethodCalls()));
|
||||
$definition->setProperties($this->processArguments($definition->getProperties()));
|
||||
$definition->setFactory($this->processFactory($definition->getFactory()));
|
||||
$definition->setFactoryService($this->processFactoryService($definition->getFactoryService(false)), false);
|
||||
}
|
||||
parent::process($container);
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
$aliasId = (string) $alias;
|
||||
if ($aliasId !== $defId = $this->getDefinitionId($aliasId)) {
|
||||
$container->setAlias($id, new Alias($defId, $alias->isPublic()));
|
||||
$aliasId = $container->normalizeId($alias);
|
||||
if ($aliasId !== $defId = $this->getDefinitionId($aliasId, $container)) {
|
||||
$container->setAlias($id, $defId)->setPublic($alias->isPublic())->setPrivate($alias->isPrivate());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the arguments to replace aliases.
|
||||
*
|
||||
* @param array $arguments An array of References
|
||||
*
|
||||
* @return array An array of References
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
private function processArguments(array $arguments)
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if (\is_array($argument)) {
|
||||
$arguments[$k] = $this->processArguments($argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
$defId = $this->getDefinitionId($id = (string) $argument);
|
||||
if ($value instanceof Reference) {
|
||||
$defId = $this->getDefinitionId($id = $this->container->normalizeId($value), $this->container);
|
||||
|
||||
if ($defId !== $id) {
|
||||
$arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict(false));
|
||||
}
|
||||
if ($defId !== $id) {
|
||||
return new Reference($defId, $value->getInvalidBehavior());
|
||||
}
|
||||
}
|
||||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
private function processFactoryService($factoryService)
|
||||
{
|
||||
if (null === $factoryService) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $this->getDefinitionId($factoryService);
|
||||
}
|
||||
|
||||
private function processFactory($factory)
|
||||
{
|
||||
if (null === $factory || !\is_array($factory) || !$factory[0] instanceof Reference) {
|
||||
return $factory;
|
||||
}
|
||||
|
||||
$defId = $this->getDefinitionId($id = (string) $factory[0]);
|
||||
|
||||
if ($defId !== $id) {
|
||||
$factory[0] = new Reference($defId, $factory[0]->getInvalidBehavior(), $factory[0]->isStrict(false));
|
||||
}
|
||||
|
||||
return $factory;
|
||||
return parent::processValue($value);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -107,15 +60,15 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
||||
*
|
||||
* @return string The definition id with aliases resolved
|
||||
*/
|
||||
private function getDefinitionId($id)
|
||||
private function getDefinitionId($id, ContainerBuilder $container)
|
||||
{
|
||||
$seen = array();
|
||||
while ($this->container->hasAlias($id)) {
|
||||
$seen = [];
|
||||
while ($container->hasAlias($id)) {
|
||||
if (isset($seen[$id])) {
|
||||
throw new ServiceCircularReferenceException($id, array_keys($seen));
|
||||
throw new ServiceCircularReferenceException($id, array_merge(array_keys($seen), [$id]));
|
||||
}
|
||||
$seen[$id] = true;
|
||||
$id = (string) $this->container->getAlias($id);
|
||||
$id = $container->normalizeId($container->getAlias($id));
|
||||
}
|
||||
|
||||
return $id;
|
||||
|
||||
51
vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php
vendored
Normal file
51
vendor/symfony/dependency-injection/Compiler/ResolveServiceSubscribersPass.php
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Psr\Container\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Compiler pass to inject their service locator to service subscribers.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveServiceSubscribersPass extends AbstractRecursivePass
|
||||
{
|
||||
private $serviceLocator;
|
||||
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if ($value instanceof Reference && $this->serviceLocator && ContainerInterface::class === $this->container->normalizeId($value)) {
|
||||
return new Reference($this->serviceLocator);
|
||||
}
|
||||
|
||||
if (!$value instanceof Definition) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$serviceLocator = $this->serviceLocator;
|
||||
$this->serviceLocator = null;
|
||||
|
||||
if ($value->hasTag('container.service_subscriber.locator')) {
|
||||
$this->serviceLocator = $value->getTag('container.service_subscriber.locator')[0]['id'];
|
||||
$value->clearTag('container.service_subscriber.locator');
|
||||
}
|
||||
|
||||
try {
|
||||
return parent::processValue($value);
|
||||
} finally {
|
||||
$this->serviceLocator = $serviceLocator;
|
||||
}
|
||||
}
|
||||
}
|
||||
38
vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php
vendored
Normal file
38
vendor/symfony/dependency-injection/Compiler/ResolveTaggedIteratorArgumentPass.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
|
||||
/**
|
||||
* Resolves all TaggedIteratorArgument arguments.
|
||||
*
|
||||
* @author Roland Franssen <franssen.roland@gmail.com>
|
||||
*/
|
||||
class ResolveTaggedIteratorArgumentPass extends AbstractRecursivePass
|
||||
{
|
||||
use PriorityTaggedServiceTrait;
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof TaggedIteratorArgument) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
$value->setValues($this->findAndSortTaggedServices($value->getTag(), $this->container));
|
||||
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
126
vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php
vendored
Normal file
126
vendor/symfony/dependency-injection/Compiler/ServiceLocatorTagPass.php
vendored
Normal file
@@ -0,0 +1,126 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ServiceLocator;
|
||||
|
||||
/**
|
||||
* Applies the "container.service_locator" tag by wrapping references into ServiceClosureArgument instances.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
final class ServiceLocatorTagPass extends AbstractRecursivePass
|
||||
{
|
||||
protected function processValue($value, $isRoot = false)
|
||||
{
|
||||
if (!$value instanceof Definition || !$value->hasTag('container.service_locator')) {
|
||||
return parent::processValue($value, $isRoot);
|
||||
}
|
||||
|
||||
if (!$value->getClass()) {
|
||||
$value->setClass(ServiceLocator::class);
|
||||
}
|
||||
|
||||
$arguments = $value->getArguments();
|
||||
if (!isset($arguments[0]) || !\is_array($arguments[0])) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set.', $this->currentId));
|
||||
}
|
||||
|
||||
$i = 0;
|
||||
|
||||
foreach ($arguments[0] as $k => $v) {
|
||||
if ($v instanceof ServiceClosureArgument) {
|
||||
continue;
|
||||
}
|
||||
if (!$v instanceof Reference) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid definition for service "%s": an array of references is expected as first argument when the "container.service_locator" tag is set, "%s" found for key "%s".', $this->currentId, \is_object($v) ? \get_class($v) : \gettype($v), $k));
|
||||
}
|
||||
|
||||
if ($i === $k) {
|
||||
unset($arguments[0][$k]);
|
||||
|
||||
$k = (string) $v;
|
||||
++$i;
|
||||
} elseif (\is_int($k)) {
|
||||
$i = null;
|
||||
}
|
||||
$arguments[0][$k] = new ServiceClosureArgument($v);
|
||||
}
|
||||
ksort($arguments[0]);
|
||||
|
||||
$value->setArguments($arguments);
|
||||
|
||||
$id = 'service_locator.'.ContainerBuilder::hash($value);
|
||||
|
||||
if ($isRoot) {
|
||||
if ($id !== $this->currentId) {
|
||||
$this->container->setAlias($id, new Alias($this->currentId, false));
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
$this->container->setDefinition($id, $value->setPublic(false));
|
||||
|
||||
return new Reference($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param Reference[] $refMap
|
||||
* @param string|null $callerId
|
||||
*
|
||||
* @return Reference
|
||||
*/
|
||||
public static function register(ContainerBuilder $container, array $refMap, $callerId = null)
|
||||
{
|
||||
foreach ($refMap as $id => $ref) {
|
||||
if (!$ref instanceof Reference) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid service locator definition: only services can be referenced, "%s" found for key "%s". Inject parameter values using constructors instead.', \is_object($ref) ? \get_class($ref) : \gettype($ref), $id));
|
||||
}
|
||||
$refMap[$id] = new ServiceClosureArgument($ref);
|
||||
}
|
||||
ksort($refMap);
|
||||
|
||||
$locator = (new Definition(ServiceLocator::class))
|
||||
->addArgument($refMap)
|
||||
->setPublic(false)
|
||||
->addTag('container.service_locator');
|
||||
|
||||
if (null !== $callerId && $container->hasDefinition($callerId)) {
|
||||
$locator->setBindings($container->getDefinition($callerId)->getBindings());
|
||||
}
|
||||
|
||||
if (!$container->hasDefinition($id = 'service_locator.'.ContainerBuilder::hash($locator))) {
|
||||
$container->setDefinition($id, $locator);
|
||||
}
|
||||
|
||||
if (null !== $callerId) {
|
||||
$locatorId = $id;
|
||||
// Locators are shared when they hold the exact same list of factories;
|
||||
// to have them specialized per consumer service, we use a cloning factory
|
||||
// to derivate customized instances from the prototype one.
|
||||
$container->register($id .= '.'.$callerId, ServiceLocator::class)
|
||||
->setPublic(false)
|
||||
->setFactory([new Reference($locatorId), 'withContext'])
|
||||
->addArgument($callerId)
|
||||
->addArgument(new Reference('service_container'));
|
||||
}
|
||||
|
||||
return new Reference($id);
|
||||
}
|
||||
}
|
||||
@@ -20,13 +20,15 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
* it themselves which improves performance quite a lot.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @final since version 3.4
|
||||
*/
|
||||
class ServiceReferenceGraph
|
||||
{
|
||||
/**
|
||||
* @var ServiceReferenceGraphNode[]
|
||||
*/
|
||||
private $nodes = array();
|
||||
private $nodes = [];
|
||||
|
||||
/**
|
||||
* Checks if the graph has a specific node.
|
||||
@@ -73,7 +75,10 @@ class ServiceReferenceGraph
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->nodes = array();
|
||||
foreach ($this->nodes as $node) {
|
||||
$node->clear();
|
||||
}
|
||||
$this->nodes = [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,14 +90,19 @@ class ServiceReferenceGraph
|
||||
* @param mixed $destValue
|
||||
* @param string $reference
|
||||
*/
|
||||
public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null)
|
||||
public function connect($sourceId, $sourceValue, $destId, $destValue = null, $reference = null/*, bool $lazy = false, bool $weak = false, bool $byConstructor = false*/)
|
||||
{
|
||||
$lazy = \func_num_args() >= 6 ? func_get_arg(5) : false;
|
||||
$weak = \func_num_args() >= 7 ? func_get_arg(6) : false;
|
||||
$byConstructor = \func_num_args() >= 8 ? func_get_arg(7) : false;
|
||||
|
||||
if (null === $sourceId || null === $destId) {
|
||||
return;
|
||||
}
|
||||
|
||||
$sourceNode = $this->createNode($sourceId, $sourceValue);
|
||||
$destNode = $this->createNode($destId, $destValue);
|
||||
$edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference);
|
||||
$edge = new ServiceReferenceGraphEdge($sourceNode, $destNode, $reference, $lazy, $weak, $byConstructor);
|
||||
|
||||
$sourceNode->addOutEdge($edge);
|
||||
$destNode->addInEdge($edge);
|
||||
|
||||
@@ -23,17 +23,24 @@ class ServiceReferenceGraphEdge
|
||||
private $sourceNode;
|
||||
private $destNode;
|
||||
private $value;
|
||||
private $lazy;
|
||||
private $weak;
|
||||
private $byConstructor;
|
||||
|
||||
/**
|
||||
* @param ServiceReferenceGraphNode $sourceNode
|
||||
* @param ServiceReferenceGraphNode $destNode
|
||||
* @param mixed $value
|
||||
* @param mixed $value
|
||||
* @param bool $lazy
|
||||
* @param bool $weak
|
||||
* @param bool $byConstructor
|
||||
*/
|
||||
public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null)
|
||||
public function __construct(ServiceReferenceGraphNode $sourceNode, ServiceReferenceGraphNode $destNode, $value = null, $lazy = false, $weak = false, $byConstructor = false)
|
||||
{
|
||||
$this->sourceNode = $sourceNode;
|
||||
$this->destNode = $destNode;
|
||||
$this->value = $value;
|
||||
$this->lazy = $lazy;
|
||||
$this->weak = $weak;
|
||||
$this->byConstructor = $byConstructor;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -65,4 +72,34 @@ class ServiceReferenceGraphEdge
|
||||
{
|
||||
return $this->destNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the edge is lazy, meaning it's a dependency not requiring direct instantiation.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isLazy()
|
||||
{
|
||||
return $this->lazy;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the edge is weak, meaning it shouldn't prevent removing the target service.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isWeak()
|
||||
{
|
||||
return $this->weak;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the edge links with a constructor argument.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isReferencedByConstructor()
|
||||
{
|
||||
return $this->byConstructor;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,8 @@ use Symfony\Component\DependencyInjection\Definition;
|
||||
class ServiceReferenceGraphNode
|
||||
{
|
||||
private $id;
|
||||
private $inEdges = array();
|
||||
private $outEdges = array();
|
||||
private $inEdges = [];
|
||||
private $outEdges = [];
|
||||
private $value;
|
||||
|
||||
/**
|
||||
@@ -81,7 +81,7 @@ class ServiceReferenceGraphNode
|
||||
/**
|
||||
* Returns the in edges.
|
||||
*
|
||||
* @return array The in ServiceReferenceGraphEdge array
|
||||
* @return ServiceReferenceGraphEdge[]
|
||||
*/
|
||||
public function getInEdges()
|
||||
{
|
||||
@@ -91,7 +91,7 @@ class ServiceReferenceGraphNode
|
||||
/**
|
||||
* Returns the out edges.
|
||||
*
|
||||
* @return array The out ServiceReferenceGraphEdge array
|
||||
* @return ServiceReferenceGraphEdge[]
|
||||
*/
|
||||
public function getOutEdges()
|
||||
{
|
||||
@@ -107,4 +107,12 @@ class ServiceReferenceGraphNode
|
||||
{
|
||||
return $this->value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all edges.
|
||||
*/
|
||||
public function clear()
|
||||
{
|
||||
$this->inEdges = $this->outEdges = [];
|
||||
}
|
||||
}
|
||||
|
||||
88
vendor/symfony/dependency-injection/Config/AutowireServiceResource.php
vendored
Normal file
88
vendor/symfony/dependency-injection/Config/AutowireServiceResource.php
vendored
Normal file
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Config;
|
||||
|
||||
@trigger_error('The '.__NAMESPACE__.'\AutowireServiceResource class is deprecated since Symfony 3.3 and will be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.', E_USER_DEPRECATED);
|
||||
|
||||
use Symfony\Component\Config\Resource\SelfCheckingResourceInterface;
|
||||
use Symfony\Component\DependencyInjection\Compiler\AutowirePass;
|
||||
|
||||
/**
|
||||
* @deprecated since version 3.3, to be removed in 4.0. Use ContainerBuilder::getReflectionClass() instead.
|
||||
*/
|
||||
class AutowireServiceResource implements SelfCheckingResourceInterface, \Serializable
|
||||
{
|
||||
private $class;
|
||||
private $filePath;
|
||||
private $autowiringMetadata = [];
|
||||
|
||||
public function __construct($class, $path, array $autowiringMetadata)
|
||||
{
|
||||
$this->class = $class;
|
||||
$this->filePath = $path;
|
||||
$this->autowiringMetadata = $autowiringMetadata;
|
||||
}
|
||||
|
||||
public function isFresh($timestamp)
|
||||
{
|
||||
if (!file_exists($this->filePath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// has the file *not* been modified? Definitely fresh
|
||||
if (@filemtime($this->filePath) <= $timestamp) {
|
||||
return true;
|
||||
}
|
||||
|
||||
try {
|
||||
$reflectionClass = new \ReflectionClass($this->class);
|
||||
} catch (\ReflectionException $e) {
|
||||
// the class does not exist anymore!
|
||||
return false;
|
||||
}
|
||||
|
||||
return (array) $this === (array) AutowirePass::createResourceForClass($reflectionClass);
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return 'service.autowire.'.$this->class;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize([$this->class, $this->filePath, $this->autowiringMetadata]);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
if (\PHP_VERSION_ID >= 70000) {
|
||||
list($this->class, $this->filePath, $this->autowiringMetadata) = unserialize($serialized, ['allowed_classes' => false]);
|
||||
} else {
|
||||
list($this->class, $this->filePath, $this->autowiringMetadata) = unserialize($serialized);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Implemented for compatibility with Symfony 2.8
|
||||
*/
|
||||
public function getResource()
|
||||
{
|
||||
return $this->filePath;
|
||||
}
|
||||
}
|
||||
64
vendor/symfony/dependency-injection/Config/ContainerParametersResource.php
vendored
Normal file
64
vendor/symfony/dependency-injection/Config/ContainerParametersResource.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Config;
|
||||
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
|
||||
/**
|
||||
* Tracks container parameters.
|
||||
*
|
||||
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
|
||||
*/
|
||||
class ContainerParametersResource implements ResourceInterface, \Serializable
|
||||
{
|
||||
private $parameters;
|
||||
|
||||
/**
|
||||
* @param array $parameters The container parameters to track
|
||||
*/
|
||||
public function __construct(array $parameters)
|
||||
{
|
||||
$this->parameters = $parameters;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __toString()
|
||||
{
|
||||
return 'container_parameters_'.md5(serialize($this->parameters));
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function serialize()
|
||||
{
|
||||
return serialize($this->parameters);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
public function unserialize($serialized)
|
||||
{
|
||||
$this->parameters = unserialize($serialized);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array Tracked parameters
|
||||
*/
|
||||
public function getParameters()
|
||||
{
|
||||
return $this->parameters;
|
||||
}
|
||||
}
|
||||
52
vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php
vendored
Normal file
52
vendor/symfony/dependency-injection/Config/ContainerParametersResourceChecker.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Config;
|
||||
|
||||
use Symfony\Component\Config\Resource\ResourceInterface;
|
||||
use Symfony\Component\Config\ResourceCheckerInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @author Maxime Steinhausser <maxime.steinhausser@gmail.com>
|
||||
*/
|
||||
class ContainerParametersResourceChecker implements ResourceCheckerInterface
|
||||
{
|
||||
/** @var ContainerInterface */
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function supports(ResourceInterface $metadata)
|
||||
{
|
||||
return $metadata instanceof ContainerParametersResource;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function isFresh(ResourceInterface $resource, $timestamp)
|
||||
{
|
||||
foreach ($resource->getParameters() as $key => $value) {
|
||||
if (!$this->container->hasParameter($key) || $this->container->getParameter($key) !== $value) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
556
vendor/symfony/dependency-injection/Container.php
vendored
556
vendor/symfony/dependency-injection/Container.php
vendored
@@ -11,59 +11,61 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InactiveScopeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\LogicException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ParameterCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\FrozenParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
|
||||
|
||||
/**
|
||||
* Container is a dependency injection container.
|
||||
*
|
||||
* It gives access to object instances (services).
|
||||
*
|
||||
* Services and parameters are simple key/pair stores.
|
||||
*
|
||||
* Parameter and service keys are case insensitive.
|
||||
*
|
||||
* A service can also be defined by creating a method named
|
||||
* getXXXService(), where XXX is the camelized version of the id:
|
||||
*
|
||||
* * request -> getRequestService()
|
||||
* * mysql_session_storage -> getMysqlSessionStorageService()
|
||||
* * symfony.mysql_session_storage -> getSymfony_MysqlSessionStorageService()
|
||||
*
|
||||
* The container can have three possible behaviors when a service does not exist:
|
||||
* The container can have four possible behaviors when a service
|
||||
* does not exist (or is not initialized for the last case):
|
||||
*
|
||||
* * EXCEPTION_ON_INVALID_REFERENCE: Throws an exception (the default)
|
||||
* * NULL_ON_INVALID_REFERENCE: Returns null
|
||||
* * IGNORE_ON_INVALID_REFERENCE: Ignores the wrapping command asking for the reference
|
||||
* (for instance, ignore a setter if the service does not exist)
|
||||
* * IGNORE_ON_UNINITIALIZED_REFERENCE: Ignores/returns null for uninitialized services or invalid references
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class Container implements IntrospectableContainerInterface, ResettableContainerInterface
|
||||
class Container implements ResettableContainerInterface
|
||||
{
|
||||
protected $parameterBag;
|
||||
protected $services = array();
|
||||
protected $methodMap = array();
|
||||
protected $aliases = array();
|
||||
protected $scopes = array();
|
||||
protected $scopeChildren = array();
|
||||
protected $scopedServices = array();
|
||||
protected $scopeStacks = array();
|
||||
protected $loading = array();
|
||||
protected $services = [];
|
||||
protected $fileMap = [];
|
||||
protected $methodMap = [];
|
||||
protected $aliases = [];
|
||||
protected $loading = [];
|
||||
protected $resolving = [];
|
||||
protected $syntheticIds = [];
|
||||
|
||||
private $underscoreMap = array('_' => '', '.' => '_', '\\' => '_');
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected $privates = [];
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
protected $normalizedIds = [];
|
||||
|
||||
private $underscoreMap = ['_' => '', '.' => '_', '\\' => '_'];
|
||||
private $envCache = [];
|
||||
private $compiled = false;
|
||||
private $getEnv;
|
||||
|
||||
public function __construct(ParameterBagInterface $parameterBag = null)
|
||||
{
|
||||
$this->parameterBag = $parameterBag ?: new ParameterBag();
|
||||
$this->parameterBag = $parameterBag ?: new EnvPlaceholderParameterBag();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -79,15 +81,31 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
$this->parameterBag->resolve();
|
||||
|
||||
$this->parameterBag = new FrozenParameterBag($this->parameterBag->all());
|
||||
|
||||
$this->compiled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the container is compiled.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isCompiled()
|
||||
{
|
||||
return $this->compiled;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if the container parameter bag are frozen.
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*
|
||||
* @return bool true if the container parameter bag are frozen, false otherwise
|
||||
*/
|
||||
public function isFrozen()
|
||||
{
|
||||
@trigger_error(sprintf('The %s() method is deprecated since Symfony 3.3 and will be removed in 4.0. Use the isCompiled() method instead.', __METHOD__), E_USER_DEPRECATED);
|
||||
|
||||
return $this->parameterBag instanceof FrozenParameterBag;
|
||||
}
|
||||
|
||||
@@ -141,61 +159,55 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
* Setting a service to null resets the service: has() returns false and get()
|
||||
* Setting a synthetic service to null resets it: has() returns false and get()
|
||||
* behaves in the same way as if the service was never created.
|
||||
*
|
||||
* Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope of the service
|
||||
*
|
||||
* @throws RuntimeException When trying to set a service in an inactive scope
|
||||
* @throws InvalidArgumentException When trying to set a service in the prototype scope
|
||||
* @param string $id The service identifier
|
||||
* @param object|null $service The service instance
|
||||
*/
|
||||
public function set($id, $service, $scope = self::SCOPE_CONTAINER)
|
||||
public function set($id, $service)
|
||||
{
|
||||
if (!\in_array($scope, array('container', 'request')) || ('request' === $scope && 'request' !== $id)) {
|
||||
@trigger_error('The concept of container scopes is deprecated since Symfony 2.8 and will be removed in 3.0. Omit the third parameter.', E_USER_DEPRECATED);
|
||||
// Runs the internal initializer; used by the dumped container to include always-needed files
|
||||
if (isset($this->privates['service_container']) && $this->privates['service_container'] instanceof \Closure) {
|
||||
$initialize = $this->privates['service_container'];
|
||||
unset($this->privates['service_container']);
|
||||
$initialize();
|
||||
}
|
||||
|
||||
if (self::SCOPE_PROTOTYPE === $scope) {
|
||||
throw new InvalidArgumentException(sprintf('You cannot set service "%s" of scope "prototype".', $id));
|
||||
}
|
||||
|
||||
$id = strtolower($id);
|
||||
$id = $this->normalizeId($id);
|
||||
|
||||
if ('service_container' === $id) {
|
||||
// BC: 'service_container' is no longer a self-reference but always
|
||||
// $this, so ignore this call.
|
||||
// @todo Throw InvalidArgumentException in next major release.
|
||||
return;
|
||||
throw new InvalidArgumentException('You cannot set service "service_container".');
|
||||
}
|
||||
if (self::SCOPE_CONTAINER !== $scope) {
|
||||
if (!isset($this->scopedServices[$scope])) {
|
||||
throw new RuntimeException(sprintf('You cannot set service "%s" of inactive scope.', $id));
|
||||
}
|
||||
|
||||
$this->scopedServices[$scope][$id] = $service;
|
||||
if (isset($this->privates[$id]) || !(isset($this->fileMap[$id]) || isset($this->methodMap[$id]))) {
|
||||
if (!isset($this->privates[$id]) && !isset($this->getRemovedIds()[$id])) {
|
||||
// no-op
|
||||
} elseif (null === $service) {
|
||||
@trigger_error(sprintf('The "%s" service is private, unsetting it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), E_USER_DEPRECATED);
|
||||
unset($this->privates[$id]);
|
||||
} else {
|
||||
@trigger_error(sprintf('The "%s" service is private, replacing it is deprecated since Symfony 3.2 and will fail in 4.0.', $id), E_USER_DEPRECATED);
|
||||
}
|
||||
} elseif (isset($this->services[$id])) {
|
||||
if (null === $service) {
|
||||
@trigger_error(sprintf('The "%s" service is already initialized, unsetting it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), E_USER_DEPRECATED);
|
||||
} else {
|
||||
@trigger_error(sprintf('The "%s" service is already initialized, replacing it is deprecated since Symfony 3.3 and will fail in 4.0.', $id), E_USER_DEPRECATED);
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($this->aliases[$id])) {
|
||||
unset($this->aliases[$id]);
|
||||
}
|
||||
|
||||
$this->services[$id] = $service;
|
||||
|
||||
if (method_exists($this, $method = 'synchronize'.strtr($id, $this->underscoreMap).'Service')) {
|
||||
$this->$method();
|
||||
}
|
||||
|
||||
if (null === $service) {
|
||||
if (self::SCOPE_CONTAINER !== $scope) {
|
||||
unset($this->scopedServices[$scope][$id]);
|
||||
}
|
||||
|
||||
unset($this->services[$id]);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->services[$id] = $service;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -208,18 +220,37 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
public function has($id)
|
||||
{
|
||||
for ($i = 2;;) {
|
||||
if ('service_container' === $id
|
||||
|| isset($this->aliases[$id])
|
||||
|| isset($this->services[$id])
|
||||
|| array_key_exists($id, $this->services)
|
||||
) {
|
||||
if (isset($this->privates[$id])) {
|
||||
@trigger_error(sprintf('The "%s" service is private, checking for its existence is deprecated since Symfony 3.2 and will fail in 4.0.', $id), E_USER_DEPRECATED);
|
||||
}
|
||||
if (isset($this->aliases[$id])) {
|
||||
$id = $this->aliases[$id];
|
||||
}
|
||||
if (isset($this->services[$id])) {
|
||||
return true;
|
||||
}
|
||||
if (--$i && $id !== $lcId = strtolower($id)) {
|
||||
$id = $lcId;
|
||||
} else {
|
||||
return method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service');
|
||||
if ('service_container' === $id) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (isset($this->fileMap[$id]) || isset($this->methodMap[$id])) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
|
||||
$id = $normalizedId;
|
||||
continue;
|
||||
}
|
||||
|
||||
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
|
||||
// and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
|
||||
if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, 'get'.strtr($id, $this->underscoreMap).'Service')) {
|
||||
@trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,7 +263,7 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
* @param string $id The service identifier
|
||||
* @param int $invalidBehavior The behavior when the service does not exist
|
||||
*
|
||||
* @return object The associated service
|
||||
* @return object|null The associated service
|
||||
*
|
||||
* @throws ServiceCircularReferenceException When a circular reference is detected
|
||||
* @throws ServiceNotFoundException When the service is not defined
|
||||
@@ -240,18 +271,22 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
*
|
||||
* @see Reference
|
||||
*/
|
||||
public function get($id, $invalidBehavior = self::EXCEPTION_ON_INVALID_REFERENCE)
|
||||
public function get($id, $invalidBehavior = /* self::EXCEPTION_ON_INVALID_REFERENCE */ 1)
|
||||
{
|
||||
// Attempt to retrieve the service by checking first aliases then
|
||||
// available services. Service IDs are case insensitive, however since
|
||||
// this method can be called thousands of times during a request, avoid
|
||||
// calling strtolower() unless necessary.
|
||||
// calling $this->normalizeId($id) unless necessary.
|
||||
for ($i = 2;;) {
|
||||
if (isset($this->privates[$id])) {
|
||||
@trigger_error(sprintf('The "%s" service is private, getting it from the container is deprecated since Symfony 3.2 and will fail in 4.0. You should either make the service public, or stop using the container directly and use dependency injection instead.', $id), E_USER_DEPRECATED);
|
||||
}
|
||||
if (isset($this->aliases[$id])) {
|
||||
$id = $this->aliases[$id];
|
||||
}
|
||||
|
||||
// Re-use shared service instance if it exists.
|
||||
if (isset($this->services[$id]) || array_key_exists($id, $this->services)) {
|
||||
if (isset($this->services[$id])) {
|
||||
return $this->services[$id];
|
||||
}
|
||||
if ('service_container' === $id) {
|
||||
@@ -259,59 +294,58 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
}
|
||||
|
||||
if (isset($this->loading[$id])) {
|
||||
throw new ServiceCircularReferenceException($id, array_keys($this->loading));
|
||||
}
|
||||
|
||||
if (isset($this->methodMap[$id])) {
|
||||
$method = $this->methodMap[$id];
|
||||
} elseif (--$i && $id !== $lcId = strtolower($id)) {
|
||||
$id = $lcId;
|
||||
continue;
|
||||
} elseif (method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
|
||||
// $method is set to the right value, proceed
|
||||
} else {
|
||||
if (self::EXCEPTION_ON_INVALID_REFERENCE === $invalidBehavior) {
|
||||
if (!$id) {
|
||||
throw new ServiceNotFoundException($id);
|
||||
}
|
||||
|
||||
$alternatives = array();
|
||||
foreach ($this->getServiceIds() as $knownId) {
|
||||
$lev = levenshtein($id, $knownId);
|
||||
if ($lev <= \strlen($id) / 3 || false !== strpos($knownId, $id)) {
|
||||
$alternatives[] = $knownId;
|
||||
}
|
||||
}
|
||||
|
||||
throw new ServiceNotFoundException($id, null, null, $alternatives);
|
||||
}
|
||||
|
||||
return;
|
||||
throw new ServiceCircularReferenceException($id, array_merge(array_keys($this->loading), [$id]));
|
||||
}
|
||||
|
||||
$this->loading[$id] = true;
|
||||
|
||||
try {
|
||||
$service = $this->$method();
|
||||
} catch (\Exception $e) {
|
||||
unset($this->loading[$id]);
|
||||
unset($this->services[$id]);
|
||||
if (isset($this->fileMap[$id])) {
|
||||
return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->load($this->fileMap[$id]);
|
||||
} elseif (isset($this->methodMap[$id])) {
|
||||
return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$this->methodMap[$id]}();
|
||||
} elseif (--$i && $id !== $normalizedId = $this->normalizeId($id)) {
|
||||
unset($this->loading[$id]);
|
||||
$id = $normalizedId;
|
||||
continue;
|
||||
} elseif (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class && method_exists($this, $method = 'get'.strtr($id, $this->underscoreMap).'Service')) {
|
||||
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
|
||||
// and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
|
||||
@trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED);
|
||||
|
||||
if ($e instanceof InactiveScopeException && self::EXCEPTION_ON_INVALID_REFERENCE !== $invalidBehavior) {
|
||||
return;
|
||||
return /* self::IGNORE_ON_UNINITIALIZED_REFERENCE */ 4 === $invalidBehavior ? null : $this->{$method}();
|
||||
}
|
||||
|
||||
throw $e;
|
||||
} catch (\Throwable $e) {
|
||||
unset($this->loading[$id]);
|
||||
break;
|
||||
} catch (\Exception $e) {
|
||||
unset($this->services[$id]);
|
||||
|
||||
throw $e;
|
||||
} finally {
|
||||
unset($this->loading[$id]);
|
||||
}
|
||||
}
|
||||
|
||||
if (/* self::EXCEPTION_ON_INVALID_REFERENCE */ 1 === $invalidBehavior) {
|
||||
if (!$id) {
|
||||
throw new ServiceNotFoundException($id);
|
||||
}
|
||||
if (isset($this->syntheticIds[$id])) {
|
||||
throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service is synthetic, it needs to be set at boot time before it can be used.', $id));
|
||||
}
|
||||
if (isset($this->getRemovedIds()[$id])) {
|
||||
throw new ServiceNotFoundException($id, null, null, [], sprintf('The "%s" service or alias has been removed or inlined when the container was compiled. You should either make it public, or stop using the container directly and use dependency injection instead.', $id));
|
||||
}
|
||||
|
||||
unset($this->loading[$id]);
|
||||
$alternatives = [];
|
||||
foreach ($this->getServiceIds() as $knownId) {
|
||||
$lev = levenshtein($id, $knownId);
|
||||
if ($lev <= \strlen($id) / 3 || false !== strpos($knownId, $id)) {
|
||||
$alternatives[] = $knownId;
|
||||
}
|
||||
}
|
||||
|
||||
return $service;
|
||||
throw new ServiceNotFoundException($id, null, null, $alternatives);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -324,19 +358,21 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
*/
|
||||
public function initialized($id)
|
||||
{
|
||||
$id = strtolower($id);
|
||||
$id = $this->normalizeId($id);
|
||||
|
||||
if (isset($this->privates[$id])) {
|
||||
@trigger_error(sprintf('Checking for the initialization of the "%s" private service is deprecated since Symfony 3.4 and won\'t be supported anymore in Symfony 4.0.', $id), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (isset($this->aliases[$id])) {
|
||||
$id = $this->aliases[$id];
|
||||
}
|
||||
|
||||
if ('service_container' === $id) {
|
||||
// BC: 'service_container' was a synthetic service previously.
|
||||
// @todo Change to false in next major release.
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
return isset($this->services[$id]) || array_key_exists($id, $this->services);
|
||||
return isset($this->services[$id]);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -344,204 +380,42 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
*/
|
||||
public function reset()
|
||||
{
|
||||
if (!empty($this->scopedServices)) {
|
||||
throw new LogicException('Resetting the container is not allowed when a scope is active.');
|
||||
}
|
||||
|
||||
$this->services = array();
|
||||
$this->services = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets all service ids.
|
||||
*
|
||||
* @return array An array of all defined service ids
|
||||
* @return string[] An array of all defined service ids
|
||||
*/
|
||||
public function getServiceIds()
|
||||
{
|
||||
$ids = array();
|
||||
foreach (get_class_methods($this) as $method) {
|
||||
if (preg_match('/^get(.+)Service$/', $method, $match)) {
|
||||
$ids[] = self::underscore($match[1]);
|
||||
$ids = [];
|
||||
|
||||
if (!$this->methodMap && !$this instanceof ContainerBuilder && __CLASS__ !== static::class) {
|
||||
// We only check the convention-based factory in a compiled container (i.e. a child class other than a ContainerBuilder,
|
||||
// and only when the dumper has not generated the method map (otherwise the method map is considered to be fully populated by the dumper)
|
||||
@trigger_error('Generating a dumped container without populating the method map is deprecated since Symfony 3.2 and will be unsupported in 4.0. Update your dumper to generate the method map.', E_USER_DEPRECATED);
|
||||
|
||||
foreach (get_class_methods($this) as $method) {
|
||||
if (preg_match('/^get(.+)Service$/', $method, $match)) {
|
||||
$ids[] = self::underscore($match[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
$ids[] = 'service_container';
|
||||
|
||||
return array_unique(array_merge($ids, array_keys($this->services)));
|
||||
return array_map('strval', array_unique(array_merge($ids, array_keys($this->methodMap), array_keys($this->fileMap), array_keys($this->aliases), array_keys($this->services))));
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called when you enter a scope.
|
||||
* Gets service ids that existed at compile time.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @throws RuntimeException When the parent scope is inactive
|
||||
* @throws InvalidArgumentException When the scope does not exist
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
* @return array
|
||||
*/
|
||||
public function enterScope($name)
|
||||
public function getRemovedIds()
|
||||
{
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!isset($this->scopes[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" does not exist.', $name));
|
||||
}
|
||||
|
||||
if (self::SCOPE_CONTAINER !== $this->scopes[$name] && !isset($this->scopedServices[$this->scopes[$name]])) {
|
||||
throw new RuntimeException(sprintf('The parent scope "%s" must be active when entering this scope.', $this->scopes[$name]));
|
||||
}
|
||||
|
||||
// check if a scope of this name is already active, if so we need to
|
||||
// remove all services of this scope, and those of any of its child
|
||||
// scopes from the global services map
|
||||
if (isset($this->scopedServices[$name])) {
|
||||
$services = array($this->services, $name => $this->scopedServices[$name]);
|
||||
unset($this->scopedServices[$name]);
|
||||
|
||||
foreach ($this->scopeChildren[$name] as $child) {
|
||||
if (isset($this->scopedServices[$child])) {
|
||||
$services[$child] = $this->scopedServices[$child];
|
||||
unset($this->scopedServices[$child]);
|
||||
}
|
||||
}
|
||||
|
||||
// update global map
|
||||
$this->services = \call_user_func_array('array_diff_key', $services);
|
||||
array_shift($services);
|
||||
|
||||
// add stack entry for this scope so we can restore the removed services later
|
||||
if (!isset($this->scopeStacks[$name])) {
|
||||
$this->scopeStacks[$name] = new \SplStack();
|
||||
}
|
||||
$this->scopeStacks[$name]->push($services);
|
||||
}
|
||||
|
||||
$this->scopedServices[$name] = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* This is called to leave the current scope, and move back to the parent
|
||||
* scope.
|
||||
*
|
||||
* @param string $name The name of the scope to leave
|
||||
*
|
||||
* @throws InvalidArgumentException if the scope is not active
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function leaveScope($name)
|
||||
{
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (!isset($this->scopedServices[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" is not active.', $name));
|
||||
}
|
||||
|
||||
// remove all services of this scope, or any of its child scopes from
|
||||
// the global service map
|
||||
$services = array($this->services, $this->scopedServices[$name]);
|
||||
unset($this->scopedServices[$name]);
|
||||
|
||||
foreach ($this->scopeChildren[$name] as $child) {
|
||||
if (isset($this->scopedServices[$child])) {
|
||||
$services[] = $this->scopedServices[$child];
|
||||
unset($this->scopedServices[$child]);
|
||||
}
|
||||
}
|
||||
|
||||
// update global map
|
||||
$this->services = \call_user_func_array('array_diff_key', $services);
|
||||
|
||||
// check if we need to restore services of a previous scope of this type
|
||||
if (isset($this->scopeStacks[$name]) && \count($this->scopeStacks[$name]) > 0) {
|
||||
$services = $this->scopeStacks[$name]->pop();
|
||||
$this->scopedServices += $services;
|
||||
|
||||
if ($this->scopeStacks[$name]->isEmpty()) {
|
||||
unset($this->scopeStacks[$name]);
|
||||
}
|
||||
|
||||
foreach ($services as $array) {
|
||||
foreach ($array as $id => $service) {
|
||||
$this->set($id, $service, $name);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a scope to the container.
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function addScope(ScopeInterface $scope)
|
||||
{
|
||||
$name = $scope->getName();
|
||||
$parentScope = $scope->getParentName();
|
||||
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
if (self::SCOPE_CONTAINER === $name || self::SCOPE_PROTOTYPE === $name) {
|
||||
throw new InvalidArgumentException(sprintf('The scope "%s" is reserved.', $name));
|
||||
}
|
||||
if (isset($this->scopes[$name])) {
|
||||
throw new InvalidArgumentException(sprintf('A scope with name "%s" already exists.', $name));
|
||||
}
|
||||
if (self::SCOPE_CONTAINER !== $parentScope && !isset($this->scopes[$parentScope])) {
|
||||
throw new InvalidArgumentException(sprintf('The parent scope "%s" does not exist, or is invalid.', $parentScope));
|
||||
}
|
||||
|
||||
$this->scopes[$name] = $parentScope;
|
||||
$this->scopeChildren[$name] = array();
|
||||
|
||||
// normalize the child relations
|
||||
while (self::SCOPE_CONTAINER !== $parentScope) {
|
||||
$this->scopeChildren[$parentScope][] = $name;
|
||||
$parentScope = $this->scopes[$parentScope];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this container has a certain scope.
|
||||
*
|
||||
* @param string $name The name of the scope
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function hasScope($name)
|
||||
{
|
||||
if ('request' !== $name) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return isset($this->scopes[$name]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether this scope is currently active.
|
||||
*
|
||||
* This does not actually check if the passed scope actually exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function isScopeActive($name)
|
||||
{
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
|
||||
return isset($this->scopedServices[$name]);
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -553,7 +427,7 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
*/
|
||||
public static function camelize($id)
|
||||
{
|
||||
return strtr(ucwords(strtr($id, array('_' => ' ', '.' => '_ ', '\\' => '_ '))), array(' ' => ''));
|
||||
return strtr(ucwords(strtr($id, ['_' => ' ', '.' => '_ ', '\\' => '_ '])), [' ' => '']);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -565,7 +439,85 @@ class Container implements IntrospectableContainerInterface, ResettableContainer
|
||||
*/
|
||||
public static function underscore($id)
|
||||
{
|
||||
return strtolower(preg_replace(array('/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'), array('\\1_\\2', '\\1_\\2'), str_replace('_', '.', $id)));
|
||||
return strtolower(preg_replace(['/([A-Z]+)([A-Z][a-z])/', '/([a-z\d])([A-Z])/'], ['\\1_\\2', '\\1_\\2'], str_replace('_', '.', $id)));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a service by requiring its factory file.
|
||||
*/
|
||||
protected function load($file)
|
||||
{
|
||||
return require $file;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetches a variable from the environment.
|
||||
*
|
||||
* @param string $name The name of the environment variable
|
||||
*
|
||||
* @return mixed The value to use for the provided environment variable name
|
||||
*
|
||||
* @throws EnvNotFoundException When the environment variable is not found and has no default value
|
||||
*/
|
||||
protected function getEnv($name)
|
||||
{
|
||||
if (isset($this->resolving[$envName = "env($name)"])) {
|
||||
throw new ParameterCircularReferenceException(array_keys($this->resolving));
|
||||
}
|
||||
if (isset($this->envCache[$name]) || \array_key_exists($name, $this->envCache)) {
|
||||
return $this->envCache[$name];
|
||||
}
|
||||
if (!$this->has($id = 'container.env_var_processors_locator')) {
|
||||
$this->set($id, new ServiceLocator([]));
|
||||
}
|
||||
if (!$this->getEnv) {
|
||||
$this->getEnv = new \ReflectionMethod($this, __FUNCTION__);
|
||||
$this->getEnv->setAccessible(true);
|
||||
$this->getEnv = $this->getEnv->getClosure($this);
|
||||
}
|
||||
$processors = $this->get($id);
|
||||
|
||||
if (false !== $i = strpos($name, ':')) {
|
||||
$prefix = substr($name, 0, $i);
|
||||
$localName = substr($name, 1 + $i);
|
||||
} else {
|
||||
$prefix = 'string';
|
||||
$localName = $name;
|
||||
}
|
||||
$processor = $processors->has($prefix) ? $processors->get($prefix) : new EnvVarProcessor($this);
|
||||
|
||||
$this->resolving[$envName] = true;
|
||||
try {
|
||||
return $this->envCache[$name] = $processor->getEnv($prefix, $localName, $this->getEnv);
|
||||
} finally {
|
||||
unset($this->resolving[$envName]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the case sensitive id used at registration time.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
public function normalizeId($id)
|
||||
{
|
||||
if (!\is_string($id)) {
|
||||
$id = (string) $id;
|
||||
}
|
||||
if (isset($this->normalizedIds[$normalizedId = strtolower($id)])) {
|
||||
$normalizedId = $this->normalizedIds[$normalizedId];
|
||||
if ($id !== $normalizedId) {
|
||||
@trigger_error(sprintf('Service identifiers will be made case sensitive in Symfony 4.0. Using "%s" instead of "%s" is deprecated since Symfony 3.3.', $id, $normalizedId), E_USER_DEPRECATED);
|
||||
}
|
||||
} else {
|
||||
$normalizedId = $this->normalizedIds[$normalizedId] = $id;
|
||||
}
|
||||
|
||||
return $normalizedId;
|
||||
}
|
||||
|
||||
private function __clone()
|
||||
|
||||
1021
vendor/symfony/dependency-injection/ContainerBuilder.php
vendored
1021
vendor/symfony/dependency-injection/ContainerBuilder.php
vendored
File diff suppressed because it is too large
Load Diff
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Psr\Container\ContainerInterface as PsrContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
@@ -21,24 +22,20 @@ use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
interface ContainerInterface
|
||||
interface ContainerInterface extends PsrContainerInterface
|
||||
{
|
||||
const EXCEPTION_ON_INVALID_REFERENCE = 1;
|
||||
const NULL_ON_INVALID_REFERENCE = 2;
|
||||
const IGNORE_ON_INVALID_REFERENCE = 3;
|
||||
const SCOPE_CONTAINER = 'container';
|
||||
const SCOPE_PROTOTYPE = 'prototype';
|
||||
const IGNORE_ON_UNINITIALIZED_REFERENCE = 4;
|
||||
|
||||
/**
|
||||
* Sets a service.
|
||||
*
|
||||
* Note: The $scope parameter is deprecated since version 2.8 and will be removed in 3.0.
|
||||
*
|
||||
* @param string $id The service identifier
|
||||
* @param object $service The service instance
|
||||
* @param string $scope The scope of the service
|
||||
* @param string $id The service identifier
|
||||
* @param object|null $service The service instance
|
||||
*/
|
||||
public function set($id, $service, $scope = self::SCOPE_CONTAINER);
|
||||
public function set($id, $service);
|
||||
|
||||
/**
|
||||
* Gets a service.
|
||||
@@ -46,7 +43,7 @@ interface ContainerInterface
|
||||
* @param string $id The service identifier
|
||||
* @param int $invalidBehavior The behavior when the service does not exist
|
||||
*
|
||||
* @return object The associated service
|
||||
* @return object|null The associated service
|
||||
*
|
||||
* @throws ServiceCircularReferenceException When a circular reference is detected
|
||||
* @throws ServiceNotFoundException When the service is not defined
|
||||
@@ -64,6 +61,15 @@ interface ContainerInterface
|
||||
*/
|
||||
public function has($id);
|
||||
|
||||
/**
|
||||
* Check for whether or not a service has been initialized.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return bool true if the service has been initialized, false otherwise
|
||||
*/
|
||||
public function initialized($id);
|
||||
|
||||
/**
|
||||
* Gets a parameter.
|
||||
*
|
||||
@@ -91,55 +97,4 @@ interface ContainerInterface
|
||||
* @param mixed $value The parameter value
|
||||
*/
|
||||
public function setParameter($name, $value);
|
||||
|
||||
/**
|
||||
* Enters the given scope.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function enterScope($name);
|
||||
|
||||
/**
|
||||
* Leaves the current scope, and re-enters the parent scope.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function leaveScope($name);
|
||||
|
||||
/**
|
||||
* Adds a scope to the container.
|
||||
*
|
||||
* @param ScopeInterface $scope
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function addScope(ScopeInterface $scope);
|
||||
|
||||
/**
|
||||
* Whether this container has the given scope.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function hasScope($name);
|
||||
|
||||
/**
|
||||
* Determines whether the given scope is currently active.
|
||||
*
|
||||
* It does however not check if the scope actually exists.
|
||||
*
|
||||
* @param string $name
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function isScopeActive($name);
|
||||
}
|
||||
|
||||
438
vendor/symfony/dependency-injection/Definition.php
vendored
438
vendor/symfony/dependency-injection/Definition.php
vendored
@@ -11,6 +11,7 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\BoundArgument;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
|
||||
|
||||
@@ -24,40 +25,67 @@ class Definition
|
||||
private $class;
|
||||
private $file;
|
||||
private $factory;
|
||||
private $factoryClass;
|
||||
private $factoryMethod;
|
||||
private $factoryService;
|
||||
private $shared = true;
|
||||
private $deprecated = false;
|
||||
private $deprecationTemplate;
|
||||
private $scope = ContainerInterface::SCOPE_CONTAINER;
|
||||
private $properties = array();
|
||||
private $calls = array();
|
||||
private $properties = [];
|
||||
private $calls = [];
|
||||
private $instanceof = [];
|
||||
private $autoconfigured = false;
|
||||
private $configurator;
|
||||
private $tags = array();
|
||||
private $tags = [];
|
||||
private $public = true;
|
||||
private $private = true;
|
||||
private $synthetic = false;
|
||||
private $abstract = false;
|
||||
private $synchronized = false;
|
||||
private $lazy = false;
|
||||
private $decoratedService;
|
||||
private $autowired = false;
|
||||
private $autowiringTypes = array();
|
||||
private $autowiringTypes = [];
|
||||
private $changes = [];
|
||||
private $bindings = [];
|
||||
private $errors = [];
|
||||
|
||||
protected $arguments = [];
|
||||
|
||||
private static $defaultDeprecationTemplate = 'The "%service_id%" service is deprecated. You should stop using it, as it will soon be removed.';
|
||||
|
||||
protected $arguments;
|
||||
|
||||
/**
|
||||
* @param string|null $class The service class
|
||||
* @param array $arguments An array of arguments to pass to the service constructor
|
||||
*/
|
||||
public function __construct($class = null, array $arguments = array())
|
||||
public function __construct($class = null, array $arguments = [])
|
||||
{
|
||||
$this->class = $class;
|
||||
if (null !== $class) {
|
||||
$this->setClass($class);
|
||||
}
|
||||
$this->arguments = $arguments;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all changes tracked for the Definition object.
|
||||
*
|
||||
* @return array An array of changes for this Definition
|
||||
*/
|
||||
public function getChanges()
|
||||
{
|
||||
return $this->changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the tracked changes for the Definition object.
|
||||
*
|
||||
* @param array $changes An array of changes for this Definition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setChanges(array $changes)
|
||||
{
|
||||
$this->changes = $changes;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a factory.
|
||||
*
|
||||
@@ -67,6 +95,8 @@ class Definition
|
||||
*/
|
||||
public function setFactory($factory)
|
||||
{
|
||||
$this->changes['factory'] = true;
|
||||
|
||||
if (\is_string($factory) && false !== strpos($factory, '::')) {
|
||||
$factory = explode('::', $factory, 2);
|
||||
}
|
||||
@@ -86,59 +116,6 @@ class Definition
|
||||
return $this->factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the class that acts as a factory using the factory method,
|
||||
* which will be invoked statically.
|
||||
*
|
||||
* @param string $factoryClass The factory class name
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function setFactoryClass($factoryClass)
|
||||
{
|
||||
@trigger_error(sprintf('%s(%s) is deprecated since Symfony 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryClass), E_USER_DEPRECATED);
|
||||
|
||||
$this->factoryClass = $factoryClass;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory class.
|
||||
*
|
||||
* @return string|null The factory class name
|
||||
*
|
||||
* @deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function getFactoryClass($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->factoryClass;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the factory method able to create an instance of this class.
|
||||
*
|
||||
* @param string $factoryMethod The factory method name
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function setFactoryMethod($factoryMethod)
|
||||
{
|
||||
@trigger_error(sprintf('%s(%s) is deprecated since Symfony 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryMethod), E_USER_DEPRECATED);
|
||||
|
||||
$this->factoryMethod = $factoryMethod;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service that this service is decorating.
|
||||
*
|
||||
@@ -153,13 +130,15 @@ class Definition
|
||||
public function setDecoratedService($id, $renamedId = null, $priority = 0)
|
||||
{
|
||||
if ($renamedId && $id === $renamedId) {
|
||||
throw new \InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
|
||||
throw new InvalidArgumentException(sprintf('The decorated service inner name for "%s" must be different than the service name itself.', $id));
|
||||
}
|
||||
|
||||
$this->changes['decorated_service'] = true;
|
||||
|
||||
if (null === $id) {
|
||||
$this->decoratedService = null;
|
||||
} else {
|
||||
$this->decoratedService = array($id, $renamedId, (int) $priority);
|
||||
$this->decoratedService = [$id, $renamedId, (int) $priority];
|
||||
}
|
||||
|
||||
return $this;
|
||||
@@ -175,58 +154,6 @@ class Definition
|
||||
return $this->decoratedService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory method.
|
||||
*
|
||||
* @return string|null The factory method name
|
||||
*
|
||||
* @deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function getFactoryMethod($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->factoryMethod;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the name of the service that acts as a factory using the factory method.
|
||||
*
|
||||
* @param string $factoryService The factory service id
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function setFactoryService($factoryService, $triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error(sprintf('%s(%s) is deprecated since Symfony 2.6 and will be removed in 3.0. Use Definition::setFactory() instead.', __METHOD__, $factoryService), E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->factoryService = $factoryService;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the factory service id.
|
||||
*
|
||||
* @return string|null The factory service id
|
||||
*
|
||||
* @deprecated since version 2.6, to be removed in 3.0.
|
||||
*/
|
||||
public function getFactoryService($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.6 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->factoryService;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the service class.
|
||||
*
|
||||
@@ -236,6 +163,8 @@ class Definition
|
||||
*/
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->changes['class'] = true;
|
||||
|
||||
$this->class = $class;
|
||||
|
||||
return $this;
|
||||
@@ -317,8 +246,8 @@ class Definition
|
||||
/**
|
||||
* Replaces a specific argument.
|
||||
*
|
||||
* @param int $index
|
||||
* @param mixed $argument
|
||||
* @param int|string $index
|
||||
* @param mixed $argument
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
@@ -330,15 +259,34 @@ class Definition
|
||||
throw new OutOfBoundsException('Cannot replace arguments if none have been configured yet.');
|
||||
}
|
||||
|
||||
if ($index < 0 || $index > \count($this->arguments) - 1) {
|
||||
if (\is_int($index) && ($index < 0 || $index > \count($this->arguments) - 1)) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, \count($this->arguments) - 1));
|
||||
}
|
||||
|
||||
if (!\array_key_exists($index, $this->arguments)) {
|
||||
throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
|
||||
}
|
||||
|
||||
$this->arguments[$index] = $argument;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a specific argument.
|
||||
*
|
||||
* @param int|string $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setArgument($key, $value)
|
||||
{
|
||||
$this->arguments[$key] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the arguments to pass to the service constructor/factory method.
|
||||
*
|
||||
@@ -352,7 +300,7 @@ class Definition
|
||||
/**
|
||||
* Gets an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param int $index
|
||||
* @param int|string $index
|
||||
*
|
||||
* @return mixed The argument value
|
||||
*
|
||||
@@ -360,8 +308,8 @@ class Definition
|
||||
*/
|
||||
public function getArgument($index)
|
||||
{
|
||||
if ($index < 0 || $index > \count($this->arguments) - 1) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, \count($this->arguments) - 1));
|
||||
if (!\array_key_exists($index, $this->arguments)) {
|
||||
throw new OutOfBoundsException(sprintf('The argument "%s" doesn\'t exist.', $index));
|
||||
}
|
||||
|
||||
return $this->arguments[$index];
|
||||
@@ -372,9 +320,9 @@ class Definition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setMethodCalls(array $calls = array())
|
||||
public function setMethodCalls(array $calls = [])
|
||||
{
|
||||
$this->calls = array();
|
||||
$this->calls = [];
|
||||
foreach ($calls as $call) {
|
||||
$this->addMethodCall($call[0], $call[1]);
|
||||
}
|
||||
@@ -392,12 +340,12 @@ class Definition
|
||||
*
|
||||
* @throws InvalidArgumentException on empty $method param
|
||||
*/
|
||||
public function addMethodCall($method, array $arguments = array())
|
||||
public function addMethodCall($method, array $arguments = [])
|
||||
{
|
||||
if (empty($method)) {
|
||||
throw new InvalidArgumentException('Method name cannot be empty.');
|
||||
}
|
||||
$this->calls[] = array($method, $arguments);
|
||||
$this->calls[] = [$method, $arguments];
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -449,6 +397,54 @@ class Definition
|
||||
return $this->calls;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the definition templates to conditionally apply on the current definition, keyed by parent interface/class.
|
||||
*
|
||||
* @param ChildDefinition[] $instanceof
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setInstanceofConditionals(array $instanceof)
|
||||
{
|
||||
$this->instanceof = $instanceof;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the definition templates to conditionally apply on the current definition, keyed by parent interface/class.
|
||||
*
|
||||
* @return ChildDefinition[]
|
||||
*/
|
||||
public function getInstanceofConditionals()
|
||||
{
|
||||
return $this->instanceof;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets whether or not instanceof conditionals should be prepended with a global set.
|
||||
*
|
||||
* @param bool $autoconfigured
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setAutoconfigured($autoconfigured)
|
||||
{
|
||||
$this->changes['autoconfigured'] = true;
|
||||
|
||||
$this->autoconfigured = $autoconfigured;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function isAutoconfigured()
|
||||
{
|
||||
return $this->autoconfigured;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets tags for this definition.
|
||||
*
|
||||
@@ -480,7 +476,7 @@ class Definition
|
||||
*/
|
||||
public function getTag($name)
|
||||
{
|
||||
return isset($this->tags[$name]) ? $this->tags[$name] : array();
|
||||
return isset($this->tags[$name]) ? $this->tags[$name] : [];
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -491,7 +487,7 @@ class Definition
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function addTag($name, array $attributes = array())
|
||||
public function addTag($name, array $attributes = [])
|
||||
{
|
||||
$this->tags[$name][] = $attributes;
|
||||
|
||||
@@ -531,7 +527,7 @@ class Definition
|
||||
*/
|
||||
public function clearTags()
|
||||
{
|
||||
$this->tags = array();
|
||||
$this->tags = [];
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -545,6 +541,8 @@ class Definition
|
||||
*/
|
||||
public function setFile($file)
|
||||
{
|
||||
$this->changes['file'] = true;
|
||||
|
||||
$this->file = $file;
|
||||
|
||||
return $this;
|
||||
@@ -569,6 +567,8 @@ class Definition
|
||||
*/
|
||||
public function setShared($shared)
|
||||
{
|
||||
$this->changes['shared'] = true;
|
||||
|
||||
$this->shared = (bool) $shared;
|
||||
|
||||
return $this;
|
||||
@@ -584,46 +584,6 @@ class Definition
|
||||
return $this->shared;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the scope of the service.
|
||||
*
|
||||
* @param string $scope Whether the service must be shared or not
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function setScope($scope, $triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $scope) {
|
||||
$this->setShared(false);
|
||||
}
|
||||
|
||||
$this->scope = $scope;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the scope of the service.
|
||||
*
|
||||
* @return string
|
||||
*
|
||||
* @deprecated since version 2.8, to be removed in 3.0.
|
||||
*/
|
||||
public function getScope($triggerDeprecationError = true)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.8 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->scope;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the visibility of this service.
|
||||
*
|
||||
@@ -633,7 +593,10 @@ class Definition
|
||||
*/
|
||||
public function setPublic($boolean)
|
||||
{
|
||||
$this->changes['public'] = true;
|
||||
|
||||
$this->public = (bool) $boolean;
|
||||
$this->private = false;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -649,39 +612,32 @@ class Definition
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the synchronized flag of this service.
|
||||
* Sets if this service is private.
|
||||
*
|
||||
* When set, the "private" state has a higher precedence than "public".
|
||||
* In version 3.4, a "private" service always remains publicly accessible,
|
||||
* but triggers a deprecation notice when accessed from the container,
|
||||
* so that the service can be made really private in 4.0.
|
||||
*
|
||||
* @param bool $boolean
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 2.7, will be removed in 3.0.
|
||||
*/
|
||||
public function setSynchronized($boolean, $triggerDeprecationError = true)
|
||||
public function setPrivate($boolean)
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
$this->synchronized = (bool) $boolean;
|
||||
$this->private = (bool) $boolean;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Whether this service is synchronized.
|
||||
* Whether this service is private.
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since version 2.7, will be removed in 3.0.
|
||||
*/
|
||||
public function isSynchronized($triggerDeprecationError = true)
|
||||
public function isPrivate()
|
||||
{
|
||||
if ($triggerDeprecationError) {
|
||||
@trigger_error('The '.__METHOD__.' method is deprecated since Symfony 2.7 and will be removed in 3.0.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return $this->synchronized;
|
||||
return $this->private;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -693,6 +649,8 @@ class Definition
|
||||
*/
|
||||
public function setLazy($lazy)
|
||||
{
|
||||
$this->changes['lazy'] = true;
|
||||
|
||||
$this->lazy = (bool) $lazy;
|
||||
|
||||
return $this;
|
||||
@@ -785,6 +743,8 @@ class Definition
|
||||
$this->deprecationTemplate = $template;
|
||||
}
|
||||
|
||||
$this->changes['deprecated'] = true;
|
||||
|
||||
$this->deprecated = (bool) $status;
|
||||
|
||||
return $this;
|
||||
@@ -816,13 +776,19 @@ class Definition
|
||||
/**
|
||||
* Sets a configurator to call after the service is fully initialized.
|
||||
*
|
||||
* @param callable $callable A PHP callable
|
||||
* @param string|array $configurator A PHP callable
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setConfigurator($callable)
|
||||
public function setConfigurator($configurator)
|
||||
{
|
||||
$this->configurator = $callable;
|
||||
$this->changes['configurator'] = true;
|
||||
|
||||
if (\is_string($configurator) && false !== strpos($configurator, '::')) {
|
||||
$configurator = explode('::', $configurator, 2);
|
||||
}
|
||||
|
||||
$this->configurator = $configurator;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -830,7 +796,7 @@ class Definition
|
||||
/**
|
||||
* Gets the configurator to call after the service is fully initialized.
|
||||
*
|
||||
* @return callable|null The PHP callable to call
|
||||
* @return callable|array|null
|
||||
*/
|
||||
public function getConfigurator()
|
||||
{
|
||||
@@ -843,10 +809,14 @@ class Definition
|
||||
* @param string[] $types
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function setAutowiringTypes(array $types)
|
||||
{
|
||||
$this->autowiringTypes = array();
|
||||
@trigger_error('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead.', E_USER_DEPRECATED);
|
||||
|
||||
$this->autowiringTypes = [];
|
||||
|
||||
foreach ($types as $type) {
|
||||
$this->autowiringTypes[$type] = true;
|
||||
@@ -874,7 +844,9 @@ class Definition
|
||||
*/
|
||||
public function setAutowired($autowired)
|
||||
{
|
||||
$this->autowired = $autowired;
|
||||
$this->changes['autowired'] = true;
|
||||
|
||||
$this->autowired = (bool) $autowired;
|
||||
|
||||
return $this;
|
||||
}
|
||||
@@ -883,9 +855,15 @@ class Definition
|
||||
* Gets autowiring types that will default to this definition.
|
||||
*
|
||||
* @return string[]
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function getAutowiringTypes()
|
||||
public function getAutowiringTypes(/*$triggerDeprecation = true*/)
|
||||
{
|
||||
if (1 > \func_num_args() || func_get_arg(0)) {
|
||||
@trigger_error('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead.', E_USER_DEPRECATED);
|
||||
}
|
||||
|
||||
return array_keys($this->autowiringTypes);
|
||||
}
|
||||
|
||||
@@ -895,9 +873,13 @@ class Definition
|
||||
* @param string $type
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function addAutowiringType($type)
|
||||
{
|
||||
@trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), E_USER_DEPRECATED);
|
||||
|
||||
$this->autowiringTypes[$type] = true;
|
||||
|
||||
return $this;
|
||||
@@ -909,9 +891,13 @@ class Definition
|
||||
* @param string $type
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function removeAutowiringType($type)
|
||||
{
|
||||
@trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), E_USER_DEPRECATED);
|
||||
|
||||
unset($this->autowiringTypes[$type]);
|
||||
|
||||
return $this;
|
||||
@@ -923,9 +909,65 @@ class Definition
|
||||
* @param string $type
|
||||
*
|
||||
* @return bool
|
||||
*
|
||||
* @deprecated since version 3.3, to be removed in 4.0.
|
||||
*/
|
||||
public function hasAutowiringType($type)
|
||||
{
|
||||
@trigger_error(sprintf('Autowiring-types are deprecated since Symfony 3.3 and will be removed in 4.0. Use aliases instead for "%s".', $type), E_USER_DEPRECATED);
|
||||
|
||||
return isset($this->autowiringTypes[$type]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets bindings.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getBindings()
|
||||
{
|
||||
return $this->bindings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets bindings.
|
||||
*
|
||||
* Bindings map $named or FQCN arguments to values that should be
|
||||
* injected in the matching parameters (of the constructor, of methods
|
||||
* called and of controller actions).
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
public function setBindings(array $bindings)
|
||||
{
|
||||
foreach ($bindings as $key => $binding) {
|
||||
if (!$binding instanceof BoundArgument) {
|
||||
$bindings[$key] = new BoundArgument($binding);
|
||||
}
|
||||
}
|
||||
|
||||
$this->bindings = $bindings;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add an error that occurred when building this Definition.
|
||||
*
|
||||
* @param string $error
|
||||
*/
|
||||
public function addError($error)
|
||||
{
|
||||
$this->errors[] = $error;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns any errors that occurred while building this Definition.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function getErrors()
|
||||
{
|
||||
return $this->errors;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,219 +11,19 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Exception\OutOfBoundsException;
|
||||
@trigger_error('The '.__NAMESPACE__.'\DefinitionDecorator class is deprecated since Symfony 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.', E_USER_DEPRECATED);
|
||||
|
||||
/**
|
||||
* This definition decorates another definition.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class DefinitionDecorator extends Definition
|
||||
{
|
||||
private $parent;
|
||||
private $changes = array();
|
||||
class_exists(ChildDefinition::class);
|
||||
|
||||
if (false) {
|
||||
/**
|
||||
* @param string $parent The id of Definition instance to decorate
|
||||
*/
|
||||
public function __construct($parent)
|
||||
{
|
||||
parent::__construct();
|
||||
|
||||
$this->parent = $parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the Definition being decorated.
|
||||
* This definition decorates another definition.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getParent()
|
||||
{
|
||||
return $this->parent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all changes tracked for the Definition object.
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*
|
||||
* @return array An array of changes for this Definition
|
||||
* @deprecated The DefinitionDecorator class is deprecated since version 3.3 and will be removed in 4.0. Use the Symfony\Component\DependencyInjection\ChildDefinition class instead.
|
||||
*/
|
||||
public function getChanges()
|
||||
class DefinitionDecorator extends Definition
|
||||
{
|
||||
return $this->changes;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setClass($class)
|
||||
{
|
||||
$this->changes['class'] = true;
|
||||
|
||||
return parent::setClass($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFactory($callable)
|
||||
{
|
||||
$this->changes['factory'] = true;
|
||||
|
||||
return parent::setFactory($callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFactoryClass($class)
|
||||
{
|
||||
$this->changes['factory_class'] = true;
|
||||
|
||||
return parent::setFactoryClass($class);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFactoryMethod($method)
|
||||
{
|
||||
$this->changes['factory_method'] = true;
|
||||
|
||||
return parent::setFactoryMethod($method);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFactoryService($service, $triggerDeprecationError = true)
|
||||
{
|
||||
$this->changes['factory_service'] = true;
|
||||
|
||||
return parent::setFactoryService($service, $triggerDeprecationError);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setConfigurator($callable)
|
||||
{
|
||||
$this->changes['configurator'] = true;
|
||||
|
||||
return parent::setConfigurator($callable);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setFile($file)
|
||||
{
|
||||
$this->changes['file'] = true;
|
||||
|
||||
return parent::setFile($file);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setPublic($boolean)
|
||||
{
|
||||
$this->changes['public'] = true;
|
||||
|
||||
return parent::setPublic($boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setLazy($boolean)
|
||||
{
|
||||
$this->changes['lazy'] = true;
|
||||
|
||||
return parent::setLazy($boolean);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDecoratedService($id, $renamedId = null, $priority = 0)
|
||||
{
|
||||
$this->changes['decorated_service'] = true;
|
||||
|
||||
return parent::setDecoratedService($id, $renamedId, $priority);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setDeprecated($boolean = true, $template = null)
|
||||
{
|
||||
$this->changes['deprecated'] = true;
|
||||
|
||||
return parent::setDeprecated($boolean, $template);
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function setAutowired($autowired)
|
||||
{
|
||||
$this->changes['autowire'] = true;
|
||||
|
||||
return parent::setAutowired($autowired);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* If replaceArgument() has been used to replace an argument, this method
|
||||
* will return the replacement value.
|
||||
*
|
||||
* @param int $index
|
||||
*
|
||||
* @return mixed The argument value
|
||||
*
|
||||
* @throws OutOfBoundsException When the argument does not exist
|
||||
*/
|
||||
public function getArgument($index)
|
||||
{
|
||||
if (array_key_exists('index_'.$index, $this->arguments)) {
|
||||
return $this->arguments['index_'.$index];
|
||||
}
|
||||
|
||||
$lastIndex = \count(array_filter(array_keys($this->arguments), 'is_int')) - 1;
|
||||
|
||||
if ($index < 0 || $index > $lastIndex) {
|
||||
throw new OutOfBoundsException(sprintf('The index "%d" is not in the range [0, %d].', $index, $lastIndex));
|
||||
}
|
||||
|
||||
return $this->arguments[$index];
|
||||
}
|
||||
|
||||
/**
|
||||
* You should always use this method when overwriting existing arguments
|
||||
* of the parent definition.
|
||||
*
|
||||
* If you directly call setArguments() keep in mind that you must follow
|
||||
* certain conventions when you want to overwrite the arguments of the
|
||||
* parent definition, otherwise your arguments will only be appended.
|
||||
*
|
||||
* @param int $index
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when $index isn't an integer
|
||||
*/
|
||||
public function replaceArgument($index, $value)
|
||||
{
|
||||
if (!\is_int($index)) {
|
||||
throw new InvalidArgumentException('$index must be an integer.');
|
||||
}
|
||||
|
||||
$this->arguments['index_'.$index] = $value;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,9 +21,7 @@ interface DumperInterface
|
||||
/**
|
||||
* Dumps the service container.
|
||||
*
|
||||
* @param array $options An array of options
|
||||
*
|
||||
* @return string The representation of the service container
|
||||
* @return string|array The representation of the service container
|
||||
*/
|
||||
public function dump(array $options = array());
|
||||
public function dump(array $options = []);
|
||||
}
|
||||
|
||||
@@ -11,14 +11,13 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ParameterNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\Scope;
|
||||
|
||||
/**
|
||||
* GraphvizDumper dumps a service container as a graphviz file.
|
||||
@@ -33,14 +32,14 @@ class GraphvizDumper extends Dumper
|
||||
{
|
||||
private $nodes;
|
||||
private $edges;
|
||||
private $options = array(
|
||||
'graph' => array('ratio' => 'compress'),
|
||||
'node' => array('fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'),
|
||||
'edge' => array('fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5),
|
||||
'node.instance' => array('fillcolor' => '#9999ff', 'style' => 'filled'),
|
||||
'node.definition' => array('fillcolor' => '#eeeeee'),
|
||||
'node.missing' => array('fillcolor' => '#ff9999', 'style' => 'filled'),
|
||||
);
|
||||
private $options = [
|
||||
'graph' => ['ratio' => 'compress'],
|
||||
'node' => ['fontsize' => 11, 'fontname' => 'Arial', 'shape' => 'record'],
|
||||
'edge' => ['fontsize' => 9, 'fontname' => 'Arial', 'color' => 'grey', 'arrowhead' => 'open', 'arrowsize' => 0.5],
|
||||
'node.instance' => ['fillcolor' => '#9999ff', 'style' => 'filled'],
|
||||
'node.definition' => ['fillcolor' => '#eeeeee'],
|
||||
'node.missing' => ['fillcolor' => '#ff9999', 'style' => 'filled'],
|
||||
];
|
||||
|
||||
/**
|
||||
* Dumps the service container as a graphviz graph.
|
||||
@@ -56,9 +55,9 @@ class GraphvizDumper extends Dumper
|
||||
*
|
||||
* @return string The dot representation of the service container
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
public function dump(array $options = [])
|
||||
{
|
||||
foreach (array('graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing') as $key) {
|
||||
foreach (['graph', 'node', 'edge', 'node.instance', 'node.definition', 'node.missing'] as $key) {
|
||||
if (isset($options[$key])) {
|
||||
$this->options[$key] = array_merge($this->options[$key], $options[$key]);
|
||||
}
|
||||
@@ -66,7 +65,7 @@ class GraphvizDumper extends Dumper
|
||||
|
||||
$this->nodes = $this->findNodes();
|
||||
|
||||
$this->edges = array();
|
||||
$this->edges = [];
|
||||
foreach ($this->container->getDefinitions() as $id => $definition) {
|
||||
$this->edges[$id] = array_merge(
|
||||
$this->findEdges($id, $definition->getArguments(), true, ''),
|
||||
@@ -81,7 +80,7 @@ class GraphvizDumper extends Dumper
|
||||
}
|
||||
}
|
||||
|
||||
return $this->startDot().$this->addNodes().$this->addEdges().$this->endDot();
|
||||
return $this->container->resolveEnvPlaceholders($this->startDot().$this->addNodes().$this->addEdges().$this->endDot(), '__ENV_%s__');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -111,7 +110,7 @@ class GraphvizDumper extends Dumper
|
||||
$code = '';
|
||||
foreach ($this->edges as $id => $edges) {
|
||||
foreach ($edges as $edge) {
|
||||
$code .= sprintf(" node_%s -> node_%s [label=\"%s\" style=\"%s\"];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed');
|
||||
$code .= sprintf(" node_%s -> node_%s [label=\"%s\" style=\"%s\"%s];\n", $this->dotize($id), $this->dotize($edge['to']), $edge['name'], $edge['required'] ? 'filled' : 'dashed', $edge['lazy'] ? ' color="#9999ff"' : '');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -128,9 +127,9 @@ class GraphvizDumper extends Dumper
|
||||
*
|
||||
* @return array An array of edges
|
||||
*/
|
||||
private function findEdges($id, array $arguments, $required, $name)
|
||||
private function findEdges($id, array $arguments, $required, $name, $lazy = false)
|
||||
{
|
||||
$edges = array();
|
||||
$edges = [];
|
||||
foreach ($arguments as $argument) {
|
||||
if ($argument instanceof Parameter) {
|
||||
$argument = $this->container->hasParameter($argument) ? $this->container->getParameter($argument) : null;
|
||||
@@ -139,13 +138,27 @@ class GraphvizDumper extends Dumper
|
||||
}
|
||||
|
||||
if ($argument instanceof Reference) {
|
||||
$lazyEdge = $lazy;
|
||||
|
||||
if (!$this->container->has((string) $argument)) {
|
||||
$this->nodes[(string) $argument] = array('name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']);
|
||||
$this->nodes[(string) $argument] = ['name' => $name, 'required' => $required, 'class' => '', 'attributes' => $this->options['node.missing']];
|
||||
} elseif ('service_container' !== (string) $argument) {
|
||||
$lazyEdge = $lazy || $this->container->getDefinition((string) $argument)->isLazy();
|
||||
}
|
||||
|
||||
$edges[] = array('name' => $name, 'required' => $required, 'to' => $argument);
|
||||
$edges[] = ['name' => $name, 'required' => $required, 'to' => $argument, 'lazy' => $lazyEdge];
|
||||
} elseif ($argument instanceof ArgumentInterface) {
|
||||
$edges = array_merge($edges, $this->findEdges($id, $argument->getValues(), $required, $name, true));
|
||||
} elseif ($argument instanceof Definition) {
|
||||
$edges = array_merge($edges,
|
||||
$this->findEdges($id, $argument->getArguments(), $required, ''),
|
||||
$this->findEdges($id, $argument->getProperties(), false, '')
|
||||
);
|
||||
foreach ($argument->getMethodCalls() as $call) {
|
||||
$edges = array_merge($edges, $this->findEdges($id, $call[1], false, $call[0].'()'));
|
||||
}
|
||||
} elseif (\is_array($argument)) {
|
||||
$edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name));
|
||||
$edges = array_merge($edges, $this->findEdges($id, $argument, $required, $name, $lazy));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -159,7 +172,7 @@ class GraphvizDumper extends Dumper
|
||||
*/
|
||||
private function findNodes()
|
||||
{
|
||||
$nodes = array();
|
||||
$nodes = [];
|
||||
|
||||
$container = $this->cloneContainer();
|
||||
|
||||
@@ -175,20 +188,17 @@ class GraphvizDumper extends Dumper
|
||||
} catch (ParameterNotFoundException $e) {
|
||||
}
|
||||
|
||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], array('style' => $definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false) ? 'filled' : 'dotted')));
|
||||
$nodes[$id] = ['class' => str_replace('\\', '\\\\', $class), 'attributes' => array_merge($this->options['node.definition'], ['style' => $definition->isShared() ? 'filled' : 'dotted'])];
|
||||
$container->setDefinition($id, new Definition('stdClass'));
|
||||
}
|
||||
|
||||
foreach ($container->getServiceIds() as $id) {
|
||||
$service = $container->get($id);
|
||||
|
||||
if (array_key_exists($id, $container->getAliases())) {
|
||||
if (\array_key_exists($id, $container->getAliases())) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!$container->hasDefinition($id)) {
|
||||
$class = ('service_container' === $id) ? \get_class($this->container) : \get_class($service);
|
||||
$nodes[$id] = array('class' => str_replace('\\', '\\\\', $class), 'attributes' => $this->options['node.instance']);
|
||||
$nodes[$id] = ['class' => str_replace('\\', '\\\\', \get_class($container->get($id))), 'attributes' => $this->options['node.instance']];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -203,9 +213,6 @@ class GraphvizDumper extends Dumper
|
||||
$container->setDefinitions($this->container->getDefinitions());
|
||||
$container->setAliases($this->container->getAliases());
|
||||
$container->setResources($this->container->getResources());
|
||||
foreach ($this->container->getScopes(false) as $scope => $parentScope) {
|
||||
$container->addScope(new Scope($scope, $parentScope));
|
||||
}
|
||||
foreach ($this->container->getExtensions() as $extension) {
|
||||
$container->registerExtension($extension);
|
||||
}
|
||||
@@ -246,7 +253,7 @@ class GraphvizDumper extends Dumper
|
||||
*/
|
||||
private function addAttributes(array $attributes)
|
||||
{
|
||||
$code = array();
|
||||
$code = [];
|
||||
foreach ($attributes as $k => $v) {
|
||||
$code[] = sprintf('%s="%s"', $k, $v);
|
||||
}
|
||||
@@ -263,7 +270,7 @@ class GraphvizDumper extends Dumper
|
||||
*/
|
||||
private function addOptions(array $options)
|
||||
{
|
||||
$code = array();
|
||||
$code = [];
|
||||
foreach ($options as $k => $v) {
|
||||
$code[] = sprintf('%s="%s"', $k, $v);
|
||||
}
|
||||
@@ -292,7 +299,7 @@ class GraphvizDumper extends Dumper
|
||||
*/
|
||||
private function getAliases($id)
|
||||
{
|
||||
$aliases = array();
|
||||
$aliases = [];
|
||||
foreach ($this->container->getAliases() as $alias => $origin) {
|
||||
if ($id == $origin) {
|
||||
$aliases[] = $alias;
|
||||
|
||||
1876
vendor/symfony/dependency-injection/Dumper/PhpDumper.php
vendored
1876
vendor/symfony/dependency-injection/Dumper/PhpDumper.php
vendored
File diff suppressed because it is too large
Load Diff
@@ -12,6 +12,9 @@
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
@@ -37,14 +40,14 @@ class XmlDumper extends Dumper
|
||||
*
|
||||
* @return string An xml string representing of the service container
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
public function dump(array $options = [])
|
||||
{
|
||||
$this->document = new \DOMDocument('1.0', 'utf-8');
|
||||
$this->document->formatOutput = true;
|
||||
|
||||
$container = $this->document->createElementNS('http://symfony.com/schema/dic/services', 'container');
|
||||
$container->setAttribute('xmlns:xsi', 'http://www.w3.org/2001/XMLSchema-instance');
|
||||
$container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd');
|
||||
$container->setAttribute('xsi:schemaLocation', 'http://symfony.com/schema/dic/services https://symfony.com/schema/dic/services/services-1.0.xsd');
|
||||
|
||||
$this->addParameters($container);
|
||||
$this->addServices($container);
|
||||
@@ -53,7 +56,7 @@ class XmlDumper extends Dumper
|
||||
$xml = $this->document->saveXML();
|
||||
$this->document = null;
|
||||
|
||||
return $xml;
|
||||
return $this->container->resolveEnvPlaceholders($xml);
|
||||
}
|
||||
|
||||
private function addParameters(\DOMElement $parent)
|
||||
@@ -63,7 +66,7 @@ class XmlDumper extends Dumper
|
||||
return;
|
||||
}
|
||||
|
||||
if ($this->container->isFrozen()) {
|
||||
if ($this->container->isCompiled()) {
|
||||
$data = $this->escape($data);
|
||||
}
|
||||
|
||||
@@ -87,9 +90,8 @@ class XmlDumper extends Dumper
|
||||
/**
|
||||
* Adds a service.
|
||||
*
|
||||
* @param Definition $definition
|
||||
* @param string $id
|
||||
* @param \DOMElement $parent
|
||||
* @param Definition $definition
|
||||
* @param string $id
|
||||
*/
|
||||
private function addService($definition, $id, \DOMElement $parent)
|
||||
{
|
||||
@@ -104,30 +106,15 @@ class XmlDumper extends Dumper
|
||||
|
||||
$service->setAttribute('class', $class);
|
||||
}
|
||||
if ($definition->getFactoryMethod(false)) {
|
||||
$service->setAttribute('factory-method', $definition->getFactoryMethod(false));
|
||||
}
|
||||
if ($definition->getFactoryClass(false)) {
|
||||
$service->setAttribute('factory-class', $definition->getFactoryClass(false));
|
||||
}
|
||||
if ($definition->getFactoryService(false)) {
|
||||
$service->setAttribute('factory-service', $definition->getFactoryService(false));
|
||||
}
|
||||
if (!$definition->isShared()) {
|
||||
$service->setAttribute('shared', 'false');
|
||||
}
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
|
||||
$service->setAttribute('scope', $scope);
|
||||
}
|
||||
if (!$definition->isPublic()) {
|
||||
$service->setAttribute('public', 'false');
|
||||
if (!$definition->isPrivate()) {
|
||||
$service->setAttribute('public', $definition->isPublic() ? 'true' : 'false');
|
||||
}
|
||||
if ($definition->isSynthetic()) {
|
||||
$service->setAttribute('synthetic', 'true');
|
||||
}
|
||||
if ($definition->isSynchronized(false)) {
|
||||
$service->setAttribute('synchronized', 'true');
|
||||
}
|
||||
if ($definition->isLazy()) {
|
||||
$service->setAttribute('lazy', 'true');
|
||||
}
|
||||
@@ -176,7 +163,9 @@ class XmlDumper extends Dumper
|
||||
$this->addService($callable[0], null, $factory);
|
||||
$factory->setAttribute('method', $callable[1]);
|
||||
} elseif (\is_array($callable)) {
|
||||
$factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
|
||||
if (null !== $callable[0]) {
|
||||
$factory->setAttribute($callable[0] instanceof Reference ? 'service' : 'class', $callable[0]);
|
||||
}
|
||||
$factory->setAttribute('method', $callable[1]);
|
||||
} else {
|
||||
$factory->setAttribute('function', $callable);
|
||||
@@ -195,13 +184,17 @@ class XmlDumper extends Dumper
|
||||
$service->setAttribute('autowire', 'true');
|
||||
}
|
||||
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringTypeValue) {
|
||||
foreach ($definition->getAutowiringTypes(false) as $autowiringTypeValue) {
|
||||
$autowiringType = $this->document->createElement('autowiring-type');
|
||||
$autowiringType->appendChild($this->document->createTextNode($autowiringTypeValue));
|
||||
|
||||
$service->appendChild($autowiringType);
|
||||
}
|
||||
|
||||
if ($definition->isAutoconfigured()) {
|
||||
$service->setAttribute('autoconfigure', 'true');
|
||||
}
|
||||
|
||||
if ($definition->isAbstract()) {
|
||||
$service->setAttribute('abstract', 'true');
|
||||
}
|
||||
@@ -227,17 +220,15 @@ class XmlDumper extends Dumper
|
||||
/**
|
||||
* Adds a service alias.
|
||||
*
|
||||
* @param string $alias
|
||||
* @param Alias $id
|
||||
* @param \DOMElement $parent
|
||||
* @param string $alias
|
||||
*/
|
||||
private function addServiceAlias($alias, Alias $id, \DOMElement $parent)
|
||||
{
|
||||
$service = $this->document->createElement('service');
|
||||
$service->setAttribute('id', $alias);
|
||||
$service->setAttribute('alias', $id);
|
||||
if (!$id->isPublic()) {
|
||||
$service->setAttribute('public', 'false');
|
||||
if (!$id->isPrivate()) {
|
||||
$service->setAttribute('public', $id->isPublic() ? 'true' : 'false');
|
||||
}
|
||||
$parent->appendChild($service);
|
||||
}
|
||||
@@ -267,10 +258,8 @@ class XmlDumper extends Dumper
|
||||
/**
|
||||
* Converts parameters.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param string $type
|
||||
* @param \DOMElement $parent
|
||||
* @param string $keyAttribute
|
||||
* @param string $type
|
||||
* @param string $keyAttribute
|
||||
*/
|
||||
private function convertParameters(array $parameters, $type, \DOMElement $parent, $keyAttribute = 'key')
|
||||
{
|
||||
@@ -281,20 +270,28 @@ class XmlDumper extends Dumper
|
||||
$element->setAttribute($keyAttribute, $key);
|
||||
}
|
||||
|
||||
if ($value instanceof ServiceClosureArgument) {
|
||||
$value = $value->getValues()[0];
|
||||
}
|
||||
if (\is_array($value)) {
|
||||
$element->setAttribute('type', 'collection');
|
||||
$this->convertParameters($value, $type, $element, 'key');
|
||||
} elseif ($value instanceof TaggedIteratorArgument) {
|
||||
$element->setAttribute('type', 'tagged');
|
||||
$element->setAttribute('tag', $value->getTag());
|
||||
} elseif ($value instanceof IteratorArgument) {
|
||||
$element->setAttribute('type', 'iterator');
|
||||
$this->convertParameters($value->getValues(), $type, $element, 'key');
|
||||
} elseif ($value instanceof Reference) {
|
||||
$element->setAttribute('type', 'service');
|
||||
$element->setAttribute('id', (string) $value);
|
||||
$behaviour = $value->getInvalidBehavior();
|
||||
if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behaviour) {
|
||||
$behavior = $value->getInvalidBehavior();
|
||||
if (ContainerInterface::NULL_ON_INVALID_REFERENCE == $behavior) {
|
||||
$element->setAttribute('on-invalid', 'null');
|
||||
} elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behaviour) {
|
||||
} elseif (ContainerInterface::IGNORE_ON_INVALID_REFERENCE == $behavior) {
|
||||
$element->setAttribute('on-invalid', 'ignore');
|
||||
}
|
||||
if (!$value->isStrict(false)) {
|
||||
$element->setAttribute('strict', 'false');
|
||||
} elseif (ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE == $behavior) {
|
||||
$element->setAttribute('on-invalid', 'ignore_uninitialized');
|
||||
}
|
||||
} elseif ($value instanceof Definition) {
|
||||
$element->setAttribute('type', 'service');
|
||||
@@ -304,9 +301,14 @@ class XmlDumper extends Dumper
|
||||
$text = $this->document->createTextNode(self::phpToXml((string) $value));
|
||||
$element->appendChild($text);
|
||||
} else {
|
||||
if (\in_array($value, array('null', 'true', 'false'), true)) {
|
||||
if (\in_array($value, ['null', 'true', 'false'], true)) {
|
||||
$element->setAttribute('type', 'string');
|
||||
}
|
||||
|
||||
if (\is_string($value) && (is_numeric($value) || preg_match('/^0b[01]*$/', $value) || preg_match('/^0x[0-9a-f]++$/i', $value))) {
|
||||
$element->setAttribute('type', 'string');
|
||||
}
|
||||
|
||||
$text = $this->document->createTextNode(self::phpToXml($value));
|
||||
$element->appendChild($text);
|
||||
}
|
||||
@@ -321,7 +323,7 @@ class XmlDumper extends Dumper
|
||||
*/
|
||||
private function escape(array $arguments)
|
||||
{
|
||||
$args = array();
|
||||
$args = [];
|
||||
foreach ($arguments as $k => $v) {
|
||||
if (\is_array($v)) {
|
||||
$args[$k] = $this->escape($v);
|
||||
|
||||
@@ -12,6 +12,10 @@
|
||||
namespace Symfony\Component\DependencyInjection\Dumper;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\ServiceClosureArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
@@ -19,6 +23,9 @@ use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
use Symfony\Component\Yaml\Dumper as YmlDumper;
|
||||
use Symfony\Component\Yaml\Parser;
|
||||
use Symfony\Component\Yaml\Tag\TaggedValue;
|
||||
use Symfony\Component\Yaml\Yaml;
|
||||
|
||||
/**
|
||||
* YamlDumper dumps a service container as a YAML string.
|
||||
@@ -34,7 +41,7 @@ class YamlDumper extends Dumper
|
||||
*
|
||||
* @return string A YAML string representing of the service container
|
||||
*/
|
||||
public function dump(array $options = array())
|
||||
public function dump(array $options = [])
|
||||
{
|
||||
if (!class_exists('Symfony\Component\Yaml\Dumper')) {
|
||||
throw new RuntimeException('Unable to dump the container as the Symfony Yaml Component is not installed.');
|
||||
@@ -44,14 +51,13 @@ class YamlDumper extends Dumper
|
||||
$this->dumper = new YmlDumper();
|
||||
}
|
||||
|
||||
return $this->addParameters()."\n".$this->addServices();
|
||||
return $this->container->resolveEnvPlaceholders($this->addParameters()."\n".$this->addServices());
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
* @param string $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
@@ -66,14 +72,14 @@ class YamlDumper extends Dumper
|
||||
$code .= sprintf(" class: %s\n", $this->dumper->dump($class));
|
||||
}
|
||||
|
||||
if (!$definition->isPublic()) {
|
||||
$code .= " public: false\n";
|
||||
if (!$definition->isPrivate()) {
|
||||
$code .= sprintf(" public: %s\n", $definition->isPublic() ? 'true' : 'false');
|
||||
}
|
||||
|
||||
$tagsCode = '';
|
||||
foreach ($definition->getTags() as $name => $tags) {
|
||||
foreach ($tags as $attributes) {
|
||||
$att = array();
|
||||
$att = [];
|
||||
foreach ($attributes as $key => $value) {
|
||||
$att[] = sprintf('%s: %s', $this->dumper->dump($key), $this->dumper->dump($value));
|
||||
}
|
||||
@@ -94,10 +100,6 @@ class YamlDumper extends Dumper
|
||||
$code .= " synthetic: true\n";
|
||||
}
|
||||
|
||||
if ($definition->isSynchronized(false)) {
|
||||
$code .= " synchronized: true\n";
|
||||
}
|
||||
|
||||
if ($definition->isDeprecated()) {
|
||||
$code .= sprintf(" deprecated: %s\n", $this->dumper->dump($definition->getDeprecationMessage('%service_id%')));
|
||||
}
|
||||
@@ -107,15 +109,15 @@ class YamlDumper extends Dumper
|
||||
}
|
||||
|
||||
$autowiringTypesCode = '';
|
||||
foreach ($definition->getAutowiringTypes() as $autowiringType) {
|
||||
foreach ($definition->getAutowiringTypes(false) as $autowiringType) {
|
||||
$autowiringTypesCode .= sprintf(" - %s\n", $this->dumper->dump($autowiringType));
|
||||
}
|
||||
if ($autowiringTypesCode) {
|
||||
$code .= sprintf(" autowiring_types:\n%s", $autowiringTypesCode);
|
||||
}
|
||||
|
||||
if ($definition->getFactoryClass(false)) {
|
||||
$code .= sprintf(" factory_class: %s\n", $this->dumper->dump($definition->getFactoryClass(false)));
|
||||
if ($definition->isAutoconfigured()) {
|
||||
$code .= " autoconfigure: true\n";
|
||||
}
|
||||
|
||||
if ($definition->isAbstract()) {
|
||||
@@ -126,14 +128,6 @@ class YamlDumper extends Dumper
|
||||
$code .= " lazy: true\n";
|
||||
}
|
||||
|
||||
if ($definition->getFactoryMethod(false)) {
|
||||
$code .= sprintf(" factory_method: %s\n", $this->dumper->dump($definition->getFactoryMethod(false)));
|
||||
}
|
||||
|
||||
if ($definition->getFactoryService(false)) {
|
||||
$code .= sprintf(" factory_service: %s\n", $this->dumper->dump($definition->getFactoryService(false)));
|
||||
}
|
||||
|
||||
if ($definition->getArguments()) {
|
||||
$code .= sprintf(" arguments: %s\n", $this->dumper->dump($this->dumpValue($definition->getArguments()), 0));
|
||||
}
|
||||
@@ -150,10 +144,6 @@ class YamlDumper extends Dumper
|
||||
$code .= " shared: false\n";
|
||||
}
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER !== $scope = $definition->getScope(false)) {
|
||||
$code .= sprintf(" scope: %s\n", $this->dumper->dump($scope));
|
||||
}
|
||||
|
||||
if (null !== $decorated = $definition->getDecoratedService()) {
|
||||
list($decorated, $renamedId, $priority) = $decorated;
|
||||
$code .= sprintf(" decorates: %s\n", $decorated);
|
||||
@@ -180,17 +170,16 @@ class YamlDumper extends Dumper
|
||||
* Adds a service alias.
|
||||
*
|
||||
* @param string $alias
|
||||
* @param Alias $id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function addServiceAlias($alias, Alias $id)
|
||||
{
|
||||
if ($id->isPublic()) {
|
||||
if ($id->isPrivate()) {
|
||||
return sprintf(" %s: '@%s'\n", $alias, $id);
|
||||
}
|
||||
|
||||
return sprintf(" %s:\n alias: %s\n public: false\n", $alias, $id);
|
||||
return sprintf(" %s:\n alias: %s\n public: %s\n", $alias, $id, $id->isPublic() ? 'true' : 'false');
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -231,25 +220,23 @@ class YamlDumper extends Dumper
|
||||
return '';
|
||||
}
|
||||
|
||||
$parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isFrozen());
|
||||
$parameters = $this->prepareParameters($this->container->getParameterBag()->all(), $this->container->isCompiled());
|
||||
|
||||
return $this->dumper->dump(array('parameters' => $parameters), 2);
|
||||
return $this->dumper->dump(['parameters' => $parameters], 2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps callable to YAML format.
|
||||
*
|
||||
* @param callable $callable
|
||||
*
|
||||
* @return callable
|
||||
* @param mixed $callable
|
||||
*/
|
||||
private function dumpCallable($callable)
|
||||
{
|
||||
if (\is_array($callable)) {
|
||||
if ($callable[0] instanceof Reference) {
|
||||
$callable = array($this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]);
|
||||
$callable = [$this->getServiceCall((string) $callable[0], $callable[0]), $callable[1]];
|
||||
} else {
|
||||
$callable = array($callable[0], $callable[1]);
|
||||
$callable = [$callable[0], $callable[1]];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -267,8 +254,24 @@ class YamlDumper extends Dumper
|
||||
*/
|
||||
private function dumpValue($value)
|
||||
{
|
||||
if ($value instanceof ServiceClosureArgument) {
|
||||
$value = $value->getValues()[0];
|
||||
}
|
||||
if ($value instanceof ArgumentInterface) {
|
||||
if ($value instanceof TaggedIteratorArgument) {
|
||||
return new TaggedValue('tagged', $value->getTag());
|
||||
}
|
||||
if ($value instanceof IteratorArgument) {
|
||||
$tag = 'iterator';
|
||||
} else {
|
||||
throw new RuntimeException(sprintf('Unspecified Yaml tag for type "%s".', \get_class($value)));
|
||||
}
|
||||
|
||||
return new TaggedValue($tag, $this->dumpValue($value->getValues()));
|
||||
}
|
||||
|
||||
if (\is_array($value)) {
|
||||
$code = array();
|
||||
$code = [];
|
||||
foreach ($value as $k => $v) {
|
||||
$code[$k] = $this->dumpValue($v);
|
||||
}
|
||||
@@ -280,6 +283,8 @@ class YamlDumper extends Dumper
|
||||
return $this->getParameterCall((string) $value);
|
||||
} elseif ($value instanceof Expression) {
|
||||
return $this->getExpressionCall((string) $value);
|
||||
} elseif ($value instanceof Definition) {
|
||||
return new TaggedValue('service', (new Parser())->parse("_:\n".$this->addService('_', $value), Yaml::PARSE_CUSTOM_TAGS)['_']['_']);
|
||||
} elseif (\is_object($value) || \is_resource($value)) {
|
||||
throw new RuntimeException('Unable to dump a service container if a parameter is an object or a resource.');
|
||||
}
|
||||
@@ -297,8 +302,12 @@ class YamlDumper extends Dumper
|
||||
*/
|
||||
private function getServiceCall($id, Reference $reference = null)
|
||||
{
|
||||
if (null !== $reference && ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE !== $reference->getInvalidBehavior()) {
|
||||
return sprintf('@?%s', $id);
|
||||
if (null !== $reference) {
|
||||
switch ($reference->getInvalidBehavior()) {
|
||||
case ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE: break;
|
||||
case ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE: return sprintf('@!%s', $id);
|
||||
default: return sprintf('@?%s', $id);
|
||||
}
|
||||
}
|
||||
|
||||
return sprintf('@%s', $id);
|
||||
@@ -324,14 +333,13 @@ class YamlDumper extends Dumper
|
||||
/**
|
||||
* Prepares parameters.
|
||||
*
|
||||
* @param array $parameters
|
||||
* @param bool $escape
|
||||
* @param bool $escape
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function prepareParameters(array $parameters, $escape = true)
|
||||
{
|
||||
$filtered = array();
|
||||
$filtered = [];
|
||||
foreach ($parameters as $key => $value) {
|
||||
if (\is_array($value)) {
|
||||
$value = $this->prepareParameters($value, $escape);
|
||||
@@ -352,7 +360,7 @@ class YamlDumper extends Dumper
|
||||
*/
|
||||
private function escape(array $arguments)
|
||||
{
|
||||
$args = array();
|
||||
$args = [];
|
||||
foreach ($arguments as $k => $v) {
|
||||
if (\is_array($v)) {
|
||||
$args[$k] = $this->escape($v);
|
||||
|
||||
163
vendor/symfony/dependency-injection/EnvVarProcessor.php
vendored
Normal file
163
vendor/symfony/dependency-injection/EnvVarProcessor.php
vendored
Normal file
@@ -0,0 +1,163 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\Config\Util\XmlUtils;
|
||||
use Symfony\Component\DependencyInjection\Exception\EnvNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class EnvVarProcessor implements EnvVarProcessorInterface
|
||||
{
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerInterface $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public static function getProvidedTypes()
|
||||
{
|
||||
return [
|
||||
'base64' => 'string',
|
||||
'bool' => 'bool',
|
||||
'const' => 'bool|int|float|string|array',
|
||||
'file' => 'string',
|
||||
'float' => 'float',
|
||||
'int' => 'int',
|
||||
'json' => 'array',
|
||||
'resolve' => 'string',
|
||||
'string' => 'string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getEnv($prefix, $name, \Closure $getEnv)
|
||||
{
|
||||
$i = strpos($name, ':');
|
||||
|
||||
if ('file' === $prefix) {
|
||||
if (!is_scalar($file = $getEnv($name))) {
|
||||
throw new RuntimeException(sprintf('Invalid file name: env var "%s" is non-scalar.', $name));
|
||||
}
|
||||
if (!file_exists($file)) {
|
||||
throw new RuntimeException(sprintf('Env "file:%s" not found: %s does not exist.', $name, $file));
|
||||
}
|
||||
|
||||
return file_get_contents($file);
|
||||
}
|
||||
|
||||
if (false !== $i || 'string' !== $prefix) {
|
||||
if (null === $env = $getEnv($name)) {
|
||||
return null;
|
||||
}
|
||||
} elseif (isset($_ENV[$name])) {
|
||||
$env = $_ENV[$name];
|
||||
} elseif (isset($_SERVER[$name]) && 0 !== strpos($name, 'HTTP_')) {
|
||||
$env = $_SERVER[$name];
|
||||
} elseif (false === ($env = getenv($name)) || null === $env) { // null is a possible value because of thread safety issues
|
||||
if (!$this->container->hasParameter("env($name)")) {
|
||||
throw new EnvNotFoundException($name);
|
||||
}
|
||||
|
||||
if (null === $env = $this->container->getParameter("env($name)")) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
if (!is_scalar($env)) {
|
||||
throw new RuntimeException(sprintf('Non-scalar env var "%s" cannot be cast to %s.', $name, $prefix));
|
||||
}
|
||||
|
||||
if ('string' === $prefix) {
|
||||
return (string) $env;
|
||||
}
|
||||
|
||||
if ('bool' === $prefix) {
|
||||
return (bool) self::phpize($env);
|
||||
}
|
||||
|
||||
if ('int' === $prefix) {
|
||||
if (!is_numeric($env = self::phpize($env))) {
|
||||
throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to int.', $name));
|
||||
}
|
||||
|
||||
return (int) $env;
|
||||
}
|
||||
|
||||
if ('float' === $prefix) {
|
||||
if (!is_numeric($env = self::phpize($env))) {
|
||||
throw new RuntimeException(sprintf('Non-numeric env var "%s" cannot be cast to float.', $name));
|
||||
}
|
||||
|
||||
return (float) $env;
|
||||
}
|
||||
|
||||
if ('const' === $prefix) {
|
||||
if (!\defined($env)) {
|
||||
throw new RuntimeException(sprintf('Env var "%s" maps to undefined constant "%s".', $name, $env));
|
||||
}
|
||||
|
||||
return \constant($env);
|
||||
}
|
||||
|
||||
if ('base64' === $prefix) {
|
||||
return base64_decode($env);
|
||||
}
|
||||
|
||||
if ('json' === $prefix) {
|
||||
$env = json_decode($env, true);
|
||||
|
||||
if (JSON_ERROR_NONE !== json_last_error()) {
|
||||
throw new RuntimeException(sprintf('Invalid JSON in env var "%s": '.json_last_error_msg(), $name));
|
||||
}
|
||||
|
||||
if (!\is_array($env)) {
|
||||
throw new RuntimeException(sprintf('Invalid JSON env var "%s": array expected, %s given.', $name, \gettype($env)));
|
||||
}
|
||||
|
||||
return $env;
|
||||
}
|
||||
|
||||
if ('resolve' === $prefix) {
|
||||
return preg_replace_callback('/%%|%([^%\s]+)%/', function ($match) use ($name) {
|
||||
if (!isset($match[1])) {
|
||||
return '%';
|
||||
}
|
||||
$value = $this->container->getParameter($match[1]);
|
||||
if (!is_scalar($value)) {
|
||||
throw new RuntimeException(sprintf('Parameter "%s" found when resolving env var "%s" must be scalar, "%s" given.', $match[1], $name, \gettype($value)));
|
||||
}
|
||||
|
||||
return $value;
|
||||
}, $env);
|
||||
}
|
||||
|
||||
throw new RuntimeException(sprintf('Unsupported env var prefix "%s".', $prefix));
|
||||
}
|
||||
|
||||
private static function phpize($value)
|
||||
{
|
||||
if (!class_exists(XmlUtils::class)) {
|
||||
throw new RuntimeException('The Symfony Config component is required to cast env vars to "bool", "int" or "float".');
|
||||
}
|
||||
|
||||
return XmlUtils::phpize($value);
|
||||
}
|
||||
}
|
||||
40
vendor/symfony/dependency-injection/EnvVarProcessorInterface.php
vendored
Normal file
40
vendor/symfony/dependency-injection/EnvVarProcessorInterface.php
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
||||
|
||||
/**
|
||||
* The EnvVarProcessorInterface is implemented by objects that manage environment-like variables.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
interface EnvVarProcessorInterface
|
||||
{
|
||||
/**
|
||||
* Returns the value of the given variable as managed by the current instance.
|
||||
*
|
||||
* @param string $prefix The namespace of the variable
|
||||
* @param string $name The name of the variable within the namespace
|
||||
* @param \Closure $getEnv A closure that allows fetching more env vars
|
||||
*
|
||||
* @return mixed
|
||||
*
|
||||
* @throws RuntimeException on error
|
||||
*/
|
||||
public function getEnv($prefix, $name, \Closure $getEnv);
|
||||
|
||||
/**
|
||||
* @return string[] The PHP-types managed by getEnv(), keyed by prefixes
|
||||
*/
|
||||
public static function getProvidedTypes();
|
||||
}
|
||||
32
vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php
vendored
Normal file
32
vendor/symfony/dependency-injection/Exception/AutowiringFailedException.php
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* Thrown when a definition cannot be autowired.
|
||||
*/
|
||||
class AutowiringFailedException extends RuntimeException
|
||||
{
|
||||
private $serviceId;
|
||||
|
||||
public function __construct($serviceId, $message = '', $code = 0, \Exception $previous = null)
|
||||
{
|
||||
$this->serviceId = $serviceId;
|
||||
|
||||
parent::__construct($message, $code, $previous);
|
||||
}
|
||||
|
||||
public function getServiceId()
|
||||
{
|
||||
return $this->serviceId;
|
||||
}
|
||||
}
|
||||
25
vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php
vendored
Normal file
25
vendor/symfony/dependency-injection/Exception/EnvNotFoundException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception is thrown when an environment variable is not found.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class EnvNotFoundException extends InvalidArgumentException
|
||||
{
|
||||
public function __construct($name)
|
||||
{
|
||||
parent::__construct(sprintf('Environment variable not found: "%s".', $name));
|
||||
}
|
||||
}
|
||||
25
vendor/symfony/dependency-injection/Exception/EnvParameterException.php
vendored
Normal file
25
vendor/symfony/dependency-injection/Exception/EnvParameterException.php
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
/**
|
||||
* This exception wraps exceptions whose messages contain a reference to an env parameter.
|
||||
*
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class EnvParameterException extends InvalidArgumentException
|
||||
{
|
||||
public function __construct(array $envs, \Exception $previous = null, $message = 'Incompatible use of dynamic environment variables "%s" found in parameters.')
|
||||
{
|
||||
parent::__construct(sprintf($message, implode('", "', $envs)), 0, $previous);
|
||||
}
|
||||
}
|
||||
@@ -11,12 +11,14 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
use Psr\Container\ContainerExceptionInterface;
|
||||
|
||||
/**
|
||||
* Base ExceptionInterface for Dependency Injection component.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Bulat Shakirzyanov <bulat@theopenskyproject.com>
|
||||
*/
|
||||
interface ExceptionInterface
|
||||
interface ExceptionInterface extends ContainerExceptionInterface
|
||||
{
|
||||
}
|
||||
|
||||
@@ -22,20 +22,23 @@ class ParameterNotFoundException extends InvalidArgumentException
|
||||
private $sourceId;
|
||||
private $sourceKey;
|
||||
private $alternatives;
|
||||
private $nonNestedAlternative;
|
||||
|
||||
/**
|
||||
* @param string $key The requested parameter key
|
||||
* @param string $sourceId The service id that references the non-existent parameter
|
||||
* @param string $sourceKey The parameter key that references the non-existent parameter
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param string[] $alternatives Some parameter name alternatives
|
||||
* @param string $key The requested parameter key
|
||||
* @param string $sourceId The service id that references the non-existent parameter
|
||||
* @param string $sourceKey The parameter key that references the non-existent parameter
|
||||
* @param \Exception $previous The previous exception
|
||||
* @param string[] $alternatives Some parameter name alternatives
|
||||
* @param string|null $nonNestedAlternative The alternative parameter name when the user expected dot notation for nested parameters
|
||||
*/
|
||||
public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = array())
|
||||
public function __construct($key, $sourceId = null, $sourceKey = null, \Exception $previous = null, array $alternatives = [], $nonNestedAlternative = null)
|
||||
{
|
||||
$this->key = $key;
|
||||
$this->sourceId = $sourceId;
|
||||
$this->sourceKey = $sourceKey;
|
||||
$this->alternatives = $alternatives;
|
||||
$this->nonNestedAlternative = $nonNestedAlternative;
|
||||
|
||||
parent::__construct('', 0, $previous);
|
||||
|
||||
@@ -59,6 +62,8 @@ class ParameterNotFoundException extends InvalidArgumentException
|
||||
$this->message .= ' Did you mean one of these: "';
|
||||
}
|
||||
$this->message .= implode('", "', $this->alternatives).'"?';
|
||||
} elseif (null !== $this->nonNestedAlternative) {
|
||||
$this->message .= ' You cannot access nested array items, do you want to inject "'.$this->nonNestedAlternative.'" instead?';
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,19 +11,24 @@
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Exception;
|
||||
|
||||
use Psr\Container\NotFoundExceptionInterface;
|
||||
|
||||
/**
|
||||
* This exception is thrown when a non-existent service is requested.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
*/
|
||||
class ServiceNotFoundException extends InvalidArgumentException
|
||||
class ServiceNotFoundException extends InvalidArgumentException implements NotFoundExceptionInterface
|
||||
{
|
||||
private $id;
|
||||
private $sourceId;
|
||||
private $alternatives;
|
||||
|
||||
public function __construct($id, $sourceId = null, \Exception $previous = null, array $alternatives = array())
|
||||
public function __construct($id, $sourceId = null, \Exception $previous = null, array $alternatives = [], $msg = null)
|
||||
{
|
||||
if (null === $sourceId) {
|
||||
if (null !== $msg) {
|
||||
// no-op
|
||||
} elseif (null === $sourceId) {
|
||||
$msg = sprintf('You have requested a non-existent service "%s".', $id);
|
||||
} else {
|
||||
$msg = sprintf('The service "%s" has a dependency on a non-existent service "%s".', $sourceId, $id);
|
||||
@@ -42,6 +47,7 @@ class ServiceNotFoundException extends InvalidArgumentException
|
||||
|
||||
$this->id = $id;
|
||||
$this->sourceId = $sourceId;
|
||||
$this->alternatives = $alternatives;
|
||||
}
|
||||
|
||||
public function getId()
|
||||
@@ -53,4 +59,9 @@ class ServiceNotFoundException extends InvalidArgumentException
|
||||
{
|
||||
return $this->sourceId;
|
||||
}
|
||||
|
||||
public function getAlternatives()
|
||||
{
|
||||
return $this->alternatives;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@
|
||||
namespace Symfony\Component\DependencyInjection;
|
||||
|
||||
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
|
||||
use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
|
||||
|
||||
/**
|
||||
* Adds some function to the default ExpressionLanguage.
|
||||
@@ -23,10 +22,13 @@ use Symfony\Component\ExpressionLanguage\ParserCache\ParserCacheInterface;
|
||||
*/
|
||||
class ExpressionLanguage extends BaseExpressionLanguage
|
||||
{
|
||||
public function __construct(ParserCacheInterface $cache = null, array $providers = array())
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function __construct($cache = null, array $providers = [], callable $serviceCompiler = null)
|
||||
{
|
||||
// prepend the default provider to let users override it easily
|
||||
array_unshift($providers, new ExpressionLanguageProvider());
|
||||
array_unshift($providers, new ExpressionLanguageProvider($serviceCompiler));
|
||||
|
||||
parent::__construct($cache, $providers);
|
||||
}
|
||||
|
||||
@@ -24,10 +24,17 @@ use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
|
||||
*/
|
||||
class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
|
||||
{
|
||||
private $serviceCompiler;
|
||||
|
||||
public function __construct(callable $serviceCompiler = null)
|
||||
{
|
||||
$this->serviceCompiler = $serviceCompiler;
|
||||
}
|
||||
|
||||
public function getFunctions()
|
||||
{
|
||||
return array(
|
||||
new ExpressionFunction('service', function ($arg) {
|
||||
return [
|
||||
new ExpressionFunction('service', $this->serviceCompiler ?: function ($arg) {
|
||||
return sprintf('$this->get(%s)', $arg);
|
||||
}, function (array $variables, $value) {
|
||||
return $variables['container']->get($value);
|
||||
@@ -38,6 +45,6 @@ class ExpressionLanguageProvider implements ExpressionFunctionProviderInterface
|
||||
}, function (array $variables, $value) {
|
||||
return $variables['container']->getParameter($value);
|
||||
}),
|
||||
);
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,7 +13,6 @@ namespace Symfony\Component\DependencyInjection\Extension;
|
||||
|
||||
use Symfony\Component\Config\Definition\ConfigurationInterface;
|
||||
use Symfony\Component\Config\Definition\Processor;
|
||||
use Symfony\Component\Config\Resource\FileResource;
|
||||
use Symfony\Component\DependencyInjection\Container;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Exception\BadMethodCallException;
|
||||
@@ -26,6 +25,8 @@ use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
*/
|
||||
abstract class Extension implements ExtensionInterface, ConfigurationExtensionInterface
|
||||
{
|
||||
private $processedConfigs = [];
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
@@ -78,25 +79,34 @@ abstract class Extension implements ExtensionInterface, ConfigurationExtensionIn
|
||||
*/
|
||||
public function getConfiguration(array $config, ContainerBuilder $container)
|
||||
{
|
||||
$reflected = new \ReflectionClass($this);
|
||||
$namespace = $reflected->getNamespaceName();
|
||||
$class = \get_class($this);
|
||||
$class = substr_replace($class, '\Configuration', strrpos($class, '\\'));
|
||||
$class = $container->getReflectionClass($class);
|
||||
$constructor = $class ? $class->getConstructor() : null;
|
||||
|
||||
$class = $namespace.'\\Configuration';
|
||||
if (class_exists($class)) {
|
||||
$r = new \ReflectionClass($class);
|
||||
$container->addResource(new FileResource($r->getFileName()));
|
||||
|
||||
if (!method_exists($class, '__construct')) {
|
||||
return new $class();
|
||||
}
|
||||
}
|
||||
return $class && (!$constructor || !$constructor->getNumberOfRequiredParameters()) ? $class->newInstance() : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
final protected function processConfiguration(ConfigurationInterface $configuration, array $configs)
|
||||
{
|
||||
$processor = new Processor();
|
||||
|
||||
return $processor->processConfiguration($configuration, $configs);
|
||||
return $this->processedConfigs[] = $processor->processConfiguration($configuration, $configs);
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
final public function getProcessedConfigs()
|
||||
{
|
||||
try {
|
||||
return $this->processedConfigs;
|
||||
} finally {
|
||||
$this->processedConfigs = [];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -106,7 +116,7 @@ abstract class Extension implements ExtensionInterface, ConfigurationExtensionIn
|
||||
*/
|
||||
protected function isConfigEnabled(ContainerBuilder $container, array $config)
|
||||
{
|
||||
if (!array_key_exists('enabled', $config)) {
|
||||
if (!\array_key_exists('enabled', $config)) {
|
||||
throw new InvalidArgumentException("The config array has no 'enabled' key.");
|
||||
}
|
||||
|
||||
|
||||
@@ -37,7 +37,7 @@ interface ExtensionInterface
|
||||
/**
|
||||
* Returns the base path for the XSD files.
|
||||
*
|
||||
* @return string The XSD base path
|
||||
* @return string|false
|
||||
*/
|
||||
public function getXsdValidationBasePath();
|
||||
|
||||
|
||||
2
vendor/symfony/dependency-injection/LICENSE
vendored
2
vendor/symfony/dependency-injection/LICENSE
vendored
@@ -1,4 +1,4 @@
|
||||
Copyright (c) 2004-2018 Fabien Potencier
|
||||
Copyright (c) 2004-2019 Fabien Potencier
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -17,7 +17,7 @@ use Symfony\Component\DependencyInjection\Definition;
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*
|
||||
* Noop proxy instantiator - simply produces the real service instead of a proxy instance.
|
||||
* Noop proxy instantiator - produces the real service instead of a proxy instance.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*/
|
||||
|
||||
@@ -30,12 +30,11 @@ interface DumperInterface
|
||||
/**
|
||||
* Generates the code to be used to instantiate a proxy in the dumped factory code.
|
||||
*
|
||||
* @param Definition $definition
|
||||
* @param string $id Service identifier
|
||||
* @param string $id Service identifier
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, $id);
|
||||
public function getProxyFactoryCode(Definition $definition, $id/**, $factoryCode = null */);
|
||||
|
||||
/**
|
||||
* Generates the code for the lazy proxy.
|
||||
|
||||
@@ -17,6 +17,8 @@ use Symfony\Component\DependencyInjection\Definition;
|
||||
* Null dumper, negates any proxy code generation for any given service definition.
|
||||
*
|
||||
* @author Marco Pivetta <ocramius@gmail.com>
|
||||
*
|
||||
* @final since version 3.3
|
||||
*/
|
||||
class NullDumper implements DumperInterface
|
||||
{
|
||||
@@ -31,7 +33,7 @@ class NullDumper implements DumperInterface
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function getProxyFactoryCode(Definition $definition, $id)
|
||||
public function getProxyFactoryCode(Definition $definition, $id, $factoryCode = null)
|
||||
{
|
||||
return '';
|
||||
}
|
||||
|
||||
64
vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php
vendored
Normal file
64
vendor/symfony/dependency-injection/LazyProxy/ProxyHelper.php
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\LazyProxy;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class ProxyHelper
|
||||
{
|
||||
/**
|
||||
* @return string|null The FQCN or builtin name of the type hint, or null when the type hint references an invalid self|parent context
|
||||
*/
|
||||
public static function getTypeHint(\ReflectionFunctionAbstract $r, \ReflectionParameter $p = null, $noBuiltin = false)
|
||||
{
|
||||
if ($p instanceof \ReflectionParameter) {
|
||||
if (method_exists($p, 'getType')) {
|
||||
$type = $p->getType();
|
||||
} elseif (preg_match('/^(?:[^ ]++ ){4}([a-zA-Z_\x7F-\xFF][^ ]++)/', $p, $type)) {
|
||||
$name = $type = $type[1];
|
||||
|
||||
if ('callable' === $name || 'array' === $name) {
|
||||
return $noBuiltin ? null : $name;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$type = method_exists($r, 'getReturnType') ? $r->getReturnType() : null;
|
||||
}
|
||||
if (!$type) {
|
||||
return null;
|
||||
}
|
||||
if (!\is_string($type)) {
|
||||
$name = $type instanceof \ReflectionNamedType ? $type->getName() : $type->__toString();
|
||||
|
||||
if ($type->isBuiltin()) {
|
||||
return $noBuiltin ? null : $name;
|
||||
}
|
||||
}
|
||||
$lcName = strtolower($name);
|
||||
$prefix = $noBuiltin ? '' : '\\';
|
||||
|
||||
if ('self' !== $lcName && 'parent' !== $lcName) {
|
||||
return $prefix.$name;
|
||||
}
|
||||
if (!$r instanceof \ReflectionMethod) {
|
||||
return null;
|
||||
}
|
||||
if ('self' === $lcName) {
|
||||
return $prefix.$r->getDeclaringClass()->name;
|
||||
}
|
||||
|
||||
return ($parent = $r->getDeclaringClass()->getParentClass()) ? $prefix.$parent->name : null;
|
||||
}
|
||||
}
|
||||
87
vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php
vendored
Normal file
87
vendor/symfony/dependency-injection/Loader/Configurator/AbstractConfigurator.php
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\ArgumentInterface;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Parameter;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
abstract class AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'unknown';
|
||||
|
||||
/** @internal */
|
||||
protected $definition;
|
||||
|
||||
public function __call($method, $args)
|
||||
{
|
||||
if (method_exists($this, 'set'.$method)) {
|
||||
return \call_user_func_array([$this, 'set'.$method], $args);
|
||||
}
|
||||
|
||||
throw new \BadMethodCallException(sprintf('Call to undefined method %s::%s()', \get_class($this), $method));
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks that a value is valid, optionally replacing Definition and Reference configurators by their configure value.
|
||||
*
|
||||
* @param mixed $value
|
||||
* @param bool $allowServices whether Definition and Reference are allowed; by default, only scalars and arrays are
|
||||
*
|
||||
* @return mixed the value, optionally cast to a Definition/Reference
|
||||
*/
|
||||
public static function processValue($value, $allowServices = false)
|
||||
{
|
||||
if (\is_array($value)) {
|
||||
foreach ($value as $k => $v) {
|
||||
$value[$k] = static::processValue($v, $allowServices);
|
||||
}
|
||||
|
||||
return $value;
|
||||
}
|
||||
|
||||
if ($value instanceof ReferenceConfigurator) {
|
||||
return new Reference($value->id, $value->invalidBehavior);
|
||||
}
|
||||
|
||||
if ($value instanceof InlineServiceConfigurator) {
|
||||
$def = $value->definition;
|
||||
$value->definition = null;
|
||||
|
||||
return $def;
|
||||
}
|
||||
|
||||
if ($value instanceof self) {
|
||||
throw new InvalidArgumentException(sprintf('"%s()" can be used only at the root of service configuration files.', $value::FACTORY));
|
||||
}
|
||||
|
||||
switch (true) {
|
||||
case null === $value:
|
||||
case is_scalar($value):
|
||||
return $value;
|
||||
|
||||
case $value instanceof ArgumentInterface:
|
||||
case $value instanceof Definition:
|
||||
case $value instanceof Expression:
|
||||
case $value instanceof Parameter:
|
||||
case $value instanceof Reference:
|
||||
if ($allowServices) {
|
||||
return $value;
|
||||
}
|
||||
}
|
||||
|
||||
throw new InvalidArgumentException(sprintf('Cannot use values of type "%s" in service configuration files.', \is_object($value) ? \get_class($value) : \gettype($value)));
|
||||
}
|
||||
}
|
||||
117
vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php
vendored
Normal file
117
vendor/symfony/dependency-injection/Loader/Configurator/AbstractServiceConfigurator.php
vendored
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
|
||||
abstract class AbstractServiceConfigurator extends AbstractConfigurator
|
||||
{
|
||||
protected $parent;
|
||||
protected $id;
|
||||
private $defaultTags = [];
|
||||
|
||||
public function __construct(ServicesConfigurator $parent, Definition $definition, $id = null, array $defaultTags = [])
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->definition = $definition;
|
||||
$this->id = $id;
|
||||
$this->defaultTags = $defaultTags;
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
// default tags should be added last
|
||||
foreach ($this->defaultTags as $name => $attributes) {
|
||||
foreach ($attributes as $attributes) {
|
||||
$this->definition->addTag($name, $attributes);
|
||||
}
|
||||
}
|
||||
$this->defaultTags = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function set($id, $class = null)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->set($id, $class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an alias.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $referencedId
|
||||
*
|
||||
* @return AliasConfigurator
|
||||
*/
|
||||
final public function alias($id, $referencedId)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->alias($id, $referencedId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a PSR-4 namespace using a glob pattern.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $resource
|
||||
*
|
||||
* @return PrototypeConfigurator
|
||||
*/
|
||||
final public function load($namespace, $resource)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->load($namespace, $resource);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an already defined service definition.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*
|
||||
* @throws ServiceNotFoundException if the service definition does not exist
|
||||
*/
|
||||
final public function get($id)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->get($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function __invoke($id, $class = null)
|
||||
{
|
||||
$this->__destruct();
|
||||
|
||||
return $this->parent->set($id, $class);
|
||||
}
|
||||
}
|
||||
30
vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php
vendored
Normal file
30
vendor/symfony/dependency-injection/Loader/Configurator/AliasConfigurator.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class AliasConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'alias';
|
||||
|
||||
use Traits\PublicTrait;
|
||||
|
||||
public function __construct(ServicesConfigurator $parent, Alias $alias)
|
||||
{
|
||||
$this->parent = $parent;
|
||||
$this->definition = $alias;
|
||||
}
|
||||
}
|
||||
141
vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php
vendored
Normal file
141
vendor/symfony/dependency-injection/Loader/Configurator/ContainerConfigurator.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\Argument\TaggedIteratorArgument;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
use Symfony\Component\ExpressionLanguage\Expression;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ContainerConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'container';
|
||||
|
||||
private $container;
|
||||
private $loader;
|
||||
private $instanceof;
|
||||
private $path;
|
||||
private $file;
|
||||
|
||||
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof, $path, $file)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->loader = $loader;
|
||||
$this->instanceof = &$instanceof;
|
||||
$this->path = $path;
|
||||
$this->file = $file;
|
||||
}
|
||||
|
||||
final public function extension($namespace, array $config)
|
||||
{
|
||||
if (!$this->container->hasExtension($namespace)) {
|
||||
$extensions = array_filter(array_map(function ($ext) { return $ext->getAlias(); }, $this->container->getExtensions()));
|
||||
throw new InvalidArgumentException(sprintf(
|
||||
'There is no extension able to load the configuration for "%s" (in %s). Looked for namespace "%s", found %s',
|
||||
$namespace,
|
||||
$this->file,
|
||||
$namespace,
|
||||
$extensions ? sprintf('"%s"', implode('", "', $extensions)) : 'none'
|
||||
));
|
||||
}
|
||||
|
||||
$this->container->loadFromExtension($namespace, static::processValue($config));
|
||||
}
|
||||
|
||||
final public function import($resource, $type = null, $ignoreErrors = false)
|
||||
{
|
||||
$this->loader->setCurrentDir(\dirname($this->path));
|
||||
$this->loader->import($resource, $type, $ignoreErrors, $this->file);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ParametersConfigurator
|
||||
*/
|
||||
final public function parameters()
|
||||
{
|
||||
return new ParametersConfigurator($this->container);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return ServicesConfigurator
|
||||
*/
|
||||
final public function services()
|
||||
{
|
||||
return new ServicesConfigurator($this->container, $this->loader, $this->instanceof);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a service reference.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return ReferenceConfigurator
|
||||
*/
|
||||
function ref($id)
|
||||
{
|
||||
return new ReferenceConfigurator($id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an inline service.
|
||||
*
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return InlineServiceConfigurator
|
||||
*/
|
||||
function inline($class = null)
|
||||
{
|
||||
return new InlineServiceConfigurator(new Definition($class));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy iterator.
|
||||
*
|
||||
* @param ReferenceConfigurator[] $values
|
||||
*
|
||||
* @return IteratorArgument
|
||||
*/
|
||||
function iterator(array $values)
|
||||
{
|
||||
return new IteratorArgument(AbstractConfigurator::processValue($values, true));
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a lazy iterator by tag name.
|
||||
*
|
||||
* @param string $tag
|
||||
*
|
||||
* @return TaggedIteratorArgument
|
||||
*/
|
||||
function tagged($tag)
|
||||
{
|
||||
return new TaggedIteratorArgument($tag);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an expression.
|
||||
*
|
||||
* @param string $expression an expression
|
||||
*
|
||||
* @return Expression
|
||||
*/
|
||||
function expr($expression)
|
||||
{
|
||||
return new Expression($expression);
|
||||
}
|
||||
68
vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php
vendored
Normal file
68
vendor/symfony/dependency-injection/Loader/Configurator/DefaultsConfigurator.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @method InstanceofConfigurator instanceof(string $fqcn)
|
||||
*/
|
||||
class DefaultsConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'defaults';
|
||||
|
||||
use Traits\AutoconfigureTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\PublicTrait;
|
||||
|
||||
/**
|
||||
* Adds a tag for this definition.
|
||||
*
|
||||
* @param string $name The tag name
|
||||
* @param array $attributes An array of attributes
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when an invalid tag name or attribute is provided
|
||||
*/
|
||||
final public function tag($name, array $attributes = [])
|
||||
{
|
||||
if (!\is_string($name) || '' === $name) {
|
||||
throw new InvalidArgumentException('The tag name in "_defaults" must be a non-empty string.');
|
||||
}
|
||||
|
||||
foreach ($attributes as $attribute => $value) {
|
||||
if (!is_scalar($value) && null !== $value) {
|
||||
throw new InvalidArgumentException(sprintf('Tag "%s", attribute "%s" in "_defaults" must be of a scalar-type.', $name, $attribute));
|
||||
}
|
||||
}
|
||||
|
||||
$this->definition->addTag($name, $attributes);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an instanceof-conditional to be applied to following service definitions.
|
||||
*
|
||||
* @param string $fqcn
|
||||
*
|
||||
* @return InstanceofConfigurator
|
||||
*/
|
||||
final protected function setInstanceof($fqcn)
|
||||
{
|
||||
return $this->parent->instanceof($fqcn);
|
||||
}
|
||||
}
|
||||
36
vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php
vendored
Normal file
36
vendor/symfony/dependency-injection/Loader/Configurator/InlineServiceConfigurator.php
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class InlineServiceConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'inline';
|
||||
|
||||
use Traits\ArgumentTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\FactoryTrait;
|
||||
use Traits\FileTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\ParentTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
public function __construct(Definition $definition)
|
||||
{
|
||||
$this->definition = $definition;
|
||||
}
|
||||
}
|
||||
43
vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php
vendored
Normal file
43
vendor/symfony/dependency-injection/Loader/Configurator/InstanceofConfigurator.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @method InstanceofConfigurator instanceof(string $fqcn)
|
||||
*/
|
||||
class InstanceofConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'instanceof';
|
||||
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\CallTrait;
|
||||
use Traits\ConfiguratorTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\PropertyTrait;
|
||||
use Traits\PublicTrait;
|
||||
use Traits\ShareTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
/**
|
||||
* Defines an instanceof-conditional to be applied to following service definitions.
|
||||
*
|
||||
* @param string $fqcn
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
final protected function setInstanceof($fqcn)
|
||||
{
|
||||
return $this->parent->instanceof($fqcn);
|
||||
}
|
||||
}
|
||||
57
vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php
vendored
Normal file
57
vendor/symfony/dependency-injection/Loader/Configurator/ParametersConfigurator.php
vendored
Normal file
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ParametersConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'parameters';
|
||||
|
||||
private $container;
|
||||
|
||||
public function __construct(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a parameter.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function set($name, $value)
|
||||
{
|
||||
$this->container->setParameter($name, static::processValue($value, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a parameter.
|
||||
*
|
||||
* @param string $name
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function __invoke($name, $value)
|
||||
{
|
||||
return $this->set($name, $value);
|
||||
}
|
||||
}
|
||||
84
vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php
vendored
Normal file
84
vendor/symfony/dependency-injection/Loader/Configurator/PrototypeConfigurator.php
vendored
Normal file
@@ -0,0 +1,84 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class PrototypeConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'load';
|
||||
|
||||
use Traits\AbstractTrait;
|
||||
use Traits\ArgumentTrait;
|
||||
use Traits\AutoconfigureTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\CallTrait;
|
||||
use Traits\ConfiguratorTrait;
|
||||
use Traits\DeprecateTrait;
|
||||
use Traits\FactoryTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\ParentTrait;
|
||||
use Traits\PropertyTrait;
|
||||
use Traits\PublicTrait;
|
||||
use Traits\ShareTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
private $loader;
|
||||
private $resource;
|
||||
private $exclude;
|
||||
private $allowParent;
|
||||
|
||||
public function __construct(ServicesConfigurator $parent, PhpFileLoader $loader, Definition $defaults, $namespace, $resource, $allowParent)
|
||||
{
|
||||
$definition = new Definition();
|
||||
$definition->setPublic($defaults->isPublic());
|
||||
$definition->setAutowired($defaults->isAutowired());
|
||||
$definition->setAutoconfigured($defaults->isAutoconfigured());
|
||||
$definition->setBindings($defaults->getBindings());
|
||||
$definition->setChanges([]);
|
||||
|
||||
$this->loader = $loader;
|
||||
$this->resource = $resource;
|
||||
$this->allowParent = $allowParent;
|
||||
|
||||
parent::__construct($parent, $definition, $namespace, $defaults->getTags());
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
|
||||
if ($this->loader) {
|
||||
$this->loader->registerClasses($this->definition, $this->id, $this->resource, $this->exclude);
|
||||
}
|
||||
$this->loader = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Excludes files from registration using a glob pattern.
|
||||
*
|
||||
* @param string $exclude
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function exclude($exclude)
|
||||
{
|
||||
$this->exclude = $exclude;
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
66
vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php
vendored
Normal file
66
vendor/symfony/dependency-injection/Loader/Configurator/ReferenceConfigurator.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ReferenceConfigurator extends AbstractConfigurator
|
||||
{
|
||||
/** @internal */
|
||||
protected $id;
|
||||
|
||||
/** @internal */
|
||||
protected $invalidBehavior = ContainerInterface::EXCEPTION_ON_INVALID_REFERENCE;
|
||||
|
||||
public function __construct($id)
|
||||
{
|
||||
$this->id = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final public function ignoreOnInvalid()
|
||||
{
|
||||
$this->invalidBehavior = ContainerInterface::IGNORE_ON_INVALID_REFERENCE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final public function nullOnInvalid()
|
||||
{
|
||||
$this->invalidBehavior = ContainerInterface::NULL_ON_INVALID_REFERENCE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return $this
|
||||
*/
|
||||
final public function ignoreOnUninitialized()
|
||||
{
|
||||
$this->invalidBehavior = ContainerInterface::IGNORE_ON_UNINITIALIZED_REFERENCE;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function __toString()
|
||||
{
|
||||
return $this->id;
|
||||
}
|
||||
}
|
||||
70
vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php
vendored
Normal file
70
vendor/symfony/dependency-injection/Loader/Configurator/ServiceConfigurator.php
vendored
Normal file
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ServiceConfigurator extends AbstractServiceConfigurator
|
||||
{
|
||||
const FACTORY = 'services';
|
||||
|
||||
use Traits\AbstractTrait;
|
||||
use Traits\ArgumentTrait;
|
||||
use Traits\AutoconfigureTrait;
|
||||
use Traits\AutowireTrait;
|
||||
use Traits\BindTrait;
|
||||
use Traits\CallTrait;
|
||||
use Traits\ClassTrait;
|
||||
use Traits\ConfiguratorTrait;
|
||||
use Traits\DecorateTrait;
|
||||
use Traits\DeprecateTrait;
|
||||
use Traits\FactoryTrait;
|
||||
use Traits\FileTrait;
|
||||
use Traits\LazyTrait;
|
||||
use Traits\ParentTrait;
|
||||
use Traits\PropertyTrait;
|
||||
use Traits\PublicTrait;
|
||||
use Traits\ShareTrait;
|
||||
use Traits\SyntheticTrait;
|
||||
use Traits\TagTrait;
|
||||
|
||||
private $container;
|
||||
private $instanceof;
|
||||
private $allowParent;
|
||||
|
||||
public function __construct(ContainerBuilder $container, array $instanceof, $allowParent, ServicesConfigurator $parent, Definition $definition, $id, array $defaultTags)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->instanceof = $instanceof;
|
||||
$this->allowParent = $allowParent;
|
||||
|
||||
parent::__construct($parent, $definition, $id, $defaultTags);
|
||||
}
|
||||
|
||||
public function __destruct()
|
||||
{
|
||||
parent::__destruct();
|
||||
|
||||
$this->container->removeBindings($this->id);
|
||||
|
||||
if (!$this->definition instanceof ChildDefinition) {
|
||||
$this->container->setDefinition($this->id, $this->definition->setInstanceofConditionals($this->instanceof));
|
||||
} else {
|
||||
$this->container->setDefinition($this->id, $this->definition);
|
||||
}
|
||||
}
|
||||
}
|
||||
154
vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php
vendored
Normal file
154
vendor/symfony/dependency-injection/Loader/Configurator/ServicesConfigurator.php
vendored
Normal file
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException;
|
||||
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
|
||||
|
||||
/**
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*
|
||||
* @method InstanceofConfigurator instanceof($fqcn)
|
||||
*/
|
||||
class ServicesConfigurator extends AbstractConfigurator
|
||||
{
|
||||
const FACTORY = 'services';
|
||||
|
||||
private $defaults;
|
||||
private $container;
|
||||
private $loader;
|
||||
private $instanceof;
|
||||
|
||||
public function __construct(ContainerBuilder $container, PhpFileLoader $loader, array &$instanceof)
|
||||
{
|
||||
$this->defaults = new Definition();
|
||||
$this->container = $container;
|
||||
$this->loader = $loader;
|
||||
$this->instanceof = &$instanceof;
|
||||
$instanceof = [];
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines a set of defaults for following service definitions.
|
||||
*
|
||||
* @return DefaultsConfigurator
|
||||
*/
|
||||
final public function defaults()
|
||||
{
|
||||
return new DefaultsConfigurator($this, $this->defaults = new Definition());
|
||||
}
|
||||
|
||||
/**
|
||||
* Defines an instanceof-conditional to be applied to following service definitions.
|
||||
*
|
||||
* @param string $fqcn
|
||||
*
|
||||
* @return InstanceofConfigurator
|
||||
*/
|
||||
final protected function setInstanceof($fqcn)
|
||||
{
|
||||
$this->instanceof[$fqcn] = $definition = new ChildDefinition('');
|
||||
|
||||
return new InstanceofConfigurator($this, $definition, $fqcn);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function set($id, $class = null)
|
||||
{
|
||||
$defaults = $this->defaults;
|
||||
$allowParent = !$defaults->getChanges() && empty($this->instanceof);
|
||||
|
||||
$definition = new Definition();
|
||||
$definition->setPublic($defaults->isPublic());
|
||||
$definition->setAutowired($defaults->isAutowired());
|
||||
$definition->setAutoconfigured($defaults->isAutoconfigured());
|
||||
$definition->setBindings($defaults->getBindings());
|
||||
$definition->setChanges([]);
|
||||
|
||||
$configurator = new ServiceConfigurator($this->container, $this->instanceof, $allowParent, $this, $definition, $id, $defaults->getTags());
|
||||
|
||||
return null !== $class ? $configurator->class($class) : $configurator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an alias.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string $referencedId
|
||||
*
|
||||
* @return AliasConfigurator
|
||||
*/
|
||||
final public function alias($id, $referencedId)
|
||||
{
|
||||
$ref = static::processValue($referencedId, true);
|
||||
$alias = new Alias((string) $ref, $this->defaults->isPublic());
|
||||
$this->container->setAlias($id, $alias);
|
||||
|
||||
return new AliasConfigurator($this, $alias);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a PSR-4 namespace using a glob pattern.
|
||||
*
|
||||
* @param string $namespace
|
||||
* @param string $resource
|
||||
*
|
||||
* @return PrototypeConfigurator
|
||||
*/
|
||||
final public function load($namespace, $resource)
|
||||
{
|
||||
$allowParent = !$this->defaults->getChanges() && empty($this->instanceof);
|
||||
|
||||
return new PrototypeConfigurator($this, $this->loader, $this->defaults, $namespace, $resource, $allowParent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets an already defined service definition.
|
||||
*
|
||||
* @param string $id
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*
|
||||
* @throws ServiceNotFoundException if the service definition does not exist
|
||||
*/
|
||||
final public function get($id)
|
||||
{
|
||||
$allowParent = !$this->defaults->getChanges() && empty($this->instanceof);
|
||||
$definition = $this->container->getDefinition($id);
|
||||
|
||||
return new ServiceConfigurator($this->container, $definition->getInstanceofConditionals(), $allowParent, $this, $definition, $id, []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param string|null $class
|
||||
*
|
||||
* @return ServiceConfigurator
|
||||
*/
|
||||
final public function __invoke($id, $class = null)
|
||||
{
|
||||
return $this->set($id, $class);
|
||||
}
|
||||
}
|
||||
33
vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php
vendored
Normal file
33
vendor/symfony/dependency-injection/Loader/Configurator/Traits/AbstractTrait.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;
|
||||
|
||||
/**
|
||||
* @method $this abstract(bool $abstract = true)
|
||||
*/
|
||||
trait AbstractTrait
|
||||
{
|
||||
/**
|
||||
* Whether this definition is abstract, that means it merely serves as a
|
||||
* template for other definitions.
|
||||
*
|
||||
* @param bool $abstract
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final protected function setAbstract($abstract = true)
|
||||
{
|
||||
$this->definition->setAbstract($abstract);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
44
vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php
vendored
Normal file
44
vendor/symfony/dependency-injection/Loader/Configurator/Traits/ArgumentTrait.php
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;
|
||||
|
||||
trait ArgumentTrait
|
||||
{
|
||||
/**
|
||||
* Sets the arguments to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param array $arguments An array of arguments
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function args(array $arguments)
|
||||
{
|
||||
$this->definition->setArguments(static::processValue($arguments, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets one argument to pass to the service constructor/factory method.
|
||||
*
|
||||
* @param string|int $key
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function arg($key, $value)
|
||||
{
|
||||
$this->definition->setArgument($key, static::processValue($value, true));
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
37
vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php
vendored
Normal file
37
vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutoconfigureTrait.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\ChildDefinition;
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
|
||||
trait AutoconfigureTrait
|
||||
{
|
||||
/**
|
||||
* Sets whether or not instanceof conditionals should be prepended with a global set.
|
||||
*
|
||||
* @param bool $autoconfigured
|
||||
*
|
||||
* @return $this
|
||||
*
|
||||
* @throws InvalidArgumentException when a parent is already set
|
||||
*/
|
||||
final public function autoconfigure($autoconfigured = true)
|
||||
{
|
||||
if ($autoconfigured && $this->definition instanceof ChildDefinition) {
|
||||
throw new InvalidArgumentException(sprintf('The service "%s" cannot have a "parent" and also have "autoconfigure". Try disabling autoconfiguration for the service.', $this->id));
|
||||
}
|
||||
$this->definition->setAutoconfigured($autoconfigured);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
29
vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php
vendored
Normal file
29
vendor/symfony/dependency-injection/Loader/Configurator/Traits/AutowireTrait.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;
|
||||
|
||||
trait AutowireTrait
|
||||
{
|
||||
/**
|
||||
* Enables/disables autowiring.
|
||||
*
|
||||
* @param bool $autowired
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function autowire($autowired = true)
|
||||
{
|
||||
$this->definition->setAutowired($autowired);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
43
vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php
vendored
Normal file
43
vendor/symfony/dependency-injection/Loader/Configurator/Traits/BindTrait.php
vendored
Normal file
@@ -0,0 +1,43 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of the Symfony package.
|
||||
*
|
||||
* (c) Fabien Potencier <fabien@symfony.com>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Symfony\Component\DependencyInjection\Loader\Configurator\Traits;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
trait BindTrait
|
||||
{
|
||||
/**
|
||||
* Sets bindings.
|
||||
*
|
||||
* Bindings map $named or FQCN arguments to values that should be
|
||||
* injected in the matching parameters (of the constructor, of methods
|
||||
* called and of controller actions).
|
||||
*
|
||||
* @param string $nameOrFqcn A parameter name with its "$" prefix, or a FQCN
|
||||
* @param mixed $valueOrRef The value or reference to bind
|
||||
*
|
||||
* @return $this
|
||||
*/
|
||||
final public function bind($nameOrFqcn, $valueOrRef)
|
||||
{
|
||||
$valueOrRef = static::processValue($valueOrRef, true);
|
||||
if (isset($nameOrFqcn[0]) && '$' !== $nameOrFqcn[0] && !$valueOrRef instanceof Reference) {
|
||||
throw new InvalidArgumentException(sprintf('Invalid binding for service "%s": named arguments must start with a "$", and FQCN must map to references. Neither applies to binding "%s".', $this->id, $nameOrFqcn));
|
||||
}
|
||||
$bindings = $this->definition->getBindings();
|
||||
$bindings[$nameOrFqcn] = $valueOrRef;
|
||||
$this->definition->setBindings($bindings);
|
||||
|
||||
return $this;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user