Update to Drupal 8.1.0. For more information, see https://www.drupal.org/drupal-8.1.0-release-notes
This commit is contained in:
parent
b11a755ba8
commit
c0a0d5a94c
6920 changed files with 64395 additions and 57312 deletions
252
vendor/symfony/dependency-injection/Compiler/AutowirePass.php
vendored
Normal file
252
vendor/symfony/dependency-injection/Compiler/AutowirePass.php
vendored
Normal file
|
@ -0,0 +1,252 @@
|
|||
<?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\Exception\RuntimeException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
|
||||
/**
|
||||
* Guesses constructor arguments of services definitions and try to instantiate services if necessary.
|
||||
*
|
||||
* @author Kévin Dunglas <dunglas@gmail.com>
|
||||
*/
|
||||
class AutowirePass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
private $reflectionClasses = array();
|
||||
private $definedTypes = array();
|
||||
private $types;
|
||||
private $notGuessableTypes = array();
|
||||
|
||||
/**
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if ($definition->isAutowired()) {
|
||||
$this->completeDefinition($id, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
// Free memory and remove circular reference to container
|
||||
$this->container = null;
|
||||
$this->reflectionClasses = array();
|
||||
$this->definedTypes = array();
|
||||
$this->types = null;
|
||||
$this->notGuessableTypes = array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Wires the given definition.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function completeDefinition($id, Definition $definition)
|
||||
{
|
||||
if (!$reflectionClass = $this->getReflectionClass($id, $definition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->container->addClassResource($reflectionClass);
|
||||
|
||||
if (!$constructor = $reflectionClass->getConstructor()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$arguments = $definition->getArguments();
|
||||
foreach ($constructor->getParameters() as $index => $parameter) {
|
||||
if (array_key_exists($index, $arguments) && '' !== $arguments[$index]) {
|
||||
continue;
|
||||
}
|
||||
|
||||
try {
|
||||
if (!$typeHint = $parameter->getClass()) {
|
||||
// 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;
|
||||
}
|
||||
|
||||
if (null === $this->types) {
|
||||
$this->populateAvailableTypes();
|
||||
}
|
||||
|
||||
if (isset($this->types[$typeHint->name])) {
|
||||
$value = new Reference($this->types[$typeHint->name]);
|
||||
} else {
|
||||
try {
|
||||
$value = $this->createAutowiredDefinition($typeHint, $id);
|
||||
} catch (RuntimeException $e) {
|
||||
if ($parameter->allowsNull()) {
|
||||
$value = null;
|
||||
} elseif ($parameter->isDefaultValueAvailable()) {
|
||||
$value = $parameter->getDefaultValue();
|
||||
} else {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
// Typehint against a non-existing class
|
||||
|
||||
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(), $reflectionException->getMessage()), 0, $reflectionException);
|
||||
}
|
||||
|
||||
$value = $parameter->getDefaultValue();
|
||||
}
|
||||
|
||||
$arguments[$index] = $value;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the list of available types.
|
||||
*/
|
||||
private function populateAvailableTypes()
|
||||
{
|
||||
$this->types = array();
|
||||
|
||||
foreach ($this->container->getDefinitions() as $id => $definition) {
|
||||
$this->populateAvailableType($id, $definition);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Populates the list of available types for a given definition.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
*/
|
||||
private function populateAvailableType($id, Definition $definition)
|
||||
{
|
||||
// Never use abstract services
|
||||
if ($definition->isAbstract()) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($definition->getAutowiringTypes() as $type) {
|
||||
$this->definedTypes[$type] = true;
|
||||
$this->types[$type] = $id;
|
||||
}
|
||||
|
||||
if (!$reflectionClass = $this->getReflectionClass($id, $definition)) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ($reflectionClass->getInterfaces() as $reflectionInterface) {
|
||||
$this->set($reflectionInterface->name, $id);
|
||||
}
|
||||
|
||||
do {
|
||||
$this->set($reflectionClass->name, $id);
|
||||
} while ($reflectionClass = $reflectionClass->getParentClass());
|
||||
}
|
||||
|
||||
/**
|
||||
* Associates a type and a service id if applicable.
|
||||
*
|
||||
* @param string $type
|
||||
* @param string $id
|
||||
*/
|
||||
private function set($type, $id)
|
||||
{
|
||||
if (isset($this->definedTypes[$type]) || isset($this->notGuessableTypes[$type])) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (isset($this->types[$type])) {
|
||||
if ($this->types[$type] === $id) {
|
||||
return;
|
||||
}
|
||||
|
||||
unset($this->types[$type]);
|
||||
$this->notGuessableTypes[$type] = true;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$this->types[$type] = $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a definition for the type if possible or throws an exception.
|
||||
*
|
||||
* @param \ReflectionClass $typeHint
|
||||
* @param string $id
|
||||
*
|
||||
* @return Reference A reference to the registered definition
|
||||
*
|
||||
* @throws RuntimeException
|
||||
*/
|
||||
private function createAutowiredDefinition(\ReflectionClass $typeHint, $id)
|
||||
{
|
||||
if (isset($this->notGuessableTypes[$typeHint->name]) || !$typeHint->isInstantiable()) {
|
||||
throw new RuntimeException(sprintf('Unable to autowire argument of type "%s" for the service "%s".', $typeHint->name, $id));
|
||||
}
|
||||
|
||||
$argumentId = sprintf('autowired.%s', $typeHint->name);
|
||||
|
||||
$argumentDefinition = $this->container->register($argumentId, $typeHint->name);
|
||||
$argumentDefinition->setPublic(false);
|
||||
|
||||
$this->populateAvailableType($argumentId, $argumentDefinition);
|
||||
$this->completeDefinition($argumentId, $argumentDefinition);
|
||||
|
||||
return new Reference($argumentId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves the reflection class associated with the given service.
|
||||
*
|
||||
* @param string $id
|
||||
* @param Definition $definition
|
||||
*
|
||||
* @return \ReflectionClass|null
|
||||
*/
|
||||
private function getReflectionClass($id, Definition $definition)
|
||||
{
|
||||
if (isset($this->reflectionClasses[$id])) {
|
||||
return $this->reflectionClasses[$id];
|
||||
}
|
||||
|
||||
// Cannot use reflection if the class isn't set
|
||||
if (!$class = $definition->getClass()) {
|
||||
return;
|
||||
}
|
||||
|
||||
$class = $this->container->getParameterBag()->resolveValue($class);
|
||||
|
||||
try {
|
||||
return $this->reflectionClasses[$id] = new \ReflectionClass($class);
|
||||
} catch (\ReflectionException $reflectionException) {
|
||||
// return null
|
||||
}
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ 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>
|
||||
*/
|
||||
|
@ -46,10 +47,15 @@ class CheckDefinitionValidityPass implements CompilerPassInterface
|
|||
}
|
||||
|
||||
// synthetic service has non-prototype scope
|
||||
if ($definition->isSynthetic() && ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -46,10 +46,10 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
{
|
||||
$this->container = $container;
|
||||
|
||||
$children = $this->container->getScopeChildren();
|
||||
$children = $this->container->getScopeChildren(false);
|
||||
$ancestors = array();
|
||||
|
||||
$scopes = $this->container->getScopes();
|
||||
$scopes = $this->container->getScopes(false);
|
||||
foreach ($scopes as $name => $parent) {
|
||||
$ancestors[$name] = array($parent);
|
||||
|
||||
|
@ -64,7 +64,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
}
|
||||
|
||||
$this->currentId = $id;
|
||||
$this->currentScope = $scope = $definition->getScope();
|
||||
$this->currentScope = $scope = $definition->getScope(false);
|
||||
|
||||
if (ContainerInterface::SCOPE_CONTAINER === $scope) {
|
||||
$this->currentScopeChildren = array_keys($scopes);
|
||||
|
@ -124,7 +124,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
return;
|
||||
}
|
||||
|
||||
if (!$reference->isStrict()) {
|
||||
if (!$reference->isStrict(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ class CheckReferenceValidityPass implements CompilerPassInterface
|
|||
return;
|
||||
}
|
||||
|
||||
if ($this->currentScope === $scope = $definition->getScope()) {
|
||||
if ($this->currentScope === $scope = $definition->getScope(false)) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,18 +19,28 @@ use Symfony\Component\DependencyInjection\Alias;
|
|||
*
|
||||
* @author Christophe Coevoet <stof@notk.org>
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Diego Saint Esteben <diego@saintesteben.me>
|
||||
*/
|
||||
class DecoratorServicePass implements CompilerPassInterface
|
||||
{
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$definitions = new \SplPriorityQueue();
|
||||
$order = PHP_INT_MAX;
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
if (!$decorated = $definition->getDecoratedService()) {
|
||||
continue;
|
||||
}
|
||||
$definitions->insert(array($id, $definition), array($decorated[2], --$order));
|
||||
}
|
||||
|
||||
foreach ($definitions as $arr) {
|
||||
list($id, $definition) = $arr;
|
||||
list($inner, $renamedId) = $definition->getDecoratedService();
|
||||
|
||||
$definition->setDecoratedService(null);
|
||||
|
||||
list($inner, $renamedId) = $decorated;
|
||||
if (!$renamedId) {
|
||||
$renamedId = $id.'.inner';
|
||||
}
|
||||
|
|
|
@ -48,27 +48,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
$this->graph = $this->compiler->getServiceReferenceGraph();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
$this->currentId = $id;
|
||||
|
||||
$definition->setArguments(
|
||||
$this->inlineArguments($container, $definition->getArguments())
|
||||
);
|
||||
|
||||
$definition->setMethodCalls(
|
||||
$this->inlineArguments($container, $definition->getMethodCalls())
|
||||
);
|
||||
|
||||
$definition->setProperties(
|
||||
$this->inlineArguments($container, $definition->getProperties())
|
||||
);
|
||||
|
||||
$configurator = $this->inlineArguments($container, array($definition->getConfigurator()));
|
||||
$definition->setConfigurator($configurator[0]);
|
||||
|
||||
$factory = $this->inlineArguments($container, array($definition->getFactory()));
|
||||
$definition->setFactory($factory[0]);
|
||||
}
|
||||
$container->setDefinitions($this->inlineArguments($container, $container->getDefinitions(), true));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -76,12 +56,16 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
*
|
||||
* @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 inlineArguments(ContainerBuilder $container, array $arguments)
|
||||
private function inlineArguments(ContainerBuilder $container, array $arguments, $isRoot = false)
|
||||
{
|
||||
foreach ($arguments as $k => $argument) {
|
||||
if ($isRoot) {
|
||||
$this->currentId = $k;
|
||||
}
|
||||
if (is_array($argument)) {
|
||||
$arguments[$k] = $this->inlineArguments($container, $argument);
|
||||
} elseif ($argument instanceof Reference) {
|
||||
|
@ -92,7 +76,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
if ($this->isInlineableDefinition($container, $id, $definition = $container->getDefinition($id))) {
|
||||
$this->compiler->addLogMessage($this->formatter->formatInlineService($this, $id, $this->currentId));
|
||||
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope()) {
|
||||
if ($definition->isShared() && ContainerInterface::SCOPE_PROTOTYPE !== $definition->getScope(false)) {
|
||||
$arguments[$k] = $definition;
|
||||
} else {
|
||||
$arguments[$k] = clone $definition;
|
||||
|
@ -102,6 +86,12 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
$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]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -119,7 +109,7 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
*/
|
||||
private function isInlineableDefinition(ContainerBuilder $container, $id, Definition $definition)
|
||||
{
|
||||
if (ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope()) {
|
||||
if (!$definition->isShared() || ContainerInterface::SCOPE_PROTOTYPE === $definition->getScope(false)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -152,6 +142,6 @@ class InlineServiceDefinitionsPass implements RepeatablePassInterface
|
|||
return false;
|
||||
}
|
||||
|
||||
return $container->getDefinition(reset($ids))->getScope() === $definition->getScope();
|
||||
return $container->getDefinition(reset($ids))->getScope(false) === $definition->getScope(false);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,7 +20,7 @@ class LoggingFormatter
|
|||
{
|
||||
public function formatRemoveService(CompilerPassInterface $pass, $id, $reason)
|
||||
{
|
||||
return $this->format($pass, sprintf('Removed service "%s"; reason: %s', $id, $reason));
|
||||
return $this->format($pass, sprintf('Removed service "%s"; reason: %s.', $id, $reason));
|
||||
}
|
||||
|
||||
public function formatInlineService(CompilerPassInterface $pass, $id, $target)
|
||||
|
|
|
@ -50,6 +50,7 @@ class PassConfig
|
|||
new CheckDefinitionValidityPass(),
|
||||
new ResolveReferencesToAliasesPass(),
|
||||
new ResolveInvalidReferencesPass(),
|
||||
new AutowirePass(),
|
||||
new AnalyzeServiceReferencesPass(true),
|
||||
new CheckCircularReferencesPass(),
|
||||
new CheckReferenceValidityPass(),
|
||||
|
|
|
@ -45,7 +45,7 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
|
|||
try {
|
||||
$definition = $container->getDefinition($aliasId);
|
||||
} catch (InvalidArgumentException $e) {
|
||||
throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with "%s".', $alias, $id), null, $e);
|
||||
throw new InvalidArgumentException(sprintf('Unable to replace alias "%s" with actual definition "%s".', $id, $alias), null, $e);
|
||||
}
|
||||
|
||||
if ($definition->isPublic()) {
|
||||
|
@ -95,6 +95,9 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
|
|||
$definition->setProperties(
|
||||
$this->updateArgumentReferences($definition->getProperties(), $currentId, $newId)
|
||||
);
|
||||
|
||||
$definition->setFactoryService($this->updateFactoryServiceReference($definition->getFactoryService(false), $currentId, $newId), false);
|
||||
$definition->setFactory($this->updateFactoryReference($definition->getFactory(), $currentId, $newId));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -122,4 +125,26 @@ class ReplaceAliasByActualDefinitionPass implements CompilerPassInterface
|
|||
|
||||
return $arguments;
|
||||
}
|
||||
|
||||
private function updateFactoryServiceReference($factoryService, $currentId, $newId)
|
||||
{
|
||||
if (null === $factoryService) {
|
||||
return;
|
||||
}
|
||||
|
||||
return $currentId === $factoryService ? $newId : $factoryService;
|
||||
}
|
||||
|
||||
private function updateFactoryReference($factory, $currentId, $newId)
|
||||
{
|
||||
if (null === $factory || !is_array($factory) || !$factory[0] instanceof Reference) {
|
||||
return $factory;
|
||||
}
|
||||
|
||||
if ($currentId === (string) $factory[0]) {
|
||||
$factory[0] = new Reference($newId, $factory[0]->getInvalidBehavior());
|
||||
}
|
||||
|
||||
return $factory;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,12 +21,13 @@ use Symfony\Component\DependencyInjection\Exception\RuntimeException;
|
|||
* merged Definition instance.
|
||||
*
|
||||
* @author Johannes M. Schmitt <schmittjoh@gmail.com>
|
||||
* @author Nicolas Grekas <p@tchwork.com>
|
||||
*/
|
||||
class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
||||
{
|
||||
private $container;
|
||||
private $compiler;
|
||||
private $formatter;
|
||||
private $currentId;
|
||||
|
||||
/**
|
||||
* Process the ContainerBuilder to replace DefinitionDecorator instances with their real Definition instances.
|
||||
|
@ -35,44 +36,80 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
*/
|
||||
public function process(ContainerBuilder $container)
|
||||
{
|
||||
$this->container = $container;
|
||||
$this->compiler = $container->getCompiler();
|
||||
$this->formatter = $this->compiler->getLoggingFormatter();
|
||||
|
||||
foreach ($container->getDefinitions() as $id => $definition) {
|
||||
// yes, we are specifically fetching the definition from the
|
||||
// container to ensure we are not operating on stale data
|
||||
$definition = $container->getDefinition($id);
|
||||
if (!$definition instanceof DefinitionDecorator || $definition->isAbstract()) {
|
||||
continue;
|
||||
}
|
||||
$container->setDefinitions($this->resolveArguments($container, $container->getDefinitions(), true));
|
||||
}
|
||||
|
||||
$this->resolveDefinition($id, $definition);
|
||||
/**
|
||||
* 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 string $id The definition identifier
|
||||
* @param ContainerBuilder $container The ContainerBuilder
|
||||
* @param DefinitionDecorator $definition
|
||||
*
|
||||
* @return Definition
|
||||
*
|
||||
* @throws \RuntimeException When the definition is invalid
|
||||
*/
|
||||
private function resolveDefinition($id, DefinitionDecorator $definition)
|
||||
private function resolveDefinition(ContainerBuilder $container, DefinitionDecorator $definition)
|
||||
{
|
||||
if (!$this->container->hasDefinition($parent = $definition->getParent())) {
|
||||
throw new RuntimeException(sprintf('The parent definition "%s" defined for definition "%s" does not exist.', $parent, $id));
|
||||
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 = $this->container->getDefinition($parent);
|
||||
$parentDef = $container->getDefinition($parent);
|
||||
if ($parentDef instanceof DefinitionDecorator) {
|
||||
$parentDef = $this->resolveDefinition($parent, $parentDef);
|
||||
$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, $id, $parent));
|
||||
$this->compiler->addLogMessage($this->formatter->formatResolveInheritance($this, $this->currentId, $parent));
|
||||
$def = new Definition();
|
||||
|
||||
// merge in parent definition
|
||||
|
@ -81,6 +118,7 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
$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));
|
||||
}
|
||||
|
@ -90,6 +128,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
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());
|
||||
|
@ -125,6 +166,9 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
if (isset($changes['lazy'])) {
|
||||
$def->setLazy($definition->isLazy());
|
||||
}
|
||||
if (isset($changes['deprecated'])) {
|
||||
$def->setDeprecated($definition->isDeprecated(), $definition->getDeprecationMessage('%service_id%'));
|
||||
}
|
||||
if (isset($changes['decorated_service'])) {
|
||||
$decoratedService = $definition->getDecoratedService();
|
||||
if (null === $decoratedService) {
|
||||
|
@ -159,14 +203,17 @@ class ResolveDefinitionTemplatesPass implements CompilerPassInterface
|
|||
$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());
|
||||
$def->setScope($definition->getScope(false), false);
|
||||
$def->setShared($definition->isShared());
|
||||
$def->setTags($definition->getTags());
|
||||
|
||||
// set new definition on container
|
||||
$this->container->setDefinition($id, $def);
|
||||
|
||||
return $def;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
namespace Symfony\Component\DependencyInjection\Compiler;
|
||||
|
||||
use Symfony\Component\DependencyInjection\Alias;
|
||||
use Symfony\Component\DependencyInjection\Definition;
|
||||
use Symfony\Component\DependencyInjection\Exception\ServiceCircularReferenceException;
|
||||
use Symfony\Component\DependencyInjection\Reference;
|
||||
use Symfony\Component\DependencyInjection\ContainerBuilder;
|
||||
|
@ -42,6 +43,8 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
|||
$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);
|
||||
}
|
||||
|
||||
foreach ($container->getAliases() as $id => $alias) {
|
||||
|
@ -68,7 +71,7 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
|||
$defId = $this->getDefinitionId($id = (string) $argument);
|
||||
|
||||
if ($defId !== $id) {
|
||||
$arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict());
|
||||
$arguments[$k] = new Reference($defId, $argument->getInvalidBehavior(), $argument->isStrict(false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -76,6 +79,30 @@ class ResolveReferencesToAliasesPass implements CompilerPassInterface
|
|||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Resolves an alias into a definition id.
|
||||
*
|
||||
|
|
Reference in a new issue