00001 <?php
00002
00012 class MWTidy {
00013
00022 public static function tidy( $text ) {
00023 global $wgTidyInternal;
00024
00025 $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.
00026 ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>'.
00027 '<head><title>test</title></head><body>'.$text.'</body></html>';
00028
00029 # Tidy is known to clobber tabs; convert them to entities
00030 $wrappedtext = str_replace( "\t", '	', $wrappedtext );
00031
00032 if( $wgTidyInternal ) {
00033 $correctedtext = self::execInternalTidy( $wrappedtext );
00034 } else {
00035 $correctedtext = self::execExternalTidy( $wrappedtext );
00036 }
00037 if( is_null( $correctedtext ) ) {
00038 wfDebug( "Tidy error detected!\n" );
00039 return $text . "\n<!-- Tidy found serious XHTML errors -->\n";
00040 }
00041
00042 # Convert the tabs back from entities
00043 $correctedtext = str_replace( '	', "\t", $correctedtext );
00044
00045 return $correctedtext;
00046 }
00047
00055 public static function checkErrors( $text, &$errorStr = null ) {
00056 global $wgTidyInternal;
00057
00058 $retval = 0;
00059 if( $wgTidyInternal ) {
00060 $errorStr = self::execInternalTidy( $text, true, $retval );
00061 } else {
00062 $errorStr = self::execExternalTidy( $text, true, $retval );
00063 }
00064 return ( $retval < 0 && $errorStr == '' ) || $retval == 0;
00065 }
00066
00076 private static function execExternalTidy( $text, $stderr = false, &$retval = null ) {
00077 global $wgTidyConf, $wgTidyBin, $wgTidyOpts;
00078 wfProfileIn( __METHOD__ );
00079
00080 $cleansource = '';
00081 $opts = ' -utf8';
00082
00083 if( $stderr ) {
00084 $descriptorspec = array(
00085 0 => array( 'pipe', 'r' ),
00086 1 => array( 'file', wfGetNull(), 'a' ),
00087 2 => array( 'pipe', 'w' )
00088 );
00089 } else {
00090 $descriptorspec = array(
00091 0 => array( 'pipe', 'r' ),
00092 1 => array( 'pipe', 'w' ),
00093 2 => array( 'file', wfGetNull(), 'a' )
00094 );
00095 }
00096
00097 $readpipe = $stderr ? 2 : 1;
00098 $pipes = array();
00099
00100 if( function_exists( 'proc_open' ) ) {
00101 $process = proc_open( "$wgTidyBin -config $wgTidyConf $wgTidyOpts$opts", $descriptorspec, $pipes );
00102 if ( is_resource( $process ) ) {
00103
00104
00105
00106
00107
00108 fwrite( $pipes[0], $text );
00109 fclose( $pipes[0] );
00110 while ( !feof( $pipes[$readpipe] ) ) {
00111 $cleansource .= fgets( $pipes[$readpipe], 1024 );
00112 }
00113 fclose( $pipes[$readpipe] );
00114 $retval = proc_close( $process );
00115 } else {
00116 $retval = -1;
00117 }
00118 } else {
00119 $retval = -1;
00120 }
00121
00122 wfProfileOut( __METHOD__ );
00123
00124 if( !$stderr && $cleansource == '' && $text != '' ) {
00125
00126
00127 return null;
00128 } else {
00129 return $cleansource;
00130 }
00131 }
00132
00139 private static function execInternalTidy( $text, $stderr = false, &$retval = null ) {
00140 global $wgTidyConf, $IP, $wgDebugTidy;
00141 wfProfileIn( __METHOD__ );
00142
00143 $tidy = new tidy;
00144 $tidy->parseString( $text, $wgTidyConf, 'utf8' );
00145
00146 if( $stderr ) {
00147 $retval = $tidy->getStatus();
00148 return $tidy->errorBuffer;
00149 } else {
00150 $tidy->cleanRepair();
00151 $retval = $tidy->getStatus();
00152 if( $retval == 2 ) {
00153
00154
00155 $cleansource = null;
00156 } else {
00157 $cleansource = tidy_get_output( $tidy );
00158 }
00159 if ( $wgDebugTidy && $retval > 0 ) {
00160 $cleansource .= "<!--\nTidy reports:\n" .
00161 str_replace( '-->', '-->', $tidy->errorBuffer ) .
00162 "\n-->";
00163 }
00164
00165 wfProfileOut( __METHOD__ );
00166 return $cleansource;
00167 }
00168 }
00169
00170 }