You are here

MediaDirectoriesLibraryState.php in Media Directories 3.x

File

modules/media_directories_ui/src/MediaDirectoriesLibraryState.php
View source
<?php

namespace Drupal\media_directories_ui;

use Drupal\media_library\MediaLibraryState;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpKernel\Exception\BadRequestHttpException;

/**
 * A value object for the media library state.
 *
 * When the media library is opened it needs several parameters to work
 * properly. These parameters are normally extracted from the current URL, then
 * retrieved from and managed by the MediaLibraryState value object. The
 * following parameters are required in order to open the media library:
 * - media_library_opener_id: The ID of a container service which implements
 *   \Drupal\media_library\MediaLibraryOpenerInterface and is responsible for
 *   interacting with the media library on behalf of the "thing" (e.g., a field
 *   widget or text editor button) which opened it.
 * - media_library_allowed_types: The media types available in the library can
 *   be restricted to a list of allowed types. This should be an array of media
 *   type IDs.
 * - media_library_selected_type: The media library contains tabs to navigate
 *   between the different media types. The selected type contains the ID of the
 *   media type whose tab that should be opened.
 * - media_library_remaining: When the opener wants to limit the amount of media
 *   items that can be selected, it can pass the number of remaining slots. When
 *   the number of remaining slots is a negative number, an unlimited amount of
 *   items can be selected.
 *
 * This object can also carry an optional opener-specific array of arbitrary
 * values, under the media_library_opener_parameters key. These values are
 * included in the hash generated by ::getHash(), so the end user cannot tamper
 * with them either.
 *
 * @see \Drupal\media_library\MediaLibraryOpenerInterface
 */
class MediaDirectoriesLibraryState extends MediaLibraryState {

  /**
   * {@inheritdoc}
   */
  public function __construct(array $parameters = []) {
    $this
      ->validateRequiredParameters($parameters['media_library_opener_id'], $parameters['media_library_allowed_types'], $parameters['media_library_selected_type'], $parameters['media_library_remaining']);
    $parameters += [
      'media_library_opener_parameters' => [],
    ];
    parent::__construct($parameters);
    $this
      ->set('hash', $this
      ->getHash());
  }

  /**
   * Creates a new MediaLibraryState object.
   *
   * @param string $opener_id
   *   The opener ID.
   * @param string[] $allowed_media_type_ids
   *   The allowed media type IDs.
   * @param string $selected_type_id
   *   The selected media type ID.
   * @param int $remaining_slots
   *   The number of remaining items the user is allowed to select or add in the
   *   library.
   * @param array $opener_parameters
   *   (optional) Any additional opener-specific parameter values.
   *
   * @param int $selected_directory
   *
   * @return static
   *   A state object.
   */
  public static function create($opener_id, array $allowed_media_type_ids, $selected_type_id, $remaining_slots, array $opener_parameters = [], $selected_directory = MEDIA_DIRECTORY_ROOT) {
    $state = new static([
      'media_library_opener_id' => $opener_id,
      'media_library_allowed_types' => $allowed_media_type_ids,
      'media_library_selected_type' => $selected_type_id,
      'media_library_remaining' => $remaining_slots,
      'media_library_opener_parameters' => $opener_parameters,
      'directory' => $selected_directory,
    ]);
    return $state;
  }

  /**
   * Get the media library state from a request.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   The request.
   *
   * @return static
   *   A state object.
   *
   * @throws \Symfony\Component\HttpKernel\Exception\BadRequestHttpException
   *   Thrown when the hash query parameter is invalid.
   */
  public static function fromRequest(Request $request) {
    $query = $request->query;

    // Create a MediaLibraryState object through the create method to make sure
    // all validation runs.
    $state = static::create($query
      ->get('media_library_opener_id'), $query
      ->get('media_library_allowed_types', []), $query
      ->get('media_library_selected_type'), $query
      ->get('media_library_remaining'), $query
      ->get('media_library_opener_parameters', []), $query
      ->get('directory', ''));

    // The request parameters need to contain a valid hash to prevent a
    // malicious user modifying the query string to attempt to access
    // inaccessible information.
    if (!$state
      ->isValidHash($query
      ->get('hash'))) {
      throw new BadRequestHttpException("Invalid media library parameters specified.");
    }

    // Once we have validated the required parameters, we restore the parameters
    // from the request since there might be additional values.
    $state
      ->replace($query
      ->all());
    return $state;
  }

  /**
   * Validate a hash for the state object.
   *
   * @param string $hash
   *   The hash to validate.
   *
   * @return string
   *   The hashed parameters.
   */
  public function isValidHash($hash) {
    return hash_equals($this
      ->getHash(), $hash);
  }

}

Classes

Namesort descending Description
MediaDirectoriesLibraryState A value object for the media library state.