src/Form/Type/SiteMenuHeaderType.php line 38

Open in your IDE?
  1. <?php
  2. namespace App\Form\Type;
  3. use Sylius\Bundle\ResourceBundle\Form\Registry\FormTypeRegistryInterface;
  4. use Sylius\Component\Resource\Repository\RepositoryInterface;
  5. use Sylius\Bundle\ResourceBundle\Form\Type\AbstractResourceType;
  6. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  7. use Symfony\Component\Form\Extension\Core\Type\TextType;
  8. use Symfony\Component\Form\FormBuilderInterface;
  9. use Symfony\Component\Form\FormEvent;
  10. use Symfony\Component\Form\FormEvents;
  11. use Symfony\Component\Form\FormInterface;
  12. use Symfony\Component\Form\FormError;
  13. use Symfony\Component\OptionsResolver\OptionsResolver;
  14. use Symfony\Bridge\Doctrine\Form\Type\EntityType;
  15. use App\Entity\SiteMenuHeader;
  16. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  17. final class SiteMenuHeaderType extends AbstractResourceType
  18. {
  19.     private const ROOT_MENU 12;
  20.     /**
  21.      * @var FormTypeRegistryInterface
  22.      */
  23.     private $formTypeRegistry;
  24.     /**
  25.      * @var RepositoryInterface
  26.      */
  27.     private $siteMenuHeaderRepository;
  28.     /**
  29.      * {@inheritdoc}
  30.      */
  31.     public function __construct(
  32.         $dataClass,
  33.         array $validationGroups = [],
  34.         FormTypeRegistryInterface $formTypeRegistry,
  35.         RepositoryInterface $siteMenuHeaderRepository
  36.     ) {
  37.         parent::__construct($dataClass$validationGroups);
  38.         $this->formTypeRegistry $formTypeRegistry;
  39.         $this->siteMenuHeaderRepository $siteMenuHeaderRepository;
  40.     }
  41.     /**
  42.      * {@inheritdoc}
  43.      */
  44.     public function buildForm(FormBuilderInterface $builder, array $options = [])
  45.     {
  46.         parent::buildForm($builder$options);
  47.         $builder
  48.             ->add('title'TextType::class, [
  49.                 'label' => 'Titre de la navigation',
  50.                 'required' => true
  51.             ])
  52.             ->add('enabled'CheckboxType::class, [
  53.                 'label' => 'Activé',
  54.                 'required' => true
  55.             ])
  56.             ->add('saumon'CheckboxType::class, [
  57.                 'label' => 'Police saumon',
  58.                 'required' => false
  59.             ])
  60.             ->add('attr_title'TextType::class, [
  61.                 'label' => 'Attribut de titre',
  62.                 'required' => false
  63.             ])
  64.             ->add('parent'EntityType::class, [
  65.                 'label' => 'sylius.ui.parent',
  66.                 'required' => false,
  67.                 'class' => SiteMenuHeader::class,
  68.                 'choice_attr' => function ($val) {
  69.                     return $val->getId() == '12' ? ['disabled' => 'disabled'] : [];
  70.                 },
  71.                 'choice_label' => function ($entity) {
  72.                     if ($entity->getLevel() <= 1) {
  73.                         return $entity->getTitle();
  74.                     } else {
  75.                         $currentEntity $entity;
  76.                         $title '';
  77.                         while (empty($currentEntity) == false && $currentEntity->getId() != 12) {
  78.                             if (empty($title)) {
  79.                                 $title $currentEntity->getTitle();
  80.                             } else {
  81.                                 $title $currentEntity->getTitle() . ' / ' $title;
  82.                             }
  83.                             
  84.                             $currentEntity $currentEntity->getParent();
  85.                         }
  86.                         return $title;
  87.                     }
  88.                 },
  89.                 'required' => false,
  90.                 'multiple' => false
  91.             ])
  92.             ->add('bold'CheckboxType::class, [
  93.                 'label' => 'Mettre en gras',
  94.                 'required' => false,
  95.                 'disabled' => true,
  96.                 'data' => false
  97.             ])
  98.             ->add('type'SiteMenuHeaderItemChoiceType::class, [
  99.                 'label' => 'Type',
  100.                 'attr' => [
  101.                     'data-form-collection' => 'update',
  102.                 ],
  103.             ])
  104.             ->add('language'ChoiceType::class, [
  105.                 'required' => true,
  106.                 'label' => 'Langue (utile uniquement pour le premier niveau)',
  107.                 'choices' => $this->getLanguages()
  108.             ])
  109.             ->addEventListener(FormEvents::PRE_SET_DATA, function (FormEvent $event) use ($options) {
  110.                 $form $event->getForm();
  111.                 $data $event->getData();
  112.                 if (empty($data->getId()) == false) {
  113.                     // On modifie un menu
  114.                     // - On désactive la modification du parent
  115.                     // - On désactive la modification du type de menu
  116.                     $form->remove('parent');
  117.                     $form->remove('type');
  118.                     $form->add('parent'EntityType::class, [
  119.                         'label' => 'sylius.ui.parent',
  120.                         'required' => false,
  121.                         'class' => SiteMenuHeader::class,
  122.                         'choice_attr' => function ($val) {
  123.                             return $val->getId() == '12' ? ['disabled' => 'disabled'] : [];
  124.                         },
  125.                         'choice_label' => function ($entity) {
  126.                             if ($entity->getLevel() <= 1) {
  127.                                 return $entity->getTitle();
  128.                             } else {
  129.                                 $currentEntity $entity;
  130.                                 $title '';
  131.                                 while (empty($currentEntity) == false && $currentEntity->getId() != 12) {
  132.                                     if (empty($title)) {
  133.                                         $title $currentEntity->getTitle();
  134.                                     } else {
  135.                                         $title $currentEntity->getTitle() . ' / ' $title;
  136.                                     }
  137.                                     
  138.                                     $currentEntity $currentEntity->getParent();
  139.                                 }
  140.                                 return $title;
  141.                             }
  142.                         },
  143.                         'required' => false,
  144.                         'multiple' => false,
  145.                         'disabled' => true
  146.                     ]);
  147.                     $form->add('type'SiteMenuHeaderItemChoiceType::class, [
  148.                         'label' => 'Type',
  149.                         'attr' => [
  150.                             'data-form-collection' => 'update',
  151.                         ],
  152.                         'disabled' => true
  153.                     ]);
  154.                     if ($data->getParent()->getId() == self::ROOT_MENU) {
  155.                         // C'est un élément sans parent, dans ce cas :
  156.                         // - Ajoute une option pour mettre en gras ou non
  157.                         $form->remove('bold');
  158.                         $form->add('bold'CheckboxType::class, [
  159.                             'label' => 'Mettre en gras',
  160.                             'required' => false
  161.                         ]);
  162.                     }
  163.                 }
  164.                 $type $this->getRegistryIdentifier($event->getForm(), $event->getData());
  165.                 if (null === $type) {
  166.                     return;
  167.                 }
  168.                 $this->addConfigurationFields($event->getForm(), $this->formTypeRegistry->get($type'default'));
  169.             })
  170.             ->addEventListener(FormEvents::POST_SET_DATA, function (FormEvent $event) {
  171.                 $type $this->getRegistryIdentifier($event->getForm(), $event->getData());
  172.                 if (null === $type) {
  173.                     return;
  174.                 }
  175.                 $event->getForm()->get('type')->setData($type);
  176.             })
  177.             ->addEventListener(FormEvents::PRE_SUBMIT, function (FormEvent $event) use ($options) {
  178.                 $data $event->getData();
  179.                 $form $event->getForm();
  180.                 if (isset($data['parent']) && empty($data['parent']) == false) {
  181.                     $parent $this->siteMenuHeaderRepository->findOneById($data['parent']);
  182.                     if (empty($parent) == false && $parent->getLevel() >= 3) {
  183.                         // Il n'y a que 3 niveaux de menu (level 1, 2 et 3), pas plus.
  184.                         $form->addError(new FormError(
  185.                             "Il n'est pas possible de créer plus de 3 niveaux de menu. "
  186.                             "Veuillez changer l'élément parent."
  187.                         ));
  188.                     }
  189.                 }
  190.                 if (empty($data['parent'])) {
  191.                     $data['parent'] = 12;
  192.                     $event->setData($data);
  193.                 }
  194.                 if (!isset($data['type'])) {
  195.                     return;
  196.                 }
  197.                 $this->addConfigurationFields($event->getForm(), $this->formTypeRegistry->get($data['type'], 'default'));
  198.             })
  199.         ;
  200.     }
  201.     /**
  202.      * {@inheritdoc}
  203.      */
  204.     public function configureOptions(OptionsResolver $resolver): void
  205.     {
  206.         parent::configureOptions($resolver);
  207.         $resolver
  208.             ->setDefault('configuration_type'null)
  209.             ->setAllowedTypes('configuration_type', ['string''null'])
  210.         ;
  211.     }
  212.     /**
  213.      * @param FormInterface $form
  214.      * @param string $configurationType
  215.      */
  216.     protected function addConfigurationFields(FormInterface $form$configurationType)
  217.     {
  218.         $form->add('configuration'$configurationType, [
  219.             'label' => false,
  220.         ]);
  221.     }
  222.     /**
  223.      * {@inheritdoc}
  224.      */
  225.     public function getBlockPrefix()
  226.     {
  227.         return 'app_site_menu_header_item_type';
  228.     }
  229.     /**
  230.      * {@inheritdoc}
  231.      */
  232.     protected function getRegistryIdentifier(FormInterface $form$data null)
  233.     {
  234.         if (null !== $data && null !== $data->getType()) {
  235.             return $data->getType();
  236.         }
  237.         if (null !== $form->getConfig()->hasOption('configuration_type')) {
  238.             return $form->getConfig()->getOption('configuration_type');
  239.         }
  240.         return null;
  241.     }
  242.     private function getLanguages(): array
  243.     {
  244.         return array(
  245.             'FR'                   => 'fr_FR' ,
  246.             'EN'                   => 'en_US',
  247.         );
  248.     }
  249. }