Subida del módulo y tema de PrestaShop

This commit is contained in:
Kaloyan
2026-04-09 18:31:51 +02:00
parent 12c253296f
commit 16b3ff9424
39262 changed files with 7418797 additions and 0 deletions

View File

@@ -0,0 +1,74 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\CacheWarmer;
use Psr\Container\ContainerInterface;
use Symfony\Component\HttpKernel\CacheWarmer\CacheWarmerInterface;
use Symfony\Contracts\Service\ServiceSubscriberInterface;
use Twig\Environment;
use Twig\Error\Error;
/**
* Generates the Twig cache for all templates.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TemplateCacheWarmer implements CacheWarmerInterface, ServiceSubscriberInterface
{
private ContainerInterface $container;
private Environment $twig;
private iterable $iterator;
public function __construct(ContainerInterface $container, iterable $iterator)
{
// As this cache warmer is optional, dependencies should be lazy-loaded, that's why a container should be injected.
$this->container = $container;
$this->iterator = $iterator;
}
/**
* @param string|null $buildDir
*/
public function warmUp(string $cacheDir /* , string $buildDir = null */): array
{
$this->twig ??= $this->container->get('twig');
foreach ($this->iterator as $template) {
try {
$this->twig->load($template);
} catch (Error) {
/*
* Problem during compilation, give up for this template (e.g. syntax errors).
* Failing silently here allows to ignore templates that rely on functions that aren't available in
* the current environment. For example, the WebProfilerBundle shouldn't be available in the prod
* environment, but some templates that are never used in prod might rely on functions the bundle provides.
* As we can't detect which templates are "really" important, we try to load all of them and ignore
* errors. Error checks may be performed by calling the lint:twig command.
*/
}
}
return [];
}
public function isOptional(): bool
{
return true;
}
public static function getSubscribedServices(): array
{
return [
'twig' => Environment::class,
];
}
}

View File

@@ -0,0 +1,51 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\Command;
use Symfony\Bridge\Twig\Command\LintCommand as BaseLintCommand;
use Symfony\Component\Console\Attribute\AsCommand;
/**
* Command that will validate your template syntax and output encountered errors.
*
* @author Marc Weistroff <marc.weistroff@sensiolabs.com>
* @author Jérôme Tamarelle <jerome@tamarelle.net>
*/
#[AsCommand(name: 'lint:twig', description: 'Lint a Twig template and outputs encountered errors')]
final class LintCommand extends BaseLintCommand
{
protected function configure(): void
{
parent::configure();
$this
->setHelp(
$this->getHelp().<<<'EOF'
Or all template files in a bundle:
<info>php %command.full_name% @AcmeDemoBundle</info>
EOF
)
;
}
protected function findFiles(string $filename): iterable
{
if (str_starts_with($filename, '@')) {
$filename = $this->getApplication()->getKernel()->locateResource($filename);
}
return parent::findFiles($filename);
}
}

View File

@@ -0,0 +1,142 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
use Symfony\Component\Asset\Packages;
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\ExpressionLanguage\Expression;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Workflow\Workflow;
use Symfony\Component\Yaml\Yaml;
/**
* @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
*/
class ExtensionPass implements CompilerPassInterface
{
/**
* @return void
*/
public function process(ContainerBuilder $container)
{
if (!class_exists(Packages::class)) {
$container->removeDefinition('twig.extension.assets');
}
if (!class_exists(Expression::class)) {
$container->removeDefinition('twig.extension.expression');
}
if (!interface_exists(UrlGeneratorInterface::class)) {
$container->removeDefinition('twig.extension.routing');
}
if (!class_exists(Yaml::class)) {
$container->removeDefinition('twig.extension.yaml');
}
if (!$container->has('asset_mapper')) {
// edge case where AssetMapper is installed, but not enabled
$container->removeDefinition('twig.extension.importmap');
$container->removeDefinition('twig.runtime.importmap');
}
$viewDir = \dirname((new \ReflectionClass(\Symfony\Bridge\Twig\Extension\FormExtension::class))->getFileName(), 2).'/Resources/views';
$templateIterator = $container->getDefinition('twig.template_iterator');
$templatePaths = $templateIterator->getArgument(1);
$loader = $container->getDefinition('twig.loader.native_filesystem');
if ($container->has('mailer')) {
$emailPath = $viewDir.'/Email';
$loader->addMethodCall('addPath', [$emailPath, 'email']);
$loader->addMethodCall('addPath', [$emailPath, '!email']);
$templatePaths[$emailPath] = 'email';
}
if ($container->has('form.extension')) {
$container->getDefinition('twig.extension.form')->addTag('twig.extension');
$coreThemePath = $viewDir.'/Form';
$loader->addMethodCall('addPath', [$coreThemePath]);
$templatePaths[$coreThemePath] = null;
}
$templateIterator->replaceArgument(1, $templatePaths);
if ($container->has('router')) {
$container->getDefinition('twig.extension.routing')->addTag('twig.extension');
}
if ($container->has('html_sanitizer')) {
$container->getDefinition('twig.extension.htmlsanitizer')->addTag('twig.extension');
}
if ($container->has('fragment.handler')) {
$container->getDefinition('twig.extension.httpkernel')->addTag('twig.extension');
$container->getDefinition('twig.runtime.httpkernel')->addTag('twig.runtime');
if ($container->hasDefinition('fragment.renderer.hinclude')) {
$container->getDefinition('fragment.renderer.hinclude')
->addTag('kernel.fragment_renderer', ['alias' => 'hinclude'])
;
}
}
if ($container->has('request_stack')) {
$container->getDefinition('twig.extension.httpfoundation')->addTag('twig.extension');
}
if ($container->getParameter('kernel.debug')) {
$container->getDefinition('twig.extension.profiler')->addTag('twig.extension');
// only register if the improved version from DebugBundle is *not* present
if (!$container->has('twig.extension.dump')) {
$container->getDefinition('twig.extension.debug')->addTag('twig.extension');
}
}
if ($container->has('web_link.add_link_header_listener')) {
$container->getDefinition('twig.extension.weblink')->addTag('twig.extension');
}
$container->setAlias('twig.loader.filesystem', new Alias('twig.loader.native_filesystem', false));
if ($container->has('assets.packages')) {
$container->getDefinition('twig.extension.assets')->addTag('twig.extension');
}
if ($container->hasDefinition('twig.extension.yaml')) {
$container->getDefinition('twig.extension.yaml')->addTag('twig.extension');
}
if (class_exists(\Symfony\Component\Stopwatch\Stopwatch::class)) {
$container->getDefinition('twig.extension.debug.stopwatch')->addTag('twig.extension');
}
if ($container->hasDefinition('twig.extension.expression')) {
$container->getDefinition('twig.extension.expression')->addTag('twig.extension');
}
if (!class_exists(Workflow::class) || !$container->has('workflow.registry')) {
$container->removeDefinition('workflow.twig_extension');
} else {
$container->getDefinition('workflow.twig_extension')->addTag('twig.extension');
}
if ($container->has('serializer')) {
$container->getDefinition('twig.runtime.serializer')->addTag('twig.runtime');
$container->getDefinition('twig.extension.serializer')->addTag('twig.extension');
}
}
}

View File

@@ -0,0 +1,42 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
/**
* Registers Twig runtime services.
*/
class RuntimeLoaderPass implements CompilerPassInterface
{
/**
* @return void
*/
public function process(ContainerBuilder $container)
{
if (!$container->hasDefinition('twig.runtime_loader')) {
return;
}
$definition = $container->getDefinition('twig.runtime_loader');
$mapping = [];
foreach ($container->findTaggedServiceIds('twig.runtime', true) as $id => $attributes) {
$def = $container->getDefinition($id);
$mapping[$def->getClass()] = new Reference($id);
}
$definition->replaceArgument(0, ServiceLocatorTagPass::register($container, $mapping));
}
}

View File

@@ -0,0 +1,60 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\PriorityTaggedServiceTrait;
use Symfony\Component\DependencyInjection\ContainerBuilder;
/**
* Adds tagged twig.extension services to twig service.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TwigEnvironmentPass implements CompilerPassInterface
{
use PriorityTaggedServiceTrait;
/**
* @return void
*/
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition('twig')) {
return;
}
$definition = $container->getDefinition('twig');
// Extensions must always be registered before everything else.
// For instance, global variable definitions must be registered
// afterward. If not, the globals from the extensions will never
// be registered.
$currentMethodCalls = $definition->getMethodCalls();
$twigBridgeExtensionsMethodCalls = [];
$othersExtensionsMethodCalls = [];
foreach ($this->findAndSortTaggedServices('twig.extension', $container) as $extension) {
$methodCall = ['addExtension', [$extension]];
$extensionClass = $container->getDefinition((string) $extension)->getClass();
if (\is_string($extensionClass) && str_starts_with($extensionClass, 'Symfony\Bridge\Twig\Extension')) {
$twigBridgeExtensionsMethodCalls[] = $methodCall;
} else {
$othersExtensionsMethodCalls[] = $methodCall;
}
}
if ($twigBridgeExtensionsMethodCalls || $othersExtensionsMethodCalls) {
$definition->setMethodCalls(array_merge($twigBridgeExtensionsMethodCalls, $othersExtensionsMethodCalls, $currentMethodCalls));
}
}
}

View File

@@ -0,0 +1,63 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Exception\LogicException;
use Symfony\Component\DependencyInjection\Reference;
/**
* Adds services tagged twig.loader as Twig loaders.
*
* @author Daniel Leech <daniel@dantleech.com>
*/
class TwigLoaderPass implements CompilerPassInterface
{
/**
* @return void
*/
public function process(ContainerBuilder $container)
{
if (false === $container->hasDefinition('twig')) {
return;
}
$prioritizedLoaders = [];
$found = 0;
foreach ($container->findTaggedServiceIds('twig.loader', true) as $id => $attributes) {
$priority = $attributes[0]['priority'] ?? 0;
$prioritizedLoaders[$priority][] = $id;
++$found;
}
if (!$found) {
throw new LogicException('No twig loaders found. You need to tag at least one loader with "twig.loader".');
}
if (1 === $found) {
$container->setAlias('twig.loader', $id);
} else {
$chainLoader = $container->getDefinition('twig.loader.chain');
krsort($prioritizedLoaders);
foreach ($prioritizedLoaders as $loaders) {
foreach ($loaders as $loader) {
$chainLoader->addMethodCall('addLoader', [new Reference($loader)]);
}
}
$container->setAlias('twig.loader', 'twig.loader.chain');
}
}
}

View File

@@ -0,0 +1,232 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\DependencyInjection;
use Symfony\Component\Config\Definition\Builder\ArrayNodeDefinition;
use Symfony\Component\Config\Definition\Builder\TreeBuilder;
use Symfony\Component\Config\Definition\ConfigurationInterface;
use Symfony\Component\Config\Definition\Exception\InvalidConfigurationException;
use Symfony\Component\Mime\HtmlToTextConverter\HtmlToTextConverterInterface;
/**
* TwigExtension configuration structure.
*
* @author Jeremy Mikola <jmikola@gmail.com>
*/
class Configuration implements ConfigurationInterface
{
/**
* Generates the configuration tree builder.
*/
public function getConfigTreeBuilder(): TreeBuilder
{
$treeBuilder = new TreeBuilder('twig');
$rootNode = $treeBuilder->getRootNode();
$rootNode->beforeNormalization()
->ifTrue(fn ($v) => \is_array($v) && \array_key_exists('exception_controller', $v))
->then(function ($v) {
if (isset($v['exception_controller'])) {
throw new InvalidConfigurationException('Option "exception_controller" under "twig" must be null or unset, use "error_controller" under "framework" instead.');
}
unset($v['exception_controller']);
return $v;
})
->end();
$this->addFormThemesSection($rootNode);
$this->addGlobalsSection($rootNode);
$this->addTwigOptions($rootNode);
$this->addTwigFormatOptions($rootNode);
$this->addMailerSection($rootNode);
return $treeBuilder;
}
private function addFormThemesSection(ArrayNodeDefinition $rootNode): void
{
$rootNode
->fixXmlConfig('form_theme')
->children()
->arrayNode('form_themes')
->addDefaultChildrenIfNoneSet()
->prototype('scalar')->defaultValue('form_div_layout.html.twig')->end()
->example(['@My/form.html.twig'])
->validate()
->ifTrue(fn ($v) => !\in_array('form_div_layout.html.twig', $v))
->then(fn ($v) => array_merge(['form_div_layout.html.twig'], $v))
->end()
->end()
->end()
;
}
private function addGlobalsSection(ArrayNodeDefinition $rootNode): void
{
$rootNode
->fixXmlConfig('global')
->children()
->arrayNode('globals')
->normalizeKeys(false)
->useAttributeAsKey('key')
->example(['foo' => '@bar', 'pi' => 3.14])
->prototype('array')
->normalizeKeys(false)
->beforeNormalization()
->ifTrue(fn ($v) => \is_string($v) && str_starts_with($v, '@'))
->then(function ($v) {
if (str_starts_with($v, '@@')) {
return substr($v, 1);
}
return ['id' => substr($v, 1), 'type' => 'service'];
})
->end()
->beforeNormalization()
->ifTrue(function ($v) {
if (\is_array($v)) {
$keys = array_keys($v);
sort($keys);
return $keys !== ['id', 'type'] && $keys !== ['value'];
}
return true;
})
->then(fn ($v) => ['value' => $v])
->end()
->children()
->scalarNode('id')->end()
->scalarNode('type')
->validate()
->ifNotInArray(['service'])
->thenInvalid('The %s type is not supported')
->end()
->end()
->variableNode('value')->end()
->end()
->end()
->end()
->end()
;
}
private function addTwigOptions(ArrayNodeDefinition $rootNode): void
{
$rootNode
->fixXmlConfig('path')
->children()
->variableNode('autoescape')
->defaultValue('name')
->setDeprecated('symfony/twig-bundle', '6.1', 'Option "%node%" at "%path%" is deprecated, use autoescape_service[_method] instead.')
->end()
->scalarNode('autoescape_service')->defaultNull()->end()
->scalarNode('autoescape_service_method')->defaultNull()->end()
->scalarNode('base_template_class')->example('Twig\Template')->cannotBeEmpty()->end()
->scalarNode('cache')->defaultValue('%kernel.cache_dir%/twig')->end()
->scalarNode('charset')->defaultValue('%kernel.charset%')->end()
->booleanNode('debug')->defaultValue('%kernel.debug%')->end()
->booleanNode('strict_variables')->defaultValue('%kernel.debug%')->end()
->scalarNode('auto_reload')->end()
->integerNode('optimizations')->min(-1)->end()
->scalarNode('default_path')
->info('The default path used to load templates')
->defaultValue('%kernel.project_dir%/templates')
->end()
->arrayNode('file_name_pattern')
->example('*.twig')
->info('Pattern of file name used for cache warmer and linter')
->beforeNormalization()
->ifString()
->then(fn ($value) => [$value])
->end()
->prototype('scalar')->end()
->end()
->arrayNode('paths')
->normalizeKeys(false)
->useAttributeAsKey('paths')
->beforeNormalization()
->ifArray()
->then(function ($paths) {
$normalized = [];
foreach ($paths as $path => $namespace) {
if (\is_array($namespace)) {
// xml
$path = $namespace['value'];
$namespace = $namespace['namespace'];
}
// path within the default namespace
if (ctype_digit((string) $path)) {
$path = $namespace;
$namespace = null;
}
$normalized[$path] = $namespace;
}
return $normalized;
})
->end()
->prototype('variable')->end()
->end()
->end()
;
}
private function addTwigFormatOptions(ArrayNodeDefinition $rootNode): void
{
$rootNode
->children()
->arrayNode('date')
->info('The default format options used by the date filter')
->addDefaultsIfNotSet()
->children()
->scalarNode('format')->defaultValue('F j, Y H:i')->end()
->scalarNode('interval_format')->defaultValue('%d days')->end()
->scalarNode('timezone')
->info('The timezone used when formatting dates, when set to null, the timezone returned by date_default_timezone_get() is used')
->defaultNull()
->end()
->end()
->end()
->arrayNode('number_format')
->info('The default format options for the number_format filter')
->addDefaultsIfNotSet()
->children()
->integerNode('decimals')->defaultValue(0)->end()
->scalarNode('decimal_point')->defaultValue('.')->end()
->scalarNode('thousands_separator')->defaultValue(',')->end()
->end()
->end()
->end()
;
}
private function addMailerSection(ArrayNodeDefinition $rootNode): void
{
$rootNode
->children()
->arrayNode('mailer')
->children()
->scalarNode('html_to_text_converter')
->info(\sprintf('A service implementing the "%s"', HtmlToTextConverterInterface::class))
->defaultNull()
->end()
->end()
->end()
->end()
;
}
}

View File

@@ -0,0 +1,62 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\DependencyInjection\Configurator;
use Symfony\Bridge\Twig\UndefinedCallableHandler;
use Twig\Environment;
use Twig\Extension\CoreExtension;
// BC/FC with namespaced Twig
class_exists(Environment::class);
/**
* Twig environment configurator.
*
* @author Christian Flothmann <christian.flothmann@xabbuh.de>
*/
class EnvironmentConfigurator
{
private string $dateFormat;
private string $intervalFormat;
private ?string $timezone;
private int $decimals;
private string $decimalPoint;
private string $thousandsSeparator;
public function __construct(string $dateFormat, string $intervalFormat, ?string $timezone, int $decimals, string $decimalPoint, string $thousandsSeparator)
{
$this->dateFormat = $dateFormat;
$this->intervalFormat = $intervalFormat;
$this->timezone = $timezone;
$this->decimals = $decimals;
$this->decimalPoint = $decimalPoint;
$this->thousandsSeparator = $thousandsSeparator;
}
/**
* @return void
*/
public function configure(Environment $environment)
{
$environment->getExtension(CoreExtension::class)->setDateFormat($this->dateFormat, $this->intervalFormat);
if (null !== $this->timezone) {
$environment->getExtension(CoreExtension::class)->setTimezone($this->timezone);
}
$environment->getExtension(CoreExtension::class)->setNumberFormat($this->decimals, $this->decimalPoint, $this->thousandsSeparator);
// wrap UndefinedCallableHandler in closures for lazy-autoloading
$environment->registerUndefinedFilterCallback(fn ($name) => UndefinedCallableHandler::onUndefinedFilter($name));
$environment->registerUndefinedFunctionCallback(fn ($name) => UndefinedCallableHandler::onUndefinedFunction($name));
}
}

View File

@@ -0,0 +1,228 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle\DependencyInjection;
use Symfony\Component\AssetMapper\AssetMapper;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Loader\PhpFileLoader;
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\Form\AbstractRendererEngine;
use Symfony\Component\Form\Form;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\Mailer\Mailer;
use Symfony\Component\Translation\LocaleSwitcher;
use Symfony\Component\Translation\Translator;
use Symfony\Contracts\Service\ResetInterface;
use Twig\Environment;
use Twig\Extension\ExtensionInterface;
use Twig\Extension\RuntimeExtensionInterface;
use Twig\Loader\LoaderInterface;
/**
* TwigExtension.
*
* @author Fabien Potencier <fabien@symfony.com>
* @author Jeremy Mikola <jmikola@gmail.com>
*/
class TwigExtension extends Extension
{
/**
* @return void
*/
public function load(array $configs, ContainerBuilder $container)
{
$loader = new PhpFileLoader($container, new FileLocator(__DIR__.'/../Resources/config'));
$loader->load('twig.php');
if (method_exists(Environment::class, 'resetGlobals')) {
$container->getDefinition('twig')->addTag('kernel.reset', ['method' => 'resetGlobals']);
}
if ($container::willBeAvailable('symfony/form', Form::class, ['symfony/twig-bundle'])) {
$loader->load('form.php');
if (is_subclass_of(AbstractRendererEngine::class, ResetInterface::class)) {
$container->getDefinition('twig.form.engine')->addTag('kernel.reset', [
'method' => 'reset',
]);
}
}
if ($container::willBeAvailable('symfony/console', Application::class, ['symfony/twig-bundle'])) {
$loader->load('console.php');
}
if (!$container::willBeAvailable('symfony/translation', Translator::class, ['symfony/twig-bundle'])) {
$container->removeDefinition('twig.translation.extractor');
}
foreach ($configs as $key => $config) {
if (isset($config['globals'])) {
foreach ($config['globals'] as $name => $value) {
if (\is_array($value) && isset($value['key'])) {
$configs[$key]['globals'][$name] = [
'key' => $name,
'value' => $value,
];
}
}
}
}
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
if ($container::willBeAvailable('symfony/mailer', Mailer::class, ['symfony/twig-bundle'])) {
$loader->load('mailer.php');
if ($htmlToTextConverter = $config['mailer']['html_to_text_converter'] ?? null) {
$container->getDefinition('twig.mime_body_renderer')->setArgument('$converter', new Reference($htmlToTextConverter));
}
if (ContainerBuilder::willBeAvailable('symfony/translation', LocaleSwitcher::class, ['symfony/framework-bundle'])) {
$container->getDefinition('twig.mime_body_renderer')->setArgument('$localeSwitcher', new Reference('translation.locale_switcher', ContainerBuilder::IGNORE_ON_INVALID_REFERENCE));
}
}
if ($container::willBeAvailable('symfony/asset-mapper', AssetMapper::class, ['symfony/twig-bundle'])) {
$loader->load('importmap.php');
}
$container->setParameter('twig.form.resources', $config['form_themes']);
$container->setParameter('twig.default_path', $config['default_path']);
$defaultTwigPath = $container->getParameterBag()->resolveValue($config['default_path']);
$envConfiguratorDefinition = $container->getDefinition('twig.configurator.environment');
$envConfiguratorDefinition->replaceArgument(0, $config['date']['format']);
$envConfiguratorDefinition->replaceArgument(1, $config['date']['interval_format']);
$envConfiguratorDefinition->replaceArgument(2, $config['date']['timezone']);
$envConfiguratorDefinition->replaceArgument(3, $config['number_format']['decimals']);
$envConfiguratorDefinition->replaceArgument(4, $config['number_format']['decimal_point']);
$envConfiguratorDefinition->replaceArgument(5, $config['number_format']['thousands_separator']);
$twigFilesystemLoaderDefinition = $container->getDefinition('twig.loader.native_filesystem');
// register user-configured paths
foreach ($config['paths'] as $path => $namespace) {
if (!$namespace) {
$twigFilesystemLoaderDefinition->addMethodCall('addPath', [$path]);
} else {
$twigFilesystemLoaderDefinition->addMethodCall('addPath', [$path, $namespace]);
}
}
// paths are modified in ExtensionPass if forms are enabled
$container->getDefinition('twig.template_iterator')->replaceArgument(1, $config['paths']);
$container->getDefinition('twig.template_iterator')->replaceArgument(3, $config['file_name_pattern']);
if ($container->hasDefinition('twig.command.lint')) {
$container->getDefinition('twig.command.lint')->replaceArgument(1, $config['file_name_pattern'] ?: ['*.twig']);
}
foreach ($this->getBundleTemplatePaths($container, $config) as $name => $paths) {
$namespace = $this->normalizeBundleName($name);
foreach ($paths as $path) {
$twigFilesystemLoaderDefinition->addMethodCall('addPath', [$path, $namespace]);
}
if ($paths) {
// the last path must be the bundle views directory
$twigFilesystemLoaderDefinition->addMethodCall('addPath', [$path, '!'.$namespace]);
}
}
if (file_exists($defaultTwigPath)) {
$twigFilesystemLoaderDefinition->addMethodCall('addPath', [$defaultTwigPath]);
}
$container->addResource(new FileExistenceResource($defaultTwigPath));
if (!empty($config['globals'])) {
$def = $container->getDefinition('twig');
foreach ($config['globals'] as $key => $global) {
if (isset($global['type']) && 'service' === $global['type']) {
$def->addMethodCall('addGlobal', [$key, new Reference($global['id'])]);
} else {
$def->addMethodCall('addGlobal', [$key, $global['value']]);
}
}
}
if (isset($config['autoescape_service'])) {
$config['autoescape'] = [new Reference($config['autoescape_service']), $config['autoescape_service_method'] ?? '__invoke'];
}
$container->getDefinition('twig')->replaceArgument(1, array_intersect_key($config, [
'debug' => true,
'charset' => true,
'base_template_class' => true,
'strict_variables' => true,
'autoescape' => true,
'cache' => true,
'auto_reload' => true,
'optimizations' => true,
]));
$container->registerForAutoconfiguration(\Twig_ExtensionInterface::class)->addTag('twig.extension');
$container->registerForAutoconfiguration(\Twig_LoaderInterface::class)->addTag('twig.loader');
$container->registerForAutoconfiguration(ExtensionInterface::class)->addTag('twig.extension');
$container->registerForAutoconfiguration(LoaderInterface::class)->addTag('twig.loader');
$container->registerForAutoconfiguration(RuntimeExtensionInterface::class)->addTag('twig.runtime');
if (false === $config['cache']) {
$container->removeDefinition('twig.template_cache_warmer');
}
}
private function getBundleTemplatePaths(ContainerBuilder $container, array $config): array
{
$bundleHierarchy = [];
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
$defaultOverrideBundlePath = $container->getParameterBag()->resolveValue($config['default_path']).'/bundles/'.$name;
if (file_exists($defaultOverrideBundlePath)) {
$bundleHierarchy[$name][] = $defaultOverrideBundlePath;
}
$container->addResource(new FileExistenceResource($defaultOverrideBundlePath));
if (file_exists($dir = $bundle['path'].'/Resources/views') || file_exists($dir = $bundle['path'].'/templates')) {
$bundleHierarchy[$name][] = $dir;
}
$container->addResource(new FileExistenceResource($dir));
}
return $bundleHierarchy;
}
private function normalizeBundleName(string $name): string
{
if (str_ends_with($name, 'Bundle')) {
$name = substr($name, 0, -6);
}
return $name;
}
public function getXsdValidationBasePath(): string|false
{
return __DIR__.'/../Resources/config/schema';
}
public function getNamespace(): string
{
return 'http://symfony.com/schema/dic/twig';
}
}

19
vendor/symfony/twig-bundle/LICENSE vendored Normal file
View File

@@ -0,0 +1,19 @@
Copyright (c) 2004-present Fabien Potencier
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,33 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Bridge\Twig\Command\DebugCommand;
use Symfony\Bundle\TwigBundle\Command\LintCommand;
return static function (ContainerConfigurator $container) {
$container->services()
->set('twig.command.debug', DebugCommand::class)
->args([
service('twig'),
param('kernel.project_dir'),
param('kernel.bundles_metadata'),
param('twig.default_path'),
service('debug.file_link_formatter')->nullOnInvalid(),
])
->tag('console.command')
->set('twig.command.lint', LintCommand::class)
->args([service('twig'), abstract_arg('File name pattern')])
->tag('console.command')
;
};

View File

@@ -0,0 +1,30 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Bridge\Twig\Extension\FormExtension;
use Symfony\Bridge\Twig\Form\TwigRendererEngine;
use Symfony\Component\Form\FormRenderer;
return static function (ContainerConfigurator $container) {
$container->services()
->set('twig.extension.form', FormExtension::class)
->args([service('translator')->nullOnInvalid()])
->set('twig.form.engine', TwigRendererEngine::class)
->args([param('twig.form.resources'), service('twig')])
->set('twig.form.renderer', FormRenderer::class)
->args([service('twig.form.engine'), service('security.csrf.token_manager')->nullOnInvalid()])
->tag('twig.runtime')
;
};

View File

@@ -0,0 +1,27 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Bridge\Twig\Extension\ImportMapExtension;
use Symfony\Bridge\Twig\Extension\ImportMapRuntime;
return static function (ContainerConfigurator $container) {
$container->services()
->set('twig.runtime.importmap', ImportMapRuntime::class)
->args([service('asset_mapper.importmap.renderer')])
->tag('twig.runtime')
->set('twig.extension.importmap', ImportMapExtension::class)
->tag('twig.extension')
;
};

View File

@@ -0,0 +1,28 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Symfony\Bridge\Twig\Mime\BodyRenderer;
use Symfony\Component\Mailer\EventListener\MessageListener;
use Symfony\Component\Mime\BodyRendererInterface;
return static function (ContainerConfigurator $container) {
$container->services()
->set('twig.mailer.message_listener', MessageListener::class)
->args([null, service('twig.mime_body_renderer')])
->tag('kernel.event_subscriber')
->set('twig.mime_body_renderer', BodyRenderer::class)
->args([service('twig')])
->alias(BodyRendererInterface::class, 'twig.mime_body_renderer')
;
};

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" ?>
<xsd:schema xmlns="http://symfony.com/schema/dic/twig"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
targetNamespace="http://symfony.com/schema/dic/twig"
elementFormDefault="qualified">
<xsd:element name="config" type="config" />
<xsd:complexType name="config">
<xsd:sequence>
<xsd:element name="date" type="date" minOccurs="0" maxOccurs="1" />
<xsd:element name="number-format" type="number_format" minOccurs="0" maxOccurs="1" />
<xsd:element name="form-theme" type="xsd:string" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="global" type="global" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="path" type="path" minOccurs="0" maxOccurs="unbounded" />
<xsd:element name="mailer" type="mailer" minOccurs="0" maxOccurs="1" />
</xsd:sequence>
<xsd:attribute name="auto-reload" type="xsd:string" />
<xsd:attribute name="autoescape" type="xsd:string" />
<xsd:attribute name="autoescape-service" type="xsd:string" />
<xsd:attribute name="autoescape-service-method" type="xsd:string" />
<xsd:attribute name="base-template-class" type="xsd:string" />
<xsd:attribute name="cache" type="xsd:string" />
<xsd:attribute name="charset" type="xsd:string" />
<xsd:attribute name="debug" type="xsd:string" />
<xsd:attribute name="strict-variables" type="xsd:string" />
<xsd:attribute name="default-path" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="date">
<xsd:attribute name="format" type="xsd:string" />
<xsd:attribute name="interval-format" type="xsd:string" />
<xsd:attribute name="timezone" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="number_format">
<xsd:attribute name="decimals" type="xsd:integer" />
<xsd:attribute name="decimal-point" type="xsd:string" />
<xsd:attribute name="thousands-separator" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="path" mixed="true">
<xsd:attribute name="namespace" type="xsd:string" />
</xsd:complexType>
<xsd:complexType name="global" mixed="true">
<xsd:attribute name="key" type="xsd:string" use="required" />
<xsd:attribute name="type" type="global_type" />
<xsd:attribute name="id" type="xsd:string" />
</xsd:complexType>
<xsd:simpleType name="global_type">
<xsd:restriction base="xsd:string">
<xsd:enumeration value="service" />
</xsd:restriction>
</xsd:simpleType>
<xsd:complexType name="mailer">
<xsd:attribute name="html-to-text-converter" type="xsd:string" />
</xsd:complexType>
</xsd:schema>

View File

@@ -0,0 +1,183 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
use Psr\Container\ContainerInterface;
use Symfony\Bridge\Twig\AppVariable;
use Symfony\Bridge\Twig\DataCollector\TwigDataCollector;
use Symfony\Bridge\Twig\ErrorRenderer\TwigErrorRenderer;
use Symfony\Bridge\Twig\EventListener\TemplateAttributeListener;
use Symfony\Bridge\Twig\Extension\AssetExtension;
use Symfony\Bridge\Twig\Extension\CodeExtension;
use Symfony\Bridge\Twig\Extension\ExpressionExtension;
use Symfony\Bridge\Twig\Extension\HtmlSanitizerExtension;
use Symfony\Bridge\Twig\Extension\HttpFoundationExtension;
use Symfony\Bridge\Twig\Extension\HttpKernelExtension;
use Symfony\Bridge\Twig\Extension\HttpKernelRuntime;
use Symfony\Bridge\Twig\Extension\ProfilerExtension;
use Symfony\Bridge\Twig\Extension\RoutingExtension;
use Symfony\Bridge\Twig\Extension\SerializerExtension;
use Symfony\Bridge\Twig\Extension\SerializerRuntime;
use Symfony\Bridge\Twig\Extension\StopwatchExtension;
use Symfony\Bridge\Twig\Extension\TranslationExtension;
use Symfony\Bridge\Twig\Extension\WebLinkExtension;
use Symfony\Bridge\Twig\Extension\WorkflowExtension;
use Symfony\Bridge\Twig\Extension\YamlExtension;
use Symfony\Bridge\Twig\Translation\TwigExtractor;
use Symfony\Bundle\TwigBundle\CacheWarmer\TemplateCacheWarmer;
use Symfony\Bundle\TwigBundle\DependencyInjection\Configurator\EnvironmentConfigurator;
use Symfony\Bundle\TwigBundle\TemplateIterator;
use Twig\Cache\FilesystemCache;
use Twig\Environment;
use Twig\ExpressionParser\Infix\BinaryOperatorExpressionParser;
use Twig\Extension\CoreExtension;
use Twig\Extension\DebugExtension;
use Twig\Extension\EscaperExtension;
use Twig\Extension\OptimizerExtension;
use Twig\Extension\StagingExtension;
use Twig\ExtensionSet;
use Twig\Loader\ChainLoader;
use Twig\Loader\FilesystemLoader;
use Twig\Profiler\Profile;
use Twig\RuntimeLoader\ContainerRuntimeLoader;
use Twig\Template;
use Twig\TemplateWrapper;
return static function (ContainerConfigurator $container) {
$container->services()
->set('twig', Environment::class)
->args([service('twig.loader'), abstract_arg('Twig options')])
->call('addGlobal', ['app', service('twig.app_variable')])
->call('addRuntimeLoader', [service('twig.runtime_loader')])
->configurator([service('twig.configurator.environment'), 'configure'])
->tag('container.preload', ['class' => FilesystemCache::class])
->tag('container.preload', ['class' => CoreExtension::class])
->tag('container.preload', ['class' => EscaperExtension::class])
->tag('container.preload', ['class' => OptimizerExtension::class])
->tag('container.preload', ['class' => StagingExtension::class])
->tag('container.preload', ['class' => BinaryOperatorExpressionParser::class])
->tag('container.preload', ['class' => ExtensionSet::class])
->tag('container.preload', ['class' => Template::class])
->tag('container.preload', ['class' => TemplateWrapper::class])
->alias('Twig_Environment', 'twig')
->deprecate('symfony/twig-bundle', '6.3', 'The "%alias_id%" service alias is deprecated, use "'.Environment::class.'" or "twig" instead.')
->alias(Environment::class, 'twig')
->set('twig.app_variable', AppVariable::class)
->call('setEnvironment', [param('kernel.environment')])
->call('setDebug', [param('kernel.debug')])
->call('setTokenStorage', [service('security.token_storage')->ignoreOnInvalid()])
->call('setRequestStack', [service('request_stack')->ignoreOnInvalid()])
->call('setLocaleSwitcher', [service('translation.locale_switcher')->ignoreOnInvalid()])
->call('setEnabledLocales', [param('kernel.enabled_locales')])
->set('twig.template_iterator', TemplateIterator::class)
->args([service('kernel'), abstract_arg('Twig paths'), param('twig.default_path'), abstract_arg('File name pattern')])
->set('twig.template_cache_warmer', TemplateCacheWarmer::class)
->args([service(ContainerInterface::class), service('twig.template_iterator')])
->tag('kernel.cache_warmer')
->tag('container.service_subscriber', ['id' => 'twig'])
->set('twig.loader.native_filesystem', FilesystemLoader::class)
->args([[], param('kernel.project_dir')])
->tag('twig.loader')
->set('twig.loader.chain', ChainLoader::class)
->set('twig.extension.profiler', ProfilerExtension::class)
->args([service('twig.profile'), service('debug.stopwatch')->ignoreOnInvalid()])
->set('twig.profile', Profile::class)
->set('data_collector.twig', TwigDataCollector::class)
->args([service('twig.profile'), service('twig')])
->tag('data_collector', ['template' => '@WebProfiler/Collector/twig.html.twig', 'id' => 'twig', 'priority' => 257])
->set('twig.extension.trans', TranslationExtension::class)
->args([service('translator')->nullOnInvalid()])
->tag('twig.extension')
->set('twig.extension.assets', AssetExtension::class)
->args([service('assets.packages')])
->set('twig.extension.code', CodeExtension::class)
->args([service('debug.file_link_formatter')->ignoreOnInvalid(), param('kernel.project_dir'), param('kernel.charset')])
->tag('twig.extension')
->set('twig.extension.routing', RoutingExtension::class)
->args([service('router')])
->set('twig.extension.yaml', YamlExtension::class)
->set('twig.extension.debug.stopwatch', StopwatchExtension::class)
->args([service('debug.stopwatch')->ignoreOnInvalid(), param('kernel.debug')])
->set('twig.extension.expression', ExpressionExtension::class)
->set('twig.extension.htmlsanitizer', HtmlSanitizerExtension::class)
->args([tagged_locator('html_sanitizer', 'sanitizer')])
->set('twig.extension.httpkernel', HttpKernelExtension::class)
->set('twig.runtime.httpkernel', HttpKernelRuntime::class)
->args([service('fragment.handler'), service('fragment.uri_generator')->ignoreOnInvalid()])
->set('twig.extension.httpfoundation', HttpFoundationExtension::class)
->args([service('url_helper')])
->set('twig.extension.debug', DebugExtension::class)
->set('twig.extension.weblink', WebLinkExtension::class)
->args([service('request_stack')])
->set('twig.translation.extractor', TwigExtractor::class)
->args([service('twig')])
->tag('translation.extractor', ['alias' => 'twig'])
->set('workflow.twig_extension', WorkflowExtension::class)
->args([service('workflow.registry')])
->set('twig.configurator.environment', EnvironmentConfigurator::class)
->args([
abstract_arg('date format, set in TwigExtension'),
abstract_arg('interval format, set in TwigExtension'),
abstract_arg('timezone, set in TwigExtension'),
abstract_arg('decimals, set in TwigExtension'),
abstract_arg('decimal point, set in TwigExtension'),
abstract_arg('thousands separator, set in TwigExtension'),
])
->set('twig.runtime_loader', ContainerRuntimeLoader::class)
->args([abstract_arg('runtime locator')])
->set('twig.error_renderer.html', TwigErrorRenderer::class)
->decorate('error_renderer.html')
->args([
service('twig'),
service('twig.error_renderer.html.inner'),
inline_service('bool')
->factory([TwigErrorRenderer::class, 'isDebug'])
->args([service('request_stack'), param('kernel.debug')]),
])
->set('twig.runtime.serializer', SerializerRuntime::class)
->args([service('serializer')])
->set('twig.extension.serializer', SerializerExtension::class)
->set('controller.template_attribute_listener', TemplateAttributeListener::class)
->args([service('twig')])
->tag('kernel.event_subscriber')
;
};

View File

@@ -0,0 +1,94 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle;
use Symfony\Component\Finder\Finder;
use Symfony\Component\HttpKernel\KernelInterface;
/**
* Iterator for all templates in bundles and in the application Resources directory.
*
* @author Fabien Potencier <fabien@symfony.com>
*
* @internal
*
* @implements \IteratorAggregate<int, string>
*/
class TemplateIterator implements \IteratorAggregate
{
private KernelInterface $kernel;
private \Traversable $templates;
private array $paths;
private ?string $defaultPath;
private array $namePatterns;
/**
* @param array $paths Additional Twig paths to warm
* @param string|null $defaultPath The directory where global templates can be stored
* @param string[] $namePatterns Pattern of file names
*/
public function __construct(KernelInterface $kernel, array $paths = [], ?string $defaultPath = null, array $namePatterns = [])
{
$this->kernel = $kernel;
$this->paths = $paths;
$this->defaultPath = $defaultPath;
$this->namePatterns = $namePatterns;
}
public function getIterator(): \Traversable
{
if (isset($this->templates)) {
return $this->templates;
}
$templates = null !== $this->defaultPath ? [$this->findTemplatesInDirectory($this->defaultPath, null, ['bundles'])] : [];
foreach ($this->kernel->getBundles() as $bundle) {
$name = $bundle->getName();
if (str_ends_with($name, 'Bundle')) {
$name = substr($name, 0, -6);
}
$bundleTemplatesDir = is_dir($bundle->getPath().'/Resources/views') ? $bundle->getPath().'/Resources/views' : $bundle->getPath().'/templates';
$templates[] = $this->findTemplatesInDirectory($bundleTemplatesDir, $name);
if (null !== $this->defaultPath) {
$templates[] = $this->findTemplatesInDirectory($this->defaultPath.'/bundles/'.$bundle->getName(), $name);
}
}
foreach ($this->paths as $dir => $namespace) {
$templates[] = $this->findTemplatesInDirectory($dir, $namespace);
}
return $this->templates = new \ArrayIterator(array_unique(array_merge([], ...$templates)));
}
/**
* Find templates in the given directory.
*
* @return string[]
*/
private function findTemplatesInDirectory(string $dir, ?string $namespace = null, array $excludeDirs = []): array
{
if (!is_dir($dir)) {
return [];
}
$templates = [];
foreach (Finder::create()->files()->followLinks()->in($dir)->exclude($excludeDirs)->name($this->namePatterns) as $file) {
$templates[] = (null !== $namespace ? '@'.$namespace.'/' : '').str_replace('\\', '/', $file->getRelativePathname());
}
return $templates;
}
}

View File

@@ -0,0 +1,51 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Bundle\TwigBundle;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\ExtensionPass;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\RuntimeLoaderPass;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigEnvironmentPass;
use Symfony\Bundle\TwigBundle\DependencyInjection\Compiler\TwigLoaderPass;
use Symfony\Component\Console\Application;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
/**
* Bundle.
*
* @author Fabien Potencier <fabien@symfony.com>
*/
class TwigBundle extends Bundle
{
/**
* @return void
*/
public function build(ContainerBuilder $container)
{
parent::build($container);
// ExtensionPass must be run before the FragmentRendererPass as it adds tags that are processed later
$container->addCompilerPass(new ExtensionPass(), PassConfig::TYPE_BEFORE_OPTIMIZATION, 10);
$container->addCompilerPass(new TwigEnvironmentPass());
$container->addCompilerPass(new TwigLoaderPass());
$container->addCompilerPass(new RuntimeLoaderPass(), PassConfig::TYPE_BEFORE_REMOVING);
}
/**
* @return void
*/
public function registerCommands(Application $application)
{
// noop
}
}