Save data to a file.
This will use the rename operation ensuring atomic file operations.
Parameters
string $uri: A string containing the destination location. This must be a stream wrapper URI.
string $data: A string containing the contents of the file.
bool $overwrite: (optional) Bool, set to TRUE to overwrite a file.
Return value
array Empty array if not errors happened, list of errors if the write had any issues.
5 calls to advagg_save_data()
- advagg_create_subfile in ./
advagg.inc - Write CSS parts to disk; used when CSS selectors in one file is > 4096.
- advagg_htaccess_check_generate in ./
advagg.missing.inc - Generate .htaccess rules and place them in advagg dir.
- advagg_mod_init in advagg_mod/
advagg_mod.module - Implements hook_init().
- advagg_save_aggregate in ./
advagg.missing.inc - Save an aggregate given a filename, the files included in it, and the type.
- _advagg_relocate_save_remote_asset in advagg_relocate/
advagg_relocate.advagg.inc - Parse the font family string into a structured array.
File
-
./
advagg.missing.inc, line 1271
Code
function advagg_save_data($uri, $data, $overwrite = FALSE) {
$t = get_t();
$errors = array();
// Clear the stat cache.
module_load_include('inc', 'advagg', 'advagg');
advagg_clearstatcache($uri);
// Prepare dir if needed.
$dir = dirname($uri);
$dir_good = file_prepare_directory($dir, FILE_CREATE_DIRECTORY);
if (!$dir_good) {
$errors[1] = $t('The directory for @file can not be created or is not writable.', array(
'@file' => $uri,
));
return $errors;
}
// File already exists.
if (!$overwrite && file_exists($uri) && filesize($uri) > 0) {
if (variable_get('advagg_debug', ADVAGG_DEBUG) >= 2) {
watchdog('advagg-debug', 'File @uri exists and overwrite is false.', array(
'@uri' => $uri,
), WATCHDOG_DEBUG);
}
$errors[2] = $t('File (@file) already exits.', array(
'@file' => $uri,
));
return $errors;
}
// If data is empty, write a space.
if (empty($data)) {
$data = ' ';
}
// 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 and atomic.
//
// Get a temporary filename in the destination directory.
$dir = $uri_dir = drupal_dirname($uri) . '/';
// Corect the bug with drupal_tempnam where it doesn't pass subdirs to
// tempnam() if the dir is a stream wrapper.
$scheme = file_uri_scheme($uri_dir);
if ($scheme && file_stream_wrapper_valid_scheme($scheme)) {
$wrapper = file_stream_wrapper_get_instance_by_scheme($scheme);
if ($wrapper && method_exists($wrapper, 'getDirectoryPath')) {
$wrapper_dir_path = $wrapper->getDirectoryPath();
if (!empty($wrapper_dir_path)) {
$dir = $wrapper_dir_path . '/' . substr($uri_dir, strlen($scheme . '://'));
$uri = $dir . substr($uri, strlen($uri_dir));
}
}
}
// 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($uri);
if (variable_get('advagg_debug', ADVAGG_DEBUG) >= 2) {
$variables = array(
'@uri' => $uri,
);
watchdog('advagg-debug', 'Creating URI @uri', $variables, WATCHDOG_DEBUG);
$variables = array(
'@parts' => print_r($parts, TRUE),
);
watchdog('advagg-debug', 'File Parts <pre>@parts</pre>', $variables, WATCHDOG_DEBUG);
}
$extension = '.' . $parts['extension'];
if ($extension === '.gz' || $extension === '.br') {
$parts = pathinfo($parts['filename']);
$extension = '.' . $parts['extension'] . $extension;
}
// Create temp filename.
$temporary_file = $dir . 'advagg_file_' . drupal_hash_base64(microtime(TRUE) . mt_rand()) . $extension;
// Save to temporary filename in the destination directory.
$filepath = file_unmanaged_save_data($data, $temporary_file, FILE_EXISTS_REPLACE);
if ($filepath) {
// Perform the rename operation.
if (!advagg_rename($filepath, $uri)) {
// Unlink and try again for windows. Rename on windows does not replace
// the file if it already exists.
if (variable_get('advagg_debug', ADVAGG_DEBUG) >= 2) {
watchdog('advagg-debug', 'Rename failed. @to', array(
'@to' => $uri,
), WATCHDOG_WARNING);
}
@unlink($uri);
// Remove temporary_file if rename failed.
if (!advagg_rename($filepath, $uri)) {
$errors[20] = $t('Renaming the filename (@incorrect) to (@correct) failed.', array(
'@incorrect' => $filepath,
'@correct' => $uri,
));
@unlink($filepath);
if (file_exists($filepath)) {
$errors[22] = $t('unlinking @file failed.', array(
'@file' => $filepath,
));
}
watchdog('advagg', 'Rename 4 failed. Current: %current Target: %target', array(
'%current' => $filepath,
'%target' => $uri,
), WATCHDOG_ERROR);
}
}
// Check the filesize.
$file_size = @filesize($uri);
$expected_size = _advagg_string_size_in_bytes($data);
if ($file_size === 0) {
// Zero byte file.
$errors[26] = $t('Write successful, but the file is empty. @file', array(
'@file' => $filepath,
));
watchdog('advagg', 'Write successful, but the file is empty. Target: target. The empty file has been removed. If this error continues, performance will be greatly degraded.', array(
'%target' => $uri,
), WATCHDOG_ERROR);
// Better to serve straight from Drupal than have a broken file.
@unlink($uri);
}
elseif ($file_size > 0 && $file_size != $expected_size) {
// Data written to disk doesn't match.
$errors[28] = $t('Write successful, but the file is the wrong size. @file Expected size is @expected_size, actual size is @file_size', array(
'@file' => $uri,
'@expected_size' => $expected_size,
'@file_size' => $file_size,
));
watchdog('advagg', 'Write successful, but the file is the wrong size. %file Expected size is %expected_size, actual size is %file_size. The broken file has been removed. If this error continues, performance will be greatly degraded.', array(
'%file' => $uri,
'%expected_size' => $expected_size,
'%file_size' => $file_size,
), WATCHDOG_ERROR);
// Better to serve straight from Drupal than have a broken file.
@unlink($uri);
}
}
else {
$errors[24] = $t('Write failed. @file', array(
'@file' => $temporary_file,
));
watchdog('advagg', 'Write failed. Target: %target', array(
'%target' => $temporary_file,
), WATCHDOG_ERROR);
}
// Cleanup leftover files.
if (file_exists($temporary_file)) {
@unlink($temporary_file);
}
if (file_exists($filepath)) {
@unlink($filepath);
}
return $errors;
}