Raise PHPStan level tp 6
This commit is contained in:
parent
52ddf8c055
commit
07745b170e
33 changed files with 198 additions and 21 deletions
|
|
@ -11,6 +11,7 @@ public function canParse(string $url): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract article data from HTML
|
* Extract article data from HTML
|
||||||
|
* @return array<string, mixed>
|
||||||
*/
|
*/
|
||||||
public function extractData(string $html): array;
|
public function extractData(string $html): array;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,7 @@ public function canParse(string $url): bool;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract article URLs from homepage HTML
|
* Extract article URLs from homepage HTML
|
||||||
|
* @return array<int, string>
|
||||||
*/
|
*/
|
||||||
public function extractArticleUrls(string $html): array;
|
public function extractArticleUrls(string $html): array;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,7 @@ public function __construct(
|
||||||
public Throwable $exception,
|
public Throwable $exception,
|
||||||
public LogLevelEnum $level,
|
public LogLevelEnum $level,
|
||||||
public string $message,
|
public string $message,
|
||||||
|
/** @var array<string, mixed> */
|
||||||
public array $context = []
|
public array $context = []
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -149,6 +149,9 @@ public function toggle(Request $request, Feed $feed, PlatformChannel $channel):
|
||||||
->with('success', "Routing {$status} successfully!");
|
->with('success', "Routing {$status} successfully!");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>|null
|
||||||
|
*/
|
||||||
private function parseJsonFilters(?string $json): ?array
|
private function parseJsonFilters(?string $json): ?array
|
||||||
{
|
{
|
||||||
if (empty($json)) {
|
if (empty($json)) {
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ public function authorize(): bool
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -11,6 +11,9 @@ public function authorize(): bool
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
public function rules(): array
|
public function rules(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@ enum LogLevelEnum: string
|
||||||
case ERROR = 'error';
|
case ERROR = 'error';
|
||||||
case CRITICAL = 'critical';
|
case CRITICAL = 'critical';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
public static function toArray(): array
|
public static function toArray(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -11,9 +11,9 @@
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method static firstOrCreate(string[] $array)
|
* @method static firstOrCreate(array<string, mixed> $array)
|
||||||
* @method static where(string $string, string $url)
|
* @method static where(string $string, string $url)
|
||||||
* @method static create(string[] $array)
|
* @method static create(array<string, mixed> $array)
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property int $feed_id
|
* @property int $feed_id
|
||||||
* @property Feed $feed
|
* @property Feed $feed
|
||||||
|
|
@ -40,6 +40,9 @@ class Article extends Model
|
||||||
'validated_at',
|
'validated_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
public function casts(): array
|
public function casts(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
@ -65,11 +68,17 @@ public function isValid(): bool
|
||||||
return $this->is_valid;
|
return $this->is_valid;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HasOne<ArticlePublication, $this>
|
||||||
|
*/
|
||||||
public function articlePublication(): HasOne
|
public function articlePublication(): HasOne
|
||||||
{
|
{
|
||||||
return $this->hasOne(ArticlePublication::class);
|
return $this->hasOne(ArticlePublication::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<Feed, $this>
|
||||||
|
*/
|
||||||
public function feed(): BelongsTo
|
public function feed(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Feed::class);
|
return $this->belongsTo(Feed::class);
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
* @property integer $platform_channel_id
|
* @property integer $platform_channel_id
|
||||||
* @property integer $post_id
|
* @property integer $post_id
|
||||||
*
|
*
|
||||||
* @method static create(array $array)
|
* @method static create(array<string, mixed> $array)
|
||||||
*/
|
*/
|
||||||
class ArticlePublication extends Model
|
class ArticlePublication extends Model
|
||||||
{
|
{
|
||||||
|
|
@ -29,6 +29,9 @@ class ArticlePublication extends Model
|
||||||
'publication_data' => 'array',
|
'publication_data' => 'array',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<Article, $this>
|
||||||
|
*/
|
||||||
public function article(): BelongsTo
|
public function article(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Article::class);
|
return $this->belongsTo(Article::class);
|
||||||
|
|
|
||||||
|
|
@ -18,12 +18,12 @@
|
||||||
* @property int $language_id
|
* @property int $language_id
|
||||||
* @property Language|null $language
|
* @property Language|null $language
|
||||||
* @property string $description
|
* @property string $description
|
||||||
* @property array $settings
|
* @property array<string, mixed> $settings
|
||||||
* @property bool $is_active
|
* @property bool $is_active
|
||||||
* @property Carbon|null $last_fetched_at
|
* @property Carbon|null $last_fetched_at
|
||||||
* @property Carbon $created_at
|
* @property Carbon $created_at
|
||||||
* @property Carbon $updated_at
|
* @property Carbon $updated_at
|
||||||
* @method static create(array $validated)
|
* @method static create(array<string, mixed> $validated)
|
||||||
* @method static orderBy(string $string, string $string1)
|
* @method static orderBy(string $string, string $string1)
|
||||||
* @method static where(string $string, true $true)
|
* @method static where(string $string, true $true)
|
||||||
* @method static findOrFail(mixed $feed_id)
|
* @method static findOrFail(mixed $feed_id)
|
||||||
|
|
@ -82,6 +82,9 @@ public function getStatusAttribute(): string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<PlatformChannel, $this, FeedPlatformChannel>
|
||||||
|
*/
|
||||||
public function channels(): BelongsToMany
|
public function channels(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(PlatformChannel::class, 'feed_platform_channels')
|
return $this->belongsToMany(PlatformChannel::class, 'feed_platform_channels')
|
||||||
|
|
@ -90,6 +93,9 @@ public function channels(): BelongsToMany
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<PlatformChannel, $this, FeedPlatformChannel>
|
||||||
|
*/
|
||||||
public function activeChannels(): BelongsToMany
|
public function activeChannels(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->channels()
|
return $this->channels()
|
||||||
|
|
@ -97,11 +103,17 @@ public function activeChannels(): BelongsToMany
|
||||||
->orderByPivot('priority', 'desc');
|
->orderByPivot('priority', 'desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HasMany<Article, $this>
|
||||||
|
*/
|
||||||
public function articles(): HasMany
|
public function articles(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Article::class);
|
return $this->hasMany(Article::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<Language, $this>
|
||||||
|
*/
|
||||||
public function language(): BelongsTo
|
public function language(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Language::class);
|
return $this->belongsTo(Language::class);
|
||||||
|
|
|
||||||
|
|
@ -12,10 +12,10 @@
|
||||||
* @property int $platform_channel_id
|
* @property int $platform_channel_id
|
||||||
* @property bool $is_active
|
* @property bool $is_active
|
||||||
* @property int $priority
|
* @property int $priority
|
||||||
* @property array $filters
|
* @property array<string, mixed> $filters
|
||||||
* @property Carbon $created_at
|
* @property Carbon $created_at
|
||||||
* @property Carbon $updated_at
|
* @property Carbon $updated_at
|
||||||
* @method static create(array $array)
|
* @method static create(array<string, mixed> $array)
|
||||||
*/
|
*/
|
||||||
class FeedPlatformChannel extends Pivot
|
class FeedPlatformChannel extends Pivot
|
||||||
{
|
{
|
||||||
|
|
@ -36,16 +36,25 @@ class FeedPlatformChannel extends Pivot
|
||||||
'filters' => 'array'
|
'filters' => 'array'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<Feed, $this>
|
||||||
|
*/
|
||||||
public function feed(): BelongsTo
|
public function feed(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Feed::class);
|
return $this->belongsTo(Feed::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<PlatformChannel, $this>
|
||||||
|
*/
|
||||||
public function platformChannel(): BelongsTo
|
public function platformChannel(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(PlatformChannel::class);
|
return $this->belongsTo(PlatformChannel::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HasMany<Keyword, $this>
|
||||||
|
*/
|
||||||
public function keywords(): HasMany
|
public function keywords(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Keyword::class, 'feed_id', 'feed_id')
|
return $this->hasMany(Keyword::class, 'feed_id', 'feed_id')
|
||||||
|
|
|
||||||
|
|
@ -30,11 +30,17 @@ class Keyword extends Model
|
||||||
'is_active' => 'boolean'
|
'is_active' => 'boolean'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<Feed, $this>
|
||||||
|
*/
|
||||||
public function feed(): BelongsTo
|
public function feed(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Feed::class);
|
return $this->belongsTo(Feed::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<PlatformChannel, $this>
|
||||||
|
*/
|
||||||
public function platformChannel(): BelongsTo
|
public function platformChannel(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(PlatformChannel::class);
|
return $this->belongsTo(PlatformChannel::class);
|
||||||
|
|
|
||||||
|
|
@ -24,6 +24,9 @@ class Language extends Model
|
||||||
'is_active' => 'boolean'
|
'is_active' => 'boolean'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<PlatformInstance, $this>
|
||||||
|
*/
|
||||||
public function platformInstances(): BelongsToMany
|
public function platformInstances(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(PlatformInstance::class)
|
return $this->belongsToMany(PlatformInstance::class)
|
||||||
|
|
@ -31,11 +34,17 @@ public function platformInstances(): BelongsToMany
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HasMany<PlatformChannel, $this>
|
||||||
|
*/
|
||||||
public function platformChannels(): HasMany
|
public function platformChannels(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(PlatformChannel::class);
|
return $this->hasMany(PlatformChannel::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HasMany<Feed, $this>
|
||||||
|
*/
|
||||||
public function feeds(): HasMany
|
public function feeds(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(Feed::class);
|
return $this->hasMany(Feed::class);
|
||||||
|
|
|
||||||
|
|
@ -7,10 +7,10 @@
|
||||||
use Illuminate\Support\Carbon;
|
use Illuminate\Support\Carbon;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method static create(array $array)
|
* @method static create(array<string, mixed> $array)
|
||||||
* @property LogLevelEnum $level
|
* @property LogLevelEnum $level
|
||||||
* @property string $message
|
* @property string $message
|
||||||
* @property array $context
|
* @property array<string, mixed> $context
|
||||||
* @property Carbon $created_at
|
* @property Carbon $created_at
|
||||||
* @property Carbon $updated_at
|
* @property Carbon $updated_at
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -24,10 +24,10 @@
|
||||||
* @property string $status
|
* @property string $status
|
||||||
* @property Carbon $created_at
|
* @property Carbon $created_at
|
||||||
* @property Carbon $updated_at
|
* @property Carbon $updated_at
|
||||||
* @property Collection $activeChannels
|
* @property Collection<int, PlatformChannel> $activeChannels
|
||||||
* @method static where(string $string, PlatformEnum $platform)
|
* @method static where(string $string, PlatformEnum $platform)
|
||||||
* @method static orderBy(string $string)
|
* @method static orderBy(string $string)
|
||||||
* @method static create(array $validated)
|
* @method static create(array<string, mixed> $validated)
|
||||||
*/
|
*/
|
||||||
class PlatformAccount extends Model
|
class PlatformAccount extends Model
|
||||||
{
|
{
|
||||||
|
|
@ -54,6 +54,9 @@ class PlatformAccount extends Model
|
||||||
];
|
];
|
||||||
|
|
||||||
// Encrypt password when storing
|
// Encrypt password when storing
|
||||||
|
/**
|
||||||
|
* @return Attribute<string|null, string|null>
|
||||||
|
*/
|
||||||
protected function password(): Attribute
|
protected function password(): Attribute
|
||||||
{
|
{
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
|
|
@ -63,6 +66,9 @@ protected function password(): Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt API token when storing
|
// Encrypt API token when storing
|
||||||
|
/**
|
||||||
|
* @return Attribute<string|null, string|null>
|
||||||
|
*/
|
||||||
protected function apiToken(): Attribute
|
protected function apiToken(): Attribute
|
||||||
{
|
{
|
||||||
return Attribute::make(
|
return Attribute::make(
|
||||||
|
|
@ -72,6 +78,9 @@ protected function apiToken(): Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get the active accounts for a platform (returns collection)
|
// Get the active accounts for a platform (returns collection)
|
||||||
|
/**
|
||||||
|
* @return Collection<int, PlatformAccount>
|
||||||
|
*/
|
||||||
public static function getActive(PlatformEnum $platform): Collection
|
public static function getActive(PlatformEnum $platform): Collection
|
||||||
{
|
{
|
||||||
return static::where('platform', $platform)
|
return static::where('platform', $platform)
|
||||||
|
|
@ -91,6 +100,9 @@ public function setAsActive(): void
|
||||||
$this->update(['is_active' => true]);
|
$this->update(['is_active' => true]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<PlatformChannel, $this>
|
||||||
|
*/
|
||||||
public function channels(): BelongsToMany
|
public function channels(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
|
return $this->belongsToMany(PlatformChannel::class, 'platform_account_channels')
|
||||||
|
|
@ -98,6 +110,9 @@ public function channels(): BelongsToMany
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<PlatformChannel, $this>
|
||||||
|
*/
|
||||||
public function activeChannels(): BelongsToMany
|
public function activeChannels(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->channels()
|
return $this->channels()
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
namespace App\Models;
|
namespace App\Models;
|
||||||
|
|
||||||
use App\Enums\PlatformEnum;
|
|
||||||
use Database\Factories\PlatformChannelFactory;
|
use Database\Factories\PlatformChannelFactory;
|
||||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||||
use Illuminate\Database\Eloquent\Model;
|
use Illuminate\Database\Eloquent\Model;
|
||||||
|
|
@ -10,7 +9,7 @@
|
||||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method static create(array $validated)
|
* @method static create(array<string, mixed> $validated)
|
||||||
* @method static findMany(mixed $channel_ids)
|
* @method static findMany(mixed $channel_ids)
|
||||||
* @property integer $id
|
* @property integer $id
|
||||||
* @property integer $platform_instance_id
|
* @property integer $platform_instance_id
|
||||||
|
|
@ -42,11 +41,17 @@ class PlatformChannel extends Model
|
||||||
'is_active' => 'boolean'
|
'is_active' => 'boolean'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<PlatformInstance, $this>
|
||||||
|
*/
|
||||||
public function platformInstance(): BelongsTo
|
public function platformInstance(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(PlatformInstance::class);
|
return $this->belongsTo(PlatformInstance::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<PlatformAccount, $this>
|
||||||
|
*/
|
||||||
public function platformAccounts(): BelongsToMany
|
public function platformAccounts(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
|
return $this->belongsToMany(PlatformAccount::class, 'platform_account_channels')
|
||||||
|
|
@ -54,6 +59,9 @@ public function platformAccounts(): BelongsToMany
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<PlatformAccount, $this>
|
||||||
|
*/
|
||||||
public function activePlatformAccounts(): BelongsToMany
|
public function activePlatformAccounts(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->platformAccounts()->where('is_active', true);
|
return $this->platformAccounts()->where('is_active', true);
|
||||||
|
|
@ -65,6 +73,9 @@ public function getFullNameAttribute(): string
|
||||||
return $this->platformInstance->url . '/c/' . $this->name;
|
return $this->platformInstance->url . '/c/' . $this->name;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<Feed, $this, FeedPlatformChannel>
|
||||||
|
*/
|
||||||
public function feeds(): BelongsToMany
|
public function feeds(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Feed::class, 'feed_platform_channels')
|
return $this->belongsToMany(Feed::class, 'feed_platform_channels')
|
||||||
|
|
@ -73,6 +84,9 @@ public function feeds(): BelongsToMany
|
||||||
->withTimestamps();
|
->withTimestamps();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<Feed, $this, FeedPlatformChannel>
|
||||||
|
*/
|
||||||
public function activeFeeds(): BelongsToMany
|
public function activeFeeds(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->feeds()
|
return $this->feeds()
|
||||||
|
|
@ -80,6 +94,9 @@ public function activeFeeds(): BelongsToMany
|
||||||
->orderByPivot('priority', 'desc');
|
->orderByPivot('priority', 'desc');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsTo<Language, $this>
|
||||||
|
*/
|
||||||
public function language(): BelongsTo
|
public function language(): BelongsTo
|
||||||
{
|
{
|
||||||
return $this->belongsTo(Language::class);
|
return $this->belongsTo(Language::class);
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method static where(string $string, PlatformEnum $platform)
|
* @method static where(string $string, PlatformEnum $platform)
|
||||||
* @method static updateOrCreate(array $array, array $array1)
|
* @method static updateOrCreate(array<string, mixed> $array, array<string, mixed> $array1)
|
||||||
*/
|
*/
|
||||||
class PlatformChannelPost extends Model
|
class PlatformChannelPost extends Model
|
||||||
{
|
{
|
||||||
|
|
@ -21,6 +21,9 @@ class PlatformChannelPost extends Model
|
||||||
'posted_at',
|
'posted_at',
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string>
|
||||||
|
*/
|
||||||
protected function casts(): array
|
protected function casts(): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,7 @@
|
||||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @method static updateOrCreate(array $array, $instanceData)
|
* @method static updateOrCreate(array<string, mixed> $array, $instanceData)
|
||||||
* @method static where(string $string, mixed $operator)
|
* @method static where(string $string, mixed $operator)
|
||||||
* @property PlatformEnum $platform
|
* @property PlatformEnum $platform
|
||||||
* @property string $url
|
* @property string $url
|
||||||
|
|
@ -36,11 +36,17 @@ class PlatformInstance extends Model
|
||||||
'is_active' => 'boolean'
|
'is_active' => 'boolean'
|
||||||
];
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return HasMany<PlatformChannel, $this>
|
||||||
|
*/
|
||||||
public function channels(): HasMany
|
public function channels(): HasMany
|
||||||
{
|
{
|
||||||
return $this->hasMany(PlatformChannel::class);
|
return $this->hasMany(PlatformChannel::class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return BelongsToMany<Language, $this>
|
||||||
|
*/
|
||||||
public function languages(): BelongsToMany
|
public function languages(): BelongsToMany
|
||||||
{
|
{
|
||||||
return $this->belongsToMany(Language::class)
|
return $this->belongsToMany(Language::class)
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,9 @@ public function __construct(string $instance, ?string $token = null)
|
||||||
$this->token = $token;
|
$this->token = $token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $params
|
||||||
|
*/
|
||||||
public function get(string $endpoint, array $params = []): Response
|
public function get(string $endpoint, array $params = []): Response
|
||||||
{
|
{
|
||||||
$url = "https://{$this->instance}/api/v3/{$endpoint}";
|
$url = "https://{$this->instance}/api/v3/{$endpoint}";
|
||||||
|
|
@ -29,6 +32,9 @@ public function get(string $endpoint, array $params = []): Response
|
||||||
return $request->get($url, $params);
|
return $request->get($url, $params);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $data
|
||||||
|
*/
|
||||||
public function post(string $endpoint, array $data = []): Response
|
public function post(string $endpoint, array $data = []): Response
|
||||||
{
|
{
|
||||||
$url = "https://{$this->instance}/api/v3/{$endpoint}";
|
$url = "https://{$this->instance}/api/v3/{$endpoint}";
|
||||||
|
|
|
||||||
|
|
@ -107,6 +107,9 @@ public function syncChannelPosts(string $token, int $platformChannelId, string $
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
|
public function createPost(string $token, string $title, string $body, int $platformChannelId, ?string $url = null, ?string $thumbnail = null, ?int $languageId = null): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
@ -143,6 +146,9 @@ public function createPost(string $token, string $title, string $body, int $plat
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, mixed>
|
||||||
|
*/
|
||||||
public function getLanguages(): array
|
public function getLanguages(): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,8 @@ public function __construct(PlatformAccount $account)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* @param array<string, mixed> $extractedData
|
||||||
|
* @return array<string, mixed>
|
||||||
* @throws PlatformAuthException
|
* @throws PlatformAuthException
|
||||||
* @throws Exception
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,9 @@
|
||||||
|
|
||||||
class ArticleFetcher
|
class ArticleFetcher
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Article>
|
||||||
|
*/
|
||||||
public static function getArticlesFromFeed(Feed $feed): Collection
|
public static function getArticlesFromFeed(Feed $feed): Collection
|
||||||
{
|
{
|
||||||
if ($feed->type === 'rss') {
|
if ($feed->type === 'rss') {
|
||||||
|
|
@ -29,6 +32,9 @@ public static function getArticlesFromFeed(Feed $feed): Collection
|
||||||
return collect();
|
return collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Article>
|
||||||
|
*/
|
||||||
private static function getArticlesFromRssFeed(Feed $feed): Collection
|
private static function getArticlesFromRssFeed(Feed $feed): Collection
|
||||||
{
|
{
|
||||||
// TODO: Implement RSS feed parsing
|
// TODO: Implement RSS feed parsing
|
||||||
|
|
@ -36,6 +42,9 @@ private static function getArticlesFromRssFeed(Feed $feed): Collection
|
||||||
return collect();
|
return collect();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Collection<int, Article>
|
||||||
|
*/
|
||||||
private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
|
private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
@ -68,6 +77,9 @@ private static function getArticlesFromWebsiteFeed(Feed $feed): Collection
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, mixed>
|
||||||
|
*/
|
||||||
public static function fetchArticleData(Article $article): array
|
public static function fetchArticleData(Article $article): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -9,6 +9,9 @@
|
||||||
|
|
||||||
class ArticleParserFactory
|
class ArticleParserFactory
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var array<int, class-string<ArticleParserInterface>>
|
||||||
|
*/
|
||||||
private static array $parsers = [
|
private static array $parsers = [
|
||||||
VrtArticleParser::class,
|
VrtArticleParser::class,
|
||||||
BelgaArticleParser::class,
|
BelgaArticleParser::class,
|
||||||
|
|
@ -27,6 +30,9 @@ public static function getParser(string $url): ArticleParserInterface
|
||||||
throw new Exception("No parser found for URL: {$url}");
|
throw new Exception("No parser found for URL: {$url}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
public static function getSupportedSources(): array
|
public static function getSupportedSources(): array
|
||||||
{
|
{
|
||||||
return array_map(function($parserClass) {
|
return array_map(function($parserClass) {
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,9 @@
|
||||||
|
|
||||||
class HomepageParserFactory
|
class HomepageParserFactory
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @var array<int, class-string<HomepageParserInterface>>
|
||||||
|
*/
|
||||||
private static array $parsers = [
|
private static array $parsers = [
|
||||||
VrtHomepageParserAdapter::class,
|
VrtHomepageParserAdapter::class,
|
||||||
BelgaHomepageParserAdapter::class,
|
BelgaHomepageParserAdapter::class,
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,10 @@ public static function fetchHtml(string $url): string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<int, string> $urls
|
||||||
|
* @return array<int, array<string, mixed>>
|
||||||
|
*/
|
||||||
public static function fetchMultipleUrls(array $urls): array
|
public static function fetchMultipleUrls(array $urls): array
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -8,26 +8,41 @@
|
||||||
|
|
||||||
class LogSaver
|
class LogSaver
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public static function info(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
public static function info(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
||||||
{
|
{
|
||||||
self::log(LogLevelEnum::INFO, $message, $channel, $context);
|
self::log(LogLevelEnum::INFO, $message, $channel, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public static function error(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
public static function error(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
||||||
{
|
{
|
||||||
self::log(LogLevelEnum::ERROR, $message, $channel, $context);
|
self::log(LogLevelEnum::ERROR, $message, $channel, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public static function warning(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
public static function warning(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
||||||
{
|
{
|
||||||
self::log(LogLevelEnum::WARNING, $message, $channel, $context);
|
self::log(LogLevelEnum::WARNING, $message, $channel, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
public static function debug(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
public static function debug(string $message, ?PlatformChannel $channel = null, array $context = []): void
|
||||||
{
|
{
|
||||||
self::log(LogLevelEnum::DEBUG, $message, $channel, $context);
|
self::log(LogLevelEnum::DEBUG, $message, $channel, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array<string, mixed> $context
|
||||||
|
*/
|
||||||
private static function log(LogLevelEnum $level, string $message, ?PlatformChannel $channel = null, array $context = []): void
|
private static function log(LogLevelEnum $level, string $message, ?PlatformChannel $channel = null, array $context = []): void
|
||||||
{
|
{
|
||||||
$logContext = $context;
|
$logContext = $context;
|
||||||
|
|
|
||||||
|
|
@ -95,6 +95,9 @@ public static function extractThumbnail(string $html): ?string
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string|null>
|
||||||
|
*/
|
||||||
public static function extractData(string $html): array
|
public static function extractData(string $html): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
class BelgaHomepageParser
|
class BelgaHomepageParser
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
public static function extractArticleUrls(string $html): array
|
public static function extractArticleUrls(string $html): array
|
||||||
{
|
{
|
||||||
preg_match_all('/href="(https:\/\/www\.belganewsagency\.eu\/[a-z0-9-]+)"/', $html, $matches);
|
preg_match_all('/href="(https:\/\/www\.belganewsagency\.eu\/[a-z0-9-]+)"/', $html, $matches);
|
||||||
|
|
|
||||||
|
|
@ -77,6 +77,9 @@ public static function extractThumbnail(string $html): ?string
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return array<string, string|null>
|
||||||
|
*/
|
||||||
public static function extractData(string $html): array
|
public static function extractData(string $html): array
|
||||||
{
|
{
|
||||||
return [
|
return [
|
||||||
|
|
|
||||||
|
|
@ -4,6 +4,9 @@
|
||||||
|
|
||||||
class VrtHomepageParser
|
class VrtHomepageParser
|
||||||
{
|
{
|
||||||
|
/**
|
||||||
|
* @return array<int, string>
|
||||||
|
*/
|
||||||
public static function extractArticleUrls(string $html): array
|
public static function extractArticleUrls(string $html): array
|
||||||
{
|
{
|
||||||
// Extract article links using regex
|
// Extract article links using regex
|
||||||
|
|
|
||||||
|
|
@ -17,9 +17,11 @@
|
||||||
class ArticlePublishingService
|
class ArticlePublishingService
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
* @param array<string, mixed> $extractedData
|
||||||
|
* @return EloquentCollection<int, ArticlePublication>
|
||||||
* @throws PublishException
|
* @throws PublishException
|
||||||
*/
|
*/
|
||||||
public function publishToRoutedChannels(Article $article, array $extractedData): Collection
|
public function publishToRoutedChannels(Article $article, array $extractedData): EloquentCollection
|
||||||
{
|
{
|
||||||
if (! $article->is_valid) {
|
if (! $article->is_valid) {
|
||||||
throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
|
throw new PublishException($article, PlatformEnum::LEMMY, new RuntimeException('CANNOT_PUBLISH_INVALID_ARTICLE'));
|
||||||
|
|
@ -46,7 +48,10 @@ public function publishToRoutedChannels(Article $article, array $extractedData):
|
||||||
->filter();
|
->filter();
|
||||||
}
|
}
|
||||||
|
|
||||||
private function publishToChannel(Article $article, array $extractedData, $channel, $account): ?ArticlePublication
|
/**
|
||||||
|
* @param array<string, mixed> $extractedData
|
||||||
|
*/
|
||||||
|
private function publishToChannel(Article $article, array $extractedData, PlatformChannel $channel, mixed $account): ?ArticlePublication
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
$publisher = new LemmyPublisher($account);
|
$publisher = new LemmyPublisher($account);
|
||||||
|
|
@ -64,7 +69,7 @@ private function publishToChannel(Article $article, array $extractedData, $chann
|
||||||
|
|
||||||
LogSaver::info('Published to channel via routing', $channel, [
|
LogSaver::info('Published to channel via routing', $channel, [
|
||||||
'article_id' => $article->id,
|
'article_id' => $article->id,
|
||||||
'priority' => $channel->pivot->priority
|
'priority' => $channel->pivot->priority ?? null
|
||||||
]);
|
]);
|
||||||
|
|
||||||
return $publication;
|
return $publication;
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,13 @@
|
||||||
|
|
||||||
use App\Exceptions\RoutingMismatchException;
|
use App\Exceptions\RoutingMismatchException;
|
||||||
use App\Models\Feed;
|
use App\Models\Feed;
|
||||||
|
use App\Models\PlatformChannel;
|
||||||
use Illuminate\Support\Collection;
|
use Illuminate\Support\Collection;
|
||||||
|
|
||||||
class RoutingValidationService
|
class RoutingValidationService
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
|
* @param Collection<int, PlatformChannel> $channels
|
||||||
* @throws RoutingMismatchException
|
* @throws RoutingMismatchException
|
||||||
*/
|
*/
|
||||||
public function validateLanguageCompatibility(Feed $feed, Collection $channels): void
|
public function validateLanguageCompatibility(Feed $feed, Collection $channels): void
|
||||||
|
|
|
||||||
|
|
@ -2,11 +2,11 @@ includes:
|
||||||
- vendor/larastan/larastan/extension.neon
|
- vendor/larastan/larastan/extension.neon
|
||||||
|
|
||||||
parameters:
|
parameters:
|
||||||
level: 5
|
level: 6
|
||||||
paths:
|
paths:
|
||||||
- app/
|
- app/
|
||||||
- tests/
|
- tests/
|
||||||
|
|
||||||
excludePaths:
|
excludePaths:
|
||||||
- bootstrap/*.php
|
- bootstrap/*.php
|
||||||
- storage/*
|
- storage/*
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue