<?php declare(strict_types=1);
namespace Acris\CmsPreConfig\Subscriber;
use Shopware\Core\Content\Cms\Aggregate\CmsSlot\CmsSlotEntity;
use Shopware\Core\Content\Cms\CmsPageEvents;
use Shopware\Core\Content\Cms\DataResolver\FieldConfig;
use Shopware\Core\Defaults;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CmsSlotWrittenSubscriber implements EventSubscriberInterface
{
const ACRIS_SLOT_TRANSLATION_KEY = 'acrisTranslation';
// custom fields which should be merged for default languages
const DEFAULT_LANGUAGE_CUSTOM_FIELDS = [
'position',
'acrisCmsSlot'
];
private EntityRepository $slotRepository;
public function __construct(
EntityRepository $slotRepository
)
{
$this->slotRepository = $slotRepository;
}
public static function getSubscribedEvents(): array
{
return [
CmsPageEvents::SLOT_WRITTEN_EVENT => 'onSlotWrittenEvent'
];
}
public function onSlotWrittenEvent(EntityWrittenEvent $event): void
{
$results = $event->getWriteResults();
foreach ($results as $result) {
$payload = $result->getPayload();
if (!empty($payload) && array_key_exists('id', $payload) && !empty($payload['id'])) {
$slotId = $payload['id'];
/** @var CmsSlotEntity $cmsSlot */
$cmsSlot = $this->slotRepository->search(new Criteria([$slotId]), $event->getContext())->first();
if (empty($cmsSlot)) continue;
$configArray = [];
$translations = [];
foreach ($cmsSlot->getFieldConfig()->getElements() as $configKey => $element) {
if ($element instanceof FieldConfig) {
if ($configKey === self::ACRIS_SLOT_TRANSLATION_KEY) {
$translations = $element->getArrayValue();
foreach ($translations as $key => $translation) {
if (is_array($translation) && array_key_exists('languageId', $translation) && $translation['languageId'] === $event->getContext()->getLanguageId()) {
unset($translations[$key]);
} else {
// remove acrisTranslations to prevent problems on further usage
if(array_key_exists('config', $translation) && is_array($translation['config'])
&& array_key_exists(self::ACRIS_SLOT_TRANSLATION_KEY, $translation['config'])) {
unset($translations[$key]['config'][self::ACRIS_SLOT_TRANSLATION_KEY]);
}
// compatibility with AcrisCms slot position
if (is_array($translation) && array_key_exists('languageId', $translation) && $translation['languageId'] === Defaults::LANGUAGE_SYSTEM) {
$this->mergeDefaultCustomFields($cmsSlot, $translations[$key]);
}
}
}
} else {
$configArray[$configKey] = $element->getVars();
if (array_key_exists('name', $configArray[$configKey])) {
unset($configArray[$configKey]['name']);
}
if (array_key_exists('extensions', $configArray[$configKey])) {
unset($configArray[$configKey]['extensions']);
}
}
}
}
if (!empty($translations)) {
$this->slotRepository->upsert([
[
'id' => $slotId,
'config' => $configArray,
'translations' => $translations
]
], $event->getContext());
}
}
}
}
private function mergeDefaultCustomFields(CmsSlotEntity $cmsSlot, array &$translation): void
{
foreach (self::DEFAULT_LANGUAGE_CUSTOM_FIELDS as $customField) {
if(is_array($cmsSlot->getTranslation('customFields')) && array_key_exists($customField, $cmsSlot->getTranslation('customFields'))) {
if(!array_key_exists('customFields', $translation) || !is_array($translation['customFields'])) {
$translation['customFields'] = [];
}
$translation['customFields'][$customField] = $cmsSlot->getTranslation('customFields')[$customField];
}
}
}
}