Further Drupal 8.6.4 changes. Some core files were not committed before a commit...
[yaffs-website] / web / core / modules / media_library / src / Plugin / views / field / MediaLibrarySelectForm.php
1 <?php
2
3 namespace Drupal\media_library\Plugin\views\field;
4
5 use Drupal\Core\Ajax\AjaxResponse;
6 use Drupal\Core\Ajax\CloseDialogCommand;
7 use Drupal\Core\Ajax\InvokeCommand;
8 use Drupal\Core\Form\FormBuilderInterface;
9 use Drupal\Core\Form\FormStateInterface;
10 use Drupal\Core\Url;
11 use Drupal\views\Plugin\views\field\FieldPluginBase;
12 use Drupal\views\Render\ViewsRenderPipelineMarkup;
13 use Drupal\views\ResultRow;
14 use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
15
16 /**
17  * Defines a field that outputs a checkbox and form for selecting media.
18  *
19  * @ViewsField("media_library_select_form")
20  *
21  * @internal
22  */
23 class MediaLibrarySelectForm extends FieldPluginBase {
24
25   /**
26    * {@inheritdoc}
27    */
28   public function getValue(ResultRow $row, $field = NULL) {
29     return '<!--form-item-' . $this->options['id'] . '--' . $row->index . '-->';
30   }
31
32   /**
33    * {@inheritdoc}
34    */
35   public function render(ResultRow $values) {
36     return ViewsRenderPipelineMarkup::create($this->getValue($values));
37   }
38
39   /**
40    * Form constructor for the media library select form.
41    *
42    * @param array $form
43    *   An associative array containing the structure of the form.
44    * @param \Drupal\Core\Form\FormStateInterface $form_state
45    *   The current state of the form.
46    */
47   public function viewsForm(array &$form, FormStateInterface $form_state) {
48     // Only add the bulk form options and buttons if there are results.
49     if (empty($this->view->result)) {
50       return;
51     }
52
53     // Render checkboxes for all rows.
54     $form[$this->options['id']]['#tree'] = TRUE;
55     foreach ($this->view->result as $row_index => $row) {
56       $entity = $this->getEntity($row);
57       $form[$this->options['id']][$row_index] = [
58         '#type' => 'checkbox',
59         '#title' => $this->t('Select @label', [
60           '@label' => $entity->label(),
61         ]),
62         '#title_display' => 'invisible',
63         '#return_value' => $entity->id(),
64       ];
65     }
66
67     // @todo Remove in https://www.drupal.org/project/drupal/issues/2504115
68     // Currently the default URL for all AJAX form elements is the current URL,
69     // not the form action. This causes bugs when this form is rendered from an
70     // AJAX path like /views/ajax, which cannot process AJAX form submits.
71     $url = parse_url($form['#action'], PHP_URL_PATH);
72     $query = \Drupal::request()->query->all();
73     $query[FormBuilderInterface::AJAX_FORM_REQUEST] = TRUE;
74     $form['actions']['submit']['#ajax'] = [
75       'url' => Url::fromUserInput($url),
76       'options' => [
77         'query' => $query,
78       ],
79       'callback' => [static::class, 'updateWidget'],
80     ];
81
82     $form['actions']['submit']['#value'] = $this->t('Select media');
83     $form['actions']['submit']['#field_id'] = $this->options['id'];
84   }
85
86   /**
87    * Submit handler for the media library select form.
88    *
89    * @param array $form
90    *   An associative array containing the structure of the form.
91    * @param \Drupal\Core\Form\FormStateInterface $form_state
92    *   The current state of the form.
93    *
94    * @return \Drupal\Core\Ajax\AjaxResponse
95    *   A command to send the selection to the current field widget.
96    */
97   public static function updateWidget(array &$form, FormStateInterface $form_state) {
98     $widget_id = \Drupal::request()->query->get('media_library_widget_id');
99     if (!$widget_id || !is_string($widget_id)) {
100       throw new BadRequestHttpException('The "media_library_widget_id" query parameter is required and must be a string.');
101     }
102     $field_id = $form_state->getTriggeringElement()['#field_id'];
103     $selected = array_values(array_filter($form_state->getValue($field_id, [])));
104     // Pass the selection to the field widget based on the current widget ID.
105     return (new AjaxResponse())
106       ->addCommand(new InvokeCommand("[data-media-library-widget-value=\"$widget_id\"]", 'val', [implode(',', $selected)]))
107       ->addCommand(new InvokeCommand("[data-media-library-widget-update=\"$widget_id\"]", 'trigger', ['mousedown']))
108       ->addCommand(new CloseDialogCommand());
109   }
110
111   /**
112    * {@inheritdoc}
113    */
114   public function viewsFormValidate(array &$form, FormStateInterface $form_state) {
115     $selected = array_filter($form_state->getValue($this->options['id']));
116     if (empty($selected)) {
117       $form_state->setErrorByName('', $this->t('No items selected.'));
118     }
119   }
120
121   /**
122    * {@inheritdoc}
123    */
124   public function clickSortable() {
125     return FALSE;
126   }
127
128 }