N°8834 - Add compatibility with PHP 8.4 (#819)

* N°8834 - Add compatibility with PHP 8.4

* Rollback of scssphp/scssphp version upgrade due to compilation error
This commit is contained in:
Lenaick
2026-02-26 10:36:32 +01:00
committed by GitHub
parent d4821b7edc
commit fc967c06ce
961 changed files with 12298 additions and 7130 deletions

View File

@@ -122,6 +122,8 @@ use Symfony\Component\Mime\Header\Headers;
use Symfony\Component\Mime\MimeTypeGuesserInterface;
use Symfony\Component\Mime\MimeTypes;
use Symfony\Component\Notifier\Bridge as NotifierBridge;
use Symfony\Component\Notifier\Bridge\FakeChat\FakeChatTransportFactory;
use Symfony\Component\Notifier\Bridge\FakeSms\FakeSmsTransportFactory;
use Symfony\Component\Notifier\ChatterInterface;
use Symfony\Component\Notifier\Notifier;
use Symfony\Component\Notifier\Recipient\Recipient;
@@ -161,6 +163,7 @@ use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Mapping\Loader\AttributeLoader;
use Symfony\Component\Serializer\Mapping\Loader\XmlFileLoader;
use Symfony\Component\Serializer\Mapping\Loader\YamlFileLoader;
use Symfony\Component\Serializer\Normalizer\CacheableSupportsMethodInterface;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Serializer\Serializer;
@@ -349,7 +352,7 @@ class FrameworkExtension extends Extension
throw new LogicException('AssetMapper support cannot be enabled as the AssetMapper component is not installed. Try running "composer require symfony/asset-mapper".');
}
$this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets']));
$this->registerAssetMapperConfiguration($config['asset_mapper'], $container, $loader, $this->readConfigEnabled('assets', $container, $config['assets']), $this->readConfigEnabled('http_client', $container, $config['http_client']));
} else {
$container->removeDefinition('cache.asset_mapper');
}
@@ -677,7 +680,7 @@ class FrameworkExtension extends Extension
$tagAttributes = get_object_vars($attribute);
if ($reflector instanceof \ReflectionMethod) {
if (isset($tagAttributes['method'])) {
throw new LogicException(sprintf('AsEventListener attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name));
throw new LogicException(\sprintf('AsEventListener attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name));
}
$tagAttributes['method'] = $reflector->getName();
}
@@ -695,7 +698,7 @@ class FrameworkExtension extends Extension
unset($tagAttributes['fromTransport']);
if ($reflector instanceof \ReflectionMethod) {
if (isset($tagAttributes['method'])) {
throw new LogicException(sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name));
throw new LogicException(\sprintf('AsMessageHandler attribute cannot declare a method on "%s::%s()".', $reflector->class, $reflector->name));
}
$tagAttributes['method'] = $reflector->getName();
}
@@ -719,7 +722,7 @@ class FrameworkExtension extends Extension
];
if ($reflector instanceof \ReflectionMethod) {
if (isset($tagAttributes['method'])) {
throw new LogicException(sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name));
throw new LogicException(\sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name));
}
$tagAttributes['method'] = $reflector->getName();
}
@@ -733,7 +736,7 @@ class FrameworkExtension extends Extension
$container->getDefinition('config_cache_factory')->setArguments([]);
}
if (!$config['disallow_search_engine_index'] ?? false) {
if (!$config['disallow_search_engine_index']) {
$container->removeDefinition('disallow_search_engine_index_response_listener');
}
@@ -906,7 +909,7 @@ class FrameworkExtension extends Extension
// Choose storage class based on the DSN
[$class] = explode(':', $config['dsn'], 2);
if ('file' !== $class) {
throw new \LogicException(sprintf('Driver "%s" is not supported for the profiler.', $class));
throw new \LogicException(\sprintf('Driver "%s" is not supported for the profiler.', $class));
}
$container->setParameter('profiler.storage.dsn', $config['dsn']);
@@ -918,11 +921,11 @@ class FrameworkExtension extends Extension
$container->getDefinition('profiler_listener')
->addArgument($config['collect_parameter']);
if (!$container->getParameter('kernel.debug') || !class_exists(CliRequest::class) || !$container->has('debug.stopwatch')) {
if (!$container->getParameter('kernel.debug') || !$this->hasConsole() || !$container->has('debug.stopwatch') || !class_exists(CliRequest::class)) {
$container->removeDefinition('console_profiler_listener');
}
if (!class_exists(CommandDataCollector::class)) {
if (!$this->hasConsole() || !class_exists(CommandDataCollector::class)) {
$container->removeDefinition('.data_collector.command');
}
}
@@ -945,7 +948,7 @@ class FrameworkExtension extends Extension
foreach ($config['workflows'] as $name => $workflow) {
$type = $workflow['type'];
$workflowId = sprintf('%s.%s', $type, $name);
$workflowId = \sprintf('%s.%s', $type, $name);
// Process Metadata (workflow + places (transition is done in the "create transition" block))
$metadataStoreDefinition = new Definition(Workflow\Metadata\InMemoryMetadataStore::class, [[], [], null]);
@@ -970,19 +973,19 @@ class FrameworkExtension extends Extension
$transitionCounter = 0;
foreach ($workflow['transitions'] as $transition) {
if ('workflow' === $type) {
$transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $transition['from'], $transition['to']]);
$transitionId = sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
$container->setDefinition($transitionId, $transitionDefinition);
$transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
$container->register($transitionId, Workflow\Transition::class)
->setArguments([$transition['name'], $transition['from'], $transition['to']]);
$transitions[] = new Reference($transitionId);
if (isset($transition['guard'])) {
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
$configuration->addArgument(new Reference($transitionId));
$configuration->addArgument($transition['guard']);
$eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']);
$guardsConfiguration[$eventName][] = $configuration;
$eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']);
$guardsConfiguration[$eventName][] = new Definition(
Workflow\EventListener\GuardExpression::class,
[new Reference($transitionId), $transition['guard']]
);
}
if ($transition['metadata']) {
$transitionsMetadataDefinition->addMethodCall('attach', [
$transitionsMetadataDefinition->addMethodCall('offsetSet', [
new Reference($transitionId),
$transition['metadata'],
]);
@@ -990,19 +993,19 @@ class FrameworkExtension extends Extension
} elseif ('state_machine' === $type) {
foreach ($transition['from'] as $from) {
foreach ($transition['to'] as $to) {
$transitionDefinition = new Definition(Workflow\Transition::class, [$transition['name'], $from, $to]);
$transitionId = sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
$container->setDefinition($transitionId, $transitionDefinition);
$transitionId = \sprintf('.%s.transition.%s', $workflowId, $transitionCounter++);
$container->register($transitionId, Workflow\Transition::class)
->setArguments([$transition['name'], $from, $to]);
$transitions[] = new Reference($transitionId);
if (isset($transition['guard'])) {
$configuration = new Definition(Workflow\EventListener\GuardExpression::class);
$configuration->addArgument(new Reference($transitionId));
$configuration->addArgument($transition['guard']);
$eventName = sprintf('workflow.%s.guard.%s', $name, $transition['name']);
$guardsConfiguration[$eventName][] = $configuration;
$eventName = \sprintf('workflow.%s.guard.%s', $name, $transition['name']);
$guardsConfiguration[$eventName][] = new Definition(
Workflow\EventListener\GuardExpression::class,
[new Reference($transitionId), $transition['guard']]
);
}
if ($transition['metadata']) {
$transitionsMetadataDefinition->addMethodCall('attach', [
$transitionsMetadataDefinition->addMethodCall('offsetSet', [
new Reference($transitionId),
$transition['metadata'],
]);
@@ -1012,7 +1015,7 @@ class FrameworkExtension extends Extension
}
}
$metadataStoreDefinition->replaceArgument(2, $transitionsMetadataDefinition);
$container->setDefinition(sprintf('%s.metadata_store', $workflowId), $metadataStoreDefinition);
$container->setDefinition(\sprintf('%s.metadata_store', $workflowId), $metadataStoreDefinition);
// Create places
$places = array_column($workflow['places'], 'name');
@@ -1023,7 +1026,7 @@ class FrameworkExtension extends Extension
$definitionDefinition->addArgument($places);
$definitionDefinition->addArgument($transitions);
$definitionDefinition->addArgument($initialMarking);
$definitionDefinition->addArgument(new Reference(sprintf('%s.metadata_store', $workflowId)));
$definitionDefinition->addArgument(new Reference(\sprintf('%s.metadata_store', $workflowId)));
// Create MarkingStore
$markingStoreDefinition = null;
@@ -1038,8 +1041,8 @@ class FrameworkExtension extends Extension
}
// Create Workflow
$workflowDefinition = new ChildDefinition(sprintf('%s.abstract', $type));
$workflowDefinition->replaceArgument(0, new Reference(sprintf('%s.definition', $workflowId)));
$workflowDefinition = new ChildDefinition(\sprintf('%s.abstract', $type));
$workflowDefinition->replaceArgument(0, new Reference(\sprintf('%s.definition', $workflowId)));
$workflowDefinition->replaceArgument(1, $markingStoreDefinition);
$workflowDefinition->replaceArgument(3, $name);
$workflowDefinition->replaceArgument(4, $workflow['events_to_dispatch']);
@@ -1053,7 +1056,7 @@ class FrameworkExtension extends Extension
// Store to container
$container->setDefinition($workflowId, $workflowDefinition);
$container->setDefinition(sprintf('%s.definition', $workflowId), $definitionDefinition);
$container->setDefinition(\sprintf('%s.definition', $workflowId), $definitionDefinition);
$container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name.'.'.$type);
$container->registerAliasForArgument($workflowId, WorkflowInterface::class, $name);
@@ -1082,11 +1085,11 @@ class FrameworkExtension extends Extension
if ($workflow['audit_trail']['enabled']) {
$listener = new Definition(Workflow\EventListener\AuditTrailListener::class);
$listener->addTag('monolog.logger', ['channel' => 'workflow']);
$listener->addTag('kernel.event_listener', ['event' => sprintf('workflow.%s.leave', $name), 'method' => 'onLeave']);
$listener->addTag('kernel.event_listener', ['event' => sprintf('workflow.%s.transition', $name), 'method' => 'onTransition']);
$listener->addTag('kernel.event_listener', ['event' => sprintf('workflow.%s.enter', $name), 'method' => 'onEnter']);
$listener->addTag('kernel.event_listener', ['event' => \sprintf('workflow.%s.leave', $name), 'method' => 'onLeave']);
$listener->addTag('kernel.event_listener', ['event' => \sprintf('workflow.%s.transition', $name), 'method' => 'onTransition']);
$listener->addTag('kernel.event_listener', ['event' => \sprintf('workflow.%s.enter', $name), 'method' => 'onEnter']);
$listener->addArgument(new Reference('logger'));
$container->setDefinition(sprintf('.%s.listener.audit_trail', $workflowId), $listener);
$container->setDefinition(\sprintf('.%s.listener.audit_trail', $workflowId), $listener);
}
// Add Guard Listener
@@ -1114,7 +1117,7 @@ class FrameworkExtension extends Extension
$guard->addTag('kernel.event_listener', ['event' => $eventName, 'method' => 'onTransition']);
}
$container->setDefinition(sprintf('.%s.listener.guard', $workflowId), $guard);
$container->setDefinition(\sprintf('.%s.listener.guard', $workflowId), $guard);
$container->setParameter('workflow.has_guard_listeners', true);
}
}
@@ -1134,7 +1137,7 @@ class FrameworkExtension extends Extension
$tagAttributes = get_object_vars($attribute);
if ($reflector instanceof \ReflectionMethod) {
if (isset($tagAttributes['method'])) {
throw new LogicException(sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name));
throw new LogicException(\sprintf('"%s" attribute cannot declare a method on "%s::%s()".', $attribute::class, $reflector->class, $reflector->name));
}
$tagAttributes['method'] = $reflector->getName();
}
@@ -1330,7 +1333,7 @@ class FrameworkExtension extends Extension
}
}
private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled): void
private function registerAssetMapperConfiguration(array $config, ContainerBuilder $container, PhpFileLoader $loader, bool $assetEnabled, bool $httpClientEnabled): void
{
$loader->load('asset_mapper.php');
@@ -1338,10 +1341,16 @@ class FrameworkExtension extends Extension
$container->removeDefinition('asset_mapper.asset_package');
}
if (!$httpClientEnabled) {
$container->register('asset_mapper.http_client', HttpClientInterface::class)
->addTag('container.error')
->addError('You cannot use the AssetMapper integration since the HttpClient component is not enabled. Try enabling the "framework.http_client" config option.');
}
$paths = $config['paths'];
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
if ($container->fileExists($dir = $bundle['path'].'/Resources/public') || $container->fileExists($dir = $bundle['path'].'/public')) {
$paths[$dir] = sprintf('bundles/%s', preg_replace('/bundle$/', '', strtolower($name)));
$paths[$dir] = \sprintf('bundles/%s', preg_replace('/bundle$/', '', strtolower($name)));
}
}
$excludedPathPatterns = [];
@@ -1507,7 +1516,7 @@ class FrameworkExtension extends Extension
$defaultDir = $container->getParameterBag()->resolveValue($config['default_path']);
foreach ($container->getParameter('kernel.bundles_metadata') as $name => $bundle) {
if ($container->fileExists($dir = $bundle['path'].'/Resources/translations') || $container->fileExists($dir = $bundle['path'].'/translations')) {
$dirs[] = $dir;
$dirs[] = $transPaths[] = $dir;
} else {
$nonExistingDirs[] = $dir;
}
@@ -1517,7 +1526,7 @@ class FrameworkExtension extends Extension
if ($container->fileExists($dir)) {
$dirs[] = $transPaths[] = $dir;
} else {
throw new \UnexpectedValueException(sprintf('"%s" defined in translator.paths does not exist or is not a directory.', $dir));
throw new \UnexpectedValueException(\sprintf('"%s" defined in translator.paths does not exist or is not a directory.', $dir));
}
}
@@ -1601,7 +1610,7 @@ class FrameworkExtension extends Extension
foreach ($classToServices as $class => $service) {
$package = substr($service, \strlen('translation.provider_factory.'));
if (!$container->hasDefinition('http_client') || !ContainerBuilder::willBeAvailable(sprintf('symfony/%s-translation-provider', $package), $class, $parentPackages)) {
if (!$container->hasDefinition('http_client') || !ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-translation-provider', $package), $class, $parentPackages)) {
$container->removeDefinition($service);
}
}
@@ -1614,11 +1623,11 @@ class FrameworkExtension extends Extension
foreach ($config['providers'] as $provider) {
if ($provider['locales']) {
$locales += $provider['locales'];
$locales = array_merge($locales, $provider['locales']);
}
}
$locales = array_unique($locales);
$locales = array_values(array_unique($locales));
$container->getDefinition('console.command.translation_pull')
->replaceArgument(4, array_merge($transPaths, [$config['default_path']]))
@@ -1762,11 +1771,11 @@ class FrameworkExtension extends Extension
$container->addResource(new DirectoryResource($path, '/^$/'));
} elseif ($container->fileExists($path, false)) {
if (!preg_match('/\.(xml|ya?ml)$/', $path, $matches)) {
throw new \RuntimeException(sprintf('Unsupported mapping type in "%s", supported types are XML & Yaml.', $path));
throw new \RuntimeException(\sprintf('Unsupported mapping type in "%s", supported types are XML & Yaml.', $path));
}
$fileRecorder($matches[1], $path);
} else {
throw new \RuntimeException(sprintf('Could not open file or directory "%s".', $path));
throw new \RuntimeException(\sprintf('Could not open file or directory "%s".', $path));
}
}
}
@@ -1802,7 +1811,7 @@ class FrameworkExtension extends Extension
$cacheDir = $container->getParameterBag()->resolveValue($config['file_cache_dir']);
if (!is_dir($cacheDir) && false === @mkdir($cacheDir, 0777, true) && !is_dir($cacheDir)) {
throw new \RuntimeException(sprintf('Could not create cache directory "%s".', $cacheDir));
throw new \RuntimeException(\sprintf('Could not create cache directory "%s".', $cacheDir));
}
$container
@@ -1874,7 +1883,7 @@ class FrameworkExtension extends Extension
if ($config['decryption_env_var']) {
if (!preg_match('/^(?:[-.\w\\\\]*+:)*+\w++$/', $config['decryption_env_var'])) {
throw new InvalidArgumentException(sprintf('Invalid value "%s" set as "decryption_env_var": only "word" characters are allowed.', $config['decryption_env_var']));
throw new InvalidArgumentException(\sprintf('Invalid value "%s" set as "decryption_env_var": only "word" characters are allowed.', $config['decryption_env_var']));
}
if (ContainerBuilder::willBeAvailable('symfony/string', LazyString::class, ['symfony/framework-bundle'])) {
@@ -1946,7 +1955,7 @@ class FrameworkExtension extends Extension
if (isset($config['enable_attributes']) && $config['enable_attributes']) {
$annotationLoader = new Definition(
AttributeLoader::class,
[new Reference('annotation_reader', ContainerInterface::NULL_ON_INVALID_REFERENCE)]
interface_exists(CacheableSupportsMethodInterface::class) ? [new Reference('annotation_reader', ContainerInterface::NULL_ON_INVALID_REFERENCE)] : [],
);
$serializerLoaders[] = $annotationLoader;
@@ -1996,18 +2005,23 @@ class FrameworkExtension extends Extension
$container->setParameter('serializer.default_context', $defaultContext);
}
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
if ($container->hasDefinition('serializer.normalizer.object')) {
$arguments = $container->getDefinition('serializer.normalizer.object')->getArguments();
$context = ($arguments[6] ?? $defaultContext) + ['circular_reference_handler' => new Reference($config['circular_reference_handler'])];
$container->getDefinition('serializer.normalizer.object')->setArgument(5, null);
$context = $arguments[6] ?? $defaultContext;
if (isset($config['circular_reference_handler']) && $config['circular_reference_handler']) {
$context += ['circular_reference_handler' => new Reference($config['circular_reference_handler'])];
$container->getDefinition('serializer.normalizer.object')->setArgument(5, null);
}
if ($config['max_depth_handler'] ?? false) {
$context += ['max_depth_handler' => new Reference($config['max_depth_handler'])];
}
$container->getDefinition('serializer.normalizer.object')->setArgument(6, $context);
}
if ($config['max_depth_handler'] ?? false) {
$arguments = $container->getDefinition('serializer.normalizer.object')->getArguments();
$context = ($arguments[6] ?? $defaultContext) + ['max_depth_handler' => new Reference($config['max_depth_handler'])];
$container->getDefinition('serializer.normalizer.object')->setArgument(6, $context);
}
$container->getDefinition('serializer.normalizer.property')->setArgument(5, $defaultContext);
}
private function registerPropertyInfoConfiguration(ContainerBuilder $container, PhpFileLoader $loader): void
@@ -2201,16 +2215,18 @@ class FrameworkExtension extends Extension
$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)) {
@@ -2245,7 +2261,7 @@ class FrameworkExtension extends Extension
$failureTransports = [];
if ($config['failure_transport']) {
if (!isset($config['transports'][$config['failure_transport']])) {
throw new LogicException(sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $config['failure_transport']));
throw new LogicException(\sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $config['failure_transport']));
}
$container->setAlias('messenger.failure_transports.default', 'messenger.transport.'.$config['failure_transport']);
@@ -2267,14 +2283,17 @@ class FrameworkExtension extends Extension
$transportRateLimiterReferences = [];
foreach ($config['transports'] as $name => $transport) {
$serializerId = $transport['serializer'] ?? 'messenger.default_serializer';
$tags = [
'alias' => $name,
'is_failure_transport' => \in_array($name, $failureTransports),
];
if (str_starts_with($transport['dsn'], 'sync://')) {
$tags['is_consumable'] = false;
}
$transportDefinition = (new Definition(TransportInterface::class))
->setFactory([new Reference('messenger.transport_factory'), 'createTransport'])
->setArguments([$transport['dsn'], $transport['options'] + ['transport_name' => $name], new Reference($serializerId)])
->addTag('messenger.receiver', [
'alias' => $name,
'is_failure_transport' => \in_array($name, $failureTransports),
]
)
->addTag('messenger.receiver', $tags)
;
$container->setDefinition($transportId = 'messenger.transport.'.$name, $transportDefinition);
$senderAliases[$name] = $transportId;
@@ -2282,7 +2301,7 @@ class FrameworkExtension extends Extension
if (null !== $transport['retry_strategy']['service']) {
$transportRetryReferences[$name] = new Reference($transport['retry_strategy']['service']);
} else {
$retryServiceId = sprintf('messenger.retry.multiplier_retry_strategy.%s', $name);
$retryServiceId = \sprintf('messenger.retry.multiplier_retry_strategy.%s', $name);
$retryDefinition = new ChildDefinition('messenger.retry.abstract_multiplier_retry_strategy');
$retryDefinition
->replaceArgument(0, $transport['retry_strategy']['max_retries'])
@@ -2316,7 +2335,7 @@ class FrameworkExtension extends Extension
foreach ($config['transports'] as $name => $transport) {
if ($transport['failure_transport']) {
if (!isset($senderReferences[$transport['failure_transport']])) {
throw new LogicException(sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $transport['failure_transport']));
throw new LogicException(\sprintf('Invalid Messenger configuration: the failure transport "%s" is not a valid transport or service id.', $transport['failure_transport']));
}
}
}
@@ -2327,16 +2346,16 @@ class FrameworkExtension extends Extension
foreach ($config['routing'] as $message => $messageConfiguration) {
if ('*' !== $message && !class_exists($message) && !interface_exists($message, false) && !preg_match('/^(?:[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*+\\\\)++\*$/', $message)) {
if (str_contains($message, '*')) {
throw new LogicException(sprintf('Invalid Messenger routing configuration: invalid namespace "%s" wildcard.', $message));
throw new LogicException(\sprintf('Invalid Messenger routing configuration: invalid namespace "%s" wildcard.', $message));
}
throw new LogicException(sprintf('Invalid Messenger routing configuration: class or interface "%s" not found.', $message));
throw new LogicException(\sprintf('Invalid Messenger routing configuration: class or interface "%s" not found.', $message));
}
// make sure senderAliases contains all senders
foreach ($messageConfiguration['senders'] as $sender) {
if (!isset($senderReferences[$sender])) {
throw new LogicException(sprintf('Invalid Messenger routing configuration: the "%s" class is being routed to a sender called "%s". This is not a valid transport or service id.', $message, $sender));
throw new LogicException(\sprintf('Invalid Messenger routing configuration: the "%s" class is being routed to a sender called "%s". This is not a valid transport or service id.', $message, $sender));
}
}
@@ -2537,7 +2556,7 @@ class FrameworkExtension extends Extension
foreach ($config['scoped_clients'] as $name => $scopeConfig) {
if ($container->has($name)) {
throw new InvalidArgumentException(sprintf('Invalid scope name: "%s" is reserved.', $name));
throw new InvalidArgumentException(\sprintf('Invalid scope name: "%s" is reserved.', $name));
}
$scope = $scopeConfig['scope'] ?? null;
@@ -2553,11 +2572,13 @@ class FrameworkExtension extends Extension
->setFactory([ScopingHttpClient::class, 'forBaseUri'])
->setArguments([new Reference('http_client.transport'), $baseUri, $scopeConfig])
->addTag('http_client.client')
->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore'])
;
} else {
$container->register($name, ScopingHttpClient::class)
->setArguments([new Reference('http_client.transport'), [$scope => $scopeConfig], $scope])
->addTag('http_client.client')
->addTag('kernel.reset', ['method' => 'reset', 'on_invalid' => 'ignore'])
;
}
@@ -2644,7 +2665,6 @@ class FrameworkExtension extends Extension
}
$transports = $config['dsn'] ? ['main' => $config['dsn']] : $config['transports'];
$container->getDefinition('mailer.transports')->setArgument(0, $transports);
$container->getDefinition('mailer.default_transport')->setArgument(0, current($transports));
$mailer = $container->getDefinition('mailer.mailer');
if (false === $messageBus = $config['message_bus']) {
@@ -2673,7 +2693,7 @@ class FrameworkExtension extends Extension
foreach ($classToServices as $class => $service) {
$package = substr($service, \strlen('mailer.transport_factory.'));
if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) {
if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) {
$container->removeDefinition($service);
}
}
@@ -2690,7 +2710,7 @@ class FrameworkExtension extends Extension
foreach ($webhookRequestParsers as $class => $service) {
$package = substr($service, \strlen('mailer.webhook.request_parser.'));
if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) {
if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-mailer', 'gmail' === $package ? 'google' : $package), $class, ['symfony/framework-bundle', 'symfony/mailer'])) {
$container->removeDefinition($service);
}
}
@@ -2753,7 +2773,7 @@ class FrameworkExtension extends Extension
$container->removeDefinition('notifier.channel.email');
}
foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms'] as $serviceId) {
foreach (['texter', 'chatter', 'notifier.channel.chat', 'notifier.channel.email', 'notifier.channel.sms', 'notifier.channel.push'] as $serviceId) {
if (!$container->hasDefinition($serviceId)) {
continue;
}
@@ -2800,8 +2820,6 @@ class FrameworkExtension extends Extension
NotifierBridge\Engagespot\EngagespotTransportFactory::class => 'notifier.transport_factory.engagespot',
NotifierBridge\Esendex\EsendexTransportFactory::class => 'notifier.transport_factory.esendex',
NotifierBridge\Expo\ExpoTransportFactory::class => 'notifier.transport_factory.expo',
NotifierBridge\FakeChat\FakeChatTransportFactory::class => 'notifier.transport_factory.fake-chat',
NotifierBridge\FakeSms\FakeSmsTransportFactory::class => 'notifier.transport_factory.fake-sms',
NotifierBridge\Firebase\FirebaseTransportFactory::class => 'notifier.transport_factory.firebase',
NotifierBridge\FortySixElks\FortySixElksTransportFactory::class => 'notifier.transport_factory.forty-six-elks',
NotifierBridge\FreeMobile\FreeMobileTransportFactory::class => 'notifier.transport_factory.free-mobile',
@@ -2820,7 +2838,7 @@ class FrameworkExtension extends Extension
NotifierBridge\Mastodon\MastodonTransportFactory::class => 'notifier.transport_factory.mastodon',
NotifierBridge\Mattermost\MattermostTransportFactory::class => 'notifier.transport_factory.mattermost',
NotifierBridge\Mercure\MercureTransportFactory::class => 'notifier.transport_factory.mercure',
NotifierBridge\MessageBird\MessageBirdTransport::class => 'notifier.transport_factory.message-bird',
NotifierBridge\MessageBird\MessageBirdTransportFactory::class => 'notifier.transport_factory.message-bird',
NotifierBridge\MessageMedia\MessageMediaTransportFactory::class => 'notifier.transport_factory.message-media',
NotifierBridge\MicrosoftTeams\MicrosoftTeamsTransportFactory::class => 'notifier.transport_factory.microsoft-teams',
NotifierBridge\Mobyt\MobytTransportFactory::class => 'notifier.transport_factory.mobyt',
@@ -2851,7 +2869,7 @@ class FrameworkExtension extends Extension
NotifierBridge\Telegram\TelegramTransportFactory::class => 'notifier.transport_factory.telegram',
NotifierBridge\Telnyx\TelnyxTransportFactory::class => 'notifier.transport_factory.telnyx',
NotifierBridge\Termii\TermiiTransportFactory::class => 'notifier.transport_factory.termii',
NotifierBridge\TurboSms\TurboSmsTransport::class => 'notifier.transport_factory.turbo-sms',
NotifierBridge\TurboSms\TurboSmsTransportFactory::class => 'notifier.transport_factory.turbo-sms',
NotifierBridge\Twilio\TwilioTransportFactory::class => 'notifier.transport_factory.twilio',
NotifierBridge\Twitter\TwitterTransportFactory::class => 'notifier.transport_factory.twitter',
NotifierBridge\Vonage\VonageTransportFactory::class => 'notifier.transport_factory.vonage',
@@ -2865,34 +2883,40 @@ class FrameworkExtension extends Extension
foreach ($classToServices as $class => $service) {
$package = substr($service, \strlen('notifier.transport_factory.'));
if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-notifier', $package), $class, $parentPackages)) {
if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-notifier', $package), $class, $parentPackages)) {
$container->removeDefinition($service);
}
}
if (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', NotifierBridge\Mercure\MercureTransportFactory::class, $parentPackages) && ContainerBuilder::willBeAvailable('symfony/mercure-bundle', MercureBundle::class, $parentPackages) && \in_array(MercureBundle::class, $container->getParameter('kernel.bundles'), true)) {
$container->getDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class])
->replaceArgument('$registry', new Reference(HubRegistry::class))
->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
->replaceArgument(0, new Reference(HubRegistry::class))
->replaceArgument(1, new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
} elseif (ContainerBuilder::willBeAvailable('symfony/mercure-notifier', NotifierBridge\Mercure\MercureTransportFactory::class, $parentPackages)) {
$container->removeDefinition($classToServices[NotifierBridge\Mercure\MercureTransportFactory::class]);
}
if (ContainerBuilder::willBeAvailable('symfony/fake-chat-notifier', NotifierBridge\FakeChat\FakeChatTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) {
$container->getDefinition($classToServices[NotifierBridge\FakeChat\FakeChatTransportFactory::class])
->replaceArgument('$mailer', new Reference('mailer'))
->replaceArgument('$logger', new Reference('logger'))
->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
// don't use ContainerBuilder::willBeAvailable() as these are not needed in production
if (class_exists(FakeChatTransportFactory::class)) {
$container->getDefinition('notifier.transport_factory.fake-chat')
->replaceArgument(0, new Reference('mailer', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->replaceArgument(1, new Reference('logger', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->addArgument(new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
} else {
$container->removeDefinition('notifier.transport_factory.fake-chat');
}
if (ContainerBuilder::willBeAvailable('symfony/fake-sms-notifier', NotifierBridge\FakeSms\FakeSmsTransportFactory::class, ['symfony/framework-bundle', 'symfony/notifier', 'symfony/mailer'])) {
$container->getDefinition($classToServices[NotifierBridge\FakeSms\FakeSmsTransportFactory::class])
->replaceArgument('$mailer', new Reference('mailer'))
->replaceArgument('$logger', new Reference('logger'))
->replaceArgument('$client', new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->replaceArgument('$dispatcher', new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
// don't use ContainerBuilder::willBeAvailable() as these are not needed in production
if (class_exists(FakeSmsTransportFactory::class)) {
$container->getDefinition('notifier.transport_factory.fake-sms')
->replaceArgument(0, new Reference('mailer', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->replaceArgument(1, new Reference('logger', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->addArgument(new Reference('event_dispatcher', ContainerBuilder::NULL_ON_INVALID_REFERENCE))
->addArgument(new Reference('http_client', ContainerBuilder::NULL_ON_INVALID_REFERENCE));
} else {
$container->removeDefinition('notifier.transport_factory.fake-sms');
}
if (isset($config['admin_recipients'])) {
@@ -2915,7 +2939,7 @@ class FrameworkExtension extends Extension
foreach ($webhookRequestParsers as $class => $service) {
$package = substr($service, \strlen('notifier.webhook.request_parser.'));
if (!ContainerBuilder::willBeAvailable(sprintf('symfony/%s-notifier', $package), $class, ['symfony/framework-bundle', 'symfony/notifier'])) {
if (!ContainerBuilder::willBeAvailable(\sprintf('symfony/%s-notifier', $package), $class, ['symfony/framework-bundle', 'symfony/notifier'])) {
$container->removeDefinition($service);
}
}
@@ -2964,11 +2988,11 @@ class FrameworkExtension extends Extension
if (null !== $limiterConfig['lock_factory']) {
if (!interface_exists(LockInterface::class)) {
throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name));
throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name));
}
if (!$this->isInitializedConfigEnabled('lock')) {
throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name));
throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name));
}
$limiter->replaceArgument(2, new Reference($limiterConfig['lock_factory']));
@@ -3005,10 +3029,10 @@ class FrameworkExtension extends Extension
if (null !== $limiterConfig['lock_factory']) {
if (!interface_exists(LockInterface::class)) {
throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name));
throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be installed. Try running "composer require symfony/lock".', $name));
}
if (!$container->hasDefinition('lock.factory.abstract')) {
throw new LogicException(sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name));
throw new LogicException(\sprintf('Rate limiter "%s" requires the Lock component to be configured.', $name));
}
$limiter->replaceArgument(2, new Reference($limiterConfig['lock_factory']));
@@ -3173,7 +3197,7 @@ class FrameworkExtension extends Extension
return $this->configsEnabled[$path];
}
throw new LogicException(sprintf('Can not read config enabled at "%s" because it has not been initialized.', $path));
throw new LogicException(\sprintf('Can not read config enabled at "%s" because it has not been initialized.', $path));
}
private function readConfigEnabled(string $path, ContainerBuilder $container, array $config): bool