vendor/sonata-project/block-bundle/src/Block/Service/MenuBlockService.php line 66

Open in your IDE?
  1. <?php
  2. declare(strict_types=1);
  3. /*
  4.  * This file is part of the Sonata Project package.
  5.  *
  6.  * (c) Thomas Rabaix <thomas.rabaix@sonata-project.org>
  7.  *
  8.  * For the full copyright and license information, please view the LICENSE
  9.  * file that was distributed with this source code.
  10.  */
  11. namespace Sonata\BlockBundle\Block\Service;
  12. use Knp\Menu\ItemInterface;
  13. use Knp\Menu\Provider\MenuProviderInterface;
  14. use Sonata\AdminBundle\Form\FormMapper;
  15. use Sonata\BlockBundle\Block\BlockContextInterface;
  16. use Sonata\BlockBundle\Menu\MenuRegistry;
  17. use Sonata\BlockBundle\Menu\MenuRegistryInterface;
  18. use Sonata\BlockBundle\Meta\Metadata;
  19. use Sonata\BlockBundle\Model\BlockInterface;
  20. use Sonata\Form\Type\ImmutableArrayType;
  21. use Sonata\Form\Validator\ErrorElement;
  22. use Symfony\Component\Form\Extension\Core\Type\CheckboxType;
  23. use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
  24. use Symfony\Component\Form\Extension\Core\Type\TextType;
  25. use Symfony\Component\Form\FormTypeInterface;
  26. use Symfony\Component\HttpFoundation\Response;
  27. use Symfony\Component\OptionsResolver\OptionsResolver;
  28. use Symfony\Component\Templating\EngineInterface;
  29. /**
  30.  * @final since sonata-project/block-bundle 3.0
  31.  *
  32.  * @author Hugo Briand <briand@ekino.com>
  33.  */
  34. class MenuBlockService extends AbstractAdminBlockService
  35. {
  36.     /**
  37.      * @var MenuProviderInterface
  38.      */
  39.     protected $menuProvider;
  40.     /**
  41.      * NEXT_MAJOR: remove property.
  42.      *
  43.      * @var array
  44.      *
  45.      * @deprecated since sonata-project/block-bundle 3.3, to be removed in 4.0
  46.      */
  47.     protected $menus;
  48.     /**
  49.      * @var MenuRegistryInterface
  50.      */
  51.     protected $menuRegistry;
  52.     /**
  53.      * @param string                     $name
  54.      * @param MenuRegistryInterface|null $menuRegistry
  55.      */
  56.     public function __construct($nameEngineInterface $templatingMenuProviderInterface $menuProvider$menuRegistry null)
  57.     {
  58.         parent::__construct($name$templating);
  59.         $this->menuProvider $menuProvider;
  60.         if ($menuRegistry instanceof MenuRegistryInterface) {
  61.             $this->menuRegistry $menuRegistry;
  62.         } elseif (null === $menuRegistry) {
  63.             $this->menuRegistry = new MenuRegistry();
  64.         } elseif (\is_array($menuRegistry)) { //NEXT_MAJOR: Remove this case
  65.             @trigger_error(
  66.                 'Initializing '.__CLASS__.' with an array parameter is deprecated since 3.3 and will be removed in 4.0.',
  67.                 E_USER_DEPRECATED
  68.             );
  69.             $this->menuRegistry = new MenuRegistry();
  70.             foreach ($menuRegistry as $menu) {
  71.                 $this->menuRegistry->add($menu);
  72.             }
  73.         } else {
  74.             throw new \InvalidArgumentException(sprintf(
  75.                 'MenuRegistry must be either null or instance of %s',
  76.                 MenuRegistryInterface::class
  77.             ));
  78.         }
  79.     }
  80.     public function execute(BlockContextInterface $blockContext, ?Response $response null)
  81.     {
  82.         $responseSettings = [
  83.             'menu' => $this->getMenu($blockContext),
  84.             'menu_options' => $this->getMenuOptions($blockContext->getSettings()),
  85.             'block' => $blockContext->getBlock(),
  86.             'context' => $blockContext,
  87.         ];
  88.         if ('private' === $blockContext->getSetting('cache_policy')) {
  89.             return $this->renderPrivateResponse($blockContext->getTemplate(), $responseSettings$response);
  90.         }
  91.         return $this->renderResponse($blockContext->getTemplate(), $responseSettings$response);
  92.     }
  93.     public function buildEditForm(FormMapper $formBlockInterface $block)
  94.     {
  95.         $form->add('settings'ImmutableArrayType::class, [
  96.             'keys' => $this->getFormSettingsKeys(),
  97.             'translation_domain' => 'SonataBlockBundle',
  98.         ]);
  99.     }
  100.     public function validateBlock(ErrorElement $errorElementBlockInterface $block)
  101.     {
  102.         if (($name $block->getSetting('menu_name')) && '' !== $name && !$this->menuProvider->has($name)) {
  103.             // If we specified a menu_name, check that it exists
  104.             $errorElement->with('menu_name')
  105.                 ->addViolation('sonata.block.menu.not_existing', ['%name%' => $name])
  106.             ->end();
  107.         }
  108.     }
  109.     public function configureSettings(OptionsResolver $resolver)
  110.     {
  111.         $resolver->setDefaults([
  112.             'title' => $this->getName(),
  113.             'cache_policy' => 'public',
  114.             'template' => '@SonataBlock/Block/block_core_menu.html.twig',
  115.             'menu_name' => '',
  116.             'safe_labels' => false,
  117.             'current_class' => 'active',
  118.             'first_class' => false,
  119.             'last_class' => false,
  120.             'current_uri' => null,
  121.             'menu_class' => 'list-group',
  122.             'children_class' => 'list-group-item',
  123.             'menu_template' => null,
  124.         ]);
  125.     }
  126.     public function getBlockMetadata($code null)
  127.     {
  128.         return new Metadata($this->getName(), (null !== $code $code $this->getName()), false'SonataBlockBundle', [
  129.             'class' => 'fa fa-bars',
  130.         ]);
  131.     }
  132.     /**
  133.      * @return array
  134.      */
  135.     protected function getFormSettingsKeys()
  136.     {
  137.         $choiceOptions = [
  138.             'required' => false,
  139.             'label' => 'form.label_url',
  140.             'choice_translation_domain' => 'SonataBlockBundle',
  141.         ];
  142.         // choice_as_value options is not needed in SF 3.0+
  143.         if (method_exists(FormTypeInterface::class, 'setDefaultOptions')) {
  144.             $choiceOptions['choices_as_values'] = true;
  145.         }
  146.         $choiceOptions['choices'] = array_flip($this->menuRegistry->getAliasNames());
  147.         return [
  148.             ['title'TextType::class, [
  149.                 'required' => false,
  150.                 'label' => 'form.label_title',
  151.             ]],
  152.             ['cache_policy'ChoiceType::class, [
  153.                 'label' => 'form.label_cache_policy',
  154.                 'choices' => ['public''private'],
  155.             ]],
  156.             ['menu_name'ChoiceType::class, $choiceOptions],
  157.             ['safe_labels'CheckboxType::class, [
  158.                 'required' => false,
  159.                 'label' => 'form.label_safe_labels',
  160.             ]],
  161.             ['current_class'TextType::class, [
  162.                 'required' => false,
  163.                 'label' => 'form.label_current_class',
  164.             ]],
  165.             ['first_class'TextType::class, [
  166.                 'required' => false,
  167.                 'label' => 'form.label_first_class',
  168.             ]],
  169.             ['last_class'TextType::class, [
  170.                 'required' => false,
  171.                 'label' => 'form.label_last_class',
  172.             ]],
  173.             ['menu_class'TextType::class, [
  174.                 'required' => false,
  175.                 'label' => 'form.label_menu_class',
  176.             ]],
  177.             ['children_class'TextType::class, [
  178.                 'required' => false,
  179.                 'label' => 'form.label_children_class',
  180.             ]],
  181.             ['menu_template'TextType::class, [
  182.                 'required' => false,
  183.                 'label' => 'form.label_menu_template',
  184.             ]],
  185.         ];
  186.     }
  187.     /**
  188.      * Gets the menu to render.
  189.      *
  190.      * @return ItemInterface|string
  191.      */
  192.     protected function getMenu(BlockContextInterface $blockContext)
  193.     {
  194.         $settings $blockContext->getSettings();
  195.         return $settings['menu_name'];
  196.     }
  197.     /**
  198.      * Replaces setting keys with knp menu item options keys.
  199.      *
  200.      * @return array
  201.      */
  202.     protected function getMenuOptions(array $settings)
  203.     {
  204.         $mapping = [
  205.             'current_class' => 'currentClass',
  206.             'first_class' => 'firstClass',
  207.             'last_class' => 'lastClass',
  208.             'safe_labels' => 'allow_safe_labels',
  209.             'menu_template' => 'template',
  210.         ];
  211.         $options = [];
  212.         foreach ($settings as $key => $value) {
  213.             if (\array_key_exists($key$mapping) && null !== $value) {
  214.                 $options[$mapping[$key]] = $value;
  215.             }
  216.         }
  217.         return $options;
  218.     }
  219. }