Files
RomhackPlaza/app/Console/Commands/MigrateUsersPlan.php
2026-06-23 19:24:38 +02:00

144 lines
5.0 KiB
PHP

<?php
namespace App\Console\Commands;
use App\Models\MigrationUserPlan;
use Illuminate\Console\Attributes\Description;
use Illuminate\Console\Attributes\Signature;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
#[Signature('migrate:users:plan {--fresh}')]
#[Description('Construct migration plan for WP/XF accounts.')]
class MigrateUsersPlan extends Command
{
public function handle()
{
if( $this->option('fresh') ) {
MigrationUserPlan::truncate();
}
$this->info("Loading old XF accounts...");
$xfUsers = DB::connection('old_xf')->table('user')
->select('user_id','username','email')
->get()
->keyBy('user_id')
;
$xfUsersByEmail = $xfUsers->groupBy(fn($u) => strtolower($u->email));
$this->info("Loading old WP accounts...");
$wpUsers = DB::connection('old_wp')->table('users')
->leftJoin('usermeta', function ($join) {
$join->on('users.ID', '=', 'usermeta.user_id')->where('usermeta.meta_key', '=', 'xf_user_id');
})
->select('users.ID as wp_id', 'users.user_email as email', 'users.user_login as username', 'usermeta.meta_value as linked_xf_id')
->get();
$linkedXfIds = [];
$this->withProgressBar( $wpUsers, function ($wp) use ($xfUsers, $xfUsersByEmail, &$linkedXfIds) {
$email = strtolower($wp->email);
$linkedId = $wp->linked_xf_id ? (int) $wp->linked_xf_id : null;
if( $linkedId && $xfUsers->has($linkedId) ) {
$xf = $xfUsers->get($linkedId);
$matchType = strtolower($xf->email) === $email ? 'explicit' : 'conflict';
MigrationUserPlan::updateOrCreate(
['wp_user_id' => $wp->wp_id],
[
'xf_user_id' => $linkedId,
'match_type' => $matchType,
'email' => $email,
'wp_username' => $wp->username,
'xf_username' => $xf->username,
'note' => $matchType === 'conflict' ? "E-Mail différent: {$xf->email}" : null,
'status' => $matchType === 'explicit' ? 'approved' : 'pending',
]
);
$linkedXfIds[$linkedId] = true;
return;
}
if( $linkedId && !$xfUsers->has($linkedId) ) {
MigrationUserPlan::updateOrCreate(
['wp_user_id' => $wp->wp_id ],
[
'match_type' => 'conflict',
'email' => $email,
'wp_username' => $wp->username,
'note' => "xf_user_id={$linkedId} introuvable",
'status' => 'approved'
]);
return;
}
$candidates = $xfUsersByEmail->get($email,collect());
if( $candidates->count() === 1 ){
$xf = $candidates->first();
MigrationUserPlan::updateOrCreate(
['wp_user_id' => $wp->wp_id],
[
'xf_user_id' => $xf->user_id,
'match_type' => 'email',
'email' => $email,
'wp_username' => $wp->username,
'xf_username' => $xf->username,
'status' => 'pending'
]
);
$linkedXfIds[$xf->user_id] = true;
return;
}
if( $candidates->count() > 1 ){
MigrationUserPlan::updateOrCreate(
['wp_user_id' => $wp->wp_id ],
[
'match_type' => 'conflict',
'email' => $email,
'wp_username' => $wp->username,
'note' => "E-mail identique sur plusieurs comptes XF.",
]
);
return;
}
MigrationUserPlan::updateOrCreate(
['wp_user_id' => $wp->wp_id ],
[
'match_type' => 'wp_only',
'email' => $email,
'wp_username' => $wp->username,
'status' => 'approved'
]
);
});
$this->info("Listing old XF accounts...");
foreach( $xfUsers as $id => $xf ) {
if( isset($linkedXfIds[$id]) ) {
continue;
}
MigrationUserPlan::updateOrCreate(
['xf_user_id' => $xf->user_id, 'wp_user_id' => null],
[
'match_type' => 'xf_only',
'email' => strtolower($xf->email),
'xf_username' => $xf->username,
'status' => 'approved'
]
);
}
$pending = MigrationUserPlan::where('status', 'pending')->count();
$this->newLine(2);
$this->info("Plan generated. {$pending} pending cases.");
}
}