Loading src/Plugin/Block/EntityBlock.php +44 −2 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ use Drupal\Core\Block\BlockBase; use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; Loading @@ -24,6 +25,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { /** * The number of times this block allows rendering the same entity. * * @var int */ const RECURSIVE_RENDER_LIMIT = 3; /** * The name of our entity type. * Loading Loading @@ -59,10 +67,24 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { */ protected $view_mode_options; /** * An array of counters for the recursive rendering protection. * * @var array */ protected static $recursiveRenderDepth = []; /** * The logger factory. * * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface */ protected $loggerFactory; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager, EntityDisplayRepositoryInterface $entityDisplayRepository) { public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager, EntityDisplayRepositoryInterface $entityDisplayRepository, LoggerChannelFactoryInterface $logger_factory) { parent::__construct($configuration, $plugin_id, $plugin_definition); // Determine what entity type we are referring to. Loading @@ -82,6 +104,7 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { } $this->view_mode_options = $entityDisplayRepository->getViewModeOptions($this->entityTypeName); $this->loggerFactory = $logger_factory; } /** Loading @@ -91,7 +114,8 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'), $container->get('entity_display.repository') $container->get('entity_display.repository'), $container->get('logger.factory') ); } Loading Loading @@ -169,6 +193,24 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { */ public function build() { if ($entity = $this->getEntity()) { $recursive_render_id = $entity->getEntityTypeId() . ':' . $entity->id(); if (isset(static::$recursiveRenderDepth[$recursive_render_id])) { static::$recursiveRenderDepth[$recursive_render_id]++; } else { static::$recursiveRenderDepth[$recursive_render_id] = 1; } // Protect recursive rendering. if (static::$recursiveRenderDepth[$recursive_render_id] > static::RECURSIVE_RENDER_LIMIT) { $this->loggerFactory->get('entity')->error('Recursive rendering detected when rendering embedded entity %entity_type: %entity_id. Aborting rendering.', [ '%entity_type' => $entity->getEntityTypeId(), '%entity_id' => $entity->id(), ]); // return []; } $render_controller = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId()); $view_mode = $this->configuration['view_mode'] ?? 'default'; Loading tests/src/Kernel/EntityBlockTest.php +34 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ final class EntityBlockTest extends EntityKernelTestBase { $entity = EntityTest::create([ 'name' => $this->randomString(), ]); $entity->save(); $block = Block::create([ 'id' => strtolower($this->randomMachineName()), 'theme' => 'stark', Loading @@ -50,4 +51,37 @@ final class EntityBlockTest extends EntityKernelTestBase { $this->assertConfigSchemaByName($block->getConfigDependencyName()); } public function testBuild(): void { $entity = EntityTest::create([ 'name' => $this->randomString(), ]); $entity->save(); $block = Block::create([ 'id' => strtolower($this->randomMachineName()), 'theme' => 'stark', 'weight' => 0, 'status' => TRUE, 'region' => 'content', 'plugin' => 'entity_block:entity_test', 'settings' => [ 'label' => $this->randomString(), 'provider' => 'entity_block', 'label_display' => FALSE, 'entity' => $entity->id(), ], 'visibility' => [], ]); $block->save(); $view_builder_build = $this->container->get('entity_type.manager') ->getViewBuilder('entity_test') ->view($entity, 'default'); unset($view_builder_build['#entity_test']); $block_build = $block->getPlugin()->build(); unset($block_build['#entity_test']); self::assertEquals($view_builder_build, $block_build); } } Loading
src/Plugin/Block/EntityBlock.php +44 −2 Original line number Diff line number Diff line Loading @@ -8,6 +8,7 @@ use Drupal\Core\Block\BlockBase; use Drupal\Core\Cache\Cache; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Logger\LoggerChannelFactoryInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; Loading @@ -24,6 +25,13 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { /** * The number of times this block allows rendering the same entity. * * @var int */ const RECURSIVE_RENDER_LIMIT = 3; /** * The name of our entity type. * Loading Loading @@ -59,10 +67,24 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { */ protected $view_mode_options; /** * An array of counters for the recursive rendering protection. * * @var array */ protected static $recursiveRenderDepth = []; /** * The logger factory. * * @var \Drupal\Core\Logger\LoggerChannelFactoryInterface */ protected $loggerFactory; /** * {@inheritdoc} */ public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager, EntityDisplayRepositoryInterface $entityDisplayRepository) { public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager, EntityDisplayRepositoryInterface $entityDisplayRepository, LoggerChannelFactoryInterface $logger_factory) { parent::__construct($configuration, $plugin_id, $plugin_definition); // Determine what entity type we are referring to. Loading @@ -82,6 +104,7 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { } $this->view_mode_options = $entityDisplayRepository->getViewModeOptions($this->entityTypeName); $this->loggerFactory = $logger_factory; } /** Loading @@ -91,7 +114,8 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { return new static( $configuration, $plugin_id, $plugin_definition, $container->get('entity_type.manager'), $container->get('entity_display.repository') $container->get('entity_display.repository'), $container->get('logger.factory') ); } Loading Loading @@ -169,6 +193,24 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { */ public function build() { if ($entity = $this->getEntity()) { $recursive_render_id = $entity->getEntityTypeId() . ':' . $entity->id(); if (isset(static::$recursiveRenderDepth[$recursive_render_id])) { static::$recursiveRenderDepth[$recursive_render_id]++; } else { static::$recursiveRenderDepth[$recursive_render_id] = 1; } // Protect recursive rendering. if (static::$recursiveRenderDepth[$recursive_render_id] > static::RECURSIVE_RENDER_LIMIT) { $this->loggerFactory->get('entity')->error('Recursive rendering detected when rendering embedded entity %entity_type: %entity_id. Aborting rendering.', [ '%entity_type' => $entity->getEntityTypeId(), '%entity_id' => $entity->id(), ]); // return []; } $render_controller = $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId()); $view_mode = $this->configuration['view_mode'] ?? 'default'; Loading
tests/src/Kernel/EntityBlockTest.php +34 −0 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ final class EntityBlockTest extends EntityKernelTestBase { $entity = EntityTest::create([ 'name' => $this->randomString(), ]); $entity->save(); $block = Block::create([ 'id' => strtolower($this->randomMachineName()), 'theme' => 'stark', Loading @@ -50,4 +51,37 @@ final class EntityBlockTest extends EntityKernelTestBase { $this->assertConfigSchemaByName($block->getConfigDependencyName()); } public function testBuild(): void { $entity = EntityTest::create([ 'name' => $this->randomString(), ]); $entity->save(); $block = Block::create([ 'id' => strtolower($this->randomMachineName()), 'theme' => 'stark', 'weight' => 0, 'status' => TRUE, 'region' => 'content', 'plugin' => 'entity_block:entity_test', 'settings' => [ 'label' => $this->randomString(), 'provider' => 'entity_block', 'label_display' => FALSE, 'entity' => $entity->id(), ], 'visibility' => [], ]); $block->save(); $view_builder_build = $this->container->get('entity_type.manager') ->getViewBuilder('entity_test') ->view($entity, 'default'); unset($view_builder_build['#entity_test']); $block_build = $block->getPlugin()->build(); unset($block_build['#entity_test']); self::assertEquals($view_builder_build, $block_build); } }