Verzeichnisstruktur phpBB-3.3.15
- Veröffentlicht
- 28.08.2024
So funktioniert es
|
Auf das letzte Element klicken. Dies geht jeweils ein Schritt zurück |
Auf das Icon klicken, dies öffnet das Verzeichnis. Nochmal klicken schließt das Verzeichnis. |
|
(Beispiel Datei-Icons)
|
Auf das Icon klicken um den Quellcode anzuzeigen |
ResolveInstanceofConditionalsPass.php
001 <?php
002
003 /*
004 * This file is part of the Symfony package.
005 *
006 * (c) Fabien Potencier <fabien@symfony.com>
007 *
008 * For the full copyright and license information, please view the LICENSE
009 * file that was distributed with this source code.
010 */
011
012 namespace Symfony\Component\DependencyInjection\Compiler;
013
014 use Symfony\Component\DependencyInjection\ChildDefinition;
015 use Symfony\Component\DependencyInjection\ContainerBuilder;
016 use Symfony\Component\DependencyInjection\Definition;
017 use Symfony\Component\DependencyInjection\Exception\InvalidArgumentException;
018 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
019
020 /**
021 * Applies instanceof conditionals to definitions.
022 *
023 * @author Nicolas Grekas <p@tchwork.com>
024 */
025 class ResolveInstanceofConditionalsPass implements CompilerPassInterface
026 {
027 /**
028 * {@inheritdoc}
029 */
030 public function process(ContainerBuilder $container)
031 {
032 foreach ($container->getAutoconfiguredInstanceof() as $interface => $definition) {
033 if ($definition->getArguments()) {
034 throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines arguments but these are not supported and should be removed.', $interface));
035 }
036 if ($definition->getMethodCalls()) {
037 throw new InvalidArgumentException(sprintf('Autoconfigured instanceof for type "%s" defines method calls but these are not supported and should be removed.', $interface));
038 }
039 }
040
041 foreach ($container->getDefinitions() as $id => $definition) {
042 if ($definition instanceof ChildDefinition) {
043 // don't apply "instanceof" to children: it will be applied to their parent
044 continue;
045 }
046 $container->setDefinition($id, $this->processDefinition($container, $id, $definition));
047 }
048 }
049
050 private function processDefinition(ContainerBuilder $container, $id, Definition $definition)
051 {
052 $instanceofConditionals = $definition->getInstanceofConditionals();
053 $autoconfiguredInstanceof = $definition->isAutoconfigured() ? $container->getAutoconfiguredInstanceof() : [];
054 if (!$instanceofConditionals && !$autoconfiguredInstanceof) {
055 return $definition;
056 }
057
058 if (!$class = $container->getParameterBag()->resolveValue($definition->getClass())) {
059 return $definition;
060 }
061
062 $conditionals = $this->mergeConditionals($autoconfiguredInstanceof, $instanceofConditionals, $container);
063
064 $definition->setInstanceofConditionals([]);
065 $parent = $shared = null;
066 $instanceofTags = [];
067 $reflectionClass = null;
068
069 foreach ($conditionals as $interface => $instanceofDefs) {
070 if ($interface !== $class && !(null === $reflectionClass ? $reflectionClass = ($container->getReflectionClass($class, false) ?: false) : $reflectionClass)) {
071 continue;
072 }
073
074 if ($interface !== $class && !is_subclass_of($class, $interface)) {
075 continue;
076 }
077
078 foreach ($instanceofDefs as $key => $instanceofDef) {
079 /** @var ChildDefinition $instanceofDef */
080 $instanceofDef = clone $instanceofDef;
081 $instanceofDef->setAbstract(true)->setParent($parent ?: 'abstract.instanceof.'.$id);
082 $parent = 'instanceof.'.$interface.'.'.$key.'.'.$id;
083 $container->setDefinition($parent, $instanceofDef);
084 $instanceofTags[] = $instanceofDef->getTags();
085 $instanceofDef->setTags([]);
086
087 if (isset($instanceofDef->getChanges()['shared'])) {
088 $shared = $instanceofDef->isShared();
089 }
090 }
091 }
092
093 if ($parent) {
094 $bindings = $definition->getBindings();
095 $abstract = $container->setDefinition('abstract.instanceof.'.$id, $definition);
096
097 // cast Definition to ChildDefinition
098 $definition->setBindings([]);
099 $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 }
157