Files
larablog/app/Models/Comment.php
T
gouki 3cec4c5e18
CI / PHPUnit (PHP 8.3) (push) Failing after 4s
CI / PHPUnit (PHP 8.2) (push) Failing after 1m9s
CI / Deploy (manual gate) (push) Skipped
wip: article AI polish, category SEO fields, cover generator, membership plan seeder
2026-09-07 18:48:37 +00:00

84 lines
1.8 KiB
PHP

<?php
declare(strict_types=1);
namespace App\Models;
use App\Domain\Plugin\Hook;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Comment extends Model
{
public const STATUS_PENDING = 'pending';
public const STATUS_PENDING_AI = 'pending_ai';
public const STATUS_APPROVED = 'approved';
public const STATUS_REJECTED = 'rejected';
public const STATUS_NEEDS_HUMAN = 'needs_human';
protected $fillable = [
'article_id',
'author',
'url',
'content',
'ip',
'moderation_status',
'published_at',
];
protected function casts(): array
{
return [
'published_at' => 'datetime',
];
}
protected static function booted(): void
{
static::created(function (Comment $comment): void {
Hook::dispatch('comment.created', $comment);
});
}
public function article(): BelongsTo
{
return $this->belongsTo(Article::class);
}
public function scopeApproved(Builder $query): Builder
{
return $query->where('moderation_status', self::STATUS_APPROVED);
}
public function scopeVisible(Builder $query): Builder
{
return $query->approved()
->whereNotNull('published_at')
->where('published_at', '<=', now());
}
public function isApproved(): bool
{
return $this->moderation_status === self::STATUS_APPROVED;
}
public function websiteHref(): ?string
{
$url = trim((string) $this->url);
if ($url === '') {
return null;
}
if (! preg_match('#^https?://#i', $url)) {
return null;
}
return $url;
}
}