fd44b0c86aa8546264a4f6c795df473e4902b0e2
[yaffs-website] / web / core / modules / settings_tray / src / Block / BlockEntitySettingTrayForm.php
1 <?php
2
3 namespace Drupal\settings_tray\Block;
4
5 use Drupal\block\BlockForm;
6 use Drupal\block\BlockInterface;
7 use Drupal\Component\Utility\Html;
8 use Drupal\Core\Ajax\AjaxResponse;
9 use Drupal\Core\Ajax\RedirectCommand;
10 use Drupal\Core\Ajax\ReplaceCommand;
11 use Drupal\Core\Block\BlockPluginInterface;
12 use Drupal\Core\Form\FormStateInterface;
13 use Drupal\Core\Plugin\PluginWithFormsInterface;
14 use Drupal\Core\Url;
15
16 /**
17  * Provides form for block instance forms when used in the off-canvas dialog.
18  *
19  * This form removes advanced sections of regular block form such as the
20  * visibility settings, machine ID and region.
21  *
22  * @internal
23  */
24 class BlockEntitySettingTrayForm extends BlockForm {
25
26   /**
27    * Provides a title callback to get the block's admin label.
28    *
29    * @param \Drupal\block\BlockInterface $block
30    *   The block entity.
31    *
32    * @return \Drupal\Core\StringTranslation\TranslatableMarkup
33    *   The title.
34    */
35   public function title(BlockInterface $block) {
36     // @todo Wrap "Configure " in <span class="visually-hidden"></span> once
37     //   https://www.drupal.org/node/2359901 is fixed.
38     return $this->t('Configure @block', ['@block' => $block->getPlugin()->getPluginDefinition()['admin_label']]);
39   }
40
41   /**
42    * {@inheritdoc}
43    */
44   public function form(array $form, FormStateInterface $form_state) {
45     $form = parent::form($form, $form_state);
46
47     // Create link to full block form.
48     $query = [];
49     if ($destination = $this->getRequest()->query->get('destination')) {
50       $query['destination'] = $destination;
51     }
52     $form['advanced_link'] = [
53       '#type' => 'link',
54       '#title' => $this->t('Advanced block options'),
55       '#url' => $this->entity->toUrl('edit-form', ['query' => $query]),
56       '#weight' => 1000,
57     ];
58
59     // Remove the ID and region elements.
60     unset($form['id'], $form['region'], $form['settings']['admin_label']);
61
62     if (isset($form['settings']['label_display']) && isset($form['settings']['label'])) {
63       // Only show the label input if the label will be shown on the page.
64       $form['settings']['label_display']['#weight'] = -100;
65       $form['settings']['label']['#states']['visible'] = [
66         ':input[name="settings[label_display]"]' => ['checked' => TRUE],
67       ];
68
69       // Relabel to "Block title" because on the front-end this may be confused
70       // with page title.
71       $form['settings']['label']['#title'] = $this->t("Block title");
72       $form['settings']['label_display']['#title'] = $this->t("Display block title");
73     }
74     return $form;
75   }
76
77   /**
78    * {@inheritdoc}
79    */
80   protected function actions(array $form, FormStateInterface $form_state) {
81     $actions = parent::actions($form, $form_state);
82     $actions['submit']['#value'] = $this->t('Save @block', ['@block' => $this->entity->getPlugin()->getPluginDefinition()['admin_label']]);
83     $actions['delete']['#access'] = FALSE;
84     return $actions;
85   }
86
87   /**
88    * {@inheritdoc}
89    */
90   protected function buildVisibilityInterface(array $form, FormStateInterface $form_state) {
91     // Do not display the visibility.
92     return [];
93   }
94
95   /**
96    * {@inheritdoc}
97    */
98   protected function validateVisibility(array $form, FormStateInterface $form_state) {
99     // Intentionally empty.
100   }
101
102   /**
103    * {@inheritdoc}
104    */
105   protected function submitVisibility(array $form, FormStateInterface $form_state) {
106     // Intentionally empty.
107   }
108
109   /**
110    * {@inheritdoc}
111    */
112   protected function getPluginForm(BlockPluginInterface $block) {
113     if ($block instanceof PluginWithFormsInterface) {
114       return $this->pluginFormFactory->createInstance($block, 'settings_tray', 'configure');
115     }
116     return $block;
117   }
118
119   /**
120    * {@inheritdoc}
121    */
122   public function buildForm(array $form, FormStateInterface $form_state) {
123     $form = parent::buildForm($form, $form_state);
124     $form['actions']['submit']['#ajax'] = [
125       'callback' => '::submitFormDialog',
126     ];
127     $form['#attached']['library'][] = 'core/drupal.dialog.ajax';
128
129     // static::submitFormDialog() requires data-drupal-selector to be the same
130     // between the various Ajax requests. A bug in
131     // \Drupal\Core\Form\FormBuilder prevents that from happening unless
132     // $form['#id'] is also the same. Normally, #id is set to a unique HTML ID
133     // via Html::getUniqueId(), but here we bypass that in order to work around
134     // the data-drupal-selector bug. This is okay so long as we assume that this
135     // form only ever occurs once on a page.
136     // @todo Remove this workaround once https://www.drupal.org/node/2897377 is
137     //   fixed.
138     $form['#id'] = Html::getId($form_state->getBuildInfo()['form_id']);
139
140     return $form;
141   }
142
143   /**
144    * Submit form dialog #ajax callback.
145    *
146    * @param array $form
147    *   An associative array containing the structure of the form.
148    * @param \Drupal\Core\Form\FormStateInterface $form_state
149    *   The current state of the form.
150    *
151    * @return \Drupal\Core\Ajax\AjaxResponse
152    *   An AJAX response that display validation error messages or redirects
153    *   to a URL
154    *
155    * @todo Repalce this callback with generic trait in
156    *   https://www.drupal.org/node/2896535.
157    */
158   public function submitFormDialog(array &$form, FormStateInterface $form_state) {
159     $response = new AjaxResponse();
160     if ($form_state->hasAnyErrors()) {
161       $form['status_messages'] = [
162         '#type' => 'status_messages',
163         '#weight' => -1000,
164       ];
165       $command = new ReplaceCommand('[data-drupal-selector="' . $form['#attributes']['data-drupal-selector'] . '"]', $form);
166     }
167     else {
168       if ($redirect_url = $this->getRedirectUrl()) {
169         $command = new RedirectCommand($redirect_url->setAbsolute()->toString());
170       }
171       else {
172         // Settings Tray always provides a destination.
173         throw new \Exception("No destination provided by Settings Tray form");
174       }
175     }
176     return $response->addCommand($command);
177   }
178
179   /**
180    * Gets the form's redirect URL from 'destination' provide in the request.
181    *
182    * @return \Drupal\Core\Url|null
183    *   The redirect URL or NULL if dialog should just be closed.
184    */
185   protected function getRedirectUrl() {
186     // \Drupal\Core\Routing\RedirectDestination::get() cannot be used directly
187     // because it will use <current> if 'destination' is not in the query
188     // string.
189     if ($this->getRequest()->query->has('destination') && $destination = $this->getRedirectDestination()->get()) {
190       return Url::fromUserInput('/' . $destination);
191     }
192   }
193
194 }