Skip to content

Commit 78abbf4

Browse files
committed
form login : fix after review - batch 3
1 parent bc0089d commit 78abbf4

File tree

10 files changed

+114
-29
lines changed

10 files changed

+114
-29
lines changed

composer.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,8 @@
2020
"symfony/dependency-injection": "^3.4|^4.0",
2121
"symfony/filesystem": "^3.4|^4.0",
2222
"symfony/finder": "^3.4|^4.0",
23-
"symfony/form": "^3.4|^4.1",
2423
"symfony/framework-bundle": "^3.4|^4.0",
25-
"symfony/http-kernel": "^3.4|^4.0",
26-
"symfony/security": "^3.4|^4.1"
24+
"symfony/http-kernel": "^3.4|^4.0"
2725
},
2826
"require-dev": {
2927
"allocine/twigcs": "^3.0",

src/Generator.php

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Bundle\MakerBundle;
1313

14+
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1415
use Symfony\Bundle\MakerBundle\Exception\RuntimeCommandException;
1516
use Symfony\Bundle\MakerBundle\Util\ClassNameDetails;
1617

@@ -90,7 +91,7 @@ public function getFileContents(string $targetPath): string
9091
throw new RuntimeCommandException(sprintf('File "%s" is not in the Generator\'s pending operations', $targetPath));
9192
}
9293

93-
return $this->generateFileContents(
94+
return $this->getFileContentsForPendingOperation(
9495
$targetPath,
9596
$this->pendingOperations[$targetPath]
9697
);
@@ -192,14 +193,14 @@ public function writeChanges()
192193

193194
$this->fileManager->dumpFile(
194195
$targetPath,
195-
$this->generateFileContents($targetPath, $templateData)
196+
$this->getFileContentsForPendingOperation($targetPath, $templateData)
196197
);
197198
}
198199

199200
$this->pendingOperations = [];
200201
}
201202

202-
private function generateFileContents(string $targetPath, array $templateData)
203+
private function getFileContentsForPendingOperation(string $targetPath, array $templateData): string
203204
{
204205
$templatePath = $templateData['template'];
205206
$parameters = $templateData['variables'];
@@ -215,4 +216,16 @@ public function getRootNamespace(): string
215216
{
216217
return $this->namespacePrefix;
217218
}
219+
220+
public function generateController(string $controllerClassName, string $controllerTemplatePath, array $parameters = []): string
221+
{
222+
return $this->generateClass(
223+
$controllerClassName,
224+
$controllerTemplatePath,
225+
$parameters +
226+
[
227+
'parent_class_name' => \method_exists(AbstractController::class, 'getParameter') ? 'AbstractController' : 'Controller',
228+
]
229+
);
230+
}
218231
}

src/Maker/MakeAuthenticator.php

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111

1212
namespace Symfony\Bundle\MakerBundle\Maker;
1313

14-
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1514
use Symfony\Bundle\MakerBundle\ConsoleStyle;
1615
use Symfony\Bundle\MakerBundle\DependencyBuilder;
1716
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
@@ -33,7 +32,9 @@
3332
use Symfony\Component\Console\Input\InputInterface;
3433
use Symfony\Component\Console\Input\InputOption;
3534
use Symfony\Component\Console\Question\Question;
35+
use Symfony\Component\HttpKernel\Kernel;
3636
use Symfony\Component\Yaml\Yaml;
37+
use Symfony\Component\Form\Form;
3738

3839
/**
3940
* @author Ryan Weaver <[email protected]>
@@ -101,10 +102,19 @@ public function interact(InputInterface $input, ConsoleStyle $io, Command $comma
101102
$dependencies = new DependencyBuilder();
102103
$dependencies->addClassDependency(
103104
TwigBundle::class,
104-
'tiwg'
105+
'twig'
105106
);
107+
$missingPackagesMessage = 'Twig must be installed to display login form';
106108

107-
$missingPackagesMessage = $dependencies->getMissingPackagesMessage(self::getCommandName(), 'Twig must be installed to display login form');
109+
if (Kernel::VERSION_ID < 40100) {
110+
$dependencies->addClassDependency(
111+
Form::class,
112+
'symfony/form'
113+
);
114+
$missingPackagesMessage = 'Twig and symfony/form must be installed to display login form';
115+
}
116+
117+
$missingPackagesMessage = $dependencies->getMissingPackagesMessage(self::getCommandName(), $missingPackagesMessage);
108118
if ($missingPackagesMessage) {
109119
throw new RuntimeCommandException($missingPackagesMessage);
110120
}
@@ -237,7 +247,7 @@ private function generateAuthenticatorClass(InputInterface $input)
237247
'user_class_name' => $userClassNameDetails->getShortName(),
238248
'username_field' => $input->getArgument('username-field'),
239249
'user_needs_encoder' => $userNeedsEncoder,
240-
'user_is_entity' => $this->doctrineHelper->isClassAMappedEntity($input->getArgument('user-class'))
250+
'user_is_entity' => $this->doctrineHelper->isClassAMappedEntity($input->getArgument('user-class')),
241251
]
242252
);
243253
}
@@ -252,12 +262,9 @@ private function generateFormLoginFiles(InputInterface $input)
252262
);
253263

254264
if (!class_exists($controllerClassNameDetails->getFullName())) {
255-
$controllerPath = $this->generator->generateClass(
265+
$controllerPath = $this->generator->generateController(
256266
$controllerClassNameDetails->getFullName(),
257-
'authenticator/EmptySecurityController.tpl.php',
258-
[
259-
'parent_class_name' => \method_exists(AbstractController::class, 'getParameter') ? 'AbstractController' : 'Controller',
260-
]
267+
'authenticator/EmptySecurityController.tpl.php'
261268
);
262269

263270
$controllerSourceCode = $this->generator->getFileContents($controllerPath);
@@ -282,7 +289,7 @@ private function generateFormLoginFiles(InputInterface $input)
282289
'templates/security/login.html.twig',
283290
'authenticator/login_form.tpl.php',
284291
[
285-
'username_field' => $input->getArgument('username-field')
292+
'username_field' => $input->getArgument('username-field'),
286293
]
287294
);
288295
}

src/Maker/MakeController.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
namespace Symfony\Bundle\MakerBundle\Maker;
1313

1414
use Doctrine\Common\Annotations\Annotation;
15-
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1615
use Symfony\Bundle\MakerBundle\ConsoleStyle;
1716
use Symfony\Bundle\MakerBundle\DependencyBuilder;
1817
use Symfony\Bundle\MakerBundle\Generator;
@@ -52,11 +51,10 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
5251
);
5352

5453
$templateName = Str::asFilePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()).'/index.html.twig';
55-
$controllerPath = $generator->generateClass(
54+
$controllerPath = $generator->generateController(
5655
$controllerClassNameDetails->getFullName(),
5756
'controller/Controller.tpl.php',
5857
[
59-
'parent_class_name' => \method_exists(AbstractController::class, 'getParameter') ? 'AbstractController' : 'Controller',
6058
'route_path' => Str::asRoutePath($controllerClassNameDetails->getRelativeNameWithoutSuffix()),
6159
'route_name' => Str::asRouteName($controllerClassNameDetails->getRelativeNameWithoutSuffix()),
6260
'twig_installed' => $this->isTwigInstalled(),

src/Maker/MakeCrud.php

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
use Doctrine\Bundle\DoctrineBundle\DoctrineBundle;
1515
use Doctrine\Common\Inflector\Inflector;
1616
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
17-
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
1817
use Symfony\Bundle\MakerBundle\ConsoleStyle;
1918
use Symfony\Bundle\MakerBundle\DependencyBuilder;
2019
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
@@ -128,11 +127,10 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
128127

129128
$routeName = Str::asRouteName($controllerClassDetails->getRelativeNameWithoutSuffix());
130129

131-
$generator->generateClass(
130+
$generator->generateController(
132131
$controllerClassDetails->getFullName(),
133132
'crud/controller/Controller.tpl.php',
134133
array_merge([
135-
'parent_class_name' => \method_exists(AbstractController::class, 'getParameter') ? 'AbstractController' : 'Controller',
136134
'entity_full_class_name' => $entityClassDetails->getFullName(),
137135
'entity_class_name' => $entityClassDetails->getShortName(),
138136
'form_full_class_name' => $formClassDetails->getFullName(),

src/Resources/help/MakeAuth.txt

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
1-
The <info>%command.name%</info> command generates an empty
2-
Guard Authenticator class.
1+
The <info>%command.name%</info> command generates various authentication systems,
2+
by asking questions.
3+
4+
It can provide an empty authenticator, or a full login form authentication process.
5+
In both cases it also updates your <info>security.yaml</info>.
6+
For the login form, it also generates a controller and the twig template.
37

48
<info>php %command.full_name%</info>

src/Resources/skeleton/authenticator/login_form.tpl.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
</div>
3030
#}
3131

32-
<button class="btn btn-lg btn-primary btn-block" type="submit">
32+
<button class="btn btn-lg btn-primary" type="submit">
3333
Sign in
3434
</button>
3535
</form>

src/Security/InteractiveSecurityHelper.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ public function guessUserNameField(SymfonyStyle $io, string $userClass, array $p
133133
return $io->choice(
134134
sprintf('Which field on your <fg=yellow>%s</> class will people enter when logging in?', $userClass),
135135
$classProperties,
136-
property_exists($userClass, 'username') ? 'username' : property_exists($userClass, 'email') ? 'email' : null
136+
property_exists($userClass, 'username') ? 'username' : (property_exists($userClass, 'email') ? 'email' : null)
137137
);
138138
}
139139
}

tests/Maker/FunctionalTest.php

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -405,6 +405,7 @@ function (string $output, string $directory) {
405405
)
406406
->addExtraDependencies('doctrine')
407407
->addExtraDependencies('twig')
408+
->addExtraDependencies('symfony/form')
408409
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeAuthenticatorLoginFormUserEntity')
409410
->configureDatabase()
410411
->updateSchemaAfterCommand()
@@ -436,11 +437,10 @@ function (string $output, string $directory) {
436437
0
437438
]
438439
)
439-
->addExtraDependencies('doctrine')
440+
->addExtraDependencies('doctrine/annotations')
440441
->addExtraDependencies('twig')
442+
->addExtraDependencies('symfony/form')
441443
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeAuthenticatorLoginFormCustomUsernameField')
442-
->configureDatabase()
443-
->updateSchemaAfterCommand(),
444444
];
445445

446446
yield 'auth_login_form_user_entity_no_encoder' => [
@@ -457,6 +457,7 @@ function (string $output, string $directory) {
457457
)
458458
->addExtraDependencies('doctrine')
459459
->addExtraDependencies('twig')
460+
->addExtraDependencies('symfony/form')
460461
->setFixtureFilesPath(__DIR__.'/../fixtures/MakeAuthenticatorLoginFormUserEntityNoEncoder')
461462
->configureDatabase()
462463
->updateSchemaAfterCommand(),

tests/Security/InteractiveSecurityHelperTest.php

Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,4 +159,70 @@ public function getUserClassTests()
159159
false,
160160
];
161161
}
162+
163+
/**
164+
* @dataProvider getUsernameFieldsTest
165+
*/
166+
public function testGuessUserNameField(array $providers, string $expectedUsernameField, bool $fieldAutomaticallyGuessed, string $class = '', array $choices = [])
167+
{
168+
/** @var SymfonyStyle|\PHPUnit_Framework_MockObject_MockObject $io */
169+
$io = $this->createMock(SymfonyStyle::class);
170+
$io->expects($this->exactly(true === $fieldAutomaticallyGuessed ? 0 : 1))
171+
->method('choice')
172+
->with(sprintf('Which field on your <fg=yellow>%s</> class will people enter when logging in?', $class), $choices, 'username')
173+
->willReturn($expectedUsernameField);
174+
175+
$interactiveSecurityHelper = new InteractiveSecurityHelper();
176+
$this->assertEquals(
177+
$expectedUsernameField,
178+
$interactiveSecurityHelper->guessUserNameField($io, $class, $providers)
179+
);
180+
}
181+
182+
public function getUsernameFieldsTest()
183+
{
184+
yield 'guess_with_providers' => [
185+
'providers' => ['app_provider' => ['entity' => ['property' => 'userEmail']]],
186+
'expectedUsernameField' => 'userEmail',
187+
true
188+
];
189+
190+
yield 'guess_fixture_class' => [
191+
'providers' => [],
192+
'expectedUsernameField' => 'email',
193+
true,
194+
FixtureClass::class
195+
];
196+
197+
yield 'guess_fixture_class_2' => [
198+
'providers' => [],
199+
'expectedUsernameField' => 'username',
200+
true,
201+
FixtureClass2::class
202+
];
203+
204+
yield 'guess_fixture_class_3' => [
205+
'providers' => [],
206+
'expectedUsernameField' => 'username',
207+
false,
208+
FixtureClass3::class,
209+
['username', 'email']
210+
];
211+
}
212+
}
213+
214+
class FixtureClass
215+
{
216+
private $email;
217+
}
218+
219+
class FixtureClass2
220+
{
221+
private $username;
222+
}
223+
224+
class FixtureClass3
225+
{
226+
private $username;
227+
private $email;
162228
}

0 commit comments

Comments
 (0)