2025-07-05 02:37:38 +02:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace App\Models;
|
|
|
|
|
|
|
|
|
|
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
|
|
|
|
|
* @property Language $language
|
2025-07-05 02:37:38 +02:00
|
|
|
* @property string $description
|
|
|
|
|
* @property array $settings
|
|
|
|
|
* @property bool $is_active
|
|
|
|
|
* @property Carbon $last_fetched_at
|
|
|
|
|
* @property Carbon $created_at
|
|
|
|
|
* @property Carbon $updated_at
|
|
|
|
|
* @method static create(array $validated)
|
|
|
|
|
* @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-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
|
|
|
|
|
|
|
|
public function channels(): BelongsToMany
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsToMany(PlatformChannel::class, 'feed_platform_channels')
|
2025-07-05 23:54:43 +02:00
|
|
|
->using(FeedPlatformChannel::class)
|
2025-07-05 18:26:04 +02:00
|
|
|
->withPivot(['is_active', 'priority', 'filters'])
|
|
|
|
|
->withTimestamps();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function activeChannels(): BelongsToMany
|
|
|
|
|
{
|
|
|
|
|
return $this->channels()
|
|
|
|
|
->wherePivot('is_active', true)
|
|
|
|
|
->orderByPivot('priority', 'desc');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function articles(): HasMany
|
|
|
|
|
{
|
|
|
|
|
return $this->hasMany(Article::class);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public function language(): BelongsTo
|
|
|
|
|
{
|
|
|
|
|
return $this->belongsTo(Language::class);
|
|
|
|
|
}
|
2025-07-05 02:37:38 +02:00
|
|
|
}
|