diff --git a/src/Plugin/Block/EntityBlock.php b/src/Plugin/Block/EntityBlock.php index 1db4c29..577c73a 100644 --- a/src/Plugin/Block/EntityBlock.php +++ b/src/Plugin/Block/EntityBlock.php @@ -2,11 +2,15 @@ namespace Drupal\entity_block\Plugin\Block; +use Drupal\Component\Uuid\Uuid; +use Drupal\Core\Access\AccessResult; use Drupal\Core\Block\BlockBase; use Drupal\Core\Entity\EntityDisplayRepositoryInterface; +use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\Session\AccountInterface; use Symfony\Component\DependencyInjection\ContainerInterface; /** @@ -20,6 +24,20 @@ use Symfony\Component\DependencyInjection\ContainerInterface; */ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { + /** + * The entity repository. + * + * @var \Drupal\Core\Entity\EntityRepositoryInterface + */ + protected $entityRepository; + + /** + * The entity display repository. + * + * @var \Drupal\Core\Entity\EntityDisplayRepositoryInterface + */ + protected $entityDisplayRepository; + /** * The name of our entity type. * @@ -41,36 +59,24 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { */ protected $entityStorage; - /** - * The view builder for our entity type. - * - * @var \Drupal\Core\Entity\EntityViewBuilderInterface - */ - protected $entityViewBuilder; - /** * {@inheritdoc} */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entityTypeManager, EntityDisplayRepositoryInterface $entityDisplayRepository) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityRepositoryInterface $entityRepository, EntityTypeManagerInterface $entityTypeManager, EntityDisplayRepositoryInterface $entityDisplayRepository) { parent::__construct($configuration, $plugin_id, $plugin_definition); + // Allows entities to be loaded by UUID. + $this->entityRepository = $entityRepository; + + // Allows view modes to be retrieved. + $this->entityDisplayRepository = $entityDisplayRepository; + // Determine what entity type we are referring to. $this->entityTypeName = $this->getDerivativeId(); // Load various utilities related to our entity type. $this->entityTypeManager = $entityTypeManager; $this->entityStorage = $entityTypeManager->getStorage($this->entityTypeName); - - // Panelizer replaces the view_builder handler, but we want to use the - // original which has been moved to fallback_view_builder. - if ($entityTypeManager->hasHandler($this->entityTypeName, 'fallback_view_builder')) { - $this->entityViewBuilder = $entityTypeManager->getHandler($this->entityTypeName, 'fallback_view_builder'); - } - else { - $this->entityViewBuilder = $entityTypeManager->getHandler($this->entityTypeName, 'view_builder'); - } - - $this->view_mode_options = $entityDisplayRepository->getViewModeOptions($this->entityTypeName); } /** @@ -78,39 +84,53 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { */ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { return new static( - $configuration, $plugin_id, $plugin_definition, + $configuration, + $plugin_id, + $plugin_definition, + $container->get('entity.repository'), $container->get('entity.manager'), $container->get('entity_display.repository') ); } + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + 'entity' => 0, + 'entity_uuid' => '', + 'view_mode' => 'full', + ]; + } + /** * {@inheritdoc} */ public function blockForm($form, FormStateInterface $form_state) { $form = parent::blockForm($form, $form_state); $config = $this->configuration; + $options = $this->entityDisplayRepository->getViewModeOptions($this->entityTypeName); $form['entity'] = [ '#type' => 'entity_autocomplete', '#title' => $this->t('Entity'), '#target_type' => $this->entityTypeName, + '#default_value' => $this->getEntity(), '#required' => TRUE, ]; - if (isset($config['entity'])) { - if ($entity = $this->entityStorage->load($config['entity'])) { - $form['entity']['#default_value'] = $entity; - } - } - - $view_mode = isset($config['view_mode']) ? $config['view_mode'] : NULL; + $form['entity_uuid'] = array( + '#type' => 'value', + '#value' => $config['entity_uuid'], + ); $form['view_mode'] = [ '#type' => 'select', '#title' => $this->t('View mode'), - '#options' => $this->view_mode_options, - '#default_value' => $view_mode, + '#options' => $options, + '#default_value' => isset($options[$config['view_mode']]) ? $config['view_mode'] : reset($options), + '#access' => (count($options) > 1), ]; return $form; @@ -141,22 +161,54 @@ class EntityBlock extends BlockBase implements ContainerFactoryPluginInterface { $this->configuration['entity'] = $form_state->getValue('entity'); $this->configuration['view_mode'] = $form_state->getValue('view_mode'); + + if ($entity = $this->entityStorage->load($form_state->getValue('entity'))) { + if ($uuid = $entity->uuid()) { + $this->configuration['entity_uuid'] = $uuid; + } + } + } + + /** + * {@inheritdoc} + */ + protected function blockAccess(AccountInterface $account) { + if ($this->getEntity()) { + return $this->getEntity()->access('view', $account, TRUE); + } + return AccessResult::forbidden(); } /** * {@inheritdoc} */ public function build() { - if ($entity_id = $this->configuration['entity']) { - if (($entity = $this->entityStorage->load($entity_id)) && $entity->access('view')) { - $render_controller = \Drupal::entityTypeManager()->getViewBuilder($entity->getEntityTypeId()); - $view_mode = isset($this->configuration['view_mode']) ? $this->configuration['view_mode'] : 'default'; + if ($entity = $this->getEntity()) { + return $this->entityTypeManager->getViewBuilder($entity->getEntityTypeId())->view($entity, $this->configuration['view_mode']); + } + else { + return [ + '#markup' => $this->t('Unable to load %type entity %id.', array('%type' => $this->entityTypeName, '%id' => $this->configuration['entity'])), + ]; + } + } - return $render_controller->view($entity, $view_mode); - } + /** + * Loads the entity from configuration by UUID or ID. + * + * @return \Drupal\Core\Entity\EntityInterface|null + * The entity object, or NULL if there is no entity with the given ID/UUID. + */ + protected function getEntity() { + $config = $this->configuration; + + if (Uuid::isValid($config['entity_uuid'])) { + $entity = $this->entityRepository->loadEntityByUuid($this->entityTypeName, $config['entity_uuid']); + } + else { + $entity = $this->entityStorage->load($config['entity']); } - return []; + return $entity; } - }