<?php
namespace CioSponsoredOrderConfirmation\Subscriber;
use CioProductCustomerInputs\Service\SessionService;
use Shopware\Core\Checkout\Cart\Error\IncompleteLineItemError;
use Shopware\Core\Checkout\Cart\Event\AfterLineItemAddedEvent;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
use Shopware\Core\Checkout\Cart\Event\CartChangedEvent;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Storefront\Framework\Routing\Router;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\RequestStack;
class AddToCartSubscriber implements EventSubscriberInterface
{
private ContainerInterface $container;
private Router $router;
private RequestStack $requestStack;
private SessionService $sessionService;
public function __construct(ContainerInterface $container, Router $router, RequestStack $requestStack, SessionService $sessionService)
{
$this->container = $container;
$this->router = $router;
$this->requestStack = $requestStack;
$this->sessionService = $sessionService;
}
public static function getSubscribedEvents()
{
return [
BeforeLineItemAddedEvent::class => 'onBeforeLineItemAddedEvent'
];
}
public function onBeforeLineItemAddedEvent(BeforeLineItemAddedEvent $event)
{
// Handle only product line items to avoid invalid referencedId filters (e.g. "frontend.cart.offcanvas")
if ($event->getLineItem()->getType() !== \Shopware\Core\Checkout\Cart\LineItem\LineItem::PRODUCT_LINE_ITEM_TYPE) {
return;
}
$lineItem = clone $event->getLineItem();
/** @var EntityRepositoryInterface $productRepository */
$productRepository = $this->container->get('product.repository');
$criteria = (new Criteria())->addFilter(new EqualsFilter('id', $lineItem->getReferencedId()));
/** @var ProductEntity|null $product */
$product = $productRepository->search($criteria, $event->getContext())->first();
if (!is_null($product) && is_array($product->getCustomFields())) {
$numberOfRows = $this->getCustomFieldValue($product, 'cio_customer_input_count_rows', 0);
$numberOfCells = count($this->getCustomFieldValue($product, 'cio_customer_input_general_group', []));
for ($row = 1; $row <= $numberOfRows; $row++) {
for ($cell = 1; $cell <= $numberOfCells; $cell++) {
$error = false;
$value = $this->sessionService->getCustomerInputFromSession($product->getProductNumber(), 'value', $row, $cell);
// 0 is a valid value
if (!is_numeric($value)) {
if (empty($value)) {
$error = true;
}
}
if ($error) {
if ($event->getCart()->has($event->getLineItem()->getId())) {
$event->getCart()->remove($event->getLineItem()->getId());
}
$event->getCart()->addErrors(new IncompleteLineItemError($event->getLineItem()->getReferencedId(), 'cioCustomInputError'));
if ($this->requestStack->getCurrentRequest()->request->has('cioAlternativeRedirectTo')) {
(new RedirectResponse(
$this->router->generate('frontend.detail.page', ['productId' => $event->getLineItem()->getId()])
))->send();
}
}
}
}
}
}
protected function getCustomFieldValue(ProductEntity $productEntity, $key, $default = null)
{
if (!is_array($productEntity->getCustomFields()) || !key_exists($key, $productEntity->getCustomFields())) {
return $default;
}
return $productEntity->getCustomFields()[$key];
}
}