the browser-facing portion of osu!
at master 68 lines 2.4 kB view raw
1<?php 2 3// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the GNU Affero General Public License v3.0. 4// See the LICENCE file in the repository root for full licence text. 5 6namespace App\Jobs; 7 8use App\Events\NotificationReadEvent; 9use App\Libraries\MorphMap; 10use App\Models\Forum\Post as ForumPost; 11use App\Models\Notification; 12use App\Models\UserNotification; 13use App\Traits\NotificationQueue; 14use Exception; 15use Illuminate\Bus\Queueable; 16use Illuminate\Contracts\Queue\ShouldQueue; 17use Illuminate\Queue\SerializesModels; 18 19class MarkNotificationsRead implements ShouldQueue 20{ 21 use NotificationQueue, Queueable, SerializesModels; 22 23 private $object; 24 private $user; 25 26 public function __construct($object, $user) 27 { 28 $this->object = $object; 29 $this->user = $user; 30 } 31 32 public function handle() 33 { 34 if (!($this->object instanceof ForumPost)) { 35 throw new Exception('Unknown object to be marked as read: '.get_class($this->object)); 36 } 37 38 $notifiable = $this->object->topic()->withTrashed()->first(); 39 40 if ($notifiable === null) { 41 throw new Exception("Can't find topic {$this->object->getKey()} of post {$this->object->getKey()}"); 42 } 43 44 // TODO: should look at supporting marking stacks up to a certain point as read client side. 45 $userNotifications = UserNotification::where('user_id', $this->user->getKey()) 46 ->where('is_read', false) 47 ->whereHas('notification', function ($query) use ($notifiable) { 48 $query 49 ->where('notifiable_type', MorphMap::getType($notifiable)) 50 ->where('notifiable_id', $notifiable->getKey()) 51 ->where('created_at', '<=', $this->object->post_time); 52 }); 53 54 // only fetch the models that require marking as read. 55 $notifications = Notification::whereIn('id', (clone $userNotifications)->select('notification_id'))->get(); 56 $notificationIdentities = $notifications->map->toIdentityJson()->all(); 57 58 $count = $userNotifications->update(['is_read' => true]); 59 60 if ($count > 0) { 61 (new NotificationReadEvent($this->user->getKey(), [ 62 'notifications' => $notificationIdentities, 63 'read_count' => $count, 64 'timestamp' => now(), 65 ]))->broadcast(); 66 } 67 } 68}