diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php deleted file mode 100644 index 27b37e0..0000000 --- a/src/DependencyInjection/Configuration.php +++ /dev/null @@ -1,60 +0,0 @@ -getRootNode(); - - /** @psalm-suppress UndefinedMethod */ - $rootNode - ->children() - ->scalarNode('http_client') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('request_factory') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('stream_factory') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('api_token') - ->isRequired() - ->cannotBeEmpty() - ->end() - ->scalarNode('secret_token') - ->defaultNull() - ->end() - ->arrayNode('allowed_updates') - ->prototype('scalar')->end() - ->beforeNormalization() - ->always(fn ($values) => array_map(strval(...), $values)) - ->end() - ->validate() - ->ifTrue(fn ($configArray) => array_diff($configArray, Update::getUpdateTypes()) !== []) - ->then(function ($configArray) { - if (array_diff($configArray, Update::getUpdateTypes()) !== []) { - $allowedKeys = implode(', ', Update::getUpdateTypes()); - throw new \InvalidArgumentException(sprintf('Invalid updates list. Allowed updates: %s', $allowedKeys)); - } - return $configArray; - }) - ->end() - ->end() - ->end(); - - return $treeBuilder; - } -} diff --git a/src/DependencyInjection/TelegramBotExtension.php b/src/DependencyInjection/TelegramBotExtension.php deleted file mode 100644 index 4da4e63..0000000 --- a/src/DependencyInjection/TelegramBotExtension.php +++ /dev/null @@ -1,126 +0,0 @@ -getConfiguration($configs, $container); - $config = $this->processConfiguration($configuration, $configs); - - $container - ->autowire(BotApi::class) - ->setArgument('$requestFactory', new Reference($config['request_factory'])) - ->setArgument('$streamFactory', new Reference($config['stream_factory'])) - ->setArgument('$client', new Reference($config['http_client'])) - ->setArgument('$token', $config['api_token']) - ; - - $container - ->register('telegram_bot.client_api', ClientApi::class) - ; - - $container - ->register('telegram_bot.webhook_controller', WebHookController::class) - ->setArgument('$updateHandler', new Reference('telegram_bot.update_handler')) - ->setArgument('$secretToken', $config['secret_token']) - ->addTag('controller.service_arguments') - ; - - $container - ->register('telegram_bot.long_polling_service', LongPollingService::class) - ->setArgument('$botApi', new Reference(BotApi::class)) - ->setArgument('$allowedUpdates', $config['allowed_updates']) - ; - - $container - ->register('telegram_bot.set_webhook_command', SetWebhookCommand::class) - ->setArgument('$botApi', new Reference(BotApi::class)) - ->setArgument('$secretToken', $config['secret_token']) - ->setArgument('$allowedUpdates', $config['allowed_updates']) - ->addTag('console.command') - ; - - $container - ->register('telegram_bot.get_webhook_command', WebhookInfoCommand::class) - ->setArgument('$botApi', new Reference(BotApi::class)) - ->addTag('console.command') - ; - - $container - ->register('telegram_bot.delete_webhook_command', DeleteWebhookCommand::class) - ->setArgument('$botApi', new Reference(BotApi::class)) - ->addTag('console.command') - ; - - $container - ->register('telegram_bot.polling_command', PolllingStartCommand::class) - ->setArgument('$longPollingService', new Reference('telegram_bot.long_polling_service')) - ->setArgument('$updateHandler', new Reference('telegram_bot.update_handler')) - ->setArgument('$botApi', new Reference(BotApi::class)) - ->addTag('console.command') - ; - - $container - ->register('telegram_bot.menu_button_set_commands', ButtonSetCommandsCommand::class) - ->setArgument('$botApi', new Reference(BotApi::class)) - ->setArgument('$commandMetadataProvider', new Reference('telegram_bot.command_metadata_provider')) - ->setArgument('$descriptionProcessor', new Reference('telegram_bot.description_processor')) - ->addTag('console.command') - ; - - $container - ->register('telegram_bot.menu_button_delete_command', ButtonDeleteCommand::class) - ->setArgument('$botApi', new Reference(BotApi::class)) - ->addTag('console.command') - ; - - $container - ->register('telegram_bot.description_processor', DummyDescriptionProcessor::class) - ; - - $container->registerAttributeForAutoconfiguration(OnEvent::class, $this->controllerConfigurate(...)); - $container->registerAttributeForAutoconfiguration(OnCommand::class, $this->controllerConfigurate(...)); - $container->registerAttributeForAutoconfiguration(OnCallback::class, $this->controllerConfigurate(...)); - } - - private function controllerConfigurate(ChildDefinition $definition, object $attribute, \ReflectionMethod $reflector): void - { - $definition->addTag('telegram_bot.command', [ - 'event' => $attribute->event, - 'value' => $attribute->command ?? $attribute->callbackData ?? '', - 'controller' => $reflector->getDeclaringClass()->getName() . '::' . $reflector->getName(), - 'priority' => $attribute->priority, - ]); - } - - public function getAlias(): string - { - return 'telegram_bot'; - } -} diff --git a/src/TelegramBotBundle.php b/src/TelegramBotBundle.php index 8178844..b92cfd7 100644 --- a/src/TelegramBotBundle.php +++ b/src/TelegramBotBundle.php @@ -4,21 +4,29 @@ namespace Luzrain\TelegramBotBundle; -use Luzrain\TelegramBotBundle\DependencyInjection\CommandCompilerPass; -use Luzrain\TelegramBotBundle\DependencyInjection\TelegramBotExtension; +use Symfony\Component\Config\Definition\Configurator\DefinitionConfigurator; use Symfony\Component\DependencyInjection\ContainerBuilder; -use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; -use Symfony\Component\HttpKernel\Bundle\Bundle; +use Symfony\Component\DependencyInjection\Loader\Configurator\ContainerConfigurator; +use Symfony\Component\HttpKernel\Bundle\AbstractBundle; -final class TelegramBotBundle extends Bundle +final class TelegramBotBundle extends AbstractBundle { + protected string $extensionAlias = 'telegram_bot'; + + public function configure(DefinitionConfigurator $definition): void + { + $configurator = require __DIR__ . '/config/configuration.php'; + $configurator($definition); + } + public function build(ContainerBuilder $container): void { - $container->addCompilerPass(new CommandCompilerPass()); + $container->addCompilerPass(require __DIR__ . '/config/compilerpass.php'); } - public function getContainerExtension(): ExtensionInterface + public function loadExtension(array $config, ContainerConfigurator $container, ContainerBuilder $builder): void { - return new TelegramBotExtension(); + $configurator = require __DIR__ . '/config/services.php'; + $configurator($config, $builder); } } diff --git a/src/DependencyInjection/CommandCompilerPass.php b/src/config/compilerpass.php similarity index 92% rename from src/DependencyInjection/CommandCompilerPass.php rename to src/config/compilerpass.php index 85c6620..dc2655a 100644 --- a/src/DependencyInjection/CommandCompilerPass.php +++ b/src/config/compilerpass.php @@ -2,8 +2,6 @@ declare(strict_types=1); -namespace Luzrain\TelegramBotBundle\DependencyInjection; - use Luzrain\TelegramBotBundle\TelegramBot\CommandMetadataProvider; use Luzrain\TelegramBotBundle\TelegramBot\UpdateHandler; use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface; @@ -11,11 +9,7 @@ use Symfony\Component\DependencyInjection\Reference; use Symfony\Component\DependencyInjection\ServiceLocator; -final class CommandCompilerPass implements CompilerPassInterface -{ - /** - * @psalm-suppress ArgumentTypeCoercion - */ +return new class () implements CompilerPassInterface { public function process(ContainerBuilder $container): void { $controllers = $container->findTaggedServiceIds('telegram_bot.command'); @@ -69,4 +63,4 @@ private function referenceMap(array $serviceClasses): array } return $result; } -} +}; diff --git a/src/config/configuration.php b/src/config/configuration.php new file mode 100644 index 0000000..7eca501 --- /dev/null +++ b/src/config/configuration.php @@ -0,0 +1,50 @@ +rootNode() + ->children() + ->scalarNode('http_client') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('request_factory') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('stream_factory') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('api_token') + ->isRequired() + ->cannotBeEmpty() + ->end() + ->scalarNode('secret_token') + ->defaultNull() + ->end() + ->arrayNode('allowed_updates') + ->prototype('scalar')->end() + ->beforeNormalization() + ->always(fn ($values) => array_map(strval(...), $values)) + ->end() + ->validate() + ->ifTrue(fn ($configArray) => array_diff($configArray, Update::getUpdateTypes()) !== []) + ->then(function ($configArray) { + if (array_diff($configArray, Update::getUpdateTypes()) !== []) { + $allowedKeys = implode(', ', Update::getUpdateTypes()); + throw new \InvalidArgumentException(sprintf('Invalid updates list. Allowed updates: %s', $allowedKeys)); + } + return $configArray; + }) + ->end() + ->end() + ->end(); +}; diff --git a/src/config/services.php b/src/config/services.php new file mode 100644 index 0000000..d0aefcb --- /dev/null +++ b/src/config/services.php @@ -0,0 +1,107 @@ +autowire(BotApi::class) + ->setArgument('$requestFactory', new Reference($config['request_factory'])) + ->setArgument('$streamFactory', new Reference($config['stream_factory'])) + ->setArgument('$client', new Reference($config['http_client'])) + ->setArgument('$token', $config['api_token']) + ; + + $container + ->register('telegram_bot.client_api', ClientApi::class) + ; + + $container + ->register('telegram_bot.webhook_controller', WebHookController::class) + ->setArgument('$updateHandler', new Reference('telegram_bot.update_handler')) + ->setArgument('$secretToken', $config['secret_token']) + ->addTag('controller.service_arguments') + ; + + $container + ->register('telegram_bot.long_polling_service', LongPollingService::class) + ->setArgument('$botApi', new Reference(BotApi::class)) + ->setArgument('$allowedUpdates', $config['allowed_updates']) + ; + + $container + ->register('telegram_bot.set_webhook_command', SetWebhookCommand::class) + ->setArgument('$botApi', new Reference(BotApi::class)) + ->setArgument('$secretToken', $config['secret_token']) + ->setArgument('$allowedUpdates', $config['allowed_updates']) + ->addTag('console.command') + ; + + $container + ->register('telegram_bot.get_webhook_command', WebhookInfoCommand::class) + ->setArgument('$botApi', new Reference(BotApi::class)) + ->addTag('console.command') + ; + + $container + ->register('telegram_bot.delete_webhook_command', DeleteWebhookCommand::class) + ->setArgument('$botApi', new Reference(BotApi::class)) + ->addTag('console.command') + ; + + $container + ->register('telegram_bot.polling_command', PolllingStartCommand::class) + ->setArgument('$longPollingService', new Reference('telegram_bot.long_polling_service')) + ->setArgument('$updateHandler', new Reference('telegram_bot.update_handler')) + ->setArgument('$botApi', new Reference(BotApi::class)) + ->addTag('console.command') + ; + + $container + ->register('telegram_bot.menu_button_set_commands', ButtonSetCommandsCommand::class) + ->setArgument('$botApi', new Reference(BotApi::class)) + ->setArgument('$commandMetadataProvider', new Reference('telegram_bot.command_metadata_provider')) + ->setArgument('$descriptionProcessor', new Reference('telegram_bot.description_processor')) + ->addTag('console.command') + ; + + $container + ->register('telegram_bot.menu_button_delete_command', ButtonDeleteCommand::class) + ->setArgument('$botApi', new Reference(BotApi::class)) + ->addTag('console.command') + ; + + $container + ->register('telegram_bot.description_processor', DummyDescriptionProcessor::class) + ; + + $controllerConfigurate = static function(ChildDefinition $definition, object $attribute, \ReflectionMethod $reflector): void { + $definition->addTag('telegram_bot.command', [ + 'event' => $attribute->event, + 'value' => $attribute->command ?? $attribute->callbackData ?? '', + 'controller' => $reflector->getDeclaringClass()->getName() . '::' . $reflector->getName(), + 'priority' => $attribute->priority, + ]); + }; + + $container->registerAttributeForAutoconfiguration(OnEvent::class, $controllerConfigurate); + $container->registerAttributeForAutoconfiguration(OnCommand::class, $controllerConfigurate); + $container->registerAttributeForAutoconfiguration(OnCallback::class, $controllerConfigurate); +};