function hook_file_url_alter

Same name in other branches
  1. 7.x modules/system/system.api.php \hook_file_url_alter()
  2. 9 core/lib/Drupal/Core/File/file.api.php \hook_file_url_alter()
  3. 8.9.x core/lib/Drupal/Core/File/file.api.php \hook_file_url_alter()
  4. 10 core/lib/Drupal/Core/File/file.api.php \hook_file_url_alter()

Alter the URL to a file.

This hook is called from \Drupal\Core\File\FileUrlGenerator::generate(), and is called fairly frequently (10+ times per page), depending on how many files there are in a given page. If CSS and JS aggregation are disabled, this can become very frequently (50+ times per page) so performance is critical.

This function should alter the URI, if it wants to rewrite the file URL.

Parameters

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

Related topics

2 invocations of hook_file_url_alter()
FileUrlGenerator::doGenerateString in core/lib/Drupal/Core/File/FileUrlGenerator.php
Creates an absolute web-accessible URL string.
FileUrlGenerator::generate in core/lib/Drupal/Core/File/FileUrlGenerator.php
Creates a root-relative web-accessible URL object.

File

core/lib/Drupal/Core/File/file.api.php, line 60

Code

function hook_file_url_alter(&$uri) {
    $user = \Drupal::currentUser();
    // User 1 will always see the local file in this example.
    if ($user->id() == 1) {
        return;
    }
    $cdn1 = 'http://cdn1.example.com';
    $cdn2 = 'http://cdn2.example.com';
    $cdn_extensions = [
        'css',
        'js',
        'gif',
        'jpg',
        'jpeg',
        'png',
    ];
    // Most CDNs don't support private file transfers without a lot of hassle,
    // so don't support this in the common case.
    $schemes = [
        'public',
    ];
    
    /** @var \Drupal\Core\StreamWrapper\StreamWrapperManagerInterface $stream_wrapper_manager */
    $stream_wrapper_manager = \Drupal::service('stream_wrapper_manager');
    $scheme = $stream_wrapper_manager::getScheme($uri);
    // Only serve shipped files and public created files from the CDN.
    if (!$scheme || in_array($scheme, $schemes)) {
        // Shipped files.
        if (!$scheme) {
            $path = $uri;
        }
        else {
            $wrapper = $stream_wrapper_manager->getViaScheme($scheme);
            $path = $wrapper->getDirectoryPath() . '/' . $stream_wrapper_manager::getTarget($uri);
        }
        // Clean up Windows paths.
        $path = str_replace('\\', '/', $path);
        // Serve files with one of the CDN extensions from CDN 1, all others from
        // CDN 2.
        $pathinfo = pathinfo($path);
        if (isset($pathinfo['extension']) && in_array($pathinfo['extension'], $cdn_extensions)) {
            $uri = $cdn1 . '/' . $path;
        }
        else {
            $uri = $cdn2 . '/' . $path;
        }
    }
}

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