src/Blocks/BlocksLoader.php line 62

Open in your IDE?
  1. <?php
  2. namespace App\Blocks;
  3. use Psr\Container\ContainerInterface;
  4. use Twig\Environment;
  5. class BlocksLoader
  6. {
  7.     private $twig;
  8.     /**
  9.      * @var BlockRuntimeDescription[]
  10.      */
  11.     private array $blocks = [];
  12.     private ContainerInterface $container;
  13.     public function __construct(ContainerInterface $containerEnvironment $twig)
  14.     {
  15.         $this->container $container;
  16.         $this->twig $twig;
  17.     }
  18.     /**
  19.      * Load all blocks from core's block directory
  20.      */
  21.     private function loadBaseBlocks() {
  22.         $commonBlocksPath __DIR__ '/../../blocks';
  23.         $blockNames self::getBlockFolderList($commonBlocksPath);
  24.         foreach ($blockNames as $blockName) {
  25.             $this->blocks[] = new BlockRuntimeDescription($commonBlocksPath$blockName);
  26.         }
  27.     }
  28.     /**
  29.      * Load additional blocks from a custom directory and namespace
  30.      */
  31.     private function overrideBlocks(string $namespacestring $newBasePath)
  32.     {
  33.         $existingBlockNames array_map(function ($block) {
  34.             return $block->name;
  35.         }, $this->blocks);
  36.         $blockNames self::getBlockFolderList($newBasePath);
  37.         foreach ($blockNames as $blockName) {
  38.             if (in_array($blockName$existingBlockNames)) {
  39.                 $this->getBlockByName($blockName)?->override($namespace$newBasePath);
  40.             } else {
  41.                 $this->blocks[] = new BlockRuntimeDescription($newBasePath$blockName);
  42.             }
  43.         }
  44.     }
  45.     /**
  46.      * Inject all loaded blocks into ACF
  47.      */
  48.     private function inject()
  49.     {
  50.         foreach ($this->blocks as $blockDescription) {
  51.             $blockDescription->register(function (array $rawGutenbergBlockDatabool $preview$additionalData) use ($blockDescription) {
  52.                 $this->renderCallback($blockDescription->name$rawGutenbergBlockData$preview$additionalData);
  53.             });
  54.         }
  55.     }
  56.     private function getBlockClass(string $blockName): string
  57.     {
  58.         $block $this->getBlockByName($blockName);
  59.         if (!$block) {
  60.             return GenericBlock::class;
  61.         }
  62.         if ($block->overridenClass) {
  63.             return $block->overridenClass;
  64.         }
  65.         return GenericBlock::class;
  66.     }
  67.     private function getBlockObject(string $blockName): BlockInterface
  68.     {
  69.         $class $this->getBlockClass($blockName);
  70.         if ($this->container->has($class)) {
  71.             return $this->container->get($class);
  72.         }
  73.         return new $class;
  74.     }
  75.     public function renderCallback(string $blockName, array $rawGutenbergBlockData$preview false, array|false $additionalData false)
  76.     {
  77.         try {
  78.             $blockDefinition $this->getBlockByName($blockName);
  79.             $object $this->getBlockObject($blockName);
  80.             $template $this->twig->load($blockDefinition->getTemplate());
  81.             $rawGutenbergBlockData['additionalData'] = $additionalData ?: [];
  82.             $context $object->buildTemplateContext($rawGutenbergBlockData);
  83.             echo $template->render($context);
  84.         } catch (\Exception|\Error $e) {
  85.             if ($preview) {
  86.                 echo "<div><strong>Error al renderizar el bloque: {$e->getMessage()}</strong>";
  87.                 return;
  88.             }
  89.             throw $e;
  90.         }
  91.     }
  92.     public function setBlockCategories($categories$post)
  93.     {
  94.         return array_merge(
  95.             $categories,
  96.             array(
  97.                 array(
  98.                     'slug' => 'ydevs',
  99.                     'title' => 'Ydevs Blocks',
  100.                     'icon' => 'wordpress',
  101.                 ),
  102.             )
  103.         );
  104.     }
  105.     public function init(string $websiteBlocksPathstring $websiteNamespace 'Blocks')
  106.     {
  107.         $this->loadBaseBlocks();
  108.         $this->overrideBlocks($websiteNamespace$websiteBlocksPath);
  109.         $this->inject();
  110.     }
  111.     // -- old shite
  112.     public static function getBlockFolderList(string $basePath)
  113.     {
  114.         $blocks = [];
  115.         foreach (glob($basePath DIRECTORY_SEPARATOR "*"GLOB_ONLYDIR) as $folder) {
  116.             $blocks[] = basename($folder);
  117.         }
  118.         return $blocks;
  119.     }
  120.     private function getBlockByName(string $blockName): ?BlockRuntimeDescription
  121.     {
  122.         foreach ($this->blocks as $block) {
  123.             if ($block->name === $blockName) {
  124.                 return $block;
  125.             }
  126.         }
  127.         return null;
  128.     }
  129. }