172 lines
5.1 KiB
PHP
172 lines
5.1 KiB
PHP
<?php
|
|
|
|
namespace App\Console\Commands;
|
|
|
|
use App\Enums\IsActive;
|
|
use App\Enums\NotifStyle;
|
|
use App\Enums\RoleEnum;
|
|
use App\Models\User;
|
|
use Illuminate\Console\Command;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Str;
|
|
|
|
class MigrateUserCommand extends Command
|
|
{
|
|
/**
|
|
* The name and signature of the console command.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $signature = 'migrate:user';
|
|
|
|
/**
|
|
* The console command description.
|
|
*
|
|
* @var string
|
|
*/
|
|
protected $description = 'Migrate users from legacy database with optimized processing and detailed output';
|
|
|
|
/**
|
|
* Cache for existing user IDs and emails to prevent redundant queries.
|
|
*/
|
|
private array $existingUserIds = [];
|
|
|
|
private array $existingUserEmails = [];
|
|
|
|
/**
|
|
* Execute the console command.
|
|
*/
|
|
public function handle()
|
|
{
|
|
$this->info('Starting optimized user migration...');
|
|
|
|
$legacyConn = DB::connection('mysql_second');
|
|
$query = $legacyConn->table('users')->whereNull('deleted_at');
|
|
|
|
$totalCount = $query->count();
|
|
if ($totalCount === 0) {
|
|
$this->warn('No users found in legacy database.');
|
|
|
|
return;
|
|
}
|
|
|
|
$this->info("Found {$totalCount} legacy user records.");
|
|
|
|
// Pre-cache existing data to speed up individual checks
|
|
$this->existingUserIds = User::pluck('id')->flip()->all();
|
|
$this->existingUserEmails = User::pluck('email')->flip()->all();
|
|
|
|
$query->orderBy('id')->chunk(50, function ($chunk) {
|
|
foreach ($chunk as $legacy) {
|
|
$this->processUser($legacy);
|
|
}
|
|
});
|
|
|
|
$this->newLine();
|
|
$this->info('User migration completed successfully!');
|
|
}
|
|
|
|
/**
|
|
* Process a single legacy user record.
|
|
*/
|
|
private function processUser($legacy): void
|
|
{
|
|
$this->output->write("<info>[#{$legacy->id}]</info> Processing: <comment>".Str::limit($legacy->name, 40).'</comment>... ');
|
|
|
|
// Check for duplicates by ID or Email
|
|
if (isset($this->existingUserIds[$legacy->id]) || isset($this->existingUserEmails[$legacy->email])) {
|
|
$this->output->writeln('<info>SKIP (Already Exists)</info>');
|
|
|
|
return;
|
|
}
|
|
|
|
try {
|
|
$username = $this->generateUniqueUsername($legacy->name, $legacy->email);
|
|
|
|
$id = DB::table('users')->insertGetId([
|
|
'id' => $legacy->id,
|
|
'name' => Str::limit($legacy->name, 100),
|
|
'email' => $legacy->email,
|
|
'username' => $username,
|
|
'password' => $legacy->password,
|
|
'is_active' => $legacy->status == '2'
|
|
? IsActive::INACTIVE->value
|
|
: IsActive::ACTIVE->value,
|
|
'email_verified_at' => now(),
|
|
'created_at' => $legacy->created_at ?? now(),
|
|
'updated_at' => $legacy->updated_at ?? now(),
|
|
]);
|
|
|
|
$user = User::find($id);
|
|
|
|
if ($user) {
|
|
// Assign Role
|
|
$roleName = $this->mapRole($legacy->role);
|
|
if ($roleName) {
|
|
$user->syncRoles([$roleName]);
|
|
}
|
|
|
|
// Initialize User Settings if missing
|
|
if (! $user->settings()->exists()) {
|
|
$user->settings()->create([
|
|
'notif_style' => NotifStyle::FORMAL,
|
|
'primary_color' => 'blue',
|
|
'font' => 'Inter',
|
|
'content_width' => 'full',
|
|
'border_radius' => 'lg',
|
|
'top_navigation' => false,
|
|
]);
|
|
}
|
|
|
|
$this->output->writeln('<info>DONE</info>');
|
|
} else {
|
|
$this->output->writeln('<error>FAILED TO RETRIEVE</error>');
|
|
}
|
|
} catch (\Exception $e) {
|
|
$this->output->writeln('<error>FAILED: '.$e->getMessage().'</error>');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate a unique username based on name or email.
|
|
*/
|
|
private function generateUniqueUsername($name, $email): string
|
|
{
|
|
$base = Str::limit(Str::slug($name, ''), 10, '');
|
|
if (empty($base)) {
|
|
$base = Str::limit(explode('@', $email)[0], 10, '');
|
|
}
|
|
|
|
$username = $base;
|
|
$counter = 1;
|
|
|
|
while (User::where('username', $username)->exists()) {
|
|
$suffix = (string) $counter;
|
|
$maxBaseLength = 10 - strlen($suffix);
|
|
$username = substr($base, 0, $maxBaseLength).$suffix;
|
|
$counter++;
|
|
|
|
if ($counter > 999) {
|
|
break;
|
|
}
|
|
}
|
|
|
|
return $username;
|
|
}
|
|
|
|
/**
|
|
* Map legacy role IDs to RoleEnum.
|
|
*/
|
|
private function mapRole($legacyRole): ?string
|
|
{
|
|
return match ((int) $legacyRole) {
|
|
1 => RoleEnum::ADMINISTRATOR->value,
|
|
2 => RoleEnum::ADMIN_MONITORING->value,
|
|
3 => RoleEnum::PERUSAHAAN->value,
|
|
4 => RoleEnum::ADMIN_KONTEN->value,
|
|
5 => RoleEnum::ADMIN_KEUANGAN->value,
|
|
default => null,
|
|
};
|
|
}
|
|
}
|