【问题标题】:Identify user of comment and send notification Laravel识别评论用户并发送通知 Laravel
【发布时间】:2019-08-26 16:53:09
【问题描述】:

我有一个帖子系统。在我的网站上,用户可以发布文章并在每篇文章上发布 cmets。我要发布:当任何用户(不是帖子的作者)评论帖子时,我需要向帖子的作者发送通知,他的帖子是由 UserName 评论的......我这样做:

在 CommentController 中,我有一个对帖子发表评论的方法:

public function postComment(Post $post, AddPostRequest $request)
{
    if ($request->parent_id !== null) {
        $parent = Comment::where('id', $request->parent_id)->first();
        $this->authorize('canComment', $parent);
    }

    $data = [
        'user_id' => Auth::check() ? Auth::user()->id : null,
        'post_id' => $post->id
    ];

    $comment = $post->createComment(array_merge($request->except('g-recaptcha-response'), $data));

    $post->owner->sendReviewNotification($review);

    return $review;
}

在我的评论系统中,我有嵌套的 cmets。在模型帖子中,我有方法createReview.

public function owner()
{
    return $this->belongsTo(User::class, 'user_id');
}

public function comments()
{
    return $this->hasMany(Comment::class);
}

public function createComment($data = [])
{
    $review = $this->comments()->create($data);

    return $review;
}

在模型评论中我有:

public function post()
{
    return $this->belongsTo(Post::class);
}

public function user()
{
    return $this->belongsTo(User::class);
}

public function parent()
{
    return $this->belongsTo(static::class, 'id', 'parent_id');
}

public function children()
{
    return $this->hasMany(static::class, 'parent_id');
}

public function scopeActive($query)
{
    return $query->whereNotNull('user_id')->where('active', 1);
}

现在:创建评论时,会向帖子的作者发送通知,但是当作者可以回复发布他的评论时,通知会再次发送给他,但我需要向作者发送通知评论。我该如何定义这种情况?我不需要总是向帖子的作者发送通知,我需要通知 cmets 的作者和作者,这些 cmets 由帖子的作者回答。

【问题讨论】:

    标签: php laravel


    【解决方案1】:

    据我了解,您正在尝试通过电子邮件类sendReviewNotification$review 作为参数向帖子的作者发送和电子邮件通知。 如果是这样的话,那么这一行

    $post->owner->sendReviewNotification($review);
    

    因为$post->owner返回了一个雄辩的关系(它是一个查询构建器)

    我就是这样做的。 我会使用上面的关系来获取用户(作者)的电子邮件地址

    $post->owner->email
    

    上面的行将返回作者的电子邮件地址

    然后使用邮件门面

    Mail::to($post->owner->email)->send(new sendReviewNotification($review));
    

    我假设sendReviewNotification 是您的邮件类 还记得在命名空间下方的类的开头添加这一行。 use Illuminate\Support\Facades\Mail;

    【讨论】:

      【解决方案2】:

      我认为您真正想要的是向讨论的每个参与者发送通知,但只发送给自您上次发表评论后发表评论的人:

      Post #4321 (Author Richard)
        -> Comment #1 by John
        -> Comment #2 by Elias
        -> Comment #3 by Richard    <-- the author
        -> Comment #4 by Michael
        -> Comment #5 by John
        -> Comment #6 by Merry
        -> Comment #7 by Richard    <-- the author
      

      在这种情况下,您可能希望在以下情况下发送通知:

      1. 如果有人对他的帖子发表评论,Richard 会收到通知
      2. 如果 Richard cmets 也会通知评论的作者

      第一种情况似乎很简单。每当创建新评论时,您都会通知已评论帖子的作者:

      if ($comment->author_id !== $comment->post->author_id) {
          $comment->post->author->notify(new PostWasCommented($comment));
      }
      

      如您所见,我希望您使用 Laravel 内置的 notification system。老实说,这让你的生活更轻松。


      第二种情况稍微复杂一些,再次允许两种可能的解决方案:

      • 在 Richard 发表评论之前,您会向所有评论过帖子的人发送通知。
        在上面的示例中,当 Richard 创建评论 #3 时,John 和 Elias 将收到通知。当 Richard 创建评论 #7 时,John、Elias、Michael 和 Merry 会收到通知。 $comment 是要创建的新评论。)

        $users = User::query()
            ->whereHas('comment', function ($query) use ($comment) {
                return $query->where('post_id', $comment->post_id);
            })
            ->where('user_id', '!=', $comment->post->author_id)
            ->get();
        
        foreach ($users as $user) {
            $user->notify(new PostWasCommented($comment));
        }
        
      • 您只会向自作者上次发表评论后发表评论的人发送通知。
        根据上述示例,这意味着当 Richard 创建评论 #3 时将通知 John 和 Elias。当 Richard 创建评论 #7 时,只有 Michael、John 和 Merry 会收到通知 - 而 Elias 则不会。这是因为只有这三个人在 #3 和 #7 之间发表了评论。

        $users = User::query()
            ->whereHas('comment', function ($query) use ($comment) {
                return $query->where('post_id', $comment->post_id)
                    ->where(
                       'created_at', 
                       '>', 
                       DB::raw(
                           "SELECT MAX(created_at) FROM comments WHERE post_id = ? AND author_id = ?", 
                           [$comment->post_id, $comment->author_id]
                       )
                    );
            })
            ->where('user_id', '!=', $comment->post->author_id)
            ->get();
        
        foreach ($users as $user) {
            $user->notify(new PostWasCommented($comment));
        }
        

      【讨论】:

      • 不错。但是在第二种情况下,我需要编写您的代码?而且我有一个嵌套的cmets,每条评论都可以有一个孩子
      • 我想你可以写到sendReviewNotification($comment)。或者您添加一个名为CommentCreated 的事件并将其放入事件侦听器(可能是更好的解决方案,因为它可以解耦逻辑)。您如何处理嵌套的 cmets 取决于它们的存储方式。嵌套 cmets 是否还存储 上一个(父)评论post_id 或仅存储parent_id
      • 我在 cmets 表上有 post_idparent_id
      • 好吧,那为什么父母甚至重要?我认为只有当您只想通知父评论或帖子的作者时才有趣,这将是我没有包含在我的答案中的情况。只要不使用 cmets 的无限嵌套,它也与我描述的没有太大区别。
      猜你喜欢
      • 2010-11-06
      • 1970-01-01
      • 2018-12-02
      • 1970-01-01
      • 2017-03-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-19
      相关资源
      最近更新 更多