Login   Register  
PHP Classes
elePHPant
Icontem

File: Node.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of mathieu lachance  >  Node  >  Node.php  >  Download  
File: Node.php
Role: Class source
Content type: text/plain
Description: The node class file
Class: Node
Build an hierarchic tree of node elements
Author: By
Last change: added new basic method.
revised the addChild method.
revised export and import method.
Date: 7 years ago
Size: 7,081 bytes
 

Contents

Class file image Download
<?php
/**
 * Node class file
 * @author Mathieu Lachance <lachance.mathieu@poincomm.com>
 * @link http://www.mathieulachance.com/
 * @copyright Copyright (c) 2007 Mathieu Lachance
 * @license http://creativecommons.org/licenses/by/2.5/ca/
 * @version 2.0 2007-03-15 15h45
 */

/**
 * Class Node
 * The Node class is used to generate a tree architecture.
 * Each Node contains :
 * - a name, wich is not necessarly unique to the tree, the $name protected property
 * - the reference of his parent, the $parent protected property
 * - an integer indexed array containing all the references of the child nodes, the $child protected property
 * 
 * When adding a new Node with the addChild method, the node class generate a public user defined property called
 * as same as the new Node name.
 * Therefore, this kind of dynamic property can be accessed freely with the powerfull syntax :
 * - $tree->nodeName->... when there is only one node named nodeName
 * - $tree->nodeName[index]->... when there is more than one node named nodeName
 * 
 * Moreover, each node can be exported as xml with the use of the export method.
 * They can be re-imported from xml with the combine use of SimpleXML extension and the import method.
 * - TO DO : find a better way than using SimpleXML extension
 */
class Node
{
  
/**
  * @var string $name the node name
  */
  
protected $name null;
  
/**
  * @var Node $parent a reference to the parent node
  */
  
protected $parent null;
  
/**
  * @var array $children an integer indexed array containing all the references to the child nodes
  */
  
protected $children null;
  
/**
  * @var int $count the number of child nodes
  */
  
protected $count null;
  
  
/**
   * Constructor
   * @param string $name the node name
   */
  
public function __construct($name null){
    
$this->name = (string)$name;            // ensure the $name is a string an assign it to the node name
    
$this->children = array();              // initialise the childs array
    
$this->count 0;                       // initialise the count of the childs array
  
}
  
  
/**
   * Wether :
   * - create a public user defined property called by the node $n name and
   *   assign the node $n to this user defined property
   * - append the node $n to the public user defined property called by the node $n name
   * @param Node $n the node to append
   */
  
public function addChild(Node $n){
    
$n->parent $this;                     // assign the parent node to the node $n
    
$name $n->name;                       // get the node name
    
if (!(isset($this->$name))) {           // check wether the public user defined property $name is already defined
      
$this->$name $n;                    // assign the node $n to the user defined property $name
    
}
    else{
      if (!(
is_array($this->$name))){       // if the public user defined property $name is not an array containing nodes
        
$this->$name = array($this->$name); // convert the user defined property as an array
      
}
      
array_push($this->$name$n);         // append the new node $n to the user defined property
    
}
    
array_push($this->children$n);        // append the new node $n to the childs array
    
$this->count++;                         // increments $this->count the number of child nodes
    
    
return $n;
  }
  
  
/**
   * @return string $name the node name
   */
  
public function getName(){
    return 
$this->name;
  }
  
  
/**
   * @return Node $parent the reference to the parent node
   */
  
public function getParent(){
    return 
$this->parent;
  }
  
  
/**
   * @return array $children the integer indexed array containing all the references to the child nodes
   */
  
public function getChildren(){
    return 
$this->children;
  }
  
  
/**
   * @return int $count the number of child nodes
   */
  
public function getChildrenCount(){
    return 
$this->count;
  }

  
/**
   * @return bool wether : true if there is no child contained in the children array, else false
   */
  
public function isEmpty(){
    return (
$this->count == 0);
  }
  
  
/**
   * export the node and all his childs to an xml format
   * @param $level the node indentation deep
   * @return string $x the xml output of the node
   */
  
public function export($level null){
    
$level = (int)$level;
                                            
// if it's the root level element
    
$ws str_repeat("  "$level);         // calculate the whitespace, TO DO : this one could be a constant
    
if ($this->count == 0){                 // if the current node is empty
      
return "$ws<$this->name/>\n";         // return a closing tag of the current node name as the xml output
    
}
    
$x "$ws<$this->name>\n";              // open an tag of the current node name
    
foreach($this->children as $child){     // for each child of the current node
      
$x .= $child->export($level+1);       // export the child node
    
}
    
$x .= "$ws</$this->name>\n";            // close the opened tag of the current node name
    
return $x;                              // return the xml output of the current node
  
}

  
/**
   * @return the xml output of the node
   */
  
public function __toString(){
    return 
$this->export();
  }
  
  
/**
   * import all xml nodes from a SimpleXMLElement
   * @param SimpleXMLElement $sxe the xml fragment of the last import method iteration
   * @param Node $p the parent node reference of the last import method iteration
   */
  
public function import(SimpleXMLElement $sxeNode $p null){
    
$this->name $sxe->getName();          // reasign the node name with the root element of the SimpleXMLElelment
    
$this->parent $p;                     // assign the parent node    
    
if (count($sxe->children()) > 0){       // if the xml node is not empty
      
foreach($sxe->children() as $child){  // for each children
        
$n = new Node($child->getName());   // create the new node
        
$this->addChild($n);                // append the new node
        
$n->import($child$this);          // now import all nodes from the child element of the SimpleXMLElement
      
}
    }
  }

}


/* start of benchmark */
$start microtime(true);

/* export test */
$n = new Node("html");
$n->addChild(new Node("head"));
$n->head->addChild(new Node("meta"));
$n->head->addChild(new Node("meta"));
$n->addChild(new Node("body"));
$n->body->addChild(new Node("div"));
$n->body->addChild(new Node("div"));
$n->body->div[1]->addChild(new Node("span"));

echo 
$n->export(); // ouput : <html><head><meta /><meta /></head><body><div /><div><span /></div></body></html>

/* import test */
$x = new SimpleXMLElement($n->export());
$n = new Node();
$n->import($x);

echo 
$n->export(); // ouput : <html><head><meta /><meta /></head><body><div /><div><span /></div></body></html>

/* serialization test */
$n serialize($n);
$n unserialize($n);

echo 
$n->export(); // ouput : <html><head><meta /><meta /></head><body><div /><div><span /></div></body></html>

/* end of benchmark */
$end microtime(true);
echo 
$end $start// ouput : 0.00128698348999

?>