diff --git a/composer.json b/composer.json index 56c84b0..73e871a 100644 --- a/composer.json +++ b/composer.json @@ -9,7 +9,7 @@ "license": "MIT", "require": { "php": "^8.0", - "bentools/webpush-bundle": "0.9", + "bentools/webpush-bundle": "0.12", "sylius/mailer-bundle": "^1.8 || ^2.0@beta", "sylius/sylius": "^1.9", "symfony/webpack-encore-bundle": "^1.15" diff --git a/src/Controller/Admin/SendPushNotificationAction.php b/src/Controller/Admin/SendPushNotificationAction.php index f4755cd..dcda0ff 100644 --- a/src/Controller/Admin/SendPushNotificationAction.php +++ b/src/Controller/Admin/SendPushNotificationAction.php @@ -4,31 +4,22 @@ namespace SpearDevs\SyliusPushNotificationsPlugin\Controller\Admin; +use Psr\Log\LoggerInterface; use SpearDevs\SyliusPushNotificationsPlugin\Context\ChannelContextInterface; -use SpearDevs\SyliusPushNotificationsPlugin\Factory\Interfaces\WebPushFactoryInterface; +use SpearDevs\SyliusPushNotificationsPlugin\Form\Model\SendPushNotificationFormModel; use SpearDevs\SyliusPushNotificationsPlugin\Form\Type\Admin\SendPushNotificationType; -use SpearDevs\SyliusPushNotificationsPlugin\ParameterMapper\ParameterMapperInterface; use SpearDevs\SyliusPushNotificationsPlugin\WebPushSender\WebPushSenderInterface; -use Sylius\Component\Core\Model\ChannelInterface; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; -use Symfony\Contracts\Translation\TranslatorInterface; -use Twig\Environment; +use Symfony\Component\Translation\TranslatableMessage; final class SendPushNotificationAction extends AbstractController { - public const USER_RECEIVER = 'user'; - - public const GROUP_RECEIVER = 'group'; - public function __construct( - private Environment $twig, - private TranslatorInterface $translator, private WebPushSenderInterface $webPushSender, private ChannelContextInterface $channelContext, - private WebPushFactoryInterface $webPushFactory, - private ParameterMapperInterface $orderParameterMapper, + private LoggerInterface $logger, ) { } @@ -39,37 +30,27 @@ public function __invoke(Request $request): Response $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { - $data = $form->getData(); - - $pushTitle = $data['title'] ?? ''; - $pushContent = $data['body'] ?? ''; - $customerGroup = $data['groups']?->getName() ?? ''; - $receiver = $data['receiver'] ?? ''; - $user = $data['user']?->getUsername() ?? ''; - - $this->channelContext->setChannelCode($data['channel']->getCode()); - - /** @var ChannelInterface $channel */ - $channel = $this->channelContext->getChannel(); - - $webPush = $this->webPushFactory->create($this->orderParameterMapper, null, null, $pushTitle, $pushContent); - - if ($receiver === self::USER_RECEIVER) { - $this->webPushSender->sendToUser($webPush, $channel, $user); + try { + /** @var SendPushNotificationFormModel $data */ + $data = $form->getData(); + $channel = $data->channel; + $this->channelContext->setChannelCode($channel->getCode()); + $this->webPushSender->sendWebPush($data); + + $this->addFlash('success', new TranslatableMessage( + 'speardevs_sylius_push_notifications_plugin.ui.sent_success', + )); + } catch (\Exception $exception) { + $this->logger->error('Problem while sending push notifications ' . $exception->getMessage()); + + $this->addFlash('error', new TranslatableMessage( + 'speardevs_sylius_push_notifications_plugin.ui.sent_error', + )); } - if ($receiver === self::GROUP_RECEIVER) { - $this->webPushSender->sendToGroup($webPush, $channel, $customerGroup); - } - - $this->addFlash('success', $this->translator->trans('speardevs_sylius_push_notifications_plugin.ui.sent_success')); - return $this->redirect($request->getUri()); } - return new Response($this->twig->render( - $request->get('template'), - ['form' => $form->createView()], - )); + return $this->render($request->get('template'), ['form' => $form->createView()]); } } diff --git a/src/Form/Model/SendPushNotificationFormModel.php b/src/Form/Model/SendPushNotificationFormModel.php new file mode 100644 index 0000000..b236e8d --- /dev/null +++ b/src/Form/Model/SendPushNotificationFormModel.php @@ -0,0 +1,30 @@ + [ 'class' => 'form-control', ], - 'constraints' => [ - new NotBlank(), - ], ]) ->add('body', TextareaType::class, [ 'label' => 'speardevs_sylius_push_notifications_plugin.ui.content', @@ -42,19 +38,11 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'class' => 'form-control', 'rows' => 4, ], - 'constraints' => [ - new NotBlank(), - ], ]) ->add('channel', EntityType::class, [ 'label' => 'sylius.ui.channel', 'required' => true, 'class' => Channel::class, - 'constraints' => [ - new NotBlank([ - 'groups' => 'sylius', - ]), - ], ]) ->add('receiver', ChoiceType::class, [ 'label' => 'speardevs_sylius_push_notifications_plugin.ui.receiver', @@ -63,7 +51,7 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'speardevs_sylius_push_notifications_plugin.ui.user' => 'user', ], ]) - ->add('groups', EntityType::class, [ + ->add('group', EntityType::class, [ 'label' => 'speardevs_sylius_push_notifications_plugin.ui.send_to', 'class' => CustomerGroup::class, 'required' => false, @@ -73,25 +61,15 @@ public function buildForm(FormBuilderInterface $builder, array $options): void 'messages', ), ]) - ->add('user', EntityType::class, [ + ->add('userEmail', EmailType::class, [ 'label' => 'speardevs_sylius_push_notifications_plugin.ui.user', - 'class' => ShopUser::class, - 'required' => false, - 'placeholder' => $this->translator->trans( - 'speardevs_sylius_push_notifications_plugin.ui.choose_user', - [], - 'messages', - ), - 'query_builder' => function (EntityRepository $shopUserRepository) { - return $shopUserRepository->createQueryBuilder('shopUser') - ->leftJoin( - UserSubscription::class, - 'userSubscription', - 'WITH', - 'userSubscription.user = shopUser.id', - ) - ->where('userSubscription IS NOT NULL'); - }, ]); } + + public function configureOptions(OptionsResolver $resolver): void + { + $resolver->setDefaults([ + 'data_class' => SendPushNotificationFormModel::class, + ]); + } } diff --git a/src/Validator/Constraints/PushNotificationUserSubscriptionExists.php b/src/Validator/Constraints/PushNotificationUserSubscriptionExists.php new file mode 100644 index 0000000..0845754 --- /dev/null +++ b/src/Validator/Constraints/PushNotificationUserSubscriptionExists.php @@ -0,0 +1,20 @@ +receiver === WebPushSender::GROUP_RECEIVER) { + return; + } + + $subscriptions = $this->userSubscriptionRepository->getSubscriptionsForUserByEmail( + $value->userEmail, + $value->channel, + ); + + /** @var Traversable $subscriptions * */ + $subscriptionCount = iterator_count($subscriptions); + + if ($subscriptionCount > 0) { + return; + } + + $this->context + ->buildViolation($constraint->message) + ->atPath('userEmail') + ->addViolation(); + } +} diff --git a/src/WebPushSender/WebPushSender.php b/src/WebPushSender/WebPushSender.php index 8b02d53..7fe7bb9 100644 --- a/src/WebPushSender/WebPushSender.php +++ b/src/WebPushSender/WebPushSender.php @@ -10,6 +10,7 @@ use SpearDevs\SyliusPushNotificationsPlugin\Context\ChannelContextInterface; use SpearDevs\SyliusPushNotificationsPlugin\Entity\PushNotificationTemplate\PushNotificationTemplate; use SpearDevs\SyliusPushNotificationsPlugin\Factory\Interfaces\WebPushFactoryInterface; +use SpearDevs\SyliusPushNotificationsPlugin\Form\Model\SendPushNotificationFormModel; use SpearDevs\SyliusPushNotificationsPlugin\ParameterMapper\ParameterMapperInterface; use SpearDevs\SyliusPushNotificationsPlugin\Repository\PushNotificationTemplate\PushNotificationTemplateRepositoryInterface; use SpearDevs\SyliusPushNotificationsPlugin\Repository\UserSubscriptionRepositoryInterface; @@ -27,6 +28,10 @@ final class WebPushSender implements WebPushSenderInterface public const PUSH_ORDER_SHIPPED_CODE = "'push_order_shipped'"; + public const USER_RECEIVER = 'user'; + + public const GROUP_RECEIVER = 'group'; + public function __construct( private UserSubscriptionRepositoryInterface $userSubscriptionRepository, private UserSubscriptionManagerInterface $userSubscriptionManager, @@ -40,6 +45,26 @@ public function __construct( ) { } + public function sendWebPush(SendPushNotificationFormModel $sendPushNotificationFormModel): void + { + $pushTitle = $sendPushNotificationFormModel->title; + $pushContent = $sendPushNotificationFormModel->body; + $receiver = $sendPushNotificationFormModel->receiver; + $channel = $sendPushNotificationFormModel->channel; + + $webPush = $this->webPushFactory->create($this->orderParameterMapper, null, null, $pushTitle, $pushContent); + + if ($receiver === self::USER_RECEIVER) { + $userEmail = $sendPushNotificationFormModel->userEmail; + $this->sendToUser($webPush, $channel, $userEmail); + } + + if ($receiver === self::GROUP_RECEIVER) { + $customerGroup = $sendPushNotificationFormModel->group; + $this->sendToGroup($webPush, $channel, $customerGroup?->getName()); + } + } + public function sendToGroup(WebPushInterface $webPush, ChannelInterface $channel, ?string $receiver = null): void { $subscriptions = ($receiver) ? diff --git a/src/WebPushSender/WebPushSenderInterface.php b/src/WebPushSender/WebPushSenderInterface.php index 847f018..99a7e61 100644 --- a/src/WebPushSender/WebPushSenderInterface.php +++ b/src/WebPushSender/WebPushSenderInterface.php @@ -4,12 +4,15 @@ namespace SpearDevs\SyliusPushNotificationsPlugin\WebPushSender; +use SpearDevs\SyliusPushNotificationsPlugin\Form\Model\SendPushNotificationFormModel; use SpearDevs\SyliusPushNotificationsPlugin\WebPush\WebPushInterface; use Sylius\Component\Core\Model\ChannelInterface; use Sylius\Component\Core\Model\OrderInterface; interface WebPushSenderInterface { + public function sendWebPush(SendPushNotificationFormModel $sendPushNotificationFormModel): void; + public function sendToGroup(WebPushInterface $webPush, ChannelInterface $channel, ?string $receiver = null): void; public function sendToUser(WebPushInterface $webPush, ChannelInterface $channel, ?string $receiver = null): void; diff --git a/templates/Admin/PushNotifications/Generate/_form.html.twig b/templates/Admin/PushNotifications/Generate/_form.html.twig index 551a09f..0de7ef9 100644 --- a/templates/Admin/PushNotifications/Generate/_form.html.twig +++ b/templates/Admin/PushNotifications/Generate/_form.html.twig @@ -10,14 +10,12 @@ {{ form_row(form.receiver, { attr: { 'data-form-field': 'receiver' } }) }} -