library/smarty/libs/sysplugins/smarty_internal_write_file.php
changeset 46 f11c31f7fa3e
parent 45 a56e7f9a0463
child 47 03388ec805b4
equal deleted inserted replaced
45:a56e7f9a0463 46:f11c31f7fa3e
     1 <?php
       
     2 /**
       
     3  * Smarty write file plugin
       
     4  *
       
     5  * @package    Smarty
       
     6  * @subpackage PluginsInternal
       
     7  * @author     Monte Ohrt
       
     8  */
       
     9 
       
    10 /**
       
    11  * Smarty Internal Write File Class
       
    12  *
       
    13  * @package    Smarty
       
    14  * @subpackage PluginsInternal
       
    15  */
       
    16 class Smarty_Internal_Write_File {
       
    17     /**
       
    18      * Writes file in a safe way to disk
       
    19      *
       
    20      * @param  string $_filepath complete filepath
       
    21      * @param  string $_contents file content
       
    22      * @param  Smarty $smarty smarty instance
       
    23      *
       
    24      * @throws SmartyException
       
    25      * @return boolean true
       
    26      */
       
    27     public function writeFile($_filepath, $_contents, Smarty $smarty) {
       
    28         $_error_reporting = error_reporting();
       
    29         error_reporting($_error_reporting & ~E_NOTICE & ~E_WARNING);
       
    30         if ($smarty->_file_perms !== null) {
       
    31             $old_umask = umask(0);
       
    32         }
       
    33 
       
    34         $_dirpath = dirname($_filepath);
       
    35         // if subdirs, create dir structure
       
    36         if ($_dirpath !== '.' && !file_exists($_dirpath)) {
       
    37             mkdir($_dirpath, $smarty->_dir_perms === null ? 0777 : $smarty->_dir_perms, true);
       
    38         }
       
    39 
       
    40         // write to tmp file, then move to overt file lock race condition
       
    41         $_tmp_file = $_dirpath . DS . str_replace(array('.', ','), '_', uniqid('wrt', true));
       
    42         if (!file_put_contents($_tmp_file, $_contents)) {
       
    43             error_reporting($_error_reporting);
       
    44             throw new SmartyException("unable to write file {$_tmp_file}");
       
    45         }
       
    46 
       
    47         /*
       
    48          * Windows' rename() fails if the destination exists,
       
    49          * Linux' rename() properly handles the overwrite.
       
    50          * Simply unlink()ing a file might cause other processes
       
    51          * currently reading that file to fail, but linux' rename()
       
    52          * seems to be smart enough to handle that for us.
       
    53          */
       
    54         if (Smarty::$_IS_WINDOWS) {
       
    55             // remove original file
       
    56             if (is_file($_filepath)) {
       
    57                 @unlink($_filepath);
       
    58             }
       
    59             // rename tmp file
       
    60             $success = @rename($_tmp_file, $_filepath);
       
    61         } else {
       
    62             // rename tmp file
       
    63             $success = @rename($_tmp_file, $_filepath);
       
    64             if (!$success) {
       
    65                 // remove original file
       
    66                 if (is_file($_filepath)) {
       
    67                     @unlink($_filepath);
       
    68                 }
       
    69                 // rename tmp file
       
    70                 $success = @rename($_tmp_file, $_filepath);
       
    71             }
       
    72         }
       
    73         if (!$success) {
       
    74             error_reporting($_error_reporting);
       
    75             throw new SmartyException("unable to write file {$_filepath}");
       
    76         }
       
    77         if ($smarty->_file_perms !== null) {
       
    78             // set file permissions
       
    79             chmod($_filepath, $smarty->_file_perms);
       
    80             umask($old_umask);
       
    81         }
       
    82         error_reporting($_error_reporting);
       
    83 
       
    84         return true;
       
    85     }
       
    86 }