diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php index ffed85b7c..7f3111730 100644 --- a/DependencyInjection/Configuration.php +++ b/DependencyInjection/Configuration.php @@ -1672,25 +1672,11 @@ private function addMessengerSection(ArrayNodeDefinition $rootNode, callable $en ->beforeNormalization() ->ifArray() ->then(function ($config) { - // If XML config with only one routing attribute - if (2 === \count($config) && isset($config['message-class']) && isset($config['sender'])) { - $config = [0 => $config]; - } - $newConfig = []; foreach ($config as $k => $v) { - if (!\is_int($k)) { - $newConfig[$k] = [ - 'senders' => $v['senders'] ?? (\is_array($v) ? array_values($v) : [$v]), - ]; - } else { - $newConfig[$v['message-class']]['senders'] = array_map( - function ($a) { - return \is_string($a) ? $a : $a['service']; - }, - array_values($v['sender']) - ); - } + $newConfig[$k] = [ + 'senders' => $v['senders'] ?? (\is_array($v) ? array_values($v) : [$v]), + ]; } return $newConfig; diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php index 2e1867677..f39d458c8 100644 --- a/DependencyInjection/FrameworkExtension.php +++ b/DependencyInjection/FrameworkExtension.php @@ -1314,6 +1314,7 @@ private function registerSessionConfiguration(array $config, ContainerBuilder $c } $container->setParameter('session.storage.options', $options); + $container->setParameter('session.metadata.cookie_lifetime', $options['cookie_lifetime'] ?? null); // session handler (the internal callback registered with PHP session management) if (null === ($config['handler_id'] ?? $config['save_path'] ?? null)) { diff --git a/Resources/config/session.php b/Resources/config/session.php index 2e481359a..649c5cd71 100644 --- a/Resources/config/session.php +++ b/Resources/config/session.php @@ -43,6 +43,7 @@ ->args([ param('session.metadata.storage_key'), param('session.metadata.update_threshold'), + param('session.metadata.cookie_lifetime'), ]), false, ]) @@ -53,6 +54,7 @@ ->args([ param('session.metadata.storage_key'), param('session.metadata.update_threshold'), + param('session.metadata.cookie_lifetime'), ]), false, ]) @@ -64,6 +66,7 @@ ->args([ param('session.metadata.storage_key'), param('session.metadata.update_threshold'), + param('session.metadata.cookie_lifetime'), ]), ]) diff --git a/Test/KernelTestCase.php b/Test/KernelTestCase.php index 427d1016a..77136fe49 100644 --- a/Test/KernelTestCase.php +++ b/Test/KernelTestCase.php @@ -12,9 +12,11 @@ namespace Symfony\Bundle\FrameworkBundle\Test; use PHPUnit\Framework\TestCase; +use Symfony\Component\Config\Resource\SelfCheckingResourceChecker; use Symfony\Component\DependencyInjection\Container; use Symfony\Component\DependencyInjection\Exception\ServiceNotFoundException; use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HttpKernel\Kernel; use Symfony\Component\HttpKernel\KernelInterface; use Symfony\Contracts\Service\ResetInterface; @@ -32,6 +34,8 @@ abstract class KernelTestCase extends TestCase protected static ?KernelInterface $kernel = null; protected static bool $booted = false; + private static bool $kernelHasBeenRebooted = false; + protected function tearDown(): void { static::ensureKernelShutdown(); @@ -82,6 +86,7 @@ protected static function bootKernel(array $options = []): KernelInterface // reboot a fresh one. if ($kernel->getContainer()->initialized('cache_warmer')) { static::ensureKernelShutdown(); + self::$kernelHasBeenRebooted = true; $kernel = static::createKernel($options); $kernel->boot(); @@ -153,6 +158,20 @@ protected static function ensureKernelShutdown() static::$kernel->shutdown(); static::$booted = false; + if (self::$kernelHasBeenRebooted) { + self::$kernelHasBeenRebooted = false; + try { + (new \ReflectionProperty(Kernel::class, 'freshCache'))->setValue(null, []); + } catch (\ReflectionException) { + // ignore if the property doesn't exist + } + try { + (new \ReflectionProperty(SelfCheckingResourceChecker::class, 'cache'))->setValue(null, []); + } catch (\ReflectionException) { + // ignore if the property doesn't exist + } + } + if ($container instanceof ResetInterface) { $container->reset(); } diff --git a/Tests/Fixtures/reference.php b/Tests/Fixtures/reference.php index 21d7d4752..2ec9700fe 100644 --- a/Tests/Fixtures/reference.php +++ b/Tests/Fixtures/reference.php @@ -118,7 +118,7 @@ * stack: list>, * public?: bool, * deprecated?: DeprecationType, - * } + * %A} * @psalm-type ServicesConfig = array{ * _defaults?: DefaultsType, * _instanceof?: InstanceofType, diff --git a/Tests/Functional/KernelTestCaseFreshCacheTest.php b/Tests/Functional/KernelTestCaseFreshCacheTest.php new file mode 100644 index 000000000..a65f68833 --- /dev/null +++ b/Tests/Functional/KernelTestCaseFreshCacheTest.php @@ -0,0 +1,82 @@ + + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ + +namespace Symfony\Bundle\FrameworkBundle\Tests\Functional; + +use Symfony\Component\HttpKernel\KernelInterface; + +class KernelTestCaseFreshCacheTest extends AbstractWebTestCase +{ + private static string $trackedFile; + + public static function setUpBeforeClass(): void + { + parent::setUpBeforeClass(); + + self::$trackedFile = sys_get_temp_dir().'/'.static::getVarDir().'/tracked_file.yaml'; + } + + public static function tearDownAfterClass(): void + { + parent::tearDownAfterClass(); + + @unlink(self::$trackedFile); + } + + public function testContainerIsRebuiltWhenTrackedFileAppears() + { + @unlink(self::$trackedFile); + + // First boot: container is built tracking the file as non-existing + static::bootKernel(['test_case' => 'TestServiceContainer', 'debug' => true]); + + $this->assertFalse(static::$kernel->getContainer()->getParameter('tracked_file_existed')); + + static::ensureKernelShutdown(); + + // Create the tracked file between boots + @mkdir(\dirname(self::$trackedFile), 0777, true); + file_put_contents(self::$trackedFile, 'placeholder'); + + // Reboot: should detect the resource change and rebuild the container + static::bootKernel(['test_case' => 'TestServiceContainer', 'debug' => true]); + + $this->assertTrue(static::$kernel->getContainer()->getParameter('tracked_file_existed')); + } + + protected static function createKernel(array $options = []): KernelInterface + { + $kernel = parent::createKernel($options); + + FileExistenceTrackingKernel::$trackedFile = self::$trackedFile; + + return $kernel; + } + + protected static function getKernelClass(): string + { + require_once __DIR__.'/app/AppKernel.php'; + + return FileExistenceTrackingKernel::class; + } +} + +class FileExistenceTrackingKernel extends app\AppKernel +{ + public static string $trackedFile; + + protected function build(\Symfony\Component\DependencyInjection\ContainerBuilder $container): void + { + parent::build($container); + + $container->setParameter('tracked_file_existed', $container->fileExists(self::$trackedFile)); + } +}