Pull merge.
[yaffs-website] / web / core / modules / layout_builder / src / Form / LayoutBuilderEntityViewDisplayForm.php
1 <?php
2
3 namespace Drupal\layout_builder\Form;
4
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;
12
13 /**
14  * Edit form for the LayoutBuilderEntityViewDisplay entity type.
15  *
16  * @internal
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.
20  */
21 class LayoutBuilderEntityViewDisplayForm extends EntityViewDisplayEditForm {
22
23   /**
24    * The entity being used by this form.
25    *
26    * @var \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface
27    */
28   protected $entity;
29
30   /**
31    * The storage section.
32    *
33    * @var \Drupal\layout_builder\DefaultsSectionStorageInterface
34    */
35   protected $sectionStorage;
36
37   /**
38    * {@inheritdoc}
39    */
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);
43   }
44
45   /**
46    * {@inheritdoc}
47    */
48   public function form(array $form, FormStateInterface $form_state) {
49     $form = parent::form($form, $form_state);
50
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]);
54
55     $is_enabled = $this->entity->isLayoutBuilderEnabled();
56     if ($is_enabled) {
57       // Hide the table of fields.
58       $form['fields']['#access'] = FALSE;
59       $form['#fields'] = [];
60       $form['#extra'] = [];
61     }
62
63     $form['manage_layout'] = [
64       '#type' => 'link',
65       '#title' => $this->t('Manage layout'),
66       '#weight' => -10,
67       '#attributes' => ['class' => ['button']],
68       '#url' => $this->sectionStorage->getLayoutBuilderUrl(),
69       '#access' => $is_enabled,
70     ];
71
72     $form['layout'] = [
73       '#type' => 'details',
74       '#open' => TRUE,
75       '#title' => $this->t('Layout options'),
76       '#tree' => TRUE,
77     ];
78
79     $form['layout']['enabled'] = [
80       '#type' => 'checkbox',
81       '#title' => $this->t('Use Layout Builder'),
82       '#default_value' => $is_enabled,
83     ];
84     $form['#entity_builders']['layout_builder'] = '::entityFormEntityBuild';
85
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(),
94         ]),
95         '#default_value' => $this->entity->isOverridable(),
96         '#states' => [
97           'disabled' => [
98             ':input[name="layout[enabled]"]' => ['checked' => FALSE],
99           ],
100           'invisible' => [
101             ':input[name="layout[enabled]"]' => ['checked' => FALSE],
102           ],
103         ],
104       ];
105       if (!$is_enabled) {
106         $form['layout']['allow_custom']['#attributes']['disabled'] = 'disabled';
107       }
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']);
116       }
117     }
118     return $form;
119   }
120
121   /**
122    * Determines if the defaults have any overrides.
123    *
124    * @param \Drupal\layout_builder\Entity\LayoutEntityDisplayInterface $display
125    *   The entity display.
126    *
127    * @return bool
128    *   TRUE if there are any overrides of this default, FALSE otherwise.
129    */
130   protected function hasOverrides(LayoutEntityDisplayInterface $display) {
131     if (!$display->isOverridable()) {
132       return FALSE;
133     }
134
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());
140     }
141     return (bool) $query->count()->execute();
142   }
143
144   /**
145    * {@inheritdoc}
146    */
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'] = [];
155     }
156
157     parent::copyFormValuesToEntity($entity, $form, $form_state);
158   }
159
160   /**
161    * Entity builder for layout options on the entity view display form.
162    */
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();
166
167     if ($set_enabled) {
168       $overridable = (bool) $form_state->getValue(['layout', 'allow_custom'], FALSE);
169       $display->setOverridable($overridable);
170
171       if (!$already_enabled) {
172         $display->enableLayoutBuilder();
173       }
174     }
175     elseif ($already_enabled) {
176       $form_state->setRedirectUrl($this->sectionStorage->getLayoutBuilderUrl('disable'));
177     }
178   }
179
180   /**
181    * {@inheritdoc}
182    */
183   protected function buildFieldRow(FieldDefinitionInterface $field_definition, array $form, FormStateInterface $form_state) {
184     if ($this->entity->isLayoutBuilderEnabled()) {
185       return [];
186     }
187
188     return parent::buildFieldRow($field_definition, $form, $form_state);
189   }
190
191   /**
192    * {@inheritdoc}
193    */
194   protected function buildExtraFieldRow($field_id, $extra_field) {
195     if ($this->entity->isLayoutBuilderEnabled()) {
196       return [];
197     }
198
199     return parent::buildExtraFieldRow($field_id, $extra_field);
200   }
201
202 }