<?php declare(strict_types=1);
namespace Tonur\GiftOption\Subscriber;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
use Shopware\Core\Checkout\Cart\Event\CheckoutOrderPlacedEvent;
use Shopware\Core\Content\Product\SalesChannel\Detail\AbstractProductDetailRoute;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Sorting\FieldSorting;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\System\SalesChannel\SalesChannelContext;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Event\StorefrontRenderEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RequestStack;
use Tonur\GiftOption\Service\GiftWrapService;
use Tonur\GiftOption\TonurGiftWrap;
class GiftOptionSubscriber implements EventSubscriberInterface
{
/**
* @var RequestStack
*/
private $requestStack;
/**
* @var GiftWrapService
*/
private $giftWrapService;
/**
* @var AbstractProductDetailRoute
*/
private $productRoute;
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var EntityRepositoryInterface
*/
private $orderRepository;
public function __construct(
RequestStack $requestStack,
GiftWrapService $giftWrapService,
AbstractProductDetailRoute $productRoute,
SystemConfigService $systemConfigService,
EntityRepositoryInterface $orderRepository
)
{
$this->requestStack = $requestStack;
$this->giftWrapService = $giftWrapService;
$this->productRoute = $productRoute;
$this->systemConfigService = $systemConfigService;
$this->orderRepository = $orderRepository;
}
public static function getSubscribedEvents()
{
return [
BeforeLineItemAddedEvent::class => 'onBeforeLineItemAdded',
StorefrontRenderEvent::class => 'onStorefrontRender',
CheckoutOrderPlacedEvent::class => 'onCheckoutOrderPlaced',
];
}
public function onBeforeLineItemAdded(BeforeLineItemAddedEvent $event): void
{
$config = $this->getPluginConfiguration($event->getSalesChannelContext());
if (!$config['pluginActive']) {
return;
}
$lineItem = $event->getLineItem();
$lineItemId = $lineItem->getId();
$currentRequest = $this->requestStack->getCurrentRequest();
if ($currentRequest !== null && is_array($currentRequest->get('lineItems'))) {
foreach ($currentRequest->get('lineItems') as $key => $item) {
if ($lineItemId === $key && isset($item['repertusShouldWrap'])) {
if (!$this->giftWrapService->isLineItemPackable($lineItem, $event->getSalesChannelContext())) {
continue;
}
$repertusShouldWrap = filter_var($item['repertusShouldWrap'], FILTER_VALIDATE_BOOLEAN);
$lineItem->setPayloadValue('repertusShouldWrap', $repertusShouldWrap);
}
}
}
}
/**
* @param StorefrontRenderEvent $event
* @throws \Shopware\Core\Content\Product\Exception\ProductNotFoundException
* @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
* @codeCoverageIgnore
*/
public function onStorefrontRender(StorefrontRenderEvent $event): void
{
$config = $this->getPluginConfiguration($event->getSalesChannelContext());
if (!$config['pluginActive']) {
return;
}
if (strpos($event->getView(), 'storefront/page/checkout/cart/index.html.twig') !== false ||
strpos($event->getView(), 'storefront/page/checkout/confirm/index.html.twig') !== false) {
$event->setParameter(
'repertusGiftOptionCartIsWrapped',
$this->giftWrapService->checkIfCartIsWrapped($event->getSalesChannelContext())
);
$event->setParameter(
'repertusGiftOptionCartHasWrappedProduct',
$this->giftWrapService->checkIfCartContainsWrappedProduct($event->getSalesChannelContext())
);
$salesChannelContext = $event->getSalesChannelContext();
$giftWraps = $this->giftWrapService->getGiftWrapsForSalesChannel($salesChannelContext);
$products = [];
$criteria = (new Criteria())
->addAssociation('manufacturer.media')
->addAssociation('options.group')
->addAssociation('properties.group')
->addAssociation('mainCategories.category');
$criteria
->getAssociation('media')
->addSorting(new FieldSorting('position'));
foreach ($giftWraps as $giftWrap) {
$result = $this->productRoute->load($giftWrap->getProductId(), new Request(), $salesChannelContext, $criteria);
$products[$giftWrap->getId()] = $result->getProduct();
}
$event->setParameter('repertusGiftWraps', $products);
$event->setParameter('repertusGiftWrapContainerId', Uuid::randomHex());
}
}
public function onCheckoutOrderPlaced(CheckoutOrderPlacedEvent $event): void
{
$config = $this->getPluginConfiguration(null);
if (!$config['pluginActive']) {
return;
}
$request = $this->requestStack->getCurrentRequest();
if ($request !== null) {
$noInvoice = $request->request->get('repertusNoInvoice');
if ($noInvoice !== null) {
$order = $event->getOrder();
$customFields = $order->getCustomFields() ?? [];
$customFields['tonur_no_invoice'] = filter_var($noInvoice, FILTER_VALIDATE_BOOLEAN);
$this->orderRepository->upsert([
[
'id' => $order->getId(),
'customFields' => $customFields
]
], $event->getContext());
}
}
}
protected function getPluginConfiguration(?SalesChannelContext $context): array
{
return $this->systemConfigService->get(TonurGiftWrap::BUNDLE_NAME . '.config', $context ? $context->getSalesChannel()->getId() : null);
}
}