Laptop Store ب Symfony 6 Darija الجزء الرابع
فهاد الجزء الرابع من Laptop Store ب Symfony 6 Darija غادي نكملوا ل projet ديالنا ونزيدوا للمستخدم الإمكانية باش يدير registration و login & logout.
نظرة سريعة بالفيديو
1- إضافة Symfony Controller Registration
باش نزيد ل Controller دير هاد ال commande :
php bin/console make:controller RegistrationController
هنا سميناه Registration ولي فيه الكود لي كيمكن المستخدم من التسجيل.
الكود ديال الملف هو :
//
<?php
namespace App\Controller;
use App\Entity\User;
use App\Form\RegistrationFormType;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\PasswordHasher\Hasher\UserPasswordHasherInterface;
use Symfony\Component\Routing\Annotation\Route;
class RegistrationController extends AbstractController
{
#[Route('/register', name: 'app_register')]
public function register(Request $request, UserPasswordHasherInterface $userPasswordHasher, EntityManagerInterface $entityManager): Response
{
if($this->getUser()){
return $this->redirectToRoute('home');
}
$user = new User();
$form = $this->createForm(RegistrationFormType::class, $user);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
// encode the plain password
$user->setPassword(
$userPasswordHasher->hashPassword(
$user,
$form->get('plainPassword')->getData()
)
);
$entityManager->persist($user);
$entityManager->flush();
// do anything else you need here, like send an email
return $this->redirectToRoute('home');
}
return $this->render('registration/register.html.twig', [
'registrationForm' => $form->createView(),
]);
}
}
2- إضافة Symfony Controller Security
باش نزيد ل Controller دير هاد ال commande :
php bin/console make:controller SecurityController
هنا سميناه Security ولي فيه الكود لي كيمكن المستخدم من login & logout.
الكود ديال الملف هو :
//
<?php
namespace App\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
class SecurityController extends AbstractController
{
#[Route(path: '/login', name: 'app_login')]
public function login(AuthenticationUtils $authenticationUtils): Response
{
// if ($this->getUser()) {
// return $this->redirectToRoute('target_path');
// }
// get the login error if there is one
$error = $authenticationUtils->getLastAuthenticationError();
// last username entered by the user
$lastUsername = $authenticationUtils->getLastUsername();
return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
}
#[Route(path: '/logout', name: 'app_logout')]
public function logout(): void
{
throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
}
}
3- إضافة الملف AppCustomAuthenticator
منبعد غادي نزيدو dossier ف src سميه Security دير s Majuscule فيه زيد fichier سميه AppCustomAuthenticator.php لي غادي نحتاجوه ف la redirection ديال المستخدم من بعد ما يدير Login.
الكود ديال الملف هو :
//
<?php
namespace App\Security;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Http\Authenticator\AbstractLoginFormAuthenticator;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\CsrfTokenBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
use Symfony\Component\Security\Http\Authenticator\Passport\Credentials\PasswordCredentials;
use Symfony\Component\Security\Http\Authenticator\Passport\Passport;
use Symfony\Component\Security\Http\Util\TargetPathTrait;
class AppCustomAuthenticator extends AbstractLoginFormAuthenticator
{
use TargetPathTrait;
public const LOGIN_ROUTE = 'app_login';
private UrlGeneratorInterface $urlGenerator;
public function __construct(UrlGeneratorInterface $urlGenerator)
{
$this->urlGenerator = $urlGenerator;
}
public function authenticate(Request $request): Passport
{
$username = $request->request->get('username', '');
$request->getSession()->set(Security::LAST_USERNAME, $username);
return new Passport(
new UserBadge($username),
new PasswordCredentials($request->request->get('password', '')),
[
new CsrfTokenBadge('authenticate', $request->request->get('_csrf_token')),
]
);
}
public function onAuthenticationSuccess(Request $request, TokenInterface $token, string $firewallName): ?Response
{
if ($targetPath = $this->getTargetPath($request->getSession(), $firewallName)) {
return new RedirectResponse($targetPath);
}
// For example:
//return new RedirectResponse($this->urlGenerator->generate('some_route'));
return new RedirectResponse($this->urlGenerator->generate('home'));
}
protected function getLoginUrl(Request $request): string
{
return $this->urlGenerator->generate(self::LOGIN_ROUTE);
}
}
4- إضافة Register Form
منبعد غادي نزيدو dossier ف src سميه Form فيه زيد fichier سميه RegistrationFormType.php لي غادي تكون فيه الفورم ديال التسجيل.
الكود ديال الملف هو :
//
<?php
namespace App\Form;
use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Validator\Constraints\IsTrue;
use Symfony\Component\Validator\Constraints\Length;
use Symfony\Component\Validator\Constraints\NotBlank;
class RegistrationFormType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options): void
{
$builder
->add('username')
->add('agreeTerms', CheckboxType::class, [
'mapped' => false,
'constraints' => [
new IsTrue([
'message' => 'You should agree to our terms.',
]),
],
])
->add('plainPassword', PasswordType::class, [
// instead of being set onto the object directly,
// this is read and encoded in the controller
'mapped' => false,
'attr' => ['autocomplete' => 'new-password'],
'constraints' => [
new NotBlank([
'message' => 'Please enter a password',
]),
new Length([
'min' => 6,
'minMessage' => 'Your password should be at least {{ limit }} characters',
// max length allowed by Symfony for security reasons
'max' => 4096,
]),
],
])
;
}
public function configureOptions(OptionsResolver $resolver): void
{
$resolver->setDefaults([
'data_class' => User::class,
]);
}
}
5- إضافة Register View
منبعد غادي نزيدو dossier ف templates سميه registration فيه زيد fichier سميه register.html.twig لي غادي تكون فيه الفورم ديال التسجيل.
الكود ديال الملف هو :
//
{% extends 'base.html.twig' %}
{% block title %}Register{% endblock %}
{% block body %}
<div class="row my-5">
<div class="col-md-6 mx-auto">
<div class="card">
<div class="card-header">Register</div>
<div class="card-body">
{{ form_start(registrationForm) }}
{{ form_row(registrationForm.username) }}
{{ form_row(registrationForm.plainPassword, {
label: 'Password'
}) }}
{{ form_row(registrationForm.agreeTerms) }}
<button type="submit" class="btn btn-primary">Register</button>
{{ form_end(registrationForm) }}
</div>
</div>
</div>
</div>
{% endblock %}