596 lines
22 KiB
PHP
596 lines
22 KiB
PHP
<?php
|
|
|
|
/*
|
|
* This file is part of the Thelia package.
|
|
* http://www.thelia.net
|
|
*
|
|
* (c) OpenStudio <info@thelia.net>
|
|
*
|
|
* For the full copyright and license information, please view the LICENSE
|
|
* file that was distributed with this source code.
|
|
*/
|
|
|
|
namespace Front\Controller;
|
|
|
|
use Front\Front;
|
|
use Symfony\Component\Form\Extension\Core\Type\FormType;
|
|
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
|
|
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
|
|
use Thelia\Controller\Front\BaseFrontController;
|
|
use Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent;
|
|
use Thelia\Core\Event\Customer\CustomerLoginEvent;
|
|
use Thelia\Core\Event\DefaultActionEvent;
|
|
use Thelia\Core\Event\LostPasswordEvent;
|
|
use Thelia\Core\Event\Newsletter\NewsletterEvent;
|
|
use Thelia\Core\Event\TheliaEvents;
|
|
use Thelia\Core\Security\Authentication\CustomerUsernamePasswordFormAuthenticator;
|
|
use Thelia\Core\Security\Exception\AuthenticationException;
|
|
use Thelia\Core\Security\Exception\CustomerNotConfirmedException;
|
|
use Thelia\Core\Security\Exception\UsernameNotFoundException;
|
|
use Thelia\Core\Security\Exception\WrongPasswordException;
|
|
use Thelia\Form\CustomerLogin;
|
|
use Thelia\Form\Definition\FrontForm;
|
|
use Thelia\Form\Exception\FormValidationException;
|
|
use Thelia\Log\Tlog;
|
|
use Thelia\Model\ConfigQuery;
|
|
use Thelia\Model\Customer;
|
|
use Thelia\Model\CustomerQuery;
|
|
use Thelia\Model\Event\CustomerEvent;
|
|
use Thelia\Model\Newsletter;
|
|
use Thelia\Model\NewsletterQuery;
|
|
use Thelia\Tools\RememberMeTrait;
|
|
use Thelia\Tools\URL;
|
|
|
|
/**
|
|
* Class CustomerController.
|
|
*
|
|
* @author Manuel Raynaud <manu@raynaud.io>
|
|
*/
|
|
class CustomerController extends BaseFrontController
|
|
{
|
|
use RememberMeTrait;
|
|
|
|
/**
|
|
* Display the register template if no customer logged.
|
|
*/
|
|
public function viewLoginAction()
|
|
{
|
|
if ($this->getSecurityContext()->hasCustomerUser()) {
|
|
// Redirect to home page
|
|
return $this->generateRedirect(URL::getInstance()->getIndexPage());
|
|
}
|
|
|
|
return $this->render('login');
|
|
}
|
|
|
|
/**
|
|
* Display the register template if no customer logged.
|
|
*/
|
|
public function viewRegisterAction()
|
|
{
|
|
if ($this->getSecurityContext()->hasCustomerUser()) {
|
|
// Redirect to home page
|
|
return $this->generateRedirect(URL::getInstance()->getIndexPage());
|
|
}
|
|
|
|
return $this->render('register');
|
|
}
|
|
|
|
public function newPasswordAction(EventDispatcherInterface $eventDispatcher)
|
|
{
|
|
$passwordLost = $this->createForm(FrontForm::CUSTOMER_LOST_PASSWORD);
|
|
|
|
if (!$this->getSecurityContext()->hasCustomerUser()) {
|
|
try {
|
|
$form = $this->validateForm($passwordLost);
|
|
|
|
$event = new LostPasswordEvent($form->get('email')->getData());
|
|
|
|
$eventDispatcher->dispatch($event, TheliaEvents::LOST_PASSWORD);
|
|
|
|
return $this->generateSuccessRedirect($passwordLost);
|
|
} catch (FormValidationException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Please check your input: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (\Exception $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Sorry, an error occurred: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
}
|
|
|
|
if ($message !== false) {
|
|
Tlog::getInstance()->error(
|
|
sprintf(
|
|
'Error during customer creation process : %s. Exception was %s',
|
|
$message,
|
|
$e->getMessage()
|
|
)
|
|
);
|
|
}
|
|
} else {
|
|
$message = $this->getTranslator()->trans(
|
|
"You're currently logged in. Please log out before requesting a new password.",
|
|
[],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
}
|
|
|
|
$passwordLost->setErrorMessage($message);
|
|
|
|
$this->getParserContext()
|
|
->addForm($passwordLost)
|
|
->setGeneralError($message)
|
|
;
|
|
|
|
// Redirect to error URL if defined
|
|
if ($passwordLost->hasErrorUrl()) {
|
|
return $this->generateErrorRedirect($passwordLost);
|
|
}
|
|
}
|
|
|
|
public function newPasswordSentAction(): void
|
|
{
|
|
$this->getParser()->assign('password_sent', true);
|
|
}
|
|
|
|
/**
|
|
* Create a new customer.
|
|
* On success, redirect to success_url if exists, otherwise, display the same view again.
|
|
*/
|
|
public function createAction(EventDispatcherInterface $eventDispatcher)
|
|
{
|
|
if (!$this->getSecurityContext()->hasCustomerUser()) {
|
|
$customerCreation = $this->createForm(FrontForm::CUSTOMER_CREATE);
|
|
|
|
try {
|
|
$form = $this->validateForm($customerCreation, 'post');
|
|
|
|
$customerCreateEvent = $this->createEventInstance($form->getData());
|
|
|
|
$eventDispatcher->dispatch($customerCreateEvent, TheliaEvents::CUSTOMER_CREATEACCOUNT);
|
|
|
|
$newCustomer = $customerCreateEvent->getCustomer();
|
|
|
|
// Newsletter
|
|
if (true === $form->get('newsletter')->getData()) {
|
|
$newsletterEmail = $newCustomer->getEmail();
|
|
$nlEvent = new NewsletterEvent(
|
|
$newsletterEmail,
|
|
$this->getRequest()->getSession()->getLang()->getLocale()
|
|
);
|
|
$nlEvent->setFirstname($newCustomer->getFirstname());
|
|
$nlEvent->setLastname($newCustomer->getLastname());
|
|
|
|
// Security : Check if this new Email address already exist
|
|
if (null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterEmail)) {
|
|
$nlEvent->setId($newsletter->getId());
|
|
$eventDispatcher->dispatch($nlEvent, TheliaEvents::NEWSLETTER_UPDATE);
|
|
} else {
|
|
$eventDispatcher->dispatch($nlEvent, TheliaEvents::NEWSLETTER_SUBSCRIBE);
|
|
}
|
|
}
|
|
|
|
if (ConfigQuery::isCustomerEmailConfirmationEnable() && !$newCustomer->getEnable()) {
|
|
$response = $this->generateRedirectFromRoute('customer.login.view');
|
|
} else {
|
|
$this->processLogin($eventDispatcher, $customerCreateEvent->getCustomer());
|
|
|
|
$cart = $this->getSession()->getSessionCart($eventDispatcher);
|
|
if ($cart->getCartItems()->count() > 0) {
|
|
$response = $this->generateRedirectFromRoute('cart.view');
|
|
} else {
|
|
$response = $this->generateSuccessRedirect($customerCreation);
|
|
}
|
|
}
|
|
|
|
return $response;
|
|
} catch (FormValidationException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Please check your input: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (\Exception $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Sorry, an error occured: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
}
|
|
|
|
Tlog::getInstance()->error(
|
|
sprintf(
|
|
'Error during customer creation process : %s. Exception was %s',
|
|
$message,
|
|
$e->getMessage()
|
|
)
|
|
);
|
|
|
|
$customerCreation->setErrorMessage($message);
|
|
|
|
$this->getParserContext()
|
|
->addForm($customerCreation)
|
|
->setGeneralError($message)
|
|
;
|
|
|
|
// Redirect to error URL if defined
|
|
if ($customerCreation->hasErrorUrl()) {
|
|
return $this->generateErrorRedirect($customerCreation);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Prepare customer data update.
|
|
*/
|
|
public function viewAction(): void
|
|
{
|
|
$this->checkAuth();
|
|
|
|
/** @var Customer $customer */
|
|
$customer = $this->getSecurityContext()->getCustomerUser();
|
|
$newsletter = NewsletterQuery::create()->findOneByEmail($customer->getEmail());
|
|
$data = [
|
|
'id' => $customer->getId(),
|
|
'title' => $customer->getTitleId(),
|
|
'firstname' => $customer->getFirstName(),
|
|
'lastname' => $customer->getLastName(),
|
|
'email' => $customer->getEmail(),
|
|
'email_confirm' => $customer->getEmail(),
|
|
'lang_id' => $customer->getLangId(),
|
|
'newsletter' => $newsletter instanceof Newsletter ? !$newsletter->getUnsubscribed() : false,
|
|
];
|
|
|
|
$customerProfileUpdateForm = $this->createForm(FrontForm::CUSTOMER_PROFILE_UPDATE, FormType::class, $data);
|
|
|
|
// Pass it to the parser
|
|
$this->getParserContext()->addForm($customerProfileUpdateForm);
|
|
}
|
|
|
|
public function updatePasswordAction(EventDispatcherInterface $eventDispatcher)
|
|
{
|
|
if ($this->getSecurityContext()->hasCustomerUser()) {
|
|
$customerPasswordUpdateForm = $this->createForm(FrontForm::CUSTOMER_PASSWORD_UPDATE);
|
|
|
|
try {
|
|
/** @var Customer $customer */
|
|
$customer = $this->getSecurityContext()->getCustomerUser();
|
|
|
|
$form = $this->validateForm($customerPasswordUpdateForm, 'post');
|
|
|
|
$customerChangeEvent = $this->createEventInstance($form->getData());
|
|
$customerChangeEvent->setCustomer($customer);
|
|
$eventDispatcher->dispatch($customerChangeEvent, TheliaEvents::CUSTOMER_UPDATEPROFILE);
|
|
|
|
return $this->generateSuccessRedirect($customerPasswordUpdateForm);
|
|
} catch (FormValidationException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Please check your input: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (\Exception $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Sorry, an error occured: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
}
|
|
|
|
Tlog::getInstance()->error(
|
|
sprintf(
|
|
'Error during customer password modification process : %s.',
|
|
$message
|
|
)
|
|
);
|
|
|
|
$customerPasswordUpdateForm->setErrorMessage($message);
|
|
|
|
$this->getParserContext()
|
|
->addForm($customerPasswordUpdateForm)
|
|
->setGeneralError($message)
|
|
;
|
|
|
|
// Redirect to error URL if defined
|
|
if ($customerPasswordUpdateForm->hasErrorUrl()) {
|
|
return $this->generateErrorRedirect($customerPasswordUpdateForm);
|
|
}
|
|
}
|
|
}
|
|
|
|
public function updateAction(EventDispatcherInterface $eventDispatcher)
|
|
{
|
|
if ($this->getSecurityContext()->hasCustomerUser()) {
|
|
$customerProfileUpdateForm = $this->createForm(FrontForm::CUSTOMER_PROFILE_UPDATE);
|
|
|
|
try {
|
|
/** @var Customer $customer */
|
|
$customer = $this->getSecurityContext()->getCustomerUser();
|
|
$newsletterOldEmail = $customer->getEmail();
|
|
|
|
$form = $this->validateForm($customerProfileUpdateForm, 'post');
|
|
|
|
$customerChangeEvent = $this->createEventInstance($form->getData());
|
|
$customerChangeEvent->setCustomer($customer);
|
|
|
|
$customerChangeEvent->setEmailUpdateAllowed(
|
|
((int) ConfigQuery::read('customer_change_email', 0)) ? true : false
|
|
);
|
|
|
|
$eventDispatcher->dispatch($customerChangeEvent, TheliaEvents::CUSTOMER_UPDATEPROFILE);
|
|
|
|
$updatedCustomer = $customerChangeEvent->getCustomer();
|
|
|
|
// Newsletter
|
|
if (true === $form->get('newsletter')->getData()) {
|
|
$nlEvent = new NewsletterEvent(
|
|
$updatedCustomer->getEmail(),
|
|
$this->getRequest()->getSession()->getLang()->getLocale()
|
|
);
|
|
$nlEvent->setFirstname($updatedCustomer->getFirstname());
|
|
$nlEvent->setLastname($updatedCustomer->getLastname());
|
|
|
|
if (null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterOldEmail)) {
|
|
$nlEvent->setId($newsletter->getId());
|
|
$eventDispatcher->dispatch($nlEvent, TheliaEvents::NEWSLETTER_UPDATE);
|
|
} else {
|
|
$eventDispatcher->dispatch($nlEvent, TheliaEvents::NEWSLETTER_SUBSCRIBE);
|
|
}
|
|
} else {
|
|
if (null !== $newsletter = NewsletterQuery::create()->findOneByEmail($newsletterOldEmail)) {
|
|
$nlEvent = new NewsletterEvent(
|
|
$updatedCustomer->getEmail(),
|
|
$this->getRequest()->getSession()->getLang()->getLocale()
|
|
);
|
|
$nlEvent->setId($newsletter->getId());
|
|
$eventDispatcher->dispatch($nlEvent, TheliaEvents::NEWSLETTER_UNSUBSCRIBE);
|
|
}
|
|
}
|
|
|
|
$this->processLogin($eventDispatcher, $updatedCustomer);
|
|
|
|
return $this->generateSuccessRedirect($customerProfileUpdateForm);
|
|
} catch (FormValidationException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Please check your input: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (\Exception $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Sorry, an error occured: %s',
|
|
[
|
|
'%s' => $e->getMessage(),
|
|
],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
}
|
|
|
|
Tlog::getInstance()->error(sprintf('Error during customer modification process : %s.', $message));
|
|
|
|
$customerProfileUpdateForm->setErrorMessage($message);
|
|
|
|
$this->getParserContext()
|
|
->addForm($customerProfileUpdateForm)
|
|
->setGeneralError($message)
|
|
;
|
|
|
|
// Redirect to error URL if defined
|
|
if ($customerProfileUpdateForm->hasErrorUrl()) {
|
|
return $this->generateErrorRedirect($customerProfileUpdateForm);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Perform user login. On a successful login, the user is redirected to the URL
|
|
* found in the success_url form parameter, or / if none was found.
|
|
*
|
|
* If login is not successfull, the same view is displayed again.
|
|
*/
|
|
public function loginAction(EventDispatcherInterface $eventDispatcher)
|
|
{
|
|
if (!$this->getSecurityContext()->hasCustomerUser()) {
|
|
$request = $this->getRequest();
|
|
$customerLoginForm = $this->createForm(CustomerLogin::class);
|
|
|
|
try {
|
|
$form = $this->validateForm($customerLoginForm, 'post');
|
|
|
|
// If User is a new customer
|
|
if ($form->get('account')->getData() == 0 && $form->get('email')->getErrors()->count() == 0) {
|
|
return $this->generateRedirectFromRoute(
|
|
'customer.create.process',
|
|
['email' => $form->get('email')->getData()]
|
|
);
|
|
}
|
|
try {
|
|
$authenticator = new CustomerUsernamePasswordFormAuthenticator($request, $customerLoginForm);
|
|
|
|
/** @var Customer $customer */
|
|
$customer = $authenticator->getAuthentifiedUser();
|
|
|
|
$this->processLogin($eventDispatcher, $customer);
|
|
|
|
if ((int) $form->get('remember_me')->getData() > 0) {
|
|
// If a remember me field if present and set in the form, create
|
|
// the cookie thant store "remember me" information
|
|
$this->createRememberMeCookie(
|
|
$customer,
|
|
$this->getRememberMeCookieName(),
|
|
$this->getRememberMeCookieExpiration()
|
|
);
|
|
}
|
|
|
|
return $this->generateSuccessRedirect($customerLoginForm);
|
|
} catch (UsernameNotFoundException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Wrong email or password. Please try again',
|
|
[],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (WrongPasswordException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Wrong email or password. Please try again',
|
|
[],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (CustomerNotConfirmedException $e) {
|
|
if ($e->getUser() !== null) {
|
|
// Send the confirmation email again
|
|
$eventDispatcher->dispatch(
|
|
new CustomerEvent($e->getUser()),
|
|
TheliaEvents::SEND_ACCOUNT_CONFIRMATION_EMAIL
|
|
);
|
|
}
|
|
$message = $this->getTranslator()->trans(
|
|
'Your account is not yet confirmed. A confirmation email has been sent to your email address, please check your mailbox',
|
|
[],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (AuthenticationException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Wrong email or password. Please try again',
|
|
[],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
}
|
|
} catch (FormValidationException $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Please check your input: %s',
|
|
['%s' => $e->getMessage()],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
} catch (\Exception $e) {
|
|
$message = $this->getTranslator()->trans(
|
|
'Sorry, an error occured: %s',
|
|
['%s' => $e->getMessage()],
|
|
Front::MESSAGE_DOMAIN
|
|
);
|
|
}
|
|
|
|
Tlog::getInstance()->error(
|
|
sprintf(
|
|
'Error during customer login process : %s. Exception was %s',
|
|
$message,
|
|
$e->getMessage()
|
|
)
|
|
);
|
|
|
|
$customerLoginForm->setErrorMessage($message);
|
|
|
|
$this->getParserContext()->addForm($customerLoginForm);
|
|
|
|
if ($customerLoginForm->hasErrorUrl()) {
|
|
return $this->generateErrorRedirect($customerLoginForm);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Perform customer logout.
|
|
*/
|
|
public function logoutAction(EventDispatcherInterface $eventDispatcher)
|
|
{
|
|
if ($this->getSecurityContext()->hasCustomerUser()) {
|
|
$eventDispatcher->dispatch(new DefaultActionEvent(), TheliaEvents::CUSTOMER_LOGOUT);
|
|
}
|
|
|
|
$this->clearRememberMeCookie($this->getRememberMeCookieName());
|
|
|
|
// Redirect to home page
|
|
return $this->generateRedirect(URL::getInstance()->getIndexPage());
|
|
}
|
|
|
|
/**
|
|
* @throws \Exception
|
|
* @throws \Propel\Runtime\Exception\PropelException
|
|
*
|
|
* @return \Symfony\Component\HttpFoundation\Response
|
|
*/
|
|
public function confirmCustomerAction($token)
|
|
{
|
|
/** @var Customer $customer */
|
|
if (null === $customer = CustomerQuery::create()->findOneByConfirmationToken($token)) {
|
|
throw new NotFoundHttpException();
|
|
}
|
|
|
|
$customer
|
|
->setEnable(true)
|
|
->save()
|
|
;
|
|
|
|
// Clear form error context
|
|
|
|
return $this->generateRedirectFromRoute('customer.login.view', ['validation_done' => 1]);
|
|
}
|
|
|
|
/**
|
|
* Dispatch event for customer login action.
|
|
*/
|
|
protected function processLogin(EventDispatcherInterface $eventDispatcher, Customer $customer): void
|
|
{
|
|
$eventDispatcher->dispatch(new CustomerLoginEvent($customer), TheliaEvents::CUSTOMER_LOGIN);
|
|
}
|
|
|
|
/**
|
|
* @return \Thelia\Core\Event\Customer\CustomerCreateOrUpdateEvent
|
|
*/
|
|
private function createEventInstance($data)
|
|
{
|
|
$customerCreateEvent = new CustomerCreateOrUpdateEvent(
|
|
$data['title'] ?? null,
|
|
$data['firstname'] ?? null,
|
|
$data['lastname'] ?? null,
|
|
$data['address1'] ?? null,
|
|
$data['address2'] ?? null,
|
|
$data['address3'] ?? null,
|
|
$data['phone'] ?? null,
|
|
$data['cellphone'] ?? null,
|
|
$data['zipcode'] ?? null,
|
|
$data['city'] ?? null,
|
|
$data['country'] ?? null,
|
|
$data['email'] ?? null,
|
|
$data['password'] ?? null,
|
|
$data['lang_id'] ?? $this->getSession()->getLang()->getId(),
|
|
$data['reseller'] ?? null,
|
|
$data['sponsor'] ?? null,
|
|
$data['discount'] ?? null,
|
|
$data['company'] ?? null,
|
|
null,
|
|
$data['state'] ?? null
|
|
);
|
|
|
|
return $customerCreateEvent;
|
|
}
|
|
|
|
protected function getRememberMeCookieName()
|
|
{
|
|
return ConfigQuery::read('customer_remember_me_cookie_name', 'crmcn');
|
|
}
|
|
|
|
protected function getRememberMeCookieExpiration()
|
|
{
|
|
return ConfigQuery::read('customer_remember_me_cookie_expiration', 2592000 /* 1 month */);
|
|
}
|
|
}
|