isConfigured()) { $this->error('DeepSeek API anahtarı ayarlanmamış. Admin > Ayarlar > deepseek_api_key'); return self::FAILURE; } $count = (int) $this->option('count'); $animeId = $this->option('anime'); $force = $this->option('force'); if ($animeId) { $animes = Anime::where('id', $animeId)->where('is_published', true)->with('genres')->get(); } else { $alreadyBlogged = $force ? [] : BlogPost::whereNotNull('anime_id')->pluck('anime_id')->toArray(); $animesQuery = Anime::where('is_published', true) ->whereNotIn('id', $alreadyBlogged) ->with('genres') ->orderByDesc('rating') ->limit($count * 3) ->get(); $randomResult = $animesQuery->random(min($count, $animesQuery->count())); $animes = collect($randomResult); } if ($animes->isEmpty()) { $this->info('Blog yazısı üretilecek anime bulunamadı.'); return self::SUCCESS; } $generated = 0; foreach ($animes->take($count) as $anime) { $this->info("Blog üretiliyor: {$anime->title}..."); // Aynı türden ilgili animeler bul $genreIds = $anime->genres->pluck('id'); $related = Anime::where('is_published', true) ->where('id', '!=', $anime->id) ->whereHas('genres', fn($q) => $q->whereIn('genres.id', $genreIds)) ->orderByDesc('rating') ->limit(5) ->get(['id', 'title', 'slug']) ->map(fn($a) => ['slug' => $a->slug, 'title' => $a->title]) ->toArray(); $data = $deepseek->generateBlogPost($anime, $related); if (!$data || empty($data['content'])) { $this->warn(" [{$anime->title}] için içerik üretilemedi: " . $deepseek->lastError); continue; } // [LINK:slug]Title[/LINK] placeholder'larını gerçek URL'lerle değiştir $content = preg_replace_callback( '/\[LINK:([^\]]+)\]([^\[]*)\[\/LINK\]/', function ($m) { $slug = trim($m[1]); $label = trim($m[2]); try { $url = route('anime.show', $slug); return "{$label}"; } catch (\Exception $e) { return $label; } }, $data['content'] ?? '' ); $title = $data['title'] ?? ($anime->title . ' İzle — Animexe Rehberi'); $slug = BlogPost::generateSlug($title); // Linked anime IDs $linkedIds = []; if (!empty($data['linked_slugs'])) { $linkedIds = Anime::whereIn('slug', $data['linked_slugs'])->pluck('id')->toArray(); } $readingTime = max(3, (int) (str_word_count(strip_tags($content)) / 200)); BlogPost::create([ 'title' => $title, 'slug' => $slug, 'excerpt' => $data['excerpt'] ?? '', 'content' => $content, 'cover_image' => $anime->cover_image, 'focus_keyword' => $data['focus_keyword'] ?? $anime->title, 'meta_title' => $data['title'] ?? null, 'meta_description' => $data['meta_description'] ?? $data['excerpt'] ?? '', 'meta_keywords' => implode(', ', array_filter([ $anime->title, $anime->title . ' izle', 'türkçe anime', $data['focus_keyword'] ?? '', ])), 'status' => 'published', 'ai_generated' => true, 'anime_id' => $anime->id, 'linked_anime_ids' => $linkedIds, 'faq' => $data['faq'] ?? [], 'reading_time' => $readingTime, 'published_at' => now(), ]); $this->info(" ✓ Blog yazısı oluşturuldu: {$title}"); $generated++; // API rate limit sleep(2); } $this->info("Tamamlandı. {$generated} blog yazısı üretildi."); return self::SUCCESS; } }