From 2280082408686af9993136e2775f28bd1b61e5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 20 Nov 2025 19:32:22 +0100 Subject: [PATCH 1/7] Add support for the buitin Hub provided by FrankenPHP --- composer.json | 8 +- src/DependencyInjection/Configuration.php | 23 ++- src/DependencyInjection/MercureExtension.php | 149 ++++++++++-------- .../MercureExtensionTest.php | 7 +- 4 files changed, 111 insertions(+), 76 deletions(-) diff --git a/composer.json b/composer.json index b356f8d..a2ddd01 100644 --- a/composer.json +++ b/composer.json @@ -5,6 +5,12 @@ "keywords": ["mercure", "push", "sse", "updates"], "homepage": "https://symfony.com", "license": "MIT", + "repositories": [ + { + "type": "path", + "url": "../symfony-mercure" + } + ], "authors": [ { "name": "Kévin Dunglas", @@ -21,7 +27,7 @@ "symfony/config": "^6.4|^7.3|^8.0", "symfony/dependency-injection": "^6.4|^7.3|^8.0", "symfony/http-kernel": "^6.4|^7.3|^8.0", - "symfony/mercure": "^0.6.1", + "symfony/mercure": "*", "symfony/web-link": "^6.4|^7.3|^8.0" }, "autoload": { diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index ee39bac..80ea99e 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -25,9 +25,12 @@ final class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { + $builtinPublish = function_exists('mercure_publish'); + $treeBuilder = new TreeBuilder('mercure'); $rootNode = $treeBuilder->getRootNode(); - $rootNode + + $urlNode = $rootNode ->fixXmlConfig('hub') ->children() ->arrayNode('hubs') @@ -35,8 +38,20 @@ public function getConfigTreeBuilder(): TreeBuilder ->normalizeKeys(false) ->arrayPrototype() ->children() - ->scalarNode('url')->info('URL of the hub\'s publish endpoint')->example('https://demo.mercure.rocks/.well-known/mercure')->end() - ->scalarNode('public_url')->info('URL of the hub\'s public endpoint')->example('https://demo.mercure.rocks/.well-known/mercure')->defaultNull()->end() + ->scalarNode('url')->info('URL of the hub\'s publish endpoint')->example('https://demo.mercure.rocks/.well-known/mercure'); + + if ($builtinPublish) { + $urlNode->defaultNull(); + } + + $publicUrlNode = $urlNode->end() + ->scalarNode('public_url')->info('URL of the hub\'s public endpoint')->example('https://demo.mercure.rocks/.well-known/mercure'); + + if (!$builtinPublish) { + $publicUrlNode->defaultNull(); + } + + $publicUrlNode->end() ->arrayNode('jwt') ->beforeNormalization() ->ifString() @@ -77,7 +92,7 @@ public function getConfigTreeBuilder(): TreeBuilder ->thenInvalid('"jwt" and "jwt_provider" cannot be used together.') ->end() ->validate() - ->ifTrue(function ($v) { return !isset($v['jwt']) && !isset($v['jwt_provider']); }) + ->ifTrue(function ($v) { return isset($v['url']) && !isset($v['jwt']) && !isset($v['jwt_provider']); }) ->thenInvalid('You must specify at least one of "jwt", and "jwt_provider".') ->end() ->validate() diff --git a/src/DependencyInjection/MercureExtension.php b/src/DependencyInjection/MercureExtension.php index b1adb26..9327e08 100644 --- a/src/DependencyInjection/MercureExtension.php +++ b/src/DependencyInjection/MercureExtension.php @@ -28,6 +28,7 @@ use Symfony\Component\Mercure\Debug\TraceablePublisher; use Symfony\Component\Mercure\Discovery; use Symfony\Component\Mercure\EventSubscriber\SetCookieSubscriber; +use Symfony\Component\Mercure\FrankenPhpHub; use Symfony\Component\Mercure\Hub; use Symfony\Component\Mercure\HubInterface; use Symfony\Component\Mercure\HubRegistry; @@ -66,23 +67,22 @@ public function load(array $configs, ContainerBuilder $container): void $defaultPublisher = null; $defaultHubId = null; - $hubUrls = []; $traceableHubs = []; $hubs = []; - $defaultHubUrl = null; $defaultHubName = null; $enableProfiler = ($config['enable_profiler'] ?? $container->getParameter('kernel.debug')) && class_exists(Stopwatch::class); foreach ($config['hubs'] as $name => $hub) { + $builtinHub = !isset($hub['url']); + $tokenFactory = null; + $tokenProvider = null; if (isset($hub['jwt'])) { - $tokenProvider = null; if (isset($hub['jwt']['value'])) { $tokenProvider = \sprintf('mercure.hub.%s.jwt.provider', $name); $container->register($tokenProvider, StaticTokenProvider::class) ->addArgument($hub['jwt']['value']) - ->addTag('mercure.jwt.provider') - ; + ->addTag('mercure.jwt.provider'); // TODO: remove the following definition in 0.4 $jwtProvider = \sprintf('mercure.hub.%s.jwt_provider', $name); @@ -106,14 +106,12 @@ public function load(array $configs, ContainerBuilder $container): void ->addArgument($hub['jwt']['algorithm']) ->addArgument(null) ->addArgument($hub['jwt']['passphrase']) - ->addTag('mercure.jwt.factory') - ; + ->addTag('mercure.jwt.factory'); } $container->register('.lazy.'.$tokenFactory, TokenFactoryInterface::class) ->setFactory(['Closure', 'fromCallable']) - ->addArgument([new Reference($tokenFactory), 'create']) - ; + ->addArgument([new Reference($tokenFactory), 'create']); $tokenFactory = '.lazy.'.$tokenFactory; $tokenProvider = \sprintf('mercure.hub.%s.jwt.provider', $name); @@ -121,71 +119,81 @@ public function load(array $configs, ContainerBuilder $container): void ->addArgument(new Reference($tokenFactory)) ->addArgument($hub['jwt']['subscribe'] ?? []) ->addArgument($hub['jwt']['publish'] ?? []) - ->addTag('mercure.jwt.factory') - ; + ->addTag('mercure.jwt.factory'); $container->registerAliasForArgument($tokenFactory, TokenFactoryInterface::class, $name); $container->registerAliasForArgument($tokenFactory, TokenFactoryInterface::class, "{$name}Factory"); - $container->registerAliasForArgument($tokenFactory, TokenFactoryInterface::class, "{$name}TokenFactory"); + $container->registerAliasForArgument( + $tokenFactory, + TokenFactoryInterface::class, + "{$name}TokenFactory" + ); } - } else { + } elseif (isset($hub['jwt_provider'])) { $jwtProvider = $hub['jwt_provider']; $tokenProvider = \sprintf('mercure.hub.%s.jwt.provider', $name); $container->register($tokenProvider, CallableTokenProvider::class) ->addArgument(new Reference($jwtProvider)) - ->addTag('mercure.jwt.provider') - ; + ->addTag('mercure.jwt.provider'); } - $container->registerAliasForArgument($tokenProvider, TokenProviderInterface::class, $name); - $container->registerAliasForArgument($tokenProvider, TokenProviderInterface::class, "{$name}Provider"); - $container->registerAliasForArgument($tokenProvider, TokenProviderInterface::class, "{$name}TokenProvider"); + if (null !== $tokenProvider) { + $container->registerAliasForArgument($tokenProvider, TokenProviderInterface::class, $name); + $container->registerAliasForArgument($tokenProvider, TokenProviderInterface::class, "{$name}Provider"); + $container->registerAliasForArgument($tokenProvider, TokenProviderInterface::class, "{$name}TokenProvider"); + } - $hubUrls[$name] = $hub['url']; $hubId = \sprintf('mercure.hub.%s', $name); $publisherId = \sprintf('mercure.hub.%s.publisher', $name); $hubs[$name] = new Reference($hubId); if (!$defaultPublisher && ($config['default_hub'] ?? $name) === $name) { $defaultHubName = $name; $defaultHubId = $hubId; - $defaultHubUrl = $hub['url']; $defaultPublisher = $publisherId; } - $container->register($hubId, Hub::class) - ->addArgument($hub['url']) - ->addArgument(new Reference($tokenProvider)) - ->addArgument($tokenFactory ? new Reference($tokenFactory) : null) - ->addArgument($hub['public_url']) - ->addArgument(new Reference('http_client', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) - ->addTag('mercure.hub') - ; - - $container->registerAliasForArgument($hubId, HubInterface::class, "{$name}Hub"); - $container->registerAliasForArgument($hubId, HubInterface::class, $name); - - $publisherDefinition = $container->register($publisherId, Publisher::class) - ->addArgument($hub['url']) - ->addArgument(new Reference($tokenProvider)) - ->addArgument(new Reference('http_client', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) - ->addTag('mercure.publisher') - ; - - $this->deprecate( - $publisherDefinition, - 'The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future, use "'.$hubId.'" instead.' - ); + if ($builtinHub) { + $container->register($hubId, FrankenPhpHub::class) + ->addArgument($hub['public_url']) + ->addArgument($tokenFactory ? new Reference($tokenFactory) : null) + ->addTag('mercure.hub'); - $this->deprecate( - $container->registerAliasForArgument($publisherId, PublisherInterface::class, "{$name}Publisher"), - 'The "%alias_id%" service is deprecated. You should stop using it, as it will be removed in the future, use "'.$hubId.'" instead.' - ); + } else { + $container->register($hubId, Hub::class) + ->addArgument($hub['url']) + ->addArgument(new Reference($tokenProvider)) + ->addArgument($tokenFactory ? new Reference($tokenFactory) : null) + ->addArgument($hub['public_url']) + ->addArgument(new Reference('http_client', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) + ->addTag('mercure.hub'); + } - $this->deprecate( - $container->registerAliasForArgument($publisherId, PublisherInterface::class, $name), - 'The "%alias_id%" service is deprecated. You should stop using it, as it will be removed in the future, use "'.$hubId.'" instead.' - ); + if (!$builtinHub) { + $container->registerAliasForArgument($hubId, HubInterface::class, "{$name}Hub"); + $container->registerAliasForArgument($hubId, HubInterface::class, $name); + + $publisherDefinition = $container->register($publisherId, Publisher::class) + ->addArgument($hub['url']) + ->addArgument(new Reference($tokenProvider)) + ->addArgument(new Reference('http_client', ContainerInterface::IGNORE_ON_INVALID_REFERENCE)) + ->addTag('mercure.publisher'); + + $this->deprecate( + $publisherDefinition, + 'The "%service_id%" service is deprecated. You should stop using it, as it will be removed in the future, use "'.$hubId.'" instead.' + ); + + $this->deprecate( + $container->registerAliasForArgument($publisherId, PublisherInterface::class, "{$name}Publisher"), + 'The "%alias_id%" service is deprecated. You should stop using it, as it will be removed in the future, use "'.$hubId.'" instead.' + ); + + $this->deprecate( + $container->registerAliasForArgument($publisherId, PublisherInterface::class, $name), + 'The "%alias_id%" service is deprecated. You should stop using it, as it will be removed in the future, use "'.$hubId.'" instead.' + ); + } $bus = $hub['bus'] ?? null; $attributes = null === $bus ? [] : ['bus' => $hub['bus']]; @@ -196,14 +204,19 @@ public function load(array $configs, ContainerBuilder $container): void ->addTag('messenger.message_handler', $attributes); if ($enableProfiler) { - $traceablePublisher = $container->register("$publisherId.traceable", TraceablePublisher::class) - ->setDecoratedService($publisherId) - ->addArgument(new Reference("$publisherId.traceable.inner")) - ->addArgument(new Reference('debug.stopwatch')); + if (!$builtinHub) { + $traceablePublisher = $container->register("$publisherId.traceable", TraceablePublisher::class) + ->setDecoratedService($publisherId) + ->addArgument(new Reference("$publisherId.traceable.inner")) + ->addArgument(new Reference('debug.stopwatch')); - $this->deprecate($traceablePublisher, 'The "%service_id%" service is deprecated. Use "'.$hubId.'.traceable" instead.'); + $this->deprecate( + $traceablePublisher, + 'The "%service_id%" service is deprecated. Use "'.$hubId.'.traceable" instead.' + ); - $traceableHubs[$name] = new Reference("$publisherId.traceable"); + $traceableHubs[$name] = new Reference("$publisherId.traceable"); + } $container->register("$hubId.traceable", TraceableHub::class) ->setDecoratedService($hubId) @@ -245,15 +258,17 @@ public function load(array $configs, ContainerBuilder $container): void $container->setAlias(HubInterface::class, $defaultHubId); - $this->deprecate( - $container->setAlias(Publisher::class, $defaultPublisher), - 'The "%alias_id%" service alias is deprecated. Use "'.Hub::class.'" instead.' - ); + if (null !== $defaultPublisher) { + $this->deprecate( + $container->setAlias(Publisher::class, $defaultPublisher), + 'The "%alias_id%" service alias is deprecated. Use "'.Hub::class.'" instead.' + ); - $this->deprecate( - $container->setAlias(PublisherInterface::class, $defaultPublisher), - 'The "%alias_id%" service alias is deprecated. Use "'.HubInterface::class.'" instead.' - ); + $this->deprecate( + $container->setAlias(PublisherInterface::class, $defaultPublisher), + 'The "%alias_id%" service alias is deprecated. Use "'.HubInterface::class.'" instead.' + ); + } $container->register(HubRegistry::class) ->addArgument(new Reference($defaultHubId)) @@ -279,10 +294,6 @@ public function load(array $configs, ContainerBuilder $container): void ->setArguments([new Reference(HubRegistry::class), new Reference(Authorization::class), new Reference('request_stack')]) ->addTag('twig.extension'); } - - // TODO: remove these parameters in the next release. - $container->setParameter('mercure.hubs', $hubUrls); - $container->setParameter('mercure.default_hub', $defaultHubUrl); } /** diff --git a/tests/DependencyInjection/MercureExtensionTest.php b/tests/DependencyInjection/MercureExtensionTest.php index 8e711e4..ed36c57 100644 --- a/tests/DependencyInjection/MercureExtensionTest.php +++ b/tests/DependencyInjection/MercureExtensionTest.php @@ -198,8 +198,6 @@ public function testExtensionLegacy() $this->assertSame('https://demo.mercure.rocks/hub', $container->getDefinition('mercure.hub.default')->getArgument(0)); $this->assertArrayHasKey('mercure.publisher', $container->getDefinition('mercure.hub.default.publisher')->getTags()); $this->assertSame('eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.e30.HB0k08BaV8KlLZ3EafCRlTDGbkd9qdznCzJQ_l8ELTU', $container->getDefinition('mercure.hub.default.jwt_provider')->getArgument(0)); - $this->assertSame(['default' => 'https://demo.mercure.rocks/hub', 'managed' => 'https://demo.mercure.rocks/managed'], $container->getParameter('mercure.hubs')); - $this->assertSame('https://demo.mercure.rocks/hub', $container->getParameter('mercure.default_hub')); $this->assertArrayHasKey('Symfony\Component\Mercure\PublisherInterface $defaultPublisher', $container->getAliases()); $this->assertArrayHasKey('Symfony\Component\Mercure\PublisherInterface $managedPublisher', $container->getAliases()); @@ -212,4 +210,9 @@ public function testExtensionLegacy() $this->assertSame($config['mercure']['hubs'][0]['url'], $registry->getHub('default')->getUrl()); $this->assertSame($config['mercure']['hubs'][1]['url'], $registry->getHub('managed')->getUrl()); } + + public function testExtensionBuiltin() + { + + } } From 1e3ca060650362890f71a014dfbe63b7426cc38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 20 Nov 2025 19:37:42 +0100 Subject: [PATCH 2/7] cs --- src/DependencyInjection/Configuration.php | 104 +++++++++--------- src/DependencyInjection/MercureExtension.php | 1 - .../MercureExtensionTest.php | 1 - 3 files changed, 52 insertions(+), 54 deletions(-) diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index 80ea99e..d1c5259 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -25,7 +25,7 @@ final class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { - $builtinPublish = function_exists('mercure_publish'); + $builtinPublish = \function_exists('mercure_publish'); $treeBuilder = new TreeBuilder('mercure'); $rootNode = $treeBuilder->getRootNode(); @@ -40,68 +40,68 @@ public function getConfigTreeBuilder(): TreeBuilder ->children() ->scalarNode('url')->info('URL of the hub\'s publish endpoint')->example('https://demo.mercure.rocks/.well-known/mercure'); - if ($builtinPublish) { - $urlNode->defaultNull(); - } + if ($builtinPublish) { + $urlNode->defaultNull(); + } - $publicUrlNode = $urlNode->end() - ->scalarNode('public_url')->info('URL of the hub\'s public endpoint')->example('https://demo.mercure.rocks/.well-known/mercure'); + $publicUrlNode = $urlNode->end() + ->scalarNode('public_url')->info('URL of the hub\'s public endpoint')->example('https://demo.mercure.rocks/.well-known/mercure'); - if (!$builtinPublish) { - $publicUrlNode->defaultNull(); - } + if (!$builtinPublish) { + $publicUrlNode->defaultNull(); + } - $publicUrlNode->end() - ->arrayNode('jwt') - ->beforeNormalization() - ->ifString() - ->then(static function (string $token): array { - return [ - 'value' => $token, - ]; - }) - ->end() - ->info('JSON Web Token configuration.') - ->children() - ->scalarNode('value')->info('JSON Web Token to use to publish to this hub.')->end() - ->scalarNode('provider')->info('The ID of a service to call to provide the JSON Web Token.')->end() - ->scalarNode('factory')->info('The ID of a service to call to create the JSON Web Token.')->end() - ->arrayNode('publish') - ->beforeNormalization()->castToArray()->end() - ->scalarPrototype()->end() - ->info('A list of topics to allow publishing to when using the given factory to generate the JWT.') - ->end() - ->arrayNode('subscribe') - ->beforeNormalization()->castToArray()->end() - ->scalarPrototype()->end() - ->info('A list of topics to allow subscribing to when using the given factory to generate the JWT.') - ->end() - ->scalarNode('secret')->info('The JWT Secret to use.')->example('!ChangeMe!')->end() - ->scalarNode('passphrase')->info('The JWT secret passphrase.')->defaultValue('')->end() - ->scalarNode('algorithm')->info('The algorithm to use to sign the JWT')->defaultValue('hmac.sha256')->end() - ->end() - ->end() - ->scalarNode('jwt_provider') - ->info('The ID of a service to call to generate the JSON Web Token.') - ->setDeprecated('symfony/mercure-bundle', '0.3', 'The child node "%node%" at path "%path%" is deprecated, use "jwt.provider" instead.') - ->end() - ->scalarNode('bus')->info('Name of the Messenger bus where the handler for this hub must be registered. Default to the default bus if Messenger is enabled.')->end() + $publicUrlNode->end() + ->arrayNode('jwt') + ->beforeNormalization() + ->ifString() + ->then(static function (string $token): array { + return [ + 'value' => $token, + ]; + }) + ->end() + ->info('JSON Web Token configuration.') + ->children() + ->scalarNode('value')->info('JSON Web Token to use to publish to this hub.')->end() + ->scalarNode('provider')->info('The ID of a service to call to provide the JSON Web Token.')->end() + ->scalarNode('factory')->info('The ID of a service to call to create the JSON Web Token.')->end() + ->arrayNode('publish') + ->beforeNormalization()->castToArray()->end() + ->scalarPrototype()->end() + ->info('A list of topics to allow publishing to when using the given factory to generate the JWT.') + ->end() + ->arrayNode('subscribe') + ->beforeNormalization()->castToArray()->end() + ->scalarPrototype()->end() + ->info('A list of topics to allow subscribing to when using the given factory to generate the JWT.') + ->end() + ->scalarNode('secret')->info('The JWT Secret to use.')->example('!ChangeMe!')->end() + ->scalarNode('passphrase')->info('The JWT secret passphrase.')->defaultValue('')->end() + ->scalarNode('algorithm')->info('The algorithm to use to sign the JWT')->defaultValue('hmac.sha256')->end() + ->end() + ->end() + ->scalarNode('jwt_provider') + ->info('The ID of a service to call to generate the JSON Web Token.') + ->setDeprecated('symfony/mercure-bundle', '0.3', 'The child node "%node%" at path "%path%" is deprecated, use "jwt.provider" instead.') + ->end() + ->scalarNode('bus')->info('Name of the Messenger bus where the handler for this hub must be registered. Default to the default bus if Messenger is enabled.')->end() ->end() ->validate() - ->ifTrue(function ($v) { return isset($v['jwt'], $v['jwt_provider']); }) - ->thenInvalid('"jwt" and "jwt_provider" cannot be used together.') + ->ifTrue(function ($v) { return isset($v['jwt'], $v['jwt_provider']); }) + ->thenInvalid('"jwt" and "jwt_provider" cannot be used together.') ->end() ->validate() - ->ifTrue(function ($v) { return isset($v['url']) && !isset($v['jwt']) && !isset($v['jwt_provider']); }) - ->thenInvalid('You must specify at least one of "jwt", and "jwt_provider".') + ->ifTrue(function ($v) { return isset($v['url']) && !isset($v['jwt']) && !isset($v['jwt_provider']); }) + ->thenInvalid('You must specify at least one of "jwt", and "jwt_provider".') ->end() ->validate() - ->ifTrue(function ($v) { return isset($v['jwt']['value'], $v['jwt']['provider']); }) - ->thenInvalid('"jwt.value" and "jwt.provider" cannot be used together.') + ->ifTrue(function ($v) { return isset($v['jwt']['value'], $v['jwt']['provider']); }) + ->thenInvalid('"jwt.value" and "jwt.provider" cannot be used together.') ->end() ->validate() - ->ifTrue(function ($v) { return isset($v['jwt']) && !isset($v['jwt']['value']) && !isset($v['jwt']['provider']) && !isset($v['jwt']['factory']) && !isset($v['jwt']['secret']); }) - ->thenInvalid('You must specify at least one of "jwt.value", "jwt.provider", "jwt.factory", and "jwt.secret".') + ->ifTrue(function ($v) { return isset($v['jwt']) && !isset($v['jwt']['value']) && !isset($v['jwt']['provider']) && !isset($v['jwt']['factory']) && !isset($v['jwt']['secret']); }) + ->thenInvalid('You must specify at least one of "jwt.value", "jwt.provider", "jwt.factory", and "jwt.secret".') ->end() ->end() ->end() diff --git a/src/DependencyInjection/MercureExtension.php b/src/DependencyInjection/MercureExtension.php index 9327e08..83372ca 100644 --- a/src/DependencyInjection/MercureExtension.php +++ b/src/DependencyInjection/MercureExtension.php @@ -158,7 +158,6 @@ public function load(array $configs, ContainerBuilder $container): void ->addArgument($hub['public_url']) ->addArgument($tokenFactory ? new Reference($tokenFactory) : null) ->addTag('mercure.hub'); - } else { $container->register($hubId, Hub::class) ->addArgument($hub['url']) diff --git a/tests/DependencyInjection/MercureExtensionTest.php b/tests/DependencyInjection/MercureExtensionTest.php index ed36c57..e4c7cee 100644 --- a/tests/DependencyInjection/MercureExtensionTest.php +++ b/tests/DependencyInjection/MercureExtensionTest.php @@ -213,6 +213,5 @@ public function testExtensionLegacy() public function testExtensionBuiltin() { - } } From 7ab58f12bb3693ab7af281cda22f7cc52a3bcbe3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 21 Nov 2025 11:37:27 +0100 Subject: [PATCH 3/7] test version --- src/DependencyInjection/Configuration.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php index d1c5259..181a609 100644 --- a/src/DependencyInjection/Configuration.php +++ b/src/DependencyInjection/Configuration.php @@ -15,6 +15,7 @@ use Symfony\Component\Config\Definition\Builder\TreeBuilder; use Symfony\Component\Config\Definition\ConfigurationInterface; +use Symfony\Component\Mercure\FrankenPhpHub; /** * MercureExtension configuration structure. @@ -25,7 +26,7 @@ final class Configuration implements ConfigurationInterface { public function getConfigTreeBuilder(): TreeBuilder { - $builtinPublish = \function_exists('mercure_publish'); + $builtinPublish = class_exists(FrankenPhpHub::class) && \function_exists('mercure_publish'); $treeBuilder = new TreeBuilder('mercure'); $rootNode = $treeBuilder->getRootNode(); From 027ccd6935fb4f9685821aa7f2f9f621537efd26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 21 Nov 2025 11:38:34 +0100 Subject: [PATCH 4/7] remove local repo config --- composer.json | 6 ------ 1 file changed, 6 deletions(-) diff --git a/composer.json b/composer.json index a2ddd01..04ccbd4 100644 --- a/composer.json +++ b/composer.json @@ -5,12 +5,6 @@ "keywords": ["mercure", "push", "sse", "updates"], "homepage": "https://symfony.com", "license": "MIT", - "repositories": [ - { - "type": "path", - "url": "../symfony-mercure" - } - ], "authors": [ { "name": "Kévin Dunglas", From a63454acc1c96babb88c0d08ccc4b526c54d0a56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 21 Nov 2025 11:51:39 +0100 Subject: [PATCH 5/7] add test --- .../MercureExtensionTest.php | 27 +++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/tests/DependencyInjection/MercureExtensionTest.php b/tests/DependencyInjection/MercureExtensionTest.php index e4c7cee..831524e 100644 --- a/tests/DependencyInjection/MercureExtensionTest.php +++ b/tests/DependencyInjection/MercureExtensionTest.php @@ -17,6 +17,8 @@ use Symfony\Bundle\MercureBundle\DependencyInjection\MercureExtension; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\ParameterBag\ParameterBag; +use Symfony\Component\Mercure\FrankenPhpHub; +use Symfony\Component\Mercure\Hub; use Symfony\Component\Mercure\HubRegistry; /** @@ -213,5 +215,30 @@ public function testExtensionLegacy() public function testExtensionBuiltin() { + if (!class_exists(FrankenPhpHub::class)) { + $this->markTestSkipped('FrankenPhpHub is not available (old version of symfony/mercure).'); + } + + $config = [ + 'mercure' => [ + 'hubs' => [ + [ + 'name' => 'default', + 'public_url' => 'https://demo.mercure.rocks/hub', + ], + ], + ], + ]; + + $container = new ContainerBuilder(new ParameterBag(['kernel.debug' => false])); + (new MercureExtension())->load($config, $container); + + $this->assertTrue($container->hasDefinition('mercure.hub.default')); + $this->assertSame(FrankenPhpHub::class, $container->getDefinition('mercure.hub.default')->getClass()); } } + +// Stub for mercure_publish() +if (!function_exists('mercure_publish')) { + function mercure_publish() {} +} From 3a2e0f4c1831b76ec5556bd04292475e5da7e599 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 21 Nov 2025 11:53:22 +0100 Subject: [PATCH 6/7] cs --- tests/DependencyInjection/MercureExtensionTest.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/tests/DependencyInjection/MercureExtensionTest.php b/tests/DependencyInjection/MercureExtensionTest.php index 831524e..c981415 100644 --- a/tests/DependencyInjection/MercureExtensionTest.php +++ b/tests/DependencyInjection/MercureExtensionTest.php @@ -239,6 +239,7 @@ public function testExtensionBuiltin() } // Stub for mercure_publish() -if (!function_exists('mercure_publish')) { - function mercure_publish() {} +if (!\function_exists('mercure_publish')) { + function mercure_publish() { + } } From 4e3e49a0c2ef96b6c0e9685e4ab94547bb03cb6f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Fri, 21 Nov 2025 11:56:35 +0100 Subject: [PATCH 7/7] cs --- tests/DependencyInjection/MercureExtensionTest.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/DependencyInjection/MercureExtensionTest.php b/tests/DependencyInjection/MercureExtensionTest.php index c981415..54fc4ba 100644 --- a/tests/DependencyInjection/MercureExtensionTest.php +++ b/tests/DependencyInjection/MercureExtensionTest.php @@ -240,6 +240,7 @@ public function testExtensionBuiltin() // Stub for mercure_publish() if (!\function_exists('mercure_publish')) { - function mercure_publish() { + function mercure_publish() + { } }