'draft', 'pending' => 'pending', 'publish' => 'published', 'private' => 'hidden', 'locked' => 'locked', ]; private array $stats = []; private function uniqueSlug(string $baseSlug, string $table, ?int $ignoreId = null): string { $slug = $baseSlug; $i = 1; while ( DB::table($table)->where('slug', $slug) ->when($ignoreId, fn ($q) => $q->where('id', '!=', $ignoreId)) ->exists() && $i < 100 ) { $slug = $baseSlug . '-' . $i++; } if ($i >= 100) { $slug = (string) Str::uuid(); } return $slug; } private function migrateNews($post): void { $exists = DB::table('migrations_logs') ->where('source_system', 'wp') ->where('source_table', 'wp_posts__news') ->where('source_id', $post->ID) ->exists(); if ($exists) return; $meta = DB::connection('old_wp') ->table('postmeta') ->where('post_id', $post->ID) ->whereIn('meta_key', ['release_site', 'romhacks_page', 'youtube_video' ]) ->pluck('meta_value', 'meta_key'); $categoryTtId = DB::connection('old_wp') ->table('term_relationships as tr') ->join('term_taxonomy as tt', 'tr.term_taxonomy_id', '=', 'tt.term_taxonomy_id') ->where('tr.object_id', $post->ID) ->where('tt.taxonomy', 'news-category') ->value('tt.term_taxonomy_id'); $categoryId = null; if( $categoryTtId ){ $categoryId = DB::table('migrations_logs') ->where('source_system', 'wp') ->where('target_table', 'categories' ) ->where('source_id', $categoryTtId) ->value('target_id'); if( !$categoryId ){ $this->stats['missing_category']++; } } $userId = DB::table('migration_user_plan') ->where('wp_user_id', $post->post_author ) ->value('user_id'); if( !$userId ){ $this->stats['missing_author']++; return; } $slug = $this->uniqueSlug(rawurldecode($post->post_name), 'news'); $description = trim($post->post_content) === '' ? '' : MigrationHelpers::htmlToMarkdown($post->post_content); if( isset( $meta['romhacks_page'] ) && $meta['romhacks_page'] !== null && $meta['romhacks_page'] !== '' ){ $description .= "\n\nLink to: " . $meta['romhacks_page']; } $newsId = DB::table('news') ->insertGetId([ 'title' => $post->post_title, 'slug' => $slug, 'category_id' => $categoryId, 'description' => $description, 'state' => self::STATE_MAP[$post->post_status], 'entry_id' => null, 'relevant_link' => $meta['release_site'] ?? null, 'youtube_link' => $meta['youtube_video'] ?? null, 'user_id' => $userId, 'created_at' => $post->post_date, 'updated_at' => $post->post_modified, ]); DB::table('migrations_logs')->insert([ 'source_system' => 'wp', 'source_table' => 'wp_posts__news', 'source_id' => $post->ID, 'target_table' => 'news', 'target_id' => $newsId, 'status' => 'done', 'migrated_at' => now(), 'created_at' => now(), 'updated_at' => now(), ]); $this->stats['created']++; } public function handle() { $this->stats = [ 'created' => 0, 'missing_author' => 0, 'missing_category' => 0 ]; $query = DB::connection('old_wp') ->table('posts') ->where('post_type', 'news') ->whereIn('post_status', array_keys(self::STATE_MAP)) ; if( $limit = $this->option('limit') ) { $query->limit((int)$limit); } $posts = $query->select('ID', 'post_title', 'post_name', 'post_content', 'post_author', 'post_status', 'post_date', 'post_modified')->get(); $this->info( "{$posts->count()} posts found" ); $this->withProgressBar($posts, fn($post) => $this->migrateNews($post) ); $this->newLine(); $this->info( "Created {$this->stats['created']} posts. Missing authors: {$this->stats['missing_author']}. Missing category: {$this->stats['missing_category']}" ); return self::SUCCESS; } }