<?php
/**
* @copyright 2023 Crehler Sp. z o.o.
*
* https://crehler.com/
* support@crehler.com
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Crehler\AdvancedSort\Subscriber;
use Crehler\AdvancedSort\Services\Indexer\CategoryItemsUpdaterInterface;
use Crehler\AdvancedSort\Services\PropagatePositionService;
use Doctrine\DBAL\Connection;
use Doctrine\DBAL\Driver\Exception;
use Monolog\Logger;
use Shopware\Core\Content\Category\Event\CategoryIndexerEvent;
use Shopware\Core\Content\Product\Events\ProductIndexerEvent;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\Uuid\Uuid;
use Shopware\Core\Profiling\Profiler;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class IndexerSubscriber implements EventSubscriberInterface
{
private EntityRepository $productRepository;
private Logger $crehlerAdvancedSortLogger;
private CategoryItemsUpdaterInterface $categoryItemsUpdater;
private Connection $connection;
private PropagatePositionService $propagatePositionService;
public function __construct(EntityRepository $productRepository, Logger $crehlerAdvancedSortLogger, CategoryItemsUpdaterInterface $categoryItemsUpdater, Connection $connection, PropagatePositionService $propagatePositionService)
{
$this->productRepository = $productRepository;
$this->crehlerAdvancedSortLogger = $crehlerAdvancedSortLogger;
$this->categoryItemsUpdater = $categoryItemsUpdater;
$this->connection = $connection;
$this->propagatePositionService =$propagatePositionService;
}
public static function getSubscribedEvents()
{
return [
// CategoryIndexerEvent::class => 'onCategoryIndexer',
ProductIndexerEvent::class => 'onProductIndexer',
];
}
public function onCategoryIndexer(CategoryIndexerEvent $event)
{
$this->crehlerAdvancedSortLogger->info('Indexer Subscriber onCategoryIndexer');
Profiler::trace('crehler-advanced-sort::indekser::category', function () use ($event) {
$this->updateByCategory($event->getIds(), $event->getContext());
});
// $this->propagatePositionService->inheritPositionsOnIndexer($event->getIds());
}
/**
* Błędne założenie, jeśli ustawimy sortowanie dla root kategorii to przy każdym produkcie będzie się wykonywać na tej kategorii
*
* @throws Exception
* @throws \Doctrine\DBAL\Exception
*/
public function onProductIndexer(ProductIndexerEvent $event)
{
return;
$this->crehlerAdvancedSortLogger->info('Indexer Subscriber onProductIndexer');
Profiler::trace('crehler-advanced-sort::indekser::product', function () use ($event) {
$categories = [];
foreach ($event->getIds() as $id) {
$categories = array_merge($categories, $this->getCategoriesByProduct($id));
}
$this->updateByCategory($categories, $event->getContext());
});
}
private function updateByCategory(array $categories, Context $context)
{
$categories = array_filter(array_unique($categories));
foreach ($categories as $category) {
$this->crehlerAdvancedSortLogger->info('Indexer Subscriber updateByCategory ' . $category);
}
$this->categoryItemsUpdater->update($categories, $context);
}
/**
* @throws Exception
* @throws \Doctrine\DBAL\Exception
*/
private function getCategoriesByProduct(string $productId): array
{
try {
$result = $this->connection
->createQueryBuilder()
->select('LOWER(HEX(category_id))')
->from('product_category')
->where('product_id = :productId')
->setParameter('productId', Uuid::fromHexToBytes($productId))
->execute()
->fetchFirstColumn();
} catch (\Throwable $exception) {
return [];
}
return $result ?? [];
}
}