<?php
namespace App\Form\Type;
use Sylius\Bundle\ResourceBundle\Form\Registry\FormTypeRegistryInterface;
use Sylius\Component\Resource\Repository\RepositoryInterface;
use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\FormEvent;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormInterface;
use Symfony\Component\Form\FormError;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Bridge\Doctrine\Form\Type\EntityType;
use App\Entity\SiteMenuHeader;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
final class SiteMenuHeaderType extends AbstractResourceType
{
private const ROOT_MENU = 12;
/**
* @var FormTypeRegistryInterface
*/
private $formTypeRegistry;
/**
* @var RepositoryInterface
*/
private $siteMenuHeaderRepository;
/**
* {@inheritdoc}
*/
public function __construct(
$dataClass,
array $validationGroups = [],
FormTypeRegistryInterface $formTypeRegistry,
RepositoryInterface $siteMenuHeaderRepository
) {
parent::__construct($dataClass, $validationGroups);
$this->formTypeRegistry = $formTypeRegistry;
$this->siteMenuHeaderRepository = $siteMenuHeaderRepository;
}
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options = [])
{
parent::buildForm($builder, $options);
$builder
->add('title', TextType::class, [
'label' => 'Titre de la navigation',
'required' => true
])
->add('enabled', CheckboxType::class, [
'label' => 'Activé',
'required' => true
])
->add('saumon', CheckboxType::class, [
'label' => 'Police saumon',
'required' => false
])
->add('attr_title', TextType::class, [
'label' => 'Attribut de titre',
'required' => false
])
->add('parent', EntityType::class, [
'label' => 'sylius.ui.parent',
'required' => false,
'class' => SiteMenuHeader::class,
'choice_attr' => function ($val) {
return $val->getId() == '12' ? ['disabled' => 'disabled'] : [];
},
'choice_label' => function ($entity) {
if ($entity->getLevel() <= 1) {
return $entity->getTitle();
} else {
$currentEntity = $entity;
$title = '';
while (empty($currentEntity) == false && $currentEntity->getId() != 12) {
if (empty($title)) {
$title = $currentEntity->getTitle();
} else {
$title = $currentEntity->getTitle() . ' / ' . $title;
}
$currentEntity = $currentEntity->getParent();
}
return $title;
}
},
'required' => false,
'multiple' => false
])
->add('bold', CheckboxType::class, [
'label' => 'Mettre en gras',
'required' => false,
'disabled' => true,
'data' => false
])
->add('type', SiteMenuHeaderItemChoiceType::class, [
'label' => 'Type',
'attr' => [
'data-form-collection' => 'update',
],
])
->add('language', ChoiceType::class, [
'required' => true,
'label' => 'Langue (utile uniquement pour le premier niveau)',
'choices' => $this->getLanguages()
])
->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
$form = $event->getForm();
$data = $event->getData();
if (empty($data->getId()) == false) {
// On modifie un menu
// - On désactive la modification du parent
// - On désactive la modification du type de menu
$form->remove('parent');
$form->remove('type');
$form->add('parent', EntityType::class, [
'label' => 'sylius.ui.parent',
'required' => false,
'class' => SiteMenuHeader::class,
'choice_attr' => function ($val) {
return $val->getId() == '12' ? ['disabled' => 'disabled'] : [];
},
'choice_label' => function ($entity) {
if ($entity->getLevel() <= 1) {
return $entity->getTitle();
} else {
$currentEntity = $entity;
$title = '';
while (empty($currentEntity) == false && $currentEntity->getId() != 12) {
if (empty($title)) {
$title = $currentEntity->getTitle();
} else {
$title = $currentEntity->getTitle() . ' / ' . $title;
}
$currentEntity = $currentEntity->getParent();
}
return $title;
}
},
'required' => false,
'multiple' => false,
'disabled' => true
]);
$form->add('type', SiteMenuHeaderItemChoiceType::class, [
'label' => 'Type',
'attr' => [
'data-form-collection' => 'update',
],
'disabled' => true
]);
if ($data->getParent()->getId() == self::ROOT_MENU) {
// C'est un élément sans parent, dans ce cas :
// - Ajoute une option pour mettre en gras ou non
$form->remove('bold');
$form->add('bold', CheckboxType::class, [
'label' => 'Mettre en gras',
'required' => false
]);
}
}
$type = $this->getRegistryIdentifier($event->getForm(), $event->getData());
if (null === $type) {
return;
}
$this->addConfigurationFields($event->getForm(), $this->formTypeRegistry->get($type, 'default'));
})
->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
$type = $this->getRegistryIdentifier($event->getForm(), $event->getData());
if (null === $type) {
return;
}
$event->getForm()->get('type')->setData($type);
})
->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
$data = $event->getData();
$form = $event->getForm();
if (isset($data['parent']) && empty($data['parent']) == false) {
$parent = $this->siteMenuHeaderRepository->findOneById($data['parent']);
if (empty($parent) == false && $parent->getLevel() >= 3) {
// Il n'y a que 3 niveaux de menu (level 1, 2 et 3), pas plus.
$form->addError(new FormError(
"Il n'est pas possible de créer plus de 3 niveaux de menu. "
. "Veuillez changer l'élément parent."
));
}
}
if (empty($data['parent'])) {
$data['parent'] = 12;
$event->setData($data);
}
if (!isset($data['type'])) {
return;
}
$this->addConfigurationFields($event->getForm(), $this->formTypeRegistry->get($data['type'], 'default'));
})
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver): void
{
parent::configureOptions($resolver);
$resolver
->setDefault('configuration_type', null)
->setAllowedTypes('configuration_type', ['string', 'null'])
;
}
/**
* @param FormInterface $form
* @param string $configurationType
*/
protected function addConfigurationFields(FormInterface $form, $configurationType)
{
$form->add('configuration', $configurationType, [
'label' => false,
]);
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'app_site_menu_header_item_type';
}
/**
* {@inheritdoc}
*/
protected function getRegistryIdentifier(FormInterface $form, $data = null)
{
if (null !== $data && null !== $data->getType()) {
return $data->getType();
}
if (null !== $form->getConfig()->hasOption('configuration_type')) {
return $form->getConfig()->getOption('configuration_type');
}
return null;
}
private function getLanguages(): array
{
return array(
'FR' => 'fr_FR' ,
'EN' => 'en_US',
);
}
}