【Node.php】
<?php
class Node implements ArrayAccess {
protected $attributes = array();
protected $children = array(); // Accessed by $this[number]
protected $nodeName = 'div';
protected static function attributeNameWarning() {
triger_error('The name of the attribute cannot be an empty string.', E_USER_WARNING);
}
protected static function nodeNameWarning() {
triger_error('The name of the node cannot be an empty string.', E_USER_WARNING);
}
/*static public function render($string) {
}*/
function __construct($nodeName = 'div') {
$this->setNodeName($nodeName);
}
/* ------ Functions for ArrayAccess ------ */
public function offsetExists($offset) {
if (is_numeric($offset)) {
return isset($this->children[$offset]);
} else {
return $this->hasAttribute($offset);
}
}
public function offsetGet($offset) {
if (is_numeric($offset)) {
return $this->children[$offset];
} else {
return $this->getAttribute($offset);
}
}
public function offsetSet($offset, $value) {
if (is_numeric($offset)) {
$this->children[$offset] = $value;
} else {
return $this->setAttribute($offset, $value);
}
}
public function offsetUnset($offset) {
if (is_numeric($offset)) {
unset($this->children[$offset]);
} else {
$this->removeAttribute($offset);
}
}
/* ------ END OF Functions for ArrayAccess ------ */
public function getAttribute($name) {
$name = trim($name);
if (isset($this->attributes[$name])) {
return $this->attributes[$name];
} else {
return '';
}
}
public function getLength() {
return count($this->children);
}
public function getNodeName() {
return $this->nodeName;
}
public function hasAttribute($name) {
if (empty($name)) {
self::attributeNameWarning();
return;
}
return isset($this->attributes[$name]);
}
public function removeAttribute($name) {
if (empty($name)) {
self::attributeNameWarning();
return;
}
unset($this->attributes[$name]);
}
public function render($indentation = NULL, $noEndingSlash = false) {
$str = $beginning = '';
if (!is_null($indentation) && $indentation > 0) {
$beginning = str_repeat(' ', $indentation);
$str .= $beginning;
}
$str .= '<' . $this->nodeName;
foreach ($this->attributes as $name => $value) {
$str .= " $name";
if (!is_null($value)) {
$str .= "=\"$value\"";
}
}
$len = $this->getLength();
if ($len > 0) {
$str .= '>';
if ($len == 1 && is_string($this->children[0])) {
$str .= $this->children[0];
} else {
$str .= "\n";
foreach ($this->children as $child) {
if ($child instanceof Node) {
if (is_null($indentation)) {
$newIndentation = null;
} else {
$newIndentation = $indentation + 1;
}
$child = $child->render($newIndentation, $noEndingSlash);
} else {
$child = " {$beginning}{$child}\n";
}
$str .= $child;
}
$str .= $beginning;
}
$str .= '</' . $this->nodeName . '>';
} else {
if ($noEndingSlash) {
$str .= '>';
} else {
$str .= ' />';
}
}
$str .= "\n";
return $str;
}
public function setAttribute($name, $value = NULL) {
if (empty($name)) {
self::attributeNameWarning();
return;
}
$this->attributes[$name] = $value;
}
public function setNodeName($newNodeName) {
if (empty($newNodeName)) {
self::nodeNameWarning();
return;
}
$this->nodeName = trim($newNodeName);
}
}