Pull merge.
[yaffs-website] / web / core / modules / field_layout / src / Form / FieldLayoutEntityDisplayFormTrait.php
1 <?php
2
3 namespace Drupal\field_layout\Form;
4
5 use Drupal\Core\Form\FormStateInterface;
6 use Drupal\Core\Form\SubformState;
7 use Drupal\Core\Plugin\PluginFormInterface;
8 use Drupal\field_layout\Display\EntityDisplayWithLayoutInterface;
9
10 /**
11  * Provides shared code for entity display forms.
12  *
13  * Both EntityViewDisplayEditForm and EntityFormDisplayEditForm must maintain
14  * their parent hierarchy, while being identically enhanced by Field Layout.
15  * This trait contains the code they both share.
16  */
17 trait FieldLayoutEntityDisplayFormTrait {
18
19   /**
20    * The field layout plugin manager.
21    *
22    * @var \Drupal\Core\Layout\LayoutPluginManagerInterface
23    */
24   protected $layoutPluginManager;
25
26   /**
27    * Overrides \Drupal\field_ui\Form\EntityDisplayFormBase::getRegions().
28    */
29   public function getRegions() {
30     $regions = [];
31
32     $layout_definition = $this->layoutPluginManager->getDefinition($this->getEntity()->getLayoutId());
33     foreach ($layout_definition->getRegions() as $name => $region) {
34       $regions[$name] = [
35         'title' => $region['label'],
36         'message' => $this->t('No field is displayed.'),
37       ];
38     }
39
40     $regions['hidden'] = [
41       'title' => $this->t('Disabled', [], ['context' => 'Plural']),
42       'message' => $this->t('No field is hidden.'),
43     ];
44
45     return $regions;
46   }
47
48   /**
49    * Overrides \Drupal\field_ui\Form\EntityDisplayFormBase::form().
50    */
51   public function form(array $form, FormStateInterface $form_state) {
52     $form = parent::form($form, $form_state);
53
54     $form['field_layouts'] = [
55       '#type' => 'details',
56       '#title' => $this->t('Layout settings'),
57     ];
58
59     $layout_plugin = $this->getLayout($this->getEntity(), $form_state);
60
61     $form['field_layouts']['field_layout'] = [
62       '#type' => 'select',
63       '#title' => $this->t('Select a layout'),
64       '#options' => $this->layoutPluginManager->getLayoutOptions(),
65       '#default_value' => $layout_plugin->getPluginId(),
66       '#ajax' => [
67         'callback' => '::settingsAjax',
68         'wrapper' => 'field-layout-settings-wrapper',
69         'trigger_as' => ['name' => 'field_layout_change'],
70       ],
71     ];
72     $form['field_layouts']['submit'] = [
73       '#type' => 'submit',
74       '#name' => 'field_layout_change',
75       '#value' => $this->t('Change layout'),
76       '#submit' => ['::settingsAjaxSubmit'],
77       '#attributes' => ['class' => ['js-hide']],
78       '#ajax' => [
79         'callback' => '::settingsAjax',
80         'wrapper' => 'field-layout-settings-wrapper',
81       ],
82     ];
83
84     $form['field_layouts']['settings_wrapper'] = [
85       '#type' => 'container',
86       '#id' => 'field-layout-settings-wrapper',
87       '#tree' => TRUE,
88     ];
89
90     $form['field_layouts']['settings_wrapper']['icon'] = $layout_plugin->getPluginDefinition()->getIcon();
91
92     if ($layout_plugin instanceof PluginFormInterface) {
93       $form['field_layouts']['settings_wrapper']['layout_settings'] = [];
94       $subform_state = SubformState::createForSubform($form['field_layouts']['settings_wrapper']['layout_settings'], $form, $form_state);
95       $form['field_layouts']['settings_wrapper']['layout_settings'] = $layout_plugin->buildConfigurationForm($form['field_layouts']['settings_wrapper']['layout_settings'], $subform_state);
96     }
97
98     return $form;
99   }
100
101   /**
102    * Gets the layout plugin for the currently selected field layout.
103    *
104    * @param \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface $entity
105    *   The current form entity.
106    * @param \Drupal\Core\Form\FormStateInterface $form_state
107    *   The current state of the form.
108    *
109    * @return \Drupal\Core\Layout\LayoutInterface
110    *   The layout plugin.
111    */
112   protected function getLayout(EntityDisplayWithLayoutInterface $entity, FormStateInterface $form_state) {
113     if (!$layout_plugin = $form_state->get('layout_plugin')) {
114       $stored_layout_id = $entity->getLayoutId();
115       // Use selected layout if it exists, falling back to the stored layout.
116       $layout_id = $form_state->getValue('field_layout', $stored_layout_id);
117       // If the current layout is the stored layout, use the stored layout
118       // settings. Otherwise leave the settings empty.
119       $layout_settings = $layout_id === $stored_layout_id ? $entity->getLayoutSettings() : [];
120
121       $layout_plugin = $this->layoutPluginManager->createInstance($layout_id, $layout_settings);
122       $form_state->set('layout_plugin', $layout_plugin);
123     }
124     return $layout_plugin;
125   }
126
127   /**
128    * Ajax callback for the field layout settings form.
129    */
130   public static function settingsAjax($form, FormStateInterface $form_state) {
131     return $form['field_layouts']['settings_wrapper'];
132   }
133
134   /**
135    * Submit handler for the non-JS case.
136    */
137   public function settingsAjaxSubmit($form, FormStateInterface $form_state) {
138     $form_state->set('layout_plugin', NULL);
139     $form_state->setRebuild();
140   }
141
142   /**
143    * Overrides \Drupal\field_ui\Form\EntityDisplayFormBase::validateForm().
144    */
145   public function validateForm(array &$form, FormStateInterface $form_state) {
146     parent::validateForm($form, $form_state);
147
148     $layout_plugin = $this->getLayout($this->getEntity(), $form_state);
149     if ($layout_plugin instanceof PluginFormInterface) {
150       $subform_state = SubformState::createForSubform($form['field_layouts']['settings_wrapper']['layout_settings'], $form, $form_state);
151       $layout_plugin->validateConfigurationForm($form['field_layouts']['settings_wrapper']['layout_settings'], $subform_state);
152     }
153   }
154
155   /**
156    * Overrides \Drupal\field_ui\Form\EntityDisplayFormBase::submitForm().
157    */
158   public function submitForm(array &$form, FormStateInterface $form_state) {
159     parent::submitForm($form, $form_state);
160
161     $entity = $this->getEntity();
162     $layout_plugin = $this->getLayout($entity, $form_state);
163     if ($layout_plugin instanceof PluginFormInterface) {
164       $subform_state = SubformState::createForSubform($form['field_layouts']['settings_wrapper']['layout_settings'], $form, $form_state);
165       $layout_plugin->submitConfigurationForm($form['field_layouts']['settings_wrapper']['layout_settings'], $subform_state);
166     }
167
168     $entity->setLayout($layout_plugin);
169   }
170
171   /**
172    * Gets the form entity.
173    *
174    * @return \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface
175    *   The current form entity.
176    */
177   abstract public function getEntity();
178
179 }