_primaryKey = $pk; $this->_file = $file; $this->_doc = new DOMDocument; $this->_doc->preserveWhiteSpace = false; $this->_doc->formatOutput = true; if($this->_doc->load($this->_file)){ $this->_xpath = new DOMXpath($this->_doc); } else{ if($createIfNotExist){ $this->createDatabase($file); }else{ $this->_file = null; $this->_doc = null; $this->xpath = null; } } } public function createDatabase($file){ $this->_file = $file; $this->_doc = DOMDocument::loadXML(' '); $this->_xpath = new DOMXpath($this->_doc); return $this->save(); } public function createTable($name){ if($name == '*' || $this->tableAlreadyExists($name)) return false; else return $this->insertNode(array('name'=>'table', 'attributes'=>array('name'=>$name))); } /** * @return bool */ public function tableAlreadyExists($tableName){ if($this->selectTable($tableName, 'count') >= 1) return true; return false; } public function selectTable($name, $format = 'node'){ return $this->select($name, null, null, null, $format); } public function isLoaded(){ if($this->_doc != null) return true; else return false; } public function count($from, $id = null, $attributes = null, $childs = null){ return $this->select($from, $id, $attributes, $childs, 'count'); } public function setPrimaryKey($pk){ $this->_primaryKey = $pk; } public function getPrimaryKey(){ return $this->_primaryKey; } public function getXPath(){ return $this->_xpath; } /** * Saving the DB file */ public function save(){ if($this->_doc != null && $this->_file != null){ $this->_doc->preserveWhiteSpace = false; $this->_doc->formatOutput = true; $this->_doc->save($this->_file); return true; }else{ return false; } } // TODO checking $request public function requestToArray($request){ foreach($request as $element){ /*if($childName != null && $childValue != null) $element = $element->parentNode;*/ $elementValue = $element->attributes->item(0)->value; $return[$elementValue]['attributes'] = array(); $return[$elementValue]['childs'] = array(); //Retrieving Attributes $attributes = $element->attributes; $length = $attributes->length; for ($i = 1; $i <= $length; $i++) { $return[$elementValue]['attributes'][$attributes->item($i)->name] = $attributes->item($i)->value; } // Retrivieving childs $nodes = $element->childNodes; $length = $nodes->length; for ($i = 1; $i <= $length; $i++) { $return[$elementValue]['childs'][$nodes->item($i)->nodeName] = $nodes->item($i)->nodeValue; } } return $return; } /** * Shortcuts for select */ public function selectFromAttribute($table, $attributes, $format = 'array'){ return $this->select($table, null, $attributes, null, $format); } public function selectFromChilds($table, $childs, $format = 'array'){ return $this->select($table, null, null, $childs, $format); } public function selectFromPK($table, $pk, $format = "array"){ return $this->select($table, $pk, null, null, $format); } /** * Allows you to get an array of the node you're looking for based on a "where" search thanks to child or attribute value * @param $from string Name of the table * @param $id string value of the primary key * @param $childs array name/value of the child node * @param $attributes array name/value of the attribute * @return array */ public function select($from, $id = null, $attributes = null, $childs = null, $format = 'array'){ if (!$from) { throw new Exception('uhoh, no table selected'); } if($id != null && count($id) == 1){ $attribute .= '[@' . $this->_primaryKey . ' = "' . $id . '"]'; } if($attributes != null){ foreach($attributes as $attributeName=>$attributeValue) $attribute .= '[@' . $attributeName . ' = "' . $attributeValue . '"]'; } if($childs != null){ foreach($childs as $childName=>$childValue) $child .= '[' . $childName . '="' . $childValue . '"]'; /*$child .= '/' . $childName . '[.="' . $childValue . '"]'; if(count($childs)>1){ $child = str_replace('/', '', $child); $child = '/'.$child; }*/ } if($from == '*') $request = $this->_xpath->query('//item'.$attribute.$child); else $request = $this->_xpath->query('//table[@name = "'.$from.'"]/item'.$attribute.$child); switch($format){ case "node": $return = $request; break; case "count": $return = $request->length; break; case "array": default: $return = $this->requestToArray($request); } return $return; } /** * Same as above, but user can build his own xpath */ public function select_xpath($from, $xpath, $format = 'array'){ if (!$from || !$xpath) { throw new Exception('uhoh, no table selected'); } $request = $this->_xpath->query('//table[@name = "'.$from.'"]/'.$xpath); switch($format){ case "node": $return = $request; break; case "count": $return = $request->length; break; case "array": default: $return = $this->requestToArray($request); } return $return; } /** * Allows you to insert a node into your DB thanks to an array * @param $node array with 'name' 'attributes' and 'childs' * @param $table string in which node you want to put it. By default, the root of the xml file * @param $position string 'before' or 'after' * @return bool */ // TODO other $where and $position public function insertNode($node, $table = null, $position = null){ if(!is_array($node) || !isset($node['name'])) return false; // Creating the node from an array $element = $this->_doc->createElement($node['name']); if(isset($node['attributes'])){ foreach($node['attributes'] as $attributeName=>$attributeValue){ $element->setAttribute($attributeName, $attributeValue); } } if(isset($node['childs'])){ foreach($node['childs'] as $childName=>$childValue){ $newElement = $this->_doc->createElement($childName, $childValue); $element->appendChild($newElement); } } // Inserting the node into the DB // case : creation of a new table if($table == null){ $this->_doc->firstChild->appendChild($element); }else{ // case : insertion into the end of table //TODO checking if PK already exists $request = $this->_xpath->query('//table[@name = "'.$table.'"]'); if($request->length != 1){ return false; } $request->item(0)->appendChild($element); } return $this->save(); } /** * * @param $table string * @param $oldAttribute string name of the attribute you want to change * @param $newAttribute array name/value of the attribute you want to add * @param $forceInsert bool * @return bool */ public function updateNodeAttribute($table, $oldAttribute, $newAttribute, $forceInsert = false){ $request = $this->select($table, null, array($oldAttribute[0]=>$oldAttribute[1]), null, 'node'); if($request->length == 1){ if(!$forceInsert){ $request->item(0)->setAttribute($oldAttribute[0],$newAttribute[1]); }else{ $request->item(0)->setAttribute($newAttribute[0],$newAttribute[1]); } return $this->save(); } else return false; } /** * * @param $table string * @param $value string new value of the node * @return bool */ public function updateNodeValue($table, $attribute = null, $child = null, $value){ $request = $this->select($table, null, array($attribute[0]=>$attribute[1]), null, 'node'); //$request = $this->_xpath->query('//'.$node.'[@' . $attribute[0] . ' = "' . $attribute[1] . '"]'); if($request->length == 1){ $request = $request->item(0); $newText = new DOMText($value); $request->removeChild($request->firstChild); $request->appendChild($newText); return $this->save(); } else return false; } public function deleteNode($table, $id = null, $attributes = null){ if($id != null && $attributes != null) return false; if($id != null) $request = $this->select($table, $id, null, null, 'node')->item(0); if($attributes != null) $request = $this->select($table, null, array($attribute[0]=>$attribute[1]), null, 'node')->item(0); $request->parentNode->removeChild($request); return $this->save(); } public function moveNode($node, $from, $to){ } }