3 namespace Drupal\layout_builder\Form;
5 use Drupal\Core\Entity\EntityInterface;
6 use Drupal\Core\Field\FieldDefinitionInterface;
7 use Drupal\Core\Form\FormStateInterface;
8 use Drupal\field_ui\Form\EntityViewDisplayEditForm;
9 use Drupal\layout_builder\Entity\LayoutEntityDisplayInterface;
10 use Drupal\layout_builder\Plugin\SectionStorage\OverridesSectionStorage;
11 use Drupal\layout_builder\SectionStorageInterface;
14 * Edit form for the LayoutBuilderEntityViewDisplay entity type.
17 * Layout Builder is currently experimental and should only be leveraged by
18 * experimental modules and development releases of contributed modules.
19 * See https://www.drupal.org/core/experimental for more information.
21 class LayoutBuilderEntityViewDisplayForm extends EntityViewDisplayEditForm {
24 * The entity being used by this form.
26 * @var \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface
31 * The storage section.
33 * @var \Drupal\layout_builder\DefaultsSectionStorageInterface
35 protected $sectionStorage;
40 public function buildForm(array $form, FormStateInterface $form_state, SectionStorageInterface $section_storage = NULL) {
41 $this->sectionStorage = $section_storage;
42 return parent::buildForm($form, $form_state);
48 public function form(array $form, FormStateInterface $form_state) {
49 $form = parent::form($form, $form_state);
51 // Remove the Layout Builder field from the list.
52 $form['#fields'] = array_diff($form['#fields'], [OverridesSectionStorage::FIELD_NAME]);
53 unset($form['fields'][OverridesSectionStorage::FIELD_NAME]);
55 $is_enabled = $this->entity->isLayoutBuilderEnabled();
57 // Hide the table of fields.
58 $form['fields']['#access'] = FALSE;
59 $form['#fields'] = [];
63 $form['manage_layout'] = [
65 '#title' => $this->t('Manage layout'),
67 '#attributes' => ['class' => ['button']],
68 '#url' => $this->sectionStorage->getLayoutBuilderUrl(),
69 '#access' => $is_enabled,
75 '#title' => $this->t('Layout options'),
79 $form['layout']['enabled'] = [
80 '#type' => 'checkbox',
81 '#title' => $this->t('Use Layout Builder'),
82 '#default_value' => $is_enabled,
84 $form['#entity_builders']['layout_builder'] = '::entityFormEntityBuild';
86 // @todo Expand to work for all view modes in
87 // https://www.drupal.org/node/2907413.
88 if ($this->entity->getMode() === 'default') {
89 $entity_type = $this->entityTypeManager->getDefinition($this->entity->getTargetEntityTypeId());
90 $form['layout']['allow_custom'] = [
91 '#type' => 'checkbox',
92 '#title' => $this->t('Allow each @entity to have its layout customized.', [
93 '@entity' => $entity_type->getSingularLabel(),
95 '#default_value' => $this->entity->isOverridable(),
98 ':input[name="layout[enabled]"]' => ['checked' => FALSE],
101 ':input[name="layout[enabled]"]' => ['checked' => FALSE],
106 $form['layout']['allow_custom']['#attributes']['disabled'] = 'disabled';
108 // Prevent turning off overrides while any exist.
109 if ($this->hasOverrides($this->entity)) {
110 $form['layout']['enabled']['#disabled'] = TRUE;
111 $form['layout']['enabled']['#description'] = $this->t('You must revert all customized layouts of this display before you can disable this option.');
112 $form['layout']['allow_custom']['#disabled'] = TRUE;
113 $form['layout']['allow_custom']['#description'] = $this->t('You must revert all customized layouts of this display before you can disable this option.');
114 unset($form['layout']['allow_custom']['#states']);
115 unset($form['#entity_builders']['layout_builder']);
122 * Determines if the defaults have any overrides.
124 * @param \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface $display
125 * The entity display.
128 * TRUE if there are any overrides of this default, FALSE otherwise.
130 protected function hasOverrides(LayoutEntityDisplayInterface $display) {
131 if (!$display->isOverridable()) {
135 $entity_type = $this->entityTypeManager->getDefinition($display->getTargetEntityTypeId());
136 $query = $this->entityTypeManager->getStorage($display->getTargetEntityTypeId())->getQuery()
137 ->exists(OverridesSectionStorage::FIELD_NAME);
138 if ($bundle_key = $entity_type->getKey('bundle')) {
139 $query->condition($bundle_key, $display->getTargetBundle());
141 return (bool) $query->count()->execute();
147 protected function copyFormValuesToEntity(EntityInterface $entity, array $form, FormStateInterface $form_state) {
148 // Do not process field values if Layout Builder is or will be enabled.
149 $set_enabled = (bool) $form_state->getValue(['layout', 'enabled'], FALSE);
150 /** @var \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface $entity */
151 $already_enabled = $entity->isLayoutBuilderEnabled();
152 if ($already_enabled || $set_enabled) {
153 $form['#fields'] = [];
154 $form['#extra'] = [];
157 parent::copyFormValuesToEntity($entity, $form, $form_state);
161 * Entity builder for layout options on the entity view display form.
163 public function entityFormEntityBuild($entity_type_id, LayoutEntityDisplayInterface $display, &$form, FormStateInterface &$form_state) {
164 $set_enabled = (bool) $form_state->getValue(['layout', 'enabled'], FALSE);
165 $already_enabled = $display->isLayoutBuilderEnabled();
168 $overridable = (bool) $form_state->getValue(['layout', 'allow_custom'], FALSE);
169 $display->setOverridable($overridable);
171 if (!$already_enabled) {
172 $display->enableLayoutBuilder();
175 elseif ($already_enabled) {
176 $form_state->setRedirectUrl($this->sectionStorage->getLayoutBuilderUrl('disable'));
183 protected function buildFieldRow(FieldDefinitionInterface $field_definition, array $form, FormStateInterface $form_state) {
184 if ($this->entity->isLayoutBuilderEnabled()) {
188 return parent::buildFieldRow($field_definition, $form, $form_state);
194 protected function buildExtraFieldRow($field_id, $extra_field) {
195 if ($this->entity->isLayoutBuilderEnabled()) {
199 return parent::buildExtraFieldRow($field_id, $extra_field);