fedi-feed-router/backend/app/Models/Feed.php

120 lines
3.1 KiB
PHP
Raw Normal View History

2025-07-05 02:37:38 +02:00
<?php
namespace App\Models;
2025-07-06 01:35:59 +02:00
use Database\Factories\FeedFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
2025-07-05 02:37:38 +02:00
use Illuminate\Database\Eloquent\Model;
2025-07-05 18:26:04 +02:00
use Illuminate\Database\Eloquent\Relations\BelongsTo;
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
use Illuminate\Database\Eloquent\Relations\HasMany;
2025-07-05 02:37:38 +02:00
use Illuminate\Support\Carbon;
/**
* @property int $id
* @property string $name
* @property string $url
* @property string $type
2025-07-05 18:26:04 +02:00
* @property int $language_id
2025-07-06 20:45:40 +02:00
* @property Language|null $language
2025-07-05 02:37:38 +02:00
* @property string $description
2025-07-07 00:51:32 +02:00
* @property array<string, mixed> $settings
2025-07-05 02:37:38 +02:00
* @property bool $is_active
2025-07-06 20:45:40 +02:00
* @property Carbon|null $last_fetched_at
2025-07-05 02:37:38 +02:00
* @property Carbon $created_at
* @property Carbon $updated_at
* @method static orderBy(string $string, string $string1)
2025-07-05 18:26:04 +02:00
* @method static where(string $string, true $true)
* @method static findOrFail(mixed $feed_id)
2025-07-05 02:37:38 +02:00
*/
class Feed extends Model
{
2025-07-06 01:35:59 +02:00
/** @use HasFactory<FeedFactory> */
use HasFactory;
2025-07-05 18:26:04 +02:00
private const RECENT_FETCH_THRESHOLD_HOURS = 2;
private const DAILY_FETCH_THRESHOLD_HOURS = 24;
2025-07-05 02:37:38 +02:00
protected $fillable = [
'name',
'url',
'type',
2025-07-05 18:26:04 +02:00
'language_id',
2025-07-05 02:37:38 +02:00
'description',
'settings',
'is_active',
'last_fetched_at'
];
protected $casts = [
'settings' => 'array',
'is_active' => 'boolean',
'last_fetched_at' => 'datetime'
];
public function getTypeDisplayAttribute(): string
{
return match ($this->type) {
'website' => 'Website',
'rss' => 'RSS Feed',
default => 'Unknown'
};
}
public function getStatusAttribute(): string
{
if (!$this->is_active) {
return 'Inactive';
}
if (!$this->last_fetched_at) {
return 'Never fetched';
}
$hoursAgo = $this->last_fetched_at->diffInHours(now());
2025-07-05 18:26:04 +02:00
if ($hoursAgo < self::RECENT_FETCH_THRESHOLD_HOURS) {
2025-07-05 02:37:38 +02:00
return 'Recently fetched';
2025-07-05 18:26:04 +02:00
} elseif ($hoursAgo < self::DAILY_FETCH_THRESHOLD_HOURS) {
2025-07-05 02:37:38 +02:00
return "Fetched {$hoursAgo}h ago";
} else {
return "Fetched " . $this->last_fetched_at->diffForHumans();
}
}
2025-07-05 18:26:04 +02:00
2025-07-07 00:51:32 +02:00
/**
2025-07-10 11:14:06 +02:00
* @return BelongsToMany<PlatformChannel, $this, Route>
2025-07-07 00:51:32 +02:00
*/
2025-07-05 18:26:04 +02:00
public function channels(): BelongsToMany
{
2025-07-10 11:14:06 +02:00
return $this->belongsToMany(PlatformChannel::class, 'routes')
2025-07-05 18:26:04 +02:00
->withPivot(['is_active', 'priority', 'filters'])
->withTimestamps();
}
2025-07-07 00:51:32 +02:00
/**
2025-07-10 11:14:06 +02:00
* @return BelongsToMany<PlatformChannel, $this, Route>
2025-07-07 00:51:32 +02:00
*/
2025-07-05 18:26:04 +02:00
public function activeChannels(): BelongsToMany
{
return $this->channels()
->wherePivot('is_active', true)
->orderByPivot('priority', 'desc');
}
2025-07-07 00:51:32 +02:00
/**
* @return HasMany<Article, $this>
*/
2025-07-05 18:26:04 +02:00
public function articles(): HasMany
{
return $this->hasMany(Article::class);
}
2025-07-07 00:51:32 +02:00
/**
* @return BelongsTo<Language, $this>
*/
2025-07-05 18:26:04 +02:00
public function language(): BelongsTo
{
return $this->belongsTo(Language::class);
}
2025-07-05 02:37:38 +02:00
}