Updated Drupal to 8.6. This goes with the following updates because it's possible...
[yaffs-website] / web / core / modules / media_library / src / Plugin / views / field / MediaLibrarySelectForm.php
diff --git a/web/core/modules/media_library/src/Plugin/views/field/MediaLibrarySelectForm.php b/web/core/modules/media_library/src/Plugin/views/field/MediaLibrarySelectForm.php
new file mode 100644 (file)
index 0000000..72a4b50
--- /dev/null
@@ -0,0 +1,128 @@
+<?php
+
+namespace Drupal\media_library\Plugin\views\field;
+
+use Drupal\Core\Ajax\AjaxResponse;
+use Drupal\Core\Ajax\CloseDialogCommand;
+use Drupal\Core\Ajax\InvokeCommand;
+use Drupal\Core\Form\FormBuilderInterface;
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Url;
+use Drupal\views\Plugin\views\field\FieldPluginBase;
+use Drupal\views\Render\ViewsRenderPipelineMarkup;
+use Drupal\views\ResultRow;
+use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;
+
+/**
+ * Defines a field that outputs a checkbox and form for selecting media.
+ *
+ * @ViewsField("media_library_select_form")
+ *
+ * @internal
+ */
+class MediaLibrarySelectForm extends FieldPluginBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getValue(ResultRow $row, $field = NULL) {
+    return '<!--form-item-' . $this->options['id'] . '--' . $row->index . '-->';
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function render(ResultRow $values) {
+    return ViewsRenderPipelineMarkup::create($this->getValue($values));
+  }
+
+  /**
+   * Form constructor for the media library select form.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   */
+  public function viewsForm(array &$form, FormStateInterface $form_state) {
+    // Only add the bulk form options and buttons if there are results.
+    if (empty($this->view->result)) {
+      return;
+    }
+
+    // Render checkboxes for all rows.
+    $form[$this->options['id']]['#tree'] = TRUE;
+    foreach ($this->view->result as $row_index => $row) {
+      $entity = $this->getEntity($row);
+      $form[$this->options['id']][$row_index] = [
+        '#type' => 'checkbox',
+        '#title' => $this->t('Select @label', [
+          '@label' => $entity->label(),
+        ]),
+        '#title_display' => 'invisible',
+        '#return_value' => $entity->id(),
+      ];
+    }
+
+    // @todo Remove in https://www.drupal.org/project/drupal/issues/2504115
+    // Currently the default URL for all AJAX form elements is the current URL,
+    // not the form action. This causes bugs when this form is rendered from an
+    // AJAX path like /views/ajax, which cannot process AJAX form submits.
+    $url = parse_url($form['#action'], PHP_URL_PATH);
+    $query = \Drupal::request()->query->all();
+    $query[FormBuilderInterface::AJAX_FORM_REQUEST] = TRUE;
+    $form['actions']['submit']['#ajax'] = [
+      'url' => Url::fromUserInput($url),
+      'options' => [
+        'query' => $query,
+      ],
+      'callback' => [static::class, 'updateWidget'],
+    ];
+
+    $form['actions']['submit']['#value'] = $this->t('Select media');
+    $form['actions']['submit']['#field_id'] = $this->options['id'];
+  }
+
+  /**
+   * Submit handler for the media library select form.
+   *
+   * @param array $form
+   *   An associative array containing the structure of the form.
+   * @param \Drupal\Core\Form\FormStateInterface $form_state
+   *   The current state of the form.
+   *
+   * @return \Drupal\Core\Ajax\AjaxResponse
+   *   A command to send the selection to the current field widget.
+   */
+  public static function updateWidget(array &$form, FormStateInterface $form_state) {
+    $widget_id = \Drupal::request()->query->get('media_library_widget_id');
+    if (!$widget_id || !is_string($widget_id)) {
+      throw new BadRequestHttpException('The "media_library_widget_id" query parameter is required and must be a string.');
+    }
+    $field_id = $form_state->getTriggeringElement()['#field_id'];
+    $selected = array_values(array_filter($form_state->getValue($field_id, [])));
+    // Pass the selection to the field widget based on the current widget ID.
+    return (new AjaxResponse())
+      ->addCommand(new InvokeCommand("[data-media-library-widget-value=\"$widget_id\"]", 'val', [implode(',', $selected)]))
+      ->addCommand(new InvokeCommand("[data-media-library-widget-update=\"$widget_id\"]", 'trigger', ['mousedown']))
+      ->addCommand(new CloseDialogCommand());
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewsFormValidate(array &$form, FormStateInterface $form_state) {
+    $selected = array_filter($form_state->getValue($this->options['id']));
+    if (empty($selected)) {
+      $form_state->setErrorByName('', $this->t('No items selected.'));
+    }
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function clickSortable() {
+    return FALSE;
+  }
+
+}