66
77use CodeIgniter \CLI \BaseCommand ;
88use CodeIgniter \CLI \CLI ;
9+ use CodeIgniter \CodeIgniter ;
910use CodeIgniter \Commands \Database \Migrate ;
1011use CodeIgniter \Shield \Commands \Setup \ContentReplacer ;
12+ use CodeIgniter \Shield \Commands \Utils \InputOutput ;
13+ use CodeIgniter \Test \Filters \CITestStreamFilter ;
14+ use Config \Email as EmailConfig ;
1115use Config \Services ;
1216
1317class Setup extends BaseCommand
1418{
19+ private static ?InputOutput $ io = null ;
20+
1521 /**
1622 * The group the command is lumped under
1723 * when listing commands.
@@ -89,6 +95,7 @@ private function publishConfig(): void
8995 $ this ->setupRoutes ();
9096
9197 $ this ->setSecurityCSRF ();
98+ $ this ->setupEmail ();
9299
93100 $ this ->runMigrations ();
94101 }
@@ -166,7 +173,7 @@ protected function writeFile(string $file, string $content): void
166173
167174 if (
168175 ! $ overwrite
169- && CLI :: prompt (" File ' {$ cleanPath }' already exists in destination. Overwrite? " , ['n ' , 'y ' ]) === 'n '
176+ && $ this -> prompt (" File ' {$ cleanPath }' already exists in destination. Overwrite? " , ['n ' , 'y ' ]) === 'n '
170177 ) {
171178 CLI ::error (" Skipped {$ cleanPath }. If you wish to overwrite, please use the '-f' option or reply 'y' to the prompt. " );
172179
@@ -175,7 +182,7 @@ protected function writeFile(string $file, string $content): void
175182 }
176183
177184 if (write_file ($ path , $ content )) {
178- CLI :: write (CLI ::color (' Created: ' , 'green ' ) . $ cleanPath );
185+ $ this -> write (CLI ::color (' Created: ' , 'green ' ) . $ cleanPath );
179186 } else {
180187 CLI ::error (" Error creating {$ cleanPath }. " );
181188 }
@@ -206,7 +213,7 @@ protected function add(string $file, string $code, string $pattern, string $repl
206213 }
207214
208215 if (write_file ($ path , $ output )) {
209- CLI :: write (CLI ::color (' Updated: ' , 'green ' ) . $ cleanPath );
216+ $ this -> write (CLI ::color (' Updated: ' , 'green ' ) . $ cleanPath );
210217 } else {
211218 CLI ::error (" Error updating {$ cleanPath }. " );
212219 }
@@ -232,7 +239,7 @@ private function replace(string $file, array $replaces): bool
232239 }
233240
234241 if (write_file ($ path , $ output )) {
235- CLI :: write (CLI ::color (' Updated: ' , 'green ' ) . $ cleanPath );
242+ $ this -> write (CLI ::color (' Updated: ' , 'green ' ) . $ cleanPath );
236243
237244 return true ;
238245 }
@@ -297,13 +304,71 @@ private function setSecurityCSRF(): void
297304
298305 // check $csrfProtection = 'session'
299306 if ($ output === $ content ) {
300- CLI :: write (CLI ::color (' Security Setup: ' , 'green ' ) . 'Everything is fine. ' );
307+ $ this -> write (CLI ::color (' Security Setup: ' , 'green ' ) . 'Everything is fine. ' );
301308
302309 return ;
303310 }
304311
305312 if (write_file ($ path , $ output )) {
306- CLI ::write (CLI ::color (' Updated: ' , 'green ' ) . "We have updated file ' {$ cleanPath }' for security reasons. " );
313+ $ this ->write (CLI ::color (' Updated: ' , 'green ' ) . "We have updated file ' {$ cleanPath }' for security reasons. " );
314+ } else {
315+ CLI ::error (" Error updating file ' {$ cleanPath }'. " );
316+ }
317+ }
318+
319+ private function setupEmail (): void
320+ {
321+ $ file = 'Config/Email.php ' ;
322+
323+ $ path = $ this ->distPath . $ file ;
324+ $ cleanPath = clean_path ($ path );
325+
326+ if (! is_file ($ path )) {
327+ CLI ::error (" Not found file ' {$ cleanPath }'. " );
328+
329+ return ;
330+ }
331+
332+ $ config = new EmailConfig ();
333+ $ fromEmail = $ config ->fromEmail ;
334+ $ fromName = $ config ->fromName ;
335+
336+ if ($ fromEmail !== '' && $ fromName !== '' ) {
337+ $ this ->write (CLI ::color (' Email Setup: ' , 'green ' ) . 'Everything is fine. ' );
338+
339+ return ;
340+ }
341+
342+ $ content = file_get_contents ($ path );
343+ $ output = $ content ;
344+
345+ if ($ fromEmail === '' ) {
346+ $ set = $ this ->prompt (' The required Config\Email::$fromEmail is not set. Do you set now? ' , ['y ' , 'n ' ]);
347+
348+ if ($ set === 'y ' ) {
349+ // Input from email
350+ $ fromEmail = $ this ->prompt (' What is your email? ' , null , 'required|valid_email ' );
351+
352+ $ pattern = '/^ public .*\$fromEmail\s+= \'\';/mu ' ;
353+ $ replace = ' public string $fromEmail = \'' . $ fromEmail . '\'; ' ;
354+ $ output = preg_replace ($ pattern , $ replace , $ content );
355+ }
356+ }
357+
358+ if ($ fromName === '' ) {
359+ $ set = $ this ->prompt (' The required Config\Email::$fromName is not set. Do you set now? ' , ['y ' , 'n ' ]);
360+
361+ if ($ set === 'y ' ) {
362+ $ fromName = $ this ->prompt (' What is your name? ' , null , 'required ' );
363+
364+ $ pattern = '/^ public .*\$fromName\s+= \'\';/mu ' ;
365+ $ replace = ' public string $fromName = \'' . $ fromName . '\'; ' ;
366+ $ output = preg_replace ($ pattern , $ replace , $ output );
367+ }
368+ }
369+
370+ if (write_file ($ path , $ output )) {
371+ $ this ->write (CLI ::color (' Updated: ' , 'green ' ) . $ cleanPath );
307372 } else {
308373 CLI ::error (" Error updating file ' {$ cleanPath }'. " );
309374 }
@@ -312,20 +377,65 @@ private function setSecurityCSRF(): void
312377 private function runMigrations (): void
313378 {
314379 if (
315- $ this ->cliPrompt (' Run `spark migrate --all` now? ' , ['y ' , 'n ' ]) === 'n '
380+ $ this ->prompt (' Run `spark migrate --all` now? ' , ['y ' , 'n ' ]) === 'n '
316381 ) {
317382 return ;
318383 }
319384
320385 $ command = new Migrate (Services::logger (), Services::commands ());
386+
387+ // This is a hack for testing.
388+ // @TODO Remove CITestStreamFilter and refactor when CI 4.5.0 or later is supported.
389+ CITestStreamFilter::registration ();
390+ CITestStreamFilter::addOutputFilter ();
391+ CITestStreamFilter::addErrorFilter ();
392+
321393 $ command ->run (['all ' => null ]);
394+
395+ CITestStreamFilter::removeOutputFilter ();
396+ CITestStreamFilter::removeErrorFilter ();
397+
398+ // Capture the output, and write for testing.
399+ // @TODO Remove CITestStreamFilter and refactor when CI 4.5.0 or later is supported.
400+ $ output = CITestStreamFilter::$ buffer ;
401+ $ this ->write ($ output );
402+
403+ CITestStreamFilter::$ buffer = '' ;
404+ }
405+
406+ private function prompt (string $ field , $ options = null , $ validation = null ): string
407+ {
408+ return self ::$ io ->prompt ($ field , $ options , $ validation );
409+ }
410+
411+ private function write (
412+ string $ text = '' ,
413+ ?string $ foreground = null ,
414+ ?string $ background = null
415+ ): void {
416+ self ::$ io ->write ($ text , $ foreground , $ background );
417+ }
418+
419+ private function ensureInputOutput (): void
420+ {
421+ if (self ::$ io === null ) {
422+ self ::$ io = new InputOutput ();
423+ }
424+ }
425+
426+ /**
427+ * @internal Testing purpose only
428+ */
429+ public static function setInputOutput (InputOutput $ io ): void
430+ {
431+ self ::$ io = $ io ;
322432 }
323433
324434 /**
325- * This method is for testing.
435+ * @internal Testing purpose only
326436 */
327- protected function cliPrompt ( string $ field , array $ options ): string
437+ public static function resetInputOutput ( ): void
328438 {
329- return CLI :: prompt ( $ field , $ options ) ;
439+ self :: $ io = null ;
330440 }
331441}
0 commit comments