Подтвердить что ты не робот

Laravel Уведомления Слушатель событий Undefined Свойство

У меня есть следующая ошибка:

Undefined свойство: Illuminate\Notifications\Events\NotificationSent:: $user в /var/www/app/app/Listeners/NoticationListener.php:31

Ошибка здесь:

<?php

namespace App\Listeners;

use Illuminate\Notifications\Events\NotificationSent;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;

class NoticationListener implements ShouldQueue
{
    /**
     * Create the event listener.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }

    /**
     * Handle the event.
     *
     * @param  NotificationSent  $event
     * @return void
     */
    public function handle(NotificationSent $event)
    {
       $notification = $event->notifiable;
       $addressee = $notification; //error here
       $address = $notification; 
       $type = "Notification";
       dispatch(new SendEmail($type,$addressee,$address));
    }
}

Я не понимаю этого свойства undefined, особенно в этой строке. Как я могу dd() отсюда? Я попытался зарегистрировать $event, но я не смог его записать, только получил эту ошибку.

Мои уведомления очень хорошо работают в приложении, я просто хочу, чтобы их сопровождало электронное письмо, поэтому у меня есть этот event-listener/job.

Спасибо.

ИЗМЕНИТЬ

Код репозитория, отправляющий уведомление, находится ниже:

public function notify($asset)
{
    $users = User::where("id","!=",Auth::user()->id)->get();
    Notification::send($users, new NewAsset($asset));
}

Это расширение класса Notification ниже:

class NewAsset extends Notification
{
    use Queueable;

    /**
     * Create a new notification instance.
     *
     * @return void
     */
    protected $asset;

    public function __construct($asset)
    {
        $this->asset = $asset;
    }

    /**
     * Get the notification delivery channels.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function via($notifiable)
    {
        return ['database'];
    }

    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            'asset_id' => $this->asset->id
        ];
    }
}

РЕДАКТИРОВАТЬ 2

Если кто-то может посоветовать, как сделать некоторую проверку ошибок на этом этапе, это может быть полезно в будущем. Поскольку код является асинхронным на сервере, он не возвращает данные клиенту, и когда я пытаюсь получить его на Log, он, похоже, не делает этого, прежде чем он попадает в ошибку.

Как я могу отлаживать этот сценарий?

Я рассмотрел исходный код и понятия не имею, откуда происходит свойство $user. Я предполагаю, что это связано с тем, что $event->notifiable привязан к модели User, но если он правильно срабатывает для всех затронутых пользователей из приложения, почему его свойство должно быть undefined в этом контексте?

Пожалуйста, помогите, спасибо.

4b9b3361

Ответ 1

Это странная проблема. Когда вы обнаружили, Laravel не устанавливает свойство $user для этого объекта, поэтому необходимо задействовать что-то еще. Здесь мое понимание процесса:

  • Notification::send() → enqueue NewAsset уведомление для каждого пользователя
  • Отменить внутреннее задание для уведомления NewAsset → отправлять уведомления
  • Fire NotificationSent event → enqueue NotificationListener обработчик

Ошибка, кажется, здесь:

  1. Внутреннее задание Dequeue для обработчика NotificationListener → событие обработки
  2. Отправка задания для SendEmail [enqueue if ShouldQueue]
  3. [Заменить задание SendEmail, если ShouldQueue] → Отправить уведомление по электронной почте

Как вы можете видеть, происходит много сериализации и десериализации при размещении и удалении заданий для уведомления. Похоже, что структура пытается установить свойство $user при десериализации события NotificationSent из очереди, но трудно сказать из вашего вопроса без полной трассировки стека, и я не уверен, что добавляет $user к сериализованным данным без дополнительной видимости в коде.

Вот несколько советов по отладке:

Установите QUEUE_DRIVER в sync:

Это предотвращает сериализацию данных события. Если электронное письмо с уведомлением отправляется без каких-либо ошибок, мы знаем, что пользовательский код где-то добавляет свойство $user к событию.

Проверить сериализованные данные очереди:

Непонятно из вопроса, какой драйвер очереди используется вашим приложением. Если вы не используете sync, мы можем посмотреть на ожидающие задания в очереди, чтобы попытаться найти расхождение (в базе данных, redis и т.д.).

  • Остановить всех сотрудников очереди.
  • Запустите уведомление через приложение.
  • Запустите php artisan queue:work --once, чтобы вручную обработать одно задание, пока запущенное задание не будет запущено и не сработает событие NotificationSent.
  • Осмотреть задание, созданное в очереди, для обработки события NotificationSent

Мы также можем использовать этот подход для вывода данных с помощью dd() во время заданий очереди, поскольку artisan queue:work --once работает на переднем плане.

Не помещайте в очередь обработчик событий NotificationSent:

Поскольку уведомление уже настроено для обработки в задании с заданием в очереди, нам необязательно также вводить в очередь обработчик событий уведомлений. Попробуйте удалить интерфейс ShouldQueue, чтобы узнать, устраняет ли это проблему.

Как отмечали другие комментаторы, эту проблему можно лучше решить, используя Laravel Mail Notifications, которые устраняют необходимость в отдельном обработчике событий NotificationSent полностью.