initial commit
This commit is contained in:
171
exp/Plugin/DebugKit/View/Helper/TidyHelper.php
Normal file
171
exp/Plugin/DebugKit/View/Helper/TidyHelper.php
Normal file
@@ -0,0 +1,171 @@
|
||||
<?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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user