<?php declare(strict_types=1);
namespace Samson\Controller;
/***
*
* This file is part of the "SAMSON Shop" project.
*
* For the full copyright and license information, please read the
* LICENSE.txt file that was distributed with this source code.
*
* (c) 2022
*
***/
use Psr\Log\LoggerInterface;
use Samson\CustomFieldSet\Constants\CustomerCustomFieldConstants;
use Samson\Entities\CustomerExtension\CustomerExtensionEntity;
use Samson\Exception\CustomerNeedsPasswordChangeException;
use Samson\Pages\SubAccount\SubAccountPageLoader;
use Shopware\Core\Checkout\Cart\Exception\CustomerNotLoggedInException;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractChangeCustomerProfileRoute;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractChangeEmailRoute;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractChangePasswordRoute;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractDeleteCustomerRoute;
use Shopware\Core\Checkout\Customer\SalesChannel\AbstractLogoutRoute;
use Shopware\Core\Content\Category\Exception\CategoryNotFoundException;
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
use Shopware\Core\Framework\Routing\Annotation\LoginRequired;
use Shopware\Core\Framework\Routing\Annotation\RouteScope;
use Shopware\Core\Framework\Routing\Annotation\Since;
use Shopware\Core\Framework\Routing\Exception\MissingRequestParameterException;
use Shopware\Core\Framework\Validation\DataBag\RequestDataBag;
use Shopware\Core\Framework\Validation\Exception\ConstraintViolationException;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use \Shopware\Storefront\Controller\AccountProfileController as ShopwareAccountProfileController;
use Shopware\Storefront\Framework\Routing\Annotation\NoStore;
use Shopware\Storefront\Page\Account\Overview\AccountOverviewPageLoader;
use Shopware\Storefront\Page\Account\Profile\AccountProfilePageLoader;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Samson\Annotation\CustomerNeedsPasswordChange;
/**
* @RouteScope(scopes={"storefront"})
*/
class AccountProfileController extends ShopwareAccountProfileController
{
private AbstractLogoutRoute $logoutRoute;
private SubAccountPageLoader $subAccountPageLoader;
private AbstractDeleteCustomerRoute $deleteCustomerRoute;
private AbstractChangePasswordRoute $changePasswordRoute;
public function __construct(
AccountOverviewPageLoader $overviewPageLoader,
AccountProfilePageLoader $profilePageLoader,
AbstractChangeCustomerProfileRoute $changeCustomerProfileRoute,
AbstractChangePasswordRoute $changePasswordRoute,
AbstractChangeEmailRoute $changeEmailRoute,
AbstractDeleteCustomerRoute $deleteCustomerRoute,
LoggerInterface $logger,
AbstractLogoutRoute $logoutRoute,
SubAccountPageLoader $subAccountPageLoader
)
{
parent::__construct($overviewPageLoader,
$profilePageLoader,
$changeCustomerProfileRoute,
$changePasswordRoute,
$changeEmailRoute,
$deleteCustomerRoute,
$logger
);
$this->logoutRoute = $logoutRoute;
$this->subAccountPageLoader = $subAccountPageLoader;
$this->deleteCustomerRoute = $deleteCustomerRoute;
$this->changePasswordRoute = $changePasswordRoute;
}
/**
* @Since("6.0.0.0")
* @LoginRequired()
* @CustomerNeedsPasswordChange()
* @Route("/account", name="frontend.account.home.page", methods={"GET"})
* @NoStore
*
* @throws CustomerNotLoggedInException
* @throws CategoryNotFoundException
* @throws InconsistentCriteriaIdsException
* @throws MissingRequestParameterException
* @throws CustomerNeedsPasswordChangeException
*/
public function index(Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
if (array_key_exists(CustomerCustomFieldConstants::CUSTOM_FIELD_ADMIN_ACTIVATION_NEEDED, $customer->getCustomFields() ?? [])) {
$this->logoutRoute->logout($context, new RequestDataBag());
return $this->redirectToRoute("frontend.account.login.page");
}
return parent::index($request, $context, $customer);
}
/**
* @Since("6.0.0.0")
* @LoginRequired()
* @CustomerNeedsPasswordChange()
* @Route("/account/profile", name="frontend.account.profile.page", methods={"GET"})
* @NoStore
*
* @throws CustomerNotLoggedInException
* @throws CategoryNotFoundException
* @throws InconsistentCriteriaIdsException
* @throws MissingRequestParameterException
* @throws CustomerNeedsPasswordChangeException
*/
public function profileOverview(Request $request, SalesChannelContext $context): Response
{
return parent::profileOverview($request, $context);
}
/**
* @Since("6.0.0.0")
* @LoginRequired()
* @CustomerNeedsPasswordChange()
* @Route("/account/profile", name="frontend.account.profile.save", methods={"POST"})
*
* @throws CustomerNotLoggedInException
* @throws CustomerNeedsPasswordChangeException
*/
public function saveProfile(RequestDataBag $data, SalesChannelContext $context, CustomerEntity $customer): Response
{
return parent::saveProfile($data, $context, $customer);
}
/**
* @Since("6.0.0.0")
* @LoginRequired()
* @CustomerNeedsPasswordChange()
* @Route("/account/profile/email", name="frontend.account.profile.email.save", methods={"POST"})
*
* @throws CustomerNotLoggedInException
* @throws CustomerNeedsPasswordChangeException
*/
public function saveEmail(RequestDataBag $data, SalesChannelContext $context, CustomerEntity $customer): Response
{
return parent::saveEmail($data, $context, $customer);
}
/**
* @Since("6.0.0.0")
* @LoginRequired()
* @CustomerNeedsPasswordChange()
* @Route("/account/profile/password", name="frontend.account.profile.password.save", methods={"POST"})
*
* @throws CustomerNotLoggedInException
* @throws CustomerNeedsPasswordChangeException
*/
public function savePassword(RequestDataBag $data, SalesChannelContext $context, CustomerEntity $customer): Response
{
return parent::savePassword($data, $context, $customer);
}
/**
* @Since("6.3.3.0")
* @LoginRequired()
* @CustomerNeedsPasswordChange()
* @Route("/account/profile/delete", name="frontend.account.profile.delete", methods={"POST"})
*
* @throws CustomerNotLoggedInException
* @throws CustomerNeedsPasswordChangeException
*/
public function deleteProfile(Request $request, SalesChannelContext $context, CustomerEntity $customer): Response
{
return parent::deleteProfile($request, $context, $customer);
}
/**
* @Route("/account/sub-account", name="frontend.account.sub-account.page", methods={"GET"})
* @LoginRequired()
*
* @throws CustomerNotLoggedInException
*/
public function subAccountOverview(Request $request, SalesChannelContext $context): Response
{
$customer = $context->getCustomer();
if ($this->isSubAccount($customer)) {
return $this->redirectToRoute('frontend.account.home.page', ['customer' => $customer]);
}
$page = $this->subAccountPageLoader->load($request, $context);
return $this->renderStorefront('@Storefront/storefront/page/account/sub-account/index.html.twig',
[
'page' => $page
]);
}
/**
* @Route("/account/sub-account/{subAccountId}", name="frontend.account.sub-account.delete", methods={"GET"})
* @LoginRequired()
*
* @throws CustomerNotLoggedInException
*/
public function deleteSubAccount(string $subAccountId, Request $request, SalesChannelContext $context): Response
{
$customer = $context->getCustomer();
if ($this->isSubAccount($customer)) {
return $this->redirectToRoute('frontend.account.home.page', ['customer' => $customer]);
}
$customerEntity = new CustomerEntity();
$customerEntity->setId($subAccountId);
$this->deleteCustomerRoute->delete($context, $customerEntity);
return $this->redirectToRoute('frontend.account.sub-account.page');
}
/**
* @Route("/sub-account/password", name="frontend.sub-account.password.page", methods={"GET"})
* @LoginRequired()
*
* @throws CustomerNotLoggedInException
**/
public function showPasswordChange(Request $request, RequestDataBag $dataBag, SalesChannelContext $context): Response
{
return $this->renderStorefront('@Storefront/storefront/page/password/index.html.twig',
[
'redirectTo' => $request->get('redirectTo'),
'redirectParameters' => $request->get('redirectParameters', json_encode([]))
]);
}
/**
* @Route("/sub-account/password", name="frontend.sub-account.password.change", methods={"POST"})
* @LoginRequired()
*
* @throws CustomerNotLoggedInException
**/
public function changePassword(Request $request, RequestDataBag $dataBag, SalesChannelContext $context): Response
{
$customer = $context->getCustomer();
try {
$this->changePasswordRoute->change($dataBag->get('password')->toRequestDataBag(), $context, $customer);
$this->addFlash(self::SUCCESS, $this->trans('account.passwordChangeSuccess'));
} catch (ConstraintViolationException $formViolations) {
$this->addFlash(self::DANGER, $this->trans('account.passwordChangeNoSuccess'));
return $this->forwardToRoute('frontend.account.profile.page', ['formViolations' => $formViolations, 'passwordFormViolation' => true]);
}
if ($dataBag->has('redirectTo') && !empty($dataBag->get('redirectTo'))) {
return $this->redirectToRoute($dataBag->get('redirectTo'), json_decode($dataBag->get('redirectParameters'), true));
}
return $this->redirectToRoute('frontend.home.page');
}
private function isSubAccount(CustomerEntity $customer): bool
{
return isset($customer->getCustomFields()[CustomerCustomFieldConstants::CUSTOM_FIELD_IS_SUB_ACCOUNT])
&& $customer->getCustomFields()[CustomerCustomFieldConstants::CUSTOM_FIELD_IS_SUB_ACCOUNT];
}
}