e13df69885
API CI/CD / Validate (composer + pint) (push) Successful in 3m6s
API CI/CD / Test (PHPUnit) (push) Failing after 4m53s
API CI/CD / Build frontend assets (push) Successful in 1m2s
API CI/CD / Security audit (push) Failing after 59s
API CI/CD / Deploy to shared hosting (PHP) (push) Has been skipped
115 lines
3.0 KiB
PHP
115 lines
3.0 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
|
|
class UserNotification extends BaseModel
|
|
{
|
|
protected $table = 'user_notifications';
|
|
|
|
/**
|
|
* legacy: timestamps disabled (uses delivered_at)
|
|
*/
|
|
public $timestamps = false;
|
|
|
|
protected $fillable = ['notification_id', 'user_id', 'is_read', 'delivered', 'delivered_at', 'school_year', 'semester'];
|
|
|
|
protected $casts = [
|
|
'notification_id' => 'integer',
|
|
'user_id' => 'integer',
|
|
'is_read' => 'boolean',
|
|
'delivered' => 'boolean',
|
|
'delivered_at' => 'datetime',
|
|
];
|
|
|
|
/* ============================================================
|
|
* Relationships (optional)
|
|
* ============================================================
|
|
*/
|
|
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class, 'user_id');
|
|
}
|
|
|
|
public function notification(): BelongsTo
|
|
{
|
|
// Change Notification::class if your model name differs
|
|
return $this->belongsTo(Notification::class, 'notification_id');
|
|
}
|
|
|
|
/* ============================================================
|
|
* Scopes
|
|
* ============================================================
|
|
*/
|
|
|
|
public function scopeForUser(Builder $q, int $userId): Builder
|
|
{
|
|
return $q->where('user_id', $userId);
|
|
}
|
|
|
|
public function scopeUnread(Builder $q): Builder
|
|
{
|
|
return $q->where('is_read', 0);
|
|
}
|
|
|
|
public function scopeRead(Builder $q): Builder
|
|
{
|
|
return $q->where('is_read', 1);
|
|
}
|
|
|
|
public function scopeDelivered(Builder $q): Builder
|
|
{
|
|
return $q->where('delivered', 1);
|
|
}
|
|
|
|
public function scopeUndelivered(Builder $q): Builder
|
|
{
|
|
return $q->where(function (Builder $w) {
|
|
$w->whereNull('delivered')->orWhere('delivered', 0);
|
|
});
|
|
}
|
|
|
|
/* ============================================================
|
|
* Helpers
|
|
* ============================================================
|
|
*/
|
|
|
|
public function markDelivered(?\DateTimeInterface $at = null): self
|
|
{
|
|
$this->delivered = true;
|
|
$this->delivered_at = $at ?: now();
|
|
$this->save();
|
|
|
|
return $this;
|
|
}
|
|
|
|
public function markRead(): self
|
|
{
|
|
$this->is_read = true;
|
|
$this->save();
|
|
|
|
return $this;
|
|
}
|
|
|
|
/* ============================================================
|
|
* Optional validation helper
|
|
* ============================================================
|
|
*/
|
|
|
|
public static function rules(bool $updating = false): array
|
|
{
|
|
$req = $updating ? 'sometimes' : 'required';
|
|
|
|
return [
|
|
'notification_id' => [$req, 'integer', 'min:1', 'exists:notifications,id'],
|
|
'user_id' => [$req, 'integer', 'min:1', 'exists:users,id'],
|
|
'is_read' => ['nullable', 'boolean'],
|
|
'delivered' => ['nullable', 'boolean'],
|
|
'delivered_at' => ['nullable', 'date'],
|
|
];
|
|
}
|
|
}
|