flysystem_drupal_cache-8.x-1.0-alpha3/src/StackMiddleware/Flysystem.php

src/StackMiddleware/Flysystem.php
<?php

namespace Drupal\flysystem_drupal_cache\StackMiddleware;

use DateTime;
use Drupal\Component\Datetime\DateTimePlus;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Cache\CacheFactoryInterface;
use Drupal\Core\File\FileSystem;
use Drupal\Core\PageCache\RequestPolicyInterface;
use Drupal\flysystem\FlysystemFactory;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\ResponseHeaderBag;
use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\Mime\MimeTypeGuesserInterface;

/**
 * Executes the page caching before the main kernel takes over the request.
 */
class Flysystem implements HttpKernelInterface {

  /**
   * The wrapped HTTP kernel.
   *
   * @var \Symfony\Component\HttpKernel\HttpKernelInterface
   */
  protected $httpKernel;

  /**
   * @var \Drupal\Core\Cache\CacheFactoryInterface
   */
  protected $cacheFactory;

  /**
   * A policy rule determining the cacheability of a request.
   *
   * @var \Drupal\Core\PageCache\RequestPolicyInterface
   */
  protected $requestPolicy;

  /**
   * Mime Type Guesser.
   *
   * @var \Symfony\Component\Mime\MimeTypeGuesserInterface
   */
  protected $mimeTypeGuesser;

  /**
   * Flysystem Factory.
   *
   * @var \Drupal\flysystem\FlysystemFactory
   */
  protected $flysystemFactory;

  /**
   * Filesystem.
   *
   * @var \Drupal\Core\File\FileSystem
   */
  protected $filesystem;

  /**
   * Constructs a PageCache object.
   *
   * @param \Symfony\Component\HttpKernel\HttpKernelInterface $http_kernel
   *   The decorated kernel.
   * @param \Drupal\Core\Cache\CacheFactoryInterface $cacheFactory
   *   The cache bin.
   * @param \Drupal\Core\PageCache\RequestPolicyInterface $request_policy
   *   A policy rule determining the cacheability of a request.
   * @param \Symfony\Component\Mime\MimeTypeGuesserInterface $mimeTypeGuesser
   *   Mime Type Guesser.
   * @param \Drupal\flysystem\FlysystemFactory $flysystemFactory
   *   Flysystem Factory.
   * @param \Drupal\Core\File\FileSystem $filesystem
   *   Filesystem.
   */
  public function __construct(HttpKernelInterface $http_kernel, CacheFactoryInterface $cacheFactory, RequestPolicyInterface $request_policy, MimeTypeGuesserInterface $mimeTypeGuesser, FlysystemFactory $flysystemFactory, FileSystem $filesystem) {
    $this->httpKernel = $http_kernel;
    $this->cacheFactory = $cacheFactory;
    $this->requestPolicy = $request_policy;
    $this->mimeTypeGuesser = $mimeTypeGuesser;
    $this->flysystemFactory = $flysystemFactory;
    $this->filesystem = $filesystem;
  }

  /**
   * {@inheritdoc}
   */
  public function handle(Request $request, int $type = self::MAIN_REQUEST, bool $catch = true): Response {
    // Only allow page caching on master request.
    if ($type !== static::MAIN_REQUEST || $this->requestPolicy->check($request) !== RequestPolicyInterface::ALLOW) {
      return $this->pass($request, $type, $catch);
    }

    // Stream wrapper protocols must conform to /^[a-zA-Z0-9+.-]+$/
    // Via php_stream_wrapper_scheme_validate() in the PHP source.
    if (!preg_match('|^/_flysystem/([a-zA-Z0-9+.-]+)/|', $request->getRequestUri(), $matches)) {
      return $this->pass($request, $type, $catch);
    }

    if (empty($matches[1]) || !in_array($matches[1], $this->flysystemFactory->getSchemes(), TRUE)) {
      return $this->pass($request, $type, $catch);
    }

    $scheme = $matches[1];
    $settings = $this->flysystemFactory->getSettings($scheme);

    if ($settings['driver'] !== 'drupal_cache') {
      return $this->pass($request, $type, $catch);
    }

    $cid = substr($request->getRequestUri(), strlen($matches[0]));
    $cid = UrlHelper::parse($cid)['path'];

    try {
      return $this->getResponse($request, $scheme, $cid);
    }
    catch (NotFoundHttpException $exception) {
      return $this->pass($request, $type, $catch);
    }
  }

  /**
   * Sidesteps the page cache and directly forwards a request to the backend.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   *   A request object.
   * @param int $type
   *   The type of the request (one of HttpKernelInterface::MAIN_REQUEST or
   *   HttpKernelInterface::SUB_REQUEST)
   * @param bool $catch
   *   Whether to catch exceptions or not
   *
   * @return \Symfony\Component\HttpFoundation\Response
   * @throws \Exception
   */
  protected function pass(Request $request, $type = self::MAIN_REQUEST, $catch = TRUE): Response {
    return $this->httpKernel->handle($request, $type, $catch);
  }

  /**
   * Get the response object.
   *
   * @param \Symfony\Component\HttpFoundation\Request $request
   * @param string $scheme
   *   The scheme for the file.
   * @param string $cid
   *   The cid/path of the file.
   *
   * @return \Symfony\Component\HttpFoundation\Response
   * @throws \Exception
   */
  private function getResponse(Request $request, $scheme, $cid): Response {
    $adapter = $this->flysystemFactory->getPlugin($scheme)->getAdapter();
    $data = $adapter->read($cid);
    $metadata = $adapter->getMetadata($cid);
    $uri = $scheme . '://' . $cid;

    $response = new Response();

    $response->headers->set('Content-type', $metadata['mimetype'] );
    $response->headers->set('Content-length',  strlen($data['contents']));
    $response->setLastModified(new DateTime(gmdate(DateTimePlus::RFC7231, (int) $metadata['timestamp'])));

    $date = new DateTime(gmdate(DateTimePlus::RFC7231, (int) $metadata['timestamp']));
    $response->setExpires($date->modify('+1 year'));
    $response->setPublic();
    $response->setMaxAge(31556926);
    $response->setEtag(md5($data['contents']), TRUE);

    $disposition = $response->headers->makeDisposition(ResponseHeaderBag::DISPOSITION_INLINE, pathinfo($uri, PATHINFO_BASENAME));
    $response->headers->set('Content-Disposition', $disposition);

    $response->setContent($data['contents']);
    $response->isNotModified($request);

    return $response;
  }

}

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

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