Skip to content

Instantly share code, notes, and snippets.

@norkunas
Last active November 6, 2023 15:21
Show Gist options
  • Select an option

  • Save norkunas/987c82e964027c4d31f37d4197fd2931 to your computer and use it in GitHub Desktop.

Select an option

Save norkunas/987c82e964027c4d31f37d4197fd2931 to your computer and use it in GitHub Desktop.
Simple user notifications with Symfony Notifier
<?php
declare(strict_types=1);
namespace App\Notifier\Channel\Doctrine;
use App\Message\DoctrineNotificationMessage;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Notifier\Channel\ChannelInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
final class DoctrineChannel implements ChannelInterface
{
private MessageBusInterface $messageBus;
public function __construct(MessageBusInterface $messageBus)
{
$this->messageBus = $messageBus;
}
public function notify(Notification $notification, RecipientInterface $recipient, string $transportName = null): void
{
$message = null;
if ($notification instanceof DoctrineNotificationInterface) {
$message = $notification->asDoctrineMessage($recipient, $transportName);
}
if ($message === null) {
$message = DoctrineNotificationMessage::fromNotification($notification, $recipient);
}
$this->messageBus->dispatch($message);
}
public function supports(Notification $notification, RecipientInterface $recipient): bool
{
return $recipient instanceof DoctrineRecipientInterface;
}
}
<?php
declare(strict_types=1);
namespace App\Notifier\Channel\Doctrine;
use App\Message\DoctrineNotificationMessage;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
interface DoctrineNotificationInterface
{
public function asDoctrineMessage(RecipientInterface $recipient, string $transport = null): ?DoctrineNotificationMessage;
}
<?php
declare(strict_types=1);
namespace App\Message;
use App\Notifier\Channel\Doctrine\DoctrineNotificationInterface;
use App\Notifier\Channel\Doctrine\DoctrineRecipientInterface;
use Symfony\Component\Notifier\Exception\LogicException;
use Symfony\Component\Notifier\Message\MessageInterface;
use Symfony\Component\Notifier\Message\MessageOptionsInterface;
use Symfony\Component\Notifier\Notification\Notification;
use Symfony\Component\Notifier\Recipient\RecipientInterface;
final class DoctrineNotificationMessage implements MessageInterface
{
private string $userId;
private string $subject;
private string $content;
private array $payload;
public function __construct(string $userId, string $subject, string $content, array $payload = [])
{
$this->userId = $userId;
$this->subject = $subject;
$this->content = $content;
$this->payload = $payload;
}
public static function fromNotification(Notification $notification, RecipientInterface $recipient): self
{
assert($recipient instanceof DoctrineRecipientInterface);
return new self($recipient->getUserId(), $notification->getSubject(), $notification->getContent());
}
public function userId(string $userId): self
{
$this->userId = $userId;
return $this;
}
public function getUserId(): string
{
return $this->userId;
}
public function getRecipientId(): string
{
return $this->userId;
}
/**
* @return $this
*/
public function subject(string $subject): self
{
$this->subject = $subject;
return $this;
}
public function getSubject(): string
{
return $this->subject;
}
/**
* @return $this
*/
public function content(string $content): self
{
$this->content = $content;
return $this;
}
public function getContent(): string
{
return $this->content;
}
/**
* @return $this
*/
public function payload(array $payload): self
{
$this->payload = $payload;
return $this;
}
public function getPayload(): array
{
return $this->payload;
}
public function getTransport(): ?string
{
return null;
}
public function getOptions(): ?MessageOptionsInterface
{
return null;
}
}
<?php
declare(strict_types=1);
namespace App\MessageHandler;
use App\Entity\User\UserNotification;
use App\Message\DoctrineNotificationMessage;
use App\Repository\UserRepositoryInterface;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\Uid\Uuid;
final class DoctrineNotificationMessageHandler
{
private UserRepositoryInterface $userRepository;
private EntityManagerInterface $entityManager;
public function __construct(UserRepositoryInterface $userRepository, EntityManagerInterface $entityManager)
{
$this->userRepository = $userRepository;
$this->entityManager = $entityManager;
}
public function __invoke(DoctrineNotificationMessage $message): void
{
$user = $this->userRepository->find($message->getUserId());
if ($user === null) {
return;
}
$notification = new UserNotification(Uuid::v4(), $user, $message->getSubject(), $message->getContent(), $message->getPayload());
$this->entityManager->persist($notification);
$this->entityManager->flush();
}
}
<?php
declare(strict_types=1);
namespace App\Notifier\Channel\Doctrine;
interface DoctrineRecipientInterface
{
public function getUserId(): string;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment