<?php
/**
* Moc10 Library
*
* LICENSE
*
* This source file is subject to the new BSD license that is bundled
* with this package in the file LICENSE.TXT.
* It is also available through the world-wide-web at this URL:
* http://www.moc10phplibrary.com/LICENSE.TXT
* If you did not receive a copy of the license and are unable to
* obtain it through the world-wide-web, please send an email
* to hide@address.com so we can send you a copy immediately.
*
* @category Moc10
* @package Moc10_Dom
* @author Nick Sagona, III <hide@address.com>
* @copyright Copyright (c) 2009-2011 Moc 10 Media, LLC. (http://www.moc10media.com)
* @license http://www.moc10phplibrary.com/LICENSE.TXT New BSD License
*/
/**
* Moc10_Dom
*
* @category Moc10
* @package Moc10_Dom
* @author Nick Sagona, III <hide@address.com>
* @copyright Copyright (c) 2009-2011 Moc 10 Media, LLC. (http://www.moc10media.com)
* @license http://www.moc10phplibrary.com/LICENSE.TXT New BSD License
* @version 1.9.7
*/
class Moc10_Dom
{
/**
* Document type
* @var string
*/
protected $_type = null;
/**
* Document content type
* @var string
*/
protected $_contentType = 'text/html';
/**
* Document charset
* @var string
*/
protected $_charset = 'utf-8';
/**
* Document indent
* @var string
*/
protected $_indent = null;
/**
* Document children
* @var array
*/
protected $_childNodes = array();
/**
* Document output
* @var string
*/
protected $_output = null;
/**
* Document doctypes
* @var array
*/
protected $_doctypes = array('HTML_TRANS' => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n",
'HTML_STRICT' => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01//EN\" \"http://www.w3.org/TR/html4/strict.dtd\">\n",
'HTML_FRAMES' => "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Frameset//EN\" \"http://www.w3.org/TR/html4/frameset.dtd\">\n",
'XHTML_TRANS' => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Transitional//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd\">\n",
'XHTML_STRICT' => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Strict//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd\">\n",
'XHTML_FRAMES' => "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.0 Frameset//EN\" \"http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd\">\n",
'XHTML11' => "<?xml version=\"1.0\" encoding=\"[{charset}]\"?>\n<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n",
'XML' => "<?xml version=\"1.0\" encoding=\"[{charset}]\"?>\n",
'RSS' => "<?xml version=\"1.0\" encoding=\"[{charset}]\"?>\n",
'ATOM' => "<?xml version=\"1.0\" encoding=\"[{charset}]\"?>\n");
/**
* Language object
* @var Moc10_Language
*/
protected $_lang = null;
/**
* Constructor
*
* Instantiate the document object
*
* @param string $type
* @param string $charset
* @param array|Moc10_Dom_Child $childNode
* @param string $indent
* @throws Exception
* @return void
*/
public function __construct($type = null, $charset = 'utf-8', $childNode = null, $indent = null)
{
$this->_lang = new Moc10_Language();
// Check the document type, else set the properties.
if ((!is_null($type)) && (!array_key_exists($type, $this->_doctypes))) {
throw new Exception($this->_lang->__('Error: That doctype is not allowed.'));
} else {
$this->_type = $type;
if ($type == 'ATOM') {
$this->_contentType = 'application/atom+xml';
} else if ($type == 'RSS') {
$this->_contentType = 'application/rss+xml';
} else if ($type == 'XML') {
$this->_contentType = 'application/xml';
} else {
$this->_contentType = 'text/html';
}
$this->_charset = $charset;
$this->_indent = $indent;
if (!is_null($childNode)) {
$this->addChildren($childNode);
}
}
}
/**
* Method to return the document type.
*
* @return void
*/
public function getType()
{
return $this->_type;
}
/**
* Method to return the document charset.
*
* @return void
*/
public function getCharset()
{
return $this->_charset;
}
/**
* Method to return the document indent.
*
* @return void
*/
public function getIndent()
{
return $this->_indent;
}
/**
* Method to set the document type.
*
* @param string $type
* @return void
*/
public function setType($type)
{
$this->_type = $type;
}
/**
* Method to set the document type declaration in the doctype header.
*
* @param string $dtd
* @return void
*/
public function setDTD($dtd)
{
if (($this->_type == 'XML') || ($this->_type == 'RSS') || ($this->_type == 'ATOM')) {
$this->_doctypes[$this->_type] .= $dtd . "\n";
}
}
/**
* Method to set the document charset.
*
* @param string $chr
* @return void
*/
public function setCharset($chr)
{
$this->_charset = $chr;
}
/**
* Method to set the document indent.
*
* @param string $ind
* @return void
*/
public function setIndent($ind)
{
$this->_indent = $ind;
}
/**
* Add a child or children to the child element.
*
* @param array|Moc10_Dom_Child $c
* @throws Exception
* @return void
*/
public function addChildren($c)
{
// Check if the argument passed is an array or not.
if (!is_array($c)) {
// Check the argument passed to see if it is an instance of Moc10_Dom_Child.
if (!($c instanceof Moc10_Dom_Child)) {
throw new Exception($this->_lang->__('The child element passed is not an instance of Moc10_Dom_Child.'));
} else {
// Append the child to the form object.
$this->_childNodes[] = $c;
}
} else {
// Check the arguments passed to see if they are all instances of Moc10_Dom_Child.
foreach ($c as $obj) {
if (!($obj instanceof Moc10_Dom_Child)) {
throw new Exception($this->_lang->__('One or more of the child elements passed is not an instance of Moc10_Dom_Child.'));
} else {
$this->_childNodes[] = $obj;
}
}
}
}
/**
* Get the child nodes of the document.
*
* @return array
*/
public function getChildren()
{
return $this->_childNodes;
}
/**
* Remove all child nodes from the document object.
*
* @return void
*/
public function removeChildren()
{
$this->_childNodes = array();
}
/**
* Method to render the document and its elements.
*
* @param boolean $ret
* @return void
*/
public function render($ret = false)
{
// If the return flag is passed, return output.
if ($ret) {
$this->_output = '';
if (!is_null($this->_type)) {
$this->_output .= str_replace('[{charset}]', $this->_charset, $this->_doctypes[$this->_type]);
}
foreach ($this->_childNodes as $child) {
$this->_output .= $child->render(true, 0, $this->_indent);
}
return $this->_output;
// Else, print output.
} else {
if (!is_null($this->_type)) {
if (!headers_sent()) {
header('Content-type: ' . $this->_contentType);
}
print(str_replace('[{charset}]', $this->_charset, $this->_doctypes[$this->_type]));
}
foreach ($this->_childNodes as $child) {
$child->render(false, 0, $this->_indent);
}
}
}
}