[ Index ]

PHP Cross Reference of phpBB-3.3.14-deutsch

title

Body

[close]

/vendor/symfony/dependency-injection/Compiler/ -> MergeExtensionConfigurationPass.php (source)

   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\ContainerBuilder;
  15  use Symfony\Component\DependencyInjection\Exception\LogicException;
  16  use Symfony\Component\DependencyInjection\Exception\RuntimeException;
  17  use Symfony\Component\DependencyInjection\Extension\ConfigurationExtensionInterface;
  18  use Symfony\Component\DependencyInjection\Extension\Extension;
  19  use Symfony\Component\DependencyInjection\Extension\ExtensionInterface;
  20  use Symfony\Component\DependencyInjection\Extension\PrependExtensionInterface;
  21  use Symfony\Component\DependencyInjection\ParameterBag\EnvPlaceholderParameterBag;
  22  use Symfony\Component\DependencyInjection\ParameterBag\ParameterBagInterface;
  23  
  24  /**
  25   * Merges extension configs into the container builder.
  26   *
  27   * @author Fabien Potencier <fabien@symfony.com>
  28   */
  29  class MergeExtensionConfigurationPass implements CompilerPassInterface
  30  {
  31      /**
  32       * {@inheritdoc}
  33       */
  34      public function process(ContainerBuilder $container)
  35      {
  36          $parameters = $container->getParameterBag()->all();
  37          $definitions = $container->getDefinitions();
  38          $aliases = $container->getAliases();
  39          $exprLangProviders = $container->getExpressionLanguageProviders();
  40  
  41          foreach ($container->getExtensions() as $extension) {
  42              if ($extension instanceof PrependExtensionInterface) {
  43                  $extension->prepend($container);
  44              }
  45          }
  46  
  47          foreach ($container->getExtensions() as $name => $extension) {
  48              if (!$config = $container->getExtensionConfig($name)) {
  49                  // this extension was not called
  50                  continue;
  51              }
  52              $resolvingBag = $container->getParameterBag();
  53              if ($resolvingBag instanceof EnvPlaceholderParameterBag && $extension instanceof Extension) {
  54                  // create a dedicated bag so that we can track env vars per-extension
  55                  $resolvingBag = new MergeExtensionConfigurationParameterBag($resolvingBag);
  56              }
  57              $config = $resolvingBag->resolveValue($config);
  58  
  59              try {
  60                  $tmpContainer = new MergeExtensionConfigurationContainerBuilder($extension, $resolvingBag);
  61                  $tmpContainer->setResourceTracking($container->isTrackingResources());
  62                  $tmpContainer->addObjectResource($extension);
  63                  if ($extension instanceof ConfigurationExtensionInterface && null !== $configuration = $extension->getConfiguration($config, $tmpContainer)) {
  64                      $tmpContainer->addObjectResource($configuration);
  65                  }
  66  
  67                  foreach ($exprLangProviders as $provider) {
  68                      $tmpContainer->addExpressionLanguageProvider($provider);
  69                  }
  70  
  71                  $extension->load($config, $tmpContainer);
  72              } catch (\Exception $e) {
  73                  if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
  74                      $container->getParameterBag()->mergeEnvPlaceholders($resolvingBag);
  75                  }
  76  
  77                  throw $e;
  78              }
  79  
  80              if ($resolvingBag instanceof MergeExtensionConfigurationParameterBag) {
  81                  // don't keep track of env vars that are *overridden* when configs are merged
  82                  $resolvingBag->freezeAfterProcessing($extension, $tmpContainer);
  83              }
  84  
  85              $container->merge($tmpContainer);
  86              $container->getParameterBag()->add($parameters);
  87          }
  88  
  89          $container->addDefinitions($definitions);
  90          $container->addAliases($aliases);
  91      }
  92  }
  93  
  94  /**
  95   * @internal
  96   */
  97  class MergeExtensionConfigurationParameterBag extends EnvPlaceholderParameterBag
  98  {
  99      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  }


Generated: Mon Nov 25 19:05:08 2024 Cross-referenced by PHPXref 0.7.1