Apache Zeta Components Manual :: File Source for xml.php

Source for file xml.php

Documentation is available at xml.php

  1. <?php
  2. /**
  3.  * File containing the ezcTreeXml class.
  4.  *
  5.  * Licensed to the Apache Software Foundation (ASF) under one
  6.  * or more contributor license agreements.  See the NOTICE file
  7.  * distributed with this work for additional information
  8.  * regarding copyright ownership.  The ASF licenses this file
  9.  * to you under the Apache License, Version 2.0 (the
  10.  * "License"); you may not use this file except in compliance
  11.  * with the License.  You may obtain a copy of the License at
  12.  * 
  13.  *   http://www.apache.org/licenses/LICENSE-2.0
  14.  * 
  15.  * Unless required by applicable law or agreed to in writing,
  16.  * software distributed under the License is distributed on an
  17.  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  18.  * KIND, either express or implied.  See the License for the
  19.  * specific language governing permissions and limitations
  20.  * under the License.
  21.  *
  22.  * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License, Version 2.0
  23.  * @version //autogentag//
  24.  * @filesource
  25.  * @package Tree
  26.  */
  27.  
  28. /**
  29.  * ezcTreeXml is an implementation of a tree backend that operates on
  30.  * an XML file.
  31.  *
  32.  * Example:
  33.  * <code>
  34.  * <?php
  35.  *     // Create a new tree in a new XML file
  36.  *     $tree = ezcTreeXml::create(
  37.  *         'new-tree.xml',
  38.  *         new ezcTreeXmlInternalDataStore()
  39.  *     );
  40.  * 
  41.  *     // Open an existing XML file containing a tree structure
  42.  *     $tree = new ezcTreeXml(
  43.  *         'existing-tree.xml',
  44.  *         new ezcTreeXmlInternalDataStore()
  45.  *     );
  46.  * ?>
  47.  * </code>
  48.  *
  49.  * See {@link ezcTree} for examples on how to operate on the tree.
  50.  *
  51.  * @property-read ezcTreeXmlDataStore $store 
  52.  *                 The data store that is used for retrieving/storing data.
  53.  * @property-read string              $prefix 
  54.  *                 The prefix that is used to prefix node IDs with in the tree.
  55.  * @property      string              $nodeClassName 
  56.  *                 Which class is used as tree node - this class *must* inherit
  57.  *                 the ezcTreeNode class.
  58.  *
  59.  * @package Tree
  60.  * @version //autogentag//
  61.  * @mainclass
  62.  */
  63. class ezcTreeXml extends ezcTree
  64. {
  65.     /**
  66.      * Contains the relax-NG schema to validate the tree XML.
  67.      */
  68.     const relaxNG = '<?xml version="1.0" encoding="UTF-8"?>
  69. <grammar xmlns:etd="http://components.ez.no/Tree/data" ns="http://components.ez.no/Tree" xmlns="http://relaxng.org/ns/structure/1.0" datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes">
  70.   <start>
  71.     <element name="tree">
  72.       <optional>
  73.         <attribute name="prefix">
  74.           <data type="ID"/>
  75.         </attribute>
  76.       </optional>
  77.       <optional>
  78.         <attribute name="lastNodeId">
  79.           <data type="string"/>
  80.         </attribute>
  81.       </optional>
  82.       <optional>
  83.         <ref name="node"/>
  84.       </optional>
  85.     </element>
  86.   </start>
  87.   <define name="node">
  88.     <element name="node">
  89.       <attribute name="id">
  90.         <data type="ID"/>
  91.       </attribute>
  92.       <optional>
  93.         <element name="etd:data">
  94.           <text/>
  95.         </element>
  96.       </optional>
  97.       <zeroOrMore>
  98.         <ref name="node"/>
  99.       </zeroOrMore>
  100.     </element>
  101.   </define>
  102. </grammar>';
  103.  
  104.     /**
  105.      * Contains the DOM Tree that all operations will be done on.
  106.      *
  107.      * When the tree object is constructed the XML is parsed with DOM and
  108.      * stored into this member variable. When the tree is modified the changes
  109.      * are then flushed to disk with the saveFile() method.
  110.      *
  111.      * @var DOMDocument $dom 
  112.      */
  113.     private $dom;
  114.  
  115.     /**
  116.      * The file name that contains the tree as XML string.
  117.      *
  118.      * @var string $xmlFile 
  119.      */
  120.     private $xmlFile;
  121.  
  122.     /**
  123.      * Stores the last auto generated ID that was used.
  124.      *
  125.      * @var integer $autoNodeId 
  126.      */
  127.     private $autoNodeId 0;
  128.  
  129.     /**
  130.      * Constructs a new ezcTreeXml object from the XML data in $xmlFile and using
  131.      * the $store to retrieve data from.
  132.      *
  133.      * @param string $xmlFile 
  134.      * @param ezcTreeXmlDataStore $store 
  135.      */
  136.     public function __construct$xmlFileezcTreeXmlDataStore $store )
  137.     {
  138.         if !file_exists$xmlFile ) )
  139.         {
  140.             throw new ezcBaseFileNotFoundException$xmlFile"XML" );
  141.         }
  142.  
  143.         $previous libxml_use_internal_errorstrue );
  144.  
  145.         $dom new DomDocument();
  146.         $dom->load$xmlFile );
  147.         $dom->formatOutput true;
  148.  
  149.         $errors libxml_get_errors();
  150.         libxml_clear_errors();
  151.         if count$errors ) )
  152.         {
  153.             throw new ezcTreeInvalidXmlException$xmlFile$errors );
  154.         }
  155.  
  156.         $valid $dom->relaxNGValidateSourceself::relaxNG );
  157.         if !$valid )
  158.         {
  159.             $errors libxml_get_errors();
  160.             libxml_clear_errors();
  161.             throw new ezcTreeInvalidXmlFormatException$xmlFile$errors );
  162.         }
  163.  
  164.         libxml_use_internal_errors$previous );
  165.  
  166.         // Associate the DOM tree with the data store
  167.         $store->setDomTree$dom );
  168.  
  169.         // Figure out the prefix - which is the "prefix" attribute on the root node.
  170.         $document $dom->documentElement;
  171.         $prefix $document->getAttribute'prefix' );
  172.  
  173.         // Figure out the last auto generated ID
  174.         $autoId false;
  175.         $this->autoNodeId $document->getAttribute'lastNodeId' );
  176.         if $this->autoNodeId !== "" )
  177.         {
  178.             $autoId true;
  179.         }
  180.  
  181.         // Set member variables
  182.         $this->dom $dom;
  183.         $this->xmlFile $xmlFile;
  184.         $this->properties['store'$store;
  185.         $this->properties['prefix'$prefix;
  186.         $this->properties['autoId'$autoId;
  187.     }
  188.  
  189.     /**
  190.      * Returns the value of the property $name.
  191.      *
  192.      * @throws ezcBasePropertyNotFoundException if the property does not exist.
  193.      * @param string $name 
  194.      * @ignore
  195.      */
  196.     public function __get$name )
  197.     {
  198.         switch $name )
  199.         {
  200.             case 'prefix':
  201.                 return $this->properties[$name];
  202.         }
  203.         return parent::__get$name );
  204.     }
  205.  
  206.     /**
  207.      * Sets the property $name to $value.
  208.      *
  209.      * @throws ezcBasePropertyNotFoundException if the property does not exist.
  210.      * @throws ezcBasePropertyPermissionException if a read-only property is
  211.      *          tried to be modified.
  212.      * @param string $name 
  213.      * @param mixed $value 
  214.      * @ignore
  215.      */
  216.     public function __set$name$value )
  217.     {
  218.         switch $name )
  219.         {
  220.             case 'prefix':
  221.                 throw new ezcBasePropertyPermissionException$nameezcBasePropertyPermissionException::READ );
  222.  
  223.             default:
  224.                 return parent::__set$name$value );
  225.         }
  226.     }
  227.  
  228.     /**
  229.      * Returns true if the property $name is set, otherwise false.
  230.      *
  231.      * @param string $name 
  232.      * @return bool 
  233.      * @ignore
  234.      */
  235.     public function __isset$name )
  236.     {
  237.         switch $name )
  238.         {
  239.             case 'prefix':
  240.                 return isset$this->properties[$name);
  241.  
  242.             default:
  243.                 return parent::__isset$name );
  244.         }
  245.     }
  246.  
  247.     /**
  248.      * Creates a new XML tree in the file $xmlFile using $store as data store.
  249.      *
  250.      * The $prefix option can be used to change the prefix that is used for IDs
  251.      * in the created tree. By default this is set to "id" so that numerical
  252.      * node IDs are not a problem.
  253.      *
  254.      * @param string $xmlFile 
  255.      * @param ezcTreeXmlDataStore $store 
  256.      * @param string $prefix 
  257.      * @return ezcTreeXml 
  258.      */
  259.     public static function create$xmlFileezcTreeXmlDataStore $store$prefix 'id' )
  260.     {
  261.         $dom new DomDocument'1.0''utf-8' );
  262.         $dom->formatOutput true;
  263.  
  264.         $element $dom->createElement'tree' );
  265.         $element->setAttributeNodenew DOMAttr'xmlns''http://components.ez.no/Tree' ) );
  266.         $element->setAttributeNodenew DOMAttr'xmlns:etd''http://components.ez.no/Tree/data' ) );
  267.         if $prefix !== null )
  268.         {
  269.             $element->setAttributeNodenew DOMAttr'prefix'$prefix ) );
  270.         }
  271.  
  272.         $dom->appendChild$element );
  273.  
  274.         $dom->save$xmlFile );
  275.         return new ezcTreeXml$xmlFile$store$prefix );
  276.     }
  277.  
  278.     /**
  279.      * Saves the internal DOM representation of the tree back to disk.
  280.      */
  281.     public function saveFile()
  282.     {
  283.         $this->dom->save$this->xmlFile );
  284.     }
  285.  
  286.     /**
  287.      * This method generates the next node ID.
  288.      *
  289.      * It uses the stored last generated ID, and also stores this in an
  290.      * attribute on the root node so that it can be correctly incremented
  291.      * without having to search for the last generated ID in the whole tree.
  292.      *
  293.      * @return integer 
  294.      */
  295.     protected function generateNodeID()
  296.     {
  297.         $this->autoNodeId++;
  298.  
  299.         $document $this->dom->documentElement;
  300.         $document->setAttributeNodenew DOMAttr'lastNodeId'$this->autoNodeId ) );
  301.  
  302.         return $this->autoNodeId;
  303.     }
  304.  
  305.     /**
  306.      * Returns whether the node with ID $nodeId exists.
  307.      *
  308.      * @param string $nodeId 
  309.      * @return bool 
  310.      */
  311.     public function nodeExists$nodeId )
  312.     {
  313.         $elem $this->dom->getElementById"{$this->properties['prefix']}$nodeId);
  314.         return $elem !== null true false;
  315.     }
  316.  
  317.     /**
  318.      * Retrieves a DOMElement containing the node with node ID $nodeId.
  319.      *
  320.      * @param string $nodeId 
  321.      * @return DOMElement 
  322.      */
  323.     private function getNodeById$nodeId )
  324.     {
  325.         $node $this->dom->getElementById"{$this->properties['prefix']}$nodeId);
  326.         if !$node )
  327.         {
  328.             throw new ezcTreeUnknownIdException$nodeId );
  329.         }
  330.         return $node;
  331.     }
  332.  
  333.     /**
  334.      * Fetches all the child "node" DOM elements of the node with ID $nodeId.
  335.      *
  336.      * @param string $nodeId 
  337.      * @return array(string) 
  338.      */
  339.     private function fetchChildIds$nodeId )
  340.     {
  341.         $childNodes array();
  342.         $elem $this->getNodeById$nodeId );
  343.         $children $elem->childNodes;
  344.         foreach $children as $child )
  345.         {
  346.             if $child->nodeType === XML_ELEMENT_NODE && $child->tagName == "node" )
  347.             {
  348.                 $nodeId substr$child->getAttribute'id' )strlen$this->properties['prefix') );
  349.                 $childNodes[$nodeId;
  350.             }
  351.         }
  352.         return $childNodes;
  353.     }
  354.  
  355.     /**
  356.      * Returns all the children of the node with ID $nodeId.
  357.      *
  358.      * @param string $nodeId 
  359.      * @return ezcTreeNodeList 
  360.      */
  361.     public function fetchChildren$nodeId )
  362.     {
  363.         $className $this->properties['nodeClassName'];
  364.         $list new ezcTreeNodeList;
  365.         foreach $this->fetchChildIds$nodeId as $childId )
  366.         {
  367.             $list->addNodenew $className$this$childId ) );
  368.         }
  369.         return $list;
  370.     }
  371.  
  372.     /**
  373.      * Returns the parent node of the node with ID $nodeId.
  374.      *
  375.      * This method returns null if there is no parent node.
  376.      *
  377.      * @param string $nodeId 
  378.      * @return ezcTreeNode 
  379.      */
  380.     public function fetchParent$nodeId )
  381.     {
  382.         $className $this->properties['nodeClassName'];
  383.         $elem $this->getNodeById$nodeId );
  384.         $elem $elem->parentNode;
  385.         $parentId $elem !== null substr$elem->getAttribute'id' )strlen$this->properties['prefix') ) null;
  386.         if $parentId === false )
  387.         {
  388.             return null;
  389.         }
  390.         return new $className$this$parentId );
  391.     }
  392.  
  393.     /**
  394.      * Returns all the nodes in the path from the root node to the node with ID
  395.      * $nodeId, including those two nodes.
  396.      *
  397.      * @param string $nodeId 
  398.      * @return ezcTreeNodeList 
  399.      */
  400.     public function fetchPath$nodeId )
  401.     {
  402.         $className $this->properties['nodeClassName'];
  403.  
  404.         $nodes array();
  405.         $nodes[new $className$this$nodeId );
  406.  
  407.         $elem $this->getNodeById$nodeId );
  408.         $elem $elem->parentNode;
  409.  
  410.         while $elem !== null && $elem->nodeType == XML_ELEMENT_NODE && $elem->tagName == 'node' )
  411.         {
  412.             $id substr$elem->getAttribute'id' )strlen$this->properties['prefix') );
  413.             $nodes[new $className$this$id );
  414.             $elem $elem->parentNode;
  415.         }
  416.  
  417.         $list new ezcTreeNodeList;
  418.         foreach array_reverse$nodes as $node )
  419.         {
  420.             $list->addNode$node );
  421.         }
  422.         return $list;
  423.     }
  424.  
  425.     /**
  426.      * Adds the children nodes of the node with ID $nodeId to the
  427.      * ezcTreeNodeList $list.
  428.      *
  429.      * @param ezcTreeNodeList $list 
  430.      * @param string          $nodeId 
  431.      */
  432.     private function addChildNodesDepthFirstezcTreeNodeList $list$nodeId )
  433.     {
  434.         $className $this->properties['nodeClassName'];
  435.         foreach $this->fetchChildIds$nodeId as $childId )
  436.         {
  437.             $list->addNodenew $className$this$childId ) );
  438.             $this->addChildNodesDepthFirst$list$childId );
  439.         }
  440.     }
  441.  
  442.     /**
  443.      * Returns the node with ID $nodeId and all its children, sorted according to
  444.      * the {@link http://en.wikipedia.org/wiki/Depth-first_search Depth-first sorting}
  445.      * algorithm.
  446.      *
  447.      * @param string $nodeId 
  448.      * @return ezcTreeNodeList 
  449.      */
  450.     public function fetchSubtreeDepthFirst$nodeId )
  451.     {
  452.         $className $this->properties['nodeClassName'];
  453.         $list new ezcTreeNodeList;
  454.         $list->addNodenew $className$this$nodeId ) );
  455.         $this->addChildNodesDepthFirst$list$nodeId );
  456.         return $list;
  457.     }
  458.  
  459.     /**
  460.      * Alias for fetchSubtreeDepthFirst().
  461.      *
  462.      * @param string $nodeId 
  463.      * @return ezcTreeNodeList 
  464.      */
  465.     public function fetchSubtree$nodeId )
  466.     {
  467.         return $this->fetchSubtreeDepthFirst$nodeId );
  468.     }
  469.  
  470.     /**
  471.      * Adds the children nodes of the node with ID $nodeId to the
  472.      * ezcTreeNodeList $list.
  473.      *
  474.      * @param ezcTreeNodeList $list 
  475.      * @param string          $nodeId 
  476.      */
  477.     private function addChildNodesBreadthFirstezcTreeNodeList $list$nodeId )
  478.     {
  479.         $className $this->properties['nodeClassName'];
  480.         $childIds $this->fetchChildIds$nodeId );
  481.         foreach $childIds as $childId )
  482.         {
  483.             $list->addNodenew $className$this$childId ) );
  484.         }
  485.         foreach $childIds as $childId )
  486.         {
  487.             $this->addChildNodesDepthFirst$list$childId );
  488.         }
  489.     }
  490.  
  491.     /**
  492.      * Returns the node with ID $nodeId and all its children, sorted according to
  493.      * the {@link http://en.wikipedia.org/wiki/Breadth-first_search Breadth-first sorting}
  494.      * algorithm.
  495.      *
  496.      * @param string $nodeId 
  497.      * @return ezcTreeNodeList 
  498.      */
  499.     public function fetchSubtreeBreadthFirst$nodeId )
  500.     {
  501.         $className $this->properties['nodeClassName'];
  502.         $list new ezcTreeNodeList;
  503.         $list->addNodenew $className$this$nodeId ) );
  504.         $this->addChildNodesBreadthFirst$list$nodeId );
  505.         return $list;
  506.     }
  507.  
  508.     /**
  509.      * Returns the number of direct children of the node with ID $nodeId.
  510.      *
  511.      * @param string $nodeId 
  512.      * @return int 
  513.      */
  514.     public function getChildCount$nodeId )
  515.     {
  516.         $count 0;
  517.         $elem $this->getNodeById$nodeId );
  518.         $children $elem->childNodes;
  519.         foreach $children as $child )
  520.         {
  521.             if $child->nodeType === XML_ELEMENT_NODE && $child->tagName == "node" )
  522.             {
  523.                 $count++;
  524.             }
  525.         }
  526.         return $count;
  527.     }
  528.  
  529.     /**
  530.      * Adds the number of children with for the node with ID $nodeId nodes to
  531.      * $count, recursively.
  532.      *
  533.      * @param int $count 
  534.      * @param string $nodeId 
  535.      */
  536.     private function countChildNodes&$count$nodeId )
  537.     {
  538.         foreach $this->fetchChildIds$nodeId as $childId )
  539.         {
  540.             $count++;
  541.             $this->countChildNodes$count$childId );
  542.         }
  543.     }
  544.  
  545.     /**
  546.      * Returns the number of children of the node with ID $nodeId, recursively.
  547.      *
  548.      * @param string $nodeId 
  549.      * @return int 
  550.      */
  551.     public function getChildCountRecursive$nodeId )
  552.     {
  553.         $count 0;
  554.         $this->countChildNodes$count$nodeId );
  555.         return $count;
  556.     }
  557.  
  558.     /**
  559.      * Returns the distance from the root node to the node with ID $nodeId.
  560.      *
  561.      * @param string $nodeId 
  562.      * @return int 
  563.      */
  564.     public function getPathLength$nodeId )
  565.     {
  566.         $elem $this->getNodeById$nodeId );
  567.         $elem $elem->parentNode;
  568.         $length = -1;
  569.  
  570.         while $elem !== null && $elem->nodeType == XML_ELEMENT_NODE )
  571.         {
  572.             $elem $elem->parentNode;
  573.             $length++;
  574.         }
  575.         return $length;
  576.     }
  577.  
  578.     /**
  579.      * Returns whether the node with ID $nodeId has children.
  580.      *
  581.      * @param string $nodeId 
  582.      * @return bool 
  583.      */
  584.     public function hasChildNodes$nodeId )
  585.     {
  586.         $elem $this->getNodeById$nodeId );
  587.         $children $elem->childNodes;
  588.         foreach $children as $child )
  589.         {
  590.             if $child->nodeType === XML_ELEMENT_NODE && $child->tagName == "node" )
  591.             {
  592.                 return true;
  593.             }
  594.         }
  595.         return false;
  596.     }
  597.  
  598.     /**
  599.      * Returns whether the node with ID $childId is a direct child of the node
  600.      * with ID $parentId.
  601.      *
  602.      * @param string $childId 
  603.      * @param string $parentId 
  604.      * @return bool 
  605.      */
  606.     public function isChildOf$childId$parentId )
  607.     {
  608.         $elem $this->getNodeById$childId );
  609.         $parentElem $elem->parentNode;
  610.         $nodeId $parentElem->getAttribute'id' );
  611.         if $nodeId === "{$this->properties['prefix']}$parentId)
  612.         {
  613.             return true;
  614.         }
  615.         return false;
  616.     }
  617.  
  618.     /**
  619.      * Returns whether the node with ID $childId is a direct or indirect child
  620.      * of the node with ID $parentId.
  621.      *
  622.      * @param string $childId 
  623.      * @param string $parentId 
  624.      * @return bool 
  625.      */
  626.     public function isDescendantOf$childId$parentId )
  627.     {
  628.         $elem $this->getNodeById$childId );
  629.         $elem $elem->parentNode;
  630.  
  631.         while $elem !== null && $elem->nodeType == XML_ELEMENT_NODE )
  632.         {
  633.             $nodeId $elem->getAttribute'id' );
  634.             if $nodeId === "{$this->properties['prefix']}$parentId)
  635.             {
  636.                     return true;
  637.             }
  638.             $elem $elem->parentNode;
  639.         }
  640.         return false;
  641.     }
  642.  
  643.     /**
  644.      * Returns whether the nodes with IDs $child1Id and $child2Id are siblings
  645.      * (ie, they share the same parent).
  646.      *
  647.      * @param string $child1Id 
  648.      * @param string $child2Id 
  649.      * @return bool 
  650.      */
  651.     public function isSiblingOf$child1Id$child2Id )
  652.     {
  653.         $elem1 $this->getNodeById$child1Id );
  654.         $elem2 $this->getNodeById$child2Id );
  655.         return (
  656.             $child1Id !== $child2Id && 
  657.             $elem1->parentNode->getAttribute'id' === $elem2->parentNode->getAttribute'id' ) )
  658.         );
  659.     }
  660.  
  661.     /**
  662.      * Sets a new node as root node, this also wipes out the whole tree.
  663.      *
  664.      * @param ezcTreeNode $node 
  665.      */
  666.     public function setRootNodeezcTreeNode $node )
  667.     {
  668.         $document $this->dom->documentElement;
  669.  
  670.         // remove old root node(s)
  671.         foreach $document->childNodes as $childNode )
  672.         {
  673.             if $childNode->nodeType == XML_ELEMENT_NODE && $childNode->tagName === 'node' )
  674.             {
  675.                 $nodeId substr$childNode->getAttribute'id' )strlen$this->properties['prefix') );
  676.                 $this->delete$nodeId );
  677.             }
  678.         }
  679.         $this->store->deleteDataForAllNodes();
  680.  
  681.         // Create new root node
  682.         $root $this->dom->createElement'node' );
  683.         $root->setAttributeNodenew DOMAttr'id'"{$this->properties['prefix']}{$node->id}) );
  684.         $root->setIdAttribute'id'true );
  685.         $document->appendChild$root );
  686.         $this->store->storeDataForNode$node$node->data );
  687.         $this->saveFile();
  688.     }
  689.  
  690.     /**
  691.      * Returns the root node.
  692.      *
  693.      * This methods returns null if there is no root node.
  694.      *
  695.      * @return ezcTreeNode 
  696.      */
  697.     public function getRootNode()
  698.     {
  699.         $className $this->properties['nodeClassName'];
  700.         $document $this->dom->documentElement;
  701.  
  702.         foreach $document->childNodes as $childNode )
  703.         {
  704.             if $childNode->nodeType == XML_ELEMENT_NODE && $childNode->tagName == 'node' )
  705.             {
  706.                 $nodeId substr$childNode->getAttribute'id' )strlen$this->properties['prefix') );
  707.                 return new $className$this$nodeId );
  708.             }
  709.         }
  710.         return null;
  711.     }
  712.  
  713.     /**
  714.      * Adds the node $childNode as child of the node with ID $parentId.
  715.      *
  716.      * @param string $parentId 
  717.      * @param ezcTreeNode $childNode 
  718.      */
  719.     public function addChild$parentIdezcTreeNode $childNode )
  720.     {
  721.         if $this->inTransaction )
  722.         {
  723.             $this->addTransactionItemnew ezcTreeTransactionItemezcTreeTransactionItem::ADD$childNodenull$parentId ) );
  724.             return;
  725.         }
  726.  
  727.         // locate parent node
  728.         $elem $this->getNodeById$parentId );
  729.  
  730.         // Create new DOM node
  731.         $child $this->dom->createElement'node' );
  732.         $child->setAttributeNodenew DOMAttr'id'"{$this->properties['prefix']}{$childNode->id}) );
  733.         $child->setIdAttribute'id'true );
  734.  
  735.         // Append to parent node
  736.         $elem->appendChild$child );
  737.         $this->store->storeDataForNode$childNode$childNode->data );
  738.  
  739.         if !$this->inTransactionCommit )
  740.         {
  741.             $this->saveFile();
  742.         }
  743.     }
  744.  
  745.     /**
  746.      * Deletes the node with ID $nodeId from the tree, including all its children.
  747.      *
  748.      * @param string $nodeId 
  749.      */
  750.     public function delete$nodeId )
  751.     {
  752.         if $this->inTransaction )
  753.         {
  754.             $this->addTransactionItemnew ezcTreeTransactionItemezcTreeTransactionItem::DELETEnull$nodeId ) );
  755.             return;
  756.         }
  757.  
  758.         // Delete all the associated data
  759.         $nodeList $this->fetchSubtree$nodeId );
  760.         $this->store->deleteDataForNodes$nodeList );
  761.  
  762.         // locate node to move
  763.         $nodeToDelete $this->getNodeById$nodeId );
  764.  
  765.         // Remove the ID on all children by hand as this would crash in PHP <= 5.2.3
  766.         $nodeToDelete->removeAttribute"id" );
  767.  
  768.         $children $nodeToDelete->getElementsByTagName'node' );
  769.         foreach $children as $child )
  770.         {
  771.             $child->removeAttribute"id" );
  772.         }
  773.  
  774.         // Use the parent to remove the child
  775.         $nodeToDelete->parentNode->removeChild$nodeToDelete );
  776.  
  777.         if !$this->inTransactionCommit )
  778.         {
  779.             $this->saveFile();
  780.         }
  781.     }
  782.  
  783.     /**
  784.      * Moves the node with ID $nodeId as child to the node with ID $targetParentId.
  785.      *
  786.      * @param string $nodeId 
  787.      * @param string $targetParentId 
  788.      */
  789.     public function move$nodeId$targetParentId )
  790.     {
  791.         if $this->inTransaction )
  792.         {
  793.             $this->addTransactionItemnew ezcTreeTransactionItemezcTreeTransactionItem::MOVEnull$nodeId$targetParentId ) );
  794.             return;
  795.         }
  796.  
  797.         // locate node to move
  798.         $nodeToMove $this->getNodeById$nodeId );
  799.  
  800.         // locate new parent
  801.         $parent $this->getNodeById$targetParentId );
  802.  
  803.         $parent->appendChild$nodeToMove );
  804.  
  805.         if !$this->inTransactionCommit )
  806.         {
  807.             $this->saveFile();
  808.         }
  809.     }
  810.  
  811.     /**
  812.      * Fixates the transaction (saves the XML file).
  813.      */
  814.     public function fixateTransaction()
  815.     {
  816.         $this->saveFile();
  817.     }
  818. }
  819. ?>
Documentation generated by phpDocumentor 1.4.3