<?php
namespace Proclane\WegmannTheme\Subscriber;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepositoryInterface;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsAnyFilter;
use Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter;
use Shopware\Core\Framework\Struct\ArrayStruct;
use Shopware\Core\System\CustomField\CustomFieldEntity;
use Shopware\Core\System\Language\LanguageEntity;
use Shopware\Core\System\Locale\LocaleEntity;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Page\Product\ProductPageLoadedEvent;
use Shopware\Storefront\Pagelet\Footer\FooterPageletLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Psr\Log\LoggerInterface;
class ProductSubscriber implements EventSubscriberInterface
{
/**
* @var LoggerInterface
*/
private $loggerInterface;
private $technicalNameOfCustomFieldSet = 'custom_product_data';
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $languageRepository;
/**
* @var EntityRepositoryInterface
*/
private EntityRepositoryInterface $customFieldRepository;
/**
* @var SystemConfigService
*/
private SystemConfigService $systemConfigService;
/**
* Blacklist of technical properties which should not be displayed in storefront
*
* @var array|string[]
*/
private array $technicalPropertiesBlacklist = [
// 'custom_product_data_Verpackungstyp1',
// 'custom_product_data_GlobalerMaterialstatus',
// 'custom_product_data_SAPProdukthirarchie',
// 'custom_product_data_Rundungsmenge1',
// 'custom_product_data_Vertriebseinheit1',
];
/**
* @var array
*/
private array $customFields;
/**
* @var string
*/
private string $localeCode;
/**
* @param EntityRepositoryInterface $languageRepository
* @param EntityRepositoryInterface $customFieldRepository
* @param SystemConfigService $systemConfigService
*/
public function __construct(
EntityRepositoryInterface $languageRepository,
EntityRepositoryInterface $customFieldRepository,
SystemConfigService $systemConfigService)
{
$this->languageRepository = $languageRepository;
$this->customFieldRepository = $customFieldRepository;
$this->systemConfigService = $systemConfigService;
$this->loggerInterface = new Logger('ProcErrorLog');
try {
$this->loggerInterface->pushHandler(new StreamHandler(__DIR__ . '/../../../../../var/log/proc_error_log' . date("Y-m-d") . '.log'));
} catch (Exception $e) {
}
}
/**
* @return string[]
*/
public static function getSubscribedEvents()
{
return [
ProductPageLoadedEvent::class => 'onProductPageLoadedEvent',
];
}
/**
* @param ProductPageLoadedEvent $event
*/
public function onProductPageLoadedEvent(ProductPageLoadedEvent $event)
{
$this->generateTechnicalPropertiesBlackList();
$product = $event->getPage()->getProduct();
$this->customFields = $product->getCustomFields();
$arr_customFieldNames = [];
foreach ($this->customFields as $cfName => $cfValue) {
if (str_contains($cfName, $this->technicalNameOfCustomFieldSet)
&& !in_array($cfName, $this->technicalPropertiesBlacklist)) {
$arr_customFieldNames[] = $cfName;
} else {
unset($this->customFields[$cfName]);
}
}
$criteria = new Criteria();
$criteria->addFilter(new EqualsAnyFilter('name', $arr_customFieldNames));
/** @var CustomFieldEntity $customFieldEntities */
$customFieldEntities = $this->customFieldRepository->search($criteria, $event->getContext())->getElements();
$localeCodeDefault = $this->getLocaleCode($event->getContext()->getLanguageId(), $event->getContext());
$arr_finalCustomFieldsForStorefront = [];
/** @var CustomFieldEntity $customField */
foreach ($customFieldEntities as $customFieldEntity) {
$value = '';
$localeCode = null;
if ($customFieldEntity->getType() == 'select') {
$value = $this->getSelectFieldValues($customFieldEntity, $localeCodeDefault);
} else if (($customFieldEntity->getType() == 'checkbox') && ($this->customFields[$customFieldEntity->getName()] == false)){
continue;
} else {
$value = $this->customFields[$customFieldEntity->getName()];
}
if (!isset($customFieldEntity->getConfig()['label'][$localeCodeDefault])) {
$localeCode = "en-GB";
if (!isset($customFieldEntity->getConfig()['label'][$localeCode])) {
$localeCode = "de-DE";
}
}
if(!empty($value)) {
$arr_finalCustomFieldsForStorefront[] = [
'name' => $customFieldEntity->getConfig()['label'][$localeCode ?? $localeCodeDefault],
'value' => $value
];
}
}
$extensionStruct = new ArrayStruct(['fields' => $arr_finalCustomFieldsForStorefront]);
$event->getPage()->addExtension("productTechnicalInformation", $extensionStruct);
}
private function getSelectFieldValues(CustomFieldEntity $customFieldEntity, $localeCode)
{
$value = '';
$customFieldConfig = $customFieldEntity->getConfig();
$customFieldName = $customFieldEntity->getName();
$customFieldValue = $this->customFields[$customFieldName];
if (array_key_exists('options', $customFieldConfig) && !empty($customFieldConfig['options'])) {
for ($i = 0; $i < count($customFieldConfig['options']); $i++) {
if ($customFieldEntity->getConfig()['componentName'] == 'sw-multi-select' && is_array($this->customFields[$customFieldName])) {
for ($j = 0; $j < count($this->customFields[$customFieldName]); $j++) {
if ($customFieldConfig['options'][$i]['value'] == $customFieldValue[$j]) {
if (!empty($customFieldConfig['options'][$i]['label'][$localeCode])) {
$value .= $customFieldConfig['options'][$i]['label'][$localeCode] . ', ';
} else {
$value .= $customFieldConfig['options'][$i]['label']['de-DE'] . ', ';
}
}
}
} elseif ($customFieldEntity->getConfig()['componentName'] == 'sw-multi-select' && !is_array($this->customFields[$customFieldName])) {
$this->loggerInterface->info('Fehler im customField: ' . print_r($this->customFields[$customFieldName], true));
} else {
if ($customFieldConfig['options'][$i]['value'] == $customFieldValue) {
if (!empty($customFieldConfig['options'][$i]['label'][$localeCode])) {
$value = $customFieldConfig['options'][$i]['label'][$localeCode] . ', ';
} else {
$value .= $customFieldConfig['options'][$i]['label']['de-DE'] . ', ';
}
}
}
}
}
$value = substr($value, 0, -2);
return $value;
}
/**
* Generate the blacklist of properties that should not be shown in the storefront
*
* @return void
*/
private function generateTechnicalPropertiesBlackList()
{
$pluginConfig = $this->systemConfigService->get('ProclaneWegmannTheme.config.customFieldsToHideInSpecifications');
$criteria = new Criteria();
$criteria->addFilter(new EqualsAnyFilter('id', $pluginConfig));
$customFieldEntities = $this->customFieldRepository->search($criteria, Context::createDefaultContext())->getElements();
/** @var CustomFieldEntity $entity */
foreach ($customFieldEntities as $entity) {
$this->technicalPropertiesBlacklist[] = $entity->getName();
}
}
/**
* Get locale code from database
*
* @param string $languageId
* @param Context $context
* @return string
*/
private function getLocaleCode(string $languageId, Context $context): string
{
$criteria = new Criteria();
$criteria->addFilter(new EqualsFilter('id', $languageId));
$criteria->addAssociation('locale');
/** @var LanguageEntity $languageEntity */
$languageEntity = $this->languageRepository->search($criteria, $context)->first();
return $languageEntity->getLocale()->getCode();
}
}