You are here

class MediaController in Gutenberg 8.2

Same name and namespace in other branches
  1. 8 src/Controller/MediaController.php \Drupal\gutenberg\Controller\MediaController

Returns responses for our image routes.

Hierarchy

Expanded class hierarchy of MediaController

File

src/Controller/MediaController.php, line 25

Namespace

Drupal\gutenberg\Controller
View source
class MediaController extends ControllerBase {

  /**
   * The media service.
   *
   * @var \Drupal\gutenberg\Service\MediaService
   */
  protected $mediaService;

  /**
   * The media selection processor manager.
   *
   * @var \Drupal\gutenberg\MediaSelectionProcessor\MediaSelectionProcessorManagerInterface
   */
  protected $mediaSelectionProcessorManager;

  /**
   * Drupal\Core\Render\RendererInterface instance.
   *
   * @var \Drupal\Core\Render\RendererInterface
   */
  protected $renderer;

  /**
   * MediaController constructor.
   *
   * @param \Drupal\gutenberg\Service\MediaService $media_service
   *   The media service.
   * @param \Drupal\gutenberg\MediaSelectionProcessor\MediaSelectionProcessorManagerInterface $media_selection_processor_manager
   *   The media selection processor manager.
   * @param \Drupal\Core\Render\RendererInterface $renderer
   *   The renderer.
   */
  public function __construct(MediaService $media_service, MediaSelectionProcessorManagerInterface $media_selection_processor_manager, RendererInterface $renderer) {
    $this->mediaService = $media_service;
    $this->mediaSelectionProcessorManager = $media_selection_processor_manager;
    $this->renderer = $renderer;
  }

  /**
   * {@inheritDoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('gutenberg.media_service'), $container
      ->get('gutenberg.media_selection_processor_manager'), $container
      ->get('renderer'));
  }

  /**
   * Render Drupal's media library dialog.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Current request.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
   */
  public function dialog(Request $request) {
    try {
      return new JsonResponse([
        'html' => $this->mediaService
          ->renderDialog(explode(',', $request->query
          ->get('types', ''))),
      ]);
    } catch (MediaTypeNotFoundException $exception) {
      throw new NotFoundHttpException($exception
        ->getMessage(), $exception);
    }
  }

  /**
   * Load media data.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Current request.
   * @param string $media
   *   Media data (numeric or stringified JSON for media data processing).
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function loadMedia(Request $request, string $media) {
    $media_entities = $this->mediaSelectionProcessorManager
      ->processData($media);
    try {
      if (!$media_entities) {
        throw new MediaEntityNotFoundException();
      }
      return new JsonResponse($this->mediaService
        ->loadMediaData(reset($media_entities)));
    } catch (MediaEntityNotFoundException $exception) {
      throw new NotFoundHttpException($exception
        ->getMessage(), $exception);
    }
  }

  /**
   * Render provided media entity.
   *
   * @param string $media
   *   Media data (numeric or stringified JSON for media data processing).
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   */
  public function render(string $media) {
    $media_entities = $this->mediaSelectionProcessorManager
      ->processData($media);
    try {
      if (!$media_entities) {
        throw new MediaEntityNotFoundException();
      }
      $media_entity = reset($media_entities);
      return new JsonResponse([
        'view_modes' => $this->mediaService
          ->getRenderedMediaEntity($media_entity),
        'media_entity' => [
          'id' => $media_entity
            ->id(),
          'type' => $media_entity
            ->bundle(),
        ],
      ]);
    } catch (MediaEntityNotFoundException $exception) {
      throw new NotFoundHttpException($exception
        ->getMessage(), $exception);
    }
  }

  /**
   * Upload files, save as file and media entity if possible.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Current request.
   * @param \Drupal\editor\Entity\Editor|null $editor
   *   Editor entity instance.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   *
   * @throws \Exception
   */
  public function upload(Request $request, Editor $editor = NULL) {
    $files = $request->files
      ->get('files', []);
    $uploaded_file = $files['fid'] ?? NULL;
    if (!$uploaded_file instanceof UploadedFile) {
      throw new UnprocessableEntityHttpException('The uploaded file is invalid.');
    }
    try {
      return new JsonResponse($this->mediaService
        ->processMediaEntityUpload('fid', $uploaded_file, $editor));
    } catch (\Exception $exception) {

      // DefaultExceptionSubscriber::on4xx only normalizes 4xx client errors.
      return new JsonResponse($this
        ->getErrorResponse($exception
        ->getMessage()), JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
    }
  }

  /**
   * Get data of the media entity required for Gutenberg editor.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Current request.
   * @param \Drupal\file\Entity\File|null $file
   *   Loaded found file entity instance.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   *
   * @throws \Exception
   */
  public function load(Request $request, File $file = NULL) {
    if (!$file) {
      throw new NotFoundHttpException('File entity not found.');
    }
    try {
      return new JsonResponse($this->mediaService
        ->loadFileData($file));
    } catch (FileEntityNotFoundException $exception) {
      throw new NotFoundHttpException($exception
        ->getMessage(), $exception);
    }
  }

  /**
   * Searches for files.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   * @param string $type
   *   The MIME type search string.
   * @param string $search
   *   The filename search string.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   * @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
   */
  public function search(Request $request, string $type = '', string $search = '') {
    return new JsonResponse($this->mediaService
      ->search($request, $type, $search));
  }

  /**
   * Updates file data.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Current request.
   * @param string|int $fid
   *   File id.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\HttpException
   */
  public function updateData(Request $request, $fid) {
    $data = json_decode($request
      ->getContent(), TRUE);
    if (json_last_error() !== JSON_ERROR_NONE) {
      throw new BadRequestHttpException('Request data could not be parsed.');
    }
    try {
      $this->mediaService
        ->updateMediaData($fid, $data);
    } catch (\Throwable $exception) {
      return new JsonResponse([
        'message' => 'Data could not be updated',
      ], JsonResponse::HTTP_INTERNAL_SERVER_ERROR);
    }
    return new JsonResponse([
      'status' => 'ok',
    ]);
  }

  /**
   * Get data for autocomplete.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   Current request.
   *
   * @return \Symfony\Component\HttpFoundation\JsonResponse
   *   The JSON response.
   */
  public function autocomplete(Request $request) {
    return new JsonResponse($this->mediaService
      ->getMediaEntityAutoCompleteData($request
      ->get('search', '')));
  }

  /**
   * Returns the error response including status messages.
   *
   * @param string $error
   *   The original error.
   *
   * @return array
   *   JSON response to return to the client.
   */
  protected function getErrorResponse($error) {
    $messages = $this
      ->messenger()
      ->deleteAll();
    if ($messages) {

      // Display the status messages along with the original error.
      // @todo (HACKY) Leverage AjaxRenderer + "_wrapper_format=drupal_ajax" to handle this instead.
      $message_entries = [];
      foreach ([
        'error',
        'warning',
        'status',
      ] as $status) {
        if (isset($messages[$status])) {

          /* @noinspection SlowArrayOperationsInLoopInspection */
          $message_entries = array_merge($message_entries, $messages[$status]);
        }
      }
      if ($message_entries) {
        $render = [
          '#type' => 'inline_template',
          '#template' => '<div class="gutenberg-error--initial">{{ error }}</div><div class="gutenberg-error--other-messages">{{ messages }}</div>',
          '#context' => [
            'error' => $error,
            'messages' => [
              '#theme' => 'item_list',
              '#list_type' => 'ul',
              '#items' => $message_entries,
            ],
          ],
        ];
        $output = $this->renderer
          ->renderRoot($render);
        return [
          'error' => $output,
          // Render as Raw HTML.
          'rawHTML' => TRUE,
        ];
      }
    }
    return [
      'error' => $error,
    ];
  }

}

Members

Namesort descending Modifiers Type Description Overrides
ControllerBase::$configFactory protected property The configuration factory.
ControllerBase::$currentUser protected property The current user service. 1
ControllerBase::$entityFormBuilder protected property The entity form builder.
ControllerBase::$entityManager protected property The entity manager.
ControllerBase::$entityTypeManager protected property The entity type manager.
ControllerBase::$formBuilder protected property The form builder. 2
ControllerBase::$keyValue protected property The key-value storage. 1
ControllerBase::$languageManager protected property The language manager. 1
ControllerBase::$moduleHandler protected property The module handler. 2
ControllerBase::$stateService protected property The state service.
ControllerBase::cache protected function Returns the requested cache bin.
ControllerBase::config protected function Retrieves a configuration object.
ControllerBase::container private function Returns the service container.
ControllerBase::currentUser protected function Returns the current user. 1
ControllerBase::entityFormBuilder protected function Retrieves the entity form builder.
ControllerBase::entityManager Deprecated protected function Retrieves the entity manager service.
ControllerBase::entityTypeManager protected function Retrieves the entity type manager.
ControllerBase::formBuilder protected function Returns the form builder service. 2
ControllerBase::keyValue protected function Returns a key/value storage collection. 1
ControllerBase::languageManager protected function Returns the language manager service. 1
ControllerBase::moduleHandler protected function Returns the module handler. 2
ControllerBase::redirect protected function Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait::redirect
ControllerBase::state protected function Returns the state storage service.
LinkGeneratorTrait::$linkGenerator protected property The link generator. 1
LinkGeneratorTrait::getLinkGenerator Deprecated protected function Returns the link generator.
LinkGeneratorTrait::l Deprecated protected function Renders a link to a route given a route name and its parameters.
LinkGeneratorTrait::setLinkGenerator Deprecated public function Sets the link generator service.
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MediaController::$mediaSelectionProcessorManager protected property The media selection processor manager.
MediaController::$mediaService protected property The media service.
MediaController::$renderer protected property Drupal\Core\Render\RendererInterface instance.
MediaController::autocomplete public function Get data for autocomplete.
MediaController::create public static function Instantiates a new instance of this class. Overrides ControllerBase::create
MediaController::dialog public function Render Drupal's media library dialog.
MediaController::getErrorResponse protected function Returns the error response including status messages.
MediaController::load public function Get data of the media entity required for Gutenberg editor.
MediaController::loadMedia public function Load media data.
MediaController::render public function Render provided media entity.
MediaController::search public function Searches for files.
MediaController::updateData public function Updates file data.
MediaController::upload public function Upload files, save as file and media entity if possible.
MediaController::__construct public function MediaController constructor.
MessengerTrait::$messenger protected property The messenger. 29
MessengerTrait::messenger public function Gets the messenger. 29
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 1
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.
UrlGeneratorTrait::$urlGenerator protected property The url generator.
UrlGeneratorTrait::getUrlGenerator Deprecated protected function Returns the URL generator service.
UrlGeneratorTrait::setUrlGenerator Deprecated public function Sets the URL generator service.
UrlGeneratorTrait::url Deprecated protected function Generates a URL or path for a specific route based on the given parameters.