View source
<?php
namespace Drupal\panelizer;
use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\EntityHandlerInterface;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\EntityTypeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\EntityViewBuilderInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Plugin\Context\Context;
use Drupal\Core\Plugin\Context\ContextDefinition;
use Drupal\panelizer\Plugin\PanelizerEntityManagerInterface;
use Drupal\Panels\PanelsDisplayManagerInterface;
use Drupal\panels\Plugin\DisplayVariant\PanelsDisplayVariant;
use Symfony\Component\DependencyInjection\ContainerInterface;
class PanelizerEntityViewBuilder implements EntityViewBuilderInterface, EntityHandlerInterface {
protected $entityTypeId;
protected $entityType;
protected $entityTypeManager;
protected $moduleHandler;
protected $panelizer;
protected $panelizerManager;
protected $panelsManager;
protected $panelizerPlugin;
public function __construct(EntityTypeInterface $entity_type, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler, PanelizerInterface $panelizer, PanelizerEntityManagerInterface $panelizer_manager, PanelsDisplayManagerInterface $panels_manager) {
$this->entityTypeId = $entity_type
->id();
$this->entityType = $entity_type;
$this->entityTypeManager = $entity_type_manager;
$this->moduleHandler = $module_handler;
$this->panelizer = $panelizer;
$this->panelizerManager = $panelizer_manager;
$this->panelsManager = $panels_manager;
}
public static function createInstance(ContainerInterface $container, EntityTypeInterface $entity_type) {
return new static($entity_type, $container
->get('entity_type.manager'), $container
->get('module_handler'), $container
->get('panelizer'), $container
->get('plugin.manager.panelizer_entity'), $container
->get('panels.display_manager'));
}
protected function getPanelizerPlugin() {
if (!isset($this->panelizerPlugin)) {
if (!$this->panelizerManager
->hasDefinition($this->entityTypeId)) {
$this->panelizerPlugin = FALSE;
}
else {
$this->panelizerPlugin = $this->panelizerManager
->createInstance($this->entityTypeId, []);
}
}
return $this->panelizerPlugin;
}
protected function isPanelizerEnabled(EntityViewDisplayInterface $display) {
return $display
->getThirdPartySetting('panelizer', 'enable', FALSE);
}
protected function getFallbackViewBuilder() {
return $this->entityTypeManager
->getHandler($this->entityTypeId, 'fallback_view_builder');
}
protected function getPanelsDisplay(EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
return $this->panelizer
->getPanelsDisplay($entity, $view_mode, $display);
}
protected function collectRenderDisplays($entities, $view_mode) {
return EntityViewDisplay::collectRenderDisplays($entities, $view_mode);
}
protected function getEntityContext(EntityInterface $entity) {
return new Context(new ContextDefinition('entity:' . $this->entityTypeId, NULL, TRUE), $entity);
}
public function buildComponents(array &$build, array $entities, array $displays, $view_mode) {
$fallback_view_builder = $this
->getFallbackViewBuilder();
$panelized_entities = [];
$fallback_entities = [];
foreach ($entities as $id => $entity) {
$display = $displays[$entity
->bundle()];
if ($this
->isPanelizerEnabled($display)) {
$panelized_entities[$id] = $entity;
}
else {
$fallback_entities[$id] = $entity;
}
}
if (!empty($fallback_entities)) {
$fallback_view_builder
->buildComponents($build, $fallback_entities, $displays, $view_mode);
}
if (!empty($panelized_entities)) {
$this->moduleHandler
->invokeAll('entity_prepare_view', [
$this->entityTypeId,
$panelized_entities,
$displays,
$view_mode,
]);
}
}
public function view(EntityInterface $entity, $view_mode = 'full', $langcode = NULL) {
$this->moduleHandler
->alter('panelizer_pre_view_builder', $view_mode, $entity, $langcode);
$displays = $this
->collectRenderDisplays([
$entity,
], $view_mode);
$display = $displays[$entity
->bundle()];
if (!$this
->isPanelizerEnabled($display)) {
return $this
->getFallbackViewBuilder()
->view($entity, $view_mode, $langcode);
}
$build = $this
->buildMultiplePanelized([
$entity
->id() => $entity,
], $displays, $view_mode, $langcode);
return $build[$entity
->id()];
}
public function viewMultiple(array $entities = [], $view_mode = 'full', $langcode = NULL) {
$displays = $this
->collectRenderDisplays($entities, $view_mode);
$panelized_entities = [];
$fallback_entities = [];
foreach ($entities as $id => $entity) {
$display = $displays[$entity
->bundle()];
if ($this
->isPanelizerEnabled($display)) {
$panelized_entities[$id] = $entity;
}
else {
$fallback_entities[$id] = $entity;
}
}
$result = [];
if (!empty($fallback_entities)) {
$result += $this
->getFallbackViewBuilder()
->viewMultiple($fallback_entities, $view_mode, $langcode);
}
if (!empty($panelized_entities)) {
$result += $this
->buildMultiplePanelized($panelized_entities, $displays, $view_mode, $langcode);
}
return $result;
}
public function resetCache(array $entities = NULL) {
$this
->getFallbackViewBuilder()
->resetCache($entities);
}
public function viewField(FieldItemListInterface $items, $display_options = []) {
return $this
->getFallbackViewBuilder()
->viewfield($items, $display_options);
}
public function viewFieldItem(FieldItemInterface $item, $display = []) {
return $this
->getFallbackViewBuilder()
->viewFieldItem($item, $display);
}
public function getCacheTags() {
return $this
->getFallbackViewBuilder()
->getCacheTags();
}
protected function buildMultiplePanelized(array $entities, array $displays, $view_mode, $langcode) {
$build = [];
foreach ($entities as $id => $entity) {
$panels_display = $this->panelizer
->getPanelsDisplay($entity, $view_mode, $displays[$entity
->bundle()]);
$settings = $this->panelizer
->getPanelizerSettings($entity
->getEntityTypeId(), $entity
->bundle(), $view_mode, $displays[$entity
->bundle()]);
$panels_display
->setContexts($this->panelizer
->getDisplayStaticContexts($settings['default'], $entity
->getEntityTypeId(), $entity
->bundle(), $view_mode, $displays[$entity
->bundle()]));
$build[$id] = $this
->buildPanelized($entity, $panels_display, $view_mode, $langcode);
$alter_types = [
"{$this->entityTypeId}_view",
'entity_view',
];
$this->moduleHandler
->alter($alter_types, $build[$id], $entity, $displays[$entity
->bundle()]);
}
return $build;
}
protected function buildPanelized(EntityInterface $entity, PanelsDisplayVariant $panels_display, $view_mode, $langcode) {
$contexts = $panels_display
->getContexts();
$contexts['@panelizer.entity_context:entity'] = $this
->getEntityContext($entity);
$panels_display
->setContexts($contexts);
$build = [
'#theme' => [
'panelizer_view_mode__' . $this->entityTypeId . '__' . $entity
->id(),
'panelizer_view_mode__' . $this->entityTypeId . '__' . $entity
->bundle(),
'panelizer_view_mode__' . $this->entityTypeId,
'panelizer_view_mode',
],
'#panelizer_plugin' => $this
->getPanelizerPlugin(),
'#panels_display' => $panels_display,
'#entity' => $entity,
'#view_mode' => $view_mode,
'#langcode' => $langcode,
'content' => $panels_display
->build(),
];
if (isset($build['content']['#title'])) {
$build['#title'] = $build['content']['#title'];
}
$entity_metadata = CacheableMetadata::createFromObject($entity);
CacheableMetadata::createFromObject($panels_display)
->merge($entity_metadata)
->applyTo($build);
$this
->getPanelizerPlugin()
->alterBuild($build, $entity, $panels_display, $view_mode);
return $build;
}
}