<?php
declare(strict_types=1);
namespace Hitso\Bundle\CommonBundle\Controller\Front;
use Hitso\Bundle\CommonBundle\Controller\Controller;
use Hitso\Bundle\CommonBundle\Entity\User;
use Hitso\Bundle\CommonBundle\Event\UserChangePasswordEvent;
use Hitso\Bundle\CommonBundle\Event\UserResetPasswordEvent;
use Hitso\Bundle\CommonBundle\Form\Front\ChangePasswordFormType;
use Hitso\Bundle\CommonBundle\Form\Front\RegistrationFormType;
use Hitso\Bundle\CommonBundle\Form\Front\ResettingFormType;
use Hitso\Bundle\CommonBundle\Manager\UserManager;
use Hitso\Bundle\CommonBundle\Security\FormAuthenticator;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Exception\AuthenticationException;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Guard\GuardAuthenticatorHandler;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;
use WhiteOctober\BreadcrumbsBundle\Model\Breadcrumbs;
class UserController extends Controller
{
/**
* @var UserManager
*/
protected $manager;
/**
* @var GuardAuthenticatorHandler
*/
protected $guard;
/**
* @var AuthenticationUtils
*/
protected $authenticationUtils;
/**
* @var EventDispatcherInterface
*/
protected $eventDispatcher;
/**
* @var FormAuthenticator
*/
protected $formAuthenticator;
public function __construct(
UserManager $manager,
AuthenticationUtils $authenticationUtils,
GuardAuthenticatorHandler $guard,
EventDispatcherInterface $eventDispatcher,
FormAuthenticator $formAuthenticator
) {
$this->manager = $manager;
$this->guard = $guard;
$this->authenticationUtils = $authenticationUtils;
$this->eventDispatcher = $eventDispatcher;
$this->formAuthenticator = $formAuthenticator;
}
public function registerAction(Request $request, Breadcrumbs $breadcrumbs)
{
// Breadcrumbs
$breadcrumbs->addRouteItem('Sign up', 'register');
$user = $this->getUser();
if ($user instanceof User) {
return $this->redirectToRoute('profile');
}
$this->updateSeoPageBySlug('register');
/** @var User $user */
$user = $this->manager->initResource();
$user->setEnabled(true);
$user->setDefaultLocale($request->getLocale());
$form = $this->manager->initForm($user, ['validation_groups' => ['PasswordSet', 'Default']], RegistrationFormType::class);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$user->setUsername($user->getEmail());
$this->manager->createResource($user);
$this->guard->authenticateUserAndHandleSuccess($user, $request, $this->formAuthenticator, 'frontend');
return $this->redirectToRoute('profile');
}
return $this->displayTemplate('register', [
'form' => $form->createView(),
]);
}
public function profileAction(Request $request): Response
{
$user = $this->getUser();
if (!$user instanceof User) {
return $this->redirectToAction('login');
}
$this->updateSeoPageBySlug('profile');
return $this->displayTemplate('profile');
}
public function loginAction(Request $request, Breadcrumbs $breadcrumbs)
{
// Breadcrumbs
$breadcrumbs->addRouteItem('Sign in', 'login');
$user = $this->getUser();
if ($user instanceof User) {
return $this->redirectToRoute('profile');
}
$this->updateSeoPageBySlug('login');
$error = $request->getSession()->get(Security::AUTHENTICATION_ERROR);
if (null !== $error) {
$request->getSession()->remove(Security::AUTHENTICATION_ERROR);
$request->getSession()->set(Security::AUTHENTICATION_ERROR, new AuthenticationException($error->getMessage()));
}
return $this->displayTemplate('login', [
'error' => $this->authenticationUtils->getLastAuthenticationError(),
'lastUsername' => $this->authenticationUtils->getLastUsername(),
]);
}
public function logoutAction()
{
}
public function passwordResetAction(Request $request)
{
$user = $this->getUser();
if ($user instanceof User) {
return $this->redirectToRoute('profile');
}
$this->updateSeoPageBySlug('password_reset');
$form = $this->createForm(ResettingFormType::class, null, ['validation_groups' => ['FrontPasswordReset']]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$email = $form->getData()['email'];
$user = $this->manager->getRepository()->findOneBy(['email' => $email]);
if ($user instanceof User) {
$event = new UserResetPasswordEvent($user);
$this->eventDispatcher->dispatch(UserResetPasswordEvent::EVENT_NAME, $event);
$this->manager->updateResource($user);
$success = true;
} else {
$success = false;
}
return $this->displayTemplate('password_reset', [
'success' => $success,
]);
}
return $this->displayTemplate('password_reset', [
'form' => $form->createView(),
]);
}
public function passwordChangeAction(Request $request, string $token)
{
$user = $this->getUser();
if ($user instanceof User) {
return $this->redirectToRoute('profile');
}
$user = $this->manager->getRepository()->findOneBy(['confirmationToken' => $token]);
if (!$user instanceof User) {
return $this->redirectToRoute('password_reset');
}
$form = $this->createForm(ChangePasswordFormType::class, $user, ['validation_groups' => ['PasswordSet']]);
$form->handleRequest($request);
if ($form->isSubmitted() && $form->isValid()) {
$event = new UserChangePasswordEvent($user);
$this->eventDispatcher->dispatch(UserChangePasswordEvent::EVENT_NAME, $event);
$this->manager->updateResource($user);
return $this->displayTemplate('password_change', [
'success' => true,
]);
}
return $this->displayTemplate('password_change', [
'form' => $form->createView(),
]);
}
protected function updateSeoPageBySlug(string $slug): void
{
$page = $this->getPageBySlug($slug);
if (!empty($page)) {
$this->updateSeoPage($page);
}
}
}