function image_file_download

Same name in other branches
  1. 7.x modules/image/image.module \image_file_download()
  2. 9 core/modules/image/image.module \image_file_download()
  3. 8.9.x core/modules/image/image.module \image_file_download()

Implements hook_file_download().

Control the access to files underneath the styles directory.

File

core/modules/image/image.module, line 138

Code

function image_file_download($uri) {
    $path = StreamWrapperManager::getTarget($uri);
    // Private file access for image style derivatives.
    if (str_starts_with($path, 'styles/')) {
        $args = explode('/', $path);
        // Discard "styles", style name, and scheme from the path
        $args = array_slice($args, 3);
        // Then the remaining parts are the path to the image.
        $original_uri = StreamWrapperManager::getScheme($uri) . '://' . implode('/', $args);
        // Check that the file exists and is an image.
        $image = \Drupal::service('image.factory')->get($uri);
        if ($image->isValid()) {
            // If the image style converted the extension, it has been added to the
            // original file, resulting in filenames like image.png.jpeg. So to find
            // the actual source image, we remove the extension and check if that
            // image exists.
            if (!file_exists($original_uri)) {
                $converted_original_uri = ImageStyleDownloadController::getUriWithoutConvertedExtension($original_uri);
                if ($converted_original_uri !== $original_uri && file_exists($converted_original_uri)) {
                    // The converted file does exist, use it as the source.
                    $original_uri = $converted_original_uri;
                }
            }
            // Check the permissions of the original to grant access to this image.
            $headers = \Drupal::moduleHandler()->invokeAll('file_download', [
                $original_uri,
            ]);
            // Confirm there's at least one module granting access and none denying access.
            if (!empty($headers) && !in_array(-1, $headers)) {
                return [
                    // Send headers describing the image's size, and MIME-type.
'Content-Type' => $image->getMimeType(),
                    'Content-Length' => $image->getFileSize(),
                ];
            }
        }
        return -1;
    }
    // If it is the sample image we need to grant access.
    $samplePath = \Drupal::config('image.settings')->get('preview_image');
    if ($path === $samplePath) {
        $image = \Drupal::service('image.factory')->get($samplePath);
        return [
            // Send headers describing the image's size, and MIME-type.
'Content-Type' => $image->getMimeType(),
            'Content-Length' => $image->getFileSize(),
        ];
    }
}

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