Laravel 5.4,5.3:定制或扩展的通知 - 数据库模型Laravel 5.4,5.3:定制

2019-05-12 11:21发布

恕我直言,在Laravel保存通知当前数据库通道是非常糟糕的设计:

  • 不能使用上的项目外键级联清理例如已删除项目的通知
  • 搜索定制在属性data列(浇铸阵列)不是最佳的

你会如何去延长DatabaseNotification在供应商的套餐模式?

我想补充列event_idquestion_iduser_id等(创建该通知的用户)......到默认laravel notifications

你如何重写send功能,包括多列?

在:

vendor/laravel/framework/src/Illuminate/Notifications/Channels/DatabaseChannel.php

代码:

class DatabaseChannel
{
 /**
  * Send the given notification.
  *
  * @param  mixed  $notifiable
  * @param  \Illuminate\Notifications\Notification  $notification
  * @return \Illuminate\Database\Eloquent\Model
  */
 public function send($notifiable, Notification $notification)
 {
    return $notifiable->routeNotificationFor('database')->create([
        'id' => $notification->id,
        'type' => get_class($notification),

      \\I want to add these
        'user_id' => \Auth::user()->id,
        'event_id' => $notification->type =='event' ? $notification->id : null, 
        'question_id' => $notification->type =='question' ? $notification->id : null,
      \\End adding new columns

        'data' => $this->getData($notifiable, $notification),
        'read_at' => null,
    ]);
 }
}

Answer 1:

要创建自定义通知信道:

首先,在应用程序\通知例如A类:

<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;

class CustomDbChannel 
{

  public function send($notifiable, Notification $notification)
  {
    $data = $notification->toDatabase($notifiable);

    return $notifiable->routeNotificationFor('database')->create([
        'id' => $notification->id,

        //customize here
        'answer_id' => $data['answer_id'], //<-- comes from toDatabase() Method below
        'user_id'=> \Auth::user()->id,

        'type' => get_class($notification),
        'data' => $data,
        'read_at' => null,
    ]);
  }

}

第二,在使用此信道via在通知类方法:

<?php

namespace App\Notifications;

use Illuminate\Notifications\Notification;

use App\Notifications\CustomDbChannel;

class NewAnswerPosted extends Notification
{
  private $answer;

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

  public function via($notifiable)
  {
    return [CustomDbChannel::class]; //<-- important custom Channel defined here
  }

  public function toDatabase($notifiable)
  {
    return [
      'type' => 'some data',
      'title' => 'other data',
      'url' => 'other data',
      'answer_id' => $this->answer->id //<-- send the id here
    ];
  }
}


Answer 2:

创建和使用自己的Notification模型和Notifiable特征,然后使用自己的法定特质在你(用户)模式。

应用程序\ Notifiable.php:

namespace App;

use Illuminate\Notifications\Notifiable as BaseNotifiable;

trait Notifiable
{
    use BaseNotifiable;

    /**
     * Get the entity's notifications.
     */
    public function notifications()
    {
        return $this->morphMany(Notification::class, 'notifiable')
                            ->orderBy('created_at', 'desc');
    }
}

应用程序\ Notification.php:

namespace App;

use Illuminate\Notifications\DatabaseNotification;

class Notification extends DatabaseNotification
{
    // ...
}

应用程序\ user.php的:

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class User extends Authenticatable
{
    use Notifiable;

    // ...
}


Answer 3:

在我看来laravel通知是notyet准备和非常有限的功能。

不管怎样,我通过自定义通知类解决了类似的问题:

创建此操作的类:

artisan make:notification NewQuestion

在里面:

public function __construct($user,$question)
    {
        $this->user=$user;
        $this->question=$question;
    }


...

    public function toDatabase($notifiable){
        $data=[
            'question'=>$this->(array)$this->question->getAttributes(),
            'user'=>$this->(array)$this->user->getAttributes()
        ];

        return $data;
    }

那么你就可以访问视图或控制器这样的正确的数据:

@if($notification->type=='App\Notifications\UserRegistered')
<a href="{!!route('question.show',$notification->data['question']['id'])!!}">New question from {{$notification->data['user']['name']}}</a>
@endif


Answer 4:

与“厄尔尼诺的Bassem哈希姆”,我想保持database的关键字中via()方法。

所以除了自定义DatabaseChannel ,我也写了我自己的ChannelManager返回自己DatabaseChannelcreateDatabaseDriver()方法。

在我的应用程序ServiceProvider::register()方法中,我改写为原ChannelManager类返回我的自定义管理器中的单。



文章来源: Laravel 5.4, 5.3 : customize or extend notifications - database model