Merge branch 'short-message-use-notifier-component' into 'master'

Send short messages using Notifier integration

See merge request Chill-Projet/chill-bundles!782
This commit is contained in:
Julien Fastré 2025-01-20 14:17:01 +00:00
commit 3f1a4fe353
25 changed files with 254 additions and 308 deletions

4
.env
View File

@ -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 ###

View File

@ -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,7 +58,9 @@
"symfony/messenger": "^5.4",
"symfony/mime": "^5.4",
"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",
@ -161,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": {

View File

@ -0,0 +1,13 @@
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
urgent: ['email']
high: ['email']
medium: ['email']
low: ['email']
admin_recipients:
- { email: admin@example.com }

View File

@ -16,7 +16,7 @@ Welcome to Chill documentation!
Chill is a free software for social workers.
Chill rely on the php framework `Symfony <http://symfony.com>`_.
Chill rely on the php framework `Symfony <http://symfony.com>`_.
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 <https://fr.wikibooks.org/wiki/Chill>`_
@ -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 :

View File

@ -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');

View File

@ -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);

View File

@ -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;
}

View File

@ -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<SmsMessage>
*
* @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
);
}
}

View File

@ -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<SmsMessage>
*/
public function buildMessageForCalendar(Calendar $calendar): array;
}

View File

@ -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()
);

View File

@ -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());
}
}

View File

@ -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);
}
}

View File

@ -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', [

View File

@ -1,91 +0,0 @@
<?php
/**
* Chill is a software for social workers.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\DependencyInjection\CompilerPass;
use Chill\MainBundle\Service\ShortMessage\NullShortMessageSender;
use Chill\MainBundle\Service\ShortMessage\ShortMessageTransporter;
use Chill\MainBundle\Service\ShortMessageOvh\OvhShortMessageSender;
use libphonenumber\PhoneNumberUtil;
use Psr\Log\LoggerInterface;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Definition;
use Symfony\Component\DependencyInjection\Exception\RuntimeException;
use Symfony\Component\DependencyInjection\Reference;
class ShortMessageCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$config = $container->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);
}
}

View File

@ -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')

View File

@ -0,0 +1,54 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\Notifier;
use Symfony\Component\Notifier\Exception\UnsupportedSchemeException;
use Symfony\Component\Notifier\Transport\AbstractTransportFactory;
use Symfony\Component\Notifier\Transport\Dsn;
use Symfony\Component\Notifier\Transport\TransportInterface;
/**
* This is a legacy ovh cloud provider, to provide the regular OvhCloudTransporter from the previous configuration.
*
* This is only for transition purpose from the previous ovh dsn, which was existing in chill.
*/
class LegacyOvhCloudFactory extends AbstractTransportFactory
{
protected function getSupportedSchemes(): array
{
return ['ovh'];
}
public function create(Dsn $dsn): TransportInterface
{
$scheme = $dsn->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);
}
}

View File

@ -0,0 +1,37 @@
<?php
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\Notifier;
use Psr\Log\LoggerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Notifier\Event\SentMessageEvent;
final readonly class SentMessageEventSubscriber implements EventSubscriberInterface
{
public function __construct(
private LoggerInterface $logger,
) {}
public static function getSubscribedEvents()
{
return [
SentMessageEvent::class => ['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()]);
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Chill is a software for social workers.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\ShortMessage;
class NullShortMessageSender implements ShortMessageSenderInterface
{
public function send(ShortMessage $shortMessage): void {}
}

View File

@ -20,6 +20,8 @@ namespace Chill\MainBundle\Service\ShortMessage;
use libphonenumber\PhoneNumber;
trigger_deprecation('chill-project/chill-bundles', '3.7', 'Short Messages are deprecated, use SmsMessage and Notifier component instead');
class ShortMessage
{
final public const PRIORITY_LOW = 'low';

View File

@ -18,17 +18,33 @@ declare(strict_types=1);
namespace Chill\MainBundle\Service\ShortMessage;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use Symfony\Component\Messenger\Handler\MessageHandlerInterface;
use Symfony\Component\Notifier\Message\SmsMessage;
use Symfony\Component\Notifier\TexterInterface;
/**
* @AsMessageHandler
*/
class ShortMessageHandler implements MessageHandlerInterface
{
public function __construct(private readonly ShortMessageTransporterInterface $messageTransporter) {}
private readonly PhoneNumberUtil $phoneNumberUtil;
public function __construct(private readonly TexterInterface $texter)
{
$this->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(),
),
);
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Chill is a software for social workers.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\ShortMessage;
interface ShortMessageSenderInterface
{
public function send(ShortMessage $shortMessage): void;
}

View File

@ -1,29 +0,0 @@
<?php
/**
* Chill is a software for social workers.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\ShortMessage;
class ShortMessageTransporter implements ShortMessageTransporterInterface
{
public function __construct(private readonly ShortMessageSenderInterface $sender) {}
public function send(ShortMessage $shortMessage): void
{
$this->sender->send($shortMessage);
}
}

View File

@ -1,24 +0,0 @@
<?php
/**
* Chill is a software for social workers.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\ShortMessage;
interface ShortMessageTransporterInterface
{
public function send(ShortMessage $shortMessage);
}

View File

@ -1,65 +0,0 @@
<?php
/**
* Chill is a software for social workers.
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
declare(strict_types=1);
/*
* Chill is a software for social workers
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/
namespace Chill\MainBundle\Service\ShortMessageOvh;
use Chill\MainBundle\Service\ShortMessage\ShortMessage;
use Chill\MainBundle\Service\ShortMessage\ShortMessageSenderInterface;
use libphonenumber\PhoneNumberFormat;
use libphonenumber\PhoneNumberUtil;
use Ovh\Api;
use Psr\Log\LoggerInterface;
class OvhShortMessageSender implements ShortMessageSenderInterface
{
public function __construct(
private readonly Api $api,
// for DI, must remains as first argument
private readonly string $serviceName,
// for di, must remains as second argument
private readonly string $sender,
// for DI, must remains as third argument
private readonly LoggerInterface $logger,
private readonly PhoneNumberUtil $phoneNumberUtil,
) {}
public function send(ShortMessage $shortMessage): void
{
$receiver = $this->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);
}
}

View File

@ -296,6 +296,27 @@
"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/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": {