<?php declare(strict_types=1);
namespace Okeonline\KejeRemoveProductsHotfix\Core\Subscribers;
use Doctrine\DBAL\Connection;
use Shopware\Core\Checkout\Order\Aggregate\OrderLineItem\OrderLineItemDefinition;
use Shopware\Core\Content\Product\ProductDefinition;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\DeleteCommand;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\SetNullOnDeleteCommand;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PreWriteValidationEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class RemoveOrderLineLinksBeforeProductDeleteEventSubscriber implements EventSubscriberInterface
{
/** @var Connection $connection */
private $connection;
public function __construct(
Connection $connection
)
{
$this->connection = $connection;
}
public static function getSubscribedEvents(): array
{
return [
PreWriteValidationEvent::class => ['removeOrderLineItemLinks', 0]
];
}
public function removeOrderLineItemLinks(PreWriteValidationEvent $event)
{
// get and check main command
if( ! $mainCommand = $this->checkIfMainCommandIsProductDeleteCommand($event->getCommands()))
return;
$productPrimaryKeys = $mainCommand->getPrimaryKey();
// get the key (and check if situation exists) of the setNullOnDeleteCommand for OrderLineItems on productDeletion
if( ! $removeArrayKey = $this->checkIfOrderlineCascadeDeleteIsSet($event->getCommands()))
return;
dump($removeArrayKey);
// unset the key for the OrderLine-command, preventing the query that can be enourmous and problematic
unset($event->getCommands()[$removeArrayKey]);
// manually execute the setNullOnDeleteCommand
$this->connection->executeUpdate(
'UPDATE `order_line_item` SET product_id = null, product_version_id = null WHERE product_id = :deletedProductId;',
[
'deletedProductId' => $productPrimaryKeys['id'],
'deletedProductVersionId' => $productPrimaryKeys['version_id'],
]
);
}
private function checkIfMainCommandIsProductDeleteCommand(array $commands)
{
/** @var DeleteCommand $command */
foreach($commands as $command)
{
if($command instanceof DeleteCommand && $command->getDefinition() instanceof ProductDefinition)
return $command;
}
return false;
}
private function checkIfOrderlineCascadeDeleteIsSet(array $commands)
{
/** @var SetNullOnDeleteCommand $command */
foreach($commands as $key => $command)
{
if($command instanceof SetNullOnDeleteCommand && $command->getDefinition() instanceof OrderLineItemDefinition)
return $key;
}
return false;
}
}