【问题标题】:Artisan command notification to all users gives BadMethodCallException给所有用户的 Artisan 命令通知会给出 BadMethodCallException
【发布时间】:2019-12-05 21:55:10
【问题描述】:

我如何创建一个工匠命令来向系统中的所有用户发送数据库通知,其中包含他们在系统中停留了多长时间的信息?

我的 SendEmails 命令如下所示:

    <?php

namespace App\Console\Commands;

use Illuminate\Console\Command;
use App\User;
use Illuminate\Support\Facades\Mail;
use App\Mail\UserEmails;
use Illuminate\Support\Facades\Notification;

class SendEmails extends Command
{
    /**
     * The name and signature of the console command.
     *
     * @var string
     */
    protected $signature = 'send:emails';

    /**
     * The console command description.
     *
     * @var string
     */
    protected $description = 'Send Email to allusers';

    /**
     * Create a new command instance.
     *
     * @return void
     */
    public function __construct()
    {
        parent::__construct();
    }

    /**
     * Execute the console command.
     *
     * @return mixed
     */
    public function handle()
    {
        $users = User::all();
        foreach($users as $user){
            $created_at = $user->created_at;
            Notification::send($user, new SendEmailsNotification($created_at));
        }
    }
}

然后我创建了通知表,进行了迁移,代码如下:

<?php

namespace App\Notifications;

use Illuminate\Bus\Queueable;
use Illuminate\Notifications\Notification;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;

class SendEmailsNotification extends Notification
{
    use Queueable;

    public $created_at;

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

    public function via($notifiable)
    {
        return ['database'];
    }

    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }

    public function toArray($notifiable)
    {
        return [
        ];
    }
}

用户.php:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
//use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    //use Notifiable;

    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password', 'address', 'image'
    ];

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];

    /**
     * The attributes that should be cast to native types.
     *
     * @var array
     */
    protected $casts = [
        //'email_verified_at' => 'datetime',
        'address' => 'array'
    ];

    protected $uploads = '/images/';

    public function getImageAttribute($image){
        return $this->uploads . $image;
    }

    public function contacts(){
        return $this->hasMany('App\Contact');
    }
}

当我运行 artisan 命令“php artisan send:emails”时,我在控制台中看到以下错误:

BadMethodCallException : 调用未定义的方法 App\User::routeNotificationFor()

如何将通知发送给所有用户?

【问题讨论】:

  • @Rwd 我刚刚编辑了我的问题
  • 抱歉,您能否展示整个类,即正在导入哪些类以及它使用的特征。
  • @Rwd 我刚刚编辑了我的问题
  • 您是否有理由将created_at 传递给每个通知?
  • 是的@Rwd。因为通知的内容需要在人类可读的时间内指定用户成为会员的方式

标签: php laravel laravel-artisan


【解决方案1】:

首先,您需要按照其他答案中的建议取消注释 use Notifiable;。现在Notification::send() 用于向多个用户发送通知,它希望第一个参数是通知的集合(即用户),而不是对象。要在循环中单独发送通知,您应该执行以下操作:

foreach($users as $user) {
    $created_at = $user->created_at;
    $user->notify(new SendEmailsNotification($created_at));
}

但由于通知已经在您的通知中可用,因此更好的解决方案如下:

你的通知类:

use Queueable;

public $created_at;

public function __construct()
{
    
}

public function via($notifiable)
{
    return ['database'];
}

public function toMail($notifiable)
{
    $created_at = $notifiable->created_at;
    return (new MailMessage)
                ->line('The introduction to the notification.')
                ->action('Notification Action', url('/'))
                ->line('Thank you for using our application!');
}

public function toArray($notifiable)
{
    $created_at = $notifiable->created_at;
    return [
    ];
}

在您的 Artisan 命令中:

$users = User::all();
Notification::send($users, new SendEmailsNotification());

【讨论】:

  • 您不必将一组通知传递给send。如果通过单个实例,那么它将为您包装该实例。
  • @Rwd 感谢您的澄清。文档没有提到这一点。这就是为什么我假设它总是需要一个集合。
  • 别担心,我只是想让你知道:)
【解决方案2】:

您只需取消注释// use Notifiable 行。

Notifiable 特征包括另外两个特征,其中之一是 RoutesNotifications 特征。

RoutesNotifications 特征是您需要能够将通知发送到 User


此外,您应该能够将SendEmails 命令中的代码简化为:

Notification::send(User::all(), new SendEmailsNotification()); 

而不是显式传递created_at,您可以从SendEmailsNotification 中的$notifiable 访问它(在这种情况下,$notifiable 无论如何都是User 模型)例如

public function toArray($notifiable)
{
    return [
        'data' => 'Account Created' . $notifiable->created_at->diffForHumans()
    ];
}

}

【讨论】:

  • 我取消了 Notifiable 行的注释并发送了通知,但我在 toArray 方法中收到错误,因为我有 'data' => 'Account Created' 。 $this->created_at->getDiffForHumans() 表示getDiffForHumans()方法不存在
  • @deSousa 请您更新问题中的代码以显示您当前为 SendEmailsNotification 类提供的代码,因为目前您提供的代码只是返回一个空数组。
  • @deSousa 我已经更新了我的答案,以展示您如何访问这些信息。
  • 我刚刚注意到它实际上是没有 get 的 diffForHumans()。希望你能更新你的答案。
  • @deSousa 已更新。我不知道为什么我自己没看到哈哈。很高兴我能帮上忙!
猜你喜欢
  • 1970-01-01
  • 2018-04-02
  • 1970-01-01
  • 2018-12-10
  • 1970-01-01
  • 2018-11-16
  • 1970-01-01
  • 2013-10-28
  • 2018-06-06
相关资源
最近更新 更多