phpsoftbox / notifications
Notification component for the PhpSoftBox framework
Requires
- php: ^8.4
- phpsoftbox/code-generator: dev-master
- phpsoftbox/collection: dev-master
- phpsoftbox/view: dev-master
- psr/log: ^3.0
Requires (Dev)
- friendsofphp/php-cs-fixer: ^3.93
- phpsoftbox/broadcaster: dev-master
- phpsoftbox/cli-app: dev-master
- phpsoftbox/cs-fixer: ^1.1.0
- phpsoftbox/database: dev-master
- phpsoftbox/mailer: dev-master
- phpsoftbox/telegram: dev-master
- phpunit/phpunit: ^11.2
This package is auto-updated.
Last update: 2026-03-05 13:25:51 UTC
README
Компонент уведомлений для PhpSoftBox: менеджер, каналы, драйверы (Email/Telegram/Database) и CLI.
Быстрый старт
use PhpSoftBox\Notifications\NotificationManager; use PhpSoftBox\Notifications\NotificationChannelNames as Channels; $manager = new NotificationManager([ $emailChannel, $telegramChannel, $databaseChannel, ]); $manager->send($user, new WelcomeNotification());
Уведомление определяет каналы и условия отправки:
use PhpSoftBox\Notifications\Notification; use PhpSoftBox\Notifications\NotifiableInterface; use PhpSoftBox\Notifications\NotificationChannelNames as Channels; final class WelcomeNotification extends Notification { public function via(NotifiableInterface $notifiable): array { return [Channels::EMAIL, Channels::DATABASE]; } public function shouldSend(NotifiableInterface $notifiable, string $channel): bool { return $channel !== Channels::EMAIL || $notifiable->routeNotificationFor(Channels::EMAIL) !== null; } }
NotifiableInterface
Источник получателя определяет модель:
use PhpSoftBox\Notifications\NotifiableInterface; use PhpSoftBox\Notifications\NotificationChannelNames as Channels; final class User implements NotifiableInterface { public function routeNotificationFor(string $channel, ?string $driver = null): mixed { return match ($channel) { Channels::EMAIL => $this->email, Channels::TELEGRAM => $this->telegramChats[$driver] ?? null, Channels::DATABASE => $this->id, Channels::PUSHR => $this->pushrChannels[$driver ?? 'default'] ?? null, default => null, }; } }
Email-уведомление реализует EmailNotificationInterface:
use PhpSoftBox\Notifications\Email\EmailNotificationInterface; use PhpSoftBox\Mailer\Message\EmailMessage; final class WelcomeNotification extends Notification implements EmailNotificationInterface { public function toEmail(NotifiableInterface $notifiable): EmailMessage { return EmailMessage::create('Добро пожаловать') ->markdown('Спасибо за регистрацию.'); } }
SMTP транспорт
Для SMTP можно использовать отдельный пакет phpsoftbox/mailer:
use PhpSoftBox\Mailer\Smtp\SmtpClient; use PhpSoftBox\Mailer\Smtp\SmtpClientConfig; use PhpSoftBox\Mailer\Transport\SmtpEmailTransport; use PhpSoftBox\Notifications\Email\EmailChannel; $smtp = new SmtpClient(new SmtpClientConfig( host: 'mailhog', port: 1025, encryption: 'none', )); $transport = new SmtpEmailTransport($smtp); $emailChannel = new EmailChannel($transport, null, null, 'no-reply@example.com');
Поддерживаются шаблоны (через EmailTemplateRendererInterface) и Markdown-конвертация (MarkdownToHtmlConverterInterface):
return EmailMessage::create('Сводка') ->template('emails/summary', ['items' => $items], isMarkdown: true);
Для HTML-шаблонов можно централизованно оборачивать контент в layout:
return EmailMessage::create('Подтверждение email') ->template('email/confirm-email.phtml', [ 'name' => $userName, ]) ->layout('email/layout.phtml', [ 'title' => 'Подтверждение email', 'preview' => 'Подтвердите email, чтобы завершить регистрацию.', 'actionUrl' => $confirmUrl, 'actionLabel' => 'Подтвердить email', ]);
Legacy-вариант с layout(array $data) удалён: используйте layout(string $template, array|object $data = []).
Для object-layout используйте DTO, реализующий LayoutTemplateDataInterface,
чтобы канал мог безопасно подставить content/title:
use PhpSoftBox\Notifications\Email\LayoutTemplateDataInterface; final readonly class EmailLayoutView implements LayoutTemplateDataInterface { public function __construct( public ?string $title = null, public string $content = '', public ?string $preview = null, ) { } public function withLayoutContent(string $content, ?string $defaultTitle = null): object { return new self( title: $this->title ?? $defaultTitle, content: $content, preview: $this->preview, ); } }
Telegram
Telegram-канал использует TelegramBotRegistry. Бот выбирается через TelegramMessage::bot().
use PhpSoftBox\Notifications\Telegram\TelegramNotificationInterface; use PhpSoftBox\Notifications\Message\TelegramMessage; public function toTelegram(NotifiableInterface $notifiable): TelegramMessage { return TelegramMessage::create('Ваш код подтверждения: 1234') ->bot('account') ->options(['parse_mode' => 'HTML']); }
routeNotificationFor(Channels::TELEGRAM, $botName) должен вернуть chat_id для выбранного бота.
Database
Database-канал сохраняет адресные уведомления в таблицу notifications.
use PhpSoftBox\Notifications\Database\DatabaseNotificationInterface; use PhpSoftBox\Notifications\Message\DatabaseMessage; public function toDatabase(NotifiableInterface $notifiable): DatabaseMessage { return DatabaseMessage::create('Новое уведомление') ->body('Текст уведомления') ->data(['level' => 'info']); }
Репозиторий поддерживает чтение:
$items = $repository->listForUser($userId, 5); $unread = $repository->countUnread($userId);
Pushr (WebSocket)
Pushr-канал публикует событие в WebSocket (Pushr).
use PhpSoftBox\Notifications\Pushr\PushrNotificationInterface; use PhpSoftBox\Notifications\Message\PushrMessage; use PhpSoftBox\Notifications\Pushr\PushrChannel; use PhpSoftBox\Notifications\Pushr\PushrPublisherAdapter; use PhpSoftBox\Broadcaster\Pushr\PushrPublisher; $pushrChannel = new PushrChannel( new PushrPublisherAdapter(new PushrPublisher($appId, $secret, $host)), ); final class SystemAlertNotification extends Notification implements PushrNotificationInterface { public function toPushr(NotifiableInterface $notifiable): PushrMessage { return new PushrMessage( event: 'notification.created', payload: [ 'id' => 10, 'title' => 'Система', 'body' => 'Готово.', ], driver: 'admin', ); } }
routeNotificationFor(Channels::PUSHR, $driver) должен вернуть канал (например, admin.private.user.{id}).
Аудит отправок (NotificationAuditChannel)
NotificationAuditChannel оборачивает любой канал и пишет историю отправок в ваше хранилище
(обычно в таблицу БД). Это удобно для админских журналов и разборов инцидентов.
В пакет входят:
PhpSoftBox\Notifications\Audit\NotificationAuditChannelPhpSoftBox\Notifications\Audit\NotificationAuditActorPhpSoftBox\Notifications\Contracts\NotificationAuditStoreInterfacePhpSoftBox\Notifications\Contracts\NotificationAuditActorResolverInterfacePhpSoftBox\Notifications\Contracts\NotificationAuditToggleInterface
Как подключить
use PhpSoftBox\Notifications\Audit\NotificationAuditChannel; use PhpSoftBox\Notifications\NotificationManager; $manager = new NotificationManager([ new NotificationAuditChannel($emailChannel, $auditStore, $actorResolver, $toggle), new NotificationAuditChannel($telegramChannel, $auditStore, $actorResolver, $toggle), new NotificationAuditChannel($databaseChannel, $auditStore, $actorResolver, $toggle), ]);
Где:
$auditStoreреализуетNotificationAuditStoreInterfaceи сохраняет запись (БД, файл, внешняя система).$actorResolverреализуетNotificationAuditActorResolverInterfaceи возвращает отправителя (userId,name).$toggleреализуетNotificationAuditToggleInterfaceи включает/выключает аудит (например, через конфиг/настройки).
Какие данные пишет аудит
Базово:
recipientUserId— адресат в терминах вашей системы (берётся черезrouteNotificationFor('database'), если доступен).recipientTarget— канал доставки (email,chat_id, pushr-channel и т.п.).channel,status,notificationType.title,body,payload.senderUserId,senderName.
Дополнительно по каналам:
- Email: subject/body, служебные поля (
to,cc,bcc,from,reply_to,template). - Telegram: текст сообщения, имя бота, options.
- Database: title/body/data из
DatabaseMessage.
Если toggle->isEnabled() возвращает false, отправка работает как обычно, но история не пишется.
CLI
make:notification App\\Notifications\\WelcomeNotification
notifications:prune --days=30 --read=1