diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS
index db1c2a8a6ff44..415464c40b9a8 100644
--- a/.github/CODEOWNERS
+++ b/.github/CODEOWNERS
@@ -1,3 +1,9 @@
+# Console
+/src/Symfony/Component/Console/Logger/ConsoleLogger.php @dunglas
+# DependencyInjection
+/src/Symfony/Component/DependencyInjection/Compiler/AutowirePass.php @dunglas
+# HttpKernel
+/src/Symfony/Component/HttpKernel/Log/Logger.php @dunglas
# LDAP
/src/Symfony/Component/Ldap/* @csarrazi
# Lock
@@ -5,6 +11,13 @@
# Messenger
/src/Symfony/Bridge/Doctrine/Messenger/* @sroze
/src/Symfony/Component/Messenger/* @sroze
+# PropertyInfo
+/src/Symfony/Component/PropertyInfo/* @dunglas
+/src/Symfony/Bridge/Doctrine/PropertyInfo/* @dunglas
+# Serializer
+/src/Symfony/Component/Serializer/* @dunglas
+# WebLink
+/src/Symfony/Component/WebLink/* @dunglas
# Workflow
/src/Symfony/Bridge/Twig/Extension/WorkflowExtension.php @lyrixx
/src/Symfony/Bridge/Twig/Tests/Extension/WorkflowExtensionTest.php @lyrixx
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
index 94f0fabcc4676..b6f39741d9dbc 100644
--- a/.github/PULL_REQUEST_TEMPLATE.md
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -1,6 +1,6 @@
| Q | A
| ------------- | ---
-| Branch? | master for features / 2.7 up to 4.0 for bug fixes
+| Branch? | master for features / 2.8 up to 4.1 for bug fixes
| Bug fix? | yes/no
| New feature? | yes/no
| BC breaks? | no
diff --git a/CHANGELOG-4.0.md b/CHANGELOG-4.0.md
index 7131036ba4fa8..72d24bf39e62d 100644
--- a/CHANGELOG-4.0.md
+++ b/CHANGELOG-4.0.md
@@ -7,6 +7,46 @@ in 4.0 minor versions.
To get the diff for a specific change, go to https://github.com/symfony/symfony/commit/XXX where XXX is the change hash
To get the diff between two versions, go to https://github.com/symfony/symfony/compare/v4.0.0...v4.0.1
+* 4.0.12 (2018-06-25)
+
+ * bug #27626 [TwigBundle][DX] Only add the Twig WebLinkExtension if the WebLink component is enabled (thewilkybarkid)
+ * bug #27701 [SecurityBundle] Dont throw if "security.http_utils" is not found (nicolas-grekas)
+ * bug #27690 [DI] Resolve env placeholder in logs (ro0NL)
+ * bug #26534 allow_extra_attributes does not throw an exception as documented (deviantintegral)
+ * bug #27668 [Lock] use 'r+' for fopen (fixes issue on Solaris) (fritzmg)
+ * bug #27669 [Filesystem] fix file lock on SunOS (fritzmg)
+ * bug #27662 [HttpKernel] fix handling of nested Error instances (xabbuh)
+ * bug #26845 [Config] Fixing GlobResource when inside phar archive (vworldat)
+ * bug #27382 [Form] Fix error when rendering a DateIntervalType form with exactly 0 weeks (krixon)
+ * bug #27309 Fix surrogate not using original request (Toflar)
+ * bug #27467 [HttpKernel] fix session tracking in surrogate master requests (nicolas-grekas)
+ * bug #27630 [Validator][Form] Remove BOM in some xlf files (gautierderuette)
+ * bug #27596 [Framework][Workflow] Added support for interfaces (vudaltsov)
+ * bug #27593 [ProxyManagerBridge] Fixed support of private services (nicolas-grekas)
+ * bug #27591 [VarDumper] Fix dumping ArrayObject and ArrayIterator instances (nicolas-grekas)
+ * bug #27581 Fix bad method call with guard authentication + session migration (weaverryan)
+ * bug #27576 [Cache] Fix expiry comparisons in array-based pools (nicolas-grekas)
+ * bug #27556 Avoiding session migration for stateless firewall UsernamePasswordJsonAuthenticationListener (weaverryan)
+ * bug #27452 Avoid migration on stateless firewalls (weaverryan)
+ * bug #27568 [DI] Deduplicate generated proxy classes (nicolas-grekas)
+ * bug #27326 [Serializer] deserialize from xml: Fix a collection that contains the only one element (webnet-fr)
+ * bug #27567 [PhpUnitBridge] Fix error on some Windows OS (Nsbx)
+ * bug #27357 [Lock] Remove released semaphore (jderusse)
+ * bug #27416 TagAwareAdapter over non-binary memcached connections corrupts memcache (Aleksey Prilipko)
+ * bug #27514 [Debug] Pass previous exception to FatalErrorException (pmontoya)
+ * bug #27516 Revert "bug #26138 [HttpKernel] Catch HttpExceptions when templating is not installed (cilefen)" (nicolas-grekas)
+ * bug #27318 [Cache] memcache connect should not add duplicate entries on sequential calls (Aleksey Prilipko)
+ * bug #27389 [Serializer] Fix serializer tries to denormalize null values on nullable properties (ogizanagi)
+ * bug #27272 [FrameworkBundle] Change priority of AddConsoleCommandPass to TYPE_BEFORE_REMOVING (upyx)
+ * bug #27396 [HttpKernel] fix registering IDE links (nicolas-grekas)
+ * bug #26973 [HttpKernel] Set first trusted proxy as REMOTE_ADDR in InlineFragmentRenderer. (kmadejski)
+ * bug #27303 [Process] Consider "executable" suffixes first on Windows (sanmai)
+ * bug #27297 Triggering RememberMe's loginFail() when token cannot be created (weaverryan)
+ * bug #27344 [HttpKernel] reset kernel start time on reboot (kiler129)
+ * bug #27365 [Serializer] Check the value of enable_max_depth if defined (dunglas)
+ * bug #27358 [PhpUnitBridge] silence some stderr outputs (ostrolucky)
+ * bug #27366 [DI] never inline lazy services (nicolas-grekas)
+
* 4.0.11 (2018-05-25)
* bug #27364 [DI] Fix bad exception on uninitialized references to non-shared services (nicolas-grekas)
diff --git a/README.md b/README.md
index 9db99a74c0cc0..5796b1acd7ceb 100644
--- a/README.md
+++ b/README.md
@@ -29,6 +29,7 @@ Community
* [Join the Symfony Community][11] and meet other members at the [Symfony events][12].
* [Get Symfony support][13] on Stack Overflow, Slack, IRC, etc.
* Follow us on [GitHub][14], [Twitter][15] and [Facebook][16].
+* Read our [Code of Conduct][24] and meet the [CARE Team][25]
Contributing
------------
@@ -71,3 +72,5 @@ Symfony development is sponsored by [SensioLabs][21], led by the
[21]: https://sensiolabs.com
[22]: https://symfony.com/doc/current/contributing/code/core_team.html
[23]: https://github.com/symfony/symfony-demo
+[24]: https://symfony.com/coc
+[25]: https://symfony.com/doc/current/contributing/code_of_conduct/care_team.html
diff --git a/UPGRADE-4.0.md b/UPGRADE-4.0.md
index 14dc6f07a6f8d..fe43d0cf99737 100644
--- a/UPGRADE-4.0.md
+++ b/UPGRADE-4.0.md
@@ -759,6 +759,9 @@ Security
* The `GuardAuthenticatorInterface` interface has been removed.
Use `AuthenticatorInterface` instead.
+ * When extending `AbstractGuardAuthenticator` getCredentials() cannot return
+ `null` anymore, return false from `supports()` if no credentials available instead.
+
SecurityBundle
--------------
diff --git a/composer.json b/composer.json
index b389ddf3fb4ed..d58cbc586bef0 100644
--- a/composer.json
+++ b/composer.json
@@ -18,7 +18,7 @@
"require": {
"php": "^7.1.3",
"ext-xml": "*",
- "doctrine/common": "~2.4",
+ "doctrine/common": "~2.4@stable",
"fig/link-util": "^1.0",
"twig/twig": "^1.35|^2.4.4",
"psr/cache": "~1.0",
diff --git a/phpunit b/phpunit
index c0ffe8ddef9e9..f4b80ed064121 100755
--- a/phpunit
+++ b/phpunit
@@ -8,7 +8,7 @@ if (!file_exists(__DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit')) {
exit(1);
}
if (\PHP_VERSION_ID >= 70000 && !getenv('SYMFONY_PHPUNIT_VERSION')) {
- putenv('SYMFONY_PHPUNIT_VERSION=6.0');
+ putenv('SYMFONY_PHPUNIT_VERSION=6.5');
}
putenv('SYMFONY_PHPUNIT_DIR='.__DIR__.'/.phpunit');
require __DIR__.'/vendor/symfony/phpunit-bridge/bin/simple-phpunit';
diff --git a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php
index 5de9e50e7cba6..9770e031a1097 100644
--- a/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php
+++ b/src/Symfony/Bridge/Doctrine/Tests/DependencyInjection/DoctrineExtensionTest.php
@@ -204,9 +204,7 @@ public function testLoadBasicCacheDriver(string $class, array $config, array $ex
$definition = $container->getDefinition('doctrine.orm.default_metadata_cache');
$defCalls = $definition->getMethodCalls();
$expectedCalls[] = 'setNamespace';
- $actualCalls = array_map(function ($call) {
- return $call[0];
- }, $defCalls);
+ $actualCalls = array_column($defCalls, 0);
$this->assertFalse($definition->isPublic());
$this->assertEquals("%$class%", $definition->getClass());
diff --git a/src/Symfony/Bridge/Doctrine/composer.json b/src/Symfony/Bridge/Doctrine/composer.json
index 9ad37c23e3615..e9935ed3c116b 100644
--- a/src/Symfony/Bridge/Doctrine/composer.json
+++ b/src/Symfony/Bridge/Doctrine/composer.json
@@ -17,7 +17,7 @@
],
"require": {
"php": "^7.1.3",
- "doctrine/common": "~2.4",
+ "doctrine/common": "~2.4@stable",
"symfony/polyfill-ctype": "~1.8",
"symfony/polyfill-mbstring": "~1.0"
},
diff --git a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php
index 5f2be509231a8..c18f857285c9d 100644
--- a/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php
+++ b/src/Symfony/Bridge/Monolog/Tests/Processor/WebProcessorTest.php
@@ -49,6 +49,8 @@ public function testUseRequestClientIp()
$this->assertEquals($server['REQUEST_METHOD'], $record['extra']['http_method']);
$this->assertEquals($server['SERVER_NAME'], $record['extra']['server']);
$this->assertEquals($server['HTTP_REFERER'], $record['extra']['referrer']);
+
+ Request::setTrustedProxies(array(), -1);
}
public function testCanBeConstructedWithExtraFields()
diff --git a/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php b/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php
index 008ba437d83a9..134eefe940180 100644
--- a/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php
+++ b/src/Symfony/Bridge/PhpUnit/Tests/CoverageListenerTest.php
@@ -27,11 +27,11 @@ public function test()
$dir = __DIR__.'/../Tests/Fixtures/coverage';
$phpunit = $_SERVER['argv'][0];
- exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text", $output);
+ exec("$php $phpunit -c $dir/phpunit-without-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output);
$output = implode("\n", $output);
$this->assertContains('FooCov', $output);
- exec("$php $phpunit -c $dir/phpunit-with-listener.xml.dist $dir/tests/ --coverage-text", $output);
+ exec("$php $phpunit -c $dir/phpunit-with-listener.xml.dist $dir/tests/ --coverage-text 2> /dev/null", $output);
$output = implode("\n", $output);
$this->assertNotContains('FooCov', $output);
$this->assertContains("SutNotFoundTest::test\nCould not find the tested class.", $output);
diff --git a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
index a824eae8f2ab4..197650915fe91 100755
--- a/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
+++ b/src/Symfony/Bridge/PhpUnit/bin/simple-phpunit
@@ -47,7 +47,7 @@ if ('phpdbg' === PHP_SAPI) {
$PHP .= ' -qrr';
}
-$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar`))
+$COMPOSER = file_exists($COMPOSER = $oldPwd.'/composer.phar') || ($COMPOSER = rtrim('\\' === DIRECTORY_SEPARATOR ? preg_replace('/[\r\n].*/', '', `where.exe composer.phar`) : `which composer.phar 2> /dev/null`))
? $PHP.' '.escapeshellarg($COMPOSER)
: 'composer';
@@ -70,6 +70,8 @@ if (!file_exists("$PHPUNIT_DIR/phpunit-$PHPUNIT_VERSION/phpunit") || md5_file(__
throw new \RuntimeException("Could not find $remoteZip");
}
stream_copy_to_stream($remoteZipStream, fopen("$PHPUNIT_VERSION.zip", 'wb'));
+ } elseif ('\\' === DIRECTORY_SEPARATOR) {
+ passthru("certutil -urlcache -split -f \"https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip\" $PHPUNIT_VERSION.zip");
} else {
@unlink("$PHPUNIT_VERSION.zip");
passthru("wget -q https://github.com/sebastianbergmann/phpunit/archive/$PHPUNIT_VERSION.zip");
@@ -188,15 +190,6 @@ if ($components) {
}
}
- // Fixes for colors support on appveyor
- // See https://github.com/appveyor/ci/issues/373
- $colorFixes = array(
- array("S\033[0m\033[0m\033[36m\033[1mS", "E\033[0m\033[0m\033[31m\033[1mE", "I\033[0m\033[0m\033[33m\033[1mI", "F\033[0m\033[0m\033[41m\033[37mF"),
- array("SS", "EE", "II", "FF"),
- );
- $colorFixes[0] = array_merge($colorFixes[0], $colorFixes[0]);
- $colorFixes[1] = array_merge($colorFixes[1], $colorFixes[1]);
-
while ($runningProcs) {
usleep(300000);
$terminatedProcs = array();
@@ -212,20 +205,7 @@ if ($components) {
foreach ($terminatedProcs as $component => $procStatus) {
foreach (array('out', 'err') as $file) {
$file = "$component/phpunit.std$file";
-
- if ('\\' === DIRECTORY_SEPARATOR) {
- $h = fopen($file, 'rb');
- while (false !== $line = fgets($h)) {
- echo str_replace($colorFixes[0], $colorFixes[1], preg_replace(
- '/(\033\[[0-9]++);([0-9]++m)(?:(.)(\033\[0m))?/',
- "$1m\033[$2$3$4$4",
- $line
- ));
- }
- fclose($h);
- } else {
- readfile($file);
- }
+ readfile($file);
unlink($file);
}
diff --git a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php
index ceaa1febc6202..cabae2517b691 100644
--- a/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php
+++ b/src/Symfony/Bridge/ProxyManager/LazyProxy/PhpDumper/ProxyDumper.php
@@ -54,7 +54,7 @@ public function getProxyFactoryCode(Definition $definition, $id, $factoryCode =
$instantiation = 'return';
if ($definition->isShared()) {
- $instantiation .= sprintf(' $this->%s[\'%s\'] =', $definition->isPublic() || !method_exists(ContainerBuilder::class, 'addClassResource') ? 'services' : 'privates', $id);
+ $instantiation .= sprintf(' $this->%s[\'%s\'] =', $definition->isPublic() && !$definition->isPrivate() ? 'services' : 'privates', $id);
}
if (null === $factoryCode) {
diff --git a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php
index 725d4246bac0b..cd346dfe580eb 100644
--- a/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php
+++ b/src/Symfony/Bridge/ProxyManager/Tests/LazyProxy/PhpDumper/ProxyDumperTest.php
@@ -80,6 +80,34 @@ public function testGetProxyFactoryCode()
);
}
+ /**
+ * @dataProvider getPrivatePublicDefinitions
+ */
+ public function testCorrectAssigning(Definition $definition, $access)
+ {
+ $definition->setLazy(true);
+
+ $code = $this->dumper->getProxyFactoryCode($definition, 'foo', '$this->getFoo2Service(false)');
+
+ $this->assertStringMatchesFormat('%A$this->'.$access.'[\'foo\'] = %A', $code);
+ }
+
+ public function getPrivatePublicDefinitions()
+ {
+ return array(
+ array(
+ (new Definition(__CLASS__))
+ ->setPublic(false),
+ 'privates',
+ ),
+ array(
+ (new Definition(__CLASS__))
+ ->setPublic(true),
+ 'services',
+ ),
+ );
+ }
+
/**
* @expectedException \InvalidArgumentException
* @expectedExceptionMessage Missing factory code to construct the service "foo".
diff --git a/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php b/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php
index 77c78ce38f530..c81d1cac7d3d0 100644
--- a/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php
+++ b/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php
@@ -11,6 +11,7 @@
namespace Symfony\Bridge\Twig;
+use Symfony\Bundle\FullStack;
use Twig\Error\SyntaxError;
/**
@@ -55,14 +56,21 @@ class UndefinedCallableHandler
'workflow_marked_places' => 'workflow',
);
+ private static $fullStackEnable = array(
+ 'form' => 'enable "framework.form"',
+ 'security-core' => 'add the "SecurityBundle"',
+ 'security-http' => 'add the "SecurityBundle"',
+ 'web-link' => 'enable "framework.web_link"',
+ 'workflow' => 'enable "framework.workflows"',
+ );
+
public static function onUndefinedFilter($name)
{
if (!isset(self::$filterComponents[$name])) {
return false;
}
- // Twig will append the source context to the message, so that it will end up being like "[...] Unknown filter "%s" in foo.html.twig on line 123."
- throw new SyntaxError(sprintf('Did you forget to run "composer require symfony/%s"? Unknown filter "%s".', self::$filterComponents[$name], $name));
+ self::onUndefined($name, 'filter', self::$filterComponents[$name]);
}
public static function onUndefinedFunction($name)
@@ -71,6 +79,15 @@ public static function onUndefinedFunction($name)
return false;
}
- throw new SyntaxError(sprintf('Did you forget to run "composer require symfony/%s"? Unknown function "%s".', self::$functionComponents[$name], $name));
+ self::onUndefined($name, 'function', self::$functionComponents[$name]);
+ }
+
+ private static function onUndefined($name, $type, $component)
+ {
+ if (\class_exists(FullStack::class) && isset(self::$fullStackEnable[$component])) {
+ throw new SyntaxError(sprintf('Did you forget to %s? Unknown %s "%s".', self::$fullStackEnable[$component], $type, $name));
+ }
+
+ throw new SyntaxError(sprintf('Did you forget to run "composer require symfony/%s"? Unknown %s "%s".', $component, $type, $name));
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
index e4d4d1ea209a3..9d35151dd4d6e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Console/Descriptor/TextDescriptor.php
@@ -311,7 +311,7 @@ protected function describeContainerDefinition(Definition $definition, array $op
$tableRows[] = array('Autoconfigured', $definition->isAutoconfigured() ? 'yes' : 'no');
if ($definition->getFile()) {
- $tableRows[] = array('Required File', $definition->getFile() ? $definition->getFile() : '-');
+ $tableRows[] = array('Required File', $definition->getFile() ?: '-');
}
if ($factory = $definition->getFactory()) {
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php
index 094712ded69d3..bd6908b9c4507 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Compiler/CachePoolClearerPass.php
@@ -11,7 +11,6 @@
namespace Symfony\Bundle\FrameworkBundle\DependencyInjection\Compiler;
-use Symfony\Component\Cache\Adapter\AbstractAdapter;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
@@ -38,22 +37,5 @@ public function process(ContainerBuilder $container)
}
$clearer->replaceArgument(0, $pools);
}
-
- if (!$container->has('cache.annotations')) {
- return;
- }
- $factory = array(AbstractAdapter::class, 'createSystemCache');
- $annotationsPool = $container->findDefinition('cache.annotations');
- if ($factory !== $annotationsPool->getFactory() || 4 !== count($annotationsPool->getArguments())) {
- return;
- }
- if ($container->has('monolog.logger.cache')) {
- $annotationsPool->addArgument(new Reference('monolog.logger.cache'));
- } elseif ($container->has('cache.system')) {
- $systemPool = $container->findDefinition('cache.system');
- if ($factory === $systemPool->getFactory() && 5 <= count($systemArgs = $systemPool->getArguments())) {
- $annotationsPool->addArgument($systemArgs[4]);
- }
- }
}
}
diff --git a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
index 6e6b7d19f54be..cb1a86bc50072 100644
--- a/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
+++ b/src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php
@@ -280,8 +280,8 @@ private function addWorkflowSection(ArrayNodeDefinition $rootNode)
->prototype('scalar')
->cannotBeEmpty()
->validate()
- ->ifTrue(function ($v) { return !class_exists($v); })
- ->thenInvalid('The supported class %s does not exist.')
+ ->ifTrue(function ($v) { return !class_exists($v) && !interface_exists($v); })
+ ->thenInvalid('The supported class or interface "%s" does not exist.')
->end()
->end()
->end()
diff --git a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
index 11220fe3d53c4..12a5bedcec82e 100644
--- a/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
+++ b/src/Symfony/Bundle/FrameworkBundle/FrameworkBundle.php
@@ -61,9 +61,6 @@ class FrameworkBundle extends Bundle
{
public function boot()
{
- if (!ini_get('xdebug.file_link_format') && !get_cfg_var('xdebug.file_link_format')) {
- ini_set('xdebug.file_link_format', $this->container->getParameter('debug.file_link_format'));
- }
ErrorHandler::register(null, false)->throwAt($this->container->getParameter('debug.error_handler.throw_at'), true);
if ($this->container->getParameter('kernel.http_method_override')) {
@@ -99,7 +96,7 @@ public function build(ContainerBuilder $container)
$this->addCompilerPassIfExists($container, AddConstraintValidatorsPass::class, PassConfig::TYPE_BEFORE_REMOVING);
$container->addCompilerPass(new AddAnnotationsCachedReaderPass(), PassConfig::TYPE_AFTER_REMOVING, -255);
$this->addCompilerPassIfExists($container, AddValidatorInitializersPass::class);
- $this->addCompilerPassIfExists($container, AddConsoleCommandPass::class);
+ $this->addCompilerPassIfExists($container, AddConsoleCommandPass::class, PassConfig::TYPE_BEFORE_REMOVING);
$this->addCompilerPassIfExists($container, TranslatorPass::class);
$container->addCompilerPass(new LoggingTranslatorPass());
$container->addCompilerPass(new AddExpressionLanguageProvidersPass());
diff --git a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
index 565aef68fd45c..0622c4196c104 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
+++ b/src/Symfony/Bundle/FrameworkBundle/Resources/config/web.xml
@@ -67,15 +67,6 @@
-
-
-
- null
-
- %kernel.debug%
- %kernel.charset%
-
-
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php
index e5df7b8c8a7cc..86aee6e0cc354 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/SerializerCacheWarmerTest.php
@@ -14,6 +14,8 @@
use Symfony\Bundle\FrameworkBundle\CacheWarmer\SerializerCacheWarmer;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Symfony\Component\Cache\Adapter\NullAdapter;
+use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader;
use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
@@ -41,12 +43,10 @@ public function testWarmUp()
$this->assertFileExists($file);
- $values = require $file;
+ $arrayPool = new PhpArrayAdapter($file, new NullAdapter());
- $this->assertInternalType('array', $values);
- $this->assertCount(2, $values);
- $this->assertArrayHasKey('Symfony_Bundle_FrameworkBundle_Tests_Fixtures_Serialization_Person', $values);
- $this->assertArrayHasKey('Symfony_Bundle_FrameworkBundle_Tests_Fixtures_Serialization_Author', $values);
+ $this->assertTrue($arrayPool->getItem('Symfony_Bundle_FrameworkBundle_Tests_Fixtures_Serialization_Person')->isHit());
+ $this->assertTrue($arrayPool->getItem('Symfony_Bundle_FrameworkBundle_Tests_Fixtures_Serialization_Author')->isHit());
$values = $fallbackPool->getValues();
@@ -72,11 +72,6 @@ public function testWarmUpWithoutLoader()
$this->assertFileExists($file);
- $values = require $file;
-
- $this->assertInternalType('array', $values);
- $this->assertCount(0, $values);
-
$values = $fallbackPool->getValues();
$this->assertInternalType('array', $values);
diff --git a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php
index 23b4732afcb3a..f8d3710c6d1c5 100644
--- a/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php
+++ b/src/Symfony/Bundle/FrameworkBundle/Tests/CacheWarmer/ValidatorCacheWarmerTest.php
@@ -14,6 +14,9 @@
use Symfony\Bundle\FrameworkBundle\CacheWarmer\ValidatorCacheWarmer;
use Symfony\Bundle\FrameworkBundle\Tests\TestCase;
use Symfony\Component\Cache\Adapter\ArrayAdapter;
+use Symfony\Component\Cache\Adapter\NullAdapter;
+use Symfony\Component\Cache\Adapter\PhpArrayAdapter;
+use Symfony\Component\Validator\Mapping\ClassMetadata;
use Symfony\Component\Validator\ValidatorBuilder;
class ValidatorCacheWarmerTest extends TestCase
@@ -36,12 +39,10 @@ public function testWarmUp()
$this->assertFileExists($file);
- $values = require $file;
+ $arrayPool = new PhpArrayAdapter($file, new NullAdapter());
- $this->assertInternalType('array', $values);
- $this->assertCount(2, $values);
- $this->assertArrayHasKey('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Person', $values);
- $this->assertArrayHasKey('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Author', $values);
+ $this->assertTrue($arrayPool->getItem('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Person')->isHit());
+ $this->assertTrue($arrayPool->getItem('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Author')->isHit());
$values = $fallbackPool->getValues();
@@ -67,14 +68,12 @@ public function testWarmUpWithAnnotations()
$this->assertFileExists($file);
- $values = require $file;
+ $arrayPool = new PhpArrayAdapter($file, new NullAdapter());
- $this->assertInternalType('array', $values);
- $this->assertCount(1, $values);
- $this->assertArrayHasKey('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Category', $values);
+ $item = $arrayPool->getItem('Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Category');
+ $this->assertTrue($item->isHit());
- // Simple check to make sure that at least one constraint is actually cached, in this case the "id" property Type.
- $this->assertContains('"int"', $values['Symfony.Bundle.FrameworkBundle.Tests.Fixtures.Validation.Category']);
+ $this->assertInstanceOf(ClassMetadata::class, $item->get());
$values = $fallbackPool->getValues();
@@ -98,11 +97,6 @@ public function testWarmUpWithoutLoader()
$this->assertFileExists($file);
- $values = require $file;
-
- $this->assertInternalType('array', $values);
- $this->assertCount(0, $values);
-
$values = $fallbackPool->getValues();
$this->assertInternalType('array', $values);
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSessionDomainConstraintPass.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSessionDomainConstraintPass.php
index ba523382b66ba..3dd18944de9f3 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSessionDomainConstraintPass.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Compiler/AddSessionDomainConstraintPass.php
@@ -26,7 +26,7 @@ class AddSessionDomainConstraintPass implements CompilerPassInterface
*/
public function process(ContainerBuilder $container)
{
- if (!$container->hasParameter('session.storage.options')) {
+ if (!$container->hasParameter('session.storage.options') || !$container->has('security.http_utils')) {
return;
}
@@ -34,7 +34,6 @@ public function process(ContainerBuilder $container)
$domainRegexp = empty($sessionOptions['cookie_domain']) ? '%s' : sprintf('(?:%%s|(?:.+\.)?%s)', preg_quote(trim($sessionOptions['cookie_domain'], '.')));
$domainRegexp = (empty($sessionOptions['cookie_secure']) ? 'https?://' : 'https://').$domainRegexp;
- // if the service doesn't exist, an exception must be thrown - ignoring would put security at risk
$container->findDefinition('security.http_utils')->addArgument(sprintf('{^%s$}i', $domainRegexp));
}
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php
index 3bfb50718bfa4..7c90ef620572a 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/HttpBasicFactory.php
@@ -41,6 +41,7 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
$listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.basic'));
$listener->replaceArgument(2, $id);
$listener->replaceArgument(3, new Reference($entryPointId));
+ $listener->addMethodCall('setSessionAuthenticationStrategy', array(new Reference('security.authentication.session_strategy.'.$id)));
return array($provider, $listenerId, $entryPointId);
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php
index 5a391ffacaeab..6c7adb032395b 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/JsonLoginFactory.php
@@ -89,6 +89,7 @@ protected function createListener($container, $id, $config, $userProvider)
$listener->replaceArgument(4, isset($config['success_handler']) ? new Reference($this->createAuthenticationSuccessHandler($container, $id, $config)) : null);
$listener->replaceArgument(5, isset($config['failure_handler']) ? new Reference($this->createAuthenticationFailureHandler($container, $id, $config)) : null);
$listener->replaceArgument(6, array_intersect_key($config, $this->options));
+ $listener->addMethodCall('setSessionAuthenticationStrategy', array(new Reference('security.authentication.session_strategy.'.$id)));
$listenerId .= '.'.$id;
$container->setDefinition($listenerId, $listener);
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php
index 5e0c9d716b8f5..654816e50e737 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/RemoteUserFactory.php
@@ -38,6 +38,7 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
$listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.remote_user'));
$listener->replaceArgument(2, $id);
$listener->replaceArgument(3, $config['user']);
+ $listener->addMethodCall('setSessionAuthenticationStrategy', array(new Reference('security.authentication.session_strategy.'.$id)));
return array($providerId, $listenerId, $defaultEntryPoint);
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimplePreAuthenticationFactory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimplePreAuthenticationFactory.php
index 5e394fca67c7b..de0df6868f3fa 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimplePreAuthenticationFactory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/SimplePreAuthenticationFactory.php
@@ -57,6 +57,7 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
$listener = $container->setDefinition($listenerId, new ChildDefinition('security.authentication.listener.simple_preauth'));
$listener->replaceArgument(2, $id);
$listener->replaceArgument(3, new Reference($config['authenticator']));
+ $listener->addMethodCall('setSessionAuthenticationStrategy', array(new Reference('security.authentication.session_strategy.'.$id)));
return array($provider, $listenerId, null);
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php
index 39a1016b34bb1..17390f4b828f4 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/Security/Factory/X509Factory.php
@@ -39,6 +39,7 @@ public function create(ContainerBuilder $container, $id, $config, $userProvider,
$listener->replaceArgument(2, $id);
$listener->replaceArgument(3, $config['user']);
$listener->replaceArgument(4, $config['credentials']);
+ $listener->addMethodCall('setSessionAuthenticationStrategy', array(new Reference('security.authentication.session_strategy.'.$id)));
return array($providerId, $listenerId, $defaultEntryPoint);
}
diff --git a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
index 2d165398f44e2..719e471f21225 100644
--- a/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
+++ b/src/Symfony/Bundle/SecurityBundle/DependencyInjection/SecurityExtension.php
@@ -44,6 +44,7 @@ class SecurityExtension extends Extension
private $factories = array();
private $userProviderFactories = array();
private $expressionLanguage;
+ private $statelessFirewallKeys = array();
public function __construct()
{
@@ -103,6 +104,9 @@ public function load(array $configs, ContainerBuilder $container)
$this->createAuthorization($config, $container);
$this->createRoleHierarchy($config, $container);
+ $container->getDefinition('security.authentication.guard_handler')
+ ->replaceArgument(2, $this->statelessFirewallKeys);
+
if ($config['encoders']) {
$this->createEncoders($config['encoders'], $container);
}
@@ -272,7 +276,12 @@ private function createFirewall(ContainerBuilder $container, $id, $firewall, &$a
}
$listeners[] = new Reference($this->createContextListener($container, $contextKey));
+ $sessionStrategyId = 'security.authentication.session_strategy';
+ } else {
+ $this->statelessFirewallKeys[] = $id;
+ $sessionStrategyId = 'security.authentication.session_strategy_noop';
}
+ $container->setAlias(new Alias('security.authentication.session_strategy.'.$id, false), $sessionStrategyId);
$config->replaceArgument(6, $contextKey);
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml
index 8e6133528c4bd..6e07753c896d3 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/guard.xml
@@ -12,6 +12,10 @@
>
+
+
+
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
index 515f56db6e8ca..58c84aaff1c16 100644
--- a/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
+++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/security.xml
@@ -64,6 +64,10 @@
+
+ none
+
+
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSessionDomainConstraintPassTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSessionDomainConstraintPassTest.php
index a836ab136cd93..382bdebe018fa 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSessionDomainConstraintPassTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/Compiler/AddSessionDomainConstraintPassTest.php
@@ -96,19 +96,6 @@ public function testNoSession()
$this->assertTrue($utils->createRedirectResponse($request, 'http://pirate.com/foo')->isRedirect('http://pirate.com/foo'));
}
- /**
- * @expectedException \Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException
- * @expectedExceptionMessage You have requested a non-existent service "security.http_utils".
- */
- public function testNoHttpUtils()
- {
- $container = new ContainerBuilder();
- $container->setParameter('session.storage.options', array());
-
- $pass = new AddSessionDomainConstraintPass();
- $pass->process($container);
- }
-
private function createContainer($sessionStorageOptions)
{
$container = new ContainerBuilder();
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
index 22d108c59ac56..65b681ad677d2 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/DependencyInjection/SecurityExtensionTest.php
@@ -123,6 +123,35 @@ public function testDisableRoleHierarchyVoter()
$this->assertFalse($container->hasDefinition('security.access.role_hierarchy_voter'));
}
+ public function testGuardHandlerIsPassedStatelessFirewalls()
+ {
+ $container = $this->getRawContainer();
+
+ $container->loadFromExtension('security', array(
+ 'providers' => array(
+ 'default' => array('id' => 'foo'),
+ ),
+
+ 'firewalls' => array(
+ 'some_firewall' => array(
+ 'pattern' => '^/admin',
+ 'http_basic' => null,
+ 'logout_on_user_change' => true,
+ ),
+ 'stateless_firewall' => array(
+ 'pattern' => '/.*',
+ 'stateless' => true,
+ 'http_basic' => null,
+ 'logout_on_user_change' => true,
+ ),
+ ),
+ ));
+
+ $container->compile();
+ $definition = $container->getDefinition('security.authentication.guard_handler');
+ $this->assertSame(array('stateless_firewall'), $definition->getArgument(2));
+ }
+
public function testSwitchUserNotStatelessOnStatelessFirewall()
{
$container = $this->getRawContainer();
diff --git a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php
index 8d2e34aa20422..13d2922c779e5 100644
--- a/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php
+++ b/src/Symfony/Bundle/SecurityBundle/Tests/Functional/UserPasswordEncoderCommandTest.php
@@ -86,7 +86,7 @@ public function testEncodePasswordArgon2i()
$this->assertContains('Password encoding succeeded', $output);
$encoder = new Argon2iPasswordEncoder();
- preg_match('# Encoded password\s+(\$argon2id?\$[\w\d,=\$+\/]+={0,2})\s+#', $output, $matches);
+ preg_match('# Encoded password\s+(\$argon2id?\$[\w,=\$+\/]+={0,2})\s+#', $output, $matches);
$hash = $matches[1];
$this->assertTrue($encoder->isPasswordValid($hash, 'password', null));
}
diff --git a/src/Symfony/Bundle/SecurityBundle/composer.json b/src/Symfony/Bundle/SecurityBundle/composer.json
index 19f8b023ade20..44c1845654c01 100644
--- a/src/Symfony/Bundle/SecurityBundle/composer.json
+++ b/src/Symfony/Bundle/SecurityBundle/composer.json
@@ -18,7 +18,7 @@
"require": {
"php": "^7.1.3",
"ext-xml": "*",
- "symfony/security": "~3.4.11|^4.0.11",
+ "symfony/security": "~3.4.12|~4.0.12|^4.1.1",
"symfony/dependency-injection": "^3.4.3|^4.0.3",
"symfony/http-kernel": "~3.4|~4.0"
},
@@ -44,7 +44,6 @@
"twig/twig": "~1.34|~2.4"
},
"conflict": {
- "symfony/security": "4.1.0-beta1|4.1.0-beta2",
"symfony/var-dumper": "<3.4",
"symfony/event-dispatcher": "<3.4",
"symfony/framework-bundle": "<3.4",
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
index a4e8c944c92a3..0ca55f298ee83 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/Compiler/ExtensionPass.php
@@ -82,6 +82,10 @@ public function process(ContainerBuilder $container)
}
}
+ if ($container->has('web_link.add_link_header_listener')) {
+ $container->getDefinition('twig.extension.weblink')->addTag('twig.extension');
+ }
+
$twigLoader = $container->getDefinition('twig.loader.native_filesystem');
if ($container->has('templating')) {
$loader = $container->getDefinition('twig.loader.filesystem');
diff --git a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
index b44dd2481c631..ee325ba75ac5e 100644
--- a/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
+++ b/src/Symfony/Bundle/TwigBundle/DependencyInjection/TwigExtension.php
@@ -11,7 +11,6 @@
namespace Symfony\Bundle\TwigBundle\DependencyInjection;
-use Symfony\Bridge\Twig\Extension\WebLinkExtension;
use Symfony\Component\Config\FileLocator;
use Symfony\Component\Config\Resource\FileExistenceResource;
use Symfony\Component\Console\Application;
@@ -19,7 +18,6 @@
use Symfony\Component\DependencyInjection\Reference;
use Symfony\Component\DependencyInjection\Loader\XmlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
-use Symfony\Component\WebLink\HttpHeaderSerializer;
use Twig\Extension\ExtensionInterface;
use Twig\Extension\RuntimeExtensionInterface;
use Twig\Loader\LoaderInterface;
@@ -53,13 +51,6 @@ public function load(array $configs, ContainerBuilder $container)
$container->removeDefinition('twig.translation.extractor');
}
- if (class_exists(HttpHeaderSerializer::class)) {
- $definition = $container->register('twig.extension.weblink', WebLinkExtension::class);
- $definition->setPublic(false);
- $definition->addArgument(new Reference('request_stack'));
- $definition->addTag('twig.extension');
- }
-
foreach ($configs as $key => $config) {
if (isset($config['globals'])) {
foreach ($config['globals'] as $name => $value) {
diff --git a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
index fca4367ba743c..5d014e930c53e 100644
--- a/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
+++ b/src/Symfony/Bundle/TwigBundle/Resources/config/twig.xml
@@ -114,6 +114,10 @@
+
+
+
+