gb_fields = $field_array; $this->db_driver = NULL; $this->sort_field = NULL; $this->sort_type = NULL; } ## --------------------- ## ## -----+++ Pri +++----- ## ## --------------------- ## function getAllRecords() { $records_array = $this->db_driver->parseXMLEntry(); return $records_array; break; } // this callback function is used to sort function _cmp($array_a, $array_b) { $array_a[$this->sort_field] = strtolower($array_a[$this->sort_field]); $array_b[$this->sort_field] = strtolower($array_b[$this->sort_field]); if ($array_a[$this->sort_field] == $array_b[$this->sort_field]) return 0; if ($this->sort_type == "DESC") { return ( $array_a[$this->sort_field] < $array_b[$this->sort_field] ) ? 1 : -1; } else return ( $array_a[$this->sort_field] < $array_b[$this->sort_field] ) ? -1 : 1; } // each value of $array is an array function makeSafeOutput(&$array) { foreach (array_keys($array) as $k) { ValidIO::makeSafeOutputFLAT($array[$k]); } } ## --------------------- ## ## -----+++ Pub +++----- ## ## --------------------- ## function gbConfig($db_info) { $this->db_driver = new XMLdb($db_info, $this->gb_fields); } function putIntoDB($data_array, $id = NULL, $nouv = NULL) { if ($id == NULL && $nouv == NULL) { if ( !$this->db_driver->addNewEntry($data_array) ) die("Stockage impossible."); } else { if ( !$this->db_driver->addNewEntry($data_array, $id, $nouv) ) die("Stockage impossible."); } } function getRecords($sort_field = "id", $sort_type = "ASC", $from = 0, $limit = 0) { // prepare for callback function _cmp($array_a, $array_b) $this->sort_field = ( in_array(strval($sort_field), $this->gb_fields) ) ? $sort_field : 'id'; $this->sort_type = ( strtoupper($sort_type) == "DESC" ) ? "DESC" : "ASC"; if ($from < 0) { $from = 0; } // sort $all_records = $this->getAllRecords(); usort($all_records, array($this, "_cmp")); // return the records limited by $from and $limit $record_total = count($all_records); $record_max = $record_total - 1; if ($from > $record_max) { $from = $record_max; } $to = $from + $limit; if ($to < $from) { $to = $from + 1; } if ($to == $from || $to > $record_total) { $to = $record_total; } $results = array(); for ($i = $from; $i < $to; $i++) { $results[] = $all_records[$i]; } $this->makeSafeOutput($results); return $results; } function deleteRecord($id) { $id = intval($id); if (!$this->db_driver->deleteEntry($id)) die("Suppression du numéro " . $id . " impossible. Réessayer plus tard ?"); } function getToEdit($id) { $id = intval($id); $record = $this->db_driver->getOneEntry($id); foreach ($record as $k => $v) { $record[$k] = stripslashes($record[$k]); } return $record; } function updateRecord($id, $data_array) { $id = intval($id); if ( !$this->db_driver->addNewEntry($data_array, $id) ) die("Edition du numéro " . $id . " impossible. Réessayer plus tard ?"); } function getMaxID() { return $this->db_driver->getMaxID(); } function getRecordsTotal() { return $this->db_driver->getEntryTotal(); } } // END CLASS Guestbook # ---===---------------===--- # # ---=== PRIVATE CLASS ===--- # # ---===---------------===--- # class XMLdb { var $xml_db; var $xml_fields; var $xml_fields_total; var $xml_parser; var $xml_results; var $xml_temp; var $cur_tag; /* ============================================================= // This CONSTRUCTOR will create an XML file, which is considered // as Flat DB, whose form is like that: // // // // // // ]> // // // =============================================================== */ function XMLdb($filename, $field_array) { $this->xml_db = $filename; $this->xml_fields = array(); $this->xml_results = array(); $this->xml_temp = array(); $this->cur_tag = NULL; foreach ($field_array as $v) { $this->xml_fields[] = strtoupper($v); } $this->xml_fields_total = count($this->xml_fields); if ( !file_exists($this->xml_db) ) { $xml = "\r\n"; $xml .= "xml_fields_total - 1; for ($i = 0; $i <= $c; $i++) { $xml_GB_tags .= $this->xml_fields[$i]; $xml_GB_tags .= ( $i != $c ) ? ", " : ")>\r\n"; $xml_elements .= "\txml_fields[$i] . " (#PCDATA)>\r\n"; } $xml .= $xml_GB_tags; $xml .= "\t\t\r\n"; $xml .= $xml_elements; $xml .= "]>\r\n"; $xml .= "\r\n"; $xml .= ""; if ( !$this->makeXMLdatabase($xml) ) { print( "

La FAQ demandée n'existe pas !

\n

Faites marche arrière...

" ); die("

"); /* echo "

"; echo "

"; $this->dumpStructure($xml); die("

"); */ } } } ## --------------------- ## ## -----+++ Pri +++----- ## ## --------------------- ## function makeXMLdatabase($xml) { ignore_user_abort(true); $fp = @fopen($this->xml_db, "x+b"); if (!$fp) return false; else { if (flock($fp, 2)) { fwrite($fp, $xml); fflush($fp); flock($fp, 3); } else return false; fclose($fp); } ignore_user_abort(false); return true; } function dumpStructure($content) { echo nl2br(preg_replace("/\t/", "    ", htmlspecialchars($content))); } function makeXMLEntry($id, $data_array) { $xml = "\t\r\n"; for ($i = 0; $i < $this->xml_fields_total; $i++) { if ( !empty($data_array[$i]) ) $xml .= "\t\t<" . $this->xml_fields[$i] . ">" . $data_array[$i] . "xml_fields[$i] . ">\r\n"; } $xml .= "\t\r\n"; return $xml; } function streamWriteNewEntry($fp, $xml) { fseek($fp, -8, SEEK_END); fwrite($fp, $xml); fwrite($fp, ""); fflush($fp); } function streamDeleteEntry($fp, $id) { fseek($fp, 0, SEEK_END); $filesize = ftell($fp); rewind($fp); $text = preg_replace("/\t.*?<\/GB>\r\n/is", NULL, fread($fp, $filesize), 1); rewind($fp); fwrite($fp, $text); fflush($fp); ftruncate($fp, ftell($fp)); } function streamGetIDTags($fp) { fseek($fp, 0, SEEK_END); $filesize = ftell($fp); rewind($fp); $text = fread($fp, $filesize); preg_match_all("//si", $text, $re); return $re[0]; } function streamGetMaxID($fp) { $id_tags_array = $this->streamGetIDTags($fp); foreach ($id_tags_array as $k => $v) { $id_tags_array[$k] = preg_replace("/[^\d]/", NULL, $v); } sort($id_tags_array); return end($id_tags_array); } function startElementHandler($xml, $element, $attribute) { $this->cur_tag = $element; if ( strcmp($element, "GB") == 0 ) { $this->xml_temp['id'] = $attribute['ID']; } } function cdataHandler($xml, $data) { $data = eregi_replace(">" . "[[:space:]]+" . "<", "><", $data); if ( in_array($this->cur_tag, $this->xml_fields) ) { $this->xml_temp[strtolower($this->cur_tag)] .= $data; } } function endElementHandler($xml, $element) { if ( strcmp($element, "GB") == 0 ) { $this->xml_results[] = $this->xml_temp; $this->xml_temp = array(); $this->cur_tag = NULL; } } ## --------------------- ## ## -----+++ Pub +++----- ## ## --------------------- ## // Values of $data_array must be arranged in order of $this->xml_fields // If $id is NULL, this function will increase id's value automatically // If $id is other than NULL, this function will delete the entry whose // id is equal to this id's value and add a new entry with this id. function addNewEntry($data_array, $id = NULL, $nouv = NULL) { ignore_user_abort(true); $fp = fopen($this->xml_db, "r+b"); if (!$fp) return false; else { if (flock($fp, 2)) { if ($id == NULL) { // get the last record's ID $last_id = $this->streamGetMaxID($fp); $id = $last_id + 5; } // prepare data to put into flat db $xml = $this->makeXMLEntry($id, $data_array); // write new record $this->streamWriteNewEntry($fp, $xml); flock($fp, 3); } else return false; fclose($fp); } ignore_user_abort(false); return true; } function parseXMLEntry() { $this->xml_parser = xml_parser_create("iso-8859-1"); xml_set_object($this->xml_parser, $this); xml_set_element_handler($this->xml_parser, "startElementHandler", "endElementHandler"); xml_set_character_data_handler($this->xml_parser, "cdataHandler"); xml_parser_set_option($this->xml_parser, XML_OPTION_CASE_FOLDING, 1); $fp = fopen($this->xml_db, "rb"); if (!$fp) return false; else { while ($data = fread($fp, filesize($this->xml_db))) { xml_parse($this->xml_parser, $data, feof($fp)) or die("Erreur ligne : " . xml_get_current_line_number($this->xml_parser) . ""); } xml_parser_free($this->xml_parser); fclose($fp); return $this->xml_results; } } function deleteEntry($id) { ignore_user_abort(true); $fp = fopen($this->xml_db, "r+b"); if (!$fp) return false; else { if (flock($fp, 2)) { $this->streamDeleteEntry($fp, $id); flock($fp, 3); } else return false; fclose($fp); } ignore_user_abort(false); return true; } function getOneEntry($id) { $fp = @fopen($this->xml_db, "rb"); if (!$fp) return false; else { while (!feof($fp)) { if ( preg_match("//i", fgets($fp, 4096), $re) ) { $text = NULL; while ( !preg_match("/<\/GB>/i", $buffer = fgets($fp, 4096)) ) { $text .= $buffer; } break; } } fclose($fp); $re = array(); preg_match_all("/(<([\S]+)[^>]*>)(.*)(<\/\\2>)/is", $text, $re); $record = array(); $record['id'] = $id; for ($i = 0; $i < $this->xml_fields_total; $i++) { $record[strtolower($re[2][$i])] = $re[3][$i]; } } return $record; } function getMaxID() { $fp = fopen($this->xml_db, "rb"); if (!fp) return false; else { if (flock($fp, 2)) { $max_id = $this->streamGetMaxID($fp); flock($fp, 3); } else return false; fclose($fp); } return $max_id; } function getEntryTotal() { $fp = fopen($this->xml_db, "rb"); if (!fp) return false; else { if (flock($fp, 2)) { $id_tags = $this->streamGetIDTags($fp); flock($fp, 3); } else return false; fclose($fp); } return count($id_tags); } } // END CLASS XMLdb # ---===---------------===--- # # ---=== PRIVATE CLASS ===--- # # ---===---------------===--- # class ValidIO { function makeSafeOutputFLAT(&$output) { if ( is_array($output) ) { foreach ($output as $k => $v) { $output[$k]=str_replace("\r","",$output[$k]); $output[$k]=str_replace("\n","
",trim($output[$k])); $output[$k]=preg_replace ("/\[i]([^\|]+?)\[\/i]/","$1", $output[$k]); $output[$k]=preg_replace ("/\[u]([^\|]+?)\[\/u]/","$1", $output[$k]); $output[$k]=preg_replace ("/\[b]([^\|]+?)\[\/b]/","$1", $output[$k]); $output[$k] = eregi_replace('(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1', $output[$k]); $output[$k] = eregi_replace('([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1\\2', $output[$k]); $output[$k] = eregi_replace('([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})','\\1', $output[$k]); $output[$k] = str_replace("&","&",$output[$k]); $output[$k] = stripslashes($output[$k]); } } else { $output=str_replace("\r","",$output); $output=str_replace("\n","\n
",trim($output)); $output=preg_replace ("/\[i]([^\|]+?)\[\/i]/","$1", $output); $output=preg_replace ("/\[u]([^\|]+?)\[\/u]/","$1", $output); $output=preg_replace ("/\[b]([^\|]+?)\[\/b]/","$1", $output); $output = eregi_replace('(((f|ht){1}tp://)[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1', $output); $output = eregi_replace('([[:space:]()[{}])(www.[-a-zA-Z0-9@:%_\+.~#?&//=]+)', '\\1\\2', $output); $output = eregi_replace('([_\.0-9a-z-]+@([0-9a-z][0-9a-z-]+\.)+[a-z]{2,3})','\\1', $output); $output = str_replace("&","&",$output); $output = stripslashes($output); } } }//END CLASS ValidInput ?>