Skip to content

Commit 8385d29

Browse files
committed
feature #333 New Command! make:registration-form (weaverryan)
This PR was squashed before being merged into the 1.0-dev branch (closes #333). Discussion ---------- New Command! make:registration-form New command time! `make:registration-form`. It: * Generates a completely functional controller, template & form class for registration * Is capable of detecting or asking for the exact fields you need (e.g. email & password) * When using Guard, you can generate code to automatically authenticate after registration. This is one of the last steps to getting an entire authentication system in minutes without needing FOSUserBundle (`make:user`, `make:auth`, `make:registration-form`). Feedback warmly welcomed. Cheers! ### Example of generated code: <details><summary>RegistrationFormType</summary> <p> ```php <?php namespace App\Form; use App\Entity\User; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\Extension\Core\Type\PasswordType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsResolver; use Symfony\Component\Validator\Constraints\NotBlank; use Symfony\Component\Validator\Constraints\Length; class RegistrationFormType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options) { $builder ->add('email') ->add('plainPassword', PasswordType::class, [ // instead of being set onto the object directly, // this is read and encoded in the controller 'mapped' => false, 'constraints' => [ new NotBlank([ 'message' => 'Please enter a password', ]), new Length([ 'min' => 6, 'minMessage' => 'Your password should be at least {{ limit }} characters', ]), ], ]) ; } public function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'data_class' => User::class, ]); } } ``` </p> </details> <details><summary>RegistrationController</summary> <p> ```php namespace App\Controller; use App\Entity\User; use App\Form\RegistrationFormType; use App\Security\StubAuthenticator; use Symfony\Bundle\FrameworkBundle\Controller\AbstractController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\HttpFoundation\Response; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface; use Symfony\Component\Security\Guard\GuardAuthenticatorHandler; class RegistrationController extends AbstractController { /** * @route("/register", name="app_register") */ public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, StubAuthenticator $authenticator): Response { $form = $this->createForm(RegistrationFormType::class); $form->handleRequest($request); if ($form->isSubmitted() && $form->isValid()) { /** @var User */ $user = $form->getData(); // encode the plain password $user->setPassword( $passwordEncoder->encodePassword( $user, $form->get('plainPassword')->getData() ) ); $entityManager = $this->getDoctrine()->getManager(); $entityManager->persist($user); $entityManager->flush(); // do anything else you need here, like send an email return $guardHandler->authenticateUserAndHandleSuccess( $user, $request, $authenticator, 'main' // firewall name in security.yaml ); } return $this->render('registration/register.html.twig', [ 'registrationForm' => $form->createView(), ]); } } ``` </p> </details> <details><summary>registration/register.html.twig</summary> <p> ```twig {% extends 'base.html.twig' %} {% block title %}Register{% endblock %} {% block body %} <h1>Register</h1> {{ form_start(registrationForm) }} {{ form_row(registrationForm.email) }} {{ form_row(registrationForm.plainPassword) }} <button class="btn">Register</button> {{ form_end(registrationForm) }} {% endblock %} ``` </p> </details> Commits ------- f3f4901 making test 3.4-compat 8f46cc2 Asking to add UniqueEntity during make:registration-form a018245 Adding plainPassword validation and a few other things 16d3b9b Making the make:registration-form work without authenticating 14ade82 Adding the initial version of make:registration-form 🎉 b7699a1 Refactoring form rendering into a service
2 parents c0ead73 + f3f4901 commit 8385d29

File tree

27 files changed

+1233
-31
lines changed

27 files changed

+1233
-31
lines changed

src/Doctrine/EntityDetails.php

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ public function getFormFields()
6868
}
6969
}
7070

71-
return $fields;
71+
$fieldsWithTypes = [];
72+
foreach ($fields as $field) {
73+
$fieldsWithTypes[$field] = null;
74+
}
75+
76+
return $fieldsWithTypes;
7277
}
7378
}

src/Maker/MakeCrud.php

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
2020
use Symfony\Bundle\MakerBundle\Generator;
2121
use Symfony\Bundle\MakerBundle\InputConfiguration;
22+
use Symfony\Bundle\MakerBundle\Renderer\FormTypeRenderer;
2223
use Symfony\Bundle\MakerBundle\Str;
2324
use Symfony\Bundle\MakerBundle\Validator;
2425
use Symfony\Bundle\TwigBundle\TwigBundle;
@@ -38,9 +39,12 @@ final class MakeCrud extends AbstractMaker
3839
{
3940
private $doctrineHelper;
4041

41-
public function __construct(DoctrineHelper $doctrineHelper)
42+
private $formTypeRenderer;
43+
44+
public function __construct(DoctrineHelper $doctrineHelper, FormTypeRenderer $formTypeRenderer)
4245
{
4346
$this->doctrineHelper = $doctrineHelper;
47+
$this->formTypeRenderer = $formTypeRenderer;
4448
}
4549

4650
public static function getCommandName(): string
@@ -149,14 +153,10 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
149153
)
150154
);
151155

152-
$generator->generateClass(
153-
$formClassDetails->getFullName(),
154-
'form/Type.tpl.php',
155-
[
156-
'bounded_full_class_name' => $entityClassDetails->getFullName(),
157-
'bounded_class_name' => $entityClassDetails->getShortName(),
158-
'form_fields' => $entityDoctrineDetails->getFormFields(),
159-
]
156+
$this->formTypeRenderer->render(
157+
$formClassDetails,
158+
$entityDoctrineDetails->getFormFields(),
159+
$entityClassDetails
160160
);
161161

162162
$templates = [

src/Maker/MakeEntity.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
use Symfony\Bundle\MakerBundle\Str;
2727
use Symfony\Bundle\MakerBundle\Doctrine\EntityRegenerator;
2828
use Symfony\Bundle\MakerBundle\FileManager;
29+
use Symfony\Bundle\MakerBundle\Util\ClassDetails;
2930
use Symfony\Bundle\MakerBundle\Util\ClassSourceManipulator;
3031
use Symfony\Bundle\MakerBundle\Doctrine\EntityRelation;
3132
use Symfony\Bundle\MakerBundle\Validator;
@@ -774,7 +775,9 @@ private function createClassManipulator(string $path, ConsoleStyle $io, bool $ov
774775

775776
private function getPathOfClass(string $class): string
776777
{
777-
return (new \ReflectionClass($class))->getFileName();
778+
$classDetails = new ClassDetails($class);
779+
780+
return $classDetails->getPath();
778781
}
779782

780783
private function isClassInVendor(string $class): bool

src/Maker/MakeForm.php

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use Symfony\Bundle\MakerBundle\Doctrine\DoctrineHelper;
1818
use Symfony\Bundle\MakerBundle\Generator;
1919
use Symfony\Bundle\MakerBundle\InputConfiguration;
20+
use Symfony\Bundle\MakerBundle\Renderer\FormTypeRenderer;
2021
use Symfony\Bundle\MakerBundle\Str;
2122
use Symfony\Bundle\MakerBundle\Util\ClassDetails;
2223
use Symfony\Bundle\MakerBundle\Validator;
@@ -34,10 +35,12 @@
3435
final class MakeForm extends AbstractMaker
3536
{
3637
private $entityHelper;
38+
private $formTypeRenderer;
3739

38-
public function __construct(DoctrineHelper $entityHelper)
40+
public function __construct(DoctrineHelper $entityHelper, FormTypeRenderer $formTypeRenderer)
3941
{
4042
$this->entityHelper = $entityHelper;
43+
$this->formTypeRenderer = $formTypeRenderer;
4144
}
4245

4346
public static function getCommandName(): string
@@ -81,10 +84,10 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
8184
'Type'
8285
);
8386

84-
$formFields = ['field_name'];
85-
$boundClassVars = [];
87+
$formFields = ['field_name' => null];
8688

8789
$boundClass = $input->getArgument('bound-class');
90+
$boundClassDetails = null;
8891

8992
if (null !== $boundClass) {
9093
$boundClassDetails = $generator->createClassNameDetails(
@@ -100,17 +103,12 @@ public function generate(InputInterface $input, ConsoleStyle $io, Generator $gen
100103
$classDetails = new ClassDetails($boundClassDetails->getFullName());
101104
$formFields = $classDetails->getFormFields();
102105
}
103-
104-
$boundClassVars = [
105-
'bounded_full_class_name' => $boundClassDetails->getFullName(),
106-
'bounded_class_name' => $boundClassDetails->getShortName(),
107-
];
108106
}
109107

110-
$generator->generateClass(
111-
$formClassNameDetails->getFullName(),
112-
'form/Type.tpl.php',
113-
array_merge(['form_fields' => $formFields], $boundClassVars)
108+
$this->formTypeRenderer->render(
109+
$formClassNameDetails,
110+
$formFields,
111+
$boundClassDetails
114112
);
115113

116114
$generator->writeChanges();

0 commit comments

Comments
 (0)