Skip to content

Ibexa Notifications#3090

Draft
adriendupuis wants to merge 5 commits into5.0from
notifications
Draft

Ibexa Notifications#3090
adriendupuis wants to merge 5 commits into5.0from
notifications

Conversation

@adriendupuis
Copy link
Contributor

Question Answer
JIRA Ticket
Versions
Edition

Document ibexa/notifications

Checklist

  • Text renders correctly
  • Text has been checked with vale
  • Description metadata is up to date
  • Redirects cover removed/moved pages
  • Code samples are working
  • PHP code samples have been fixed with PHP CS fixer
  • Added link to this PR in relevant JIRA ticket or code PR

@github-actions
Copy link

github-actions bot commented Mar 17, 2026

@sonarqubecloud
Copy link

Quality Gate Failed Quality Gate failed

Failed conditions
1 Security Hotspot

See analysis details on SonarQube Cloud

@github-actions
Copy link

code_samples/ change report

Before (on target branch)After (in current PR)

code_samples/user_management/notifications/config/packages/custom_notifications.yaml


code_samples/user_management/notifications/config/packages/custom_notifications.yaml

docs/users/notifications.md@38:``` yaml
docs/users/notifications.md@39:[[= include_file('code_samples/user_management/notifications/config/packages/custom_notifications.yaml', 0, 18) =]]
docs/users/notifications.md@40:```

001⫶framework:
002⫶ notifier:
003⫶ chatter_transports:
004⫶ slack: '%env(SLACK_DSN)%'
005⫶ibexa:
006⫶ system:
007⫶ default:
008⫶ notifier:
009⫶ subscriptions:
010⫶ Ibexa\OrderManagement\Notification\OrderStatusChange:
011⫶ channels:
012⫶ - chat
013⫶ Ibexa\Payment\Notification\PaymentStatusChange:
014⫶ channels:
015⫶ - chat
016⫶ Ibexa\Shipping\Notification\ShipmentStatusChange:
017⫶ channels:
018⫶ - chat

docs/users/notifications.md@75:``` yaml
docs/users/notifications.md@76:[[= include_file('code_samples/user_management/notifications/config/packages/custom_notifications.yaml', 5, 9) =]] # …
docs/users/notifications.md@77:[[= include_file('code_samples/user_management/notifications/config/packages/custom_notifications.yaml', 18) =]]
docs/users/notifications.md@78:```

001⫶ system:
002⫶ default:
003⫶ notifier:
004⫶ subscriptions:
005⫶ # …


code_samples/user_management/notifications/src/Command/NotificationSenderCommand.php


code_samples/user_management/notifications/src/Command/NotificationSenderCommand.php

docs/users/notifications.md@82:``` php
docs/users/notifications.md@83:[[= include_file('code_samples/user_management/notifications/src/Command/NotificationSenderCommand.php') =]]
docs/users/notifications.md@84:```

001⫶<?php
002⫶
003⫶declare(strict_types=1);
004⫶
005⫶namespace App\src\Command;
006⫶
007⫶use App\Notifications\CommandExecuted;
008⫶use Ibexa\Contracts\Core\Repository\UserService;
009⫶use Ibexa\Contracts\Notifications\Service\NotificationServiceInterface;
010⫶use Ibexa\Contracts\Notifications\Value\Notification\SymfonyNotificationAdapter;
011⫶use Ibexa\Contracts\Notifications\Value\Recipent\SymfonyRecipientAdapter;
012⫶use Ibexa\Contracts\Notifications\Value\Recipent\UserRecipient;
013⫶use Symfony\Component\Console\Attribute\AsCommand;
014⫶use Symfony\Component\Console\Command\Command;
015⫶use Symfony\Component\Console\Input\InputInterface;
016⫶use Symfony\Component\Console\Output\OutputInterface;
017⫶use Symfony\Component\Notifier\Recipient\RecipientInterface;
018⫶
019⫶#[AsCommand(name: 'app:send_notification', description: 'Example of command sending a notification')]
020⫶class NotificationSenderCommand extends Command
021⫶{
022⫶ /** @param array<int, string> $recipientLogins */
023⫶ public function __construct(
024⫶ private readonly NotificationServiceInterface $notificationService,
025⫶ private readonly UserService $userService,
026⫶ private readonly array $recipientLogins = ['admin'],
027⫶ ) {
028⫶ parent::__construct();
029⫶ }
030⫶
031⫶ protected function execute(InputInterface $input, OutputInterface $output): int
032⫶ {
033⫶ /** @var array<int, \Throwable> $exceptions */
034⫶ $exceptions = [];
035⫶
036⫶ try {
037⫶ // Do something
038⫶ if (rand(0, 1) == 1) {
039⫶ throw new \RuntimeException('Something went wrong');
040⫶ }
041⫶ $exitCode = Command::SUCCESS;
042⫶ } catch (\Exception $exception) {
043⫶ $exceptions[] = $exception;
044⫶ $exitCode = Command::FAILURE;
045⫶ }
046⫶
047⫶ $recipients = [];
048⫶ foreach ($this->recipientLogins as $login) {
049⫶ try {
050⫶ $user = $this->userService->loadUserByLogin($login);
051⫶ $recipients[] = new UserRecipient($user);
052⫶ } catch (\Exception $exception) {
053⫶ $exceptions[] = $exception;
054⫶ }
055⫶ }
056⫶
057⫶ $this->notificationService->send(
058⫶ new SymfonyNotificationAdapter(new CommandExecuted($this, $exitCode, $exceptions)),
059⫶ array_map(
060⫶ static fn (RecipientInterface $recipient): SymfonyRecipientAdapter => new SymfonyRecipientAdapter($recipient),
061⫶ $recipients
062⫶ )
063⫶ );
064⫶
065⫶ return $exitCode;
066⫶ }
067⫶}


code_samples/user_management/notifications/src/Notifications/CommandExecuted.php


code_samples/user_management/notifications/src/Notifications/CommandExecuted.php

docs/users/notifications.md@69:``` php
docs/users/notifications.md@70:[[= include_file('code_samples/user_management/notifications/src/Notifications/CommandExecuted.php') =]]
docs/users/notifications.md@71:```

001⫶<?php declare(strict_types=1);
002⫶
003⫶namespace App\Notifications;
004⫶
005⫶use Ibexa\Contracts\Notifications\SystemNotification\SystemMessage;
006⫶use Ibexa\Contracts\Notifications\SystemNotification\SystemNotificationInterface;
007⫶use Ibexa\Contracts\Notifications\Value\Recipent\UserRecipientInterface;
008⫶use Symfony\Bridge\Twig\Mime\NotificationEmail;
009⫶use Symfony\Component\Console\Command\Command;
010⫶use Symfony\Component\Notifier\Message\EmailMessage;
011⫶use Symfony\Component\Notifier\Notification\EmailNotificationInterface;
012⫶use Symfony\Component\Notifier\Notification\Notification;
013⫶use Symfony\Component\Notifier\Recipient\EmailRecipientInterface;
014⫶use Throwable;
015⫶
016⫶class CommandExecuted extends Notification implements SystemNotificationInterface, EmailNotificationInterface
017⫶{
018⫶ /** @param array<int, Throwable> $exceptions */
019⫶ public function __construct(
020⫶ private readonly Command $command,
021⫶ private readonly int $exitCode,
022⫶ private readonly array $exceptions
023⫶ ) {
024⫶ parent::__construct($this->command->getName());
025⫶ }
026⫶
027⫶ public function asEmailMessage(EmailRecipientInterface $recipient, ?string $transport = null): ?EmailMessage
028⫶ {
029⫶ $subject = (0 === $this->exitCode ? '✔' : '✖') . $this->command->getName();
030⫶
031⫶ $body = '';
032⫶ foreach ($this->exceptions as $exception) {
033⫶ $body .= $exception->getMessage() . '<br>';
034⫶ }
035⫶
036⫶ $email = NotificationEmail::asPublicEmail()
037⫶ ->to($recipient->getEmail())
038⫶ ->subject($subject)
039⫶ ->html($body);
040⫶
041⫶ return new EmailMessage($email);
042⫶ }
043⫶
044⫶ public function asSystemNotification(UserRecipientInterface $recipient, ?string $transport = null): ?SystemMessage
045⫶ {
046⫶ $message = new SystemMessage($recipient->getUser());
047⫶ $message->setContext([
048⫶ 'icon' => 0 === $this->exitCode ? 'check-circle' : 'discard-circle',
049⫶ 'subject' => $this->command->getName(),
050⫶ 'content' => 0 === $this->exitCode ? 'No error' : count($this->exceptions) . ' error' . (count($this->exceptions) > 1 ? 's' : ''),
051⫶ ]);
052⫶
053⫶ return $message;
054⫶ }
055⫶}

Download colorized diff

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant