You are here

public function FileUrlGenerator::generate in CDN 8.3

Generates a CDN file URL for local files that are mapped to a CDN.

Compatibility: normal paths and stream wrappers.

There are two kinds of local files:

  • "managed files", i.e. those stored by a Drupal-compatible stream wrapper. These are files that have either been uploaded by users or were generated automatically (for example through CSS aggregation).
  • "shipped files", i.e. those outside of the files directory, which ship as part of Drupal core or contributed modules or themes.

Parameters

string $uri: The URI to a file for which we need a CDN URL, or the path to a shipped file.

Return value

string|false A string containing the scheme-relative CDN file URI, or FALSE if this file URI should not be served from a CDN.

File

src/File/FileUrlGenerator.php, line 102

Class

FileUrlGenerator
Generates CDN file URLs.

Namespace

Drupal\cdn\File

Code

public function generate(string $uri) {
  if (!$this->settings
    ->isEnabled()) {
    return FALSE;
  }
  if (!$this
    ->canServe($uri)) {
    return FALSE;
  }
  $cdn_domain = $this
    ->getCdnDomain($uri);
  if ($cdn_domain === FALSE) {
    return FALSE;
  }
  if (!($scheme = StreamWrapperManager::getScheme($uri))) {
    $scheme = self::RELATIVE;
    $relative_url = '/' . $uri;
    $relative_file_path = $relative_url;
    $absolute_file_path = $this->root . $relative_url;
  }
  else {
    $relative_url = str_replace($this->requestStack
      ->getCurrentRequest()
      ->getSchemeAndHttpHost() . $this
      ->getBasePath(), '', $this->streamWrapperManager
      ->getViaUri($uri)
      ->getExternalUrl());
    $relative_file_path = '/' . substr($uri, strlen($scheme . '://'));
    $absolute_file_path = $scheme . '://' . $relative_file_path;
  }

  // When farfuture is enabled, rewrite the file URL to let Drupal serve the
  // file with optimal headers. Only possible if the file exists.
  if ($this->settings
    ->farfutureIsEnabled() && file_exists($absolute_file_path)) {

    // We do the filemtime() call separately, because a failed filemtime()
    // will cause a PHP warning to be written to the log, which would remove
    // any performance gain achieved by removing the file_exists() call.
    $mtime = filemtime($absolute_file_path);

    // Generate a security token. Ensures that users can not request any
    // file they want by manipulating the URL (they could otherwise request
    // settings.php for example). See https://www.drupal.org/node/1441502.
    $calculated_token = Crypt::hmacBase64($mtime . $scheme . UrlHelper::encodePath($relative_file_path), $this->privateKey
      ->get() . Settings::getHashSalt());
    return $this->settings
      ->getScheme() . $cdn_domain . $this
      ->getBasePath() . '/cdn/ff/' . $calculated_token . '/' . $mtime . '/' . $scheme . UrlHelper::encodePath($relative_file_path);
  }
  return $this->settings
    ->getScheme() . $cdn_domain . $this
    ->getBasePath() . $relative_url;
}