Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update translates, send push notification by enter user email #39

Merged
merged 3 commits into from
Jul 30, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/.idea
Codeweld marked this conversation as resolved.
Show resolved Hide resolved
/vendor/
/node_modules/
/composer.lock
Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
61 changes: 21 additions & 40 deletions src/Controller/Admin/SendPushNotificationAction.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
) {
}

Expand All @@ -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()]);
}
}
30 changes: 30 additions & 0 deletions src/Form/Model/SendPushNotificationFormModel.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace SpearDevs\SyliusPushNotificationsPlugin\Form\Model;

use SpearDevs\SyliusPushNotificationsPlugin\Validator\Constraints\PushNotificationUser;
use Sylius\Component\Core\Model\ChannelInterface;
use Sylius\Component\Customer\Model\CustomerGroupInterface;
use Symfony\Component\Validator\Constraints as Assert;

/** @PushNotificationUser() */
final class SendPushNotificationFormModel
TomaszLach2 marked this conversation as resolved.
Show resolved Hide resolved
{
/** @Assert\NotBlank() */
public ?string $title = null;
Codeweld marked this conversation as resolved.
Show resolved Hide resolved

/** @Assert\NotBlank() */
public ?string $body = null;

/** @Assert\NotBlank() */
public ?ChannelInterface $channel = null;

public ?string $receiver = null;

public ?CustomerGroupInterface $group = null;

/** @Assert\Email() */
public ?string $userEmail = null;
}
46 changes: 12 additions & 34 deletions src/Form/Type/Admin/SendPushNotificationType.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,17 @@

namespace SpearDevs\SyliusPushNotificationsPlugin\Form\Type\Admin;

use Doctrine\ORM\EntityRepository;
use SpearDevs\SyliusPushNotificationsPlugin\Entity\UserSubscription\UserSubscription;
use SpearDevs\SyliusPushNotificationsPlugin\Form\Model\SendPushNotificationFormModel;
use Sylius\Component\Core\Model\Channel;
use Sylius\Component\Core\Model\ShopUser;
use Sylius\Component\Customer\Model\CustomerGroup;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Form\Extension\Core\Type\EmailType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Validator\Constraints\NotBlank;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Contracts\Translation\TranslatorInterface;

class SendPushNotificationType extends AbstractType
Expand All @@ -32,29 +31,18 @@ public function buildForm(FormBuilderInterface $builder, array $options): void
'attr' => [
'class' => 'form-control',
],
'constraints' => [
new NotBlank(),
],
])
->add('body', TextareaType::class, [
'label' => 'speardevs_sylius_push_notifications_plugin.ui.content',
'attr' => [
'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',
Expand All @@ -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,
Expand All @@ -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,
]);
}
}
20 changes: 20 additions & 0 deletions src/Validator/Constraints/PushNotificationUser.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

declare(strict_types=1);

namespace SpearDevs\SyliusPushNotificationsPlugin\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
* @Annotation
*/
class PushNotificationUser extends Constraint
Codeweld marked this conversation as resolved.
Show resolved Hide resolved
{
public string $message = 'push_notifications.send.user_subscription_not_exist';

public function getTargets(): string
{
return self::CLASS_CONSTRAINT;
}
}
52 changes: 52 additions & 0 deletions src/Validator/Constraints/PushNotificationUserValidator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace SpearDevs\SyliusPushNotificationsPlugin\Validator\Constraints;

use SpearDevs\SyliusPushNotificationsPlugin\Form\Model\SendPushNotificationFormModel;
use SpearDevs\SyliusPushNotificationsPlugin\Repository\UserSubscriptionRepositoryInterface;
use SpearDevs\SyliusPushNotificationsPlugin\WebPushSender\WebPushSender;
use Symfony\Component\Form\Exception\UnexpectedTypeException;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Traversable;

final class PushNotificationUserValidator extends ConstraintValidator
Codeweld marked this conversation as resolved.
Show resolved Hide resolved
{
public function __construct(
private UserSubscriptionRepositoryInterface $userSubscriptionRepository,
) {
}

/**
* @param SendPushNotificationFormModel $value
*/
public function validate($value, Constraint $constraint): void
{
if (!$constraint instanceof PushNotificationUser) {
throw new UnexpectedTypeException($constraint, PushNotificationUser::class);
}

if ($value === null || $value === '' || $value->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();
}
}
25 changes: 25 additions & 0 deletions src/WebPushSender/WebPushSender.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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,
Expand All @@ -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;
$userEmail = $sendPushNotificationFormModel->userEmail;
$customerGroup = $sendPushNotificationFormModel->group;

$webPush = $this->webPushFactory->create($this->orderParameterMapper, null, null, $pushTitle, $pushContent);

if ($receiver === self::USER_RECEIVER) {
$this->sendToUser($webPush, $channel, $userEmail);
}

if ($receiver === self::GROUP_RECEIVER) {
$this->sendToGroup($webPush, $channel, $customerGroup);
}
}

public function sendToGroup(WebPushInterface $webPush, ChannelInterface $channel, ?string $receiver = null): void
{
$subscriptions = ($receiver) ?
Expand Down
3 changes: 3 additions & 0 deletions src/WebPushSender/WebPushSenderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
10 changes: 4 additions & 6 deletions templates/Admin/PushNotifications/Generate/_form.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,12 @@

{{ form_row(form.receiver, { attr: { 'data-form-field': 'receiver' } }) }}

<div class="field" data-form-row="send-to">
{{ form_label(form.groups) }}
{{ form_widget(form.groups) }}
<div data-form-row="send-to">
{{ form_row(form.group) }}
</div>

<div class="field" data-form-row="user">
{{ form_label(form.user) }}
{{ form_widget(form.user) }}
<div data-form-row="user">
{{ form_row(form.userEmail) }}
</div>
</div>
</div>
Expand Down
1 change: 1 addition & 0 deletions tests/Application/config/bundles.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<?php

return [
Sylius\Abstraction\StateMachine\SyliusStateMachineAbstractionBundle::class => ['all' => true],
Codeweld marked this conversation as resolved.
Show resolved Hide resolved
Symfony\Bundle\FrameworkBundle\FrameworkBundle::class => ['all' => true],
Symfony\Bundle\MonologBundle\MonologBundle::class => ['all' => true],
Symfony\Bundle\SecurityBundle\SecurityBundle::class => ['all' => true],
Expand Down
Loading