<?php declare(strict_types=1);
namespace GrimmSorting\Subscriber;
use Enqueue\Util\UUID;
use GrimmSorting\Service\SortingPreserver;
use Shopware\Core\Content\Product\Aggregate\ProductCategory\ProductCategoryDefinition;
use Shopware\Core\Content\Product\ProductEvents;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\DeleteCommand;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\InsertCommand;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Validation\PreWriteValidationEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Write\Command\ChangeSetAware;
use Doctrine\DBAL\Connection;
class ProductCategoryTree implements EventSubscriberInterface
{
/**
* @var SortingPreserver
*/
private SortingPreserver $sortingPreserver;
/**
* @var Connection
*/
private Connection $connection;
private $productCategoryTables = [
'product_category',
'product_category_tree'
];
public function __construct(Connection $connection, SortingPreserver $sortingPreserver)
{
$this->sortingPreserver = $sortingPreserver;
$this->connection = $connection;
}
public static function getSubscribedEvents()
{
return [
PreWriteValidationEvent::class => 'beforeDelete',
];
}
/**
* Before the product_category AND product_category_tree entries are deleted load the entries
* and store them in the SortingPreserver to keep the positions
*
* @param PreWriteValidationEvent $event
*
* @throws \Doctrine\DBAL\Driver\Exception
* @throws \Doctrine\DBAL\Exception
*/
public function beforeDelete(PreWriteValidationEvent $event): void
{
foreach ($event->getCommands() as $command) {
if ($command instanceof DeleteCommand || $command instanceof InsertCommand) {
if ($command->getDefinition() instanceof ProductCategoryDefinition) {
$existence = $command->getEntityExistence()->getPrimaryKey();
$productId = false;
if (!array_key_exists('product_id', $existence)) {
$primaryKey = $command->getPrimaryKey();
if (array_key_exists('product_id', $primaryKey)) {
$productId = \Shopware\Core\Framework\Uuid\Uuid::fromBytesToHex($primaryKey['product_id']);
}
} else {
$productId = $existence['product_id'];
}
$statement = $this->connection->prepare('SELECT HEX(product_id) AS product_id, HEX(category_id) AS category_id, swpa_sorting FROM product_category WHERE product_id = UNHEX(:product_id)');
$statement->bindParam('product_id', $productId);
if ($statement->execute()) {
$sortings = $statement->fetchAllAssociative();
$preservable = [];
foreach ($sortings as $sorting) {
if ((int)$sorting['swpa_sorting'] !== 99999) {
$preservable[] = $sorting;
}
}
$this->sortingPreserver->setSorting($preservable);
}
}
}
}
}
}