#php #laravel
#php #laravel
Вопрос:
У меня есть система сообщений. На моем сайте пользователи могут публиковать статьи и оставлять комментарии к каждой статье. Я хочу выпустить: когда какой-либо пользователь (не автор сообщения) комментирует сообщение, мне нужно отправить уведомление автору сообщения, чтобы его сообщение было прокомментировано по имени пользователя… Я делаю это так:
В 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;
}
В моей системе комментариев у меня есть вложенные комментарии. В сообщении модели у меня есть метод 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);
}
Теперь: когда комментарий создан, уведомления отправляются автору сообщения, но когда автор может ответить на комментарий о его публикации, уведомление отправляется ему снова, но мне нужно отправить уведомление автору комментария. Как я могу определить этот случай? Мне не нужно всегда отправлять уведомления автору сообщения, мне нужно уведомлять и авторов комментариев, что на комментарии к ним отвечает автор сообщения.
Ответ №1:
Насколько я понимаю, вы пытаетесь отправить уведомление по электронной почте автору сообщения через класс электронной почты, sendReviewNotification
с $review
в качестве параметра. если это так, то эта строка
$post->owner->sendReviewNotification($review);
потому что $post->owner
возвращает красноречивую связь (это конструктор запросов)
вот как я бы это сделал. Я бы использовал приведенное выше соотношение, чтобы получить адрес электронной почты пользователя (автора)
$post->owner->email
строка выше вернет адрес электронной почты авторов
затем используйте почтовый фасад
Mail::to($post->owner->email)->send(new sendReviewNotification($review));
Я предполагаю, sendReviewNotification
это ваш почтовый класс
также не забудьте добавить эту строку в начале вашего класса чуть ниже пространства имен.
use IlluminateSupportFacadesMail;
Ответ №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
В этом сценарии вы, вероятно, захотите отправить уведомление в следующих ситуациях:
- Ричард получает уведомление, если кто-то прокомментировал его сообщение
- Автор комментария получает уведомление, если Ричард также комментирует
Первая ситуация кажется простой. Всякий раз, когда создается новый комментарий, вы уведомляете автора сообщения, которое было прокомментировано:
if ($comment->author_id !== $comment->post->author_id) {
$comment->post->author->notify(new PostWasCommented($comment));
}
Как вы можете видеть, я ожидаю, что вы будете использовать встроенную в Laravel систему уведомлений. Это делает вашу жизнь намного проще, если быть честным.
Вторая ситуация немного более сложная и снова допускает два возможных решения:
-
Вы отправляете уведомление всем, кто прокомментировал сообщение до того, как прокомментировал Ричард.
В приведенном выше примере, когда Ричард создает комментарий # 3, Джон и Элиас получат уведомление. Когда Ричард создает комментарий # 7, Джон, Элиас, Майкл и Мерри получают уведомление. ($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)); }
-
Вы отправляете уведомление только тем людям, которые прокомментировали с момента последнего комментария автора.
В приведенном выше примере это означает, что Джон и Элиас будут уведомлены, когда Ричард создаст комментарий # 3. И когда Ричард создает комментарий # 7, тогда уведомляются только Майкл, Джон и Мерри, но не Элиас. Это потому, что только эти три человека прокомментировали между # 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)); }
Комментарии:
1. Неплохо. Но во второй ситуации, когда мне нужно написать ваш код? И у меня есть вложенные комментарии, у каждого комментария могут быть дочерние элементы
2. Я думаю, вы могли бы написать это в
sendReviewNotification($comment)
. Или вы добавляете событие с именемCommentCreated
и помещаете его в прослушиватель событий (вероятно, более приятное решение, поскольку оно разделяет логику). То, как вы будете работать с вложенными комментариями, немного зависит от того, как они хранятся. Хранят ли вложенные комментарии такжеpost_id
или толькоparent_id
предыдущий (родительский) комментарий ?3. У меня есть и
post_id
иparent_id
в таблице комментариев.4. Ну, тогда почему родительский элемент вообще имеет значение? Я думаю, что это интересно, только если вы хотите уведомить автора родительского комментария или только публикации, что было бы ситуацией, которую я не включил в свой ответ. Это также не сильно отличается от того, что я описал, если вы не используете бесконечную вложенность комментариев.