Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Middle: питання на співбесіді з теми «Сповіщення»

Питання з реальних співбесід з відповідями: Laravel і PHP, бази даних, JavaScript і фронтенд, Git, Docker, API, безпека й архітектура. Тими самими темами, що й тести.

2 питання

Notification - одне повідомлення, яке можна доставити кількома каналами одночасно.

class InvoicePaid extends Notification
{
    public function via(object $notifiable): array
    {
        return ['mail', 'database', 'broadcast'];
    }

    public function toMail($notifiable): MailMessage { /* ... */ }
    public function toArray($notifiable): array { /* для database */ }
}

$user->notify(new InvoicePaid($invoice));

Канали з коробки: mail, database (зберігає в notifications), broadcast (WebSockets), Vonage (SMS), Slack. Є community-канали (Telegram, push). Канал database зручний для «дзвіночка» сповіщень у UI; реалізувавши ShouldQueue, відправку виносять у чергу.

Докладніше в документації: Notifications

Звичайно сповіщення надсилають моделі з трейтом Notifiable: $user->notify(...). Модель сама знає свої адреси - email для пошти, phone для SMS (через методи routeNotificationFor...).

Але інколи отримувач - не користувач: гість, що залишив заявку, адреса з форми «Повідомити, коли з'явиться товар», канал Slack команди, email бухгалтерії.

Сповіщення на льоту (on-demand) - через фасад з явною маршрутизацією:

use Illuminate\Support\Facades\Notification;

Notification::route('mail', 'accounting@example.com')
    ->route('slack', '#billing')
    ->notify(new InvoicePaid($invoice));

Можна вказати ім'я отримувача пошти:

Notification::route('mail', ['buyer@example.com' => 'Олена Петренко'])
    ->notify(new OrderReceived($order));

Як це працює всередині: route() створює об'єкт AnonymousNotifiable, який зберігає маршрути для каналів. Сповіщення отримує його як $notifiable у методах via() і toMail().

Що з цього випливає:

  • via() має працювати з анонімним отримувачем. Якщо ви вибираєте канали за налаштуваннями користувача ($notifiable->prefers_sms), для анонімного отримувача таких властивостей немає:
public function via(object $notifiable): array
{
    return $notifiable instanceof AnonymousNotifiable
        ? ['mail']
        : $notifiable->notificationChannels();
}
  • канал database недоступний - немає моделі, до якої прив'язати запис;
  • немає бажаної локалі - мову доведеться задати явно: ->locale('uk');
  • маршрут береться з route(), а не з routeNotificationForMail.

Типові задачі:

  • службові сповіщення команді (новий платіж у Slack, помилка імпорту на пошту);
  • листи гостям до реєстрації;
  • кілька отримувачів: Notification::send($users, ...) для моделей і route() для зовнішніх адрес.

Тести:

Notification::fake();
// ...
Notification::assertSentOnDemand(InvoicePaid::class,
    fn ($notification, $channels, $notifiable) => $notifiable->routes['mail'] === 'accounting@example.com');

Докладніше в документації: Сповіщення: сповіщення на льоту