of special environment variables that start with SYMFONY__ (such as "%s") is deprecated as of 3.3 and will be removed in 4.0. Use the %%env()%% syntax instead to get the value of environment variables in configuration files.', $key), \E_USER_DEPRECATED); $parameters[strtolower(str_replace('__', '.', substr($key, 9)))] = $value; } } return $parameters; } /** * Builds the service container. * * @return ContainerBuilder The compiled service container * * @throws \RuntimeException */ protected function buildContainer() { foreach (['cache' => $this->warmupDir ?: $this->getCacheDir(), 'logs' => $this->getLogDir()] as $name => $dir) { if (!is_dir($dir)) { if (false === @mkdir($dir, 0777, true) && !is_dir($dir)) { throw new \RuntimeException(sprintf('Unable to create the "%s" directory (%s).', $name, $dir)); } } elseif (!is_writable($dir)) { throw new \RuntimeException(sprintf('Unable to write in the "%s" directory (%s).', $name, $dir)); } } $container = $this->getContainerBuilder(); $container->addObjectResource($this); $this->prepareContainer($container); if (null !== $cont = $this->registerContainerConfiguration($this->getContainerLoader($container))) { $container->merge($cont); } $container->addCompilerPass(new AddAnnotatedClassesToCachePass($this)); $container->addResource(new EnvParametersResource('SYMFONY__')); return $container; } /** * Prepares the ContainerBuilder before it is compiled. */ protected function prepareContainer(ContainerBuilder $container) { $extensions = []; foreach ($this->bundles as $bundle) { if ($extension = $bundle->getContainerExtension()) { $container->registerExtension($extension); } if ($this->debug) { $container->addObjectResource($bundle); } } foreach ($this->bundles as $bundle) { $bundle->build($container); } $this->build($container); foreach ($container->getExtensions() as $extension) { $extensions[] = $extension->getAlias(); } // ensure these extensions are implicitly loaded $container->getCompilerPassConfig()->setMergePass(new MergeExtensionConfigurationPass($extensions)); } /** * Gets a new ContainerBuilder instance used to build the service container. * * @return ContainerBuilder */ protected function getContainerBuilder() { $container = new ContainerBuilder(); $container->getParameterBag()->add($this->getKernelParameters()); if ($this instanceof CompilerPassInterface) { $container->addCompilerPass($this, PassConfig::TYPE_BEFORE_OPTIMIZATION, -10000); } if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\Instantiator\RuntimeInstantiator')) { $container->setProxyInstantiator(new RuntimeInstantiator()); } return $container; } /** * Dumps the service container to PHP code in the cache. * * @param ConfigCache $cache The config cache * @param ContainerBuilder $container The service container * @param string $class The name of the class to generate * @param string $baseClass The name of the container's base class */ protected function dumpContainer(ConfigCache $cache, ContainerBuilder $container, $class, $baseClass) { // cache the container $dumper = new PhpDumper($container); if (class_exists('ProxyManager\Configuration') && class_exists('Symfony\Bridge\ProxyManager\LazyProxy\PhpDumper\ProxyDumper')) { $dumper->setProxyDumper(new ProxyDumper()); } $content = $dumper->dump([ 'class' => $class, 'base_class' => $baseClass, 'file' => $cache->getPath(), 'as_files' => true, 'debug' => $this->debug, 'inline_class_loader_parameter' => \PHP_VERSION_ID >= 70000 && !$this->loadClassCache && !class_exists(ClassCollectionLoader::class, false) ? 'container.dumper.inline_class_loader' : null, 'build_time' => $container->hasParameter('kernel.container_build_time') ? $container->getParameter('kernel.container_build_time') : time(), ]); $rootCode = array_pop($content); $dir = \dirname($cache->getPath()).'/'; $fs = new Filesystem(); foreach ($content as $file => $code) { $fs->dumpFile($dir.$file, $code); @chmod($dir.$file, 0666 & ~umask()); } $legacyFile = \dirname($dir.key($content)).'.legacy'; if (file_exists($legacyFile)) { @unlink($legacyFile); } $cache->write($rootCode, $container->getResources()); } /** * Returns a loader for the container. * * @return DelegatingLoader The loader */ protected function getContainerLoader(ContainerInterface $container) { $locator = new FileLocator($this); $resolver = new LoaderResolver([ new XmlFileLoader($container, $locator), new YamlFileLoader($container, $locator), new IniFileLoader($container, $locator), new PhpFileLoader($container, $locator), new GlobFileLoader($container, $locator), new DirectoryLoader($container, $locator), new ClosureLoader($container), ]); return new DelegatingLoader($resolver); } /** * Removes comments from a PHP source string. * * We don't use the PHP php_strip_whitespace() function * as we want the content to be readable and well-formatted. * * @param string $source A PHP string * * @return string The PHP string with the comments removed */ public static function stripComments($source) { if (!\function_exists('token_get_all')) { return $source; } $rawChunk = ''; $output = ''; $tokens = token_get_all($source); $ignoreSpace = false; for ($i = 0; isset($tokens[$i]); ++$i) { $token = $tokens[$i]; if (!isset($token[1]) || 'b"' === $token) { $rawChunk .= $token; } elseif (\T_START_HEREDOC === $token[0]) { $output .= $rawChunk.$token[1]; do { $token = $tokens[++$i]; $output .= isset($token[1]) && 'b"' !== $token ? $token[1] : $token; } while (\T_END_HEREDOC !== $token[0]); $rawChunk = ''; } elseif (\T_WHITESPACE === $token[0]) { if ($ignoreSpace) { $ignoreSpace = false; continue; } // replace multiple new lines with a single newline $rawChunk .= preg_replace(['/\n{2,}/S'], "\n", $token[1]); } elseif (\in_array($token[0], [\T_COMMENT, \T_DOC_COMMENT])) { $ignoreSpace = true; } else { $rawChunk .= $token[1]; // The PHP-open tag already has a new-line if (\T_OPEN_TAG === $token[0]) { $ignoreSpace = true; } } } $output .= $rawChunk; if (\PHP_VERSION_ID >= 70000) { // PHP 7 memory manager will not release after token_get_all(), see https://bugs.php.net/70098 unset($tokens, $rawChunk); gc_mem_caches(); } return $output; } public function serialize() { return serialize([$this->environment, $this->debug]); } public function unserialize($data) { if (\PHP_VERSION_ID >= 70000) { list($environment, $debug) = unserialize($data, ['allowed_classes' => false]); } else { list($environment, $debug) = unserialize($data); } $this->__construct($environment, $debug); } }