@@ -111,9 +111,12 @@ class Control
111111 case 'reset ' :
112112 $ this ->resetMigrations ();
113113 break ;
114+ case 'docker ' :
115+ $ this ->runDockerMigrations ();
116+ break ;
114117 default :
115118 $ this ->error ("Unknown migrate command: {$ subCommand }" );
116- $ this ->info ("Available migrate commands: run, fresh, rollback, status, reset " );
119+ $ this ->info ("Available migrate commands: run, fresh, rollback, status, reset, docker " );
117120 }
118121 }
119122
@@ -398,6 +401,72 @@ class Control
398401 }
399402 }
400403
404+ private function runDockerMigrations ()
405+ {
406+ $ this ->info ("Running database migrations for Docker environment... " );
407+
408+ $ migrationFiles = $ this ->getMigrationFiles ();
409+ $ executedMigrations = $ this ->getExecutedMigrations ();
410+
411+ if (empty ($ migrationFiles )) {
412+ $ this ->warning ("No migration files found. " );
413+ return ;
414+ }
415+
416+ $ batch = $ this ->getNextBatchNumber ();
417+ $ executed = 0 ;
418+
419+ foreach ($ migrationFiles as $ file ) {
420+ $ migrationName = basename ($ file , '.php ' );
421+
422+ if (in_array ($ migrationName , $ executedMigrations )) {
423+ continue ; // Skip already executed migrations
424+ }
425+
426+ try {
427+ require_once $ file ;
428+
429+ // Get class name from file name
430+ $ className = $ this ->getClassNameFromFile ($ migrationName );
431+
432+ if (!class_exists ($ className )) {
433+ $ this ->error ("Migration class {$ className } not found in {$ file }" );
434+ continue ;
435+ }
436+
437+ $ migration = new $ className ($ this ->database );
438+
439+ $ this ->info ("Migrating: {$ migrationName }" );
440+ $ migration ->up ();
441+
442+ // Record migration
443+ $ this ->database ->insert ('migrations ' , [
444+ 'migration ' => $ migrationName ,
445+ 'batch ' => $ batch
446+ ]);
447+
448+ $ this ->success ("Migrated: {$ migrationName }" );
449+ $ executed ++;
450+
451+ } catch (Exception $ e ) {
452+ $ this ->error ("Migration failed for {$ migrationName }: " . $ e ->getMessage ());
453+ break ;
454+ }
455+ }
456+
457+ if ($ executed > 0 ) {
458+ $ this ->success ("Executed {$ executed } migrations successfully! " );
459+
460+ // Create admin user from environment variables for Docker
461+ $ this ->createDockerAdminUser ();
462+ } else {
463+ $ this ->info ("Nothing to migrate. " );
464+
465+ // Still try to create admin user if it doesn't exist
466+ $ this ->createDockerAdminUser ();
467+ }
468+ }
469+
401470 private function freshMigrations ()
402471 {
403472 $ this ->info ("Running fresh migrations (dropping all tables)... " );
@@ -695,6 +764,71 @@ class {$className} extends Migration
695764 }
696765 }
697766
767+ private function createDockerAdminUser ()
768+ {
769+ try {
770+ // Check if any admin user already exists
771+ $ existingAdmin = $ this ->database ->get ('users ' , '* ' , ['role ' => 'superadmin ' ]);
772+
773+ if ($ existingAdmin ) {
774+ $ this ->info ("Admin user already exists: " . $ existingAdmin ['email ' ]);
775+ return ;
776+ }
777+
778+ // Get admin credentials from environment variables
779+ $ adminEmail = $ _ENV ['ADMIN_EMAIL ' ] ?? null ;
780+ $ adminPassword = $ _ENV ['ADMIN_PASSWORD ' ] ?? null ;
781+ $ adminName = $ _ENV ['ADMIN_NAME ' ] ?? 'Admin ' ;
782+
783+ if (!$ adminEmail || !$ adminPassword ) {
784+ $ this ->error ("ADMIN_EMAIL and ADMIN_PASSWORD environment variables are required for Docker setup. " );
785+ $ this ->info ("Please set these in your .env file: " );
786+ $ this ->info ("ADMIN_EMAIL=admin@example.com " );
787+ $ this ->info ("ADMIN_PASSWORD=your_secure_password " );
788+ return ;
789+ }
790+
791+ // Validate email format
792+ if (!filter_var ($ adminEmail , FILTER_VALIDATE_EMAIL )) {
793+ $ this ->error ("Invalid email format in ADMIN_EMAIL environment variable: {$ adminEmail }" );
794+ return ;
795+ }
796+
797+ // Check if user with this email already exists
798+ $ existingUser = $ this ->database ->get ('users ' , '* ' , ['email ' => $ adminEmail ]);
799+ if ($ existingUser ) {
800+ $ this ->info ("User with email ' {$ adminEmail }' already exists. " );
801+ return ;
802+ }
803+
804+ // Validate password length
805+ if (strlen ($ adminPassword ) < 8 ) {
806+ $ this ->error ("ADMIN_PASSWORD must be at least 8 characters long. " );
807+ return ;
808+ }
809+
810+ // Create admin user from environment variables
811+ $ this ->info ("Creating admin user from environment variables... " );
812+
813+ $ hashedPassword = password_hash ($ adminPassword , PASSWORD_DEFAULT );
814+ $ this ->database ->insert ('users ' , [
815+ 'name ' => $ adminName ,
816+ 'email ' => $ adminEmail ,
817+ 'password ' => $ hashedPassword ,
818+ 'role ' => 'superadmin ' ,
819+ 'created_at ' => date ('Y-m-d H:i:s ' ),
820+ 'updated_at ' => date ('Y-m-d H:i:s ' )
821+ ]);
822+
823+ $ this ->success ("Admin user created successfully! " );
824+ $ this ->info ("Email: {$ adminEmail }" );
825+ $ this ->info ("Role: superadmin " );
826+
827+ } catch (Exception $ e ) {
828+ $ this ->error ("Failed to create admin user: " . $ e ->getMessage ());
829+ }
830+ }
831+
698832 private function listUsers ()
699833 {
700834 try {
@@ -996,6 +1130,7 @@ class {$className} extends Migration
9961130 $ this ->info (" migrate rollback [steps] Rollback migrations (default: 1 batch) " );
9971131 $ this ->info (" migrate status Show migration status " );
9981132 $ this ->info (" migrate reset Reset database (fresh + seed) " );
1133+ $ this ->info (" migrate docker Run migrations for Docker environment " );
9991134 $ this ->info ("" );
10001135 $ this ->info ("Make commands: " );
10011136 $ this ->info (" make migration <name> Create a new migration file " );
0 commit comments