Files
cloud-chip.cn/app/Models/Article.php
T
2026-08-08 18:27:38 +08:00

101 lines
2.4 KiB
PHP

<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\SoftDeletes;
class Article extends Model
{
use SoftDeletes;
protected $fillable = [
'category_id',
'user_id',
'title',
'slug',
'summary',
'body',
'cover',
'author',
'status',
'template',
'seo_title',
'seo_description',
'published_at',
];
protected $casts = [
'category_id' => 'integer',
'published_at' => 'datetime',
];
public const TEMPLATES = [
'standard' => '标准文章',
'tech' => '技术文档',
'feature' => '专题报道',
];
public function category(): BelongsTo
{
return $this->belongsTo(Category::class, 'category_id');
}
public function user(): BelongsTo
{
return $this->belongsTo(User::class, 'user_id');
}
/**
* 可见性作用域(与 forum 一致):
* - 审核员(articles.moderate):看全部
* - 登录用户:看已审 + 自己投稿(无论状态)
* - 游客:仅看已审
*/
public function scopeVisibleTo($query, ?User $user = null)
{
if ($user && $user->canPerm('articles.moderate')) {
return $query;
}
if ($user) {
return $query->where(function ($q) use ($user) {
$q->where('status', 'approved')->orWhere('user_id', $user->id);
});
}
return $query->where('status', 'approved');
}
public function scopePublished($query)
{
return $query->where('status', 'approved')
->whereNotNull('published_at')
->orderByDesc('published_at');
}
/**
* 前台可见文章:已审核通过(approved) 且已设定发布时间。
* 用户自己的待审(pending)/驳回(rejected) 由控制器单独查询,不进此作用域。
*/
public function scopeVisiblePublic($query)
{
return $query->where('status', 'approved')
->whereNotNull('published_at');
}
/**
* 前台 SEO 标题:优先用文章自定义,否则回退到标题。
*/
public function seoTitle(): string
{
return $this->seo_title ?: $this->title;
}
public function seoDescription(): string
{
return $this->seo_description ?: ($this->summary ?: $this->title);
}
}