170 lines
6.1 KiB
PHP
170 lines
6.1 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Models\Platform;
|
|
use Illuminate\Console\Attributes\Description;
|
|
use Illuminate\Console\Attributes\Signature;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
#[Signature('migrate:games:execute')]
|
|
#[Description("Migrate all games from WP posts.")]
|
|
class MigrateGamesExecute extends Command
|
|
{
|
|
private const array WP_CPTS = [ 'translations', 'romhacks', 'homebrew', 'utilities', 'documents', 'lua-scripts' ];
|
|
private const array RELATED_TAXS = ['game', 'platform', 'genre'];
|
|
private const int DEFAULT_GENRE_ID = 1;
|
|
private const int NO_GENRE_SENTINEL = 0;
|
|
|
|
public function handle()
|
|
{
|
|
$rows = DB::connection('old_wp')
|
|
->table('term_relationships as tr')
|
|
->join('term_taxonomy as tt', 'tr.term_taxonomy_id', '=', 'tt.term_taxonomy_id')
|
|
->join('posts as p', 'tr.object_id', '=', 'p.ID')
|
|
->whereIn('tt.taxonomy', self::RELATED_TAXS )
|
|
->whereIn('p.post_type', self::WP_CPTS )
|
|
->where('p.post_status', '!=', 'trash')
|
|
->select('p.ID as post_id', 'tt.taxonomy', 'tt.term_taxonomy_id' )
|
|
->get();
|
|
|
|
$byPost = [];
|
|
$ignored = 0;
|
|
foreach( $rows as $row ){
|
|
if( isset( $byPost[ $row->post_id ][$row->taxonomy] ) ){
|
|
$ignored++;
|
|
continue;
|
|
}
|
|
$byPost[ $row->post_id ][$row->taxonomy] = $row->term_taxonomy_id;
|
|
}
|
|
if( $ignored ){
|
|
$this->warn("$ignored posts with multiple taxs will be ignored.");
|
|
}
|
|
|
|
$structure = [];
|
|
$ignoredNoPlatform = 0;
|
|
|
|
foreach ( $byPost as $data )
|
|
{
|
|
if( empty( $data['game'] ) )
|
|
continue;
|
|
|
|
if( empty( $data['platform'] ) ){
|
|
$ignoredNoPlatform++;
|
|
continue;
|
|
}
|
|
|
|
$gameId = $data['game'];
|
|
$platformId = $data['platform'];
|
|
$genreId = $data['genre'] ?? self::NO_GENRE_SENTINEL;
|
|
|
|
$structure[$gameId][$platformId]['count'] = ( $structure[$gameId][$platformId]['count'] ?? 0 ) + 1;
|
|
$structure[$gameId][$platformId]['genres'][$genreId] = ( $structure[$gameId][$platformId]['genres'][$genreId] ?? 0 ) + 1;
|
|
}
|
|
if( $ignoredNoPlatform ){
|
|
$this->warn("$ignoredNoPlatform posts with no platforms will be ignored.");
|
|
}
|
|
|
|
$games = DB::connection('old_wp')
|
|
->table('term_taxonomy')
|
|
->join('terms', 'term_taxonomy.term_id', '=', 'terms.term_id')
|
|
->where('term_taxonomy.taxonomy', 'game' )
|
|
->select('term_taxonomy.term_taxonomy_id', 'terms.name', 'terms.slug' )
|
|
->get()
|
|
->keyBy('term_taxonomy_id');
|
|
|
|
$platformMap = DB::table('migrations_logs')
|
|
->where('source_system', 'wp' )
|
|
->where('target_table', 'platforms')
|
|
->pluck('target_id', 'source_id');
|
|
|
|
$genreMap = DB::table('migrations_logs')
|
|
->where('source_system', 'wp' )
|
|
->where('target_table', 'genres')
|
|
->pluck('target_id', 'source_id');
|
|
|
|
if( $this->ask("Are you sure you want launch that migration? Write ok if you want to launch it.", "") !== 'ok' ){
|
|
return self::SUCCESS;
|
|
}
|
|
|
|
$created = 0;
|
|
$genreConflicts = 0;
|
|
|
|
foreach( $structure as $gameId => $platforms )
|
|
{
|
|
$game = $games->get( $gameId );
|
|
if( !$game )
|
|
continue;
|
|
|
|
foreach( $platforms as $platformId => $info )
|
|
{
|
|
$alreadyExists = DB::table('migration_game_plan')
|
|
->where('wp_game_id', $gameId )
|
|
->where('wp_platform_id', $platformId )
|
|
->exists();
|
|
if( $alreadyExists )
|
|
continue;
|
|
|
|
$newPlatformId = $platformMap[$platformId] ?? null;
|
|
if( !$newPlatformId ){
|
|
$this->warn("$gameId ignored because platform $platformId does not exist in Laravel.");
|
|
continue;
|
|
}
|
|
|
|
$genres = $info['genres'];
|
|
$newGenreId = null;
|
|
$topId = null;
|
|
$genreConflict = false;
|
|
|
|
arsort( $genres );
|
|
$topId = array_key_first( $genres );
|
|
$topCount = $genres[$topId];
|
|
$tied = count(array_filter(
|
|
$genres, fn( $c ) => $c === $topCount
|
|
));
|
|
if( $tied > 1 ){
|
|
$genreConflict = true;
|
|
$genreConflicts++;
|
|
}
|
|
$newGenreId = $topId === self::NO_GENRE_SENTINEL
|
|
? self::DEFAULT_GENRE_ID
|
|
: ($genreMap[$topId] ?? self::DEFAULT_GENRE_ID);
|
|
|
|
$gameSlug = $game->slug;
|
|
if (count($platforms) > 1) {
|
|
$platformSlug = DB::table('platforms')->where('id', $newPlatformId)->value('slug');
|
|
$gameSlug = $game->slug . '-' . $platformSlug;
|
|
}
|
|
|
|
$newGameId = DB::table('games')
|
|
->insertGetId([
|
|
'name' => $game->name,
|
|
'slug' => $gameSlug,
|
|
'platform_id' => $newPlatformId,
|
|
'genre_id' => $newGenreId,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
DB::table('migration_game_plan')->insert([
|
|
'wp_game_id' => $gameId,
|
|
'wp_platform_id' => $platformId,
|
|
'game_id' => $newGameId,
|
|
'wp_genre_id' => $topId === self::NO_GENRE_SENTINEL ? null : $topId,
|
|
'post_count' => $info['count'],
|
|
'genre_conflict' => $genreConflict,
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
|
|
$created++;
|
|
|
|
}
|
|
}
|
|
|
|
$this->newLine();
|
|
$this->info("$created games created. $genreConflicts genre conflicts.");
|
|
}
|
|
}
|