You've already forked Epicnabbo-Catalogus-Updated-Daily
173 lines
4.5 KiB
PHP
173 lines
4.5 KiB
PHP
<?php
|
|
|
|
namespace App\Models;
|
|
|
|
use App\Models\Articles\WebsiteArticleComment as ArticleComment;
|
|
use App\Models\Articles\WebsiteArticleReaction as ArticleReaction;
|
|
use App\Models\Articles\Tag;
|
|
use App\Models\Compositions\HasNotificationUrl;
|
|
use App\Models\User;
|
|
use Auth;
|
|
use Illuminate\Database\Eloquent\Builder;
|
|
use Illuminate\Database\Eloquent\Casts\Attribute;
|
|
use Illuminate\Database\Eloquent\Model;
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
|
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
|
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
|
use Str;
|
|
|
|
class Article extends Model
|
|
{
|
|
use HasNotificationUrl;
|
|
|
|
protected $guarded = [];
|
|
|
|
protected $table = 'website_articles';
|
|
|
|
#[\Override]
|
|
public static function boot()
|
|
{
|
|
parent::boot();
|
|
|
|
static::creating(function (Article $article): void {
|
|
$id = Auth::id();
|
|
$article->user_id = is_numeric($id) ? (int) $id : null;
|
|
$article->slug = Str::slug($article->title);
|
|
});
|
|
|
|
static::updating(function (Article $article): void {
|
|
$article->slug = Str::slug($article->title);
|
|
});
|
|
}
|
|
|
|
public function syncPaginatedComments(): void
|
|
{
|
|
$this->setRelation('comments', $this->comments()->paginate(10)->fragment('comments'));
|
|
}
|
|
|
|
/**
|
|
* @return Builder<Article>
|
|
*/
|
|
public static function fromIdAndSlug(string $id, string $slug, bool $withDefaultRelationships = true): Builder
|
|
{
|
|
$query = Article::query()->valid();
|
|
if ($withDefaultRelationships) {
|
|
$query = $query->defaultRelationships();
|
|
}
|
|
|
|
return $query->whereId($id)->whereSlug($slug);
|
|
}
|
|
|
|
public static function getLatestValidArticle(bool $withDefaultRelationships = true): ?Article
|
|
{
|
|
/** @var Article|null $article */
|
|
$article = Article::query()->valid();
|
|
if ($withDefaultRelationships) {
|
|
$article = $article->defaultRelationships();
|
|
}
|
|
$article = $article->latest()->first();
|
|
|
|
if (! $article) {
|
|
return null;
|
|
}
|
|
|
|
$article->syncPaginatedComments();
|
|
|
|
return $article;
|
|
}
|
|
|
|
/**
|
|
* @return Builder<Article>
|
|
*/
|
|
public static function forIndex(int $limit): Builder
|
|
{
|
|
$query = Article::query()->valid();
|
|
|
|
return $query
|
|
->with(['user:id,username,look,avatar_background'])
|
|
->select(['id', 'user_id', 'title', 'slug', 'is_promotion', 'image', 'description', 'promotion_ends_at', 'created_at', 'fixed'])
|
|
->limit($limit)
|
|
->latest();
|
|
}
|
|
|
|
/**
|
|
* @param Builder<Article> $query
|
|
* @return Builder<Article>
|
|
*/
|
|
public function scopeValid(Builder $query): Builder
|
|
{
|
|
return $query->whereVisible(true);
|
|
}
|
|
|
|
/**
|
|
* @param Builder<Article> $query
|
|
* @return Builder<Article>
|
|
*/
|
|
public function scopeDefaultRelationships(Builder $query): Builder
|
|
{
|
|
return $query->with([
|
|
'user:id,username,look,gender',
|
|
'tags',
|
|
'reactions',
|
|
'user.followers',
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @return HasMany<ArticleComment, $this>
|
|
*/
|
|
public function comments(): HasMany
|
|
{
|
|
return $this->hasMany(ArticleComment::class);
|
|
}
|
|
|
|
/**
|
|
* @return HasMany<ArticleReaction, $this>
|
|
*/
|
|
public function reactions(): HasMany
|
|
{
|
|
return $this->hasMany(ArticleReaction::class);
|
|
}
|
|
|
|
/**
|
|
* @return BelongsTo<User, $this>
|
|
*/
|
|
public function user(): BelongsTo
|
|
{
|
|
return $this->belongsTo(User::class);
|
|
}
|
|
|
|
/**
|
|
* @return MorphToMany<Tag, $this>
|
|
*/
|
|
public function tags(): MorphToMany
|
|
{
|
|
return $this->morphToMany(Tag::class, 'taggable');
|
|
}
|
|
|
|
// protected function titleColor(): Attribute
|
|
// {
|
|
// return new Attribute(
|
|
// get: fn () => isDarkColor($this->predominant_color) ? '#fff' : '#000',
|
|
// );
|
|
// }
|
|
|
|
// public function createFollowersNotification(): void
|
|
// {
|
|
// $this->user->followers()
|
|
// ->with('user:id,username')
|
|
// ->each(fn (AuthorNotification $follower) => $follower->user->notify($this->user, NotificationType::ArticlePosted, $this->getNotificationUrl()),
|
|
// );
|
|
// }
|
|
protected function casts(): array
|
|
{
|
|
return [
|
|
'visible' => 'boolean',
|
|
'fixed' => 'boolean',
|
|
'allow_comments' => 'boolean',
|
|
'is_promotion' => 'boolean',
|
|
'promotion_ends_at' => 'datetime',
|
|
];
|
|
}
|
|
}
|