eltharin / invitations
invitations Bundle for symfony
Installs: 41
Dependents: 0
Suggesters: 0
Security: 0
Stars: 1
Watchers: 1
Forks: 0
Open Issues: 0
Type:symfony-bundle
README
Installation
- Require the bundle with composer:
composer require eltharin/invitaitons php bin/console make:migration php bin/console d:m:m to create invitaitons table
What is Invitations Bundle?
This bundle will help you to work with chained mail actions.
When you have to send a mail for allowing an action this bundle will helps you.
How to ?
For the example we will set the forget-password workflow:
- User go to page /forget-password
- type his mail
- receive a mail a clic on the link inside
- set his new password
- enjoy
no changes is required on User entity just a new table for all invitations.
create a FormType for reset password with just an email asked and one other for the new password :
class ForgetPasswordType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('email', EmailType::class, [ 'label' => 'Type your email' ]) ; } } class ResetPasswordType extends AbstractType { public function buildForm(FormBuilderInterface $builder, array $options): void { $builder ->add('password', PasswordType::class, [ 'label' => 'Type the new password', 'help_html' => true, ]) ; } }
now we will create an "Invitation": Class must extends from AbstractInvitation, that tag it automaticly with app.invitation
class ResetPassword extends AbstractInvitation { public function setMailContent(TemplatedEmail $email, InvitationEntityManager $invitationEntityManagerManager): void { $email->subject('Reset password') ->htmlTemplate('mail/invitations/resetpassword.html.twig'); } public function resolve(InvitationEntityManager $invitationEntityManagerManager): bool { // nothing here all is treated in controller return true; } public function getResolvePath(InvitationEntityManager $invitationEntityManagerManager) : array { return [ 'path' => 'app_reset_password', 'args' => ['id' => $invitationEntityManagerManager->getInvitation()->getId(), 'token' => $invitationEntityManagerManager->getInvitation()->getToken()], ]; } public function resendMailIfAlreadyExists(): bool { return true; } }
the mail template will contains the link :
Reset your password : <a href="{{ include(template_from_string(invitation_url)) }}">Link</a>
now the first route in security controller for show the form and send the mail :
#[Route(path: '/forget-password', name: 'app_forget_password')] public function forgetPassword( Request $request, UserRepository $userRepository, InvitationManager $invitationManager ): Response { $form = $this->createForm(ForgetPasswordType::class); $form->handleRequest($request); if($form->isSubmitted() && $form->isValid()) { $user = $userRepository->findOneByEmail($form->get('email')->getData()); if($user != null) { $invitationManager->create(ResetPassword::class, $user, $form->get('email')->getData(),0); } return $this->render('message.html.twig', [ 'message' => 'If you mail is on our base, we sent you a message for reset your password', ]); } return $this->render('security/reset_password/reset_password_request.html.twig', [ 'form' => $form->createView() ]); }
Now the route call when link inside mail is clicked :
#[Route(path: '/reset-password', name: 'app_reset_password')] public function resetPassword( Request $request, InvitationManager $invitationManager, EntityManagerInterface $em, UserPasswordHasherInterface $passwordHasher ): Response { $invitation = $invitationManager->getInvit($request->query->get('id'), ['type' => [ResetPassword::class], 'token' => $request->query->get('token')]); if($invitation == null) { throw new ItemNotFoundException('Unkwnon Invitation'); } $user = $invitation->getInvitation()->getUser(); $form = $this->createForm(ResetPasswordType::class, $user, ['action' => $invitation->getResolvePath(true)]); $form->handleRequest($request); if($form->isSubmitted() && $form->isValid()) { $user->setPassword($passwordHasher->hashPassword($user,$user->getPassword())); $em->flush(); $invitation->resolve(true); $this->addFlash('success', 'Your password has been changed.'); return $this->redirectToRoute('app_login'); } return $this->render('security/reset_password/reset_password_request.html.twig', [ 'form' => $form->createView() ]); }
As you can see you have to write code for the logic of the action you want but nothing for send a mail, get the token, reteive for witch user, all is done for you.