[ Index ] |
PHP Cross Reference of phpBB-3.3.14-deutsch |
[Summary view] [Print] [Text view]
1 <?php 2 3 /* 4 * This file is part of the Symfony package. 5 * 6 * (c) Fabien Potencier <fabien@symfony.com> 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11 12 namespace Symfony\Component\DependencyInjection\Compiler; 13 14 use Symfony\Component\DependencyInjection\ChildDefinition; 15 use Symfony\Component\DependencyInjection\ContainerBuilder; 16 use Symfony\Component\DependencyInjection\Definition; 17 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException; 18 use Symfony\Component\DependencyInjection\Exception\RuntimeException; 19 20 /** 21 * Applies instanceof conditionals to definitions. 22 * 23 * @author Nicolas Grekas <p@tchwork.com> 24 */ 25 class ResolveInstanceofConditionalsPass implements CompilerPassInterface 26 { 27 /** 28 * {@inheritdoc} 29 */ 30 public function process(ContainerBuilder $container) 31 { 32 foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) { 33 if ($definition->getArguments()) { 34 throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface)); 35 } 36 if ($definition->getMethodCalls()) { 37 throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface)); 38 } 39 } 40 41 foreach ($container->getDefinitions() as $id => $definition) { 42 if ($definition instanceof ChildDefinition) { 43 // don't apply "instanceof" to children: it will be applied to their parent 44 continue; 45 } 46 $container->setDefinition($id, $this->processDefinition($container, $id, $definition)); 47 } 48 } 49 50 private function processDefinition(ContainerBuilder $container, $id, Definition $definition) 51 { 52 $instanceofConditionals = $definition->getInstanceofConditionals(); 53 $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : []; 54 if (!$instanceofConditionals && !$autoconfiguredInstanceof) { 55 return $definition; 56 } 57 58 if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) { 59 return $definition; 60 } 61 62 $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container); 63 64 $definition->setInstanceofConditionals([]); 65 $parent = $shared = null; 66 $instanceofTags = []; 67 $reflectionClass = null; 68 69 foreach ($conditionals as $interface => $instanceofDefs) { 70 if ($interface !== $class && !(null === $reflectionClass ? $reflectionClass = ($container->getReflectionClass($class, false) ?: false) : $reflectionClass)) { 71 continue; 72 } 73 74 if ($interface !== $class && !is_subclass_of($class, $interface)) { 75 continue; 76 } 77 78 foreach ($instanceofDefs as $key => $instanceofDef) { 79 /** @var ChildDefinition $instanceofDef */ 80 $instanceofDef = clone $instanceofDef; 81 $instanceofDef->setAbstract(true)->setParent($parent ?: 'abstract.instanceof.'.$id); 82 $parent = 'instanceof.'.$interface.'.'.$key.'.'.$id; 83 $container->setDefinition($parent, $instanceofDef); 84 $instanceofTags[] = $instanceofDef->getTags(); 85 $instanceofDef->setTags([]); 86 87 if (isset($instanceofDef->getChanges()['shared'])) { 88 $shared = $instanceofDef->isShared(); 89 } 90 } 91 } 92 93 if ($parent) { 94 $bindings = $definition->getBindings(); 95 $abstract = $container->setDefinition('abstract.instanceof.'.$id, $definition); 96 97 // cast Definition to ChildDefinition 98 $definition->setBindings([]); 99 $definition = serialize($definition); 100 $definition = substr_replace($definition, '53', 2, 2); 101 $definition = substr_replace($definition, 'Child', 44, 0); 102 $definition = unserialize($definition); 103 $definition->setParent($parent); 104 105 if (null !== $shared && !isset($definition->getChanges()['shared'])) { 106 $definition->setShared($shared); 107 } 108 109 $i = \count($instanceofTags); 110 while (0 <= --$i) { 111 foreach ($instanceofTags[$i] as $k => $v) { 112 foreach ($v as $v) { 113 if ($definition->hasTag($k) && \in_array($v, $definition->getTag($k))) { 114 continue; 115 } 116 $definition->addTag($k, $v); 117 } 118 } 119 } 120 121 $definition->setBindings($bindings); 122 123 // reset fields with "merge" behavior 124 $abstract 125 ->setBindings([]) 126 ->setArguments([]) 127 ->setMethodCalls([]) 128 ->setDecoratedService(null) 129 ->setTags([]) 130 ->setAbstract(true); 131 } 132 133 return $definition; 134 } 135 136 private function mergeConditionals(array $autoconfiguredInstanceof, array $instanceofConditionals, ContainerBuilder $container) 137 { 138 // make each value an array of ChildDefinition 139 $conditionals = array_map(function ($childDef) { return [$childDef]; }, $autoconfiguredInstanceof); 140 141 foreach ($instanceofConditionals as $interface => $instanceofDef) { 142 // make sure the interface/class exists (but don't validate automaticInstanceofConditionals) 143 if (!$container->getReflectionClass($interface)) { 144 throw new RuntimeException(sprintf('"%s" is set as an "instanceof" conditional, but it does not exist.', $interface)); 145 } 146 147 if (!isset($autoconfiguredInstanceof[$interface])) { 148 $conditionals[$interface] = []; 149 } 150 151 $conditionals[$interface][] = $instanceofDef; 152 } 153 154 return $conditionals; 155 } 156 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Mon Nov 25 19:05:08 2024 | Cross-referenced by PHPXref 0.7.1 |