function FileUrlGenerator::generate

Same name and namespace in other branches
  1. 9 core/lib/Drupal/Core/File/FileUrlGenerator.php \Drupal\Core\File\FileUrlGenerator::generate()
  2. 11.x core/lib/Drupal/Core/File/FileUrlGenerator.php \Drupal\Core\File\FileUrlGenerator::generate()

Creates a root-relative web-accessible URL object.

Parameters

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

Return value

\Drupal\Core\Url For a local URL (matching domain), a base-relative Url object containing a URL that may be used to access the file. An Url object with absolute URL may be returned when using a CDN or a remote stream wrapper. Use setAbsolute() on the Url object to build an absolute URL.

Overrides FileUrlGeneratorInterface::generate

File

core/lib/Drupal/Core/File/FileUrlGenerator.php, line 154

Class

FileUrlGenerator
Default implementation for the file URL generator service.

Namespace

Drupal\Core\File

Code

public function generate(string $uri) : Url {
  // Allow the URI to be altered, e.g. to serve a file from a CDN or static
  // file server.
  $this->moduleHandler
    ->alter('file_url', $uri);
  $scheme = StreamWrapperManager::getScheme($uri);
  if (!$scheme) {
    // Allow for:
    // - root-relative URIs (e.g. /foo.jpg in http://example.com/foo.jpg)
    // - protocol-relative URIs (e.g. //bar.jpg, which is expanded to
    //   http://example.com/bar.jpg by the browser when viewing a page over
    //   HTTP and to https://example.com/bar.jpg when viewing a HTTPS page)
    // Both types of relative URIs are characterized by a leading slash, hence
    // we can use a single check.
    if (mb_substr($uri, 0, 2) == '//') {
      return Url::fromUri($uri);
    }
    elseif (mb_substr($uri, 0, 1) == '/') {
      return Url::fromUri('base:' . str_replace($this->requestStack
        ->getCurrentRequest()
        ->getBasePath(), '', $uri));
    }
    else {
      // If this is not a properly formatted stream, then it is a shipped
      // file. Therefore, return the urlencoded URI.
      $options = UrlHelper::parse($uri);
      return Url::fromUri('base:' . UrlHelper::encodePath($options['path']), $options);
    }
  }
  elseif ($scheme == 'http' || $scheme == 'https' || $scheme == 'data') {
    // Check for HTTP and data URI-encoded URLs so that we don't have to
    // implement getExternalUrl() for the HTTP and data schemes.
    $options = UrlHelper::parse($uri);
    return Url::fromUri(urldecode($options['path']), $options);
  }
  elseif ($wrapper = $this->streamWrapperManager
    ->getViaUri($uri)) {
    $external_url = $wrapper->getExternalUrl();
    $options = UrlHelper::parse($external_url);
    // @todo Switch to dependency injected request_context service after
    // https://www.drupal.org/project/drupal/issues/3256884 is fixed.
    if (UrlHelper::externalIsLocal($external_url, \Drupal::service('router.request_context')->getCompleteBaseUrl())) {
      // Attempt to return an external URL using the appropriate wrapper.
      return Url::fromUri('base:' . $this->transformRelative(urldecode($options['path']), FALSE), $options);
    }
    else {
      return Url::fromUri(urldecode($options['path']), $options);
    }
  }
  throw new InvalidStreamWrapperException();
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.