• Main Page
  • Related Pages
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

assessment/classes/class.XMLNestedSet.php

Go to the documentation of this file.
00001 <?php
00002  /*
00003    +----------------------------------------------------------------------------+
00004    | ILIAS open source                                                          |
00005    +----------------------------------------------------------------------------+
00006    | Copyright (c) 1998-2001 ILIAS open source, University of Cologne           |
00007    |                                                                            |
00008    | This program is free software; you can redistribute it and/or              |
00009    | modify it under the terms of the GNU General Public License                |
00010    | as published by the Free Software Foundation; either version 2             |
00011    | of the License, or (at your option) any later version.                     |
00012    |                                                                            |
00013    | This program is distributed in the hope that it will be useful,            |
00014    | but WITHOUT ANY WARRANTY; without even the implied warranty of             |
00015    | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the              |
00016    | GNU General Public License for more details.                               |
00017    |                                                                            |
00018    | You should have received a copy of the GNU General Public License          |
00019    | along with this program; if not, write to the Free Software                |
00020    | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | 
00021    +----------------------------------------------------------------------------+
00022 */
00023 
00024 require_once "./assessment/classes/class.XML2SQL.php";
00025 require_once "./assessment/classes/class.SQL2XML.php";
00026 
00039 class XMLNestedSet
00040 {
00047         var $doc;
00048 
00055         var $nestedset;
00056 
00064         var $error;
00065 
00073         function XMLNestedSet ()
00074         {
00075                 $num = func_num_args();
00076                 $args = func_get_args();
00077                 
00078                 if (($num == 1) && is_object($args[0]))
00079                 {
00080                         $this->doc = $args[0];
00081                 }
00082                 $this->nestedset = array();
00083                 register_shutdown_function(array(&$this, '_XMLNestedSet'));
00084         }
00085         
00086         function _XMLNestedSet() {
00087                 if ($this->doc) {
00088                         $this->doc->free();
00089                 }
00090         }
00091         
00092 
00103         function loadDocument ($a_filename, $a_validate = false)
00104         {
00105                 if ($a_validate) {
00106                         $mode = DOMXML_LOAD_VALIDATING;
00107                 } else {
00108                         $mode = DOMXML_LOAD_PARSING;
00109                 } 
00110 
00111                 if (!file_exists($a_filename)) {
00112                         array_push($this->error, array(
00113                                 "line" => "",
00114                                 "errormessage" => "The file $a_filename does not exist!"
00115                         ));
00116                         return;
00117                 }
00118                 
00119                 $this->doc = domxml_open_file($a_filename, $mode, $this->error);
00120 
00121                 // stop parsing if an error occured
00122                 if ($this->error) {
00123                         $error_msg = "Error(s) while parsing the document!<br><br>";
00124                         
00125                         foreach ($this->error as $error) {
00126                                 $error_msg .= $error["errormessage"]." in line: ".$error["line"]."<br>";
00127                         }
00128                         print $error_msg;
00129                         exit();
00130                 }
00131                 
00132                 // set encoding to UTF-8 if empty
00133                 $this->setEncoding("iso-8859-1", true);
00134                 // set charset to UTF-8
00135                 $this->setCharset("iso-8859-1");
00136 
00137                 return $this->doc; 
00138         }
00139 
00151         function setEncoding ($a_encode, $a_overwrite = false)
00152         {
00153                 if (empty($this->doc->encoding) or ($a_overwrite)) {
00154                         $this->doc->encoding = $a_encode;
00155                         return true;
00156                 }
00157                 return false;
00158         }
00159 
00168         function getEncoding ()
00169         {
00170                 return $this->doc->encoding;
00171         }
00172 
00184         function setCharset ($a_charset, $a_overwrite = false)
00185         {
00186                 if (is_integer($this->doc->charset) or ($a_overwrite)) {
00187                         $this->doc->charset = $a_charset;
00188                         return true;
00189                 }
00190                 
00191                 return false;
00192         }
00193 
00202         function getCharset ()
00203         {
00204                 return $this->doc->charset;
00205         }
00206         
00233         function transform ($node, $left2 = -1, $lvl = 0)
00234         { 
00235                 // Static varialbe for the nested set counter
00236                 static $left;
00237                 
00238                 // set depth
00239                 $lvl++;
00240 
00241                 // start value given from outside?
00242                 if ($left2 > 0) {
00243                         $left = $left2;
00244                 }
00245                 
00246                 // set default value 1 if no value given
00247                 if (!$left) {
00248                         $left = 1;
00249                 } 
00250 
00251                 // convert DomNode object to an array
00252                 $node2 = (array)$node;
00253                 
00254                 // init structure data
00255                 // provides additional information about document structure
00256                 // bitwise:
00257                 // 1: has attributes
00258                 // 2: has text element 
00259                 $this->nestedset[$node2[0]]["struct"] = 0;
00260 
00261                 if ($parent = $node->parent_node()) 
00262                 {
00263                         $parent = (array)$parent;
00264                 } 
00265 
00266                 if ($first = $node->first_child())
00267                 {
00268                         $first = (array)$first;
00269                 } 
00270 
00271                 if ($prev = $node->previous_sibling()) 
00272                 {
00273                         $prev = (array)$prev;
00274                 } 
00275 
00276                 if ($next = $node->next_sibling()) {
00277                         $next = (array)$next;
00278                 } 
00279                 
00280                 $this->nestedset[$node2[0]]["content"] = trim($node->node_value());
00281                 $this->nestedset[$node2[0]]["name"] = $node->node_name();
00282                 $this->nestedset[$node2[0]]["type"] = $node->type;
00283                 $this->nestedset[$node2[0]]["depth"] = $lvl;
00284                 $this->nestedset[$node2[0]]["parent"] = $parent[0];
00285                 $this->nestedset[$node2[0]]["first"] = $first[0];
00286                 $this->nestedset[$node2[0]]["prev"] = $prev[0];
00287                 $this->nestedset[$node2[0]]["next"] = $next[0];
00288                 $this->nestedset[$node2[0]]["left"] = $left;
00289 
00290                 // increase nested set counter for the next node
00291                 $left++;
00292                 
00293                 // write attributes to sub-array
00294                 if ($node->has_attributes())
00295                 {
00296                         $data = "";
00297                         
00298                         foreach ($node->attributes() as $attribute)
00299                         {
00300                                 $data[$attribute->name] = $attribute->value;
00301                         }
00302 
00303                         $this->nestedset[$node2[0]]["attr_list"] = $data;
00304                         $this->nestedset[$node2[0]]["struct"] += 1;
00305                 }
00306 
00307                 // check if one child is a text_node
00308                 foreach ($node->child_nodes() as $child)
00309                 {
00310                         if ($child->node_type() == XML_TEXT_NODE)
00311                         {
00312                                 $this->nestedset[$node2[0]]["struct"] += 2;
00313                                 break;
00314                         }
00315                 }
00316                 
00317                 // recursive call
00318                 foreach ($node->child_nodes() as $child)
00319                 {
00320                         $this->transform($child, $left, $lvl);
00321                 }
00322                 
00323                 $this->nestedset[$node2[0]]["right"] = $left;
00324                 $left++;
00325         }
00326 
00337         function &buildTree ($a_node = "")
00338         {
00339                 $this->nestedset = array();
00340                 if (empty($a_node)) {
00341                         $a_node = $this->doc;
00342                 }
00343                 
00344                 $this->transform($a_node, 1);
00345                 
00346                 return $this->nestedset;
00347         }
00348 
00349 
00357         function trim ($a_node)
00358         {
00359                 if ($a_node->has_child_nodes()) {
00360                         $childs = $a_node->child_nodes();
00361 
00362                         foreach ($childs as $child) {
00363                                 $content = trim($child->get_content());
00364 
00365                                 if (empty($content) and ($child->type == XML_TEXT_NODE)) {
00366                                         $child->unlink_node();
00367                                 } else {
00368                                         $this->trim($child);
00369                                 } 
00370                         } 
00371                 } 
00372         }
00373 
00382         function trimDocument ($a_node = '')
00383         {
00384                 if (empty($a_node))     {
00385                         $a_node = $this->doc;
00386                 }
00387         
00388                 $this->trim($a_node);
00389                 return $a_node;
00390         }
00391 
00404         function dumpDocument ($a_stdout = -1, $a_compress = false, $a_format = false)
00405         {
00406                 if ($a_stdout != -1) {
00407                         $this->doc->dump_file($a_stdout,$a_compress,$a_format);
00408                 }
00409                 
00410                 return $this->doc->dump_mem();
00411         }
00412 
00425         function getTextFromElement ($a_element)
00426         {
00427                 if ($a_element->node_type() == XML_ELEMENT_NODE) {
00428                         $value = "";
00429                 
00430                         foreach ($a_element->child_nodes() as $child) {
00431                                 if ($child->node_type() == XML_TEXT_NODE) {
00432                                         $value .= $child->content;
00433                                 }
00434                         }
00435                 
00436                         return trim($value);
00437                 }
00438                 
00439                 die("<b>".$a_element."</b> is not a valid element node!");
00440         }
00441 
00452         function isLeafElement ($a_node, $a_elementname, $a_num = 0)
00453         {
00454                 $var = true;
00455                 
00456                 if ($childs = $a_node->child_nodes()) {
00457                         foreach ($childs as $child) {
00458                                 $var = $this->isLeafElement($child, $a_elementname);
00459 
00460                                 if (!$var) {
00461                                         return false;
00462                                 }
00463                         }
00464                 }
00465                 
00466                 if (($a_node->node_type() == XML_ELEMENT_NODE) && ($a_node->tagname == $a_elementname) && ($a_num != 1)) {
00467                         return false;
00468                 }
00469                 
00470                 return $var;
00471         }
00472 
00484         function getElementsByTagname ($a_elementname, $a_node = "")
00485         {
00486                 if (empty($a_node)) {
00487                         $a_node = $this->doc;
00488                 }
00489                 
00490                 if (count($node = $a_node->get_elements_by_tagname($a_elementname)) > 0) {
00491                         return $node;
00492                 }
00493                 
00494                 return false;
00495         }
00496 
00504         function getRoot ()
00505         {
00506                 return $this->doc->document_element();
00507         }
00508 
00516         function getElementId($a_node)
00517         {
00518                 $node = (array) $a_node;
00519                 return $node[0];
00520         }
00521 
00529         function getElementName($a_node)
00530         {
00531                 return $a_node->node_name();
00532         }
00533         
00534         function save_to_db($db) {
00535                 if (empty($this->doc)) 
00536                 {
00537                         return;
00538                 }
00539                 if (empty($this->nestedset))
00540                 {
00541                         $this->buildTree();
00542                 }
00543                 $xml2sql = new XML2SQL($db, $this->nestedset, "1.0", $this->getEncoding(), $this->getCharset());
00544                 $xml2sql->insertDocument();
00545                 unset($xml2sql);
00546         }
00547         
00548         function loadFromDb($db, $xml_object_id) {
00549                 $sql2xml = new SQL2XML($db, $xml_object_id);
00550                 if ($this->doc) {
00551                         $this->doc->free();
00552                 }
00553                 $this->doc =& $sql2xml->doc;
00554                 unset($sql2xml);
00555         }
00556         
00557         function delete_from_db($db, $xml_object_id) {
00558                 $tables = array(
00559                         "xml_element_namespace",
00560                         "xml_pi_target",
00561                         "xml_pi_data",
00562                         "xml_cdata",
00563                         "xml_entity_reference",
00564                         "xml_attribute_namespace",
00565                         "xml_text",
00566                         "xml_comment",
00567                         "xml_attribute_idx",
00568                         "xml_element_idx"
00569                 );
00570                 foreach ($tables as $table)
00571                 {
00572                         $q = sprintf ("SELECT $table.* FROM $table, xml_tree WHERE $table.node_id = xml_tree.node_id AND xml_tree.xml_id = %s",
00573                                 $db->quote("$xml_object_id")
00574                         );
00575                         $result = $db->query($q);
00576                         if ($result->numRows()) {
00577                                 while ($row = $result->fetchRow(DB_FETCHMODE_OBJECT))
00578                                 {
00579                                         $q_delete = sprintf ("DELETE FROM $table WHERE node_id = %s",
00580                                                 $db->quote($row->node_id)
00581                                         );
00582                                         $result_delete = $db->query($q_delete);
00583                                         if (strcmp($table, "xml_attribute_idx") == 0)
00584                                         {
00585                                                 $q_delete = sprintf ("DELETE FROM xml_attribute_value WHERE value_id = %s",
00586                                                         $db->quote($row->value_id)
00587                                                 );
00588                                                 $result_delete = $db->query($q_delete);
00589                                                 $q_delete = sprintf ("DELETE FROM xml_attribute_name WHERE attribute_id = %s",
00590                                                         $db->quote($row->attribute_id)
00591                                                 );
00592                                                 $result_delete = $db->query($q_delete);
00593                                         }
00594                                         if (strcmp($table, "xml_element_idx") == 0)
00595                                         {
00596                                                 $q_delete = sprintf ("DELETE FROM xml_element_name WHERE element_id = %s",
00597                                                         $db->quote($row->element_id)
00598                                                 );
00599                                                 $result_delete = $db->query($q_delete);
00600                                         }
00601                                 }
00602                         }
00603                 }
00604                 $q = sprintf("DELETE FROM xml_object WHERE ID=%s",
00605                         $db->quote($xml_object_id)
00606                 );
00607                 $result = $db->query($q);
00608                 $q = sprintf("DELETE FROM xml_tree WHERE xml_id = %s",
00609                         $db->quote($xml_object_id)
00610                 );
00611                 $result = $db->query($q);
00612         }
00613 } // END class.XMLNestedSet
00614 
00615 ?>

Generated on Fri Dec 13 2013 09:06:33 for ILIAS Release_3_4_x_branch .rev 46804 by  doxygen 1.7.1