<?php declare(strict_types=1);
namespace Dvdw\PlatformChoice\Storefront\Controller;
use Dvdw\PlatformChoice\Checkout\Customer\SalesChannel\AbstractCustomerGroupRoute;
use Dvdw\PlatformChoice\Framework\Routing\RouterHelper;
use Dvdw\PlatformChoice\System\SalesChannel\Struct\PlatformChoiceExtension;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Exception\EntityNotFoundException;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\System\SalesChannel\Context\SalesChannelContextPersister;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Storefront\Controller\StorefrontController;
use Shopware\Storefront\Framework\Cache\Annotation\HttpCache;
use Shopware\Storefront\Framework\Routing\Annotation\NoStore;
use Shopware\Storefront\Page\GenericPageLoader;
use Shopware\Storefront\Page\Page;
use Symfony\Component\HttpFoundation\Cookie;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route(defaults={"_routeScope"={"storefront"}})
*/
class PlatformChoiceController extends StorefrontController
{
private SalesChannelContextPersister $contextPersister;
private RouterHelper $router;
private GenericPageLoader $pageLoader;
private AbstractCustomerGroupRoute $groupRoute;
private EntityRepository $customerRepo;
public function __construct(
SalesChannelContextPersister $contextPersister,
RouterHelper $router,
GenericPageLoader $pageLoader,
AbstractCustomerGroupRoute $groupRoute,
EntityRepository $customerRepo
)
{
$this->contextPersister = $contextPersister;
$this->router = $router;
$this->pageLoader = $pageLoader;
$this->groupRoute = $groupRoute;
$this->customerRepo = $customerRepo;
}
/**
* @Route("/platform-choice", name="frontend.platform-choice.index", methods={"GET"})
* @HttpCache()
*/
public function platformChoice(Request $request, SalesChannelContext $context): Response
{
$page = $this->pageLoader->load($request, $context);
$this->resetCustomFields($page);
return $this->renderStorefront(
'@DvdwPlatformChoice/storefront/page/platform-choice/platform-choice.html.twig',
[
'page' => $page,
'route' => $request->query->get('redirectTo', 'frontend.home.page'),
'routeParams' => json_decode((string) $request->query->get('redirectParams'), true)
]
);
}
/**
* @Route("/platform-choice/persist", name="frontend.platform-choice.persist", options={"seo"="false"}, methods={"POST"})
* @NoStore
*/
public function persistPlatformChoice(Request $request, SalesChannelContext $context): Response
{
$platformChoice = $request->request->get(PlatformChoiceExtension::KEY);
if ($platformChoice !== PlatformChoiceExtension::B2B && $platformChoice !== PlatformChoiceExtension::B2C) {
$platformChoice = PlatformChoiceExtension::B2C;
}
$this->contextPersister->save(
$context->getToken(),
[PlatformChoiceExtension::KEY => $platformChoice],
$context->getSalesChannelId(),
$context->getCustomerId()
);
if (($customer = $context->getCustomer()) !== null) {
$this->customerRepo->update([[
'id' => $customer->getId(),
'groupId' => $this->getGroupId($request, $context, $platformChoice)
]], $context->getContext());
}
$redirectTo = $request->request->get('redirectTo', 'frontend.home.page');
$redirectParams = $request->request->get('redirectParameters', []);
if (is_string($redirectParams)) {
$redirectParams = json_decode($redirectParams, true);
}
$url = $this->router->generate($request, $redirectTo, $redirectParams);
$response = new RedirectResponse($url);
$response->headers->setCookie(new Cookie(
PlatformChoiceExtension::KEY,
$platformChoice,
(new \DateTime())->modify('+1 year')
));
return $response;
}
private function getGroupId(Request $request, SalesChannelContext $context, string $platformChoice): string
{
$displayGross = $platformChoice === PlatformChoiceExtension::B2C;
$criteria = (new Criteria())
->addFilter(new EqualsFilter('displayGross', $displayGross));
$group = $this->groupRoute->load($request, $criteria, $context)->getGroups()->first();
if ($group === null) {
throw new EntityNotFoundException(
'customer_group',
'displayGross: ' . $displayGross ? 'true' : 'false'
);
}
return $group->getId();
}
private function resetCustomFields(Page $page): void
{
if (($header = $page->getHeader()) === null
|| ($nav = $header->getNavigation()) === null
|| ($active = $nav->getActive()) === null)
{
return;
}
$active->setCustomFields([]);
}
}