103 lines
2.7 KiB
PHP
103 lines
2.7 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
/**
|
|
* @property int $id
|
|
* @property int $user_id
|
|
* @property string $title
|
|
* @property string $body
|
|
* @property string|null $url
|
|
* @property bool $is_achievement
|
|
* @property int|null $achievement_id
|
|
* @property \Carbon\Carbon|null $read_at
|
|
* @property \Carbon\Carbon|null $dismissed_at
|
|
* @property \Carbon\Carbon|null $expires_at
|
|
*
|
|
* @property-read User $user
|
|
* @property-read Achievement|null $achievement
|
|
*
|
|
* @method static Builder unread()
|
|
* @method static Builder undismissed()
|
|
* @method static Builder active()
|
|
* @method static Builder forAchievements()
|
|
*/
|
|
class Notification extends Model
|
|
{
|
|
protected $fillable = [
|
|
'user_id',
|
|
'title',
|
|
'body',
|
|
'url',
|
|
'is_achievement',
|
|
'achievement_id',
|
|
'read_at',
|
|
'expires_at',
|
|
];
|
|
|
|
protected $casts = [
|
|
'is_achievement' => 'boolean',
|
|
'read_at' => 'datetime',
|
|
'expires_at' => 'datetime',
|
|
];
|
|
|
|
// ---------------------------------------------------------------
|
|
// Relationships
|
|
// ---------------------------------------------------------------
|
|
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
public function achievement(): BelongsTo
|
|
{
|
|
return $this->belongsTo(Achievement::class);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
// Scopes
|
|
// ---------------------------------------------------------------
|
|
|
|
/** Notifications the user hasn't opened yet. */
|
|
public function scopeUnread(Builder $query): void
|
|
{
|
|
$query->whereNull('read_at');
|
|
}
|
|
|
|
/** Not expired (no expiry set, or expiry is in the future). */
|
|
public function scopeActive(Builder $query): void
|
|
{
|
|
$query->where(function (Builder $q) {
|
|
$q->whereNull('expires_at')
|
|
->orWhere('expires_at', '>', now());
|
|
});
|
|
}
|
|
|
|
/** Only achievement notifications. */
|
|
public function scopeForAchievements(Builder $query): void
|
|
{
|
|
$query->where('is_achievement', true);
|
|
}
|
|
|
|
// ---------------------------------------------------------------
|
|
// Helpers
|
|
// ---------------------------------------------------------------
|
|
|
|
public function markAsRead(): void
|
|
{
|
|
if (! $this->read_at) {
|
|
$this->update(['read_at' => now()]);
|
|
}
|
|
}
|
|
|
|
public function isExpired(): bool
|
|
{
|
|
return $this->expires_at !== null && $this->expires_at->isPast();
|
|
}
|
|
}
|