$a_word_count) { if ($a_word_count <= 0) return 0; $total += $a_word_count; } return $total; } function comp_results($aresult, $bresult) { $acount = $aresult["count"]; $bcount = $bresult["count"]; $apage = $aresult["page"]; $bpage = $bresult["page"]; if (total_count($acount) > total_count($bcount)) return -1; if (total_count($acount) < total_count($bcount)) return 1; if (total_count($acount) == total_count($bcount)) { if (get_tag($apage, "last-modified") > get_tag($bpage, "last-modified")) return -1; if (get_tag($apage, "last-modified") < get_tag($bpage, "last-modified")) return 1; else return 0; } } function get_tag($result, $tagname) { preg_match("&<$tagname>((?:(?!).)*)&is", $result, $matches); if (count($matches) > 1) return $matches[1]; else return ""; } function write_log_file($log_file, $log_file_size, $search_string) { /* if the log file isn't specified, don't write it */ if (!isset($log_file) || $log_file == "") return; /* if the size isn't set assume a big number */ if (!isset($log_file_size) || $log_file_size == "") $log_file_size = 30000; /* prepare to write the log file */ $log_array = array(); if (file_exists($log_file)) { // if one exists $log = file_get_contents($log_file); // read it in $log_array = split("\n", $log); // split on newlines if (count($log_array) > $log_file_size + 1) { // if it is too big array_unshift($log_array); // take off the leading tag array_unshift($log_array); // take off the first element array_shift($log_array, ""); // reinsert the leading tag } /* pop off the last bits of the file */ array_pop($log_array); array_pop($log_array); /* push the new query */ array_push($log_array, " " . $search_string . ""); /* push the final tag */ array_push($log_array, ""); } else { $log_array = array("", " " . $search_string . "", ""); } if (!$handle = fopen($log_file, "w")) { echo "Cannot open log file ($log_file)"; exit; } foreach ($log_array as $log_entry) { if (fwrite($handle, $log_entry . "\n") === FALSE) { echo "Cannot write to file ($log_file)"; exit; } } fclose($handle); } function get_search_database($index, $databases) { /* if the number is not valid, then search everything */ if ($index < 0 or $index > count($databases)) { $file = ""; /* load all files */ foreach ($databases as $fname) $file .= file_get_contents($fname); } else { /* decide which file to search from */ $fname = $databases[$index]; /* load the file */ $file = file_get_contents($fname); } return $file; } function get_matches($search, $to_search) { $results = array(); // prepare the results if ($search != "") { $words = explode(" ", $search); // break up search words $pages = explode("", $to_search); // split pages foreach($pages as $page) { $count = generate_count($words, $page); $total_count = total_count($count); if ($total_count > 0 && get_tag($page, "path") != "") { $results[] = array('count' => $count, 'page' => $page); } } } /* sort the results */ usort($results, 'comp_results'); return $results; } $config = Resource::connect($config_file); $per_page = $config->get_var("results_per_page"); $dbfiles = $config->get_var_all("files.file"); $frame_file = $config->get_var("frame_file"); $template = $config->get_var("result_template"); $log_file = $config->get_var("synced-files.file.path"); $log_size = $config->get_var("log_size"); $text = get_search_database($search_database_index, $dbfiles); $results = get_matches($search_string, $text); $no_result_string = $config->get_var("noresults_template"); $header = $config->get_var("header_template"); $next_string = $config->get_var("next_page_template"); $prev_string = $config->get_var("prev_page_template"); /* prepare the output */ $output = file_get_contents($frame_file); $oresults = ""; $total_results = count($results); $starting_result = $start + 1; $ending_result = min($total_results, $start + $per_page); /* print out results counts */ if ($total_results <= 0) $oresults .= $no_result_string; else $oresults .= $header; // $oresults .= "

Results $nstart-$end of $total_results

\n"; /* print each result */ for ($i = $start; $i < min(count($results), $start + $per_page); $i++) $oresults .= template($template, $results[$i]['page']); /* initialize the variables for next and prev links */ $prevstart = $start - $per_page; $nextstart = $start + $per_page; $to_go = min(count($results) - $nextstart, $per_page); $me = $_SERVER['PHP_SELF']; /* print next and previous links */ if ($start != 0) { $oresults .= "$prev_string "; } if ($to_go > 0) { $oresults .= "$next_string"; } $output = str_replace('{$SEARCH}', $oresults, $output); $output = str_replace('{$QUERY}', $search_string, $output); $output = str_replace('{$START_RESULT}', $starting_result, $output); $output = str_replace('{$END_RESULT}', $ending_result, $output); $output = str_replace('{$TOTAL_RESULTS}', $total_results, $output); $output = str_replace('{$PER_PAGE}', $per_page, $output); $output = str_replace('{$RESULTS_ON_NEXT_PAGE}', $to_go, $output); print $output; if (isset($log_file)) write_log_file($log_file, $log_size, $search_string); /* XXX Resource.php XXX */ abstract class Resource { abstract function sync(); abstract function is_synced(); public $config; function __construct() { $this->config = array(); } public function get_var($key) { if (!isset($this->config)) return null; $k = explode(".", $key); // split on dots return $this->do_get($this->config, $k, false); } public function get_var_all($key) { if (!isset($this->config)) return null; $k = explode(".", $key); // split on dots return $this->do_get($this->config, $k, true); } public function set_var($key, $value) { if (!isset($this->config)) // error recovery return FALSE; $k = explode(".", $key); // split on dots $this->config = $this->do_set($this->config, $k, $value); // do the set return TRUE; } private function do_set($target, $path, $value) { if (count($path) <= 0) { // we've reached our destination return $value; // return the value } $element = array_shift($path); // get the next element if (!isset($target[$element])) $target[$element] = array(); $target[$element] = $this->do_set($target[$element], $path, $value); return $target; } private function do_get($target, $path, $return_all) { if (count($path) <= 0) { // we've reached our destination $to_ret = $target; /* check if we want to return everything or just the first element */ if (is_array($target) && $return_all == false) $to_ret = array_shift($target); if ($return_all == true && (!is_array($target) || $this->associative($to_ret))) $to_ret = array($to_ret); return $to_ret; // return the value } $element = array_shift($path); // get the next element if (!isset($target[$element])) return null; return $this->do_get($target[$element], $path, $return_all); } /* here we want to detect whether this is a file config or otherwise */ function connect($file) { $new_config = FileResource::connect($file); return $new_config; } protected function associative($array) { foreach($array as $key => $value) { if (!is_int($key)) return TRUE; } return FALSE; } } abstract class FileResource extends Resource { abstract function serialize(); protected $contents; protected $filename; function __construct($filename) { parent::__construct(); $this->filename = $filename; } function connect($file) { /* get the file extension */ $ext = str_replace('.','',strstr($file, '.')); /* check if the file is an XML file */ if (strtolower($ext) == "xml") $config_obj = new XMLResource($file); /* otherwise use a plain text output */ // else // $new_config = new TextResource($file); return $config_obj; } function read_file() { $temp = file_get_contents($this->filename); if ($temp == FALSE) // file read error return $temp; $this->contents = $temp; return true; } function write_file() { $result = file_put_contents($this->filename, $this->contents); if ($result <= 0 && count($contents) > 0) // file write error return FALSE; return TRUE; // return to child class } function sync() { /* check to make sure we can sync */ // if (is_writeable($this->filename) == FALSE) { // return FALSE; // } /* make a serialization of this config */ $serial = $this->serialize(); if ($serial == FALSE) return FALSE; $old_contents = $this->contents; /* record old contents */ $this->contents = $serial; /* record this serialization */ $result = $this->write_file(); if ($result == FALSE) { // the write failed $this->contents = $old_contents; return FALSE; } return TRUE; } function is_synced() { /* make a serialization of this config */ $serial = $this->serialize(); /* grab the file contents */ $temp = file_get_contents($this->filename); if ($temp == $serial && $serial != FALSE) // if this didn't work out return TRUE; // success else // something went wrong return FALSE; } } class XMLResource extends FileResource { function serialize() { $dom = new DOMDocument('1.0'); // create a dom /* create the root config node */ $root = $dom->createElement('config'); $root = $dom->appendChild($root); $this->arrayToDOM($this->config, $root, $dom); // turn config to dom $dom->formatOutput = true; // format output return $dom->saveXML(); // serialize the dom } function __construct($filename) { parent::__construct($filename); $this->initialize(); } function initialize() { /* we must be able to either read or write this file */ if (is_readable($this->filename) == FALSE && is_writeable($this->filename) == FALSE) { return FALSE; } $this->dom = new DOMDocument(); // create a DOM /* if we can read the DOM */ if (is_readable($this->filename)) { $this->read_file(); // read its contents $this->config = $this->parse_xml($this->contents); } } private function arrayToDOM($array, $node, $doc) { if (!is_array($array)) { $text = $doc->createTextnode($array); $node->appendChild($text); return; } foreach ($array as $key => $value) { if (is_array($value) && !$this->associative($value)) { foreach ($value as $vvalue) { $newNode = $doc->createElement($key); $newNode = $node->appendChild($newNode); $this->arrayToDOM($vvalue, $newNode, $doc); } } else { $newNode = $doc->createElement($key); $newNode = $node->appendChild($newNode); $this->arrayToDOM($value, $newNode, $doc); } } } private function parse_xml($xml) { $simplexml = simplexml_load_string($xml); return $this->xml_to_array($simplexml); } private function xml_to_array($xml) { if ($xml instanceof SimpleXMLElement) { $children = $xml->children(); $return = null; } $arrayed = FALSE; foreach ($children as $element => $value) { if ($value instanceof SimpleXMLElement) { $values = (array)$value->children(); if (count($values) > 0) { if (!isset($return[$element])) { $return[$element] = $this->xml_to_array($value); } else { if ($arrayed == FALSE) { $arrayed = TRUE; $return[$element] = array($return[$element], $this->xml_to_array($value)); } else { $return[$element][] = $this->xml_to_array($value); } } } else { if (!isset($return[$element])) { $return[$element] = (string) $value; } else { if (!is_array($return[$element])) $return[$element] = array($return[$element], (string)$value); else $return[$element][] = (string)$value; } } } } if (is_array($return)) { return $return; } else { return $false; } } } /* XXX Args.php XXX */ class Args { public function get($name) { global $argv; global $argc; if (isset($_POST[$name])) { return $_POST[$name]; } else if (isset($_GET[$name])) { return $_GET[$name]; } else { for ($i = 1; $i < $argc; $i++) { $arg = $argv[$i]; $splitted = explode("=", $arg); if ($splitted[0] == $name && count($splitted) > 1) return $splitted[1]; } } return null; } } ?>