101 lines
2.4 KiB
PHP
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);
|
|
}
|
|
}
|