update controllers logic
This commit is contained in:
@@ -0,0 +1,264 @@
|
||||
#!/usr/bin/env php
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Regenerate tools/ci-controller-to-laravel-mapping.csv by comparing
|
||||
* CodeIgniter app/Controllers with Laravel app/Http/Controllers.
|
||||
*
|
||||
* Usage:
|
||||
* php tools/generate-ci-controller-mapping.php
|
||||
* php tools/generate-ci-controller-mapping.php --ci-path=/path/to/app_codeigniter/app/Controllers
|
||||
* php tools/generate-ci-controller-mapping.php --output=/path/to/out.csv
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
$laravelRoot = dirname(__DIR__);
|
||||
$defaultCiRoot = dirname($laravelRoot) . DIRECTORY_SEPARATOR . 'app_codeigniter' . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'Controllers';
|
||||
$defaultOutput = $laravelRoot . DIRECTORY_SEPARATOR . 'tools' . DIRECTORY_SEPARATOR . 'ci-controller-to-laravel-mapping.csv';
|
||||
|
||||
$options = getopt('', ['ci-path:', 'output:', 'help']);
|
||||
if (isset($options['help'])) {
|
||||
fwrite(STDOUT, <<<TXT
|
||||
Generate CI → Laravel controller mapping CSV.
|
||||
|
||||
Options:
|
||||
--ci-path=PATH CodeIgniter Controllers directory (default: sibling app_codeigniter/.../Controllers)
|
||||
--output=PATH Output CSV path (default: tools/ci-controller-to-laravel-mapping.csv)
|
||||
--help Show this message
|
||||
|
||||
TXT);
|
||||
exit(0);
|
||||
}
|
||||
|
||||
$ciRoot = isset($options['ci-path']) ? $options['ci-path'] : $defaultCiRoot;
|
||||
$outputPath = isset($options['output']) ? $options['output'] : $defaultOutput;
|
||||
|
||||
if (! is_dir($ciRoot)) {
|
||||
fwrite(STDERR, "CI controllers directory not found: {$ciRoot}\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$lvControllersDir = $laravelRoot . DIRECTORY_SEPARATOR . 'app' . DIRECTORY_SEPARATOR . 'Http' . DIRECTORY_SEPARATOR . 'Controllers';
|
||||
if (! is_dir($lvControllersDir)) {
|
||||
fwrite(STDERR, "Laravel controllers directory not found: {$lvControllersDir}\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/** @var array<string, array{paths: string[], notes: string}> */
|
||||
$explicit = [
|
||||
'AdminProgressController' => ['paths' => ['Api/ClassProgress/ClassProgressController.php'], 'notes' => ''],
|
||||
'ParentProgressController' => ['paths' => ['Api/ClassProgress/ClassProgressController.php'], 'notes' => ''],
|
||||
'ParentReportCardController' => ['paths' => ['Api/Reports/ReportCardsController.php'], 'notes' => ''],
|
||||
'ApiDocsController' => ['paths' => ['Api/Documentation/ApiDocsAdminController.php'], 'notes' => ''],
|
||||
'DocsController' => [
|
||||
'paths' => ['Api/Documentation/DocsCatalogController.php', 'Api/Documentation/ApiDocsAdminController.php'],
|
||||
'notes' => 'Two CI files (root + View); docs split between catalog + admin',
|
||||
],
|
||||
'ConfigurationController' => ['paths' => ['Api/Settings/ConfigurationAdminController.php'], 'notes' => ''],
|
||||
'ClassPrepController' => ['paths' => ['Api/ClassPreparation/ClassPreparationController.php'], 'notes' => ''],
|
||||
'BadgesController' => ['paths' => ['Api/Badges/BadgeController.php'], 'notes' => ''],
|
||||
'NotificationsController' => ['paths' => ['Api/Notifications/NotificationController.php'], 'notes' => ''],
|
||||
'FlagController' => ['paths' => ['Api/Incidents/IncidentController.php'], 'notes' => ''],
|
||||
'SendSMSController' => ['paths' => ['Api/Messaging/MessagesController.php'], 'notes' => ''],
|
||||
'TestDBController' => [
|
||||
'paths' => ['Api/System/DatabaseHealthController.php', 'Api/System/HealthController.php'],
|
||||
'notes' => '',
|
||||
],
|
||||
'ErrorController' => ['paths' => ['Api/System/AccessDeniedController.php'], 'notes' => ''],
|
||||
'ScorePredictor' => ['paths' => ['Api/Scores/ScorePredictorController.php'], 'notes' => ''],
|
||||
'CompetitionWinnersController' => ['paths' => ['Api/Public/PublicWinnersController.php'], 'notes' => ''],
|
||||
'WinnersController' => ['paths' => ['Api/Public/PublicWinnersController.php'], 'notes' => ''],
|
||||
'AssignmentController' => ['paths' => ['Api/Assignment/AssignmentApiController.php'], 'notes' => ''],
|
||||
'Home' => ['paths' => [], 'notes' => 'CI welcome_message only; Laravel SPA + API'],
|
||||
'BaseController' => ['paths' => [], 'notes' => 'CI framework base'],
|
||||
'PrintablesBaseController' => ['paths' => [], 'notes' => 'Abstract printable base (CI)'],
|
||||
'InitializeRolesPermissions' => ['paths' => [], 'notes' => 'Use Laravel seeds/Artisan; not an HTTP controller'],
|
||||
'PrintRequests' => [
|
||||
'paths' => ['Api/PrintRequests/PrintRequestsController.php'],
|
||||
'notes' => 'HTTP JSON API + PrintRequestsPortalService',
|
||||
],
|
||||
'RFIDController' => [
|
||||
'paths' => [
|
||||
'Api/BadgeScan/BadgeScanController.php',
|
||||
'Api/Students/StudentController.php',
|
||||
],
|
||||
'notes' => 'Scan + logs: BadgeScanController; assign student badge: StudentController.updateBadgeScan',
|
||||
],
|
||||
'AdministratorController' => [
|
||||
'paths' => [
|
||||
'Api/Administrator/AdministratorAbsenceController.php',
|
||||
'Api/Administrator/AdministratorDashboardController.php',
|
||||
'Api/Administrator/AdministratorEnrollmentController.php',
|
||||
'Api/Administrator/AdministratorNotificationController.php',
|
||||
'Api/Administrator/AdministratorTeacherSubmissionController.php',
|
||||
'Api/Administrator/EmergencyContactController.php',
|
||||
'Api/Administrator/TeacherClassAssignmentController.php',
|
||||
],
|
||||
'notes' => 'Large CI controller split across Laravel admin APIs',
|
||||
],
|
||||
'AttendanceController' => [
|
||||
'paths' => [
|
||||
'Api/Attendance/AdminAttendanceApiController.php',
|
||||
'Api/Attendance/StaffAttendanceApiController.php',
|
||||
'Api/Attendance/TeacherAttendanceApiController.php',
|
||||
],
|
||||
'notes' => 'Attendance UI split by role in Laravel API',
|
||||
],
|
||||
];
|
||||
|
||||
/** @return array<string, string[]> basename => list of relative paths under Http/Controllers */
|
||||
function indexLaravelControllers(string $controllersDir): array
|
||||
{
|
||||
$map = [];
|
||||
$iterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($controllersDir, FilesystemIterator::SKIP_DOTS)
|
||||
);
|
||||
$prefixLen = strlen($controllersDir) + 1;
|
||||
|
||||
foreach ($iterator as $fileInfo) {
|
||||
/** @var SplFileInfo $fileInfo */
|
||||
if (! $fileInfo->isFile() || strcasecmp($fileInfo->getExtension(), 'php') !== 0) {
|
||||
continue;
|
||||
}
|
||||
if ($fileInfo->getFilename() === 'Controller.php') {
|
||||
continue;
|
||||
}
|
||||
$full = $fileInfo->getPathname();
|
||||
$rel = str_replace('\\', '/', substr($full, $prefixLen));
|
||||
$base = $fileInfo->getBasename('.php');
|
||||
if (! isset($map[$base])) {
|
||||
$map[$base] = [];
|
||||
}
|
||||
$map[$base][] = $rel;
|
||||
}
|
||||
|
||||
return $map;
|
||||
}
|
||||
|
||||
/** @param string[] $paths */
|
||||
function joinRepoPaths(array $paths): string
|
||||
{
|
||||
$prefixed = array_map(
|
||||
static fn (string $p): string => 'app/Http/Controllers/'.$p,
|
||||
array_filter($paths)
|
||||
);
|
||||
|
||||
return implode('|', $prefixed);
|
||||
}
|
||||
|
||||
function resolvePaths(string $basename, array $explicit, array $lvFiles): array
|
||||
{
|
||||
if (isset($explicit[$basename])) {
|
||||
return $explicit[$basename];
|
||||
}
|
||||
if (isset($lvFiles[$basename])) {
|
||||
return ['paths' => $lvFiles[$basename], 'notes' => ''];
|
||||
}
|
||||
|
||||
return ['paths' => [], 'notes' => 'NOT FOUND IN Laravel app/Http/Controllers'];
|
||||
}
|
||||
|
||||
function migrationStatus(string $basename, array $resolved, array $explicit, array $lvFiles): string
|
||||
{
|
||||
if (isset($explicit[$basename])) {
|
||||
$e = $explicit[$basename];
|
||||
if ($basename === 'AdministratorController') {
|
||||
return 'mapped_split';
|
||||
}
|
||||
if ($basename === 'AttendanceController') {
|
||||
return 'mapped_split';
|
||||
}
|
||||
if ($basename === 'RFIDController') {
|
||||
return 'mapped_split';
|
||||
}
|
||||
if ($basename === 'Home') {
|
||||
return 'stub_replaced';
|
||||
}
|
||||
if (in_array($basename, ['BaseController', 'PrintablesBaseController'], true)) {
|
||||
return 'framework_base';
|
||||
}
|
||||
if ($basename === 'InitializeRolesPermissions') {
|
||||
return 'setup_script';
|
||||
}
|
||||
if ($e['paths'] === []) {
|
||||
return 'no_laravel_controller';
|
||||
}
|
||||
if ($basename === 'DocsController') {
|
||||
return 'mapped_renamed';
|
||||
}
|
||||
$renamed = [
|
||||
'AdminProgressController', 'ParentProgressController', 'ParentReportCardController', 'ApiDocsController',
|
||||
'ConfigurationController', 'ClassPrepController', 'BadgesController', 'NotificationsController',
|
||||
'FlagController', 'SendSMSController', 'TestDBController', 'ErrorController', 'ScorePredictor',
|
||||
'CompetitionWinnersController', 'WinnersController', 'AssignmentController', 'PrintRequests',
|
||||
];
|
||||
if (in_array($basename, $renamed, true)) {
|
||||
return 'mapped_renamed';
|
||||
}
|
||||
|
||||
return 'mapped_explicit';
|
||||
}
|
||||
|
||||
if (isset($lvFiles[$basename])) {
|
||||
return count($lvFiles[$basename]) > 1 ? 'ambiguous_duplicate_in_laravel' : 'mapped_exact';
|
||||
}
|
||||
|
||||
return 'unmapped';
|
||||
}
|
||||
|
||||
$lvFiles = indexLaravelControllers($lvControllersDir);
|
||||
|
||||
$ciFiles = [];
|
||||
$ciIterator = new RecursiveIteratorIterator(
|
||||
new RecursiveDirectoryIterator($ciRoot, FilesystemIterator::SKIP_DOTS)
|
||||
);
|
||||
$ciPrefixLen = strlen($ciRoot) + 1;
|
||||
|
||||
foreach ($ciIterator as $fileInfo) {
|
||||
if (! $fileInfo->isFile() || strcasecmp($fileInfo->getExtension(), 'php') !== 0) {
|
||||
continue;
|
||||
}
|
||||
$full = $fileInfo->getPathname();
|
||||
$rel = str_replace('\\', '/', substr($full, $ciPrefixLen));
|
||||
$ciFiles[$full] = $rel;
|
||||
}
|
||||
ksort($ciFiles);
|
||||
|
||||
$rows = [];
|
||||
foreach ($ciFiles as $full => $relPath) {
|
||||
$basename = basename($full, '.php');
|
||||
$resolved = resolvePaths($basename, $explicit, $lvFiles);
|
||||
$pathStr = joinRepoPaths($resolved['paths']);
|
||||
$notes = $resolved['notes'];
|
||||
$status = migrationStatus($basename, $resolved, $explicit, $lvFiles);
|
||||
|
||||
if ($status === 'unmapped') {
|
||||
$pathStr = '';
|
||||
if ($notes === '') {
|
||||
$notes = 'NOT FOUND IN Laravel app/Http/Controllers';
|
||||
}
|
||||
}
|
||||
|
||||
$rows[] = [$relPath, $basename, $pathStr, $status, $notes];
|
||||
}
|
||||
|
||||
$dir = dirname($outputPath);
|
||||
if (! is_dir($dir)) {
|
||||
mkdir($dir, 0775, true);
|
||||
}
|
||||
|
||||
$fh = fopen($outputPath, 'wb');
|
||||
if ($fh === false) {
|
||||
fwrite(STDERR, "Cannot write: {$outputPath}\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
$headers = ['ci_relative_path', 'ci_basename', 'laravel_controller_paths_from_repo_root', 'migration_status', 'notes'];
|
||||
fputcsv($fh, $headers);
|
||||
foreach ($rows as $row) {
|
||||
fputcsv($fh, $row);
|
||||
}
|
||||
fclose($fh);
|
||||
|
||||
fwrite(STDOUT, "Wrote ".count($rows)." rows to {$outputPath}\n");
|
||||
Reference in New Issue
Block a user