vendor/sonata-project/block-bundle/src/DependencyInjection/Compiler/TweakCompilerPass.php line 46

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 <[email protected]>
  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\DependencyInjection\Compiler;
  12. use Sonata\BlockBundle\Naming\ConvertFromFqcn;
  13. use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
  14. use Symfony\Component\DependencyInjection\ContainerBuilder;
  15. use Symfony\Component\DependencyInjection\Definition;
  16. use Symfony\Component\DependencyInjection\Reference;
  17. /**
  18.  * Link the block service to the Page Manager.
  19.  *
  20.  * @author Thomas Rabaix <[email protected]>
  21.  */
  22. class TweakCompilerPass implements CompilerPassInterface
  23. {
  24.     /**
  25.      * {@inheritdoc}
  26.      */
  27.     public function process(ContainerBuilder $container)
  28.     {
  29.         $manager $container->getDefinition('sonata.block.manager');
  30.         $registry $container->getDefinition('sonata.block.menu.registry');
  31.         $parameters $container->getParameter('sonata_block.blocks');
  32.         $blockTypes $container->getParameter('sonata_blocks.block_types');
  33.         foreach ($container->findTaggedServiceIds('sonata.block') as $id => $tags) {
  34.             $definition $container->getDefinition($id);
  35.             $definition->setPublic(true);
  36.             if (!$definition->isAutowired()) {
  37.                 $this->replaceBlockName($container$definition$id);
  38.             }
  39.             $blockId $id;
  40.             // Only convert class service names
  41.             if (false !== strpos($blockId'\\')) {
  42.                 $convert = (new ConvertFromFqcn());
  43.                 $blockId $convert($blockId);
  44.             }
  45.             // Skip manual defined blocks
  46.             if (!isset($blockTypes[$blockId])) {
  47.                 $contexts $this->getContextFromTags($tags);
  48.                 $blockTypes[$blockId] = [
  49.                     'context' => $contexts,
  50.                 ];
  51.             }
  52.             $manager->addMethodCall('add', [$id$id, isset($parameters[$id]) ? $parameters[$id]['contexts'] : []]);
  53.         }
  54.         foreach ($container->findTaggedServiceIds('knp_menu.menu') as $id => $tags) {
  55.             foreach ($tags as $attributes) {
  56.                 if (empty($attributes['alias'])) {
  57.                     throw new \InvalidArgumentException(sprintf('The alias is not defined in the "knp_menu.menu" tag for the service "%s"'$id));
  58.                 }
  59.                 $registry->addMethodCall('add', [$attributes['alias']]);
  60.             }
  61.         }
  62.         $services = [];
  63.         foreach ($container->findTaggedServiceIds('sonata.block.loader') as $id => $tags) {
  64.             $services[] = new Reference($id);
  65.         }
  66.         $container->getDefinition('sonata.block.loader.service')->replaceArgument(0$blockTypes);
  67.         $container->getDefinition('sonata.block.loader.chain')->replaceArgument(0$services);
  68.         $this->applyContext($container);
  69.     }
  70.     /**
  71.      * Apply configurations to the context manager.
  72.      *
  73.      * @param ContainerBuilder $container
  74.      */
  75.     public function applyContext(ContainerBuilder $container)
  76.     {
  77.         $definition $container->findDefinition('sonata.block.context_manager');
  78.         foreach ($container->getParameter('sonata_block.blocks') as $service => $settings) {
  79.             if (\count($settings['settings']) > 0) {
  80.                 $definition->addMethodCall('addSettingsByType', [$service$settings['settings'], true]);
  81.             }
  82.         }
  83.         foreach ($container->getParameter('sonata_block.blocks_by_class') as $class => $settings) {
  84.             if (\count($settings['settings']) > 0) {
  85.                 $definition->addMethodCall('addSettingsByClass', [$class$settings['settings'], true]);
  86.             }
  87.         }
  88.     }
  89.     /**
  90.      * Replaces the empty service name with the service id.
  91.      */
  92.     private function replaceBlockName(ContainerBuilder $containerDefinition $definition$id)
  93.     {
  94.         $arguments $definition->getArguments();
  95.         // Replace empty block id with service id
  96.         if ($this->serviceDefinitionNeedsFirstArgument($definition)) {
  97.             // NEXT_MAJOR: Remove the if block when Symfony 2.8 support will be dropped.
  98.             if (method_exists($definition'setArgument')) {
  99.                 $definition->setArgument(0$id);
  100.                 return;
  101.             }
  102.             $definition->replaceArgument(0$id);
  103.             return;
  104.         }
  105.         if ($id !== $arguments[0] && !== strpos(
  106.             (string) $container->getParameterBag()->resolveValue($definition->getClass()),
  107.             'Sonata\\BlockBundle\\Block\\Service\\'
  108.         )) {
  109.             // NEXT_MAJOR: Remove deprecation notice
  110.             @trigger_error(
  111.                 sprintf('Using service id %s different from block id %s is deprecated since 3.3 and will be removed in 4.0.'$id$arguments[0]),
  112.                 E_USER_DEPRECATED
  113.             );
  114.         }
  115.     }
  116.     private function serviceDefinitionNeedsFirstArgument(Definition $definition): bool
  117.     {
  118.         $arguments $definition->getArguments();
  119.         return empty($arguments) ||
  120.             null === ($arguments[0]) ||
  121.             \is_string($arguments[0]) && === \strlen($arguments[0]);
  122.     }
  123.     /**
  124.      * @param string[][]
  125.      *
  126.      * @return string[]
  127.      */
  128.     private function getContextFromTags(array $tags)
  129.     {
  130.         return array_filter(array_map(function (array $attribute) {
  131.             if (\array_key_exists('context'$attribute) && \is_string($attribute['context'])) {
  132.                 return $attribute['context'];
  133.             }
  134.             return null;
  135.         }, $tags));
  136.     }
  137. }