file.api.php

Same filename in this branch
  1. main core/modules/file/file.api.php
Same filename and directory in other branches
  1. 10 core/modules/file/file.api.php
  2. 11.x core/modules/file/file.api.php
  3. 11.x core/lib/Drupal/Core/File/file.api.php
  4. 10 core/lib/Drupal/Core/File/file.api.php
  5. 9 core/modules/file/file.api.php
  6. 9 core/lib/Drupal/Core/File/file.api.php
  7. 8.9.x core/modules/file/file.api.php
  8. 8.9.x core/lib/Drupal/Core/File/file.api.php
  9. 7.x modules/file/file.api.php

Hooks related to the File management system.

File

core/lib/Drupal/Core/File/file.api.php

View source
<?php


/**
 * @file
 * Hooks related to the File management system.
 */

use Drupal\Core\StreamWrapper\StreamWrapperManager;

/**
 * @addtogroup hooks
 * @{
 */

/**
 * Control access to private file downloads and specify HTTP headers.
 *
 * This hook allows modules to enforce permissions on file downloads whenever
 * Drupal is handling file download, as opposed to the web server bypassing
 * Drupal and returning the file from a public directory. Modules can also
 * provide headers to specify information like the file's name or MIME type.
 *
 * @param string $uri
 *   The URI of the file.
 *
 * @return string[]|int|null
 *   If the user does not have permission to access the file, return -1. If the
 *   user has permission, return an array with the appropriate headers. If the
 *   file is not controlled by the current module, the return value should be
 *   NULL.
 *
 * @see \Drupal\system\FileDownloadController::download()
 */
function hook_file_download($uri) : array|int|null {
  // Check to see if this is a config download.
  $scheme = StreamWrapperManager::getScheme($uri);
  $target = StreamWrapperManager::getTarget($uri);
  if ($scheme == 'temporary' && $target == 'config.tar.gz') {
    return [
      'Content-disposition' => 'attachment; filename="config.tar.gz"',
    ];
  }
  return NULL;
}

/**
 * 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.
 *
 * @param string $uri
 *   The URI to a file for which we need an external URL, or the path to a
 *   shipped file.
 */
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;
    }
  }
}

/**
 * Alter MIME type mappings used to determine MIME type from a file extension.
 *
 * @param array $mapping
 *   An array of mimetypes correlated to the extensions that relate to them.
 *   The array has 'mimetypes' and 'extensions' elements, each of which is an
 *   array.
 *
 * @deprecated in drupal:11.2.0 and is removed from drupal:12.0.0. Create a
 *   \Drupal\Core\File\Event\MimeTypeMapLoadedEvent subscriber instead.
 *
 * It is used to allow modules to add to or modify the default mapping of
 * MIME type to file extensions.
 *
 * @see https://www.drupal.org/node/3494040
 * @see \Drupal\Core\File\EventSubscriber\LegacyMimeTypeMapLoadedSubscriber
 * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::guessMimeType()
 * @see \Drupal\Core\File\MimeType\ExtensionMimeTypeGuesser::$defaultMapping
 */
function hook_file_mimetype_mapping_alter(&$mapping) {
  // Add new MIME type 'drupal/info'.
  $mapping['mimetypes']['example_info'] = 'drupal/info';
  // Add new extension '.info.yml' and map it to the 'drupal/info' MIME type.
  $mapping['extensions']['info'] = 'example_info';
  // Override existing extension mapping for '.ogg' files.
  $mapping['extensions']['ogg'] = 189;
}

/**
 * @} End of "addtogroup hooks".
 */

Functions

Title Deprecated Summary
hook_file_download Control access to private file downloads and specify HTTP headers.
hook_file_mimetype_mapping_alter

in drupal:11.2.0 and is removed from drupal:12.0.0. Create a \Drupal\Core\File\Event\MimeTypeMapLoadedEvent subscriber instead.

It is used to allow modules to add to or modify the default mapping of MIME type to file extensions.

Alter MIME type mappings used to determine MIME type from a file extension.
hook_file_url_alter Alter the URL to a file.

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