View source
<?php
namespace Drupal\panelizer;
use Drupal\Core\Batch\BatchBuilder;
use Drupal\Core\Block\BlockManagerInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\FieldableEntityInterface;
use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage;
use Drupal\layout_builder\Section;
use Drupal\layout_builder\SectionComponent;
use Symfony\Component\DependencyInjection\ContainerInterface;
final class LayoutBuilderMigration implements ContainerInjectionInterface {
private $panelizer;
private $entityTypeManager;
private $blockManager;
public function __construct(PanelizerInterface $panelizer, EntityTypeManagerInterface $entity_type_manager, BlockManagerInterface $block_manager) {
$this->panelizer = $panelizer;
$this->entityTypeManager = $entity_type_manager;
$this->blockManager = $block_manager;
module_load_install('panels');
}
public static function create(ContainerInterface $container) {
return new static($container
->get('panelizer'), $container
->get('entity_type.manager'), $container
->get('plugin.manager.block'));
}
private function doProcessDisplay(LayoutEntityDisplayInterface $display) {
$entity_type_id = $display
->getTargetEntityTypeId();
$bundle = $display
->getTargetBundle();
$mode = $display
->getMode();
$panelizer_settings = $this->panelizer
->getPanelizerSettings($entity_type_id, $bundle, $mode, $display);
if (empty($panelizer_settings['enable'])) {
return;
}
$display_storage = $this->entityTypeManager
->getStorage('entity_view_display');
$layout_storage = $this->entityTypeManager
->getStorage('layout');
$display
->enableLayoutBuilder()
->setOverridable($panelizer_settings['custom'])
->setThirdPartySetting('layout_library', 'enable', $panelizer_settings['allow']);
$panels_displays = $this->panelizer
->getDefaultPanelsDisplays($entity_type_id, $bundle, $mode, $display);
foreach ($panels_displays as $name => $panels_display) {
$configuration = $panels_display
->getConfiguration();
$configuration += [
'static_context' => [],
];
$section = $this
->toSection($configuration, $entity_type_id, $bundle);
$panels_display
->setConfiguration($configuration);
if ($name === $panelizer_settings['default']) {
$display
->appendSection($section);
if ($configuration['static_context']) {
$display
->setThirdPartySetting('core_context', 'contexts', $configuration['static_context']);
}
}
else {
$layout = $layout_storage
->create([
'id' => implode('_', [
$entity_type_id,
$bundle,
$mode,
$name,
]),
'targetEntityType' => $entity_type_id,
'targetBundle' => $bundle,
'label' => $panels_display
->label(),
]);
$layout
->appendSection($section);
if ($configuration['static_context']) {
$layout
->setThirdPartySetting('core_context', 'contexts', $configuration['static_context']);
}
$layout_storage
->save($layout);
}
}
$display_storage
->save($display);
$panelizer_settings['enable'] = FALSE;
$panelizer_settings['allow'] = FALSE;
$panelizer_settings['custom'] = FALSE;
$this->panelizer
->setPanelizerSettings($entity_type_id, $bundle, $mode, $panelizer_settings, $display);
}
private function doProcessEntity(FieldableEntityInterface $entity) {
$entity_type_id = $entity
->getEntityTypeId();
$bundle = $entity
->bundle();
foreach ($entity->panelizer as $panelizer_item) {
if ($panelizer_item->view_mode === 'full') {
if ($panelizer_item->panels_display) {
$configuration = $panelizer_item->panels_display;
$section = $this
->toSection($configuration, $entity_type_id, $bundle);
$sections = $entity
->get(OverridesSectionStorage::FIELD_NAME);
$sections
->appendSection($section);
$panelizer_item->panels_display = $configuration;
}
if ($panelizer_item->default && $panelizer_item->default !== '__bundle_default__' && $entity
->hasField('layout_selection')) {
$entity->layout_selection->target_id = implode('_', [
$entity_type_id,
$bundle,
$panelizer_item->view_mode,
$panelizer_item->default,
]);
}
$this->entityTypeManager
->getStorage($entity_type_id)
->save($entity);
break;
}
}
}
private function toSection(array &$configuration, $entity_type_id, $bundle) {
if (isset($configuration['static_context'])) {
$static_contexts = $configuration['static_context'];
}
else {
$static_contexts = [];
}
$to_component = function (array $block) use ($entity_type_id, $bundle, $static_contexts) {
if ($block['provider'] === 'ctools_block' && strpos($block['id'], 'entity_field:') === 0) {
list(, , $field_name) = explode(':', $block['id']);
$block['provider'] = 'layout_builder';
$block['id'] = "field_block:{$entity_type_id}:{$bundle}:{$field_name}";
unset($block['formatter']['region'], $block['formatter']['weight']);
if (isset($block['context_mapping']['entity']) && $block['context_mapping']['entity'] === '@panelizer.entity_context:entity') {
$block['context_mapping']['entity'] = 'layout_builder.entity';
}
}
$plugin_definition = $this->blockManager
->getDefinition($block['id']);
foreach ($plugin_definition['context_definitions'] as $context_name => $context_definition) {
if ($context_definition
->isRequired() && array_key_exists($context_name, $static_contexts)) {
$block['context'][$context_name] = $static_contexts[$context_name]['value'];
}
}
$block['configuration'] = $block;
unset($block['configuration']['provider'], $block['configuration']['region'], $block['configuration']['uuid'], $block['configuration']['weight']);
$block += [
'additional' => [],
];
return SectionComponent::fromArray($block);
};
$layout_id = panels_convert_plugin_ids_to_layout_discovery($configuration['layout']);
if ($layout_id) {
$configuration['layout'] = $layout_id;
}
return new Section($configuration['layout'], $configuration['layout_settings'], array_map($to_component, $configuration['blocks']));
}
private function buildBatch(LayoutEntityDisplayInterface $display) {
$batch = new BatchBuilder();
$batch
->addOperation([
static::class,
'processDisplay',
], (array) $display
->id());
$entity_type = $this->entityTypeManager
->getDefinition($display
->getTargetEntityTypeId());
$storage = $this->entityTypeManager
->getStorage($entity_type
->id());
$query = $storage
->getQuery()
->exists('panelizer')
->condition('panelizer.view_mode', 'full');
if ($entity_type
->hasKey('bundle')) {
$query
->condition($entity_type
->getKey('bundle'), $display
->getTargetBundle());
}
if ($entity_type
->isRevisionable()) {
$query
->allRevisions();
}
foreach (array_keys($query
->execute()) as $entity_id) {
$batch
->addOperation([
static::class,
'processEntity',
], [
$entity_type
->id(),
$entity_id,
]);
}
return $batch;
}
public static function fromDisplay(LayoutEntityDisplayInterface $display) {
return \Drupal::classResolver(static::class)
->buildBatch($display);
}
public static function processDisplay($id) {
$display = EntityViewDisplay::load($id);
assert($display instanceof LayoutEntityDisplayInterface);
\Drupal::classResolver(static::class)
->doProcessDisplay($display);
}
public static function processEntity($entity_type_id, $entity_id) {
$storage = \Drupal::entityTypeManager()
->getStorage($entity_type_id);
if ($storage
->getEntityType()
->isRevisionable()) {
$entity = $storage
->loadRevision($entity_id);
}
else {
$entity = $storage
->load($entity_id);
}
assert($entity instanceof FieldableEntityInterface);
\Drupal::classResolver(static::class)
->doProcessEntity($entity);
}
}