Same name and namespace in other branches
  1. 4.6.x includes/file.inc \file_check_upload()
  2. 4.7.x includes/file.inc \file_check_upload()

Verify an uploaded file.

Check if $source is a valid file upload. If so, move the file to the temporary directory and return it as an object.

Parameters

$source: An upload source (the name of the upload form item), or a file.

Return value

FALSE for an invalid file or upload. A file object for valid uploads/files.

Related topics

1 call to file_check_upload()
_locale_admin_import_submit in includes/locale.inc
Process the locale import form submission.

File

includes/file.inc, line 167
API for handling file uploads and server file management.

Code

function file_check_upload($source = 'upload') {

  // Cache for uploaded files. Since the data in _FILES is modified
  // by this function, we cache the result.
  static $upload_cache;

  // Test source to see if it is an object.
  if (is_object($source)) {

    // Validate the file path if an object was passed in instead of
    // an upload key.
    if (is_file($source->filepath)) {
      return $source;
    }
    else {
      return FALSE;
    }
  }

  // Return cached objects without processing since the file will have
  // already been processed and the paths in _FILES will be invalid.
  if (isset($upload_cache[$source])) {
    return $upload_cache[$source];
  }

  // If a file was uploaded, process it.
  if ($_FILES["files"]["name"][$source] && is_uploaded_file($_FILES["files"]["tmp_name"][$source])) {

    // Check for file upload errors and return FALSE if a
    // lower level system error occurred.
    switch ($_FILES["files"]["error"][$source]) {

      // @see http://php.net/manual/en/features.file-upload.errors.php
      case UPLOAD_ERR_OK:
        break;
      case UPLOAD_ERR_INI_SIZE:
      case UPLOAD_ERR_FORM_SIZE:
        drupal_set_message(t('The file %file could not be saved, because it exceeds the maximum allowed size for uploads.', array(
          '%file' => $source,
        )), 'error');
        return 0;
      case UPLOAD_ERR_PARTIAL:
      case UPLOAD_ERR_NO_FILE:
        drupal_set_message(t('The file %file could not be saved, because the upload did not complete.', array(
          '%file' => $source,
        )), 'error');
        return 0;

      // Unknown error
      default:
        drupal_set_message(t('The file %file could not be saved. An unknown error has occurred.', array(
          '%file' => $source,
        )), 'error');
        return 0;
    }

    // Begin building file object.
    $file = new stdClass();
    $file->filename = trim(basename($_FILES["files"]["name"][$source]), '.');

    // Create temporary name/path for newly uploaded files. On Windows, tempnam()
    // requires an absolute path, so we use realpath().
    $file->filepath = tempnam(realpath(file_directory_temp()), 'tmp_');
    $file->filemime = file_get_mimetype($file->filename);

    // Rename potentially executable files, to help prevent exploits.
    if (preg_match('/\\.(php|pl|py|cgi|asp|js)$/i', $file->filename) && substr($file->filename, -4) != '.txt') {
      $file->filemime = 'text/plain';
      $file->filepath .= '.txt';
      $file->filename .= '.txt';
    }

    // Move uploaded files from php's upload_tmp_dir to Drupal's file temp.
    // This overcomes open_basedir restrictions for future file operations.
    if (!move_uploaded_file($_FILES["files"]["tmp_name"][$source], $file->filepath)) {
      drupal_set_message(t('File upload error. Could not move uploaded file.'));
      watchdog('file', t('Upload Error. Could not move uploaded file (%file) to destination (%destination).', array(
        '%file' => $_FILES["files"]["tmp_name"][$source],
        '%destination' => $file->filepath,
      )));
      return FALSE;
    }
    $file->filesize = $_FILES["files"]["size"][$source];
    $file->source = $source;

    // Add processed file to the cache.
    $upload_cache[$source] = $file;
    return $file;
  }
  else {

    // In case of previews return previous file object.
    if (file_exists($_SESSION['file_uploads'][$source]->filepath)) {
      return $_SESSION['file_uploads'][$source];
    }
  }

  // If nothing was done, return FALSE.
  return FALSE;
}