diff --git a/core/includes/file.inc b/core/includes/file.inc index d365ce8..10542db 100644 --- a/core/includes/file.inc +++ b/core/includes/file.inc @@ -216,23 +216,12 @@ function file_create_url($uri) { * original value of $file_url. * * @see file_create_url() + * + * @deprecated in Drupal 8.0.x-dev and will be removed before Drupal 9.0.0. + * Use\Drupal\Core\File\FileUrlGenerator::transformRelative(). */ function file_url_transform_relative($file_url) { - // Unfortunately, we pretty much have to duplicate Symfony's - // Request::getHttpHost() method because Request::getPort() may return NULL - // instead of a port number. - $request = \Drupal::request(); - $host = $request->getHost(); - $scheme = $request->getScheme(); - $port = $request->getPort() ?: 80; - if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) { - $http_host = $host; - } - else { - $http_host = $host . ':' . $port; - } - - return preg_replace('|^https?://' . $http_host . '|', '', $file_url); + return \Drupal::service('file_url_generator')->transformRelative($file_url); } /** diff --git a/core/lib/Drupal/Core/File/FileUrlGenerator.php b/core/lib/Drupal/Core/File/FileUrlGenerator.php index fefd33d..68562d1 100644 --- a/core/lib/Drupal/Core/File/FileUrlGenerator.php +++ b/core/lib/Drupal/Core/File/FileUrlGenerator.php @@ -81,6 +81,10 @@ public function __construct(FileSystemInterface $file_system, StreamWrapperManag * The URI to a file for which we need an external URL, or the path to a * shipped file. * + * @param bool $relative + * Set to TRUE to return a URL that is relative to the current request's + * base URI. + * * @return string * A string containing a URL that may be used to access the file. * If the provided string already contains a preceding 'http', 'https', or @@ -90,7 +94,7 @@ public function __construct(FileSystemInterface $file_system, StreamWrapperManag * @see https://www.drupal.org/node/515192 * @see file_url_transform_relative() */ - public function generate($uri) { + public function generate($uri, $relative = FALSE) { // 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); @@ -130,6 +134,9 @@ public function generate($uri) { 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. + if ($relative) { + return $this->transformRelative($uri); + } return $uri; } else { @@ -143,4 +150,36 @@ public function generate($uri) { } } + /** + * Transforms an absolute URL of a local file to a relative URL. + * + * May be useful to prevent problems on multisite set-ups and prevent mixed + * content errors when using HTTPS + HTTP. + * + * @param string $file_url + * A file URL of a local file as generated by file_create_url(). + * + * @return string + * If the file URL indeed pointed to a local file and was indeed absolute, + * then the transformed, relative URL to the local file. Otherwise: the + * original value of $file_url. + */ + public function transformRelative($file_url) { + // Unfortunately, we pretty much have to duplicate Symfony's + // Request::getHttpHost() method because Request::getPort() may return NULL + // instead of a port number. + $request = $this->requestStack->getCurrentRequest(); + $host = $request->getHost(); + $scheme = $request->getScheme(); + $port = $request->getPort() ?: 80; + if (('http' == $scheme && $port == 80) || ('https' == $scheme && $port == 443)) { + $http_host = $host; + } + else { + $http_host = $host . ':' . $port; + } + + return preg_replace('|^https?://' . $http_host . '|', '', $file_url); + } + }