Il RegistrationController
Il Controller autogenerato da Symfony contiene diversi elementi che non abbiamo ancora introdotto, merita quindi un approfondimento.
I servizi
Partiamo dalla signature del metodo:
public function register(Request $request, UserPasswordEncoderInterface $passwordEncoder, GuardAuthenticatorHandler $guardHandler, LoginFormAuthenticator $authenticator): Response
Grazie alla Dependency Injection (DI) e al concetto di autowiring possiamo passare i servizi di cui un controller necessita direttamente come parametri. Questo avviene sicuramente per la Request che è comunissimo utilizzare all'interno di un controller ma può avvenire anche per tutti gli altri servizi. Introdurremo la DI subito dopo la registrazione, per approfondimento rimando alla sezione apposita.
La action register()
, oltre la Request, necessita di altri tre servizi per funzionare correttamente:
Campo | Descrizione |
---|---|
UserPasswordEncoderInterface |
Un servizio che consente di encodare la password dell'utente. Viene passata un'interfaccia anziché una classe concreta perché Symfony è in grado di determinare il servizio più indicato per quell'interfaccia. |
GuardAuthenticatorHandler |
Il servizio che consente, tra le altre cose, di effettuare un login da codice. |
LoginFormAuthenticator |
Autenthicator, creato in precedenza, che viene utilizzato dal GuardAuthenticator per loggare l'utente. |
Il form
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
//...
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
]);
La form introdotta in precedenza viene gestita all'interno del controller con il codice in alto. In sostanza viene istanziata associandogli l'entità su cui verrà mappata, nel nostro caso lo User.
Gli viene passato l'oggetto Request
da cui sarà in grado di capire se è stato già fatto il submit e quali sono gli eventuali valori inseriti dall'utente, nonché di applicare le validazioni necessarie e determinare se il form è valida o no.
Qualora il form sia valido la variabile $user
conterrà già i valori inseriti dall'utente sul form grazie all'associazione avvenuta in fase di creazione del form.
L'EntityManager di Doctrine
Lo abbiamo visto in opera nella scorsa lezione, l'EM di Doctrine consente di salvare sul database l'entità definita.
$entityManager = $this->getDoctrine()->getManager();
$entityManager->persist($user);
$entityManager->flush();
Il Guard Authenticator
Arrivati a questo punto possiamo effettuare il login automatico dell'utente (impostazione scelta in fase di setup) grazie al GuardAuthenticatorHandler
:
return $guardHandler->authenticateUserAndHandleSuccess(
$user,
$request,
$authenticator,
'main' // firewall name in security.yaml
);
I parametri sono abbastanza auto-esplicativi, l'ultimo indica il nome del firewall definito nel security.yaml
per l'authenticator.
La vista
Ora che abbiamo una registrazione funzionante possiamo dedicarci allo stile in modo da adattare la pagina al layout disponibile. Possiamo prendere spunto dalla pagina di login aggiungendo la sola checkbox di approvazione dei termini.
{{ form_start(registrationForm) }}
{{ form_row(registrationForm.email) }}
{{ form_row(registrationForm.plainPassword, {
label: 'Password'
}) }}
{{ form_row(registrationForm.agreeTerms) }}
<button type="submit" class="btn">Register</button>
{{ form_end(registrationForm) }}
L'obiettivo quindi è quello di trasformare tale codice adattandolo alle nostre esigenze. Una breve intro alle funzioni anche se, come anticipato, approfondiremo i Form di Symfony in un altro momento.
Le funzioni form_start
e form_end
si occupano di stampare l'apertura e la chiusura del form. La funzione form_end
, inoltre, stampa tutti i campi definiti nel form e non ancora stampati all'interno del template.
La funzione {{ form_row(registrationForm.email) }}
, invece, stampa l'HTML del campo preso come parametro. L'immagine di seguito riassume quali sono le funzioni che automaticamente richiama al suo interno per tale operazione:
Dato che il layout è un po' più particolare di un normale Form HTML useremo solo alcune delle funzioni interne alla form_row
per stampare il campo input ed eventuali errori.
All'interno del tag registration-page
, il file app/templates/registration/register.html.twig
conterrà la pagina di registrazione già completata. Si tratta della pagina di login con le opportune modifiche.