<?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); } } } } }}