1: | <?php
|
2: |
|
3: | |
4: | |
5: | |
6: |
|
7: | class HTMLPurifier_ErrorCollector
|
8: | {
|
9: |
|
10: | |
11: | |
12: | |
13: |
|
14: | const LINENO = 0;
|
15: | const SEVERITY = 1;
|
16: | const MESSAGE = 2;
|
17: | const CHILDREN = 3;
|
18: |
|
19: | |
20: | |
21: |
|
22: | protected $errors;
|
23: |
|
24: | |
25: | |
26: |
|
27: | protected $_current;
|
28: |
|
29: | |
30: | |
31: |
|
32: | protected $_stacks = array(array());
|
33: |
|
34: | |
35: | |
36: |
|
37: | protected $locale;
|
38: |
|
39: | |
40: | |
41: |
|
42: | protected $generator;
|
43: |
|
44: | |
45: | |
46: |
|
47: | protected $context;
|
48: |
|
49: | |
50: | |
51: |
|
52: | protected $lines = array();
|
53: |
|
54: | |
55: | |
56: |
|
57: | public function __construct($context)
|
58: | {
|
59: | $this->locale =& $context->get('Locale');
|
60: | $this->context = $context;
|
61: | $this->_current =& $this->_stacks[0];
|
62: | $this->errors =& $this->_stacks[0];
|
63: | }
|
64: |
|
65: | |
66: | |
67: | |
68: | |
69: |
|
70: | public function send($severity, $msg)
|
71: | {
|
72: | $args = array();
|
73: | if (func_num_args() > 2) {
|
74: | $args = func_get_args();
|
75: | array_shift($args);
|
76: | unset($args[0]);
|
77: | }
|
78: |
|
79: | $token = $this->context->get('CurrentToken', true);
|
80: | $line = $token ? $token->line : $this->context->get('CurrentLine', true);
|
81: | $col = $token ? $token->col : $this->context->get('CurrentCol', true);
|
82: | $attr = $this->context->get('CurrentAttr', true);
|
83: |
|
84: |
|
85: | $subst = array();
|
86: | if (!is_null($token)) {
|
87: | $args['CurrentToken'] = $token;
|
88: | }
|
89: | if (!is_null($attr)) {
|
90: | $subst['$CurrentAttr.Name'] = $attr;
|
91: | if (isset($token->attr[$attr])) {
|
92: | $subst['$CurrentAttr.Value'] = $token->attr[$attr];
|
93: | }
|
94: | }
|
95: |
|
96: | if (empty($args)) {
|
97: | $msg = $this->locale->getMessage($msg);
|
98: | } else {
|
99: | $msg = $this->locale->formatMessage($msg, $args);
|
100: | }
|
101: |
|
102: | if (!empty($subst)) {
|
103: | $msg = strtr($msg, $subst);
|
104: | }
|
105: |
|
106: |
|
107: | $error = array(
|
108: | self::LINENO => $line,
|
109: | self::SEVERITY => $severity,
|
110: | self::MESSAGE => $msg,
|
111: | self::CHILDREN => array()
|
112: | );
|
113: | $this->_current[] = $error;
|
114: |
|
115: |
|
116: |
|
117: |
|
118: |
|
119: | $new_struct = new HTMLPurifier_ErrorStruct();
|
120: | $new_struct->type = HTMLPurifier_ErrorStruct::TOKEN;
|
121: | if ($token) {
|
122: | $new_struct->value = clone $token;
|
123: | }
|
124: | if (is_int($line) && is_int($col)) {
|
125: | if (isset($this->lines[$line][$col])) {
|
126: | $struct = $this->lines[$line][$col];
|
127: | } else {
|
128: | $struct = $this->lines[$line][$col] = $new_struct;
|
129: | }
|
130: |
|
131: | ksort($this->lines[$line], SORT_NUMERIC);
|
132: | } else {
|
133: | if (isset($this->lines[-1])) {
|
134: | $struct = $this->lines[-1];
|
135: | } else {
|
136: | $struct = $this->lines[-1] = $new_struct;
|
137: | }
|
138: | }
|
139: | ksort($this->lines, SORT_NUMERIC);
|
140: |
|
141: |
|
142: | if (!empty($attr)) {
|
143: | $struct = $struct->getChild(HTMLPurifier_ErrorStruct::ATTR, $attr);
|
144: | if (!$struct->value) {
|
145: | $struct->value = array($attr, 'PUT VALUE HERE');
|
146: | }
|
147: | }
|
148: | if (!empty($cssprop)) {
|
149: | $struct = $struct->getChild(HTMLPurifier_ErrorStruct::CSSPROP, $cssprop);
|
150: | if (!$struct->value) {
|
151: |
|
152: | $struct->value = array($cssprop, 'PUT VALUE HERE');
|
153: | }
|
154: | }
|
155: |
|
156: |
|
157: | $struct->addError($severity, $msg);
|
158: | }
|
159: |
|
160: | |
161: | |
162: |
|
163: | public function getRaw()
|
164: | {
|
165: | return $this->errors;
|
166: | }
|
167: |
|
168: | |
169: | |
170: | |
171: | |
172: | |
173: |
|
174: | public function getHTMLFormatted($config, $errors = null)
|
175: | {
|
176: | $ret = array();
|
177: |
|
178: | $this->generator = new HTMLPurifier_Generator($config, $this->context);
|
179: | if ($errors === null) {
|
180: | $errors = $this->errors;
|
181: | }
|
182: |
|
183: |
|
184: |
|
185: |
|
186: | foreach ($this->lines as $line => $col_array) {
|
187: | if ($line == -1) {
|
188: | continue;
|
189: | }
|
190: | foreach ($col_array as $col => $struct) {
|
191: | $this->_renderStruct($ret, $struct, $line, $col);
|
192: | }
|
193: | }
|
194: | if (isset($this->lines[-1])) {
|
195: | $this->_renderStruct($ret, $this->lines[-1]);
|
196: | }
|
197: |
|
198: | if (empty($errors)) {
|
199: | return '<p>' . $this->locale->getMessage('ErrorCollector: No errors') . '</p>';
|
200: | } else {
|
201: | return '<ul><li>' . implode('</li><li>', $ret) . '</li></ul>';
|
202: | }
|
203: |
|
204: | }
|
205: |
|
206: | private function _renderStruct(&$ret, $struct, $line = null, $col = null)
|
207: | {
|
208: | $stack = array($struct);
|
209: | $context_stack = array(array());
|
210: | while ($current = array_pop($stack)) {
|
211: | $context = array_pop($context_stack);
|
212: | foreach ($current->errors as $error) {
|
213: | list($severity, $msg) = $error;
|
214: | $string = '';
|
215: | $string .= '<div>';
|
216: |
|
217: | $error = $this->locale->getErrorName($severity);
|
218: | $string .= "<span class=\"error e$severity\"><strong>$error</strong></span> ";
|
219: | if (!is_null($line) && !is_null($col)) {
|
220: | $string .= "<em class=\"location\">Line $line, Column $col: </em> ";
|
221: | } else {
|
222: | $string .= '<em class="location">End of Document: </em> ';
|
223: | }
|
224: | $string .= '<strong class="description">' . $this->generator->escape($msg) . '</strong> ';
|
225: | $string .= '</div>';
|
226: |
|
227: |
|
228: |
|
229: |
|
230: |
|
231: | $ret[] = $string;
|
232: | }
|
233: | foreach ($current->children as $array) {
|
234: | $context[] = $current;
|
235: | $stack = array_merge($stack, array_reverse($array, true));
|
236: | for ($i = count($array); $i > 0; $i--) {
|
237: | $context_stack[] = $context;
|
238: | }
|
239: | }
|
240: | }
|
241: | }
|
242: | }
|
243: |
|
244: |
|
245: | |