media_library_media_modify-1.0.x-dev/src/Form/EditForm.php

src/Form/EditForm.php
<?php

namespace Drupal\media_library_media_modify\Form;

use Drupal\media_library\MediaLibraryState;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\media\MediaInterface;
use Drupal\Core\Entity\Entity\EntityFormDisplay;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Ajax\SetDialogTitleCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Security\TrustedCallbackInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Render\Element;
use Drupal\media\MediaTypeInterface;
use Drupal\media_library_media_modify\MediaLibraryMediaModifyUiBuilder;

/**
 * Provides a form for editing media items within the media library.
 */
class EditForm extends FormBase implements TrustedCallbackInterface {

  /**
   * The entity type manager.
   *
   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
   */
  protected $entityTypeManager;

  /**
   * The media library UI builder.
   *
   * @var \Drupal\media_library_media_modify\MediaLibraryMediaModifyUiBuilder
   */
  protected $libraryUiBuilder;

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): self {
    $form = parent::create($container);
    $form->setEntityTypeManager($container->get('entity_type.manager'));
    $form->setMediaLibraryUiBuilder($container->get('media_library_media_modify.ui_builder'));
    return $form;
  }

  /**
   * Set entity type manager service.
   *
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
   *   The entity type manager service.
   */
  protected function setEntityTypeManager(EntityTypeManagerInterface $entityTypeManager): void {
    $this->entityTypeManager = $entityTypeManager;
  }

  /**
   * Set media library UI builder service.
   *
   * @param \Drupal\media_library_media_modify\MediaLibraryMediaModifyUiBuilder $mediaLibraryUiBuilder
   *   The media library UI builder service.
   */
  protected function setMediaLibraryUiBuilder(MediaLibraryMediaModifyUiBuilder $mediaLibraryUiBuilder): void {
    $this->libraryUiBuilder = $mediaLibraryUiBuilder;
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'media_library_media_modify_edit_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {

    // @todo Remove the ID when we can use selectors to replace content via
    //   AJAX in https://www.drupal.org/project/drupal/issues/2821793.
    $form['#prefix'] = '<div id="media-library-media-modify-edit-form-wrapper">';
    $form['#suffix'] = '</div>';

    $message = $this->t('You are editing a media item, be aware that changes affect all contexts in which this media item is being used.');
    $form['message'] = [
      '#theme' => 'status_messages',
      '#message_list' => ['status' => [$message]],
      '#status_headings' => [
        'status' => $this->t('Status message'),
      ],
    ];

    // The form is posted via AJAX. When there are messages set during the
    // validation or submission of the form, the messages need to be shown to
    // the user.
    $form['status_messages'] = [
      '#type' => 'status_messages',
    ];

    $form['media'] = [
      '#pre_render' => [
        [$this, 'preRenderAddedMedia'],
      ],
    ];

    $state = $this->getMediaLibraryState($form_state);

    /** @var \Drupal\media\MediaInterface $media */
    $media = $this->entityTypeManager->getStorage('media')->load($state->get('media_library_media_modify_edit'));
    $form['media'][0] = $this->buildEntityFormElement($media, $form, $form_state);

    $form['actions'] = $this->buildActions($form, $form_state);
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state): void {

    $state = $this->getMediaLibraryState($form_state);

    /** @var \Drupal\media\MediaInterface $media */
    $media = $this->entityTypeManager->getStorage('media')->load($state->get('media_library_media_modify_edit'));

    $display = EntityFormDisplay::collectRenderDisplay($media, 'media_library');
    $display->extractFormValues($media, $form['media'][0]['fields'], $form_state);
    $media->save();
  }

  /**
   * Builds the sub-form for setting required fields on a new media item.
   *
   * @param \Drupal\media\MediaInterface $media
   *   A new, unsaved media item.
   * @param array $form
   *   The complete form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @return array
   *   The element containing the required fields sub-form.
   */
  protected function buildEntityFormElement(MediaInterface $media, array $form, FormStateInterface $form_state): array {
    $element = [
      'preview' => [
        '#type' => 'container',
        '#weight' => 10,
      ],
      'fields' => [
        '#type' => 'container',
        '#weight' => 20,
        // The '#parents' are set here because the entity form display needs it
        // to build the entity form fields.
        '#parents' => ['media', 0, 'fields'],
      ],
    ];
    // @todo Make the image style configurable in
    //   https://www.drupal.org/node/2988223
    $source = $media->getSource();
    $plugin_definition = $source->getPluginDefinition();
    if ($thumbnail_uri = $source->getMetadata($media, $plugin_definition['thumbnail_uri_metadata_attribute'])) {
      $element['preview']['thumbnail'] = [
        '#theme' => 'image_style',
        '#style_name' => 'media_library',
        '#uri' => $thumbnail_uri,
      ];
    }

    $form_display = EntityFormDisplay::collectRenderDisplay($media, 'media_library');
    // When the name is not added to the form as an editable field, output
    // the name as a fixed element to confirm the right file was uploaded.
    if (!$form_display->getComponent('name')) {
      $element['fields']['name'] = [
        '#type' => 'item',
        '#title' => $this->t('Name'),
        '#markup' => $media->getName(),
      ];
    }
    $form_display->buildForm($media, $element['fields'], $form_state);

    // Add source field name so that it can be identified in form alter and
    // widget alter hooks.
    /** @var \Drupal\media\MediaTypeInterface $media_type */
    $media_type = $media->bundle->entity;
    $element['fields']['#source_field_name'] = $this->getSourceFieldName($media_type);

    // The revision log field is currently not configurable from the form
    // display, so hide it by changing the access.
    // @todo Make the revision_log_message field configurable in
    //   https://www.drupal.org/project/drupal/issues/2696555
    if (isset($element['fields']['revision_log_message'])) {
      $element['fields']['revision_log_message']['#access'] = FALSE;
    }
    return $element;
  }

  /**
   * Returns an array of supported actions for the form.
   *
   * @param array $form
   *   The complete form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @return array
   *   An actions element containing the actions of the form.
   */
  protected function buildActions(array $form, FormStateInterface $form_state): array {
    return [
      '#type' => 'actions',
      'save' => [
        '#type' => 'submit',
        '#button_type' => 'primary',
        '#value' => $this->t('Save'),
        '#ajax' => [
          'callback' => '::buildMediaLibrary',
          'wrapper' => 'media-library-wrapper',
          'url' => Url::fromRoute('media_library_media_modify.ui'),
          'options' => [
            'query' => $this->getMediaLibraryState($form_state)->all() + [
              FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
            ],
          ],
        ],
      ],
      'cancel' => [
        '#type' => 'button',
        '#value' => $this->t('Cancel'),
        '#limit_validation_errors' => [],
        '#ajax' => [
          'callback' => '::buildMediaLibrary',
          'wrapper' => 'media-library-wrapper',
          'url' => Url::fromRoute('media_library_media_modify.ui'),
          'options' => [
            'query' => $this->getMediaLibraryState($form_state)->all() + [
              FormBuilderInterface::AJAX_FORM_REQUEST => TRUE,
            ],
          ],
        ],
      ],
    ];
  }

  /**
   * AJAX callback to send the overview back to the media library.
   *
   * @param array $form
   *   The complete form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @return \Drupal\Core\Ajax\AjaxResponse
   *   An AJAX response with the media library view.
   */
  public function buildMediaLibrary(array &$form, FormStateInterface $form_state): AjaxResponse {
    $response = new AjaxResponse();
    if ($form_state::hasAnyErrors()) {
      $response->addCommand(new ReplaceCommand('#media-library-media-modify-edit-form-wrapper', $form));
      return $response;
    }

    $state = $this->getMediaLibraryState($form_state);
    $state->remove('media_library_media_modify_edit');
    $state->remove('media_library_content');

    $form = $this->libraryUiBuilder->buildUi($state);

    $triggering_element = $form_state->getTriggeringElement();
    $response->addCommand(new ReplaceCommand('#' . $triggering_element['#ajax']['wrapper'], $form));

    $dialogOptions = MediaLibraryMediaModifyUiBuilder::dialogOptions();
    $response->addCommand(new SetDialogTitleCommand('', $dialogOptions['title']));
    return $response;
  }

  /**
   * {@inheritdoc}
   */
  public static function trustedCallbacks(): array {
    return ['preRenderAddedMedia'];
  }

  /**
   * Get the media library state from the form state.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   *
   * @return \Drupal\media_library\MediaLibraryState
   *   The media library state.
   *
   * @throws \InvalidArgumentException
   *   If the media library state is not present in the form state.
   */
  protected function getMediaLibraryState(FormStateInterface $form_state): MediaLibraryState {
    $state = $form_state->get('media_library_state');
    if (!$state) {
      throw new \InvalidArgumentException('The media library state is not present in the form state.');
    }
    return $state;
  }

  /**
   * Converts the set of newly added media into an item list for rendering.
   *
   * @param array $element
   *   The render element to transform.
   *
   * @return array
   *   The transformed render element.
   */
  public function preRenderAddedMedia(array $element): array {
    // Transform the element into an item list for rendering.
    $element['#theme'] = 'item_list__media_library_add_form_media_list';
    $element['#list_type'] = 'ul';

    foreach (Element::children($element) as $delta) {
      $element['#items'][$delta] = $element[$delta];
      unset($element[$delta]);
    }
    return $element;
  }

  /**
   * Returns the name of the source field for a media type.
   *
   * @param \Drupal\media\MediaTypeInterface $media_type
   *   The media type to get the source field name for.
   *
   * @return string
   *   The name of the media type's source field.
   */
  protected function getSourceFieldName(MediaTypeInterface $media_type): string {
    return $media_type->getSource()
      ->getSourceFieldDefinition($media_type)
      ->getName();
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc