/** * Use the HTML tidy extension to use the tidy library in-process, * saving the overhead of spawning a new process. * * @param string $text HTML to check * @param bool $stderr Whether to read result from error status instead of output * @param int &$retval Exit code (-1 on internal error) * @return string|null */ protected function cleanWrapped($text, $stderr = false, &$retval = null) { if (!class_exists('tidy')) { wfWarn("Unable to load internal tidy class."); $retval = -1; return null; } $tidy = new \tidy(); $tidy->parseString($text, $this->config['tidyConfigFile'], 'utf8'); if ($stderr) { $retval = $tidy->getStatus(); return $tidy->errorBuffer; } $tidy->cleanRepair(); $retval = $tidy->getStatus(); if ($retval == 2) { // 2 is magic number for fatal error // http://www.php.net/manual/en/function.tidy-get-status.php $cleansource = null; } else { $cleansource = tidy_get_output($tidy); if (!empty($this->config['debugComment']) && $retval > 0) { $cleansource .= "<!--\nTidy reports:\n" . str_replace('-->', '-->', $tidy->errorBuffer) . "\n-->"; } } return $cleansource; }
/** * Execute this filter. * * @param AgaviFilterChain The filter chain. * @param AgaviExecutionContainer The current execution container. * * @throws <b>AgaviFilterException</b> If an error occurs during execution. * * @author David Zülke <*****@*****.**> * @since 1.0.0 */ public function execute(AgaviFilterChain $filterChain, AgaviExecutionContainer $container) { // nothing to do so far. let's carry on in the chain $filterChain->execute($container); // fetch some prerequisites $response = $container->getResponse(); $ot = $response->getOutputType(); $cfg = $this->getParameters(); if (!$response->isContentMutable() || !($output = $response->getContent())) { // content empty or response not mutable; it's over! return; } if (is_array($cfg['methods']) && !in_array($container->getRequestMethod(), $cfg['methods'])) { // we're not allowed to run for this request method return; } if (is_array($cfg['output_types']) && !in_array($ot->getName(), $cfg['output_types'])) { // we're not allowed to run for this output type return; } $tidy = new tidy(); $tidy->parseString($output, $cfg['tidy_options'], $cfg['tidy_encoding']); $tidy->cleanRepair(); if ($tidy->getStatus()) { // warning or error occurred $emsg = sprintf('Tidy Filter encountered the following problems while parsing and cleaning the document: ' . "\n\n%s", $tidy->errorBuffer); if (AgaviConfig::get('core.use_logging') && $cfg['log_errors']) { $lmsg = $emsg . "\n\nResponse content:\n\n" . $response->getContent(); $lm = $this->context->getLoggerManager(); $mc = $lm->getDefaultMessageClass(); $m = new $mc($lmsg, $cfg['logging_severity']); $lm->log($m, $cfg['logging_logger']); } // all in all, that didn't go so well. let's see if we should just silently abort instead of throwing an exception if (!$cfg['ignore_errors']) { throw new AgaviParseException($emsg); } } $response->setContent((string) $tidy); }
/** * Use the HTML tidy PECL extension to use the tidy library in-process, * saving the overhead of spawning a new process. * * 'pear install tidy' should be able to compile the extension module. */ private static function execInternalTidy($text, $stderr = false, &$retval = null) { global $wgTidyConf, $IP, $wgDebugTidy; wfProfileIn(__METHOD__); $tidy = new tidy(); $tidy->parseString($text, $wgTidyConf, 'utf8'); if ($stderr) { $retval = $tidy->getStatus(); return $tidy->errorBuffer; } else { $tidy->cleanRepair(); $retval = $tidy->getStatus(); if ($retval == 2) { // 2 is magic number for fatal error // http://www.php.net/manual/en/function.tidy-get-status.php $cleansource = null; } else { $cleansource = tidy_get_output($tidy); } if ($wgDebugTidy && $retval > 0) { $cleansource .= "<!--\nTidy reports:\n" . str_replace('-->', '-->', $tidy->errorBuffer) . "\n-->"; } wfProfileOut(__METHOD__); return $cleansource; } }
/** * Use the HTML tidy PECL extension to use the tidy library in-process, * saving the overhead of spawning a new process. * * 'pear install tidy' should be able to compile the extension module. * * @private * @static */ function internalTidy($text) { global $wgTidyConf, $IP, $wgDebugTidy; $fname = 'Parser::internalTidy'; wfProfileIn($fname); $tidy = new tidy(); $tidy->parseString($text, $wgTidyConf, 'utf8'); $tidy->cleanRepair(); if ($tidy->getStatus() == 2) { // 2 is magic number for fatal error // http://www.php.net/manual/en/function.tidy-get-status.php $cleansource = null; } else { $cleansource = tidy_get_output($tidy); } if ($wgDebugTidy && $tidy->getStatus() > 0) { $cleansource .= "<!--\nTidy reports:\n" . str_replace('-->', '-->', $tidy->errorBuffer) . "\n-->"; } wfProfileOut($fname); return $cleansource; }
/** * Use the HTML tidy extension to use the tidy library in-process, * saving the overhead of spawning a new process. * * @param string $text HTML to check * @param bool $stderr Whether to read result from error status instead of output * @param int &$retval Exit code (-1 on internal error) * @return string|null */ private static function phpClean($text, $stderr = false, &$retval = null) { global $wgTidyConf, $wgDebugTidy; if (!wfIsHHVM() && !class_exists('tidy') || wfIsHHVM() && !function_exists('tidy_repair_string')) { wfWarn("Unable to load internal tidy class."); $retval = -1; return null; } $tidy = new tidy(); $tidy->parseString($text, $wgTidyConf, 'utf8'); if ($stderr) { $retval = $tidy->getStatus(); return $tidy->errorBuffer; } $tidy->cleanRepair(); $retval = $tidy->getStatus(); if ($retval == 2) { // 2 is magic number for fatal error // http://www.php.net/manual/en/function.tidy-get-status.php $cleansource = null; } else { $cleansource = tidy_get_output($tidy); if ($wgDebugTidy && $retval > 0) { $cleansource .= "<!--\nTidy reports:\n" . str_replace('-->', '-->', $tidy->errorBuffer) . "\n-->"; } } return $cleansource; }
/** * Use the HTML tidy PECL extension to use the tidy library in-process, * saving the overhead of spawning a new process. * * 'pear install tidy' should be able to compile the extension module. * * @private * @static */ function internalTidy($text) { global $wgTidyConf, $IP; $fname = 'Parser::internalTidy'; wfProfileIn($fname); $tidy = new tidy(); $tidy->parseString($text, $wgTidyConf, 'utf8'); $tidy->cleanRepair(); if ($tidy->getStatus() == 2) { // 2 is magic number for fatal error // http://www.php.net/manual/en/function.tidy-get-status.php $cleansource = null; } else { $cleansource = tidy_get_output($tidy); } wfProfileOut($fname); return $cleansource; }
/** * Replace the output with an error if the HTML is not valid */ function wfHtmlValidationHandler($s) { global $IP; $tidy = new tidy(); $tidy->parseString($s, "{$IP}/includes/tidy.conf", 'utf8'); if ($tidy->getStatus() == 0) { return $s; } header('Cache-Control: no-cache'); $out = <<<EOT <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <html> <head> <title>HTML validation error</title> <style> .highlight { background-color: #ffc } li { white-space: pre } </style> </head> <body> <h1>HTML validation error</h1> <ul> EOT; $error = strtok($tidy->errorBuffer, "\n"); $badLines = array(); while ($error !== false) { if (preg_match('/^line (\\d+)/', $error, $m)) { $lineNum = intval($m[1]); $badLines[$lineNum] = true; $out .= "<li><a href=\"#line-{$lineNum}\">" . htmlspecialchars($error) . "</a></li>\n"; } $error = strtok("\n"); } $out .= '<pre>' . htmlspecialchars($tidy->errorBuffer) . '</pre>'; $out .= '<ol>'; $line = strtok($s, "\n"); $i = 1; while ($line !== false) { if (isset($badLines[$i])) { $out .= "<li class=\"highlight\" id=\"line-{$i}\">"; } else { $out .= '<li>'; } $out .= htmlspecialchars($line) . '</li>'; $line = strtok("\n"); $i++; } $out .= '</ol></body></html>'; return $out; }