You are here

function crop_file_url_alter in Crop API 8

Same name and namespace in other branches
  1. 8.2 crop.module \crop_file_url_alter()

Implements hook_file_url_alter().

File

./crop.module, line 201
The Crop API Drupal module.

Code

function crop_file_url_alter(&$uri) {

  // Process only files that are stored in "styles" directory.
  if (strpos($uri, '/styles/') !== FALSE && preg_match('/\\/styles\\/(.*?)\\/(.*?)\\/(.+)/', $uri, $match)) {

    // Match image style, schema, file subdirectory and file name.
    // Get the image style ID.
    $image_style = $match[1];

    // Get the file path without query parameter.
    $parsed_uri = UrlHelper::parse($match[3]);

    // Get the file URI using parsed schema and file path.
    $file_uri = $match[2] . '://' . $parsed_uri['path'];

    // Prevent double hashing, if there is a hash argument already, do not add
    // it again.
    if (!empty($parsed_uri['query']['h'])) {
      return;
    }

    /** @var \Drupal\image\Entity\ImageStyle $image_style */
    if (!($image_style = ImageStyle::load($image_style))) {
      return;
    }
    if ($crop = Crop::getCropFromImageStyle($file_uri, $image_style)) {

      // Found a crop for this image, append a hash of it to the URL,
      // so that browsers reload the image and CDNs and proxies can be bypassed.
      $shortened_hash = substr(md5(implode($crop
        ->position()) . implode($crop
        ->anchor())), 0, 8);

      // If the URI has a schema and that is not http, https or data, convert
      // the URI to the external URL. Otherwise the appended query argument
      // will be encoded.
      // @see file_create_url()
      $scheme = \Drupal::service('file_system')
        ->uriScheme($uri);
      if ($scheme && !in_array($scheme, [
        'http',
        'https',
        'data',
      ])) {
        if ($wrapper = \Drupal::service('stream_wrapper_manager')
          ->getViaUri($uri)) {
          $uri = $wrapper
            ->getExternalUrl();
        }
      }

      // Append either with a ? or a & if there are existing query arguments.
      if (strpos($uri, '?') === FALSE) {
        $uri .= '?h=' . $shortened_hash;
      }
      else {
        $uri .= '&h=' . $shortened_hash;
      }
    }
  }
}