vendor/symfony/form/AbstractRendererEngine.php line 78

Open in your IDE?
  1. <?php
  2. /*
  3.  * This file is part of the Symfony package.
  4.  *
  5.  * (c) Fabien Potencier <fabien@symfony.com>
  6.  *
  7.  * For the full copyright and license information, please view the LICENSE
  8.  * file that was distributed with this source code.
  9.  */
  10. namespace Symfony\Component\Form;
  11. /**
  12.  * Default implementation of {@link FormRendererEngineInterface}.
  13.  *
  14.  * @author Bernhard Schussek <bschussek@gmail.com>
  15.  */
  16. abstract class AbstractRendererEngine implements FormRendererEngineInterface
  17. {
  18.     /**
  19.      * The variable in {@link FormView} used as cache key.
  20.      */
  21.     public const CACHE_KEY_VAR 'cache_key';
  22.     protected $defaultThemes;
  23.     protected $themes = [];
  24.     protected $useDefaultThemes = [];
  25.     protected $resources = [];
  26.     private $resourceHierarchyLevels = [];
  27.     /**
  28.      * Creates a new renderer engine.
  29.      *
  30.      * @param array $defaultThemes The default themes. The type of these
  31.      *                             themes is open to the implementation.
  32.      */
  33.     public function __construct(array $defaultThemes = [])
  34.     {
  35.         $this->defaultThemes $defaultThemes;
  36.     }
  37.     /**
  38.      * {@inheritdoc}
  39.      */
  40.     public function setTheme(FormView $view$themes$useDefaultThemes true)
  41.     {
  42.         $cacheKey $view->vars[self::CACHE_KEY_VAR];
  43.         // Do not cast, as casting turns objects into arrays of properties
  44.         $this->themes[$cacheKey] = \is_array($themes) ? $themes : [$themes];
  45.         $this->useDefaultThemes[$cacheKey] = (bool) $useDefaultThemes;
  46.         // Unset instead of resetting to an empty array, in order to allow
  47.         // implementations (like TwigRendererEngine) to check whether $cacheKey
  48.         // is set at all.
  49.         unset($this->resources[$cacheKey], $this->resourceHierarchyLevels[$cacheKey]);
  50.     }
  51.     /**
  52.      * {@inheritdoc}
  53.      */
  54.     public function getResourceForBlockName(FormView $view$blockName)
  55.     {
  56.         $cacheKey $view->vars[self::CACHE_KEY_VAR];
  57.         if (!isset($this->resources[$cacheKey][$blockName])) {
  58.             $this->loadResourceForBlockName($cacheKey$view$blockName);
  59.         }
  60.         return $this->resources[$cacheKey][$blockName];
  61.     }
  62.     /**
  63.      * {@inheritdoc}
  64.      */
  65.     public function getResourceForBlockNameHierarchy(FormView $view, array $blockNameHierarchy$hierarchyLevel)
  66.     {
  67.         $cacheKey $view->vars[self::CACHE_KEY_VAR];
  68.         $blockName $blockNameHierarchy[$hierarchyLevel];
  69.         if (!isset($this->resources[$cacheKey][$blockName])) {
  70.             $this->loadResourceForBlockNameHierarchy($cacheKey$view$blockNameHierarchy$hierarchyLevel);
  71.         }
  72.         return $this->resources[$cacheKey][$blockName];
  73.     }
  74.     /**
  75.      * {@inheritdoc}
  76.      */
  77.     public function getResourceHierarchyLevel(FormView $view, array $blockNameHierarchy$hierarchyLevel)
  78.     {
  79.         $cacheKey $view->vars[self::CACHE_KEY_VAR];
  80.         $blockName $blockNameHierarchy[$hierarchyLevel];
  81.         if (!isset($this->resources[$cacheKey][$blockName])) {
  82.             $this->loadResourceForBlockNameHierarchy($cacheKey$view$blockNameHierarchy$hierarchyLevel);
  83.         }
  84.         // If $block was previously rendered loaded with loadTemplateForBlock(), the template
  85.         // is cached but the hierarchy level is not. In this case, we know that the  block
  86.         // exists at this very hierarchy level, so we can just set it.
  87.         if (!isset($this->resourceHierarchyLevels[$cacheKey][$blockName])) {
  88.             $this->resourceHierarchyLevels[$cacheKey][$blockName] = $hierarchyLevel;
  89.         }
  90.         return $this->resourceHierarchyLevels[$cacheKey][$blockName];
  91.     }
  92.     /**
  93.      * Loads the cache with the resource for a given block name.
  94.      *
  95.      * @see getResourceForBlock()
  96.      *
  97.      * @param string   $cacheKey  The cache key of the form view
  98.      * @param FormView $view      The form view for finding the applying themes
  99.      * @param string   $blockName The name of the block to load
  100.      *
  101.      * @return bool True if the resource could be loaded, false otherwise
  102.      */
  103.     abstract protected function loadResourceForBlockName($cacheKeyFormView $view$blockName);
  104.     /**
  105.      * Loads the cache with the resource for a specific level of a block hierarchy.
  106.      *
  107.      * @see getResourceForBlockHierarchy()
  108.      */
  109.     private function loadResourceForBlockNameHierarchy(string $cacheKeyFormView $view, array $blockNameHierarchy$hierarchyLevel): bool
  110.     {
  111.         $blockName $blockNameHierarchy[$hierarchyLevel];
  112.         // Try to find a template for that block
  113.         if ($this->loadResourceForBlockName($cacheKey$view$blockName)) {
  114.             // If loadTemplateForBlock() returns true, it was able to populate the
  115.             // cache. The only missing thing is to set the hierarchy level at which
  116.             // the template was found.
  117.             $this->resourceHierarchyLevels[$cacheKey][$blockName] = $hierarchyLevel;
  118.             return true;
  119.         }
  120.         if ($hierarchyLevel 0) {
  121.             $parentLevel $hierarchyLevel 1;
  122.             $parentBlockName $blockNameHierarchy[$parentLevel];
  123.             // The next two if statements contain slightly duplicated code. This is by intention
  124.             // and tries to avoid execution of unnecessary checks in order to increase performance.
  125.             if (isset($this->resources[$cacheKey][$parentBlockName])) {
  126.                 // It may happen that the parent block is already loaded, but its level is not.
  127.                 // In this case, the parent block must have been loaded by loadResourceForBlock(),
  128.                 // which does not check the hierarchy of the block. Subsequently the block must have
  129.                 // been found directly on the parent level.
  130.                 if (!isset($this->resourceHierarchyLevels[$cacheKey][$parentBlockName])) {
  131.                     $this->resourceHierarchyLevels[$cacheKey][$parentBlockName] = $parentLevel;
  132.                 }
  133.                 // Cache the shortcuts for further accesses
  134.                 $this->resources[$cacheKey][$blockName] = $this->resources[$cacheKey][$parentBlockName];
  135.                 $this->resourceHierarchyLevels[$cacheKey][$blockName] = $this->resourceHierarchyLevels[$cacheKey][$parentBlockName];
  136.                 return true;
  137.             }
  138.             if ($this->loadResourceForBlockNameHierarchy($cacheKey$view$blockNameHierarchy$parentLevel)) {
  139.                 // Cache the shortcuts for further accesses
  140.                 $this->resources[$cacheKey][$blockName] = $this->resources[$cacheKey][$parentBlockName];
  141.                 $this->resourceHierarchyLevels[$cacheKey][$blockName] = $this->resourceHierarchyLevels[$cacheKey][$parentBlockName];
  142.                 return true;
  143.             }
  144.         }
  145.         // Cache the result for further accesses
  146.         $this->resources[$cacheKey][$blockName] = false;
  147.         $this->resourceHierarchyLevels[$cacheKey][$blockName] = false;
  148.         return false;
  149.     }
  150. }