<?php declare(strict_types=1);
namespace Kilb\KilbShopwareProductDesigner\Subscriber;
use Kilb\KilbShopwareProductDesigner\Constants;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
use Shopware\Core\Checkout\Cart\LineItem\LineItem;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
class CartSubscriber implements EventSubscriberInterface
{
private const POST_KEY_LINE_ITEMS = 'lineItems';
/**
* @return string[]
*/
public static function getSubscribedEvents(): array
{
return[
BeforeLineItemAddedEvent::class => 'onBeforeLineItemAdded',
];
}
/**
* @param BeforeLineItemAddedEvent $event
* @throws \Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException
*/
public function onBeforeLineItemAdded(BeforeLineItemAddedEvent $event): void
{
$cart = $event->getCart();
$lineItemAdded = $event->getLineItem();
$lineItemIds = $this->getLineItemIds($lineItemAdded);
$requestLineItems = $this->getRequestLineItems();
$requestLineItem = $this->getRequestLineItem($lineItemIds, $requestLineItems);
$groupSecret = $requestLineItem[Constants::LINE_ITEM_PAYLOAD_KEY_GROUP_SECRET] ?? null;
$basketImageUrl = $requestLineItem[Constants::LINE_ITEM_PAYLOAD_KEY_BASKET_IMAGE_URL] ?? null;
if (empty($groupSecret) || empty($basketImageUrl)) {
return;
}
$cart->remove($lineItemAdded->getId());
$this->setPayloadRecursively($lineItemAdded, $groupSecret, $basketImageUrl);
$this->updateLineItemId($lineItemAdded, $basketImageUrl);
$cart->add($lineItemAdded);
}
/**
* @param LineItem $lineItem
* @param string $groupSecret
* @param string $basketImageUrl
* @return void
*/
private function setPayloadRecursively(LineItem $lineItem, string $groupSecret, string $basketImageUrl): void
{
$lineItem->setPayloadValue(Constants::LINE_ITEM_PAYLOAD_KEY_GROUP_SECRET, $groupSecret);
$lineItem->setPayloadValue(Constants::LINE_ITEM_PAYLOAD_KEY_BASKET_IMAGE_URL, $basketImageUrl);
foreach ($lineItem->getChildren() as $child) {
$this->setPayloadRecursively($child, $groupSecret, $basketImageUrl);
}
}
/**
* @param LineItem $lineItem
* @param string $basketImageUrl
*
* @return void
*/
private function updateLineItemId(LineItem $lineItem, string $basketImageUrl): void
{
$lineItemId = md5($lineItem->getId() . '-' . $basketImageUrl);
$lineItem->setId($lineItemId);
}
/**
* @param string[] $lineItemIds
* @param array<string,array<string,string>> $requestLineItems
*
* @return array<string,string>
*/
private function getRequestLineItem(array $lineItemIds, array $requestLineItems): array
{
foreach ($requestLineItems as $lineItemId => $lineItem) {
if (in_array($lineItemId, $lineItemIds)) {
return $lineItem;
}
}
return [];
}
/**
* @return array<string,array<string,string>>
*/
private function getRequestLineItems(): array
{
$request = Request::createFromGlobals();
$requestParams = $request->request->all();
if (empty($requestParams[self::POST_KEY_LINE_ITEMS])) {
return [];
}
return (array)$requestParams[self::POST_KEY_LINE_ITEMS];
}
/**
* @return string[]
*/
private function getLineItemIds(LineItem $lineItem): array
{
$lineItemIds = [];
$lineItemIds[] = $lineItem->getId();
if ($lineItem->getReferencedId()) {
$lineItemIds[] = $lineItem->getReferencedId();
}
foreach ($lineItem->getChildren() as $child) {
$lineItemIds = array_merge($lineItemIds, $this->getLineItemIds($child));
}
return array_unique($lineItemIds);
}
}