Files
mtdb_movie/app/Actions/News/ImportNewsFromRemoteProvider.php
maher 703f50a09d
Some checks failed
Build / run (push) Has been cancelled
first commit
2025-10-29 11:42:25 +01:00

137 lines
4.4 KiB
PHP
Executable File

<?php
namespace App\Actions\News;
use App\Models\NewsArticle;
use App\Models\Person;
use App\Models\Title;
use App\Services\Data\News\ImdbNewsProvider;
use Carbon\Carbon;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Str;
class ImportNewsFromRemoteProvider
{
public function execute(): void
{
$newArticles = collect(
app(ImdbNewsProvider::class)->getArticles(),
)->map(function ($article) {
$article['slug'] = slugify(Str::limit($article['title'], 50));
return $article;
});
$existing = NewsArticle::whereIn(
'slug',
$newArticles->pluck('slug'),
)->get();
// filter out already existing articles
$newArticles = $newArticles
->filter(
fn($newArticle) => !$existing->first(
fn($existingArticle) => $existingArticle['title'] ===
$newArticle['title'] ||
$existingArticle['slug'] === $newArticle['slug'],
),
)
->unique('slug');
$articlesPayload = $newArticles->map(function ($article, $index) {
$date = isset($article['date'])
? Carbon::parse($article['date'])
: Carbon::now();
return [
'title' => $article['title'],
'body' => $article['body'],
'slug' => $article['slug'],
'image' => $article['image'] ?? null,
'source' => $article['source'] ?? null,
'source_url' => $article['source_url'] ?? null,
'byline' => $article['byline'] ?? null,
'created_at' => $date,
'updated_at' => $date,
];
});
NewsArticle::insert($articlesPayload->toArray());
$this->attachArticlesToRelatedModels($newArticles);
}
protected function attachArticlesToRelatedModels(Collection $articles): void
{
// fetch inserted articles from db
$dbArticles = NewsArticle::whereIn(
'slug',
$articles->pluck('slug'),
)->get(['id', 'slug']);
$titleImdbIds = [];
$personImdbIds = [];
// generate [article_slug => [imdb_id, imdb_id, ...]] arrays
foreach ($articles as $article) {
if (isset($article['imdb_title_ids'])) {
foreach ($article['imdb_title_ids'] as $imdbTitleId) {
$titleImdbIds[$article['slug']][] = $imdbTitleId;
}
}
if (isset($article['imdb_person_ids'])) {
foreach ($article['imdb_person_ids'] as $imdbPersonId) {
$personImdbIds[$article['slug']][] = $imdbPersonId;
}
}
}
// fetch titles and people by imdb_id as [imdb_id => id] arrays
$titles = Title::whereIn(
'imdb_id',
collect($titleImdbIds)
->values()
->flatten(),
)
->pluck('id', 'imdb_id')
->toArray();
$people = Person::whereIn(
'imdb_id',
collect($personImdbIds)
->values()
->flatten(),
)
->pluck('id', 'imdb_id')
->toArray();
// generate titles payload for pivot table
$payload = [];
foreach ($titleImdbIds as $slug => $imdbIds) {
foreach ($imdbIds as $imdbId) {
if (isset($titles[$imdbId])) {
$payload[] = [
'article_id' => $dbArticles->firstWhere('slug', $slug)
->id,
'model_id' => $titles[$imdbId],
'model_type' => Title::MODEL_TYPE,
];
}
}
}
// generate people payload for pivot table
foreach ($personImdbIds as $slug => $imdbIds) {
foreach ($imdbIds as $imdbId) {
if (isset($people[$imdbId])) {
$payload[] = [
'article_id' => $dbArticles->firstWhere('slug', $slug)
->id,
'model_id' => $people[$imdbId],
'model_type' => Person::class,
];
}
}
}
DB::table('news_article_models')->insert($payload);
}
}