toolshed-8.x-1.x-dev/modules/toolshed_media/src/Routing/MediaRedirectRequestSubscriber.php

modules/toolshed_media/src/Routing/MediaRedirectRequestSubscriber.php
<?php

namespace Drupal\toolshed_media\Routing;

use Drupal\Core\Cache\CacheableMetadata;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Routing\TrustedRedirectResponse;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\toolshed_media\Utility\FileHelper;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpKernel\Event\RequestEvent;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\Routing\Exception\InvalidParameterException;
use Symfony\Component\Routing\Exception\RouteNotFoundException;

/**
 * Event subscriber handler which redirects Media requests to file.
 *
 * By default the media entity canonical display page, points to fully rendered
 * display page (entity display mode), but for most non-administrators, we
 * tend want to redirect to the file directly.
 */
class MediaRedirectRequestSubscriber implements EventSubscriberInterface {

  /**
   * Route used to determine how the request needs to be handled.
   *
   * @var \Drupal\Core\Routing\RouteMatchInterface
   */
  protected RouteMatchInterface $routeMatch;

  /**
   * The account to use when determining if the request should redirect.
   *
   * @var \Drupal\Core\Session\AccountInterface
   */
  protected AccountInterface $account;

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

  /**
   * Indicates if the media_entity_download module is available.
   *
   * This will provide an option to allow for using the media download to be
   * used for the user redirect when configured. This has some benefits as
   * it sets the header correctly for downloading, and provides other
   * conveniences when loading media.
   *
   * @var bool
   */
  protected bool $hasMediaDownload;

  /**
   * Generate a new MediaRedirectRequestSubscriber event listener.
   *
   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
   *   The routing match interface to determine what route the request is
   *   acting on, and if it matches a media entity request.
   * @param \Drupal\Core\Session\AccountInterface $account
   *   An account / session proxy representing the current user to evaluate
   *   the permissions and handling of the account retrieval.
   * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
   *   The entity type manager.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
   *   The module handler service.
   */
  public function __construct(RouteMatchInterface $route_match, AccountInterface $account, EntityTypeManagerInterface $entity_type_manager, ModuleHandlerInterface $module_handler) {
    $this->routeMatch = $route_match;
    $this->account = $account;
    $this->entityTypeManager = $entity_type_manager;
    $this->hasMediaDownload = $module_handler->moduleExists('media_entity_download');
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents(): array {
    return [
      KernelEvents::REQUEST => 'onHandleRequest',
    ];
  }

  /**
   * Respond to the Request, and redirect media pages if appropriate.
   *
   * Determine if the request is for the canonical media display page and
   * decide if the page needs to get redirected to the media source file
   * if the user access and media type settings call for it.
   *
   * @param \Symfony\Component\HttpKernel\Event\RequestEvent $event
   *   The event information. This will contain the current kernel object and
   *   information about the request, since the event is responding to a
   *   KernelEvents::REQUEST event.
   */
  public function onHandleRequest(RequestEvent $event): void {
    // Ensure that the current route is for a media entity display, and
    // get the media entity that is being requested.
    $media = $this->routeMatch->getRouteName() === 'entity.media.canonical'
      ? $this->routeMatch->getParameter('media')
      : NULL;

    if ($media && !$media->access('update', $this->account)) {
      /** @var \Drupal\media\MediaTypeInterface $mediaType */
      $mediaType = $media->bundle->entity;
      if (!$mediaType) {
        return;
      }

      $settings = $mediaType->getThirdPartySettings('toolshed_media');
      if (!empty($settings['redirect_to_file'])) {
        if ($fileHelper = FileHelper::fromEntity($media)) {
          $cacheMetadata = new CacheableMetadata();

          try {
            $dlRoute = 'media_entity_download.download';
            $url = !$this->hasMediaDownload || empty($settings['use_download'])
              ? $fileHelper->buildRawUrl(FALSE)
              : Url::fromRoute($dlRoute, ['media' => $media->id()])->toString($cacheMetadata);
          }
          catch (RouteNotFoundException | InvalidParameterException $e) {
            $url = $fileHelper->buildRawUrl(FALSE);
          }

          $response = new TrustedRedirectResponse($url);
          $cacheMetadata->addCacheableDependency($mediaType);
          $cacheMetadata->addCacheableDependency($media);
          $cacheMetadata->setCacheContexts(['user.permissions']);
          $response->addCacheableDependency($cacheMetadata);

          $event->setResponse($response);
        }
        else {
          // Media referenced file is missing, return a 404.
          throw new NotFoundHttpException();
        }
      }
    }
  }

}

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

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