You are here

public function FileDownloadController::download in Commerce File 8.2

Serves the file upon request and record the download.

Parameters

\Drupal\file\FileInterface $file: The file being download.

Return value

\Symfony\Component\HttpFoundation\Response Serve the file as the response.

Throws

\Exception

\Symfony\Component\HttpKernel\Exception\NotFoundHttpException

\Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException

1 string reference to 'FileDownloadController::download'
commerce_file.routing.yml in ./commerce_file.routing.yml
commerce_file.routing.yml

File

src/Controller/FileDownloadController.php, line 89

Class

FileDownloadController
Provides the controller for downloading licensed files.

Namespace

Drupal\commerce_file\Controller

Code

public function download(FileInterface $file) {
  $uri = $file
    ->getFileUri();
  $scheme = $this->streamWrapperManager
    ->getScheme($uri);

  // Special handling for Amazon S3.
  if ($scheme === 's3') {
    $licenses = $this->licenseFileManager
      ->getActiveLicenses($file);

    // This should not happen since we're already checking for an active
    // license in our file access logic.
    if (!$licenses) {
      throw new AccessDeniedHttpException();
    }
    $license = reset($licenses);

    // Record the download if the license owner is downloading the file.
    if ($this->licenseFileManager
      ->shouldLogDownload($license)) {
      $this->downloadLogger
        ->log($license, $file);
    }
    return new TrustedRedirectResponse($file
      ->createFileUrl(FALSE));
  }
  if (!$this->streamWrapperManager
    ->isValidScheme($scheme) || !file_exists($uri)) {
    throw new NotFoundHttpException("The file {$uri} does not exist.");
  }

  // Let other modules provide headers and controls access to the file.
  $headers = $this
    ->moduleHandler()
    ->invokeAll('file_download', [
    $uri,
  ]);
  if (!count($headers)) {
    throw new AccessDeniedHttpException();
  }
  foreach ($headers as $result) {
    if ($result == -1) {
      throw new AccessDeniedHttpException();
    }
  }

  // We could log the download here, but instead this is done via an event
  // subscriber subscribing to the KernelEvents::TERMINATE event
  // to ensure the download is logged even when directly accessing the
  // core route directly.
  $filename = $file
    ->getFilename();

  // \Drupal\Core\EventSubscriber\FinishResponseSubscriber::onRespond()
  // sets response as not cacheable if the Cache-Control header is not
  // already modified. We pass in FALSE for non-private schemes for the
  // $public parameter to make sure we don't change the headers.
  $response = new BinaryFileResponse($uri, Response::HTTP_OK, $headers, FALSE);
  if (empty($headers['Content-Disposition'])) {
    $response
      ->setContentDisposition(ResponseHeaderBag::DISPOSITION_ATTACHMENT, $filename);
  }
  return $response;
}