You are here

public function FileDownloadController::download in WebP 8

Handles private file transfers.

Call modules that implement hook_file_download() to find out if a file is accessible and what headers it should be transferred with. If one or more modules returned headers the download will start with the returned headers. If a module returns -1 an AccessDeniedHttpException will be thrown. If the file exists but no modules responded an AccessDeniedHttpException will be thrown. If the file does not exist a NotFoundHttpException will be thrown.

Parameters

\Symfony\Component\HttpFoundation\Request $request: The request object.

string $scheme: The file scheme, defaults to 'private'.

Return value

\Symfony\Component\HttpFoundation\BinaryFileResponse The transferred file as response.

Throws

\Symfony\Component\HttpKernel\Exception\NotFoundHttpException Thrown when the requested file does not exist.

\Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException Thrown when the user does not have access to the file.

See also

hook_file_download()

File

src/Controller/FileDownloadController.php, line 104

Class

FileDownloadController

Namespace

Drupal\webp\Controller

Code

public function download(Request $request, $scheme = 'private') {
  $target = $request->query
    ->get('file');

  // Merge remaining path arguments into relative file path.
  $uri = $scheme . '://' . $target;

  // Don't try to generate file if source is missing.
  if (preg_match('/\\.webp$/', $uri)) {
    $path_info = pathinfo($uri);
    $possible_image_uris = [
      // If the image style converted the extension, it has been added to the
      // original file, resulting in filenames like image.png.jpeg. So to find
      // the actual source image, we remove the extension and check if that
      // image exists.
      $path_info['dirname'] . DIRECTORY_SEPARATOR . $path_info['filename'],
    ];

    // Try out the different possible sources for a webp image.
    $extensions = [
      '.jpg',
      '.jpeg',
      '.png',
    ];
    foreach ($extensions as $extension) {
      $possible_image_uris[] = str_replace('.webp', mb_strtoupper($extension), $uri);
      $possible_image_uris[] = str_replace('.webp', $extension, $uri);
    }
    $source_image_found = FALSE;
    foreach ($possible_image_uris as $possible_image_uri) {
      if (file_exists($possible_image_uri)) {
        $uri = $possible_image_uri;
        $source_image_found = TRUE;
        break;
      }
    }
    if (!$source_image_found) {
      $this->logger
        ->notice('Source image at %source_image_path not found while trying to generate derivative image.', [
        '%source_image_path' => $uri,
      ]);
      return new Response($this
        ->t('Error generating image, missing source file.'), 404);
    }
  }
  if ($this->streamWrapperManager
    ->isValidScheme($scheme) && is_file($uri)) {

    // Let other modules provide headers and controls access to the file.
    $headers = $this
      ->moduleHandler()
      ->invokeAll('file_download', [
      $uri,
    ]);
    foreach ($headers as $result) {
      if ($result == -1) {
        throw new AccessDeniedHttpException();
      }
    }
    if (count($headers)) {
      $image = $this->imageFactory
        ->get($uri);
      if (($webp = $this->webp
        ->createWebpCopy($image
        ->getSource())) && in_array('image/webp', $request
        ->getAcceptableContentTypes())) {
        return $this
          ->webpResponse($webp, $headers, $scheme);
      }
      else {
        return $this
          ->response($uri, $headers, $scheme);
      }
    }
    throw new AccessDeniedHttpException();
  }
  throw new NotFoundHttpException();
}