<?php
/**
* Dieser Quellcode ist geistiges Eigentum der Weblizards GmbH
* und darf ohne vorheriges schriftliches Einverständnis nicht
* vervielfältigt werden.
*
* @copyright Copyright (c) Weblizards GmbH <https://www.weblizards.de>
* @license https://www.gnu.org/licenses/gpl-3.0 GPLv3
*/
namespace App\EventListener;
use Pimcore\Model\DataObject;
use Pimcore\Model\DataObject\ClassDefinition;
use Symfony\Component\EventDispatcher\GenericEvent;
class AdminLayoutModificationListener
{
public function onObjectGetPreSendData(GenericEvent $event)
{
/** @var array $data */
$data = $event->getArgument('data');
if (($data['currentLayoutId'] ?? null) == -1) {
// admin layout, don't modify anything
return;
}
/** @var DataObject $object */
$object = $event->getArgument('object');
$layout = $data['layout'] ?? null;
if (! $layout instanceof ClassDefinition\Layout) {
// sanity check, get out
return;
}
if ($object instanceof DataObject\Erpitem && $object->getMadeByImport()) {
if (($erpLayout = $this->findClassDefinitionLayoutInLayout($layout, 'Basics')) !== null) {
$this->modifyDefinitionDataInLayout($object, $erpLayout, static function (DataObject\Erpitem $erpItem, ClassDefinition\Data $item) {
// never disable the override fields
if ($item->getName() == 'madeByImport' || str_ends_with($item->getName(), 'Override')) {
return;
}
// don't disable overridden fields
foreach (['drainWeight', 'weightBrutto', 'weightNetto', 'packageType'] as $fieldName) {
if ($item->getName() == $fieldName && $erpItem->{'get'.ucfirst($fieldName).'Override'}()) {
return;
}
}
$item->setNoteditable(true);
});
}
} elseif ($object instanceof DataObject\Product) {
// Different custom layouts for object and variant for markets DACH and EAST
// https://papayawhip-important-idols.awork.io/tasks/f829491f-9927-ed11-ae83-14cb65275e5b/details
if (preg_match('~^/Products/(?<market>.*?)/~', $object->getPath(), $matches)) {
$layoutId = $matches['market'] . (($object->getType() == DataObject\AbstractObject::OBJECT_TYPE_VARIANT) ? 'VAR' : 'OBJ');
$data = $this->doModifyCustomLayouts($data, $object, $layoutId);
}
}
$event->setArgument('data', $data);
}
/**
* @param ClassDefinition\Layout $layout
* @param string $name
*
* @return ClassDefinition\Data|null
*/
protected function findClassDefinitionDataInLayout(ClassDefinition\Layout $layout, string $name): ?ClassDefinition\Data
{
foreach ($layout->getChildren() as $item) {
if ($item instanceof ClassDefinition\Data && $item->getName() == $name) {
return $item;
} elseif ($item instanceof ClassDefinition\Layout) {
if (($data = $this->findClassDefinitionDataInLayout($item, $name)) !== null) {
return $data;
}
} elseif ($item instanceof ClassDefinition\Data\Localizedfields) {
foreach ($item->getChildren() as $localizedItem) {
if ($localizedItem instanceof ClassDefinition\Data && $localizedItem->getName() == $name) {
return $localizedItem;
}
}
}
}
return null;
}
/**
* @param DataObject\Concrete $object
* @param ClassDefinition\Layout $layout
* @param callable $callback
*
* @return void
*/
protected function modifyDefinitionDataInLayout(DataObject\Concrete $object, ClassDefinition\Layout $layout, callable $callback)
{
foreach ($layout->getChildren() as $item) {
if ($item instanceof ClassDefinition\Data\Localizedfields) {
foreach ($item->getChildren() as $localizedItem) {
if ($localizedItem instanceof ClassDefinition\Data) {
$callback($object, $localizedItem);
}
}
} elseif ($item instanceof ClassDefinition\Data) {
$callback($object, $item);
} elseif ($item instanceof ClassDefinition\Layout) {
$this->modifyDefinitionDataInLayout($object, $item, $callback);
}
}
}
/**
* @param ClassDefinition\Layout $layout
* @param string $name
*
* @return ClassDefinition\Layout|null
*/
protected function findClassDefinitionLayoutInLayout(ClassDefinition\Layout $layout, string $name): ?ClassDefinition\Layout
{
if ($layout->getName() == $name) {
return $layout;
}
foreach ($layout->getChildren() as $item) {
if ($item instanceof ClassDefinition\Layout) {
if (($data = $this->findClassDefinitionLayoutInLayout($item, $name)) !== null) {
return $data;
}
}
}
return null;
}
/**
* Modify custom layouts
*
* Taken from https://pimcore.com/docs/pimcore/current/Development_Documentation/Best_Practice/Showing_Custom_Layouts_based_on_Object_Data.html
*
* @param array $data
* @param DataObject\Concrete $object
* @param string|null $customLayoutToSelect
* @param array $layoutsToRemove
*
* @return array
*/
private function doModifyCustomLayouts(array $data, DataObject\Concrete $object, string $customLayoutToSelect = null, array $layoutsToRemove = [])
{
if ($customLayoutToSelect != null) {
if (($customLayout = ClassDefinition\CustomLayout::getById($customLayoutToSelect)) === null) {
// NOTE: don't throw an exception but keep default layout
// https://papayawhip-important-idols.awork.io/tasks/3269cb00-3e7e-4ebc-be77-cc5637bfaec9/details
return $data;
}
$data['currentLayoutId'] = $customLayoutToSelect;
$data['layout'] = $customLayout->getLayoutDefinitions();
DataObject\Service::enrichLayoutDefinition($data['layout'], $object);
}
if (!empty($layoutsToRemove)) {
$validLayouts = $data['validLayouts'];
foreach ($validLayouts as $key => $validLayout) {
if (in_array($validLayout['id'], $layoutsToRemove)) {
unset($validLayouts[$key]);
}
}
$data['validLayouts'] = array_values($validLayouts);
}
return $data;
}
}