You are here

protected function FetchManager::writeFile in Stage File Proxy 8

Use write & rename instead of write.

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.

Parameters

string $destination: A string containing the destination location.

string $data: A string containing the contents of the file.

Return value

bool True if write was successful. False if write or rename failed.

1 call to FetchManager::writeFile()
FetchManager::fetch in src/FetchManager.php
Downloads a remote file and saves it to the local files directory.

File

src/FetchManager.php, line 161

Class

FetchManager
Fetch manager.

Namespace

Drupal\stage_file_proxy

Code

protected function writeFile($destination, $data) {

  // Get a temporary filename in the destination directory.
  $dir = $this->fileSystem
    ->dirname($destination) . '/';
  $temporary_file = $this->fileSystem
    ->tempnam($dir, 'stage_file_proxy_');
  $temporary_file_copy = $temporary_file;

  // Get the extension of the original filename and append it to the temp file
  // name. Preserves the mime type in different stream wrapper
  // implementations.
  $parts = pathinfo($destination);
  $extension = '.' . $parts['extension'];
  if ($extension === '.gz') {
    $parts = pathinfo($parts['filename']);
    $extension = '.' . $parts['extension'] . $extension;
  }

  // Move temp file into the destination dir if not in there.
  // Add the extension on as well.
  $temporary_file = str_replace(substr($temporary_file, 0, strpos($temporary_file, 'stage_file_proxy_')), $dir, $temporary_file) . $extension;

  // Preform the rename, adding the extension to the temp file.
  if (!@rename($temporary_file_copy, $temporary_file)) {

    // Remove if rename failed.
    @unlink($temporary_file_copy);
    return FALSE;
  }

  // Save to temporary filename in the destination directory.
  $filepath = $this->fileSystem
    ->saveData($data, $temporary_file, FileSystemInterface::EXISTS_REPLACE);

  // Perform the rename operation if the write succeeded.
  if ($filepath) {
    if (!@rename($filepath, $destination)) {

      // Unlink and try again for windows. Rename on windows does not replace
      // the file if it already exists.
      @unlink($destination);
      if (!@rename($filepath, $destination)) {

        // Remove temporary_file if rename failed.
        @unlink($filepath);
      }
    }
  }

  // Final check; make sure file exists & is not empty.
  $result = FALSE;
  if (file_exists($destination) & filesize($destination) != 0) {
    $result = TRUE;
  }
  return $result;
}