From 88fbf7bc1c524d8cb263ac1bda8c72b4637fbac9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 17 Jan 2025 11:22:53 +0100 Subject: [PATCH 1/5] Add Symfony Notifier integration Integrated Symfony Notifier into the project by adding it to `composer.json` and creating a configuration file `notifier.yaml`. Updated `symfony.lock` to include the recipe configuration for Notifier. Minor documentation formatting issues were also fixed in `index.rst`. --- composer.json | 3 ++- config/packages/notifier.yaml | 12 ++++++++++++ docs/source/index.rst | 7 +++---- symfony.lock | 12 ++++++++++++ 4 files changed, 29 insertions(+), 5 deletions(-) create mode 100644 config/packages/notifier.yaml diff --git a/composer.json b/composer.json index 8f6d01335..18ff0f222 100644 --- a/composer.json +++ b/composer.json @@ -16,8 +16,8 @@ "ext-zlib": "*", "champs-libres/wopi-bundle": "dev-master@dev", "champs-libres/wopi-lib": "dev-master@dev", - "doctrine/doctrine-bundle": "^2.1", "doctrine/data-fixtures": "^1.8", + "doctrine/doctrine-bundle": "^2.1", "doctrine/doctrine-migrations-bundle": "^3.0", "doctrine/orm": "^2.13.0", "erusev/parsedown": "^1.7", @@ -58,6 +58,7 @@ "symfony/messenger": "^5.4", "symfony/mime": "^5.4", "symfony/monolog-bundle": "^3.5", + "symfony/notifier": "^5.4", "symfony/options-resolver": "^5.4", "symfony/process": "^5.4", "symfony/property-access": "^5.4", diff --git a/config/packages/notifier.yaml b/config/packages/notifier.yaml new file mode 100644 index 000000000..ce26c77c4 --- /dev/null +++ b/config/packages/notifier.yaml @@ -0,0 +1,12 @@ +framework: + notifier: + texter_transports: + twilio: '%env(resolve:SHORT_MESSAGE_DSN)%' + channel_policy: + # use chat/slack, chat/telegram, sms/twilio or sms/nexmo + urgent: ['email'] + high: ['email'] + medium: ['email'] + low: ['email'] + admin_recipients: + - { email: admin@example.com } diff --git a/docs/source/index.rst b/docs/source/index.rst index 4ac09908f..ddfa23e3b 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -16,7 +16,7 @@ Welcome to Chill documentation! Chill is a free software for social workers. -Chill rely on the php framework `Symfony `_. +Chill rely on the php framework `Symfony `_. Contents of this documentation: @@ -42,7 +42,7 @@ Contribute User manual =========== -An user manual exists in French and currently focuses on describing the main concept of the software. +An user manual exists in French and currently focuses on describing the main concept of the software. `Read (and contribute) to the manual `_ @@ -55,12 +55,11 @@ Available bundles * Chill Person, to deal with persons, * chill custom fields, to add custom fields to some entities, * chill activity: to add activities to people, - * chill report: to add report to people, + * chill report: to add report to people, * chill event: to gather people into events, * chill docs store: to store documents to people, but also entities, * chill task: to register task with people, * chill third party: to register third parties, - * chill family members: to register family members You will also found the following projects : diff --git a/symfony.lock b/symfony.lock index 3d484a508..7d33810ea 100644 --- a/symfony.lock +++ b/symfony.lock @@ -296,6 +296,18 @@ "config/packages/monolog.yaml" ] }, + "symfony/notifier": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.0", + "ref": "178877daf79d2dbd62129dd03612cb1a2cb407cc" + }, + "files": [ + "config/packages/notifier.yaml" + ] + }, "symfony/phpunit-bridge": { "version": "7.1", "recipe": { From 594ed4a5b4458b7bbd30bd690389cee3010e964a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 17 Jan 2025 13:25:38 +0100 Subject: [PATCH 2/5] =?UTF-8?q?Replace=20custom=20ShortMessage=20usage=20w?= =?UTF-8?q?ith=20Symfony=E2=80=99s=20SmsMessage.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Switched the entire short message notification system to leverage Symfony's Notifier component and its TexterInterface with SmsMessage. This update simplifies the implementation, removes custom short message handling, and aligns with Symfony's standardized approach. --- config/packages/notifier.yaml | 2 +- .../SendTestShortMessageOnCalendarCommand.php | 18 ++++++------ .../BulkCalendarShortMessageSender.php | 12 ++++++-- .../DefaultShortMessageForCalendarBuilder.php | 28 +++++++++++++------ ...hortMessageForCalendarBuilderInterface.php | 4 +-- .../BulkCalendarShortMessageSenderTest.php | 20 ++++++------- ...aultShortMessageForCalendarBuilderTest.php | 11 +++----- .../CompilerPass/ShortMessageCompilerPass.php | 1 + 8 files changed, 54 insertions(+), 42 deletions(-) diff --git a/config/packages/notifier.yaml b/config/packages/notifier.yaml index ce26c77c4..158c4be03 100644 --- a/config/packages/notifier.yaml +++ b/config/packages/notifier.yaml @@ -1,7 +1,7 @@ framework: notifier: texter_transports: - twilio: '%env(resolve:SHORT_MESSAGE_DSN)%' + ovhcloud: '%env(SHORT_MESSAGE_DSN)%' channel_policy: # use chat/slack, chat/telegram, sms/twilio or sms/nexmo urgent: ['email'] diff --git a/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php b/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php index 80ee424b8..34e20346b 100644 --- a/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php +++ b/src/Bundle/ChillCalendarBundle/Command/SendTestShortMessageOnCalendarCommand.php @@ -21,9 +21,7 @@ namespace Chill\CalendarBundle\Command; use Chill\CalendarBundle\Entity\Calendar; use Chill\CalendarBundle\Service\ShortMessageNotification\ShortMessageForCalendarBuilderInterface; use Chill\MainBundle\Entity\User; -use Chill\MainBundle\Phonenumber\PhoneNumberHelperInterface; use Chill\MainBundle\Repository\UserRepositoryInterface; -use Chill\MainBundle\Service\ShortMessage\ShortMessageTransporterInterface; use Chill\PersonBundle\Entity\Person; use Chill\PersonBundle\Repository\PersonRepository; use libphonenumber\PhoneNumber; @@ -36,6 +34,7 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\Question; +use Symfony\Component\Notifier\TexterInterface; class SendTestShortMessageOnCalendarCommand extends Command { @@ -44,9 +43,8 @@ class SendTestShortMessageOnCalendarCommand extends Command public function __construct( private readonly PersonRepository $personRepository, private readonly PhoneNumberUtil $phoneNumberUtil, - private readonly PhoneNumberHelperInterface $phoneNumberHelper, private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder, - private readonly ShortMessageTransporterInterface $transporter, + private readonly TexterInterface $transporter, private readonly UserRepositoryInterface $userRepository, ) { parent::__construct('chill:calendar:test-send-short-message'); @@ -152,10 +150,6 @@ class SendTestShortMessageOnCalendarCommand extends Command return $phone; }); - $phone = $helper->ask($input, $output, $question); - - $question = new ConfirmationQuestion('really send the message to the phone ?'); - $reallySend = (bool) $helper->ask($input, $output, $question); $messages = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar); @@ -165,8 +159,12 @@ class SendTestShortMessageOnCalendarCommand extends Command foreach ($messages as $key => $message) { $output->writeln("The short message for SMS {$key} will be: "); - $output->writeln($message->getContent()); - $message->setPhoneNumber($phone); + $output->writeln($message->getSubject()); + $output->writeln('The destination number will be:'); + $output->writeln($message->getPhone()); + + $question = new ConfirmationQuestion('really send the message to the phone ?'); + $reallySend = (bool) $helper->ask($input, $output, $question); if ($reallySend) { $this->transporter->send($message); diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php index 9a4a92a94..7053d905a 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/BulkCalendarShortMessageSender.php @@ -21,11 +21,17 @@ namespace Chill\CalendarBundle\Service\ShortMessageNotification; use Chill\CalendarBundle\Entity\Calendar; use Doctrine\ORM\EntityManagerInterface; use Psr\Log\LoggerInterface; -use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Notifier\TexterInterface; class BulkCalendarShortMessageSender { - public function __construct(private readonly CalendarForShortMessageProvider $provider, private readonly EntityManagerInterface $em, private readonly LoggerInterface $logger, private readonly MessageBusInterface $messageBus, private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder) {} + public function __construct( + private readonly CalendarForShortMessageProvider $provider, + private readonly EntityManagerInterface $em, + private readonly LoggerInterface $logger, + private readonly TexterInterface $texter, + private readonly ShortMessageForCalendarBuilderInterface $messageForCalendarBuilder, + ) {} public function sendBulkMessageToEligibleCalendars() { @@ -36,7 +42,7 @@ class BulkCalendarShortMessageSender $smses = $this->messageForCalendarBuilder->buildMessageForCalendar($calendar); foreach ($smses as $sms) { - $this->messageBus->dispatch($sms); + $this->texter->send($sms); ++$countSms; } diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php index 880c9950f..dfce0548c 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilder.php @@ -19,12 +19,26 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Service\ShortMessageNotification; use Chill\CalendarBundle\Entity\Calendar; -use Chill\MainBundle\Service\ShortMessage\ShortMessage; +use libphonenumber\PhoneNumberFormat; +use libphonenumber\PhoneNumberUtil; +use Symfony\Component\Notifier\Message\SmsMessage; class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBuilderInterface { - public function __construct(private readonly \Twig\Environment $engine) {} + private readonly PhoneNumberUtil $phoneUtil; + public function __construct(private readonly \Twig\Environment $engine) + { + $this->phoneUtil = PhoneNumberUtil::getInstance(); + } + + /** + * @return list + * + * @throws \Twig\Error\LoaderError + * @throws \Twig\Error\RuntimeError + * @throws \Twig\Error\SyntaxError + */ public function buildMessageForCalendar(Calendar $calendar): array { if (true !== $calendar->getSendSMS()) { @@ -39,16 +53,14 @@ class DefaultShortMessageForCalendarBuilder implements ShortMessageForCalendarBu } if (Calendar::SMS_PENDING === $calendar->getSmsStatus()) { - $toUsers[] = new ShortMessage( + $toUsers[] = new SmsMessage( + $this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164), $this->engine->render('@ChillCalendar/CalendarShortMessage/short_message.txt.twig', ['calendar' => $calendar]), - $person->getMobilenumber(), - ShortMessage::PRIORITY_LOW ); } elseif (Calendar::SMS_CANCEL_PENDING === $calendar->getSmsStatus()) { - $toUsers[] = new ShortMessage( + $toUsers[] = new SmsMessage( + $this->phoneUtil->format($person->getMobilenumber(), PhoneNumberFormat::E164), $this->engine->render('@ChillCalendar/CalendarShortMessage/short_message_canceled.txt.twig', ['calendar' => $calendar]), - $person->getMobilenumber(), - ShortMessage::PRIORITY_LOW ); } } diff --git a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/ShortMessageForCalendarBuilderInterface.php b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/ShortMessageForCalendarBuilderInterface.php index 65856a437..6aa21247d 100644 --- a/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/ShortMessageForCalendarBuilderInterface.php +++ b/src/Bundle/ChillCalendarBundle/Service/ShortMessageNotification/ShortMessageForCalendarBuilderInterface.php @@ -19,12 +19,12 @@ declare(strict_types=1); namespace Chill\CalendarBundle\Service\ShortMessageNotification; use Chill\CalendarBundle\Entity\Calendar; -use Chill\MainBundle\Service\ShortMessage\ShortMessage; +use Symfony\Component\Notifier\Message\SmsMessage; interface ShortMessageForCalendarBuilderInterface { /** - * @return array|ShortMessage[] + * @return list */ public function buildMessageForCalendar(Calendar $calendar): array; } diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php index 09c9ddf96..dd86ab16b 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/BulkCalendarShortMessageSenderTest.php @@ -23,17 +23,16 @@ use Chill\CalendarBundle\Service\ShortMessageNotification\BulkCalendarShortMessa use Chill\CalendarBundle\Service\ShortMessageNotification\CalendarForShortMessageProvider; use Chill\CalendarBundle\Service\ShortMessageNotification\ShortMessageForCalendarBuilderInterface; use Chill\MainBundle\Entity\User; -use Chill\MainBundle\Service\ShortMessage\ShortMessage; use Chill\MainBundle\Test\PrepareUserTrait; use Chill\PersonBundle\DataFixtures\Helper\PersonRandomHelper; use Doctrine\ORM\EntityManagerInterface; -use libphonenumber\PhoneNumberUtil; use Prophecy\Argument; use Prophecy\PhpUnit\ProphecyTrait; use Psr\Log\NullLogger; use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; -use Symfony\Component\Messenger\Envelope; -use Symfony\Component\Messenger\MessageBusInterface; +use Symfony\Component\Notifier\Message\SentMessage; +use Symfony\Component\Notifier\Message\SmsMessage; +use Symfony\Component\Notifier\TexterInterface; /** * @internal @@ -101,24 +100,23 @@ final class BulkCalendarShortMessageSenderTest extends KernelTestCase $messageBuilder->buildMessageForCalendar(Argument::type(Calendar::class)) ->willReturn( [ - new ShortMessage( + new SmsMessage( + '+32470123456', 'content', - PhoneNumberUtil::getInstance()->parse('+32470123456', 'BE'), - ShortMessage::PRIORITY_MEDIUM ), ] ); - $bus = $this->prophesize(MessageBusInterface::class); - $bus->dispatch(Argument::type(ShortMessage::class)) - ->willReturn(new Envelope(new \stdClass())) + $texter = $this->prophesize(TexterInterface::class); + $texter->send(Argument::type(SmsMessage::class)) + ->will(fn ($args): SentMessage => new SentMessage($args[0], 'sms')) ->shouldBeCalledTimes(1); $bulk = new BulkCalendarShortMessageSender( $provider->reveal(), $em, new NullLogger(), - $bus->reveal(), + $texter->reveal(), $messageBuilder->reveal() ); diff --git a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php index 222d3a451..f5b9c8fdd 100644 --- a/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php +++ b/src/Bundle/ChillCalendarBundle/Tests/Service/ShortMessageNotification/DefaultShortMessageForCalendarBuilderTest.php @@ -23,7 +23,6 @@ use Chill\CalendarBundle\Service\ShortMessageNotification\DefaultShortMessageFor use Chill\MainBundle\Entity\Location; use Chill\MainBundle\Entity\User; use Chill\PersonBundle\Entity\Person; -use libphonenumber\PhoneNumberFormat; use libphonenumber\PhoneNumberUtil; use PHPUnit\Framework\TestCase; use Prophecy\Argument; @@ -90,10 +89,9 @@ final class DefaultShortMessageForCalendarBuilderTest extends TestCase $this->assertCount(1, $sms); $this->assertEquals( '+32470123456', - $this->phoneNumberUtil->format($sms[0]->getPhoneNumber(), PhoneNumberFormat::E164) + $sms[0]->getPhone() ); - $this->assertEquals('message content', $sms[0]->getContent()); - $this->assertEquals('low', $sms[0]->getPriority()); + $this->assertEquals('message content', $sms[0]->getSubject()); // if the calendar is canceled $calendar @@ -105,9 +103,8 @@ final class DefaultShortMessageForCalendarBuilderTest extends TestCase $this->assertCount(1, $sms); $this->assertEquals( '+32470123456', - $this->phoneNumberUtil->format($sms[0]->getPhoneNumber(), PhoneNumberFormat::E164) + $sms[0]->getRecipientId(), ); - $this->assertEquals('message canceled', $sms[0]->getContent()); - $this->assertEquals('low', $sms[0]->getPriority()); + $this->assertEquals('message canceled', $sms[0]->getSubject()); } } diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php index 9da9154b3..5a974c926 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php @@ -33,6 +33,7 @@ class ShortMessageCompilerPass implements CompilerPassInterface { public function process(ContainerBuilder $container) { + return; $config = $container->resolveEnvPlaceholders($container->getParameter('chill_main.short_messages'), true); // weird fix for special characters $config['dsn'] = str_replace(['%%'], ['%'], (string) $config['dsn']); From b02820407c5596f766216135db9ea6277d7a1ca6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 17 Jan 2025 13:47:09 +0100 Subject: [PATCH 3/5] Add log SMS when a message is sent Introduced a new event subscriber to log SMS sent events with details such as recipient and message IDs. This enhances monitoring and debugging of SMS delivery. --- config/packages/notifier.yaml | 1 + .../Notifier/SentMessageEventSubscriber.php | 37 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 src/Bundle/ChillMainBundle/Service/Notifier/SentMessageEventSubscriber.php diff --git a/config/packages/notifier.yaml b/config/packages/notifier.yaml index 158c4be03..968b8aa7f 100644 --- a/config/packages/notifier.yaml +++ b/config/packages/notifier.yaml @@ -1,6 +1,7 @@ framework: notifier: texter_transports: + #ovhcloud: '%env(OVHCLOUD_DSN)%' ovhcloud: '%env(SHORT_MESSAGE_DSN)%' channel_policy: # use chat/slack, chat/telegram, sms/twilio or sms/nexmo diff --git a/src/Bundle/ChillMainBundle/Service/Notifier/SentMessageEventSubscriber.php b/src/Bundle/ChillMainBundle/Service/Notifier/SentMessageEventSubscriber.php new file mode 100644 index 000000000..ba94fba49 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Service/Notifier/SentMessageEventSubscriber.php @@ -0,0 +1,37 @@ + ['onSentMessage', 0], + ]; + } + + public function onSentMessage(SentMessageEvent $event): void + { + $message = $event->getMessage(); + + $this->logger->warning('[sms] a sms was sent', ['validReceiversI' => $message->getOriginalMessage()->getRecipientId(), 'idsI' => $message->getMessageId()]); + } +} From 5e3a1eb2aba19d62b06e6bc68c46018215286845 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Fri, 17 Jan 2025 17:13:36 +0100 Subject: [PATCH 4/5] Remove legacy ShortMessage components and integrate Notifier Replaced outdated ShortMessage functionalities with Symfony's Notifier component for handling SMS messages. Deprecated legacy `ShortMessage` components and introduced a transition layer for existing OVH configurations. Updated dependencies and environment setup to support the new implementation. --- .env | 4 + composer.json | 1 + config/packages/notifier.yaml | 2 +- rector.php | 4 + .../ChillMainBundle/ChillMainBundle.php | 2 - .../ChillMainExtension.php | 40 ++++++++ .../CompilerPass/ShortMessageCompilerPass.php | 92 ------------------- .../DependencyInjection/Configuration.php | 1 + .../Notifier/LegacyOvhCloudFactory.php | 54 +++++++++++ .../ShortMessage/NullShortMessageSender.php | 24 ----- .../Service/ShortMessage/ShortMessage.php | 2 + .../ShortMessage/ShortMessageHandler.php | 20 +++- .../ShortMessageSenderInterface.php | 24 ----- .../ShortMessage/ShortMessageTransporter.php | 29 ------ .../ShortMessageTransporterInterface.php | 24 ----- .../ShortMessageOvh/OvhShortMessageSender.php | 65 ------------- symfony.lock | 9 ++ 17 files changed, 134 insertions(+), 263 deletions(-) delete mode 100644 src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php create mode 100644 src/Bundle/ChillMainBundle/Service/Notifier/LegacyOvhCloudFactory.php delete mode 100644 src/Bundle/ChillMainBundle/Service/ShortMessage/NullShortMessageSender.php delete mode 100644 src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageSenderInterface.php delete mode 100644 src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageTransporter.php delete mode 100644 src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageTransporterInterface.php delete mode 100644 src/Bundle/ChillMainBundle/Service/ShortMessageOvh/OvhShortMessageSender.php diff --git a/.env b/.env index 4c6ee4ca6..cc23653bd 100644 --- a/.env +++ b/.env @@ -88,3 +88,7 @@ REDIS_HOST=redis REDIS_PORT=6379 REDIS_URL=redis://${REDIS_HOST}:${REDIS_PORT} ###< chill-project/chill-bundles ### + +###> symfony/ovh-cloud-notifier ### +# OVHCLOUD_DSN=ovhcloud://APPLICATION_KEY:APPLICATION_SECRET@default?consumer_key=CONSUMER_KEY&service_name=SERVICE_NAME +###< symfony/ovh-cloud-notifier ### diff --git a/composer.json b/composer.json index 18ff0f222..3ef287196 100644 --- a/composer.json +++ b/composer.json @@ -60,6 +60,7 @@ "symfony/monolog-bundle": "^3.5", "symfony/notifier": "^5.4", "symfony/options-resolver": "^5.4", + "symfony/ovh-cloud-notifier": "^5.4", "symfony/process": "^5.4", "symfony/property-access": "^5.4", "symfony/property-info": "^5.4", diff --git a/config/packages/notifier.yaml b/config/packages/notifier.yaml index 968b8aa7f..1b474455a 100644 --- a/config/packages/notifier.yaml +++ b/config/packages/notifier.yaml @@ -2,7 +2,7 @@ framework: notifier: texter_transports: #ovhcloud: '%env(OVHCLOUD_DSN)%' - ovhcloud: '%env(SHORT_MESSAGE_DSN)%' + #ovhcloud: '%env(SHORT_MESSAGE_DSN)%' channel_policy: # use chat/slack, chat/telegram, sms/twilio or sms/nexmo urgent: ['email'] diff --git a/rector.php b/rector.php index 126c814e9..3923d37e4 100644 --- a/rector.php +++ b/rector.php @@ -20,6 +20,10 @@ return static function (RectorConfig $rectorConfig): void { __DIR__ . '/src', ]); + $rectorConfig->skip([ + \Rector\Php55\Rector\String_\StringClassNameToClassConstantRector::class => __DIR__ . 'src/Bundle/ChillMainBundle/Service/Notifier/LegacyOvhCloudFactory.php' + ]); + $rectorConfig->symfonyContainerXml(__DIR__ . '/var/cache/dev/test/App_KernelTestDebugContainer.xml '); $rectorConfig->symfonyContainerPhp(__DIR__ . '/tests/symfony-container.php'); diff --git a/src/Bundle/ChillMainBundle/ChillMainBundle.php b/src/Bundle/ChillMainBundle/ChillMainBundle.php index ff721784a..bca92b85c 100644 --- a/src/Bundle/ChillMainBundle/ChillMainBundle.php +++ b/src/Bundle/ChillMainBundle/ChillMainBundle.php @@ -18,7 +18,6 @@ use Chill\MainBundle\DependencyInjection\CompilerPass\ExportsCompilerPass; use Chill\MainBundle\DependencyInjection\CompilerPass\MenuCompilerPass; use Chill\MainBundle\DependencyInjection\CompilerPass\NotificationCounterCompilerPass; use Chill\MainBundle\DependencyInjection\CompilerPass\SearchableServicesCompilerPass; -use Chill\MainBundle\DependencyInjection\CompilerPass\ShortMessageCompilerPass; use Chill\MainBundle\DependencyInjection\CompilerPass\TimelineCompilerClass; use Chill\MainBundle\DependencyInjection\CompilerPass\WidgetsCompilerPass; use Chill\MainBundle\DependencyInjection\ConfigConsistencyCompilerPass; @@ -73,6 +72,5 @@ class ChillMainBundle extends Bundle $container->addCompilerPass(new MenuCompilerPass(), \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); $container->addCompilerPass(new ACLFlagsCompilerPass(), \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); $container->addCompilerPass(new CRUDControllerCompilerPass(), \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); - $container->addCompilerPass(new ShortMessageCompilerPass(), \Symfony\Component\DependencyInjection\Compiler\PassConfig::TYPE_BEFORE_OPTIMIZATION, 0); } } diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php index 9a005be4a..2e9b7c029 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/ChillMainExtension.php @@ -234,6 +234,8 @@ class ChillMainExtension extends Extension implements public function prepend(ContainerBuilder $container) { + $this->prependNotifierTexterWithLegacyData($container); + // add installation_name and date_format to globals $chillMainConfig = $container->getExtensionConfig($this->getAlias()); $config = $this->processConfiguration($this @@ -357,6 +359,44 @@ class ChillMainExtension extends Extension implements // Note: the controller are loaded inside compiler pass } + /** + * This method prepend framework configuration with legacy configuration from "ovhCloudTransporter". + * + * It can be safely removed when the option chill_main.short_message.dsn will be removed. + */ + private function prependNotifierTexterWithLegacyData(ContainerBuilder $container): void + { + $configs = $container->getExtensionConfig('chill_main'); + $notifierSet = false; + foreach (array_reverse($configs) as $config) { + if (!array_key_exists('short_messages', $config)) { + continue; + } + + if (array_key_exists('dsn', $config['short_messages'])) { + $container->prependExtensionConfig('framework', [ + 'notifier' => [ + 'texter_transports' => [ + 'ovh_legacy' => $config['short_messages']['dsn'], + ], + ], + ]); + $notifierSet = true; + } + } + if (!$notifierSet) { + $container->prependExtensionConfig('framework', [ + 'notifier' => [ + 'texter_transports' => [ + 'dummy' => 'null://null', + ], + ], + ]); + } + + + } + protected function prependCruds(ContainerBuilder $container) { $container->prependExtensionConfig('chill_main', [ diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php b/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php deleted file mode 100644 index 5a974c926..000000000 --- a/src/Bundle/ChillMainBundle/DependencyInjection/CompilerPass/ShortMessageCompilerPass.php +++ /dev/null @@ -1,92 +0,0 @@ -resolveEnvPlaceholders($container->getParameter('chill_main.short_messages'), true); - // weird fix for special characters - $config['dsn'] = str_replace(['%%'], ['%'], (string) $config['dsn']); - $dsn = parse_url($config['dsn']); - parse_str($dsn['query'] ?? '', $dsn['queries']); - - if ('null' === $dsn['scheme'] || false === $config['enabled']) { - $defaultTransporter = new Reference(NullShortMessageSender::class); - } elseif ('ovh' === $dsn['scheme']) { - if (!class_exists('\\'.\Ovh\Api::class)) { - throw new RuntimeException('Class \Ovh\Api not found'); - } - - foreach (['user', 'host', 'pass'] as $component) { - if (!\array_key_exists($component, $dsn)) { - throw new RuntimeException(sprintf('The component %s does not exist in dsn. Please provide a dsn like ovh://applicationKey:applicationSecret@endpoint?consumerKey=xxxx&sender=yyyy&service_name=zzzz', $component)); - } - - $container->setParameter('chill_main.short_messages.ovh_config_'.$component, $dsn[$component]); - } - - foreach (['consumer_key', 'sender', 'service_name'] as $param) { - if (!\array_key_exists($param, $dsn['queries'])) { - throw new RuntimeException(sprintf('The parameter %s does not exist in dsn. Please provide a dsn like ovh://applicationKey:applicationSecret@endpoint?consumerKey=xxxx&sender=yyyy&service_name=zzzz', $param)); - } - $container->setParameter('chill_main.short_messages.ovh_config_'.$param, $dsn['queries'][$param]); - } - - $ovh = new Definition(); - $ovh - ->setClass('\\'.\Ovh\Api::class) - ->setArgument(0, $dsn['user']) - ->setArgument(1, $dsn['pass']) - ->setArgument(2, $dsn['host']) - ->setArgument(3, $dsn['queries']['consumer_key']); - $container->setDefinition(\Ovh\Api::class, $ovh); - - $ovhSender = new Definition(); - $ovhSender - ->setClass(OvhShortMessageSender::class) - ->setArgument(0, new Reference(\Ovh\Api::class)) - ->setArgument(1, $dsn['queries']['service_name']) - ->setArgument(2, $dsn['queries']['sender']) - ->setArgument(3, new Reference(LoggerInterface::class)) - ->setArgument(4, new Reference(PhoneNumberUtil::class)); - $container->setDefinition(OvhShortMessageSender::class, $ovhSender); - - $defaultTransporter = new Reference(OvhShortMessageSender::class); - } else { - throw new RuntimeException(sprintf('Cannot find a sender for this dsn: %s', $config['dsn'])); - } - - $container->getDefinition(ShortMessageTransporter::class) - ->setArgument(0, $defaultTransporter); - } -} diff --git a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php index b1bb3951f..6625488dd 100644 --- a/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php +++ b/src/Bundle/ChillMainBundle/DependencyInjection/Configuration.php @@ -123,6 +123,7 @@ class Configuration implements ConfigurationInterface ->end() ->end() ->arrayNode('short_messages') + ->setDeprecated('chill-project/chill-bundles', '3.7.0', 'Since 3.7.0, Chill use the Notifier component to send message. Configure the notifier instead. In the meantime, the previous available OVH configuration will be append to the notifier component.') ->canBeEnabled() ->children() ->scalarNode('dsn')->cannotBeEmpty()->defaultValue('null://null') diff --git a/src/Bundle/ChillMainBundle/Service/Notifier/LegacyOvhCloudFactory.php b/src/Bundle/ChillMainBundle/Service/Notifier/LegacyOvhCloudFactory.php new file mode 100644 index 000000000..5b5a5faf3 --- /dev/null +++ b/src/Bundle/ChillMainBundle/Service/Notifier/LegacyOvhCloudFactory.php @@ -0,0 +1,54 @@ +getScheme(); + + if ('ovh' !== $scheme) { + throw new UnsupportedSchemeException($dsn, 'ovh', $this->getSupportedSchemes()); + } + + if (!class_exists($class = '\Symfony\Component\Notifier\Bridge\OvhCloud\OvhCloudTransport')) { + throw new \RuntimeException(sprintf('The class %s is missing, please add the dependency with "composer require symfony/ovh-cloud-notifier".', $class)); + } + + $applicationKey = $this->getUser($dsn); + $applicationSecret = $this->getPassword($dsn); + $consumerKey = $dsn->getRequiredOption('consumer_key'); + $serviceName = $dsn->getRequiredOption('service_name'); + $sender = $dsn->getOption('sender'); + $host = null; + $port = $dsn->getPort(); + + return (new $class($applicationKey, $applicationSecret, $consumerKey, $serviceName, $this->client, $this->dispatcher)) + ->setHost($host)->setPort($port)->setSender($sender); + } +} diff --git a/src/Bundle/ChillMainBundle/Service/ShortMessage/NullShortMessageSender.php b/src/Bundle/ChillMainBundle/Service/ShortMessage/NullShortMessageSender.php deleted file mode 100644 index 16bc87790..000000000 --- a/src/Bundle/ChillMainBundle/Service/ShortMessage/NullShortMessageSender.php +++ /dev/null @@ -1,24 +0,0 @@ -phoneNumberUtil = PhoneNumberUtil::getInstance(); + } public function __invoke(ShortMessage $message): void { - $this->messageTransporter->send($message); + trigger_deprecation('Chill-project/chill-bundles', '3.7.0', 'Send message using Notifier component'); + + $this->texter->send( + new SmsMessage( + $this->phoneNumberUtil->format($message->getPhoneNumber(), PhoneNumberFormat::E164), + $message->getContent(), + ), + ); } } diff --git a/src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageSenderInterface.php b/src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageSenderInterface.php deleted file mode 100644 index 00e003709..000000000 --- a/src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageSenderInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -sender->send($shortMessage); - } -} diff --git a/src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageTransporterInterface.php b/src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageTransporterInterface.php deleted file mode 100644 index b8832f507..000000000 --- a/src/Bundle/ChillMainBundle/Service/ShortMessage/ShortMessageTransporterInterface.php +++ /dev/null @@ -1,24 +0,0 @@ -phoneNumberUtil->format($shortMessage->getPhoneNumber(), PhoneNumberFormat::E164); - - $response = $this->api->post( - strtr('/sms/{serviceName}/jobs', ['{serviceName}' => $this->serviceName]), - [ - 'message' => $shortMessage->getContent(), - 'receivers' => [$receiver], - 'sender' => $this->sender, - 'noStopClause' => true, - 'coding' => '7bit', - 'charset' => 'UTF-8', - 'priority' => $shortMessage->getPriority(), - ] - ); - - $improved = array_merge([ - 'validReceiversI' => implode(',', $response['validReceivers']), - 'idsI' => implode(',', $response['ids']), - ], $response); - - $this->logger->warning('[sms] a sms was sent', $improved); - } -} diff --git a/symfony.lock b/symfony.lock index 7d33810ea..5aac276ab 100644 --- a/symfony.lock +++ b/symfony.lock @@ -308,6 +308,15 @@ "config/packages/notifier.yaml" ] }, + "symfony/ovh-cloud-notifier": { + "version": "5.4", + "recipe": { + "repo": "github.com/symfony/recipes", + "branch": "main", + "version": "5.1", + "ref": "fe2e382c22d60eae9ad54cb22862b1c15291fdf8" + } + }, "symfony/phpunit-bridge": { "version": "7.1", "recipe": { From 20bfd5b717d0a0ef8ad4848b88fcecef9d46624c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julien=20Fastr=C3=A9?= Date: Mon, 20 Jan 2025 15:01:34 +0100 Subject: [PATCH 5/5] Add Rector command to composer scripts Included the Rector command in composer.json to streamline running Rector tasks. This addition ensures consistency and improves developer efficiency by integrating the tool directly into the project workflow. --- composer.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/composer.json b/composer.json index 3ef287196..d4134c916 100644 --- a/composer.json +++ b/composer.json @@ -163,7 +163,8 @@ "assets:install %PUBLIC_DIR%": "symfony-cmd" }, "php-cs-fixer": "php-cs-fixer fix --config=./.php-cs-fixer.dist.php --show-progress=none", - "phpstan": "phpstan --no-progress" + "phpstan": "phpstan --no-progress", + "rector": "rector --no-progress-bar" }, "extra": { "symfony": {