Version 1
[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     if ($layout_plugin instanceof PluginFormInterface) {
91       $form['field_layouts']['settings_wrapper']['layout_settings'] = [];
92       $subform_state = SubformState::createForSubform($form['field_layouts']['settings_wrapper']['layout_settings'], $form, $form_state);
93       $form['field_layouts']['settings_wrapper']['layout_settings'] = $layout_plugin->buildConfigurationForm($form['field_layouts']['settings_wrapper']['layout_settings'], $subform_state);
94     }
95
96     return $form;
97   }
98
99   /**
100    * Gets the layout plugin for the currently selected field layout.
101    *
102    * @param \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface $entity
103    *   The current form entity.
104    * @param \Drupal\Core\Form\FormStateInterface $form_state
105    *   The current state of the form.
106    *
107    * @return \Drupal\Core\Layout\LayoutInterface
108    *   The layout plugin.
109    */
110   protected function getLayout(EntityDisplayWithLayoutInterface $entity, FormStateInterface $form_state) {
111     if (!$layout_plugin = $form_state->get('layout_plugin')) {
112       $stored_layout_id = $entity->getLayoutId();
113       // Use selected layout if it exists, falling back to the stored layout.
114       $layout_id = $form_state->getValue('field_layout', $stored_layout_id);
115       // If the current layout is the stored layout, use the stored layout
116       // settings. Otherwise leave the settings empty.
117       $layout_settings = $layout_id === $stored_layout_id ? $entity->getLayoutSettings() : [];
118
119       $layout_plugin = $this->layoutPluginManager->createInstance($layout_id, $layout_settings);
120       $form_state->set('layout_plugin', $layout_plugin);
121     }
122     return $layout_plugin;
123   }
124
125   /**
126    * Ajax callback for the field layout settings form.
127    */
128   public static function settingsAjax($form, FormStateInterface $form_state) {
129     return $form['field_layouts']['settings_wrapper'];
130   }
131
132   /**
133    * Submit handler for the non-JS case.
134    */
135   public function settingsAjaxSubmit($form, FormStateInterface $form_state) {
136     $form_state->set('layout_plugin', NULL);
137     $form_state->setRebuild();
138   }
139
140   /**
141    * Overrides \Drupal\field_ui\Form\EntityDisplayFormBase::validateForm().
142    */
143   public function validateForm(array &$form, FormStateInterface $form_state) {
144     parent::validateForm($form, $form_state);
145
146     $layout_plugin = $this->getLayout($this->getEntity(), $form_state);
147     if ($layout_plugin instanceof PluginFormInterface) {
148       $subform_state = SubformState::createForSubform($form['field_layouts']['settings_wrapper']['layout_settings'], $form, $form_state);
149       $layout_plugin->validateConfigurationForm($form['field_layouts']['settings_wrapper']['layout_settings'], $subform_state);
150     }
151   }
152
153   /**
154    * Overrides \Drupal\field_ui\Form\EntityDisplayFormBase::submitForm().
155    */
156   public function submitForm(array &$form, FormStateInterface $form_state) {
157     parent::submitForm($form, $form_state);
158
159     $entity = $this->getEntity();
160     $layout_plugin = $this->getLayout($entity, $form_state);
161     if ($layout_plugin instanceof PluginFormInterface) {
162       $subform_state = SubformState::createForSubform($form['field_layouts']['settings_wrapper']['layout_settings'], $form, $form_state);
163       $layout_plugin->submitConfigurationForm($form['field_layouts']['settings_wrapper']['layout_settings'], $subform_state);
164     }
165
166     $entity->setLayout($layout_plugin);
167   }
168
169   /**
170    * Gets the form entity.
171    *
172    * @return \Drupal\field_layout\Display\EntityDisplayWithLayoutInterface
173    *   The current form entity.
174    */
175   abstract public function getEntity();
176
177 }