reverted: --- b/core/modules/media/js/ajax.js +++ /dev/null @@ -1,32 +0,0 @@ -(function ($, Drupal) { - - 'use strict'; - - /** - * JavaScript handler for opening of modal add media form. - * - * TODO: es6.js!!! - * - * @param ajax - * @param response - * @param status - */ - Drupal.AjaxCommands.prototype.openModalMediaForm = function (ajax, response, status) { - var openDialogAjax = new Drupal.Ajax(null, null, { - url: '/media/add-modal', - dialogType: 'modal', - submit: { - file_ids: response.file_ids, - field_widget_id: response.field_widget_id, - dialogOptions: { - width: 800 - } - }, - progress: { - type: 'throbber' - } - }); - - openDialogAjax.execute(); - }; -})(jQuery, Drupal); reverted: --- b/core/modules/media/media.libraries.yml +++ a/core/modules/media/media.libraries.yml @@ -11,8 +11,3 @@ js/type_form.js: {} dependencies: - core/drupal.form - -open_modal_media_form: - version: VERSION - js: - js/ajax.js: {} diff -u b/core/modules/media/media.module b/core/modules/media/media.module --- b/core/modules/media/media.module +++ b/core/modules/media/media.module @@ -110,19 +110,15 @@ * Result of validation. */ function media_validate_file_upload(FileInterface $file) { - $extension = pathinfo($file->getFilename(), PATHINFO_EXTENSION); + $media_types = \Drupal::service('media.type_guesser.file')->getTypesForFile($file); - $availableMediaTypes = \Drupal::service('media_type.manager') - ->getTypesByExtension($extension); - - if (empty($availableMediaTypes)) { + if (empty($media_types)) { return [ t('%filename could not be matched to any media types.', [ '%filename' => $file->getFilename(), ]), ]; } - return []; } diff -u b/core/modules/media/media.routing.yml b/core/modules/media/media.routing.yml --- b/core/modules/media/media.routing.yml +++ b/core/modules/media/media.routing.yml @@ -20,13 +20,6 @@ _access_media_revision: 'view' media: \d+ -entity.media.add_modal: - path: '/media/add-modal' - defaults: - _form: '\Drupal\media\Form\MediaModalForm' - requirements: - _entity_create_access: media - entity.media.add_file: path: '/media/add-file/{media_type}/{file}/{selector}' defaults: reverted: --- b/core/modules/media/src/Form/MediaModalForm.php +++ /dev/null @@ -1,580 +0,0 @@ -renderer = $renderer; - $this->elementInfo = $element_info; - $this->formValidator = $form_validator; - $this->formSubmitter = $form_submitter; - $this->entityTypeManager = $entity_type_manager; - $this->mediaTypeManager = $media_type_manager; - } - - /** - * {@inheritdoc} - */ - public static function create(ContainerInterface $container) { - return new static( - $container->get('renderer'), - $container->get('element_info'), - $container->get('form_validator'), - $container->get('form_submitter'), - $container->get('entity_type.manager'), - $container->get('media_type.manager') - ); - } - - /** - * {@inheritdoc} - */ - public function getFormId() { - return 'media_modal_form'; - } - - /** - * Init form state, it's executed for first time when dialog is open. - * - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Form state. - */ - protected function initFormState(FormStateInterface $form_state) { - // Get data provided by OpenModalMediaFormCommand. - $form_state->set('queued_fids', $form_state->getUserInput()['file_ids']); - $form_state->set('field_widget_id', $form_state->getUserInput()['field_widget_id']); - - // Init clean state of processed media IDs. - $form_state->set('processed_media_ids', []); - - $form_state->setCached(TRUE); - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, FormStateInterface $form_state) { - // Initialize form state if there are no queued files. - if (empty($form_state->get('queued_fids'))) { - $this->initFormState($form_state); - } - - // Get file IDs that should be processed. - $file_ids = $form_state->get('queued_fids'); - - // Get list of available media types for file. - $file = $this->getFileById($file_ids[0]); - $list_of_media_types = $this->getMediaTypeList($file_ids[0]); - - // Get selected media type. - $trigger_element = $form_state->getTriggeringElement(); - if (!empty($trigger_element) && $trigger_element['#name'] === 'media_type') { - $selected_media_type = $trigger_element['#value']; - } - else { - reset($list_of_media_types); - $selected_media_type = key($list_of_media_types); - } - - // Create media entity from file. - $media = $this->createMediaFromFile($selected_media_type, $file); - - // Generate form. - $form['#prefix'] = '
'; - $form['#suffix'] = '
'; - - $form['status_messages'] = $this->getStatusMessagesElement($form_state); - - $form['media_type'] = $this->getTypeSelectElement($list_of_media_types); - - // Prepare inner media form. - $form['#process'] = $this->elementInfo->getInfoProperty('form', '#process', []); - $form['#process'][] = '::processForm'; - $form[static::INNER_FORM_ID] = $this->getInnerMediaForm($form_state, $media); - - // Create action buttons for modal dialog. - $form['actions'] = $this->getActionsElement(); - - return $form; - } - - /** - * Creates build array for media type selector. - * - * Prefix is required in order to properly replace element over AJAX. - * - * @param array $list_of_media_types - * List of media types that should be displayed in select field. - * - * @return array - * Returns build array for media type selector. - */ - protected function getTypeSelectElement(array $list_of_media_types) { - return [ - '#id' => 'media-modal-form-media-type', - '#prefix' => '
', - '#suffix' => '
', - '#type' => 'select', - '#title' => $this->t('Media type'), - '#options' => $list_of_media_types, - '#ajax' => [ - 'callback' => '::ajaxChangeType', - 'wrapper' => 'media-modal-form', - ], - ]; - } - - /** - * Get build array for actions element. - * - * @return array - * Returns actions build array. - */ - protected function getActionsElement() { - $actionsElement = [ - '#type' => 'actions', - ]; - - $actionsElement['submit_form'] = [ - '#type' => 'submit', - '#name' => 'media-modal-form-submit', - '#value' => $this->t('Save'), - '#validate' => ['::validateForm'], - '#submit' => ['::submitForm'], - '#ajax' => [ - 'callback' => '::ajaxSubmitForm', - 'wrapper' => 'media-modal-form', - 'event' => 'click', - ], - ]; - - return $actionsElement; - } - - /** - * Get status messages element. - * - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Form state. - * - * @return array - * Returns status messages element. - */ - protected function getStatusMessagesElement(FormStateInterface $form_state) { - $status_messages_element = [ - '#prefix' => '
', - '#suffix' => '
', - ]; - - if ($form_state->getErrors()) { - $status_messages_element['#type'] = 'status_messages'; - } - - return $status_messages_element; - } - - /** - * Generate inner media form for provided media entity. - * - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Form state. - * @param \Drupal\Core\Entity\EntityInterface $media - * Media entity that will be edited in inner form. - * - * @return array - * Returns render array for inner media form. - */ - protected function getInnerMediaForm(FormStateInterface $form_state, EntityInterface $media) { - $inner_form_object = \Drupal::entityTypeManager() - ->getFormObject('media', 'edit') - ->setEntity($media); - - $form_state->set(static::INNER_FORM_OBJECT_KEY, $inner_form_object); - - $inner_form_state = static::createInnerFormState($form_state, $inner_form_object); - - $inner_form = ['#parents' => [static::INNER_FORM_ID]]; - $inner_form = $inner_form_object->buildForm($inner_form, $inner_form_state); - - $inner_form['#prefix'] = '
'; - $inner_form['#suffix'] = '
'; - - $inner_form['#type'] = 'container'; - $inner_form['#theme_wrappers'] = $this->elementInfo->getInfoProperty('container', '#theme_wrappers', []); - unset($inner_form['form_token']); - - if (!empty($inner_form['#process'])) { - $inner_form_state->set('#process', $inner_form['#process']); - unset($inner_form['#process']); - } - else { - $inner_form_state->set('#process', []); - } - - // Remove actions from subform, because wrapping form will handle it. - if (!empty($inner_form['actions'])) { - if (isset($inner_form['actions']['submit'])) { - $inner_form['#submit'] = $inner_form['actions']['submit']['#submit']; - } - unset($inner_form['actions']); - } - $inner_form['#element_validate'][] = '::validateForm'; - - return $inner_form; - } - - /** - * Process inner form. - * - * @param array $form - * Form array. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Form state. - * @param array $complete_form - * Complete form. - * - * @return array - * Returns processed form. - */ - public function processForm(array &$form, FormStateInterface &$form_state, array &$complete_form) { - $inner_form_state = static::getInnerFormState($form_state); - - foreach ($inner_form_state->get('#process') as $callback) { - $form[static::INNER_FORM_ID] = call_user_func_array($inner_form_state->prepareCallback($callback), array( - &$form[static::INNER_FORM_ID], - &$inner_form_state, - &$complete_form, - )); - } - - return $form; - } - - /** - * Creates new inner form state. - * - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Form state for outer form. - * @param \Drupal\Core\Form\FormInterface $inner_form_object - * Inner form object. - * - * @return \Drupal\Core\Form\FormState - * Returns created inner form state. - */ - protected static function createInnerFormState(FormStateInterface $form_state, FormInterface $inner_form_object) { - $inner_form_state = new FormState(); - $inner_form_state->setFormObject($inner_form_object); - $form_state->set([ - static::INNER_FORM_STATE_KEY, - static::INNER_FORM_ID, - ], $inner_form_state); - - return $inner_form_state; - } - - /** - * Get inner form state. - * - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Outer form state. - * - * @return \Drupal\Core\Form\FormStateInterface - * Returns inner form state. - */ - protected static function getInnerFormState(FormStateInterface $form_state) { - /** @var \Drupal\Core\Form\FormStateInterface $inner_form_state */ - $inner_form_state = $form_state->get([ - static::INNER_FORM_STATE_KEY, - static::INNER_FORM_ID, - ]); - - $inner_form_state->setCompleteForm($form_state->getCompleteForm()); - $inner_form_state->setValues($form_state->getValues() ?: []); - $inner_form_state->setUserInput($form_state->getUserInput() ?: []); - - return $inner_form_state; - } - - /** - * Create media entity for file. - * - * @param string $type - * Media type. - * @param \Drupal\Core\Entity\EntityInterface $file - * File entity that will be used to create media entity. - * - * @return \Drupal\Core\Entity\EntityInterface - * Returns media entity. - */ - protected function createMediaFromFile($type, EntityInterface $file) { - $media_item = Media::create([ - 'bundle' => $type, - ]); - - $configuration = $media_item->getSource()->getConfiguration(); - $media_item->set($configuration['source_field'], $file); - - return $media_item; - } - - /** - * Get file entity for file ID. - * - * @param string $file_id - * File ID. - * - * @return \Drupal\Core\Entity\EntityInterface - * Returns file entity. - */ - protected function getFileById($file_id) { - /** @var \Drupal\file\FileStorage $file_storage */ - $file_storage = \Drupal::service('entity_type.manager')->getStorage('file'); - - return $file_storage->load($file_id); - } - - /** - * Get media type list. - * - * @param string $file_id - * File ID. - * - * @return array - * Returns available list of media types for file extension. - */ - protected function getMediaTypeList($file_id) { - /** @var \Drupal\file\FileInterface $file */ - $file = $this->getFileById($file_id); - - $extension = pathinfo($file->getFilename(), PATHINFO_EXTENSION); - - return $this->mediaTypeManager->getTypesByExtension($extension); - } - - /** - * {@inheritdoc} - */ - public function validateForm(array &$form, FormStateInterface $form_state) { - // Validate form only if submit button triggers AJAX request. - if ($form_state->getTriggeringElement()['#name'] === 'media-modal-form-submit') { - $inner_form_object = $form_state->get(static::INNER_FORM_OBJECT_KEY); - $inner_form_state = static::getInnerFormState($form_state); - - // Clear status of inner form state. - $form_state->clearErrors(); - $inner_form_state->clearErrors(); - $inner_form_state->setValidationComplete(FALSE); - - // Pass through both the form elements validation and the form object - // validation. - $inner_form_id = $inner_form_object->getFormId(); - $this->invalidateInnerForm($form[static::INNER_FORM_ID]); - $inner_form_state->setUserInput($form_state->getUserInput()[static::INNER_FORM_ID]); - $inner_form_state->setValues($form_state->getValue(static::INNER_FORM_ID)); - $this->formValidator->validateForm($inner_form_id, $form[static::INNER_FORM_ID], $inner_form_state); - - foreach ($inner_form_state->getErrors() as $error_element_path => $error) { - // TODO: should be improved for inline error message to work. - $form_state->setErrorByName(static::INNER_FORM_ID . '][' . $error_element_path, $error); - } - } - } - - protected function invalidateInnerForm(array &$elements) { - unset($elements['#validated']); - - foreach (Element::children($elements) as $key) { - if (is_array($elements[$key])) { - $this->invalidateInnerForm($elements[$key]); - } - } - } - - /** - * {@inheritdoc} - */ - public function submitForm(array &$form, FormStateInterface $form_state) { - $inner_form_state = static::getInnerFormState($form_state); - $inner_form_state->setSubmitted(); - $this->formSubmitter->doSubmitForm($form[static::INNER_FORM_ID], $inner_form_state); - - $file_ids = $form_state->get('queued_fids'); - array_shift($file_ids); - $form_state->set('queued_fids', $file_ids); - - $processed_ids = $form_state->get('processed_media_ids'); - $processed_ids[] = $form_state->get(static::INNER_FORM_OBJECT_KEY) - ->getEntity() - ->id(); - $form_state->set('processed_media_ids', $processed_ids); - - if (!empty($file_ids)) { - $form_state->setRebuild(); - } - } - - /** - * AJAX response after submitting of form. - * - * It can go in two directions: - * - when last file is processed dialog will be closed and created media IDs - * passed to caller component. - * - if there are more queued files, next file will be displayed in form. - * - * @param array $form - * Form array. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Form state. - * - * @return \Drupal\Core\Ajax\AjaxResponse - * Returns AJAX response. - */ - public function ajaxSubmitForm(array &$form, FormStateInterface $form_state) { - $fileIds = $form_state->get('queued_fids'); - - // All files are processed, close dialog and send information to caller. - if (empty($fileIds)) { - $response = new AjaxResponse(); - - // TODO: Add exeuction of JS Command that will send processed media IDs to - // widget. - $response->addCommand(new CloseModalDialogCommand()); - } - else { - $response = $this->ajaxChangeType($form, $form_state); - - $selection_button_html = trim($this->renderer->renderRoot($form['media_type'])); - $response->addCommand(new ReplaceCommand('#media-modal-form-media-type-wrapper', $selection_button_html)); - $response->addCommand(new ReplaceCommand('#media-modal-form-status-messages', $this->getStatusMessagesElement($form_state))); - } - - return $response; - } - - /** - * AJAX response after changing media type for file. - * - * @param array $form - * Form array. - * @param \Drupal\Core\Form\FormStateInterface $form_state - * Form state. - * - * @return \Drupal\Core\Ajax\AjaxResponse - * Returns AJAX response with rebuilt type selector and inner form. - */ - public function ajaxChangeType(array &$form, FormStateInterface $form_state) { - $response = new AjaxResponse(); - - $media_form_html = trim($this->renderer->renderRoot($form[static::INNER_FORM_ID])); - $response->addCommand(new ReplaceCommand('#media-modal-form-inner-form', $media_form_html)); - - return $response; - } - -}