diff --git a/block_node.info.yml b/block_node.info.yml index e3ca016..9a7b03e 100644 --- a/block_node.info.yml +++ b/block_node.info.yml @@ -1,6 +1,5 @@ name: 'Block Node' type: module description: 'A block type which displays the current node (or a specific node) in a block in the specified view mode' -core: 8.x -core_version_requirement: ^8 || ^9 +core_version_requirement: ^8 || ^9 || ^10 package: 'Other' diff --git a/src/Plugin/Block/NodeBlock.php b/src/Plugin/Block/NodeBlock.php index 281b38a..a6f5ccb 100644 --- a/src/Plugin/Block/NodeBlock.php +++ b/src/Plugin/Block/NodeBlock.php @@ -2,17 +2,21 @@ namespace Drupal\block_node\Plugin\Block; -use Drupal\Core\Cache\Cache; -use Drupal\Core\Block\BlockBase; -use Drupal\Core\Form\FormStateInterface; -use Drupal\Core\Session\AccountInterface; use Drupal\Core\Access\AccessResult; +use Drupal\Core\Block\BlockBase; +use Drupal\Core\Cache\Cache; +use Drupal\Core\Entity\ContentEntityInterface; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; -use Drupal\node\Entity\Node; +use Drupal\Core\Entity\EntityFieldManagerInterface; +use Drupal\Core\Entity\EntityInterface; +use Drupal\Core\Entity\EntityTypeManagerInterface; +use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Routing\RouteMatchInterface; +use Drupal\Core\Session\AccountInterface; use Drupal\node\NodeInterface; +use Drupal\node\Entity\Node; use Symfony\Component\DependencyInjection\ContainerInterface; -use Drupal\Core\Entity\EntityTypeManagerInterface; /** * Provides a 'NodeBlock' block. @@ -46,6 +50,20 @@ class NodeBlock extends BlockBase implements ContainerFactoryPluginInterface { */ protected $entityDisplayRepository; + /** + * The entity to be used when displaying the block. + * + * @var \Drupal\Core\Entity\ContentEntityInterface + */ + protected $nodeBlockEntity; + + /** + * The current route match. + * + * @var \Drupal\Core\Routing\RouteMatchInterface + */ + protected $routeMatch; + /** * Constructs a NodeBlock instance. * @@ -62,9 +80,10 @@ class NodeBlock extends BlockBase implements ContainerFactoryPluginInterface { * * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityDisplayRepositoryInterface $entity_display_repository, EntityTypeManagerInterface $entity_manager) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityDisplayRepositoryInterface $entity_display_repository, EntityTypeManagerInterface $entity_manager, RouteMatchInterface $route_match) { parent::__construct($configuration, $plugin_id, $plugin_definition); $this->viewBuilder = $entity_manager->getViewBuilder('node'); + $this->routeMatch = $route_match; // If the current node should be used attempt to load it. if (empty($configuration['current'])) { $this->node = isset($configuration['nid']) ? $entity_manager->getStorage('node')->load($configuration['nid']) : []; @@ -84,7 +103,8 @@ class NodeBlock extends BlockBase implements ContainerFactoryPluginInterface { $plugin_id, $plugin_definition, $container->get('entity_display.repository'), - $container->get('entity_type.manager') + $container->get('entity_type.manager'), + $container->get('current_route_match') ); } @@ -168,11 +188,12 @@ class NodeBlock extends BlockBase implements ContainerFactoryPluginInterface { public function build() { $build = []; $config = $this->getConfiguration(); - if (!$this->node instanceof NodeInterface) { + $entity = $this->getEntity(); + if (!$entity instanceof NodeInterface) { return $build; } $view_mode = (isset($config['view_mode']) && !empty($config['view_mode']) ? $config['view_mode'] : 'full'); - $build = $this->viewBuilder->view($this->node, $view_mode); + $build = $this->viewBuilder->view($entity, $view_mode); return $build; } @@ -186,6 +207,42 @@ class NodeBlock extends BlockBase implements ContainerFactoryPluginInterface { return $this->node->access('view', NULL, TRUE); } + /** + * Finds the entity and the proper revision to be used when displaying the block. + * + * @return \Drupal\Core\Entity\ContentEntityInterface|null + * The entity to be used when displaying the block. + * + * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException + * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException + */ + protected function getEntity() { + if (!isset($this->nodeBlockEntity)) { + $entity = NULL; + $route_name = $this->routeMatch->getRouteName(); + $is_canonical_route = $route_name === 'entity.node.canonical'; + $is_latest_route = $route_name == 'entity.node.latest_version'; + + if ($is_canonical_route || $is_latest_route) { + $entity = $this->routeMatch->getParameter('node'); + } else { + if ($route_name == 'entity.node.revision') { + $entity_revision = $this->routeMatch->getParameter('node_revision'); + if (is_numeric($entity_revision)) { + $entity = $this->entityTypeManager->getStorage('node')->loadRevision($entity_revision); + } else { + $entity = $entity_revision; + } + } elseif ($route_name == 'entity.node.preview' && $this->routeMatch->getParameter('view_mode_id') === 'full') { + $entity = $this->routeMatch->getParameter('node_preview'); + } + } + + $this->nodeBlockEntity = $entity; + } + return $this->nodeBlockEntity; + } + /** * {@inheritdoc} */