info('Starting cleanup of Cyclos migration trailing pipes in cyclos_skills...'); $this->newLine(); $totalCleaned = 0; // Clean Users $usersCleaned = $this->cleanProfileSkills(User::class, 'Users'); $totalCleaned += $usersCleaned; // Clean Organizations $organizationsCleaned = $this->cleanProfileSkills(Organization::class, 'Organizations'); $totalCleaned += $organizationsCleaned; // Clean Banks $banksCleaned = $this->cleanProfileSkills(Bank::class, 'Banks'); $totalCleaned += $banksCleaned; // Note: Admins table does not have cyclos_skills column $this->newLine(); $this->info("Cleanup complete! Total profiles cleaned: {$totalCleaned}"); return Command::SUCCESS; } /** * Clean the cyclos_skills field for a specific model type. * * @param string $modelClass * @param string $displayName * @return int */ private function cleanProfileSkills(string $modelClass, string $displayName): int { // Find all profiles where cyclos_skills field contains trailing pipes and spaces $profiles = $modelClass::whereNotNull('cyclos_skills') ->where('cyclos_skills', 'like', '%|%') ->get(); $cleanedCount = 0; if ($profiles->isEmpty()) { $this->line("✓ {$displayName}: No profiles to clean"); return 0; } $bar = $this->output->createProgressBar($profiles->count()); $bar->setFormat(" {$displayName}: [%bar%] %current%/%max% (%percent:3s%%)"); foreach ($profiles as $profile) { $original = $profile->cyclos_skills; // Remove trailing pipes and spaces using regex // This matches: space, pipe, space, pipe... at the end of the string $cleaned = preg_replace('/(\s*\|\s*)+$/', '', $original); // Only update if something changed if ($cleaned !== $original) { $profile->cyclos_skills = $cleaned; $profile->save(); $cleanedCount++; } $bar->advance(); } $bar->finish(); $this->newLine(); return $cleanedCount; } }