You are here

function filedepot_file_download in filedepot 7

Implements hook_file_download().

File

./filedepot.module, line 1485
filedepot.module Filedepot: File Management Module developed by Nextide www.nextide.ca Full featured document managment module with a desktop application feel. Integrated Organic Group, Role and User permissions to secure folders, automated…

Code

function filedepot_file_download() {
  global $user;
  $op = arg(0);
  if ($op == 'filedepot_download') {
    $fid = intval(arg(2));
    $version = intval(arg(3));
    $mode = arg(4);
  }
  elseif ($op == 'system') {

    // Download of node attachment from native drupal view content page - folder node view
    if (arg(4) == 'submissions') {
      $tempname = arg(5);
      $fid = db_query("SELECT id FROM {filedepot_filesubmissions} WHERE tempname=:name", array(
        ':name' => $tempname,
      ))
        ->fetchField();
      if ($fid === FALSE) {
        watchdog('filedepot', "Download request for moderated file - invalid file reference");
        return -1;
      }
      $version = 1;
      $mode = 'moderator';
    }
    else {
      $cid = arg(3);

      // This prevents filedepot from preventing access to non filedepot files
      if ($cid === NULL) {
        return NULL;

        // Not a filedepot file
      }
      elseif (!is_int($cid)) {
        return NULL;

        // Not a filedepot file
      }
      $fname = arg(4);
      $fid = db_query("SELECT fid FROM {filedepot_files} WHERE fname=:fname AND cid=:cid", array(
        ':fname' => $fname,
        ':cid' => $cid,
      ))
        ->fetchField();
      if ($fid === FALSE) {
        watchdog('filedepot', "Download request for file - invalid file reference");
        return -1;
      }
      $version = db_query("SELECT version FROM {filedepot_files} WHERE fid=:fid", array(
        ':fid' => $fid,
      ))
        ->fetchField();
      $mode = '';
    }
  }
  else {
    return NULL;
  }
  if ($fid > 0) {
    $headers = array();

    /* Check if user has access to folder to download file */
    $cid = db_query("SELECT cid FROM {filedepot_files} WHERE fid=:fid", array(
      ':fid' => $fid,
    ))
      ->fetchField();
    if (!isset($version) or empty($version)) {
      $version = db_query("SELECT version FROM {filedepot_files} WHERE fid=:fid", array(
        ':fid' => $fid,
      ))
        ->fetchField();
    }
    $filedepot = filedepot_filedepot();
    $ret = $filedepot
      ->checkPermission($cid, 'view');
    if ($filedepot
      ->checkPermission($cid, 'view') === FALSE) {
      return -1;
    }
    if ($mode == 'edit') {
      if ($version > 0) {
        $fname = db_query("SELECT fname FROM {filedepot_fileversions} WHERE fid=:fid AND version=:version", array(
          ':fid' => $fid,
          ':version' => $version,
        ))
          ->fetchField();
        $query = db_query("SELECT cid,drupal_fid,title FROM {filedepot_files} WHERE fid=:fid", array(
          ':fid' => $fid,
        ));
        $rec = $query
          ->fetchAssoc();
        if ($rec === FALSE) {
          watchdog('filedepot', "Download request - invalid file reference");
          return -1;
        }
        else {
          list($cid, $drupal_fid, $filetitle) = array_values($rec);
        }
      }
      elseif ($mode == 'moderator') {
        $query = db_query("SELECT cid,drupal_fid,fname,tempname,title FROM {filedepot_filesubmissions} WHERE id=:fid", array(
          ':fid' => $fid,
        ));
        $rec = $query
          ->fetchAssoc();
        if ($rec === FALSE) {
          watchdog('filedepot', "Download request for moderated file - invalid file reference");
          return -1;
        }
        list($cid, $drupal_fid, $fname, $tempname, $filetitle) = array_values($rec);
      }
      else {
        $query = db_query("SELECT cid,drupal_fid,fname,title FROM {filedepot_files} WHERE fid=:fid", array(
          ':fid' => $fid,
        ));
        $rec = $query
          ->fetchAssoc();
        if ($rec === FALSE) {
          watchdog('filedepot', "Download request - invalid file reference");
          return -1;
        }
        else {
          list($cid, $drupal_fid, $fname, $filetitle) = array_values($rec);
        }
      }
      $file = file_load($drupal_fid);

      // Code pulled from file_get_content_headers() to set disposition -- need to alter the filename
      $disposition = 'attachment';

      // By default, serve images, text, and flash content for display rather than
      // download. Or if variable 'filefield_inline_types' is set, use its patterns.
      $inline_types = variable_get('filefield_inline_types', array(
        '^text/',
        '^image/',
        'flash$',
      ));
      $disposition = 'attachment';
      foreach ($inline_types as $inline_type) {

        // Exclamation marks are used as delimiters to avoid escaping slashes.
        if (preg_match('!' . $inline_type . '!', $file->filemime)) {
          $disposition = 'inline';
        }
      }
      $type = mime_header_encode($file->filemime);
      $ext_parts = explode(".", $filetitle);
      $ext = end($ext_parts);
      $pos = strpos($filetitle, ".");

      // Generate a 15 character hash value (token) and append to filename
      // Create a unique filename for download and save the token for compare use on upload
      $filename = substr($filetitle, 0, $pos);
      $hash = md5(uniqid(rand()));
      $token = substr($hash, 0, 15);
      $newfilename = $filename . '{' . $token . 't}' . ".{$ext}";
      $newfilename = str_replace(' ', '+', $newfilename);

      //Update the MimeHeader that will be used to send the file to the browser - need to include token in filename
      $name = mime_header_encode($newfilename);
      $sql = "INSERT INTO {filedepot_export_queue} (orig_filename,token,extension,timestamp,uid,fid) values (:orig_fname,:token,:extension,:time,:uid,:fid)";
      db_query($sql, array(
        ':orig_fname' => $filetitle,
        ':token' => $token,
        ':extension' => $ext,
        ':time' => time(),
        ':uid' => $user->uid,
        ':fid' => $fid,
      ));

      // Change file status to locked - being edited
      db_query("UPDATE {filedepot_files} SET status = 2, status_changedby_uid = :uid WHERE fid=:fid", array(
        ':uid' => $user->uid,
        ':fid' => $fid,
      ));
      $headers = array(
        'Content-Type' => $type . '; name="' . $name . '"',
        'Content-Length' => $file->filesize,
        'Content-Disposition' => $disposition . '; filename="' . $name . '"',
        'Cache-Control' => 'private',
      );
    }
    elseif ($version > 0) {
      if ($mode == 'moderator') {

        //$query = db_query("SELECT cid,drupal_fid,fname,tempname,title FROM {filedepot_filesubmissions} WHERE id=:fid",
        $query = db_select('filedepot_filesubmissions', 'a');
        $query
          ->fields('a', array(
          'cid',
          'title',
          'tempname',
          'drupal_fid',
        ));
        $query
          ->condition('a.id', $fid, '=');
        list($cid, $filetitle, $fname, $dfid) = array_values($query
          ->execute()
          ->fetchAssoc());
      }
      else {
        $query = db_select('filedepot_files', 'a');
        $query
          ->join('filedepot_fileversions', 'b', 'b.fid = a.fid');
        $query
          ->fields('a', array(
          'cid',
          'title',
        ));
        $query
          ->fields('b', array(
          'fname',
          'drupal_fid',
        ));
        $query
          ->condition('a.fid', $fid, '=');
        $query
          ->condition('b.version', $version, '=');
        list($cid, $filetitle, $fname, $dfid) = array_values($query
          ->execute()
          ->fetchAssoc());
      }
      $file = file_load($dfid);
      if ($file) {

        // Code pulled from file_get_content_headers() to set disposition -- need to alter the filename
        $disposition = 'attachment';

        // By default, serve images, text, and flash content for display rather than
        // download. Or if variable 'filefield_inline_types' is set, use its patterns.
        $inline_types = variable_get('filefield_inline_types', array(
          '^text/',
          '^image/',
          'flash$',
        ));
        $disposition = 'attachment';
        foreach ($inline_types as $inline_type) {

          // Exclamation marks are used as delimiters to avoid escaping slashes.
          if (preg_match('!' . $inline_type . '!', $file->filemime)) {
            $disposition = 'inline';
          }
        }
        $disposition = 'inline';
        watchdog('filedepot', "Download of file: @file (!fid), version !version by user @user", array(
          '@file' => $file->filename,
          '!fid' => $fid,
          '!version' => $version,
          '@user' => $user->name,
        ));
        $type = mime_header_encode($file->filemime);
        $headers = array(
          'Content-Type' => $type . '; name="' . $filetitle . '"',
          'Content-Length' => $file->filesize,
          'Content-Disposition' => $disposition . '; filename="' . $filetitle . '"',
          'Cache-Control' => 'private',
        );
      }
      else {
        watchdog('filedepot', "Download attempt failed for file: @fid, node: @dfid, version:@version ", array(
          "@fid" => $fid,
          "@dfid" => $dfid,
          "@version" => $version,
        ));
        return -1;
      }
    }
    return $headers;
  }
  else {
    watchdog('filedepot', "Download request for moderated file - invalid file reference");
    return -1;
  }
}