<?php
declare(strict_types=0);
/*
* WellCommerce Foundation
*
* This file is part of the WellCommerce package.
*
* (c) Adam Piotrowski <adam@wellcommerce.org>, Adrian Potepa <adrian@wellcommerce.org>
*
* For the full copyright and license information,
* please view the LICENSE file that was distributed with this source code.
*/
namespace WellCommerce\Bundle\AppBundle\EventListener;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\PropertyAccess\PropertyAccess;
use WellCommerce\Bundle\AppBundle\Entity\LayoutBox;
use WellCommerce\Bundle\AppBundle\Service\Shop\Storage\ShopStorage;
use WellCommerce\Bundle\CoreBundle\Doctrine\Event\EntityEvent;
use WellCommerce\Bundle\CoreBundle\Helper\Request\RequestHelper;
use WellCommerce\Component\Form\Event\FormEvent;
use WellCommerce\Component\Layout\Configurator\LayoutBoxConfiguratorCollection;
use WellCommerce\Component\Layout\Configurator\LayoutBoxConfiguratorInterface;
/**
* Class LayoutBoxSubscriber
*
* @author Adam Piotrowski <adam@wellcommerce.org>
*/
class LayoutBoxSubscriber implements EventSubscriberInterface
{
/**
* @var ShopStorage
*/
protected $shopStorage;
/**
* @var RequestHelper
*/
protected $requestHelper;
/**
* @var LayoutBoxConfiguratorCollection
*/
protected $configuratorCollection;
public function __construct(ShopStorage $shopStorage, RequestHelper $requestHelper, LayoutBoxConfiguratorCollection $collection)
{
$this->shopStorage = $shopStorage;
$this->requestHelper = $requestHelper;
$this->configuratorCollection = $collection;
}
public static function getSubscribedEvents()
{
return [
'admin.layout_box.pre_form_init' => 'onLayoutBoxFormInit',
'layout_box.pre_create' => 'onLayoutBoxPreCreate',
'layout_box.pre_update' => 'onLayoutBoxPreUpdate',
'layout_box.post_init' => 'onLayoutBoxPostInit',
];
}
/**
* Adds configurator fields to main layout box edit form.
* Loops through all configurators, renders the fieldset and sets default data
*
* @param FormEvent $event
*/
public function onLayoutBoxFormInit(FormEvent $event)
{
$builder = $event->getFormBuilder();
$form = $event->getForm();
$configurators = $this->configuratorCollection->all();
$resource = $event->getResource();
$settings = $resource->getSettings();
foreach ($configurators as $configurator) {
if ($configurator instanceof LayoutBoxConfiguratorInterface) {
$defaults = [];
if ($resource->getBoxType() == $configurator->getType()) {
$defaults = $settings;
}
$configurator->addFormFields($builder, $form, $defaults);
}
}
}
public function onLayoutBoxPreCreate(EntityEvent $event)
{
$resource = $event->getEntity();
if ($resource instanceof LayoutBox) {
$request = $this->requestHelper->getCurrentRequest();
$settings = $this->getBoxSettingsFromRequest($request);
$resource->setSettings($settings);
$this->syncExtraTranslations($resource);
}
}
public function onLayoutBoxPreUpdate(EntityEvent $event)
{
$resource = $event->getEntity();
if ($resource instanceof LayoutBox) {
$request = $this->requestHelper->getCurrentRequest();
$settings = $this->getBoxSettingsFromRequest($request);
$settings = $this->mergeUnmodifiedSettings($resource->getSettings(), $settings);
$resource->setSettings($settings);
$this->syncExtraTranslations($resource);
}
}
protected function syncExtraTranslations(LayoutBox $layoutBox)
{
$translations = $layoutBox->getSettings()['translations'] ?? [];
foreach ($translations as $locale => $extra) {
$layoutBox->translate($locale)->setExtra1($extra['extra1'] ?? '');
$layoutBox->translate($locale)->setExtra2($extra['extra2'] ?? '');
$layoutBox->translate($locale)->setExtra3($extra['extra3'] ?? '');
$layoutBox->translate($locale)->setExtra4($extra['extra4'] ?? '');
$layoutBox->translate($locale)->setExtra5($extra['extra5'] ?? '');
$layoutBox->translate($locale)->setExtra6($extra['extra6'] ?? '');
$layoutBox->translate($locale)->setExtra7($extra['extra7'] ?? '');
$layoutBox->translate($locale)->setExtra8($extra['extra8'] ?? '');
$layoutBox->translate($locale)->setExtra9($extra['extra9'] ?? '');
$layoutBox->translate($locale)->setExtra10($extra['extra10'] ?? '');
}
$layoutBox->mergeNewTranslations();
}
public function onLayoutBoxPostInit(EntityEvent $event)
{
$resource = $event->getEntity();
if ($resource instanceof LayoutBox) {
$resource->setShop($this->shopStorage->getCurrentShop());
}
}
private function getBoxSettingsFromRequest(Request $request)
{
$settings = [];
$accessor = PropertyAccess::createPropertyAccessor();
$parameters = $request->request->all();
$boxType = $accessor->getValue($parameters, '[required_data][boxType]');
if ($accessor->isReadable($parameters, '[' . $boxType . ']')) {
$settings = $accessor->getValue($parameters, '[' . $boxType . ']');
}
return !is_array($settings) ? [] : $settings;
}
private function mergeUnmodifiedSettings(array $oldSettings, array $newSettings): array
{
foreach ($newSettings as $key => &$setting) {
if (is_array($setting) && array_key_exists('unmodified', $setting) && isset($setting[0])) {
$setting[0] = (0 !== (int) $setting[0]) ? $setting[0] : $oldSettings[$key][0];
}
}
return $newSettings;
}
}