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;
}