Overview
Packages
Classes
1: <?php
2:
3: /**
4: * Onion Framework - Vytváranie html prvkov
5: *
6: * Copyright (c) 2011 Jano Gašpar (http://webstranky.net)
7: *
8: * @author Jano Gašpar
9: * @copyright Copyright (c) 2011 Jano Gašpar
10: * @package Onion::UI
11: **/
12: class Html implements ArrayAccess
13: {
14: private $name;
15:
16:
17: private $is_empty;
18:
19:
20: public $attributes = array();
21:
22:
23: private $children = array();
24:
25:
26: private $parent;
27:
28:
29: public static $empty_elements = array('img', 'hr', 'br', 'input', 'meta', 'link');
30:
31:
32: public static function element($name = NULL, $attributes = NULL)
33: {
34: $element = new self;
35: $element->set_name($name);
36: if (is_array($attributes)) {
37: $element->attributes = $attributes;
38:
39: } elseif ($attributes !== NULL) {
40: $element->set_text($attributes);
41: }
42:
43: return $element;
44: }
45:
46:
47: final public function set_name($name, $empty = NULL)
48: {
49: $this->name = strtolower($name);
50: $this->is_empty = FALSE;
51:
52: if (in_array($this->name, self::$empty_elements) === TRUE) {
53: $this->is_empty = TRUE;
54: }
55:
56: return $this;
57: }
58:
59:
60: final public function get_name()
61: {
62: return $this->name;
63: }
64:
65:
66: final public function is_empty()
67: {
68: return $this->is_empty;
69: }
70:
71:
72: final public function set_text($text, $is_html = FALSE)
73: {
74: if ($text === NULL) {
75: $text = '';
76: }
77:
78: if ($is_html == FALSE) {
79: $text = str_replace(array('&', '<', '>'), array('&', '<', '>'), $text);
80: }
81:
82: $this->children = array($text);
83: return $this;
84: }
85:
86:
87: final public function get_text()
88: {
89: $text = '';
90: foreach ($this->children as $child) {
91: if (is_object($child) == TRUE) {
92: return FALSE;
93: }
94:
95: $text .= $child;
96: }
97: return $text;
98: }
99:
100:
101: final public function add($child, $is_html = TRUE)
102: {
103: if ($child instanceof Html === TRUE) {
104: $is_html = TRUE;
105: }
106:
107: if ($is_html == FALSE) {
108: $child = str_replace(array('&', '<', '>'), array('&', '<', '>'), $child);
109: }
110:
111: return $this->insert(NULL, $child);
112: }
113:
114:
115: final public function create($name, $attributes = NULL)
116: {
117: $this->insert(NULL, $child = self::element($name, $attributes));
118: return $child;
119: }
120:
121:
122: final public function insert($index, $child, $replace = FALSE)
123: {
124: if ($child instanceof Html) {
125: $child->parent = $this;
126: }
127:
128: if ($index === NULL) { // append
129: $this->children[] = $child;
130:
131: } else { // insert or replace
132: array_splice($this->children, (int) $index, $replace ? 1 : 0, array($child));
133: }
134:
135: return $this;
136: }
137:
138:
139: final public function count()
140: {
141: return count($this->children);
142: }
143:
144:
145: final public function get_iterator()
146: {
147: return new ArrayIterator($this->children);
148: }
149:
150:
151: final public function get_children($index = NULL)
152: {
153: if ($index === NULL) {
154: return $this->children;
155: }
156:
157: if (isset($this->children[$index]) == TRUE) {
158: return $this->children[$index];
159: }
160:
161: return FALSE;
162: }
163:
164:
165: final public function get_parent()
166: {
167: return $this->parent;
168: }
169:
170:
171: final public function render()
172: {
173: $html_element = $this->start_tag();
174:
175: // empty elements are finished now
176: if ($this->is_empty) {
177: return $html_element;
178: }
179:
180: // add content
181: foreach ($this->children as $child) {
182: if (is_object($child)) {
183: $html_element .= $child->render();
184:
185: } else {
186: $html_element .= $child;
187: }
188: }
189:
190: // add end tag
191: return $html_element . $this->end_tag();
192: }
193:
194:
195: final public function start_tag()
196: {
197: if ($this->name == FALSE) {
198: return '';
199: }
200:
201: $html_element = '<' . $this->name;
202:
203: if (is_array($this->attributes)) {
204: foreach ($this->attributes as $key => $value) {
205: // skip NULLs and false boolean attributes
206: if ($value === NULL || $value === FALSE) {
207: continue;
208: }
209:
210: // true boolean attribute
211: if ($value === TRUE) {
212: $html_element .= ' ' . $key . '="' . $key . '"';
213: continue;
214:
215: } elseif (is_array($value) == TRUE) {
216: // prepare into temporary array
217: $tmp = NULL;
218: foreach ($value as $k => $v) {
219: // skip NULLs & empty string; composite 'style' vs. 'others'
220: if ($v <> NULL) {
221: if (is_string($k) == TRUE) {
222: $tmp[] = $k . ':' . $v;
223:
224: } else {
225: $tmp[] = $v;
226: }
227: }
228: }
229:
230: if (!$tmp) continue;
231: $value = implode($key === 'style' ? ';' : ' ', $tmp);
232: }
233:
234: // add new attribute
235: $html_element .= ' ' . $key . '="'
236: . str_replace(array('&', '"', '<', '>', '@'), array('&', '"', '<', '>', '@'), $value)
237: . '"';
238: }
239: }
240:
241:
242: // finish start tag
243: if ($this->is_empty) {
244: return $html_element . ' />';
245: }
246:
247: return $html_element . '>';
248: }
249:
250:
251: final public function end_tag()
252: {
253: if ($this->name AND $this->is_empty == FALSE) {
254: return '</' . $this->name . '>';
255: }
256: return '';
257: }
258:
259:
260: final public function __set($name, $value)
261: {
262: $this->attributes[$name] = $value;
263: }
264:
265:
266: final public function &__get($name)
267: {
268: return $this->attributes[$name];
269: }
270:
271:
272: final public function __call($m, $args)
273: {
274: $this->attributes[$m] = $args[0];
275: return $this;
276: }
277:
278:
279: final public function __tostring()
280: {
281: return $this->render();
282: }
283:
284:
285: final public function __clone()
286: {
287: $this->parent = NULL;
288: foreach ($this->children as $key => $value) {
289: if (is_object($value) == TRUE) {
290: $this->children[$key] = clone $value;
291: }
292: }
293: }
294:
295:
296: final public function offsetSet($index, $child)
297: {
298: $this->insert($index, $child, TRUE);
299: }
300:
301:
302: final public function offsetGet($index)
303: {
304: return $this->children[$index];
305: }
306:
307:
308: final public function offsetExists($index)
309: {
310: return isset($this->children[$index]);
311: }
312:
313:
314: final public function offsetUnset($index)
315: {
316: if (isset($this->children[$index]) == FALSE) {
317: $child = $this->children[$index];
318: array_splice($this->children, (int) $index, 1);
319: $child->parent = NULL;
320: }
321: }
322: }
323: