190 lines
6.9 KiB
Plaintext
190 lines
6.9 KiB
Plaintext
<?php
|
|
|
|
/**
|
|
* @file
|
|
* Provides hook implementations for Layout Builder.
|
|
*/
|
|
|
|
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
|
|
use Drupal\Core\Entity\EntityInterface;
|
|
use Drupal\Core\Entity\FieldableEntityInterface;
|
|
use Drupal\Core\Form\FormStateInterface;
|
|
use Drupal\field\Entity\FieldConfig;
|
|
use Drupal\field\Entity\FieldStorageConfig;
|
|
|
|
/**
|
|
* Implements hook_help().
|
|
*/
|
|
function layout_builder_help($route_name) {
|
|
switch ($route_name) {
|
|
case 'help.page.layout_builder':
|
|
$output = '<h3>' . t('About') . '</h3>';
|
|
$output .= '<p>' . t('Layout Builder provides layout building utility.') . '</p>';
|
|
$output .= '<p>' . t('For more information, see the <a href=":layout-builder-documentation">online documentation for the Layout Builder module</a>.', [':layout-builder-documentation' => 'https://www.drupal.org/docs/8/core/modules/layout_builder']) . '</p>';
|
|
return $output;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements hook_entity_type_alter().
|
|
*/
|
|
function layout_builder_entity_type_alter(array &$entity_types) {
|
|
/** @var \Drupal\Core\Entity\EntityTypeInterface[] $entity_types */
|
|
foreach ($entity_types as $entity_type) {
|
|
if ($entity_type->entityClassImplements(FieldableEntityInterface::class) && $entity_type->hasLinkTemplate('canonical') && $entity_type->hasViewBuilderClass()) {
|
|
$entity_type->setLinkTemplate('layout-builder', $entity_type->getLinkTemplate('canonical') . '/layout');
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Removes the Layout Builder field both visually and from the #fields handling.
|
|
*
|
|
* This prevents any interaction with this field. It is rendered directly
|
|
* in layout_builder_entity_view_alter().
|
|
*
|
|
* @internal
|
|
*/
|
|
function _layout_builder_hide_layout_field(array &$form) {
|
|
unset($form['fields']['layout_builder__layout']);
|
|
$key = array_search('layout_builder__layout', $form['#fields']);
|
|
if ($key !== FALSE) {
|
|
unset($form['#fields'][$key]);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implements hook_form_FORM_ID_alter() for \Drupal\field_ui\Form\EntityFormDisplayEditForm.
|
|
*/
|
|
function layout_builder_form_entity_form_display_edit_form_alter(&$form, FormStateInterface $form_state) {
|
|
_layout_builder_hide_layout_field($form);
|
|
}
|
|
|
|
/**
|
|
* Implements hook_form_FORM_ID_alter() for \Drupal\field_ui\Form\EntityViewDisplayEditForm.
|
|
*/
|
|
function layout_builder_form_entity_view_display_edit_form_alter(&$form, FormStateInterface $form_state) {
|
|
/** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
|
|
$display = $form_state->getFormObject()->getEntity();
|
|
$entity_type = \Drupal::entityTypeManager()->getDefinition($display->getTargetEntityTypeId());
|
|
|
|
_layout_builder_hide_layout_field($form);
|
|
|
|
// @todo Expand to work for all view modes in
|
|
// https://www.drupal.org/node/2907413.
|
|
if (!in_array($display->getMode(), ['full', 'default'], TRUE)) {
|
|
return;
|
|
}
|
|
|
|
$form['layout'] = [
|
|
'#type' => 'details',
|
|
'#open' => TRUE,
|
|
'#title' => t('Layout options'),
|
|
'#tree' => TRUE,
|
|
];
|
|
// @todo Unchecking this box is a destructive action, this should be made
|
|
// clear to the user in https://www.drupal.org/node/2914484.
|
|
$form['layout']['allow_custom'] = [
|
|
'#type' => 'checkbox',
|
|
'#title' => t('Allow each @entity to have its layout customized.', [
|
|
'@entity' => $entity_type->getSingularLabel(),
|
|
]),
|
|
'#default_value' => $display->getThirdPartySetting('layout_builder', 'allow_custom', FALSE),
|
|
];
|
|
|
|
$form['#entity_builders'][] = 'layout_builder_form_entity_view_display_edit_entity_builder';
|
|
}
|
|
|
|
/**
|
|
* Entity builder for layout options on the entity view display form.
|
|
*
|
|
* @see layout_builder_form_entity_view_display_edit_form_alter()
|
|
*/
|
|
function layout_builder_form_entity_view_display_edit_entity_builder($entity_type_id, EntityViewDisplayInterface $display, &$form, FormStateInterface &$form_state) {
|
|
$new_value = (bool) $form_state->getValue(['layout', 'allow_custom'], FALSE);
|
|
$display->setThirdPartySetting('layout_builder', 'allow_custom', $new_value);
|
|
}
|
|
|
|
/**
|
|
* Implements hook_ENTITY_TYPE_presave().
|
|
*/
|
|
function layout_builder_entity_view_display_presave(EntityViewDisplayInterface $display) {
|
|
$original_value = isset($display->original) ? $display->original->getThirdPartySetting('layout_builder', 'allow_custom', FALSE) : FALSE;
|
|
$new_value = $display->getThirdPartySetting('layout_builder', 'allow_custom', FALSE);
|
|
if ($original_value !== $new_value) {
|
|
$entity_type_id = $display->getTargetEntityTypeId();
|
|
$bundle = $display->getTargetBundle();
|
|
|
|
if ($new_value) {
|
|
layout_builder_add_layout_section_field($entity_type_id, $bundle);
|
|
}
|
|
elseif ($field = FieldConfig::loadByName($entity_type_id, $bundle, 'layout_builder__layout')) {
|
|
$field->delete();
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Adds a layout section field to a given bundle.
|
|
*
|
|
* @param string $entity_type_id
|
|
* The entity type ID.
|
|
* @param string $bundle
|
|
* The bundle.
|
|
* @param string $field_name
|
|
* (optional) The name for the layout section field. Defaults to
|
|
* 'layout_builder__layout'.
|
|
*
|
|
* @return \Drupal\field\FieldConfigInterface
|
|
* A layout section field.
|
|
*/
|
|
function layout_builder_add_layout_section_field($entity_type_id, $bundle, $field_name = 'layout_builder__layout') {
|
|
$field = FieldConfig::loadByName($entity_type_id, $bundle, $field_name);
|
|
if (!$field) {
|
|
$field_storage = FieldStorageConfig::loadByName($entity_type_id, $field_name);
|
|
if (!$field_storage) {
|
|
$field_storage = FieldStorageConfig::create([
|
|
'entity_type' => $entity_type_id,
|
|
'field_name' => $field_name,
|
|
'type' => 'layout_section',
|
|
]);
|
|
$field_storage->save();
|
|
}
|
|
|
|
$field = FieldConfig::create([
|
|
'field_storage' => $field_storage,
|
|
'bundle' => $bundle,
|
|
'label' => t('Layout'),
|
|
]);
|
|
$field->save();
|
|
}
|
|
return $field;
|
|
}
|
|
|
|
/**
|
|
* Implements hook_entity_view_alter().
|
|
*/
|
|
function layout_builder_entity_view_alter(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display) {
|
|
if ($display->getThirdPartySetting('layout_builder', 'allow_custom', FALSE) && !$entity->layout_builder__layout->isEmpty()) {
|
|
$sections = $entity->layout_builder__layout->getSections();
|
|
foreach ($sections as $delta => $section) {
|
|
$build['_layout_builder'][$delta] = $section->toRenderArray();
|
|
}
|
|
|
|
// If field layout is active, that is all that needs to be removed.
|
|
if (\Drupal::moduleHandler()->moduleExists('field_layout') && isset($build['_field_layout'])) {
|
|
unset($build['_field_layout']);
|
|
return;
|
|
}
|
|
|
|
/** @var \Drupal\Core\Field\FieldDefinitionInterface[] $field_definitions */
|
|
$field_definitions = \Drupal::service('entity_field.manager')->getFieldDefinitions($display->getTargetEntityTypeId(), $display->getTargetBundle());
|
|
// Remove all display-configurable fields.
|
|
foreach (array_keys($display->getComponents()) as $name) {
|
|
if ($name !== 'layout_builder__layout' && isset($field_definitions[$name]) && $field_definitions[$name]->isDisplayConfigurable('view')) {
|
|
unset($build[$name]);
|
|
}
|
|
}
|
|
}
|
|
}
|