BeginnerEngineerBlog
中の人
中の人

勝手にlaravelチュートリアル #8

公開: 2021-09-02 22:07
更新: 2023-04-06 15:01
833
php laravel6.x 通知
さぁ、ついに最後の記事になります!最後は通知機能を実装します!いよいよラスト!頑張っていきましょう!
変更履歴
2021/09/12 validationのリダイレクト処理を編集しました。

こんにちは!
ついにこの勝手にlaravelチュートリアルの最後の記事になります!
ラストスパート!頑張っていきましょう!


今回は通知機能を実装していきます!

  1. チュートリアル説明
  2. プログラミングの準備(エディタ、dockerの用意、環境構築)
  3. 認証機能を追加してログイン機能を実装する
  4. ブログのタイトルと記事を登録する
  5. ブログの記事へタグを登録する
  6. ブログの一覧表示、編集機能の実装
  7. ブログの検索機能の実装
  8. ユーザーへの通知機能の実装(今ここ)

それでは早速やっていきましょう!
通知するタイミングは、ブログを投稿したときということで進めていきます!


Notificationクラスを作成する


では、まずターミナルを開いて、appコンテナの中に入ってください。

で、

php artisan make:notification PostArticleNotification

と入力して実行してください。


そしたら、一旦作成されたファイルを確認しましょう。

app/Notifications/PostArticleNotification.php

<?php


namespace App\Notifications;


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


class PostArticleNotification extends Notification
{
    use Queueable;


    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct()
    {
        //
    }


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


    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        return (new MailMessage)
                    ->line('The introduction to the notification.')
                    ->action('Notification Action', url('/'))
                    ->line('Thank you for using our application!');
    }


    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}

こんな感じですね。

これはNotification(通知)のクラスで、このクラスを使って通知したいuserへ通知を行います。
通知の種類には、メール、データベース、slackなど色々あります。

今回は会員登録したuser全員に、デフォルトで設定されているメールを使って通知していきます。
(他の通知方法で実装したい方は、ご自身で調べてみましょう!ちなみにビギナーエンジニアブログのログイン時に表示されているヘッダーのベルマークの通知は、データベース通知を利用しています!)

ということで、一旦このクラスはこのまま置いといてください。

では、ArticleControllerのcreateアクションを編集して、ブログ投稿時にuserへ通知が行くように実装していきます。


ArticleControllerを編集する


//省略
use Illuminate\Support\Facades\Notification;//<-追加
use App\Notifications\PostArticleNotification;//<-追加
use App\User;//<-追加
//省略
public function create(Request $request)
{
    $validator = Validator::make($request->all(), [
        'title' => [
            'required',
            'string',
            'max:25',
        ],
        'content' => [
            'required',
            'string',
            'max:4000',
        ],
        'tag' => [
            'nullable',
            'string',
        ],
    ]);
    $validator->validate();
    $id = $request->get('id');
    $article = Article::find($id);
    if (isset($article) && $article->user_id !== Auth::user()->id) {
        abort(404);
    }
    $title = $request->get('title');
    $content = $request->get('content');


    if (isset($article)) {
        $article->title = $title;
        $article->content = $content;
        $article->save();
    } else {
        $user_id = Auth::id();
        $article = Article::create(
            [
                'title' => $title,
                'content' => $content,
                'user_id' => $user_id,
            ]
        );
    }


    $input_tag = $request->get('tag');
    if (isset($input_tag)) {
        $tag_ids = [];
        $tags = explode(',', $input_tag);
        foreach ($tags as $tag) {
            $tag = Tag::updateOrCreate(
                [
                    'name' => $tag,
                ]
            );
            $tag_ids[] = $tag->id;
        }
        $article->tags()->sync($tag_ids);
    }

    //ここから
    $users = User::where('id', '<>', $article->user->id)->get();
    Notification::send($users, new PostArticleNotification());
        //ここまで追加

    return redirect()->route('article.show', ['id' => $article->id]);
}

まず忘れずに必要なクラスをuseしてください。

で、

$users = User::where('id', '<>', $article->user->id)->get();

これはブログを投稿したuser以外を取得する書き方です。

'<>'

これはsqlの「以外」を表す書き方です。また、今までのプログラムと同じように書きたければ、

'!='

と書くこともできます。

Notification::send($users, new PostArticleNotification());

これはuseしたNotificationクラスのsend関数を使い、第一引数に送信先、第二引数に使うNotificationクラスを指定します。

つまり、ブログ投稿者以外のuserに対し、PostArticleNotificationで通知を送るという処理を行なっています。

少し脱線しますが、一度App/User.phpを見てください。

<?php


namespace App;


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


class User extends Authenticatable
{
    use Notifiable;


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


    /**
     * 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',
    ];
}



//省略
use Illuminate\Notifications\Notifiable;
//省略
use Notifiable;
//省略

これは、Notifiableトレイト(trait)で、クラスとはまた違うものになります。
traitとはコードの使い回しをしやすくするためのものです。

このNotifiableトレイトを実装していないと、Notification::sendで指定した送信先に通知することができません。
逆に言えば、このトレイトをモデルが実装することで、そのモデルに対する通知が可能ということです。
今はuserモデル以外の使い道が思いつかないかもしれませんが、頭の片隅に置いておくと今後役立ちますよ!

では、適当にブログを投稿してみてください。

で、

http://localhost:1080

へアクセスしてmailcatcherを確認してみましょう。


はい、こんな感じでブログ投稿者以外にメールが送信されてますね!

ですが、このままだと全てデフォルトの内容が記載されているので通知されたユーザーは何のことだかわかりませんね。

ということで、このメールの内容をカスタマイズして、新しく投稿されたブログの投稿者の名前、ブログのタイトルを表示してみましょう。
(ちなみにここで表示されている"Tutorial"は、.envに記載してあるAPP_NAME="Tutorial"が参照されています。)


Notificationクラスを編集する


もう一度ArticleControllerのcreateアクションを編集します。

$users = User::where('id', '<>', $article->user->id)->get();
Notification::send($users, new PostArticleNotification($article));//<-編集

PostArticleNotificationへ作成した$articleを引数で渡します。

そしたら、PostArticleNotificationを以下のように編集してください。

<?php


namespace App\Notifications;


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


class PostArticleNotification extends Notification
{
    use Queueable;


    private $article;//<-追加


    /**
     * Create a new notification instance.
     *
     * @return void
     */
    public function __construct(
        Article $article//<-追加
    )
    {
        $this->article = $article;//<-追加
    }


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


    /**
     * Get the mail representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return \Illuminate\Notifications\Messages\MailMessage
     */
    public function toMail($notifiable)
    {
        //↓諸々編集
        return (new MailMessage)
            ->subject('ブログが新しく投稿されました!|' . config('app.name'))
            ->greeting($this->article->user->name . 'さんがブログを投稿しました!')
            ->line('title: ' . $this->article->title)
            ->action('ブログをみに行く', route('article.show', ['id' => $this->article->id]))
            ->line('アプリをご利用いただきありがとうございます。')
            ->salutation(config('app.name'));
    }


    /**
     * Get the array representation of the notification.
     *
     * @param  mixed  $notifiable
     * @return array
     */
    public function toArray($notifiable)
    {
        return [
            //
        ];
    }
}



private $article;

まず、プロパティを宣言します。
プロパティとは、クラスの持ち物、属性になります。

そして、

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

__construct(){}
はクラスの初期化用の関数で、クラスがインスタンス化したとき(newした時)、引数を受け付けながら、{}の中に記述した処理を一番最初に実行してくれます。

Article $article

これは引数の型を制限、または指定する書き方です。つまり、このクラスをnewした時に渡す引数は、Articleモデルのインスタンスじゃないといけないということです。
そして、

$this->article = $article;

これは、プロパティで宣言した$articleへ、引数で渡ってきた$articleを代入する記述になります。
プロパティへのアクセスは

$this->プロパティ名

でアクセスすることができます。($は必要ありません。)
はい、諸々とよくわからない説明で???となっている方、すみません。私の説明スキルと知識が乏しいため、参考リンクを参照してください。🙇‍♂️

まさか最後の記事でクラスについて説明するとは思ってませんでしたが、まぁ今までにクラスについて言及することなかったんでオッケーでしょう!

本題に戻ります!

public function toMail($notifiable)
{
    return (new MailMessage)
        ->subject('ブログが新しく投稿されました!|' . config('app.name'))
        ->greeting($this->article->user->name . 'さんがブログを投稿しました!')
        ->line('title: ' . $this->article->title)
        ->action('ブログをみに行く', route('article.show', ['id' => $this->article->id]))
        ->line('アプリをご利用いただきありがとうございます。')
        ->salutation(config('app.name'));
}

config('app.name')

これは、config/app.phpの

'name' => env('APP_NAME', 'Laravel'),

こちらの記述を呼び出す記述になります。

env関数は第一引数にenvに記述されているkeyを指定し、第二引数は、第一引数で指定したkeyがなかった場合のデフォルトの値を設定します。

ということで、この関数から取得できる値は.envに記載されている

APP_NAME=Tutorial

Tutorialが取得できるということです。

あとは、今までやってきたように$articleモデルから必要な値を参照する書き方や、文字列連結、またurlを生成するroute関数などを利用してメール本文をカスタマイズしています。

また、
  • subjectは件名
  • greetingは見出し
  • lineは文章
  • actionはリンクボタン
  • salutationは結び?の文章

です。他にも色々指定できるのでご自身で調べてみてください。

また、メールテンプレートを自分で作成して、送信することも可能です。気になった方は調べてみましょう!

はい、色々と説明が長くなりましたが、それでは適当にブログを投稿してメールの内容を確認してみましょう!



はい、ちゃんと反映されてますね!
これでいろんなタイミングでお知らせを通知することができます!
ガンガン通知してやりましょう!うざったくなるほどに!


と...いうことで...
以上で本記事を終了したいと思います。そして、以上で勝手にlaravelチュートリアルは終了いたします!🎉

ここまでやってくださった方、お疲れ様でした!そして、この拙いチュートリアルを最後までやってくださり、ありがとうございます!

私自身、ここまでちゃんとした記事をブログとして投稿することが初めてのことでしたので、わかりにくい表現や、もっとここ詳しく説明しろやとか、参考サイトで逃げんなとか感じた方もいたと思います。

精進します!ので許してね💁‍♂️

ですが、もうみなさんはphpとlaravelの使い方の基礎は習得できたと思いますので、足りないと思う部分はご自身で勉強して理解を深めてください!
そして、自分が作りたいアプリケーションを作れるように頑張ってください!私も日々勉強しています!

お互いがんばりましょう!

また、今回のチュートリアルで作成したブログアプリは私のgithubへプッシュしてますので、参考にしてください。

ということで、今後もBeginnerEngineerBlogをよろしくお願いします!

0
0
0
0
通信エラーが発生しました。
【広告】
似たような記事