3535use Symfony \Bundle \SecurityBundle \SecurityBundle ;
3636use Symfony \Bundle \TwigBundle \TwigBundle ;
3737use Symfony \Component \Console \Command \Command ;
38+ use Symfony \Component \Console \Input \InputArgument ;
3839use Symfony \Component \Console \Input \InputInterface ;
40+ use Symfony \Component \Console \Input \InputOption ;
3941use Symfony \Component \HttpFoundation \Response ;
4042use Symfony \Component \PasswordHasher \Hasher \UserPasswordHasherInterface ;
4143use Symfony \Component \Routing \Attribute \Route ;
@@ -57,11 +59,10 @@ final class MakeFormLogin extends AbstractMaker
5759
5860 private const SECURITY_CONFIG_PATH = 'config/packages/security.yaml ' ;
5961 private YamlSourceManipulator $ ysm ;
60- private string $ controllerName ;
6162 private string $ firewallToUpdate ;
6263 private string $ userClass ;
6364 private string $ userNameField ;
64- private bool $ willLogout ;
65+ private ? array $ securityData = null ;
6566
6667 public function __construct (
6768 private FileManager $ fileManager ,
@@ -77,9 +78,12 @@ public static function getCommandName(): string
7778
7879 public function configureCommand (Command $ command , InputConfiguration $ inputConfig ): void
7980 {
80- $ command ->setHelp (file_get_contents (\dirname (__DIR__ , 2 ).'/Resources/help/security/MakeFormLogin.txt ' ));
81+ $ command ->addArgument ('controllerName ' , InputArgument::OPTIONAL , 'The class name of the Controller (e.g. <fg=yellow>SecurityController</>) ' )
82+ ->addOption ('will-logout ' , null , InputOption::VALUE_NONE , 'Will generate a \'/logout \' URL? ' )
83+ ->setHelp (file_get_contents (\dirname (__DIR__ , 2 ).'/Resources/help/security/MakeFormLogin.txt ' ));
8184
8285 $ this ->configureCommandWithTestsOption ($ command );
86+ $ inputConfig ->setArgumentAsNonInteractive ('controllerName ' );
8387 }
8488
8589 public static function getCommandDescription (): string
@@ -111,38 +115,44 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
111115 throw new RuntimeCommandException (\sprintf ('The file "%s" does not exist. PHP & XML configuration formats are currently not supported. ' , self ::SECURITY_CONFIG_PATH ));
112116 }
113117
114- $ this ->ysm = new YamlSourceManipulator ($ this ->fileManager ->getFileContents (self ::SECURITY_CONFIG_PATH ));
115- $ securityData = $ this ->ysm ->getData ();
118+ $ securityData = $ this ->getSecurityData ();
116119
117120 if (!isset ($ securityData ['security ' ]['providers ' ]) || !$ securityData ['security ' ]['providers ' ]) {
118121 throw new RuntimeCommandException ('To generate a form login authentication, you must configure at least one entry under "providers" in "security.yaml". ' );
119122 }
120123
121- $ this ->controllerName = $ io ->ask (
122- 'Choose a name for the controller class (e.g. <fg=yellow>SecurityController</>) ' ,
123- 'SecurityController ' ,
124- Validator::validateClassName (...)
125- );
124+ if (null === $ input ->getArgument ('controllerName ' )) {
125+ $ input ->setArgument (
126+ 'controllerName ' , $ input ->getArgument ('controllerName ' ) ?? $ io ->ask (
127+ 'Choose a name for the controller class (e.g. <fg=yellow>SecurityController</>) ' ,
128+ 'SecurityController ' ,
129+ Validator::validateClassName (...)
130+ ));
131+ }
126132
127- $ securityHelper = new InteractiveSecurityHelper ();
128- $ this ->firewallToUpdate = $ securityHelper ->guessFirewallName ($ io , $ securityData );
129- $ this ->userClass = $ securityHelper ->guessUserClass ($ io , $ securityData ['security ' ]['providers ' ]);
130- $ this ->userNameField = $ securityHelper ->guessUserNameField ($ io , $ this ->userClass , $ securityData ['security ' ]['providers ' ]);
131- $ this ->willLogout = $ io ->confirm ('Do you want to generate a \'/logout \' URL? ' );
133+ if (false === $ input ->getOption ('will-logout ' )) {
134+ $ input ->setOption ('will-logout ' ,$ io ->confirm ('Do you want to generate a \'/logout \' URL? ' ));
135+ }
132136
133137 $ this ->interactSetGenerateTests ($ input , $ io );
134138 }
135139
136140 public function generate (InputInterface $ input , ConsoleStyle $ io , Generator $ generator ): void
137141 {
142+ $ securityData = $ this ->getSecurityData ();
143+ $ securityHelper = new InteractiveSecurityHelper ();
144+ $ this ->firewallToUpdate = $ securityHelper ->guessFirewallName ($ io , $ securityData );
145+ $ this ->userClass = $ securityHelper ->guessUserClass ($ io , $ securityData ['security ' ]['providers ' ]);
146+ $ this ->userNameField = $ securityHelper ->guessUserNameField ($ io , $ this ->userClass , $ securityData ['security ' ]['providers ' ]);
147+
138148 $ useStatements = new UseStatementGenerator ([
139149 AbstractController::class,
140150 Response::class,
141151 Route::class,
142152 AuthenticationUtils::class,
143153 ]);
144154
145- $ controllerNameDetails = $ generator ->createClassNameDetails ($ this -> controllerName , 'Controller \\' , 'Controller ' );
155+ $ controllerNameDetails = $ generator ->createClassNameDetails ($ input -> getArgument ( ' controllerName ' ) , 'Controller \\' , 'Controller ' );
146156 $ templatePath = strtolower ($ controllerNameDetails ->getRelativeNameWithoutSuffix ());
147157
148158 $ controllerPath = $ generator ->generateController (
@@ -155,7 +165,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
155165 ]
156166 );
157167
158- if ($ this -> willLogout ) {
168+ if ($ input -> getOption ( ' will-logout ' ) ) {
159169 $ manipulator = new ClassSourceManipulator ($ generator ->getFileContentsForPendingOperation ($ controllerPath ));
160170
161171 $ this ->securityControllerBuilder ->addLogoutMethod ($ manipulator );
@@ -167,26 +177,26 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
167177 \sprintf ('%s/login.html.twig ' , $ templatePath ),
168178 'security/formLogin/login_form.tpl.php ' ,
169179 [
170- 'logout_setup ' => $ this -> willLogout ,
180+ 'logout_setup ' => $ input -> getOption ( ' will-logout ' ) ,
171181 'username_label ' => Str::asHumanWords ($ this ->userNameField ),
172182 'username_is_email ' => false !== stripos ($ this ->userNameField , 'email ' ),
173183 ]
174184 );
175185
176186 $ securityData = $ this ->securityConfigUpdater ->updateForFormLogin ($ this ->ysm ->getContents (), $ this ->firewallToUpdate , 'app_login ' , 'app_login ' );
177187
178- if ($ this -> willLogout ) {
188+ if ($ input -> getOption ( ' will-logout ' ) ) {
179189 $ securityData = $ this ->securityConfigUpdater ->updateForLogout ($ securityData , $ this ->firewallToUpdate );
180190 }
181191
182- if ($ this -> shouldGenerateTests ( )) {
192+ if ($ input -> getOption ( ' with-tests ' )) {
183193 $ userClassNameDetails = $ generator ->createClassNameDetails (
184194 '\\' .$ this ->userClass ,
185195 'Entity \\'
186196 );
187197
188198 $ testClassDetails = $ generator ->createClassNameDetails (
189- ' LoginControllerTest ' ,
199+ $ controllerNameDetails -> getShortName () . ' Test ' ,
190200 'Test \\' ,
191201 );
192202
@@ -223,4 +233,14 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
223233 \sprintf ('Next: Review and adapt the login template: <info>%s/login.html.twig</info> to suit your needs. ' , $ templatePath ),
224234 ]);
225235 }
236+
237+ private function getSecurityData (): array
238+ {
239+ if (null === $ this ->securityData )
240+ {
241+ $ this ->ysm = new YamlSourceManipulator ($ this ->fileManager ->getFileContents (self ::SECURITY_CONFIG_PATH ));
242+ $ this ->securityData = $ this ->ysm ->getData ();
243+ }
244+ return $ this ->securityData ;
245+ }
226246}
0 commit comments