You are here

function video_file_download in Video 7.2

Same name and namespace in other branches
  1. 6.5 video.module \video_file_download()
  2. 7 video.module \video_file_download()

Implements hook_file_download().

Control the access to files underneath the styles directory.

File

./video.module, line 374
All module hooks implementation can be found in this file.

Code

function video_file_download($uri) {

  // Check if the file is a transcoded or thumbnail file and determine access by evaluating access to the original file
  $fileinfo = FALSE;
  $extension = video_utility::getExtension($uri);
  $isimage = $extension == 'png' || $extension == 'jpg';

  // Check for transcoded files
  // @todo only execute the query if the file name seems to be a video
  if (!$isimage) {
    $fileinfo = db_query('SELECT video.uri videouri, converted.* FROM {file_managed} video JOIN {video_output} op ON video.fid = op.original_fid JOIN {file_managed} converted ON converted.fid = op.output_fid WHERE converted.uri = :uri', array(
      ':uri' => $uri,
    ))
      ->fetchObject();
  }

  // Check for thumbnails (new style, files uploaded after upgrade to 2.6)
  if ($fileinfo === FALSE && $isimage) {
    $fileinfo = db_query('SELECT video.uri videouri, thumb.* FROM {file_managed} video JOIN {video_thumbnails} tn ON video.fid = tn.videofid JOIN {file_managed} thumb ON thumb.fid = tn.thumbnailfid WHERE thumb.uri = :uri', array(
      ':uri' => $uri,
    ))
      ->fetchObject();
  }

  // Check for thumbnails (old style, only works for selected thumbnail)
  if ($fileinfo === FALSE && strpos($uri, '/thumbnails/') !== FALSE) {
    $thumbfile = db_query('SELECT thumb.* FROM {file_managed} thumb WHERE thumb.uri = :uri', array(
      ':uri' => $uri,
    ))
      ->fetchObject();
    if ($thumbfile != NULL && strncmp($thumbfile->filemime, 'image/', 6) === 0) {

      // The following code is derived from file_file_download() and tries to find the original video URI for this thumbnail
      $fields = field_info_fields();
      foreach ($fields as $field_name => $file_field) {
        if ($file_field['type'] != 'video') {
          continue;
        }
        $query = new EntityFieldQuery();
        $references = $query
          ->fieldCondition($file_field, 'thumbnail', $thumbfile->fid)
          ->age(FIELD_LOAD_CURRENT)
          ->execute();
        foreach ($references as $entity_type => $type_references) {
          foreach ($type_references as $id => $reference) {
            $entity = video_utility::loadEntity($entity_type, $id);
            if ($entity) {

              // Load all field items for that entity.
              $field_items = field_get_items($entity_type, $entity, $field_name);

              // Find the field item with the matching URI.
              foreach ($field_items as $item) {
                if ($item['thumbnail'] == $thumbfile->fid) {
                  $thumbfile->videouri = $item['uri'];
                  break 4;
                }
              }
            }
          }
        }
      }
      if (isset($thumbfile->videouri)) {
        $fileinfo = $thumbfile;
      }
    }
  }

  // If $uri is a converted file or thumbnail, $fileinfo contains the file object for that file and the URI of the original video
  if ($fileinfo != NULL) {
    $original_headers = file_download_headers($fileinfo->videouri);
    if (empty($original_headers)) {
      return -1;
    }

    // Get the headers of the converted file of thumbnail and return
    return file_get_content_headers($fileinfo);
  }

  // Next code derived from function image_file_download()
  $path = file_uri_target($uri);

  // Private file access for image style derivatives.
  if (strpos($path, 'styles/') === 0) {
    $args = explode('/', $path);

    // Discard the first part of the path (styles).
    array_shift($args);

    // Get the style name from the second part.
    $style_name = array_shift($args);

    // Remove the scheme from the path.
    array_shift($args);

    // Then the remaining parts are the path to the image.
    $original_uri = file_uri_scheme($uri) . '://' . implode('/', $args);

    // Check that the file exists and is an image.
    if ($info = image_get_info($uri)) {

      // Check the permissions of the original to grant access to this image.
      $headers = module_invoke_all('file_download', $original_uri);
      if (!in_array(-1, $headers)) {
        return array(
          // Send headers describing the image's size, and MIME-type...
          'Content-Type' => $info['mime_type'],
          'Content-Length' => $info['file_size'],
          // ...and allow the file to be cached for two weeks (matching the
          // value we/ use for the mod_expires settings in .htaccess) and
          // ensure that caching proxies do not share the image with other
          // users.
          'Expires' => gmdate(DATE_RFC1123, REQUEST_TIME + 1209600),
          'Cache-Control' => 'max-age=1209600, private, must-revalidate',
        );
      }
    }
    return -1;
  }

  // Private file access for the original files. Note that we only
  // check access for non-temporary images, since file.module will
  // grant access for all temporary files.
  $files = file_load_multiple(array(), array(
    'uri' => $uri,
  ));
  if (count($files)) {
    $file = reset($files);
    if ($file->status) {
      return file_file_download($uri, 'video');
    }
  }
}