You are here

function advagg_file_copy in Advanced CSS/JS Aggregation 6

Same name and namespace in other branches
  1. 7 advagg.module \advagg_file_copy()

Copies a file to a new location.

This is a powerful function that in many ways performs like an advanced version of copy().

  • Checks if $source and $dest are valid and readable/writable.
  • Performs a file copy if $source is not equal to $dest.
  • If file already exists in $dest either the call will error out, replace the file or rename the file based on the $replace parameter.

Parameters

$source: Either a string specifying the file location of the original file or an object containing a 'filepath' property. This parameter is passed by reference and will contain the resulting destination filename in case of success.

$dest: A string containing the directory $source should be copied to. If this value is omitted, Drupal's 'files' directory will be used.

$replace: Replace behavior when the destination file already exists.

Return value

TRUE for success, FALSE for failure.

See also

file_copy()

1 call to advagg_file_copy()
advagg_file_move in ./advagg.module
Moves a file to a new location.

File

./advagg.module, line 1394
Advanced CSS/JS aggregation module

Code

function advagg_file_copy(&$source, $dest = 0, $replace = FILE_EXISTS_RENAME) {
  $directory = dirname($dest);

  // Process a file upload object.
  if (is_object($source)) {
    $file = $source;
    $source = $file->filepath;
    if (!$basename) {
      $basename = $file->filename;
    }
  }
  $source = realpath($source);
  advagg_clearstatcache(TRUE, $source);
  if (!file_exists($source)) {
    drupal_set_message(t('The selected file %file could not be copied, because no file by that name exists. Please check that you supplied the correct filename.', array(
      '%file' => $source,
    )), 'error');
    return 0;
  }

  // If the destination file is not specified then use the filename of the source file.
  $basename = basename($dest);
  $basename = $basename ? $basename : basename($source);
  $dest = $directory . '/' . $basename;

  // Make sure source and destination filenames are not the same, makes no sense
  // to copy it if they are. In fact copying the file will most likely result in
  // a 0 byte file. Which is bad. Real bad.
  if ($source != realpath($dest)) {
    if (!($dest = file_destination($dest, $replace))) {
      drupal_set_message(t('The selected file %file could not be copied, because a file by that name already exists in the destination.', array(
        '%file' => $source,
      )), 'error');
      return FALSE;
    }

    // Perform the replace operation. Since there could be multiple processes
    // writing to the same file, the best option is to create a temporary file in
    // the same directory and then rename it to the destination. A temporary file
    // is needed if the directory is mounted on a separate machine; thus ensuring
    // the rename command stays local.
    $result = FALSE;
    if ($replace == FILE_EXISTS_REPLACE) {

      // Get a temporary filename in the destination directory.
      $temporary_file = tempnam(dirname($dest), 'file');

      // Place contents in the temporary file.
      if ($temporary_file && @copy($source, $temporary_file)) {
        if (!($result = @rename($temporary_file, $dest))) {

          // Unlink and try again for windows. Rename on windows does not replace
          // the file if it already exists.
          @unlink($dest);
          $result = @rename($temporary_file, $dest);
        }

        // Remove temporary_file if rename failed.
        if (!$result) {
          @unlink($temporary_file);
        }
      }
    }
    else {
      $result = @copy($source, $dest);
    }
    if ($result === FALSE) {
      drupal_set_message(t('The selected file %file could not be copied. ' . $dest, array(
        '%file' => $source,
      )), 'error');
      return 0;
    }

    // Give everyone read access so that FTP'd users or
    // non-webserver users can see/read these files,
    // and give group write permissions so group members
    // can alter files uploaded by the webserver.
    @chmod($dest, 0664);
  }
  if (isset($file) && is_object($file)) {
    $file->filename = $basename;
    $file->filepath = $dest;
    $source = $file;
  }
  else {
    $source = $dest;
  }
  return 1;

  // Everything went ok.
}