<?php
/**
* NOTICE OF LICENSE
*
* @copyright Copyright (c) 01.03.2020 brainstation GbR
* @author Mike Becker<[email protected]>
*/
declare(strict_types=1);
namespace BstCatalogMode6\Storefront\Subscriber;
use BstCatalogMode6\Struct\ConfigData;
use Psr\Log\LoggerInterface;
use Shopware\Core\Checkout\Cart\Price\Struct\CalculatedPrice;
use Shopware\Core\Checkout\Cart\Price\Struct\PriceCollection;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Symfony\Component\Routing\RouterInterface;
use Shopware\Core\Checkout\Customer\CustomerEntity;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Shopware\Core\PlatformRequest;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Models\Customer\Customer;
use Shopware\Storefront\Controller\CheckoutController;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Shopware\Storefront\Page\Search\SearchPageLoadedEvent;
use Shopware\Storefront\Page\Suggest\SuggestPageLoadedEvent;
use Shopware\Storefront\Pagelet\Header\HeaderPageletLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpKernel\Event\ControllerArgumentsEvent;
use Symfony\Component\HttpKernel\Event\ControllerEvent;
use Symfony\Component\HttpKernel\KernelEvents;
class Frontend implements EventSubscriberInterface
{
const EXTENSION_NAME = 'BstCatalogMode6';
/**
* @var SystemConfigService
*/
private $systemConfigService;
/** @var RouterInterface */
private $router;
/** @var LoggerInterface */
private $logger;
/**
* Frontend constructor.
* @param SystemConfigService $systemConfigService
* @param RouterInterface $router
* @param LoggerInterface $logger
*/
public function __construct(
SystemConfigService $systemConfigService,
RouterInterface $router,
LoggerInterface $logger
)
{
$this->systemConfigService = $systemConfigService;
$this->router = $router;
$this->logger = $logger;
}
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
StorefrontRenderEvent::class => 'onStorefrontRender',
ControllerArgumentsEvent::class => 'onControllerEvent',
ProductPageLoadedEvent::class => 'onProductPageLoaded',
];
}
/**
* @param SalesChannelContext $context
* @param boolean $asArray
* @return ConfigData
*/
private function getConfigData(SalesChannelContext $context, $asArray = false)
{
$config = new ConfigData($this->systemConfigService, $context);
if (!$config->enabled) {
return;
}
/** @var CustomerEntity $customer */
$customer = $context->getCustomer();
if ($customer !== null) {
$priceDisableGroup = false;
if (is_array($config->hidePriceCustomerGroups)) {
if (in_array($customer->getGroupId(), $config->hidePriceCustomerGroups)) {
$priceDisableGroup = true;
}
}
$checkoutDisableGroup = false;
if (is_array($config->hideCheckoutCustomerGroups)) {
if (in_array($customer->getGroupId(), $config->hideCheckoutCustomerGroups)) {
$checkoutDisableGroup = true;
}
}
$stockDisableGroup = false;
if (is_array($config->hideStockCustomerGroups)) {
if (in_array($customer->getGroupId(), $config->hideStockCustomerGroups)) {
$stockDisableGroup = true;
}
}
if ($config->showPricesAfterLogin && !$priceDisableGroup) {
$config->hidePrices = false;
}
if ($config->enableCheckoutAfterLogin && !$checkoutDisableGroup) {
$config->disableCheckout = false;
}
if ($config->enableStockAfterLogin && !$stockDisableGroup) {
$config->hideStock = false;
}
$config->showLoginButton = false;
}
if ($asArray) {
return $config->getConfig();
}
return $config;
}
/**
* @param StorefrontRenderEvent $event
*/
public function onStorefrontRender(StorefrontRenderEvent $event): void
{
$event->getContext()->addExtension(self::EXTENSION_NAME, $this->getConfigData($event->getSalesChannelContext()));
}
/**
* check if checkout is disabled
*
* @param ControllerArgumentsEvent $event
*/
public function onControllerEvent(ControllerArgumentsEvent $event): void
{
$controller = $event->getController();
if (is_array($controller)) {
$controller = $controller[0];
}
if ($controller instanceof CheckoutController) {
/** @var SalesChannelContext $context */
$context = $event->getRequest()->attributes->get(PlatformRequest::ATTRIBUTE_SALES_CHANNEL_CONTEXT_OBJECT);
$config = $this->getConfigData($context, true);
// only exist if config saved with activated setting for the first time
if (!isset($config['disableCheckout'])) {
return;
}
// disable checkout by forwarding to home
if ($config['disableCheckout']) {
if ($event->getRequest()->isXmlHttpRequest()) {
$event->setController(function() {
return new Response();
});
} else {
$event->setController(function() {
return new RedirectResponse($this->router->generate('frontend.home.page'));
});
}
}
}
}
/**
* assign zero prices to avoid price info in meta tag (source code)
*
* @param ProductPageLoadedEvent $event
*/
public function onProductPageLoaded(ProductPageLoadedEvent $event): void
{
if (!$config = $this->getConfigData($event->getSalesChannelContext())) {
return;
}
if (!$config->hidePrices) {
return;
}
$page = $event->getPage();
$product = $page->getProduct();
$priceCollection = new PriceCollection([]);
$product->setCalculatedPrices($priceCollection);
$calculatedPrice =$product->getCalculatedPrice();
$calculatedPrice->assign(['unitPrice' => 0, 'totalPrice' => 0]);
}
}