Mark notifications as read by convesrsation_id field in notifications table - closes #5600

This commit is contained in:
FreeScout
2026-08-28 04:14:49 -07:00
parent 51543a4be5
commit 46bd96f442
3 changed files with 78 additions and 5 deletions

View File

@@ -61,13 +61,18 @@ class ConversationsController extends Controller
// Mark notifications as read
if (!empty($request->mark_as_read)) {
$mark_read_result = $user->unreadNotifications()->where('id', $request->mark_as_read)->update(['read_at' => now()]);
$user->unreadNotifications()->where('id', $request->mark_as_read)->update(['read_at' => now()]);
$user->clearWebsiteNotificationsCache();
} else {
$mark_read_result = $user->unreadNotifications()->where('data', 'like', '%"conversation_id":'.$conversation->id.'%')->update(['read_at' => now()]);
}
if ($mark_read_result) {
$user->clearWebsiteNotificationsCache();
// Build quiery manually instad of unreadNotifications() in order to use indexes.
//$mark_read_result = $user->unreadNotifications()->where('data', 'like', '%"conversation_id":'.$conversation->id.'%')->update(['read_at' => now()]);
$mark_read_result = $user->morphMany(\Illuminate\Notifications\DatabaseNotification::class, 'notifiable')
->where('conversation_id', $conversation->id)
->whereNull('read_at')
->update(['read_at' => now()]);
if ($mark_read_result) {
$user->clearWebsiteNotificationsCache();
}
}
// Detect folder and redirect if needed

View File

@@ -6,6 +6,17 @@ use Illuminate\Notifications\DatabaseNotification;
class DatabaseNotificationObserver
{
/**
* Populate "conversation_id" column.
*/
public function creating(DatabaseNotification $notification)
{
// $notification->data is already cast to array by the base model.
if (!empty($notification->data['conversation_id'])) {
$notification->conversation_id = $notification->data['conversation_id'];
}
}
/**
* Notifications DB record created.
*

View File

@@ -0,0 +1,57 @@
<?php
use Illuminate\Notifications\DatabaseNotification;
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class AddConversationIdColumnToNotificationsTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('notifications', function (Blueprint $table) {
// https://github.com/freescout-help-desk/freescout/issues/5600
$table->unsignedInteger('conversation_id')->after('data')->nullable();
// "read_at" is skipped on purpose - there is no use from it here.
$table->index(['notifiable_id', 'notifiable_type', 'conversation_id'], 'notifications_conversation_id');
});
// Populate "conversation_id" field for notifications.
$total = DatabaseNotification::whereNull('conversation_id')
->where('data', 'like', '%"conversation_id":%')
->count();
$bunch_size = 500;
for ($bunch_i = 0; $bunch_i < ceil($total / $bunch_size); $bunch_i++) {
$notifications = DatabaseNotification::whereNull('conversation_id')
->where('data', 'like', '%"conversation_id":%')
->orderBy('id')
//->skip($bunch_i*$bunch_size)
->limit($bunch_size)
->get();
foreach ($notifications as $notification) {
if (!empty($notification->data['conversation_id']) && (int)$notification->data['conversation_id']) {
$notification->conversation_id = (int)$notification->data['conversation_id'];
$notification->save();
}
}
}
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('notifications', function (Blueprint $table) {
$table->dropColumn('conversation_id');
$table->dropIndex('notifications_conversation_id');
});
}
}