Subversion Repositories SmartDukaan

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
12345 anikendra 1
<?php
2
/**
3
 * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
4
 *
5
 * Licensed under The MIT License
6
 * Redistributions of files must retain the above copyright notice.
7
 *
8
 * @copyright     Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
9
 * @link          http://cakephp.org CakePHP(tm) Project
10
 * @since         v 1.0 (22-Jun-2009)
11
 * @license       http://www.opensource.org/licenses/mit-license.php MIT License
12
 */
13
 
14
App::uses('File', 'Utility');
15
 
16
/**
17
 * TidyHelper class
18
 *
19
 * Passes html through tidy on the command line, and reports markup errors
20
 *
21
 * @uses          AppHelper
22
 * @since         v 1.0 (22-Jun-2009)
23
 */
24
class TidyHelper extends AppHelper {
25
 
26
/**
27
 * helpers property
28
 *
29
 * @var array
30
 */
31
	public $helpers = array('DebugKit.Toolbar');
32
 
33
/**
34
 * results property
35
 *
36
 * @var mixed null
37
 */
38
	public $results = null;
39
 
40
/**
41
 * Return a nested array of errors for the passed html string
42
 * Fudge the markup slightly so that the tag which is invalid is highlighted
43
 *
44
 * @param string $html ''
45
 * @param string $out ''
46
 * @return array
47
 */
48
	public function process($html = '', &$out = '') {
49
		$errors = $this->tidyErrors($html, $out);
50
 
51
		if (!$errors) {
52
			return array();
53
		}
54
		$result = array('Error' => array(), 'Warning' => array(), 'Misc' => array());
55
		$errors = explode("\n", $errors);
56
		$markup = explode("\n", $out);
57
		foreach ($errors as $error) {
58
			preg_match('@line (\d+) column (\d+) - (\w+): (.*)@', $error, $matches);
59
			if ($matches) {
60
				list($original, $line, $column, $type, $message) = $matches;
61
				$line = $line - 1;
62
 
63
				$string = '</strong>';
64
				if (isset($markup[$line - 1])) {
65
					$string .= h($markup[$line - 1]);
66
				}
67
				$string .= '<strong>' . h(@$markup[$line]) . '</strong>';
68
				if (isset($markup[$line + 1])) {
69
					$string .= h($markup[$line + 1]);
70
				}
71
				$string .= '</strong>';
72
 
73
				$result[$type][$string][] = h($message);
74
			} elseif ($error) {
75
				$message = $error;
76
				$result['Misc'][h($message)][] = h($message);
77
			}
78
		}
79
		$this->results = $result;
80
		return $result;
81
	}
82
 
83
/**
84
 * report method
85
 *
86
 * Call process if a string is passed, or no prior results exist - and return the results using
87
 * the toolbar helper to generate a nested navigatable array
88
 *
89
 * @param mixed $html null
90
 * @return string
91
 */
92
	public function report($html = null) {
93
		if ($html) {
94
			$this->process($html);
95
		} elseif ($this->results === null) {
96
			$this->process($this->_View->output);
97
		}
98
		if (!$this->results) {
99
			return '<p>' . __d('debug_kit', 'No markup errors found') . '</p>';
100
		}
101
		foreach ($this->results as &$results) {
102
			foreach ($results as $type => &$messages) {
103
				foreach ($messages as &$message) {
104
					$message = html_entity_decode($message, ENT_COMPAT, Configure::read('App.encoding'));
105
				}
106
			}
107
		}
108
		return $this->Toolbar->makeNeatArray(array_filter($this->results), 0, 0, false);
109
	}
110
 
111
/**
112
 * Run the html string through tidy, and return the (raw) errors. pass back a reference to the
113
 * normalized string so that the error messages can be linked to the line that caused them.
114
 *
115
 * @param string $in ''
116
 * @param string $out ''
117
 * @return string
118
 */
119
	public function tidyErrors($in = '', &$out = '') {
120
		$out = preg_replace('@>\s*<@s', ">\n<", $in);
121
 
122
		// direct access? windows etc
123
		if (function_exists('tidy_parse_string')) {
124
			$tidy = tidy_parse_string($out, array(), 'UTF8');
125
			$tidy->cleanRepair();
126
			$errors = $tidy->errorBuffer . "\n";
127
			return $errors;
128
		}
129
 
130
		// cli
131
		$File = new File(rtrim(TMP, DS) . DS . rand() . '.html', true);
132
		$File->write($out);
133
		$path = $File->pwd();
134
		$errors = $path . '.err';
135
		$this->_exec("tidy -eq -utf8 -f $errors $path");
136
		$File->delete();
137
 
138
		if (!file_exists($errors)) {
139
			return '';
140
		}
141
		$Error = new File($errors);
142
		$errors = $Error->read();
143
		$Error->delete();
144
		return $errors;
145
	}
146
 
147
/**
148
 * exec method
149
 *
150
 * @param mixed $cmd
151
 * @param mixed $out null
152
 * @return boolean True if successful
153
 */
154
	protected function _exec($cmd, &$out = null) {
155
		if (DS === '/') {
156
			$_out = exec($cmd . ' 2>&1', $out, $return);
157
		} else {
158
			$_out = exec($cmd, $out, $return);
159
		}
160
 
161
		if (Configure::read('debug')) {
162
			$source = Debugger::trace(array('depth' => 1, 'start' => 2)) . "\n";
163
			//CakeLog::write('system_calls_' . date('Y-m-d'), "\n" . $source . Debugger::exportVar(compact('cmd','out','return')));
164
			//CakeLog::write('system_calls', "\n" . $source . Debugger::exportVar(compact('cmd','out','return')));
165
		}
166
		if ($return) {
167
			return false;
168
		}
169
		return $_out ? $_out : true;
170
	}
171
}