You are here

function amazons3_image_deliver in AmazonS3 7.2

Image delivery callback that uploads a derivative to S3.

Parameters

...: The path components of the source image.

1 string reference to 'amazons3_image_deliver'
amazons3_menu in ./amazons3.module
Implements hook_menu().

File

./amazons3.module, line 107
Hook implementations for the AmazonS3 module.

Code

function amazons3_image_deliver() {
  $args = func_get_args();
  if (count($args) < 4) {
    return MENU_NOT_FOUND;
  }
  $bucket = $args[0];

  // Pop off the bucket and the 'styles' constant in the URL.
  array_shift($args);
  array_shift($args);
  $style_name = $args[0];

  // If the image style doesn't exist, we can return early.
  if (!($style = image_style_load($style_name))) {
    return MENU_NOT_FOUND;
  }

  // Pop off the style name; the rest is our key to the original image.
  array_shift($args);
  $path = $args;
  $key = implode('/', $path);
  $source = new S3Url($bucket, $key);
  $destination_s3 = $source
    ->getImageStyleUrl($style_name);

  // Check that the image style token is valid.
  if (!variable_get('image_allow_insecure_derivatives', FALSE) || strpos($destination_s3
    ->getKey(), 'styles/') === 0) {
    $valid = isset($_GET[IMAGE_DERIVATIVE_TOKEN]) && $_GET[IMAGE_DERIVATIVE_TOKEN] === image_style_path_token($style['name'], (string) $source);
    if (!$valid) {
      return MENU_ACCESS_DENIED;
    }
  }
  if (!file_exists($destination_s3)) {

    // If there is no source image we can 404 early.
    if (!file_exists($source)) {
      return MENU_NOT_FOUND;
    }
    $lock_name = 'amazons3_image_style_deliver:' . drupal_hash_base64($destination_s3
      ->getKey());
    $destination_temp = 'temporary://amazons3/' . $destination_s3
      ->getKey();

    // Prevent cache stampedes.
    if (!lock_acquire($lock_name)) {
      _amazons3_image_wait_transfer($destination_temp);
    }

    // If the temporary file exists, we assume another thread has generated it
    // and we can transfer it directly.
    if (!file_exists($destination_temp)) {
      $image = _amazons3_generate_image_style($source, $style, $destination_temp, $destination_s3);
    }
    else {
      $image = amazons3_image_load($destination_temp);
    }
    lock_release($lock_name);

    // Transfer the image to the client from our temporary directory.
    file_transfer($image->source, array(
      'Content-Type' => $image->info['mime_type'],
      'Content-Length' => $image->info['file_size'],
    ));
  }

  // If the file exists on S3, send a permanent redirect.

  /** @var \Drupal\amazons3\StreamWrapper $wrapper */
  $wrapper = file_stream_wrapper_get_instance_by_uri($destination_s3);
  drupal_goto($wrapper
    ->getExternalUrl(), array(), 301);
}