Created
May 8, 2012 17:48
-
-
Save norv/2637875 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
function updateSettingsFile($config_vars) | |
{ | |
global $boarddir, $cachedir, $context; | |
// Updating the db_last_error, then don't mess around with Settings.php | |
if (count($config_vars) === 1 && isset($config_vars['db_last_error'])) | |
{ | |
updateDbLastError($config_vars['db_last_error']); | |
return; | |
} | |
// When was Settings.php last changed? | |
$last_settings_change = filemtime($boarddir . '/Settings.php'); | |
// Load the settings file. | |
$settingsArray = trim(file_get_contents($boarddir . '/Settings.php')); | |
// Break it up based on \r or \n, and then clean out extra characters. | |
if (strpos($settingsArray, "\n") !== false) | |
$settingsArray = explode("\n", $settingsArray); | |
elseif (strpos($settingsArray, "\r") !== false) | |
$settingsArray = explode("\r", $settingsArray); | |
else | |
return; | |
// Presumably, the file has to have stuff in it for this function to be called :P. | |
if (count($settingsArray) < 10) | |
return; | |
// remove any /r's that made there way in here | |
foreach ($settingsArray as $k => $dummy) | |
$settingsArray[$k] = strtr($dummy, array("\r" => '')) . "\n"; | |
// go line by line and see whats changing | |
for ($i = 0, $n = count($settingsArray); $i < $n; $i++) | |
{ | |
// Don't trim or bother with it if it's not a variable. | |
if (substr($settingsArray[$i], 0, 1) != '$') | |
continue; | |
$settingsArray[$i] = trim($settingsArray[$i]) . "\n"; | |
// Look through the variables to set.... | |
foreach ($config_vars as $var => $val) | |
{ | |
// be sure someone is not updating this with a group | |
if ($var === 'db_last_error') | |
{ | |
updateDbLastError($val); | |
unset($config_vars[$var]); | |
} | |
elseif (strncasecmp($settingsArray[$i], '$' . $var, 1 + strlen($var)) == 0) | |
{ | |
$comment = strstr(substr($settingsArray[$i], strpos($settingsArray[$i], ';')), '#'); | |
$settingsArray[$i] = '$' . $var . ' = ' . $val . ';' . ($comment == '' ? '' : "\t\t" . rtrim($comment)) . "\n"; | |
// This one's been 'used', so to speak. | |
unset($config_vars[$var]); | |
} | |
} | |
// End of the file ... maybe | |
if (substr(trim($settingsArray[$i]), 0, 2) == '?' . '>') | |
$end = $i; | |
} | |
// This should never happen, but apparently it is happening. | |
if (empty($end) || $end < 10) | |
$end = count($settingsArray) - 1; | |
// Still more varialbes to go? Then lets add them at the end. | |
if (!empty($config_vars)) | |
{ | |
if (trim($settingsArray[$end]) == '?' . '>') | |
$settingsArray[$end++] = ''; | |
else | |
$end++; | |
// Add in all the newly defined vars that were passed | |
foreach ($config_vars as $var => $val) | |
$settingsArray[$end++] = '$' . $var . ' = ' . $val . ';' . "\n"; | |
$settingsArray[$end] = '?' . '>'; | |
} | |
else | |
$settingsArray[$end] = trim($settingsArray[$end]); | |
// Sanity error checking: the file needs to be at least 12 lines. | |
if (count($settingsArray) < 12) | |
return; | |
// Try to avoid a few pitfalls: | |
// - like a possible race condition, | |
// - or a failure to write at low diskspace | |
// | |
// Check before you act: if cache is enabled, we can do a simple write test | |
// to validate that we even write things on this filesystem. | |
if ((empty($cachedir) || !file_exists($cachedir)) && file_exists($boarddir . '/cache')) | |
$cachedir = $boarddir . '/cache'; | |
$test_fp = @fopen($cachedir . '/settings_update.tmp', "w+"); | |
if ($test_fp) | |
{ | |
fclose($test_fp); | |
$written_bytes = file_put_contents($cachedir . '/settings_update.tmp', 'test', LOCK_EX); | |
@unlink($cachedir . '/settings_update.tmp'); | |
if ($written_bytes !== 4) | |
{ | |
// Oops. Low disk space, perhaps. Don't mess with Settings.php then. | |
// No means no. :P | |
return; | |
} | |
} | |
// You asked for it... | |
clearstatcache(); | |
if (filemtime($boarddir . '/Settings.php') === $last_settings_change) | |
{ | |
$write_settings = implode('', $settingsArray); | |
$written_bytes = file_put_contents($boarddir . '/Settings.php', $write_settings, LOCK_EX); | |
if ($written_bytes !== strlen($write_settings)) | |
{ | |
// Well this is not good at all, lets see if we can save this | |
$context['settings_message'] = 'settings_error'; | |
if (file_exists($boarddir . '/Settings_bak.php')) | |
@copy($boarddir . '/Settings_bak.php', $boarddir . '/Settings.php'); | |
// @todo fatal lang error if copy failed ? | |
} | |
} | |
} | |
/** | |
* Saves the time of the last db error for the error log | |
* - Done separately from updateSettingsFile to avoid race conditions | |
* which can occur during a db error | |
* - If it fails Settings.php will assume 0 | |
*/ | |
function updateDbLastError($time) | |
{ | |
global $boarddir; | |
// Write out the db_last_error file with the error timestamp | |
file_put_contents($boarddir . '/db_last_error.php', "<?php\n$db_last_error = " . $time . ";\n?" . ">\n", LOCK_EX); | |
@touch($boarddir . '/' . 'Settings.php'); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment