eltharin/invitations

invitations Bundle for symfony

Installs: 5

Dependents: 0

Suggesters: 0

Security: 0

Stars: 1

Watchers: 1

Forks: 0

Open Issues: 0

Type:symfony-bundle

V1.4.2 2024-05-12 08:38 UTC

This package is auto-updated.

Last update: 2024-05-12 08:39:01 UTC


README

Latest Stable Version Total Downloads Latest Unstable Version License

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.