vendor/sonata-project/block-bundle/src/Block/BlockServiceManager.php line 185

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;
  12. use Sonata\BlockBundle\Block\Service\EditableBlockService;
  13. use Sonata\BlockBundle\Model\BlockInterface;
  14. use Sonata\CoreBundle\Validator\ErrorElement;
  15. use Symfony\Component\DependencyInjection\ContainerInterface;
  16. /**
  17.  * @final since sonata-project/block-bundle 3.0
  18.  */
  19. class BlockServiceManager implements BlockServiceManagerInterface
  20. {
  21.     /**
  22.      * @var array
  23.      */
  24.     protected $services;
  25.     /**
  26.      * @var ContainerInterface
  27.      */
  28.     protected $container;
  29.     /**
  30.      * @var bool
  31.      */
  32.     protected $inValidate;
  33.     /**
  34.      * @var array
  35.      */
  36.     protected $contexts;
  37.     public function __construct(ContainerInterface $container)
  38.     {
  39.         $this->services = [];
  40.         $this->contexts = [];
  41.         $this->container $container;
  42.     }
  43.     public function get(BlockInterface $block)
  44.     {
  45.         $this->load($block->getType());
  46.         return $this->services[$block->getType()];
  47.     }
  48.     public function getService($id)
  49.     {
  50.         return $this->load($id);
  51.     }
  52.     public function has($id)
  53.     {
  54.         return isset($this->services[$id]) ? true false;
  55.     }
  56.     public function add($name$service$contexts = [])
  57.     {
  58.         $this->services[$name] = $service;
  59.         foreach ($contexts as $context) {
  60.             if (!\array_key_exists($context$this->contexts)) {
  61.                 $this->contexts[$context] = [];
  62.             }
  63.             $this->contexts[$context][] = $name;
  64.         }
  65.     }
  66.     public function setServices(array $blockServices)
  67.     {
  68.         foreach ($blockServices as $name => $service) {
  69.             $this->add($name$service);
  70.         }
  71.     }
  72.     public function getServices()
  73.     {
  74.         foreach ($this->services as $name => $id) {
  75.             if (\is_string($id)) {
  76.                 $this->load($id);
  77.             }
  78.         }
  79.         return $this->sortServices($this->services);
  80.     }
  81.     public function getServicesByContext($context$includeContainers true)
  82.     {
  83.         if (!\array_key_exists($context$this->contexts)) {
  84.             return [];
  85.         }
  86.         $services = [];
  87.         $containers $this->container->getParameter('sonata.block.container.types');
  88.         foreach ($this->contexts[$context] as $name) {
  89.             if (!$includeContainers && \in_array($name$containerstrue)) {
  90.                 continue;
  91.             }
  92.             $services[$name] = $this->getService($name);
  93.         }
  94.         return $this->sortServices($services);
  95.     }
  96.     public function getLoadedServices()
  97.     {
  98.         $services = [];
  99.         foreach ($this->services as $service) {
  100.             if (!$service instanceof BlockServiceInterface) {
  101.                 continue;
  102.             }
  103.             $services[] = $service;
  104.         }
  105.         return $services;
  106.     }
  107.     /**
  108.      * @todo: this function should be remove into a proper statefull object
  109.      *
  110.      * {@inheritdoc}
  111.      */
  112.     public function validate(ErrorElement $errorElementBlockInterface $block)
  113.     {
  114.         if (!$block->getId() && !$block->getType()) {
  115.             return;
  116.         }
  117.         if ($this->inValidate) {
  118.             return;
  119.         }
  120.         // As block can be nested, we only need to validate the main block, no the children
  121.         try {
  122.             $this->inValidate true;
  123.             $blockService $this->get($block);
  124.             if ($blockService instanceof EditableBlockService) {
  125.                 $blockService->validate($errorElement$block);
  126.             } else {
  127.                 // NEXT_MAJOR: Remove this case
  128.                 $this->get($block)->validateBlock($errorElement$block);
  129.             }
  130.             $this->inValidate false;
  131.         } catch (\Exception $e) {
  132.             $this->inValidate false;
  133.         }
  134.     }
  135.     /**
  136.      * @param string $type
  137.      *
  138.      * @throws \RuntimeException
  139.      *
  140.      * @return BlockServiceInterface
  141.      */
  142.     private function load($type)
  143.     {
  144.         if (!$this->has($type)) {
  145.             throw new \RuntimeException(sprintf('The block service `%s` does not exist'$type));
  146.         }
  147.         if (!$this->services[$type] instanceof BlockServiceInterface) {
  148.             $this->services[$type] = $this->container->get($type);
  149.         }
  150.         if (!$this->services[$type] instanceof BlockServiceInterface) {
  151.             throw new \RuntimeException(sprintf('The service %s does not implement BlockServiceInterface'$type));
  152.         }
  153.         return $this->services[$type];
  154.     }
  155.     /**
  156.      * Sort alphabetically services.
  157.      *
  158.      * @param array $services
  159.      *
  160.      * @return array
  161.      */
  162.     private function sortServices($services)
  163.     {
  164.         uasort($services, static function ($a$b) {
  165.             if ($a->getName() === $b->getName()) {
  166.                 return 0;
  167.             }
  168.             return ($a->getName() < $b->getName()) ? -1;
  169.         });
  170.         return $services;
  171.     }
  172. }