the browser-facing portion of osu!
at master 2.7 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\Models\Chat; 7 8use App\Libraries\Notification\BatchIdentities; 9use App\Models\Traits\WithDbCursorHelper; 10use App\Models\User; 11use App\Models\UserNotification; 12use DB; 13use Illuminate\Database\Query\Expression; 14 15/** 16 * @property Channel $channel 17 * @property int $channel_id 18 * @property int|null $last_read_id 19 * @property User $user 20 * @property int $user_id 21 */ 22class UserChannel extends Model 23{ 24 use WithDbCursorHelper; 25 26 const DEFAULT_SORT = 'user_id_asc'; 27 28 const SORTS = [ 29 'user_id_asc' => [['column' => 'user_id', 'order' => 'ASC']], 30 ]; 31 32 public $incrementing = false; 33 public $timestamps = false; 34 35 protected $primaryKey = ':composite'; 36 protected $primaryKeys = ['user_id', 'channel_id']; 37 38 private ?int $lastReadIdToSet; 39 40 public function user() 41 { 42 return $this->belongsTo(User::class, 'user_id'); 43 } 44 45 public function channel() 46 { 47 return $this->belongsTo(Channel::class, 'channel_id'); 48 } 49 50 public function getAttribute($key) 51 { 52 return match ($key) { 53 'channel_id', 54 'user_id' => $this->getRawAttribute($key), 55 56 'last_read_id' => $this->getLastReadId(), 57 58 'channel', 59 'user' => $this->getRelationValue($key), 60 }; 61 } 62 63 // Laravel has own hidden property 64 // TODO: https://github.com/ppy/osu-web/pull/9486#discussion_r1017831112 65 public function isHidden() 66 { 67 return (bool) $this->getRawAttribute('hidden'); 68 } 69 70 public function markAsRead($messageId = null) 71 { 72 $this->lastReadIdToSet = get_int($messageId ?? Message::where('channel_id', $this->channel_id)->max('message_id')); 73 74 if ($this->lastReadIdToSet === null) { 75 return; 76 } 77 78 // this prevents the read marker from going backwards 79 $this->update(['last_read_id' => DB::raw("GREATEST(COALESCE(last_read_id, 0), $this->lastReadIdToSet)")]); 80 81 UserNotification::batchMarkAsRead($this->user, BatchIdentities::fromParams([ 82 'identities' => [ 83 [ 84 'category' => 'channel', 85 'object_type' => 'channel', 86 'object_id' => $this->channel_id, 87 ], 88 ], 89 ])); 90 } 91 92 private function getLastReadId(): ?int 93 { 94 $value = $this->getRawAttribute('last_read_id'); 95 96 // return the value we tried to set it to, not the query expression. 97 return $value instanceof Expression ? $this->lastReadIdToSet : $value; 98 } 99}