<?php declare(strict_types=1);
namespace Tds\MerwareDiscounts\Core\Exchange\Import\Product\Subscriber;
use Shopware\Core\Content\Product\ProductEntity;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Exception\InconsistentCriteriaIdsException;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Tds\Merware\Core\Exchange\Import\Event\Product\ProductsWrittenEvent;
use Tds\Merware\Core\Exchange\Import\Struct\Product\ProductStruct;
use Tds\Merware\Service\Core\LanguageMappingService;
/**
* Class ProductsWrittenSubscriber
*
* @package Tds\MerwareDiscounts\Core\Exchange\Import\Product\Subscriber
*/
class ProductsWrittenSubscriber implements EventSubscriberInterface
{
/**
* @var SystemConfigService
*/
private $systemConfigService;
/**
* @var EntityRepositoryInterface
*/
private $productRepository;
/**
* @var LanguageMappingService
*/
private $languageMappingService;
/**
* @return array
*/
public static function getSubscribedEvents(): array
{
return [
ProductsWrittenEvent::class => 'onProductsWritten'
];
}
/**
* ProductsWrittenSubscriber constructor
*
* @param SystemConfigService $systemConfigService
* @param EntityRepositoryInterface $productRepository
*/
public function __construct(SystemConfigService $systemConfigService, EntityRepositoryInterface $productRepository, LanguageMappingService $languageMappingService)
{
$this->systemConfigService = $systemConfigService;
$this->productRepository = $productRepository;
$this->languageMappingService = $languageMappingService;
}
/**
* Event function to catch saved products.
*
* @param ProductsWrittenEvent $event
*
* @throws InconsistentCriteriaIdsException
*/
public function onProductsWritten(ProductsWrittenEvent $event)
{
$productStructs = $event->getProductStructs();
if (!empty($productStructs)) {
$this->updateDiscountableProducts($event->getContext(), $productStructs);
}
}
/**
* Helper-function to update discountable products.
*
* @param Context $context
* @param ProductStruct[] $productStructs
*/
private function updateDiscountableProducts($context, $productStructs)
{
$requests = $this->buildDiscountRequests($context, $productStructs);
if (!empty($requests)) {
$this->productRepository->update($requests, $context);
}
}
/**
* Helper-function to build valid DAL requests to update custom field data.
*
* @param Context $context
* @param ProductStruct[] $productStructs
*
* @return array
*/
private function buildDiscountRequests($context, $productStructs)
{
$requests = [];
foreach ($productStructs as $productStruct) {
/**
* required step to avoid external custom field overrides!
*/
$customFields = $this->getProductCustomFields($context, $productStruct->getUuid());
$customFields['tds_merware_product_discount_activate'] = (bool) $productStruct->getDiscountable();
$customFieldTranslations = [];
$translations = $productStruct->getTranslations();
if (!empty($translations)) {
foreach ($translations as $translation) {
$isoCode = $this->languageMappingService->getIsoByLanguageCode($translation->getCode());
if (!empty($isoCode)) {
$customFieldTranslations[$isoCode] = [
'customFields' => $customFields
];
}
}
}
$requests[] = [
'id' => $productStruct->getUuid(),
'customFields' => $customFields,
'translations' => $customFieldTranslations
];
}
return $requests;
}
/**
* Helper-function to get product custom fields.
*
* @param Context $context
* @param string $productId
*
* @return array|null
*/
private function getProductCustomFields($context, $productId)
{
$customFields = [];
$criteria = new Criteria([$productId]);
$result = $this->productRepository->search($criteria, $context)->first();
/**
* @var ProductEntity $result
*/
if (!empty($result)) {
$customFields = $result->getCustomFields();
}
return $customFields;
}
}