-
-
Notifications
You must be signed in to change notification settings - Fork 416
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Command! make:registration-form #333
Conversation
tests/fixtures/MakeRegistrationFormNoGuessing/src/Security/AuthenticatorFirst.php
Outdated
Show resolved
Hide resolved
tests/fixtures/MakeRegistrationFormNoGuessing/src/Security/AuthenticatorSecond.php
Outdated
Show resolved
Hide resolved
a5141f0
to
f3f4901
Compare
This should be ready to go! Added example generated output in the PR description. |
final class MakeRegistrationForm extends AbstractMaker | ||
{ | ||
private $fileManager; | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are the empty line breaks part of the CS guidelines?
{ | ||
$this->email = $email; | ||
|
||
return $this; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Shall we discourage the fluent interfaces for entities, especially as they seem unused in the rest of the code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's true that we don't use the fluent interface ourselves. However, adding it means that end-users can choose between using it as a fluent interface or not.
If we remove this fluent interface, we remove that flexibility entirely.
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
Hello. I'm a bit late. Why doing that: $form = $this->createForm(RegistrationFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
/** @var User */
$user = $form->getData(); Instead of: $user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) { The last one is IMHO simpler to understand and less magical. Everything is explicit, and there are no need for this PHP Doc |
Another question: why do you put the password transformation logic in the controller and not in a form listener ? Another question: Why do you authenticate the user? This si considered as a bad practice (the email is not yet validated) This could be let as an example, but commented with an explanation Finally, in your example, the |
I think your idea is indeed more clear. I'll open a pull request.
Form listeners are way too complex - I think doing a few things in the controller is easy and clear.
We ask the user whether or not they want this - so they can choose what they want :)
It is - but that's only because I messed up when copying (and simplifying) the code. It's all used correctly in your real app - if you choose to authenticate, you choose which authenticator, then we use that to authenticate the user |
Thanks for your feedback 👍 |
…licit (weaverryan) This PR was merged into the 1.0-dev branch. Discussion ---------- Fixing phpcs and making the registration controller more explicit Fixes #339 and #333 (comment) Commits ------- 4e4fe06 Fixing phpcs and making the registration controller more explicit
New command time!
make:registration-form
. It: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:
RegistrationFormType
RegistrationController
registration/register.html.twig