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 |
MergeExtensionConfigurationPass.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\ContainerBuilder;
015 use Symfony\Component\DependencyInjection\Exception\LogicException;
016 use Symfony\Component\DependencyInjection\Exception\RuntimeException;
017 use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
018 use Symfony\Component\DependencyInjection\Extension\Extension;
019 use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
020 use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
021 use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
022 use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
023
024 /**
025 * Merges extension configs into the container builder.
026 *
027 * @author Fabien Potencier <fabien@symfony.com>
028 */
029 class MergeExtensionConfigurationPass implements CompilerPassInterface
030 {
031 /**
032 * {@inheritdoc}
033 */
034 public function process(ContainerBuilder $container)
035 {
036 $parameters = $container->getParameterBag()->all();
037 $definitions = $container->getDefinitions();
038 $aliases = $container->getAliases();
039 $exprLangProviders = $container->getExpressionLanguageProviders();
040
041 foreach ($container->getExtensions() as $extension) {
042 if ($extension instanceof PrependExtensionInterface) {
043 $extension->prepend($container);
044 }
045 }
046
047 foreach ($container->getExtensions() as $name => $extension) {
048 if (!$config = $container->getExtensionConfig($name)) {
049 // this extension was not called
050 continue;
051 }
052 $resolvingBag = $container->getParameterBag();
053 if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) {
054 // create a dedicated bag so that we can track env vars per-extension
055 $resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag);
056 }
057 $config = $resolvingBag->resolveValue($config);
058
059 try {
060 $tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag);
061 $tmpContainer->setResourceTracking($container->isTrackingResources());
062 $tmpContainer->addObjectResource($extension);
063 if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
064 $tmpContainer->addObjectResource($configuration);
065 }
066
067 foreach ($exprLangProviders as $provider) {
068 $tmpContainer->addExpressionLanguageProvider($provider);
069 }
070
071 $extension->load($config, $tmpContainer);
072 } catch (\Exception $e) {
073 if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
074 $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag);
075 }
076
077 throw $e;
078 }
079
080 if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
081 // don't keep track of env vars that are *overridden* when configs are merged
082 $resolvingBag->freezeAfterProcessing($extension, $tmpContainer);
083 }
084
085 $container->merge($tmpContainer);
086 $container->getParameterBag()->add($parameters);
087 }
088
089 $container->addDefinitions($definitions);
090 $container->addAliases($aliases);
091 }
092 }
093
094 /**
095 * @internal
096 */
097 class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag
098 {
099 private $processedEnvPlaceholders;
100
101 public function __construct(parent $parameterBag)
102 {
103 parent::__construct($parameterBag->all());
104 $this->mergeEnvPlaceholders($parameterBag);
105 }
106
107 public function freezeAfterProcessing(Extension $extension, ContainerBuilder $container)
108 {
109 if (!$config = $extension->getProcessedConfigs()) {
110 // Extension::processConfiguration() wasn't called, we cannot know how configs were merged
111 return;
112 }
113 $this->processedEnvPlaceholders = [];
114
115 // serialize config and container to catch env vars nested in object graphs
116 $config = serialize($config).serialize($container->getDefinitions()).serialize($container->getAliases()).serialize($container->getParameterBag()->all());
117
118 foreach (parent::getEnvPlaceholders() as $env => $placeholders) {
119 foreach ($placeholders as $placeholder) {
120 if (false !== stripos($config, $placeholder)) {
121 $this->processedEnvPlaceholders[$env] = $placeholders;
122 break;
123 }
124 }
125 }
126 }
127
128 /**
129 * {@inheritdoc}
130 */
131 public function getEnvPlaceholders()
132 {
133 return null !== $this->processedEnvPlaceholders ? $this->processedEnvPlaceholders : parent::getEnvPlaceholders();
134 }
135 }
136
137 /**
138 * A container builder preventing using methods that wouldn't have any effect from extensions.
139 *
140 * @internal
141 */
142 class MergeExtensionConfigurationContainerBuilder extends ContainerBuilder
143 {
144 private $extensionClass;
145
146 public function __construct(ExtensionInterface $extension, ParameterBagInterface $parameterBag = null)
147 {
148 parent::__construct($parameterBag);
149
150 $this->extensionClass = \get_class($extension);
151 }
152
153 /**
154 * {@inheritdoc}
155 */
156 public function addCompilerPass(CompilerPassInterface $pass, $type = PassConfig::TYPE_BEFORE_OPTIMIZATION/*, int $priority = 0*/)
157 {
158 throw new LogicException(sprintf('You cannot add compiler pass "%s" from extension "%s". Compiler passes must be registered before the container is compiled.', \get_class($pass), $this->extensionClass));
159 }
160
161 /**
162 * {@inheritdoc}
163 */
164 public function registerExtension(ExtensionInterface $extension)
165 {
166 throw new LogicException(sprintf('You cannot register extension "%s" from "%s". Extensions must be registered before the container is compiled.', \get_class($extension), $this->extensionClass));
167 }
168
169 /**
170 * {@inheritdoc}
171 */
172 public function compile($resolveEnvPlaceholders = false)
173 {
174 throw new LogicException(sprintf('Cannot compile the container in extension "%s".', $this->extensionClass));
175 }
176
177 /**
178 * {@inheritdoc}
179 */
180 public function resolveEnvPlaceholders($value, $format = null, array &$usedEnvs = null)
181 {
182 if (true !== $format || !\is_string($value)) {
183 return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
184 }
185
186 $bag = $this->getParameterBag();
187 $value = $bag->resolveValue($value);
188
189 if (!$bag instanceof EnvPlaceholderParameterBag) {
190 return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
191 }
192
193 foreach ($bag->getEnvPlaceholders() as $env => $placeholders) {
194 if (false === strpos($env, ':')) {
195 continue;
196 }
197 foreach ($placeholders as $placeholder) {
198 if (false !== stripos($value, $placeholder)) {
199 throw new RuntimeException(sprintf('Using a cast in "env(%s)" is incompatible with resolution at compile time in "%s". The logic in the extension should be moved to a compiler pass, or an env parameter with no cast should be used instead.', $env, $this->extensionClass));
200 }
201 }
202 }
203
204 return parent::resolveEnvPlaceholders($value, $format, $usedEnvs);
205 }
206 }
207