2017-04-07 17:38:55 +01:00
|
|
|
<?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;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Applies instanceof conditionals to definitions.
|
|
|
|
*
|
|
|
|
* @author Nicolas Grekas <p@tchwork.com>
|
|
|
|
*/
|
|
|
|
class ResolveInstanceofConditionalsPass implements CompilerPassInterface
|
|
|
|
{
|
|
|
|
/**
|
|
|
|
* {@inheritdoc}
|
|
|
|
*/
|
|
|
|
public function process(ContainerBuilder $container)
|
|
|
|
{
|
|
|
|
foreach ($container->getDefinitions() as $id => $definition) {
|
|
|
|
if ($definition instanceof ChildDefinition) {
|
2017-04-11 14:35:46 +01:00
|
|
|
// don't apply "instanceof" to children: it will be applied to their parent
|
2017-04-07 17:38:55 +01:00
|
|
|
continue;
|
|
|
|
}
|
2017-04-11 23:06:53 +01:00
|
|
|
$container->setDefinition($id, $this->processDefinition($container, $id, $definition));
|
2017-04-07 17:38:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
private function processDefinition(ContainerBuilder $container, $id, Definition $definition)
|
|
|
|
{
|
|
|
|
if (!$instanceofConditionals = $definition->getInstanceofConditionals()) {
|
|
|
|
return $definition;
|
|
|
|
}
|
|
|
|
if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) {
|
|
|
|
return $definition;
|
|
|
|
}
|
|
|
|
|
|
|
|
$definition->setInstanceofConditionals(array());
|
2017-04-11 23:06:53 +01:00
|
|
|
$parent = $shared = null;
|
|
|
|
$instanceofTags = array();
|
2017-04-07 17:38:55 +01:00
|
|
|
|
|
|
|
foreach ($instanceofConditionals as $interface => $instanceofDef) {
|
|
|
|
if ($interface !== $class && (!$container->getReflectionClass($interface) || !$container->getReflectionClass($class))) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if ($interface === $class || is_subclass_of($class, $interface)) {
|
2017-04-11 23:06:53 +01:00
|
|
|
$instanceofDef = clone $instanceofDef;
|
|
|
|
$instanceofDef->setAbstract(true)->setInheritTags(false)->setParent($parent ?: 'abstract.instanceof.'.$id);
|
2017-04-07 17:38:55 +01:00
|
|
|
$parent = 'instanceof.'.$interface.'.'.$id;
|
2017-04-11 23:06:53 +01:00
|
|
|
$container->setDefinition($parent, $instanceofDef);
|
|
|
|
$instanceofTags[] = $instanceofDef->getTags();
|
|
|
|
$instanceofDef->setTags(array());
|
2017-04-07 17:38:55 +01:00
|
|
|
|
2017-04-11 23:06:53 +01:00
|
|
|
if (isset($instanceofDef->getChanges()['shared'])) {
|
|
|
|
$shared = $instanceofDef->isShared();
|
2017-04-07 17:38:55 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-11 23:06:53 +01:00
|
|
|
if ($parent) {
|
|
|
|
$abstract = $container->setDefinition('abstract.instanceof.'.$id, $definition);
|
|
|
|
|
2017-04-07 17:38:55 +01:00
|
|
|
// cast Definition to ChildDefinition
|
|
|
|
$definition = serialize($definition);
|
|
|
|
$definition = substr_replace($definition, '53', 2, 2);
|
|
|
|
$definition = substr_replace($definition, 'Child', 44, 0);
|
|
|
|
$definition = unserialize($definition);
|
2017-04-11 23:06:53 +01:00
|
|
|
$definition->setParent($parent);
|
2017-04-07 17:38:55 +01:00
|
|
|
|
|
|
|
if (null !== $shared && !isset($definition->getChanges()['shared'])) {
|
|
|
|
$definition->setShared($shared);
|
|
|
|
}
|
2017-04-11 23:06:53 +01:00
|
|
|
|
|
|
|
$i = count($instanceofTags);
|
|
|
|
while (0 <= --$i) {
|
|
|
|
foreach ($instanceofTags[$i] as $k => $v) {
|
|
|
|
foreach ($v as $v) {
|
|
|
|
$definition->addTag($k, $v);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// reset fields with "merge" behavior
|
|
|
|
$abstract
|
|
|
|
->setArguments(array())
|
|
|
|
->setMethodCalls(array())
|
|
|
|
->setTags(array())
|
|
|
|
->setAbstract(true);
|
2017-04-07 17:38:55 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
return $definition;
|
|
|
|
}
|
|
|
|
}
|