| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171 |
- <?php
- /**
- * Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- *
- * Licensed under The MIT License
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (http://cakefoundation.org)
- * @link http://cakephp.org CakePHP(tm) Project
- * @since v 1.0 (22-Jun-2009)
- * @license http://www.opensource.org/licenses/mit-license.php MIT License
- */
-
- App::uses('File', 'Utility');
-
- /**
- * TidyHelper class
- *
- * Passes html through tidy on the command line, and reports markup errors
- *
- * @uses AppHelper
- * @since v 1.0 (22-Jun-2009)
- */
- class TidyHelper extends AppHelper {
-
- /**
- * helpers property
- *
- * @var array
- */
- public $helpers = array('DebugKit.Toolbar');
-
- /**
- * results property
- *
- * @var mixed null
- */
- public $results = null;
-
- /**
- * Return a nested array of errors for the passed html string
- * Fudge the markup slightly so that the tag which is invalid is highlighted
- *
- * @param string $html ''
- * @param string $out ''
- * @return array
- */
- public function process($html = '', &$out = '') {
- $errors = $this->tidyErrors($html, $out);
-
- if (!$errors) {
- return array();
- }
- $result = array('Error' => array(), 'Warning' => array(), 'Misc' => array());
- $errors = explode("\n", $errors);
- $markup = explode("\n", $out);
- foreach ($errors as $error) {
- preg_match('@line (\d+) column (\d+) - (\w+): (.*)@', $error, $matches);
- if ($matches) {
- list($original, $line, $column, $type, $message) = $matches;
- $line = $line - 1;
-
- $string = '</strong>';
- if (isset($markup[$line - 1])) {
- $string .= h($markup[$line - 1]);
- }
- $string .= '<strong>' . h(@$markup[$line]) . '</strong>';
- if (isset($markup[$line + 1])) {
- $string .= h($markup[$line + 1]);
- }
- $string .= '</strong>';
-
- $result[$type][$string][] = h($message);
- } elseif ($error) {
- $message = $error;
- $result['Misc'][h($message)][] = h($message);
- }
- }
- $this->results = $result;
- return $result;
- }
-
- /**
- * report method
- *
- * Call process if a string is passed, or no prior results exist - and return the results using
- * the toolbar helper to generate a nested navigatable array
- *
- * @param mixed $html null
- * @return string
- */
- public function report($html = null) {
- if ($html) {
- $this->process($html);
- } elseif ($this->results === null) {
- $this->process($this->_View->output);
- }
- if (!$this->results) {
- return '<p>' . __d('debug_kit', 'No markup errors found') . '</p>';
- }
- foreach ($this->results as &$results) {
- foreach ($results as $type => &$messages) {
- foreach ($messages as &$message) {
- $message = html_entity_decode($message, ENT_COMPAT, Configure::read('App.encoding'));
- }
- }
- }
- return $this->Toolbar->makeNeatArray(array_filter($this->results), 0, 0, false);
- }
-
- /**
- * Run the html string through tidy, and return the (raw) errors. pass back a reference to the
- * normalized string so that the error messages can be linked to the line that caused them.
- *
- * @param string $in ''
- * @param string $out ''
- * @return string
- */
- public function tidyErrors($in = '', &$out = '') {
- $out = preg_replace('@>\s*<@s', ">\n<", $in);
-
- // direct access? windows etc
- if (function_exists('tidy_parse_string')) {
- $tidy = tidy_parse_string($out, array(), 'UTF8');
- $tidy->cleanRepair();
- $errors = $tidy->errorBuffer . "\n";
- return $errors;
- }
-
- // cli
- $File = new File(rtrim(TMP, DS) . DS . rand() . '.html', true);
- $File->write($out);
- $path = $File->pwd();
- $errors = $path . '.err';
- $this->_exec("tidy -eq -utf8 -f $errors $path");
- $File->delete();
-
- if (!file_exists($errors)) {
- return '';
- }
- $Error = new File($errors);
- $errors = $Error->read();
- $Error->delete();
- return $errors;
- }
-
- /**
- * exec method
- *
- * @param mixed $cmd
- * @param mixed $out null
- * @return boolean True if successful
- */
- protected function _exec($cmd, &$out = null) {
- if (DS === '/') {
- $_out = exec($cmd . ' 2>&1', $out, $return);
- } else {
- $_out = exec($cmd, $out, $return);
- }
-
- if (Configure::read('debug')) {
- $source = Debugger::trace(array('depth' => 1, 'start' => 2)) . "\n";
- //CakeLog::write('system_calls_' . date('Y-m-d'), "\n" . $source . Debugger::exportVar(compact('cmd','out','return')));
- //CakeLog::write('system_calls', "\n" . $source . Debugger::exportVar(compact('cmd','out','return')));
- }
- if ($return) {
- return false;
- }
- return $_out ? $_out : true;
- }
- }
|