* * 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\RuntimeException; use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; /** * Applies instanceof conditionals to definitions. * * @author Nicolas Grekas */ 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() : array(); if (!$instanceofConditionals && !$autoconfiguredInstanceof) { return $definition; } if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) { return $definition; } $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container); $definition->setInstanceofConditionals(array()); $parent = $shared = null; $instanceofTags = array(); 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(array()); 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(array()); $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); } } } // reset fields with "merge" behavior $abstract ->setBindings($bindings) ->setArguments(array()) ->setMethodCalls(array()) ->setDecoratedService(null) ->setTags(array()) ->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 array($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] = array(); } $conditionals[$interface][] = $instanceofDef; } return $conditionals; } } __halt_compiler();----SIGNATURE:----fupZCmG4PB45UzIZzQQqt2dWN8gwD16fryx7U1uzuUapslWhNol0SaXFPKBRP5E+a0wch9TTFOzy1wWWMmDt25sl6e4urtzw6ENDBkU4XbCcEgMgNjpUu/iytQirbnNoWhQbrt0+MhWtybNw458lE3ko2JyIaePfGJe/CQc3jrRBAnQfQOhHrlrqGaL6Ko6vfcaUc1kwQIeC7erf89dbn1zO6yoaexZZFnv7Fa3a58V3ISuD6Q5ClEAQFV0BjTaGRZ4E8jId2F0J0Dy8DOmlC6Ffur0TVn39V6A0d7iHtuILp1W9sFFvZH3+J+dDEHFzdpQHLE/OlisYm83tr8MpAH0nvcvgGeNV/ckUcHvebDYnAw+k2TphKjdgkpwiAeBlC52J95Uxh9u5m+vezvhFvoELYGCjD3V6dcAJVOjemc44Dz+xS52mn5sqG9sjdFUkJOMWGupkCxALwgZgXgojvqByeb3MA6fsBbe6+VCfhsFVnNfRQ/EtekUkDcpk+p4ZNT0EzNVSrQbXvdEGc8PrUQQoyBoV4yAvXXGRKRRUcQGTUx1nfrn8vIp99t/2NC2jMX3+5Q/OEG6Jisn3KvTowCz1djRJm/jThkmxHw/IKysfu2MlcHHL0/gBFmq9F58pNBq4NV3cib0sTbihEECDfdpQhFxpVpc6wasi8VEMw6E=----ATTACHMENT:----Njg5NzU3ODU1NDA4NTM2NiAyOTUwNjA1MzM5NTI2NTc4IDQyMDU2MTg5Mjg5OTcwMzk=