data_dir = $dbparam['directory']; if (file_exists($this->data_dir) and is_file($this->data_dir)) unlink($this->data_dir); if (is_dir($this->data_dir) == false) { mkdir($this->data_dir, 0755); } $this->_dir_names = array('ver_data' => $this->data_dir . '/' . 'ver_data', 'page_data' => $this->data_dir . '/' . 'page_data', 'latest_ver' => $this->data_dir . '/' . 'latest_ver', 'links' => $this->data_dir . '/' . 'links'); foreach ($this->_dir_names as $key => $val) { if (file_exists($val) and is_file($val)) unlink($val); if (is_dir($val) == false) mkdir($val, 0755); } $this->_page_data = NULL; $this->_page_version_data = NULL; $this->_latest_versions = NULL; } // ********************************************************************* // common file load / save functions: function _pagename2filename($type, $pagename, $version) { if ($version == 0) return $this->_dir_names[$type] . '/' . urlencode($pagename); else return $this->_dir_names[$type] . '/' . urlencode($pagename) . '--' . $version; } function _loadPage($type, $pagename, $version, $set_pagename = true) { $filename = $this->_pagename2filename($type, $pagename, $version); if (!file_exists($filename)) return NULL; if (!filesize($filename)) return array(); if ($fd = @fopen($filename, "rb")) { $locked = flock($fd, 1); # Read lock if (!$locked) { ExitWiki("Timeout while obtaining lock. Please try again"); } if ($data = fread($fd, filesize($filename))) { $pd = unserialize($data); if ($set_pagename == true) $pd['pagename'] = $pagename; if ($version != 0) $pd['version'] = $version; if (!is_array($pd)) ExitWiki(sprintf(gettext("'%s': corrupt file"), htmlspecialchars($filename))); else return $pd; } fclose($fd); } return NULL; } function _savePage($type, $pagename, $version, $data) { $filename = $this->_pagename2filename($type, $pagename, $version); if ($fd = fopen($filename, 'a+b')) { $locked = flock($fd, 2); // Exclusive blocking lock if (!$locked) { ExitWiki("Timeout while obtaining lock. Please try again"); } rewind($fd); ftruncate($fd, 0); $pagedata = serialize($data); $len = strlen($pagedata); $num = fwrite($fd, $pagedata, $len); assert($num == $len); fclose($fd); } else { ExitWiki("Error while writing page '$pagename'"); } } function _removePage($type, $pagename, $version) { $filename = $this->_pagename2filename($type, $pagename, $version); if (!file_exists($filename)) return NULL; $f = @unlink($filename); if ($f == false) trigger_error("delete file failed: " . $filename . " ver: " . $version, E_USER_WARNING); } // ********************************************************************* // ********************************************************************* // Load/Save Version-Data function _loadVersionData($pagename, $version) { if ($this->_page_version_data != NULL) { if (($this->_page_version_data['pagename'] == $pagename) && ($this->_page_version_data['version'] == $version) ) { return $this->_page_version_data; } } $vd = $this->_loadPage('ver_data', $pagename, $version); if ($vd != NULL) { $this->_page_version_data = $vd; if (($this->_page_version_data['pagename'] == $pagename) && ($this->_page_version_data['version'] == $version) ) { return $this->_page_version_data; } } return NULL; } function _saveVersionData($pagename, $version, $data) { $this->_savePage('ver_data', $pagename, $version, $data); // check if this is a newer version: if ($this->_getLatestVersion($pagename) < $version) { // write new latest-version-info $this->_setLatestVersion($pagename, $version); } } // ********************************************************************* // Load/Save Page-Data function _loadPageData($pagename) { if ($this->_page_data != NULL) { if ($this->_page_data['pagename'] == $pagename) { return $this->_page_data; } } $pd = $this->_loadPage('page_data', $pagename, 0); if ($pd != NULL) $this->_page_data = $pd; if ($this->_page_data != NULL) { if ($this->_page_data['pagename'] == $pagename) { return $this->_page_data; } } return array(); // no values found } function _savePageData($pagename, $data) { $this->_savePage('page_data', $pagename, 0, $data); } // ********************************************************************* // Load/Save Latest-Version function _saveLatestVersions() { $data = $this->_latest_versions; if ($data == NULL) $data = array(); $this->_savePage('latest_ver', 'latest_versions', 0, $data); } function _setLatestVersion($pagename, $version) { // make sure the page version list is loaded: $this->_getLatestVersion($pagename); if ($version > 0) { $this->_getLatestVersion($pagename); $this->_latest_versions[$pagename] = $version; } else { // Remove this page from the Latest-Version-List: unset($this->_latest_versions[$pagename]); } $this->_saveLatestVersions(); } function _loadLatestVersions() { if ($this->_latest_versions != NULL) return; $pd = $this->_loadPage('latest_ver', 'latest_versions', 0, false); if ($pd != NULL) $this->_latest_versions = $pd; else $this->_latest_versions = array(); // empty array } function _getLatestVersion($pagename) { $this->_loadLatestVersions(); if (array_key_exists($pagename, $this->_latest_versions) == false) return 0; // do version exists return $this->_latest_versions[$pagename]; } // ********************************************************************* // Load/Save Page-Links function _loadPageLinks($pagename) { $pd = $this->_loadPage('links', $pagename, 0, false); if ($pd != NULL) return $pd; ; return array(); // no values found } function _savePageLinks($pagename, $links) { $this->_savePage('links', $pagename, 0, $links); } /** * Get page meta-data from database. * * @param $pagename string Page name. * @return hash * Returns a hash containing the page meta-data. * Returns an empty array if there is no meta-data for the requested page. * Keys which might be present in the hash are: *
* $backend->update_pagedata($pagename, array('locked' => 1)); ** will set the value of 'locked' to 1 for the specified page, but it * will not affect the value of 'hits' (or whatever other meta-data * may have been stored for the page.) * * To delete a particular piece of meta-data, set it's value to false. *
* $backend->update_pagedata($pagename, array('locked' => false)); ** * @param $pagename string Page name. * @param $newdata hash New meta-data. */ /** * This will create a new page if page being requested does not * exist. */ function update_pagedata($pagename, $newdata) { $data = $this->get_pagedata($pagename); if (count($data) == 0) { $this->_savePageData($pagename, $newdata); // create a new pagedata-file return; } foreach ($newdata as $key => $val) { if (empty($val)) unset($data[$key]); else $data[$key] = $val; } $this->_savePageData($pagename, $data); // write new pagedata-file } /** * Get the current version number for a page. * * @param $pagename string Page name. * @return int The latest version number for the page. Returns zero if * no versions of a page exist. */ function get_latest_version($pagename) { return $this->_getLatestVersion($pagename); } /** * Get preceding version number. * * @param $pagename string Page name. * @param $version int Find version before this one. * @return int The version number of the version in the database which * immediately preceeds $version. * * FIXED: Check if this version really exists! */ function get_previous_version($pagename, $version) { $prev = ($version > 0 ? $version - 1 : 0); while ($prev and !file_exists($this->_pagename2filename('ver_data', $pagename, $prev))) { $prev--; } return $prev; } /** * Get revision meta-data and content. * * @param $pagename string Page name. * @param $version integer Which version to get. * @param $want_content boolean * Indicates the caller really wants the page content. If this * flag is not set, the backend is free to skip fetching of the * page content (as that may be expensive). If the backend omits * the content, the backend might still want to set the value of * '%content' to the empty string if it knows there's no content. * * @return hash The version data, or false if specified version does not * exist. * * Some keys which might be present in the $versiondata hash are: *
* trigger_error("Message goes here.", E_USER_WARNING); ** * @return boolean True iff database is in a consistent state. */ function check() { //trigger_error("check: Not Implemented", E_USER_WARNING); } /** * Put the database into a consistent state. * * This should put the database into a consistent state. * (I.e. rebuild indexes, etc...) * * @return boolean True iff successful. */ function rebuild() { //trigger_error("rebuild: Not Implemented", E_USER_WARNING); } function _parse_searchwords($search) { $search = strtolower(trim($search)); if (!$search) return array(array(), array()); $words = preg_split('/\s+/', $search); $exclude = array(); foreach ($words as $key => $word) { if ($word[0] == '-' && $word != '-') { $word = substr($word, 1); $exclude[] = preg_quote($word); unset($words[$key]); } } return array($words, $exclude); } } class WikiDB_backend_file_iter extends WikiDB_backend_iterator { function WikiDB_backend_file_iter(&$backend, &$query_result, $options = array()) { $this->_backend = &$backend; $this->_result = $query_result; $this->_options = $options; if (count($this->_result) > 0) reset($this->_result); } function next() { if (!$this->_result) return false; if (count($this->_result) <= 0) return false; $e = each($this->_result); if ($e == false) { return false; } $pn = $e[1]; if (is_array($pn) and isset($pn['linkto'])) { // support relation link iterator $pn = $pn['linkto']; } $pagedata = $this->_backend->get_pagedata($pn); // don't pass _cached_html via iterators if (isset($pagedata['_cached_html'])) unset($pagedata['_cached_html']); unset($pagedata['pagename']); $rec = array('pagename' => $pn, 'pagedata' => $pagedata); if (is_array($e[1])) { $rec['linkrelation'] = $e[1]['relation']; } //$rec['version'] = $backend->get_latest_version($pn); //$rec['versiondata'] = $backend->get_versiondata($pn, $rec['version'], true); return $rec; } function asArray() { reset($this->_result); return $this->_result; } function count() { return count($this->_result); } function free() { $this->_result = array(); } } // Local Variables: // mode: php // tab-width: 8 // c-basic-offset: 4 // c-hanging-comment-ender-p: nil // indent-tabs-mode: nil // End: