diff --git a/Command/SecretsRevealCommand.php b/Command/SecretsRevealCommand.php
index 150186b1d..c2110ee76 100644
--- a/Command/SecretsRevealCommand.php
+++ b/Command/SecretsRevealCommand.php
@@ -61,6 +61,10 @@ protected function execute(InputInterface $input, OutputInterface $output): int
if (!\array_key_exists($name, $secrets)) {
$io->error(\sprintf('The secret "%s" does not exist.', $name));
+ return self::INVALID;
+ } elseif (null === $secrets[$name]) {
+ $io->error(\sprintf('The secret "%s" could not be decrypted.', $name));
+
return self::INVALID;
}
diff --git a/Command/TranslationDebugCommand.php b/Command/TranslationDebugCommand.php
index 9cdfdae04..a320130d5 100644
--- a/Command/TranslationDebugCommand.php
+++ b/Command/TranslationDebugCommand.php
@@ -69,7 +69,7 @@ protected function configure(): void
->setDefinition([
new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),
new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),
- new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'The messages domain'),
+ new InputOption('domain', null, InputOption::VALUE_REQUIRED, 'The messages domain'),
new InputOption('only-missing', null, InputOption::VALUE_NONE, 'Display only missing messages'),
new InputOption('only-unused', null, InputOption::VALUE_NONE, 'Display only unused messages'),
new InputOption('all', null, InputOption::VALUE_NONE, 'Load messages from all registered bundles'),
diff --git a/Command/TranslationExtractCommand.php b/Command/TranslationExtractCommand.php
index d7967bbe8..c8e61b61a 100644
--- a/Command/TranslationExtractCommand.php
+++ b/Command/TranslationExtractCommand.php
@@ -72,15 +72,15 @@ protected function configure(): void
->setDefinition([
new InputArgument('locale', InputArgument::REQUIRED, 'The locale'),
new InputArgument('bundle', InputArgument::OPTIONAL, 'The bundle name or directory where to load the messages'),
- new InputOption('prefix', null, InputOption::VALUE_OPTIONAL, 'Override the default prefix', '__'),
+ new InputOption('prefix', null, InputOption::VALUE_REQUIRED, 'Override the default prefix', '__'),
new InputOption('no-fill', null, InputOption::VALUE_NONE, 'Extract translation keys without filling in values'),
- new InputOption('format', null, InputOption::VALUE_OPTIONAL, 'Override the default output format', 'xlf12'),
+ new InputOption('format', null, InputOption::VALUE_REQUIRED, 'Override the default output format', 'xlf12'),
new InputOption('dump-messages', null, InputOption::VALUE_NONE, 'Should the messages be dumped in the console'),
new InputOption('force', null, InputOption::VALUE_NONE, 'Should the extract be done'),
new InputOption('clean', null, InputOption::VALUE_NONE, 'Should clean not found messages'),
- new InputOption('domain', null, InputOption::VALUE_OPTIONAL, 'Specify the domain to extract'),
- new InputOption('sort', null, InputOption::VALUE_OPTIONAL, 'Return list of messages sorted alphabetically'),
- new InputOption('as-tree', null, InputOption::VALUE_OPTIONAL, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),
+ new InputOption('domain', null, InputOption::VALUE_REQUIRED, 'Specify the domain to extract'),
+ new InputOption('sort', null, InputOption::VALUE_REQUIRED, 'Return list of messages sorted alphabetically'),
+ new InputOption('as-tree', null, InputOption::VALUE_REQUIRED, 'Dump the messages as a tree-like structure: The given value defines the level where to switch to inline YAML'),
])
->setHelp(<<<'EOF'
The %command.name% command extracts translation strings from templates
diff --git a/DependencyInjection/Configuration.php b/DependencyInjection/Configuration.php
index f4e137f04..d042d44b5 100644
--- a/DependencyInjection/Configuration.php
+++ b/DependencyInjection/Configuration.php
@@ -1096,7 +1096,7 @@ private function addValidationSection(ArrayNodeDefinition $rootNode, callable $e
->validate()->castToArray()->end()
->end()
->scalarNode('translation_domain')->defaultValue('validators')->end()
- ->enumNode('email_validation_mode')->values((class_exists(Email::class) ? Email::VALIDATION_MODES : ['html5-allow-no-tld', 'html5', 'strict']) + ['loose'])->defaultValue('html5')->end()
+ ->enumNode('email_validation_mode')->values(array_merge(class_exists(Email::class) ? Email::VALIDATION_MODES : ['html5-allow-no-tld', 'html5', 'strict'], ['loose']))->defaultValue('html5')->end()
->arrayNode('mapping')
->addDefaultsIfNotSet()
->fixXmlConfig('path')
diff --git a/DependencyInjection/FrameworkExtension.php b/DependencyInjection/FrameworkExtension.php
index 347f3ed65..d3cefbb28 100644
--- a/DependencyInjection/FrameworkExtension.php
+++ b/DependencyInjection/FrameworkExtension.php
@@ -61,6 +61,7 @@
use Symfony\Component\DependencyInjection\Alias;
use Symfony\Component\DependencyInjection\Argument\IteratorArgument;
use Symfony\Component\DependencyInjection\Argument\ServiceLocatorArgument;
+use Symfony\Component\DependencyInjection\Attribute\Target;
use Symfony\Component\DependencyInjection\ChildDefinition;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\Compiler\ServiceLocatorTagPass;
@@ -302,6 +303,10 @@ public function load(array $configs, ContainerBuilder $container): void
// Load Cache configuration first as it is used by other components
$loader->load('cache.php');
+ if (!interface_exists(NamespacedPoolInterface::class)) {
+ $container->removeAlias(NamespacedPoolInterface::class);
+ }
+
$configuration = $this->getConfiguration($configs, $container);
$config = $this->processConfiguration($configuration, $configs);
@@ -1769,10 +1774,6 @@ private function registerValidationConfiguration(array $config, ContainerBuilder
throw new LogicException('Validation support cannot be enabled as the Validator component is not installed. Try running "composer require symfony/validator".');
}
- if (!isset($config['email_validation_mode'])) {
- $config['email_validation_mode'] = 'loose';
- }
-
$loader->load('validator.php');
$validatorBuilder = $container->getDefinition('validator.builder');
@@ -2293,7 +2294,7 @@ private function registerSchedulerConfiguration(ContainerBuilder $container, Php
}
// BC layer Scheduler < 7.3
- if (!class_exists(SchedulerTriggerNormalizer::class)) {
+ if (!ContainerBuilder::willBeAvailable('symfony/serializer', DenormalizerInterface::class, ['symfony/framework-bundle', 'symfony/scheduler']) || !class_exists(SchedulerTriggerNormalizer::class)) {
$container->removeDefinition('serializer.normalizer.scheduler_trigger');
}
}
@@ -2371,16 +2372,18 @@ private function registerMessengerConfiguration(array $config, ContainerBuilder
$defaultMiddleware['after'][0]['arguments'] = [$bus['default_middleware']['allow_no_senders']];
$defaultMiddleware['after'][1]['arguments'] = [$bus['default_middleware']['allow_no_handlers']];
- // argument to add_bus_name_stamp_middleware
- $defaultMiddleware['before'][0]['arguments'] = [$busId];
-
$middleware = array_merge($defaultMiddleware['before'], $middleware, $defaultMiddleware['after']);
}
- foreach ($middleware as $middlewareItem) {
+ foreach ($middleware as $key => $middlewareItem) {
if (!$validationEnabled && \in_array($middlewareItem['id'], ['validation', 'messenger.middleware.validation'], true)) {
throw new LogicException('The Validation middleware is only available when the Validator component is installed and enabled. Try running "composer require symfony/validator".');
}
+
+ // argument to add_bus_name_stamp_middleware
+ if ('add_bus_name_stamp_middleware' === $middlewareItem['id']) {
+ $middleware[$key]['arguments'] = [$busId];
+ }
}
if ($container->getParameter('kernel.debug') && class_exists(Stopwatch::class)) {
@@ -3299,7 +3302,12 @@ private function registerRateLimiterConfiguration(array $config, ContainerBuilde
if (interface_exists(RateLimiterFactoryInterface::class)) {
$container->registerAliasForArgument($limiterId, RateLimiterFactoryInterface::class, $name.'.limiter');
- $factoryAlias->setDeprecated('symfony/dependency-injection', '7.3', 'The "%alias_id%" autowiring alias is deprecated and will be removed in 8.0, use "RateLimiterFactoryInterface" instead.');
+ $factoryAlias->setDeprecated('symfony/framework-bundle', '7.3', \sprintf('The "%%alias_id%%" autowiring alias is deprecated and will be removed in 8.0, use "%s $%s" instead.', RateLimiterFactoryInterface::class, (new Target($name.'.limiter'))->getParsedName()));
+ $internalAliasId = \sprintf('.%s $%s.limiter', RateLimiterFactory::class, $name);
+
+ if ($container->hasAlias($internalAliasId)) {
+ $container->getAlias($internalAliasId)->setDeprecated('symfony/framework-bundle', '7.3', \sprintf('The "%%alias_id%%" autowiring alias is deprecated and will be removed in 8.0, use "%s $%s" instead.', RateLimiterFactoryInterface::class, (new Target($name.'.limiter'))->getParsedName()));
+ }
}
}
diff --git a/Resources/config/cache.php b/Resources/config/cache.php
index 3d96ba059..ae9d426a4 100644
--- a/Resources/config/cache.php
+++ b/Resources/config/cache.php
@@ -28,6 +28,7 @@
use Symfony\Component\Cache\Messenger\EarlyExpirationHandler;
use Symfony\Component\HttpKernel\CacheClearer\Psr6CacheClearer;
use Symfony\Contracts\Cache\CacheInterface;
+use Symfony\Contracts\Cache\NamespacedPoolInterface;
use Symfony\Contracts\Cache\TagAwareCacheInterface;
return static function (ContainerConfigurator $container) {
@@ -250,6 +251,8 @@
->alias(CacheInterface::class, 'cache.app')
+ ->alias(NamespacedPoolInterface::class, 'cache.app')
+
->alias(TagAwareCacheInterface::class, 'cache.app.taggable')
;
};
diff --git a/Secrets/AbstractVault.php b/Secrets/AbstractVault.php
index 882ec7862..788601d2e 100644
--- a/Secrets/AbstractVault.php
+++ b/Secrets/AbstractVault.php
@@ -31,6 +31,9 @@ abstract public function reveal(string $name): ?string;
abstract public function remove(string $name): bool;
+ /**
+ * @return array
+ */
abstract public function list(bool $reveal = false): array;
protected function validateName(string $name): void
diff --git a/Secrets/DotenvVault.php b/Secrets/DotenvVault.php
index 15952611a..3fab5f4e2 100644
--- a/Secrets/DotenvVault.php
+++ b/Secrets/DotenvVault.php
@@ -89,13 +89,13 @@ public function list(bool $reveal = false): array
foreach ($_ENV as $k => $v) {
if ('' !== ($v ?? '') && preg_match('/^\w+$/D', $k)) {
- $secrets[$k] = $reveal ? $v : null;
+ $secrets[$k] = \is_string($v) && $reveal ? $v : null;
}
}
foreach ($_SERVER as $k => $v) {
if ('' !== ($v ?? '') && preg_match('/^\w+$/D', $k)) {
- $secrets[$k] = $reveal ? $v : null;
+ $secrets[$k] = \is_string($v) && $reveal ? $v : null;
}
}
diff --git a/Test/KernelTestCase.php b/Test/KernelTestCase.php
index b2c2eb4d2..87925f73c 100644
--- a/Test/KernelTestCase.php
+++ b/Test/KernelTestCase.php
@@ -39,6 +39,14 @@ protected function tearDown(): void
static::$booted = false;
}
+ public static function tearDownAfterClass(): void
+ {
+ static::ensureKernelShutdown();
+ static::$class = null;
+ static::$kernel = null;
+ static::$booted = false;
+ }
+
/**
* @throws \RuntimeException
* @throws \LogicException
diff --git a/Tests/Command/SecretsRevealCommandTest.php b/Tests/Command/SecretsRevealCommandTest.php
index 94643db2c..d77d303d5 100644
--- a/Tests/Command/SecretsRevealCommandTest.php
+++ b/Tests/Command/SecretsRevealCommandTest.php
@@ -46,6 +46,19 @@ public function testInvalidName()
$this->assertStringContainsString('The secret "undefinedKey" does not exist.', trim($tester->getDisplay(true)));
}
+ public function testFailedDecrypt()
+ {
+ $vault = $this->createMock(AbstractVault::class);
+ $vault->method('list')->willReturn(['secretKey' => null]);
+
+ $command = new SecretsRevealCommand($vault);
+
+ $tester = new CommandTester($command);
+ $this->assertSame(Command::INVALID, $tester->execute(['name' => 'secretKey']));
+
+ $this->assertStringContainsString('The secret "secretKey" could not be decrypted.', trim($tester->getDisplay(true)));
+ }
+
/**
* @backupGlobals enabled
*/
diff --git a/Tests/DependencyInjection/Fixtures/php/messenger_bus_name_stamp.php b/Tests/DependencyInjection/Fixtures/php/messenger_bus_name_stamp.php
new file mode 100644
index 000000000..452594d45
--- /dev/null
+++ b/Tests/DependencyInjection/Fixtures/php/messenger_bus_name_stamp.php
@@ -0,0 +1,25 @@
+loadFromExtension('framework', [
+ 'annotations' => false,
+ 'http_method_override' => false,
+ 'handle_all_throwables' => true,
+ 'php_errors' => ['log' => true],
+ 'lock' => false,
+ 'messenger' => [
+ 'default_bus' => 'messenger.bus.commands',
+ 'buses' => [
+ 'messenger.bus.commands' => [
+ 'default_middleware' => false,
+ 'middleware' => [
+ 'add_bus_name_stamp_middleware',
+ 'send_message',
+ 'handle_message',
+ ],
+ ],
+ 'messenger.bus.events' => [
+ 'default_middleware' => true,
+ ],
+ ],
+ ],
+]);
diff --git a/Tests/DependencyInjection/Fixtures/xml/messenger_bus_name_stamp.xml b/Tests/DependencyInjection/Fixtures/xml/messenger_bus_name_stamp.xml
new file mode 100644
index 000000000..5e0b17851
--- /dev/null
+++ b/Tests/DependencyInjection/Fixtures/xml/messenger_bus_name_stamp.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/Tests/DependencyInjection/Fixtures/yml/messenger_bus_name_stamp.yml b/Tests/DependencyInjection/Fixtures/yml/messenger_bus_name_stamp.yml
new file mode 100644
index 000000000..79f8d7c87
--- /dev/null
+++ b/Tests/DependencyInjection/Fixtures/yml/messenger_bus_name_stamp.yml
@@ -0,0 +1,18 @@
+framework:
+ annotations: false
+ http_method_override: false
+ handle_all_throwables: true
+ php_errors:
+ log: true
+ lock: false
+ messenger:
+ default_bus: messenger.bus.commands
+ buses:
+ messenger.bus.commands:
+ default_middleware: false
+ middleware:
+ - "add_bus_name_stamp_middleware"
+ - "send_message"
+ - "handle_message"
+ messenger.bus.events:
+ default_middleware: true
diff --git a/Tests/DependencyInjection/FrameworkExtensionTestCase.php b/Tests/DependencyInjection/FrameworkExtensionTestCase.php
index 5ef658693..b5f5f1ef5 100644
--- a/Tests/DependencyInjection/FrameworkExtensionTestCase.php
+++ b/Tests/DependencyInjection/FrameworkExtensionTestCase.php
@@ -1099,6 +1099,28 @@ public function testMessengerWithMultipleBusesWithoutDeduplicateMiddleware()
$this->assertSame('messenger.bus.commands', (string) $container->getAlias('messenger.default_bus'));
}
+ public function testMessengerWithAddBusNameStampMiddleware()
+ {
+ $container = $this->createContainerFromFile('messenger_bus_name_stamp');
+
+ $this->assertTrue($container->has('messenger.bus.commands'));
+ $this->assertEquals([
+ ['id' => 'add_bus_name_stamp_middleware', 'arguments' => ['messenger.bus.commands']],
+ ['id' => 'send_message', 'arguments' => []],
+ ['id' => 'handle_message', 'arguments' => []],
+ ], $container->getParameter('messenger.bus.commands.middleware'));
+ $this->assertTrue($container->has('messenger.bus.events'));
+ $this->assertSame([], $container->getDefinition('messenger.bus.events')->getArgument(0));
+ $this->assertEquals([
+ ['id' => 'add_bus_name_stamp_middleware', 'arguments' => ['messenger.bus.events']],
+ ['id' => 'reject_redelivered_message_middleware'],
+ ['id' => 'dispatch_after_current_bus'],
+ ['id' => 'failed_message_processing_middleware'],
+ ['id' => 'send_message', 'arguments' => [true]],
+ ['id' => 'handle_message', 'arguments' => [false]],
+ ], $container->getParameter('messenger.bus.events.middleware'));
+ }
+
public function testMessengerWithMultipleBusesWithDeduplicateMiddleware()
{
if (!class_exists(DeduplicateMiddleware::class)) {
diff --git a/Tests/DependencyInjection/PhpFrameworkExtensionTest.php b/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
index f69a53932..65826f698 100644
--- a/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
+++ b/Tests/DependencyInjection/PhpFrameworkExtensionTest.php
@@ -456,6 +456,7 @@ public static function emailValidationModeProvider()
foreach (Email::VALIDATION_MODES as $mode) {
yield [$mode];
}
+ yield ['loose'];
}
}
diff --git a/Tests/Functional/ContainerDebugCommandTest.php b/Tests/Functional/ContainerDebugCommandTest.php
index 8d3f15ba6..d21d4d113 100644
--- a/Tests/Functional/ContainerDebugCommandTest.php
+++ b/Tests/Functional/ContainerDebugCommandTest.php
@@ -53,7 +53,7 @@ public function testNoDebug()
public function testNoDumpedXML()
{
- static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'config.yml', 'debug' => true, 'debug.container.dump' => false]);
+ static::bootKernel(['test_case' => 'ContainerDebug', 'root_config' => 'no_dump.yml', 'debug' => true]);
$application = new Application(static::$kernel);
$application->setAutoExit(false);
diff --git a/Tests/Functional/app/ContainerDebug/no_dump.yml b/Tests/Functional/app/ContainerDebug/no_dump.yml
new file mode 100644
index 000000000..a9c709e9a
--- /dev/null
+++ b/Tests/Functional/app/ContainerDebug/no_dump.yml
@@ -0,0 +1,5 @@
+imports:
+ - { resource: config.yml }
+
+parameters:
+ debug.container.dump: false