35
35
use Symfony \Bundle \SecurityBundle \SecurityBundle ;
36
36
use Symfony \Bundle \TwigBundle \TwigBundle ;
37
37
use Symfony \Component \Console \Command \Command ;
38
+ use Symfony \Component \Console \Input \InputArgument ;
38
39
use Symfony \Component \Console \Input \InputInterface ;
40
+ use Symfony \Component \Console \Input \InputOption ;
39
41
use Symfony \Component \HttpFoundation \Response ;
40
42
use Symfony \Component \PasswordHasher \Hasher \UserPasswordHasherInterface ;
41
43
use Symfony \Component \Routing \Attribute \Route ;
@@ -57,11 +59,10 @@ final class MakeFormLogin extends AbstractMaker
57
59
58
60
private const SECURITY_CONFIG_PATH = 'config/packages/security.yaml ' ;
59
61
private YamlSourceManipulator $ ysm ;
60
- private string $ controllerName ;
61
62
private string $ firewallToUpdate ;
62
63
private string $ userClass ;
63
64
private string $ userNameField ;
64
- private bool $ willLogout ;
65
+ private ? array $ securityData = null ;
65
66
66
67
public function __construct (
67
68
private FileManager $ fileManager ,
@@ -77,9 +78,12 @@ public static function getCommandName(): string
77
78
78
79
public function configureCommand (Command $ command , InputConfiguration $ inputConfig ): void
79
80
{
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 ' ));
81
84
82
85
$ this ->configureCommandWithTestsOption ($ command );
86
+ $ inputConfig ->setArgumentAsNonInteractive ('controllerName ' );
83
87
}
84
88
85
89
public static function getCommandDescription (): string
@@ -111,38 +115,44 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
111
115
throw new RuntimeCommandException (\sprintf ('The file "%s" does not exist. PHP & XML configuration formats are currently not supported. ' , self ::SECURITY_CONFIG_PATH ));
112
116
}
113
117
114
- $ this ->ysm = new YamlSourceManipulator ($ this ->fileManager ->getFileContents (self ::SECURITY_CONFIG_PATH ));
115
- $ securityData = $ this ->ysm ->getData ();
118
+ $ securityData = $ this ->getSecurityData ();
116
119
117
120
if (!isset ($ securityData ['security ' ]['providers ' ]) || !$ securityData ['security ' ]['providers ' ]) {
118
121
throw new RuntimeCommandException ('To generate a form login authentication, you must configure at least one entry under "providers" in "security.yaml". ' );
119
122
}
120
123
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
+ }
126
132
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
+ }
132
136
133
137
$ this ->interactSetGenerateTests ($ input , $ io );
134
138
}
135
139
136
140
public function generate (InputInterface $ input , ConsoleStyle $ io , Generator $ generator ): void
137
141
{
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
+
138
148
$ useStatements = new UseStatementGenerator ([
139
149
AbstractController::class,
140
150
Response::class,
141
151
Route::class,
142
152
AuthenticationUtils::class,
143
153
]);
144
154
145
- $ controllerNameDetails = $ generator ->createClassNameDetails ($ this -> controllerName , 'Controller \\' , 'Controller ' );
155
+ $ controllerNameDetails = $ generator ->createClassNameDetails ($ input -> getArgument ( ' controllerName ' ) , 'Controller \\' , 'Controller ' );
146
156
$ templatePath = strtolower ($ controllerNameDetails ->getRelativeNameWithoutSuffix ());
147
157
148
158
$ controllerPath = $ generator ->generateController (
@@ -155,7 +165,7 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
155
165
]
156
166
);
157
167
158
- if ($ this -> willLogout ) {
168
+ if ($ input -> getOption ( ' will-logout ' ) ) {
159
169
$ manipulator = new ClassSourceManipulator ($ generator ->getFileContentsForPendingOperation ($ controllerPath ));
160
170
161
171
$ this ->securityControllerBuilder ->addLogoutMethod ($ manipulator );
@@ -167,26 +177,26 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
167
177
\sprintf ('%s/login.html.twig ' , $ templatePath ),
168
178
'security/formLogin/login_form.tpl.php ' ,
169
179
[
170
- 'logout_setup ' => $ this -> willLogout ,
180
+ 'logout_setup ' => $ input -> getOption ( ' will-logout ' ) ,
171
181
'username_label ' => Str::asHumanWords ($ this ->userNameField ),
172
182
'username_is_email ' => false !== stripos ($ this ->userNameField , 'email ' ),
173
183
]
174
184
);
175
185
176
186
$ securityData = $ this ->securityConfigUpdater ->updateForFormLogin ($ this ->ysm ->getContents (), $ this ->firewallToUpdate , 'app_login ' , 'app_login ' );
177
187
178
- if ($ this -> willLogout ) {
188
+ if ($ input -> getOption ( ' will-logout ' ) ) {
179
189
$ securityData = $ this ->securityConfigUpdater ->updateForLogout ($ securityData , $ this ->firewallToUpdate );
180
190
}
181
191
182
- if ($ this -> shouldGenerateTests ( )) {
192
+ if ($ input -> getOption ( ' with-tests ' )) {
183
193
$ userClassNameDetails = $ generator ->createClassNameDetails (
184
194
'\\' .$ this ->userClass ,
185
195
'Entity \\'
186
196
);
187
197
188
198
$ testClassDetails = $ generator ->createClassNameDetails (
189
- ' LoginControllerTest ' ,
199
+ $ controllerNameDetails -> getShortName () . ' Test ' ,
190
200
'Test \\' ,
191
201
);
192
202
@@ -223,4 +233,14 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
223
233
\sprintf ('Next: Review and adapt the login template: <info>%s/login.html.twig</info> to suit your needs. ' , $ templatePath ),
224
234
]);
225
235
}
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
+ }
226
246
}
0 commit comments