/** * Updates the appropriate cache file * * @param string title of the datastore item * @param mixed The data associated with the title * * @return void */ function build($title, $data) { if (!in_array($title, $this->cacheableitems)) { return; } if (!file_exists(DATASTORE . '/datastore_cache.php')) { // file doesn't exist so don't try to write to it return; } $data_code = vb_var_export(unserialize(trim($data)), true); if ($this->lock()) { $cache = file_get_contents(DATASTORE . '/datastore_cache.php'); // this is equivalent to the old preg_match system, but doesn't have problems with big files (#23186) $open_match = strpos($cache, "### start {$title} ###"); if ($open_match) { // matched and not at the beginning $preceding = $cache[$open_match - 1]; if ($preceding != "\n" and $preceding != "\r") { $open_match = false; } } if ($open_match) { $close_match = strpos($cache, "### end {$title} ###", $open_match); if ($close_match) { // matched and not at the beginning $preceding = $cache[$close_match - 1]; if ($preceding != "\n" and $preceding != "\r") { $close_match = false; } } } // if we matched the beginning and end, then update the cache if (!empty($open_match) and !empty($close_match)) { $replace_start = $open_match - 1; // include the \n $replace_end = $close_match + strlen("### end {$title} ###"); $cache = substr_replace($cache, "\n### start {$title} ###\n\${$title} = {$data_code};\n### end {$title} ###", $replace_start, $replace_end - $replace_start); } // try an atomic operation first, if that fails go for the old method $atomic = false; if ($fp = @fopen(DATASTORE . '/datastore_cache_atomic.php', 'w')) { fwrite($fp, $cache); fclose($fp); $atomic = $this->atomic_move(DATASTORE . '/datastore_cache_atomic.php', DATASTORE . '/datastore_cache.php'); } if (!$atomic and $fp = @fopen(DATASTORE . '/datastore_cache.php', 'w')) { fwrite($fp, $cache); fclose($fp); } $this->unlock(); /*insert query*/ $this->dbobject->query_write("\n\t\t\t\tREPLACE INTO " . TABLE_PREFIX . "adminutil\n\t\t\t\t\t(title, text)\n\t\t\t\tVALUES\n\t\t\t\t\t('datastore', '" . $this->dbobject->escape_string($cache) . "')\n\t\t\t"); } else { trigger_error('Could not obtain file lock', E_USER_ERROR); } }
/** * Wrapper for the PHP function var_export to work around PHP bug #52534. See: http://bugs.php.net/bug.php?id=52534 * * @param mixed The variable to be exported * @param bool Whether or not to return the output * @param int Recursion level (for internal function recursive calls only) * * @return mixed Retuns the exported value, or null */ function vb_var_export($expression, $return = false, $level = 0) { // test if workaround is needed static $needs_workaround = null; if ($needs_workaround === null) { $test = var_export(array(-1 => 1), true); $needs_workaround = strpos($test, '-1') === false; } // skip the workaround when appropriate if (!$needs_workaround) { return var_export($expression, $return); } // begin workaround static $tab = ' '; $output = ''; if (is_array($expression)) { // use this function for arrays $tabs = str_repeat($tab, $level); if ($level > 0) { $output .= "\n{$tabs}"; } $output .= "array (\n"; foreach ($expression as $k => $v) { // use var_export for keys, as they cannot be arrays $output .= "{$tabs}{$tab}" . var_export($k, true) . ' => ' . vb_var_export($v, true, $level + 1) . ",\n"; } $output .= "{$tabs})"; } else { // use var_export for everything but arrays $output .= var_export($expression, true); } if ($level == 0) { // done // strip trailing spaces or tabs on each line to mimic var_export $output = preg_replace("/[ \t]+(\r\n|\n|\r)/", '$1', $output); if ($return) { return $output; } else { echo $output; return null; } } else { // return from recursive call return $output; } }