<?php declare(strict_types=1);
namespace NewsletterSendinblue\Subscriber;
use Monolog\Logger;
use NewsletterSendinblue\Message\Category\CategorySyncMessage;
use NewsletterSendinblue\Service\BaseSyncService;
use NewsletterSendinblue\Service\ConfigService;
use NewsletterSendinblue\Service\Constant;
use NewsletterSendinblue\Traits\HelperTrait;
use Shopware\Core\Content\Category\CategoryEntity;
use Shopware\Core\Content\Category\CategoryEvents;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityDeletedEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
class CategorySubscriber implements EventSubscriberInterface
{
use HelperTrait;
/** @var BaseSyncService */
private $categorySyncService;
/** @var EntityRepositoryInterface */
private $systemConfigRepository;
/** @var ConfigService */
private $configService;
/** @var Logger */
private $logger;
/** @var MessageBusInterface */
private $messageBus;
/**
* @param BaseSyncService $categorySyncService
* @param EntityRepositoryInterface $systemConfigRepository
* @param ConfigService $configService
* @param Logger $logger
* @param MessageBusInterface $messageBus
*/
public function __construct(
BaseSyncService $categorySyncService,
EntityRepositoryInterface $systemConfigRepository,
ConfigService $configService,
Logger $logger,
MessageBusInterface $messageBus
)
{
$this->categorySyncService = $categorySyncService;
$this->systemConfigRepository = $systemConfigRepository;
$this->configService = $configService;
$this->logger = $logger;
$this->messageBus = $messageBus;
}
/**
* @return string[]
*/
public static function getSubscribedEvents()
{
return [
CategoryEvents::CATEGORY_TRANSLATION_WRITTEN_EVENT => 'onCategoryWrittenEvent',
CategoryEvents::CATEGORY_DELETED_EVENT => 'onCategoryDeletedEvent',
];
}
/**
* @param EntityDeletedEvent $event
* @return void
*/
public function onCategoryDeletedEvent(EntityDeletedEvent $event): void
{
$connectionId = $this->getAutoSyncConnectionId(
ConfigService::CONFIG_IS_CATEGORY_AUTO_SYNC_ENABLED,
$event->getContext()
);
if (empty($connectionId)) {
return;
}
foreach ($event->getWriteResults() as $writeResult) {
$categoryId = $writeResult->getPrimaryKey();
if (empty($categoryId)) {
continue;
}
$deleteCategories = $event->getContext()->hasExtension('brevoPreWriteEvent')
? $event->getContext()->getExtension('brevoPreWriteEvent')->get('deleteCategories')
: null;
if ($writeResult->getOperation() === EntityWriteResult::OPERATION_DELETE
&& !empty($deleteCategories)
&& isset($deleteCategories[$categoryId])
&& $deleteCategories[$categoryId] instanceof CategoryEntity
) {
foreach ($deleteCategories as $deleteCategory) {
if ($deleteCategory instanceof CategoryEntity) {
$this->categorySyncService->syncDelete($deleteCategory, $connectionId, $event->getContext());
}
}
$event->getContext()->getExtension('brevoPreWriteEvent')->set('deleteCategories', []);
$this->categorySyncService->setDeleteEntities([]);
break;
}
}
}
/**
* @param EntityWrittenEvent $event
* @return void
*/
public function onCategoryWrittenEvent(EntityWrittenEvent $event): void
{
$connectionId = $this->getAutoSyncConnectionId(
ConfigService::CONFIG_IS_CATEGORY_AUTO_SYNC_ENABLED,
$event->getContext()
);
if (empty($connectionId)) {
return;
}
$writeResultsCount = count($event->getWriteResults());
foreach ($event->getWriteResults() as $writeResult) {
$categoryId = $writeResult->getPrimaryKey()['categoryId'];
if (empty($categoryId)) {
continue;
}
// it is for avoiding call "sync" action when custom field is saved
if (!$this->checkChangeSet($writeResult)) {
continue;
}
if ($writeResult->getOperation() !== EntityWriteResult::OPERATION_DELETE) {
/** @var CategoryEntity $category */
$category = $this->categorySyncService->getEntity($categoryId, $event->getContext());
// Async processing
if ($writeResultsCount >= Constant::ASYNC_THRESHOLD) {
$this->messageBus->dispatch(new CategorySyncMessage(
$categoryId,
$connectionId,
$writeResult->getOperation(),
!$category->getActive(),
$event->getContext(),
!$category->getActive()
));
} else { // Sync processing
if (!$category->getActive()) {
$this->categorySyncService->syncDelete($category, $connectionId, $event->getContext(), true);
} else {
$this->categorySyncService->sync($categoryId, $connectionId, $event->getContext());
}
}
}
}
}
}