<?php
namespace App\Http\Controller\Auth;
use App\Application\CommandBus\Command\User\RegistrationCommand;
use App\Database\Domain\Entity\User\User;
use App\Database\Domain\Entity\User\UserConfirmEmailToken;
use App\Database\Domain\Repository\UserRepository;
use App\Infrastructure\Mailer\Email\ConfirmEmailAddressEmail;
use App\Infrastructure\Mailer\SimpleMailer;
use App\Infrastructure\Messenger\CommandBus\CommandBusInterface;
use App\Infrastructure\Security\AuthManager;
use App\Infrastructure\Service\ActionResponseHandler;
use App\Infrastructure\Util\ExceptionMessage;
use App\Infrastructure\Util\Identifier;
use Doctrine\ORM\EntityManagerInterface;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route("/user-register", name="registration_")
*/
class RegistrationController extends AbstractController
{
/**
* @Route("", name="index", methods={"GET"})
*/
public function __invoke(Request $request, AuthManager $manager): Response
{
return $this->redirectToRoute('user_login');
/**
* Special param from browser extension.
* Such user must be redirected to specific route after email confirmation.
*/
$isSafari = $request->query->getBoolean('safari', false);
$request->getSession()->set('is_safari', $isSafari);
$request->getSession()->set('redirect-uri', $request->query->get('redirect-uri'));
return $this->render('user/auth/registration.html.twig');
}
/**
* @Route("/{email}/resend-email", name="resend_email", methods={"GET"})
*/
public function resendEmail(
string $email,
UserRepository $userRepository,
SimpleMailer $simpleMailer,
EntityManagerInterface $em
): \Symfony\Component\HttpFoundation\JsonResponse {
$user = $userRepository->findByEmail($email);
$confirmEmailToken = new UserConfirmEmailToken(Identifier::generate(), $user, bin2hex(random_bytes(16)));
$em->persist($confirmEmailToken);
$em->flush();
$email = new ConfirmEmailAddressEmail($user, $confirmEmailToken);
$simpleMailer->send($email);
return $this->json([]);
}
/**
* @Route("", name="form", methods={"POST"})
*/
public function register(
Request $request,
CommandBusInterface $commandBus,
ActionResponseHandler $actionResponseHandler
): Response {
$data = $request->request->all();
try {
$command = new RegistrationCommand();
$command->id = Identifier::generate();
$command->name = $data['name'];
$command->username = $data['email'];
$command->password = $data['password'];
$command->surname = $data['surname'];
$command->email = $data['email'];
$commandBus->execute($command);
} catch (\Exception $exception) {
return $actionResponseHandler->errorRedirect('registration_index', ExceptionMessage::getMessage($exception), [], $data);
}
return $actionResponseHandler->successRedirect('registration_index', 'Check your email for confirmation link!');
}
/**
* @Route("/confirm-email/{token}", name="confirm_email")
*
* @ParamConverter("token", options={"mapping": {"token": "token"}})
*/
public function confirmEmail(
UserConfirmEmailToken $token,
EntityManagerInterface $em,
AuthManager $authManager,
ActionResponseHandler $actionResponseHandler
): Response {
if ($token->isUsed()) {
return $actionResponseHandler->errorRedirect('registration_index', 'Your email is already confirmed');
}
$user = $token->getUser();
$user->getProfile()->setEmailConfirmed(true);
$token->setIsUsed(true);
$em->flush();
return $authManager->manualLogin($user, 'registration_finish_registration', ['source' => 'basic']);
}
/**
* @Route("/finish-registration", name="finish_registration")
*/
public function finishRegistration(Request $request, AuthManager $authManager)
{
/** @var User $user */
$user = $this->getUser();
if (null === $user) {
return $this->redirectToRoute('user_login');
}
if ($request->getMethod() === Request::METHOD_POST) {
$name = $request->request->get('name');
$surname = $request->request->get('surname');
$profession = $request->request->get('profession');
if (null !== $name) {
$user->getProfile()
->setName($name)
->setSurname($surname);
}
$user->getProfile()->setProfession($profession);
$this->getDoctrine()->getManager()->flush();
return $authManager->manualLogin($user, 'user_sessions_index', ['source' => 'registered']);
}
return $this->render('user/auth/finish_registration.html.twig');
}
}