- Removed SmsTextResolver dependency from multiple services and controllers. - Introduced dispatchTemplate method in SmsService to handle SMS sending with templates. - Updated existing SMS sending logic across various services (OtpService, PreRegistrationController, ClinicInvitationService, PaymentManager, SecretaryController, RepresentationActionController) to utilize the new dispatchTemplate method. - Enhanced SmsMessageTemplate entity to include kavenegar_template and token_map fields. - Created migration to add new fields to the sms_message_templates table and populate them with existing data. - Updated SeedSmsMessageTemplatesCommand to handle new template structure. - Added documentation for the new SMS template structure and usage.
98 lines
3.5 KiB
PHP
98 lines
3.5 KiB
PHP
<?php
|
|
|
|
namespace App\Sms\Service;
|
|
|
|
use App\Sms\Entity\SmsLog;
|
|
use App\Sms\Entity\SmsMessageTemplate;
|
|
use App\Sms\Message\SendSmsMessage;
|
|
use App\Sms\Provider\KavehNegarProvider;
|
|
use App\Sms\Provider\RanginehProvider;
|
|
use App\Sms\Provider\SmsProviderInterface;
|
|
use App\Sms\Repository\SmsLogRepository;
|
|
use App\Sms\Repository\SmsMessageTemplateRepository;
|
|
use Symfony\Component\Messenger\MessageBusInterface;
|
|
|
|
class SmsService
|
|
{
|
|
private array $providers;
|
|
|
|
public function __construct(
|
|
private readonly KavehNegarProvider $kavenegar,
|
|
private readonly RanginehProvider $rangineh,
|
|
private readonly SmsLogRepository $logRepo,
|
|
private readonly MessageBusInterface $bus,
|
|
private readonly SmsMessageTemplateRepository $messageTemplateRepo,
|
|
private readonly SmsTextResolver $textResolver,
|
|
) {
|
|
$this->providers = [
|
|
'kavenegar' => $kavenegar,
|
|
'rangineh' => $rangineh,
|
|
];
|
|
}
|
|
|
|
/**
|
|
* ارسال یک پیامک سیستمی از طریق تمپلت VerifyLookup کاوهنگار.
|
|
* فقط تگ + متغیرهای منطقی میگیرد؛ نام تمپلت و نگاشت token از SmsMessageTemplate (یا DEFAULTS) خوانده میشود.
|
|
*
|
|
* @param array<string,string|int> $vars متغیرهای منطقی (کلیدهای {...} بدنه)
|
|
*/
|
|
public function dispatchTemplate(string $tag, string $mobile, array $vars = [], string $provider = 'kavenegar'): void
|
|
{
|
|
$tpl = $this->messageTemplateRepo->findByTag($tag);
|
|
$kaveTemplate = $tpl?->getKavenegarTemplate()
|
|
?? (SmsMessageTemplate::DEFAULTS[$tag]['kavenegar_template'] ?? null);
|
|
$tokenMap = $tpl?->getTokenMap()
|
|
?: (SmsMessageTemplate::DEFAULTS[$tag]['token_map'] ?? []);
|
|
|
|
$message = $this->textResolver->resolve($tag, $vars);
|
|
|
|
if ($kaveTemplate === null || $tokenMap === []) {
|
|
$this->dispatchAsync($mobile, $message, $provider, tag: $tag);
|
|
return;
|
|
}
|
|
|
|
$slotVars = [];
|
|
foreach ($tokenMap as $logicalKey => $slot) {
|
|
if (array_key_exists($logicalKey, $vars)) {
|
|
$slotVars[$slot] = (string) $vars[$logicalKey];
|
|
}
|
|
}
|
|
|
|
$this->dispatchAsync($mobile, $message, $provider, templateVars: $slotVars, templateCode: $kaveTemplate, tag: $tag);
|
|
}
|
|
|
|
public function dispatchAsync(
|
|
string $mobile,
|
|
string $message,
|
|
string $provider = 'kavenegar',
|
|
?string $templateUuid = null,
|
|
array $templateVars = [],
|
|
?string $templateCode = null,
|
|
string $tag = SmsLog::TAG_GLOBAL,
|
|
): void {
|
|
$this->bus->dispatch(new SendSmsMessage(
|
|
$mobile, $message, $provider, $templateUuid, $templateVars, $templateCode, $tag
|
|
));
|
|
}
|
|
|
|
public function sendNow(SendSmsMessage $msg): bool
|
|
{
|
|
$provider = $this->resolveProvider($msg->provider);
|
|
|
|
$success = ($msg->templateCode !== null)
|
|
? $provider->sendTemplate($msg->mobile, $msg->templateCode, $msg->templateVars)
|
|
: $provider->send($msg->mobile, $msg->message);
|
|
|
|
$log = new SmsLog($msg->mobile, $msg->message, $provider->getName(), $success, $msg->tag);
|
|
if ($msg->templateUuid) $log->setTemplateUuid($msg->templateUuid);
|
|
$this->logRepo->save($log);
|
|
|
|
return $success;
|
|
}
|
|
|
|
private function resolveProvider(string $name): SmsProviderInterface
|
|
{
|
|
return $this->providers[$name] ?? $this->kavenegar;
|
|
}
|
|
}
|