1: <?php
2: namespace Tokamak\Dom;
3:
4: use DOMDocument;
5: use Closure;
6:
7: /**
8: * Class Document
9: * @package Tokamak\Dom
10: * Represents the root node of a DOM.
11: * Extend this class to create a template class for
12: * a particular document.
13: */
14: abstract class Document extends Node {
15:
16: /**
17: * @var string The XML version of the document. Not used in HTML5 docs.
18: */
19: public static $version = '1.0';
20:
21: /**
22: * @var string The character encoding of the document.
23: */
24: public static $encoding = 'UTF-8';
25:
26:
27: /**
28: * The underlying DOMDocument instance over which this library provides an abstraction.
29: * @var DOMDocument
30: */
31: protected $dom;
32:
33: /**
34: * Initialize the document by passing it data/state.
35: * @param array $data
36: * @param array $doctype
37: */
38: public function __construct(array $data = null, array $doctype = null){
39: $imp = new \DOMImplementation();
40:
41: // Optionally, create a <!DOCTYPE> tag
42: if(is_array($doctype)){
43: $dtd = $imp->createDocumentType($doctype[0], $doctype[1], $doctype[2]);
44: $this->dom = $imp->createDocument(null, null, $dtd);
45: } else {
46: $this->dom = $imp->createDocument(null, null);
47: }
48:
49: $this->dom->encoding = static::$encoding;
50: $this->dom->version = static::$version;
51: $this->dom->formatOutput = true;
52: $this->data = $data;
53:
54: // build the DOM
55: $this->render();
56: }
57:
58: /**
59: * Set whether the string output should be
60: * formatted with newLines.
61: * @param bool $bool
62: */
63: public function setFormatOutput($bool){
64: $this->dom->formatOutput = $bool;
65: }
66:
67: /**
68: * Append a Node instance to the top-level DOM root.
69: * @param Node $child An Element or Component.
70: * @return Node Returns the child for method-chaining.
71: */
72: public function append(Node $child){
73: while($child->hasDomNodes()){
74: $childNode = $child->getDomNode();
75: $this->dom->appendChild($childNode);
76: }
77: // Set the parent DOMNode of the component,
78: // so that any remaining fluent method calls
79: // can append directly to the node.
80: if($child instanceof Component){
81: $child->setParentNode($this->dom);
82: }
83:
84: return $child;
85: }
86:
87: /**
88: * Alias for "magic" __toString method.
89: * @return string
90: */
91: public function toString(){
92: return $this->__toString();
93: }
94: /**
95: * Render a string representation of the document.
96: * @return string
97: */
98: abstract public function __toString();
99:
100: }