1: <?php
2:
3: // OUT OF DATE, NEEDS UPDATING!
4: // USE XMLWRITER!
5:
6: class HTMLPurifier_Printer
7: {
8:
9: /**
10: * For HTML generation convenience funcs.
11: * @type HTMLPurifier_Generator
12: */
13: protected $generator;
14:
15: /**
16: * For easy access.
17: * @type HTMLPurifier_Config
18: */
19: protected $config;
20:
21: /**
22: * Initialize $generator.
23: */
24: public function __construct()
25: {
26: }
27:
28: /**
29: * Give generator necessary configuration if possible
30: * @param HTMLPurifier_Config $config
31: */
32: public function prepareGenerator($config)
33: {
34: $all = $config->getAll();
35: $context = new HTMLPurifier_Context();
36: $this->generator = new HTMLPurifier_Generator($config, $context);
37: }
38:
39: /**
40: * Main function that renders object or aspect of that object
41: * @note Parameters vary depending on printer
42: */
43: // function render() {}
44:
45: /**
46: * Returns a start tag
47: * @param string $tag Tag name
48: * @param array $attr Attribute array
49: * @return string
50: */
51: protected function start($tag, $attr = array())
52: {
53: return $this->generator->generateFromToken(
54: new HTMLPurifier_Token_Start($tag, $attr ? $attr : array())
55: );
56: }
57:
58: /**
59: * Returns an end tag
60: * @param string $tag Tag name
61: * @return string
62: */
63: protected function end($tag)
64: {
65: return $this->generator->generateFromToken(
66: new HTMLPurifier_Token_End($tag)
67: );
68: }
69:
70: /**
71: * Prints a complete element with content inside
72: * @param string $tag Tag name
73: * @param string $contents Element contents
74: * @param array $attr Tag attributes
75: * @param bool $escape whether or not to escape contents
76: * @return string
77: */
78: protected function element($tag, $contents, $attr = array(), $escape = true)
79: {
80: return $this->start($tag, $attr) .
81: ($escape ? $this->escape($contents) : $contents) .
82: $this->end($tag);
83: }
84:
85: /**
86: * @param string $tag
87: * @param array $attr
88: * @return string
89: */
90: protected function elementEmpty($tag, $attr = array())
91: {
92: return $this->generator->generateFromToken(
93: new HTMLPurifier_Token_Empty($tag, $attr)
94: );
95: }
96:
97: /**
98: * @param string $text
99: * @return string
100: */
101: protected function text($text)
102: {
103: return $this->generator->generateFromToken(
104: new HTMLPurifier_Token_Text($text)
105: );
106: }
107:
108: /**
109: * Prints a simple key/value row in a table.
110: * @param string $name Key
111: * @param mixed $value Value
112: * @return string
113: */
114: protected function row($name, $value)
115: {
116: if (is_bool($value)) {
117: $value = $value ? 'On' : 'Off';
118: }
119: return
120: $this->start('tr') . "\n" .
121: $this->element('th', $name) . "\n" .
122: $this->element('td', $value) . "\n" .
123: $this->end('tr');
124: }
125:
126: /**
127: * Escapes a string for HTML output.
128: * @param string $string String to escape
129: * @return string
130: */
131: protected function escape($string)
132: {
133: $string = HTMLPurifier_Encoder::cleanUTF8($string);
134: $string = htmlspecialchars($string, ENT_COMPAT, 'UTF-8');
135: return $string;
136: }
137:
138: /**
139: * Takes a list of strings and turns them into a single list
140: * @param string[] $array List of strings
141: * @param bool $polite Bool whether or not to add an end before the last
142: * @return string
143: */
144: protected function listify($array, $polite = false)
145: {
146: if (empty($array)) {
147: return 'None';
148: }
149: $ret = '';
150: $i = count($array);
151: foreach ($array as $value) {
152: $i--;
153: $ret .= $value;
154: if ($i > 0 && !($polite && $i == 1)) {
155: $ret .= ', ';
156: }
157: if ($polite && $i == 1) {
158: $ret .= 'and ';
159: }
160: }
161: return $ret;
162: }
163:
164: /**
165: * Retrieves the class of an object without prefixes, as well as metadata
166: * @param object $obj Object to determine class of
167: * @param string $sec_prefix Further prefix to remove
168: * @return string
169: */
170: protected function getClass($obj, $sec_prefix = '')
171: {
172: static $five = null;
173: if ($five === null) {
174: $five = version_compare(PHP_VERSION, '5', '>=');
175: }
176: $prefix = 'HTMLPurifier_' . $sec_prefix;
177: if (!$five) {
178: $prefix = strtolower($prefix);
179: }
180: $class = str_replace($prefix, '', get_class($obj));
181: $lclass = strtolower($class);
182: $class .= '(';
183: switch ($lclass) {
184: case 'enum':
185: $values = array();
186: foreach ($obj->valid_values as $value => $bool) {
187: $values[] = $value;
188: }
189: $class .= implode(', ', $values);
190: break;
191: case 'css_composite':
192: $values = array();
193: foreach ($obj->defs as $def) {
194: $values[] = $this->getClass($def, $sec_prefix);
195: }
196: $class .= implode(', ', $values);
197: break;
198: case 'css_multiple':
199: $class .= $this->getClass($obj->single, $sec_prefix) . ', ';
200: $class .= $obj->max;
201: break;
202: case 'css_denyelementdecorator':
203: $class .= $this->getClass($obj->def, $sec_prefix) . ', ';
204: $class .= $obj->element;
205: break;
206: case 'css_importantdecorator':
207: $class .= $this->getClass($obj->def, $sec_prefix);
208: if ($obj->allow) {
209: $class .= ', !important';
210: }
211: break;
212: }
213: $class .= ')';
214: return $class;
215: }
216: }
217:
218: // vim: et sw=4 sts=4
219: