r39662 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r39661‎ | r39662 | r39663 >
Date:20:59, 19 August 2008
Author:brion
Status:old
Tags:
Comment:
Revert Parser.php to r39295 good state.
Whitespace handling for image width magic words failed, possibly other problems.
NEEDS PARSER TESTS
Modified paths:
  • /trunk/phase3/includes/parser/Parser.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/parser/Parser.php
@@ -98,7 +98,7 @@
9999 # Cleared with clearState():
100100 var $mOutput, $mAutonumber, $mDTopen, $mStripState;
101101 var $mIncludeCount, $mArgStack, $mLastSection, $mInPre;
102 - var $mLinkHolders, $mLinkID;
 102+ var $mInterwikiLinkHolders, $mLinkHolders;
103103 var $mIncludeSizes, $mPPNodeCount, $mDefaultSort;
104104 var $mTplExpandCache; // empty-frame expansion cache
105105 var $mTplRedirCache, $mTplDomCache, $mHeadings, $mDoubleUnderscores;
@@ -179,8 +179,17 @@
180180 $this->mStripState = new StripState;
181181 $this->mArgStack = false;
182182 $this->mInPre = false;
183 - $this->mLinkHolders = new LinkHolderArray( $this );
184 - $this->mLinkID = 0;
 183+ $this->mInterwikiLinkHolders = array(
 184+ 'texts' => array(),
 185+ 'titles' => array()
 186+ );
 187+ $this->mLinkHolders = array(
 188+ 'namespaces' => array(),
 189+ 'dbkeys' => array(),
 190+ 'queries' => array(),
 191+ 'texts' => array(),
 192+ 'titles' => array()
 193+ );
185194 $this->mRevisionTimestamp = $this->mRevisionId = null;
186195
187196 /**
@@ -195,7 +204,7 @@
196205 */
197206 #$this->mUniqPrefix = "\x07UNIQ" . Parser::getRandomString();
198207 # Changed to \x7f to allow XML double-parsing -- TS
199 - $this->mUniqPrefix = "\x7fUNIQ" . self::getRandomString();
 208+ $this->mUniqPrefix = "\x7fUNIQ" . Parser::getRandomString();
200209
201210
202211 # Clear these on every parse, bug 4549
@@ -285,7 +294,7 @@
286295 */
287296
288297 global $wgUseTidy, $wgAlwaysUseTidy, $wgContLang;
289 - $fname = __METHOD__.'-' . wfGetCaller();
 298+ $fname = 'Parser::parse-' . wfGetCaller();
290299 wfProfileIn( __METHOD__ );
291300 wfProfileIn( $fname );
292301
@@ -319,6 +328,7 @@
320329 );
321330 $text = preg_replace( array_keys($fixtags), array_values($fixtags), $text );
322331
 332+ # only once and last
323333 $text = $this->doBlockLevels( $text, $linestart );
324334
325335 $this->replaceLinkHolders( $text );
@@ -338,7 +348,7 @@
339349 $uniq_prefix = $this->mUniqPrefix;
340350 $matches = array();
341351 $elements = array_keys( $this->mTransparentTagHooks );
342 - $text = self::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
 352+ $text = Parser::extractTagsAndParams( $elements, $text, $matches, $uniq_prefix );
343353
344354 foreach( $matches as $marker => $data ) {
345355 list( $element, $content, $params, $tag ) = $data;
@@ -356,7 +366,7 @@
357367 $text = Sanitizer::normalizeCharReferences( $text );
358368
359369 if (($wgUseTidy and $this->mOptions->mTidy) or $wgAlwaysUseTidy) {
360 - $text = self::tidy($text);
 370+ $text = Parser::tidy($text);
361371 } else {
362372 # attempt to sanitize at least some nesting problems
363373 # (bug #2702 and quite a few others)
@@ -461,8 +471,6 @@
462472 function &getTitle() { return $this->mTitle; }
463473 function getOptions() { return $this->mOptions; }
464474 function getRevisionId() { return $this->mRevisionId; }
465 - function getOutput() { return $this->mOutput; }
466 - function nextLinkID() { return $this->mLinkID++; }
467475
468476 function getFunctionLang() {
469477 global $wgLang, $wgContLang;
@@ -504,7 +512,7 @@
505513 * @public
506514 * @static
507515 */
508 - static function extractTagsAndParams($elements, $text, &$matches, $uniq_prefix = ''){
 516+ function extractTagsAndParams($elements, $text, &$matches, $uniq_prefix = ''){
509517 static $n = 1;
510518 $stripped = '';
511519 $matches = array();
@@ -541,7 +549,7 @@
542550 $text = $inside;
543551 $tail = null;
544552 } else {
545 - if( $element === '!--' ) {
 553+ if( $element == '!--' ) {
546554 $end = '/(-->)/';
547555 } else {
548556 $end = "/(<\\/$element\\s*>)/i";
@@ -644,15 +652,15 @@
645653 * @public
646654 * @static
647655 */
648 - static function tidy( $text ) {
 656+ function tidy( $text ) {
649657 global $wgTidyInternal;
650658 $wrappedtext = '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"'.
651659 ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html>'.
652660 '<head><title>test</title></head><body>'.$text.'</body></html>';
653661 if( $wgTidyInternal ) {
654 - $correctedtext = self::internalTidy( $wrappedtext );
 662+ $correctedtext = Parser::internalTidy( $wrappedtext );
655663 } else {
656 - $correctedtext = self::externalTidy( $wrappedtext );
 664+ $correctedtext = Parser::externalTidy( $wrappedtext );
657665 }
658666 if( is_null( $correctedtext ) ) {
659667 wfDebug( "Tidy error detected!\n" );
@@ -667,9 +675,10 @@
668676 * @private
669677 * @static
670678 */
671 - static function externalTidy( $text ) {
 679+ function externalTidy( $text ) {
672680 global $wgTidyConf, $wgTidyBin, $wgTidyOpts;
673 - wfProfileIn( __METHOD__ );
 681+ $fname = 'Parser::externalTidy';
 682+ wfProfileIn( $fname );
674683
675684 $cleansource = '';
676685 $opts = ' -utf8';
@@ -698,7 +707,7 @@
699708 }
700709 }
701710
702 - wfProfileOut( __METHOD__ );
 711+ wfProfileOut( $fname );
703712
704713 if( $cleansource == '' && $text != '') {
705714 // Some kind of error happened, so we couldn't get the corrected text.
@@ -718,9 +727,10 @@
719728 * @private
720729 * @static
721730 */
722 - static function internalTidy( $text ) {
 731+ function internalTidy( $text ) {
723732 global $wgTidyConf, $IP, $wgDebugTidy;
724 - wfProfileIn( __METHOD__ );
 733+ $fname = 'Parser::internalTidy';
 734+ wfProfileIn( $fname );
725735
726736 $tidy = new tidy;
727737 $tidy->parseString( $text, $wgTidyConf, 'utf8' );
@@ -738,7 +748,7 @@
739749 "\n-->";
740750 }
741751
742 - wfProfileOut( __METHOD__ );
 752+ wfProfileOut( $fname );
743753 return $cleansource;
744754 }
745755
@@ -748,35 +758,34 @@
749759 * @private
750760 */
751761 function doTableStuff ( $text ) {
752 - wfProfileIn( __METHOD__ );
 762+ $fname = 'Parser::doTableStuff';
 763+ wfProfileIn( $fname );
753764
754 - $lines = StringUtils::explode( "\n", $text );
755 - $out = '';
 765+ $lines = explode ( "\n" , $text );
756766 $td_history = array (); // Is currently a td tag open?
757767 $last_tag_history = array (); // Save history of last lag activated (td, th or caption)
758768 $tr_history = array (); // Is currently a tr tag open?
759769 $tr_attributes = array (); // history of tr attributes
760770 $has_opened_tr = array(); // Did this table open a <tr> element?
761771 $indent_level = 0; // indent level of the table
 772+ foreach ( $lines as $key => $line )
 773+ {
 774+ $line = trim ( $line );
762775
763 - foreach ( $lines as $outLine ) {
764 - $line = trim( $outLine );
765 -
766776 if( $line == '' ) { // empty line, go to next line
767 - $out .= "\n";
768777 continue;
769778 }
770 - $first_character = $line[0];
 779+ $first_character = $line{0};
771780 $matches = array();
772781
773 - if ( preg_match( '/^(:*)\{\|(.*)$/', $line , $matches ) ) {
 782+ if ( preg_match( '/^(:*)\{\|(.*)$/' , $line , $matches ) ) {
774783 // First check if we are starting a new table
775784 $indent_level = strlen( $matches[1] );
776785
777786 $attributes = $this->mStripState->unstripBoth( $matches[2] );
778787 $attributes = Sanitizer::fixTagAttributes ( $attributes , 'table' );
779788
780 - $outLine = str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>";
 789+ $lines[$key] = str_repeat( '<dl><dd>' , $indent_level ) . "<table{$attributes}>";
781790 array_push ( $td_history , false );
782791 array_push ( $last_tag_history , '' );
783792 array_push ( $tr_history , false );
@@ -784,9 +793,8 @@
785794 array_push ( $has_opened_tr , false );
786795 } else if ( count ( $td_history ) == 0 ) {
787796 // Don't do any of the following
788 - $out .= $outLine."\n";
789797 continue;
790 - } else if ( substr ( $line , 0 , 2 ) === '|}' ) {
 798+ } else if ( substr ( $line , 0 , 2 ) == '|}' ) {
791799 // We are ending a table
792800 $line = '</table>' . substr ( $line , 2 );
793801 $last_tag = array_pop ( $last_tag_history );
@@ -803,8 +811,8 @@
804812 $line = "</{$last_tag}>{$line}";
805813 }
806814 array_pop ( $tr_attributes );
807 - $outLine = $line . str_repeat( '</dd></dl>' , $indent_level );
808 - } else if ( substr ( $line , 0 , 2 ) === '|-' ) {
 815+ $lines[$key] = $line . str_repeat( '</dd></dl>' , $indent_level );
 816+ } else if ( substr ( $line , 0 , 2 ) == '|-' ) {
809817 // Now we have a table row
810818 $line = preg_replace( '#^\|-+#', '', $line );
811819
@@ -827,21 +835,21 @@
828836 $line = "</{$last_tag}>{$line}";
829837 }
830838
831 - $outLine = $line;
 839+ $lines[$key] = $line;
832840 array_push ( $tr_history , false );
833841 array_push ( $td_history , false );
834842 array_push ( $last_tag_history , '' );
835843 }
836 - else if ( $first_character === '|' || $first_character === '!' || substr ( $line , 0 , 2 ) === '|+' ) {
 844+ else if ( $first_character == '|' || $first_character == '!' || substr ( $line , 0 , 2 ) == '|+' ) {
837845 // This might be cell elements, td, th or captions
838 - if ( substr ( $line , 0 , 2 ) === '|+' ) {
 846+ if ( substr ( $line , 0 , 2 ) == '|+' ) {
839847 $first_character = '+';
840848 $line = substr ( $line , 1 );
841849 }
842850
843851 $line = substr ( $line , 1 );
844852
845 - if ( $first_character === '!' ) {
 853+ if ( $first_character == '!' ) {
846854 $line = str_replace ( '!!' , '||' , $line );
847855 }
848856
@@ -851,13 +859,13 @@
852860 // attribute values containing literal "||".
853861 $cells = StringUtils::explodeMarkup( '||' , $line );
854862
855 - $outLine = '';
 863+ $lines[$key] = '';
856864
857865 // Loop through each table cell
858866 foreach ( $cells as $cell )
859867 {
860868 $previous = '';
861 - if ( $first_character !== '+' )
 869+ if ( $first_character != '+' )
862870 {
863871 $tr_after = array_pop ( $tr_attributes );
864872 if ( !array_pop ( $tr_history ) ) {
@@ -875,11 +883,11 @@
876884 $previous = "</{$last_tag}>{$previous}";
877885 }
878886
879 - if ( $first_character === '|' ) {
 887+ if ( $first_character == '|' ) {
880888 $last_tag = 'td';
881 - } else if ( $first_character === '!' ) {
 889+ } else if ( $first_character == '!' ) {
882890 $last_tag = 'th';
883 - } else if ( $first_character === '+' ) {
 891+ } else if ( $first_character == '+' ) {
884892 $last_tag = 'caption';
885893 } else {
886894 $last_tag = '';
@@ -902,42 +910,38 @@
903911 $cell = "{$previous}<{$last_tag}{$attributes}>{$cell_data[1]}";
904912 }
905913
906 - $outLine .= $cell;
 914+ $lines[$key] .= $cell;
907915 array_push ( $td_history , true );
908916 }
909917 }
910 - $out .= $outLine . "\n";
911918 }
912919
913920 // Closing open td, tr && table
914921 while ( count ( $td_history ) > 0 )
915922 {
916923 if ( array_pop ( $td_history ) ) {
917 - $out .= "</td>\n";
 924+ $lines[] = '</td>' ;
918925 }
919926 if ( array_pop ( $tr_history ) ) {
920 - $out .= "</tr>\n";
 927+ $lines[] = '</tr>' ;
921928 }
922929 if ( !array_pop ( $has_opened_tr ) ) {
923 - $out .= "<tr><td></td></tr>\n" ;
 930+ $lines[] = "<tr><td></td></tr>" ;
924931 }
925932
926 - $out .= "</table>\n";
 933+ $lines[] = '</table>' ;
927934 }
928935
929 - // Remove trailing line-ending (b/c)
930 - if ( substr( $out, -1 ) === "\n" ) {
931 - $out = substr( $out, 0, -1 );
932 - }
 936+ $output = implode ( "\n" , $lines ) ;
933937
934938 // special case: don't return empty table
935 - if( $out === "<table>\n<tr><td></td></tr>\n</table>" ) {
936 - $out = '';
 939+ if( $output == "<table>\n<tr><td></td></tr>\n</table>" ) {
 940+ $output = '';
937941 }
938942
939 - wfProfileOut( __METHOD__ );
 943+ wfProfileOut( $fname );
940944
941 - return $out;
 945+ return $output;
942946 }
943947
944948 /**
@@ -948,11 +952,12 @@
949953 */
950954 function internalParse( $text ) {
951955 $isMain = true;
952 - wfProfileIn( __METHOD__ );
 956+ $fname = 'Parser::internalParse';
 957+ wfProfileIn( $fname );
953958
954959 # Hook to suspend the parser in this state
955960 if ( !wfRunHooks( 'ParserBeforeInternalParse', array( &$this, &$text, &$this->mStripState ) ) ) {
956 - wfProfileOut( __METHOD__ );
 961+ wfProfileOut( $fname );
957962 return $text ;
958963 }
959964
@@ -985,7 +990,7 @@
986991 $text = $this->doMagicLinks( $text );
987992 $text = $this->formatHeadings( $text, $isMain );
988993
989 - wfProfileOut( __METHOD__ );
 994+ wfProfileOut( $fname );
990995 return $text;
991996 }
992997
@@ -1013,10 +1018,10 @@
10141019 }
10151020
10161021 function magicLinkCallback( $m ) {
1017 - if ( substr( $m[0], 0, 1 ) === '<' ) {
 1022+ if ( substr( $m[0], 0, 1 ) == '<' ) {
10181023 # Skip HTML element
10191024 return $m[0];
1020 - } elseif ( substr( $m[0], 0, 4 ) === 'ISBN' ) {
 1025+ } elseif ( substr( $m[0], 0, 4 ) == 'ISBN' ) {
10211026 $isbn = $m[2];
10221027 $num = strtr( $isbn, array(
10231028 '-' => '',
@@ -1028,11 +1033,11 @@
10291034 $titleObj->escapeLocalUrl() .
10301035 "\" class=\"internal\">ISBN $isbn</a>";
10311036 } else {
1032 - if ( substr( $m[0], 0, 3 ) === 'RFC' ) {
 1037+ if ( substr( $m[0], 0, 3 ) == 'RFC' ) {
10331038 $keyword = 'RFC';
10341039 $urlmsg = 'rfcurl';
10351040 $id = $m[1];
1036 - } elseif ( substr( $m[0], 0, 4 ) === 'PMID' ) {
 1041+ } elseif ( substr( $m[0], 0, 4 ) == 'PMID' ) {
10371042 $keyword = 'PMID';
10381043 $urlmsg = 'pubmedurl';
10391044 $id = $m[1];
@@ -1054,14 +1059,15 @@
10551060 *
10561061 * @private
10571062 */
1058 - static function doHeadings( $text ) {
1059 - wfProfileIn( __METHOD__ );
 1063+ function doHeadings( $text ) {
 1064+ $fname = 'Parser::doHeadings';
 1065+ wfProfileIn( $fname );
10601066 for ( $i = 6; $i >= 1; --$i ) {
10611067 $h = str_repeat( '=', $i );
10621068 $text = preg_replace( "/^$h(.+)$h\\s*$/m",
10631069 "<h$i>\\1</h$i>", $text );
10641070 }
1065 - wfProfileOut( __METHOD__ );
 1071+ wfProfileOut( $fname );
10661072 return $text;
10671073 }
10681074
@@ -1070,22 +1076,23 @@
10711077 * @private
10721078 * @return string the altered text
10731079 */
1074 - static function doAllQuotes( $text ) {
1075 - wfProfileIn( __METHOD__ );
 1080+ function doAllQuotes( $text ) {
 1081+ $fname = 'Parser::doAllQuotes';
 1082+ wfProfileIn( $fname );
10761083 $outtext = '';
1077 - $lines = StringUtils::explode( "\n", $text );
 1084+ $lines = explode( "\n", $text );
10781085 foreach ( $lines as $line ) {
1079 - $outtext .= self::doQuotes( $line ) . "\n";
 1086+ $outtext .= $this->doQuotes ( $line ) . "\n";
10801087 }
10811088 $outtext = substr($outtext, 0,-1);
1082 - wfProfileOut( __METHOD__ );
 1089+ wfProfileOut( $fname );
10831090 return $outtext;
10841091 }
10851092
10861093 /**
10871094 * Helper function for doAllQuotes()
10881095 */
1089 - public static function doQuotes( $text ) {
 1096+ public function doQuotes( $text ) {
10901097 $arr = preg_split( "/(''+)/", $text, -1, PREG_SPLIT_DELIM_CAPTURE );
10911098 if ( count( $arr ) == 1 )
10921099 return $text;
@@ -1140,9 +1147,9 @@
11411148 {
11421149 $x1 = substr ($arr[$i-1], -1);
11431150 $x2 = substr ($arr[$i-1], -2, 1);
1144 - if ($x1 === ' ') {
 1151+ if ($x1 == ' ') {
11451152 if ($firstspace == -1) $firstspace = $i;
1146 - } else if ($x2 === ' ') {
 1153+ } else if ($x2 == ' ') {
11471154 if ($firstsingleletterword == -1) $firstsingleletterword = $i;
11481155 } else {
11491156 if ($firstmultiletterword == -1) $firstmultiletterword = $i;
@@ -1182,7 +1189,7 @@
11831190 {
11841191 if (($i % 2) == 0)
11851192 {
1186 - if ($state === 'both')
 1193+ if ($state == 'both')
11871194 $buffer .= $r;
11881195 else
11891196 $output .= $r;
@@ -1191,41 +1198,41 @@
11921199 {
11931200 if (strlen ($r) == 2)
11941201 {
1195 - if ($state === 'i')
 1202+ if ($state == 'i')
11961203 { $output .= '</i>'; $state = ''; }
1197 - else if ($state === 'bi')
 1204+ else if ($state == 'bi')
11981205 { $output .= '</i>'; $state = 'b'; }
1199 - else if ($state === 'ib')
 1206+ else if ($state == 'ib')
12001207 { $output .= '</b></i><b>'; $state = 'b'; }
1201 - else if ($state === 'both')
 1208+ else if ($state == 'both')
12021209 { $output .= '<b><i>'.$buffer.'</i>'; $state = 'b'; }
12031210 else # $state can be 'b' or ''
12041211 { $output .= '<i>'; $state .= 'i'; }
12051212 }
12061213 else if (strlen ($r) == 3)
12071214 {
1208 - if ($state === 'b')
 1215+ if ($state == 'b')
12091216 { $output .= '</b>'; $state = ''; }
1210 - else if ($state === 'bi')
 1217+ else if ($state == 'bi')
12111218 { $output .= '</i></b><i>'; $state = 'i'; }
1212 - else if ($state === 'ib')
 1219+ else if ($state == 'ib')
12131220 { $output .= '</b>'; $state = 'i'; }
1214 - else if ($state === 'both')
 1221+ else if ($state == 'both')
12151222 { $output .= '<i><b>'.$buffer.'</b>'; $state = 'i'; }
12161223 else # $state can be 'i' or ''
12171224 { $output .= '<b>'; $state .= 'b'; }
12181225 }
12191226 else if (strlen ($r) == 5)
12201227 {
1221 - if ($state === 'b')
 1228+ if ($state == 'b')
12221229 { $output .= '</b><i>'; $state = 'i'; }
1223 - else if ($state === 'i')
 1230+ else if ($state == 'i')
12241231 { $output .= '</i><b>'; $state = 'b'; }
1225 - else if ($state === 'bi')
 1232+ else if ($state == 'bi')
12261233 { $output .= '</i></b>'; $state = ''; }
1227 - else if ($state === 'ib')
 1234+ else if ($state == 'ib')
12281235 { $output .= '</b></i>'; $state = ''; }
1229 - else if ($state === 'both')
 1236+ else if ($state == 'both')
12301237 { $output .= '<i><b>'.$buffer.'</b></i>'; $state = ''; }
12311238 else # ($state == '')
12321239 { $buffer = ''; $state = 'both'; }
@@ -1234,14 +1241,14 @@
12351242 $i++;
12361243 }
12371244 # Now close all remaining tags. Notice that the order is important.
1238 - if ($state === 'b' || $state === 'ib')
 1245+ if ($state == 'b' || $state == 'ib')
12391246 $output .= '</b>';
1240 - if ($state === 'i' || $state === 'bi' || $state === 'ib')
 1247+ if ($state == 'i' || $state == 'bi' || $state == 'ib')
12411248 $output .= '</i>';
1242 - if ($state === 'bi')
 1249+ if ($state == 'bi')
12431250 $output .= '</b>';
12441251 # There might be lonely ''''', so make sure we have a buffer
1245 - if ($state === 'both' && $buffer)
 1252+ if ($state == 'both' && $buffer)
12461253 $output .= '<b><i>'.$buffer.'</i></b>';
12471254 return $output;
12481255 }
@@ -1257,7 +1264,8 @@
12581265 */
12591266 function replaceExternalLinks( $text ) {
12601267 global $wgContLang;
1261 - wfProfileIn( __METHOD__ );
 1268+ $fname = 'Parser::replaceExternalLinks';
 1269+ wfProfileIn( $fname );
12621270
12631271 $sk = $this->mOptions->getSkin();
12641272
@@ -1291,7 +1299,7 @@
12921300 $dtrail = '';
12931301
12941302 # Set linktype for CSS - if URL==text, link is essentially free
1295 - $linktype = ($text === $url) ? 'free' : 'text';
 1303+ $linktype = ($text == $url) ? 'free' : 'text';
12961304
12971305 # No link text, e.g. [http://domain.tld/some.link]
12981306 if ( $text == '' ) {
@@ -1327,11 +1335,11 @@
13281336 # Register link in the output object.
13291337 # Replace unnecessary URL escape codes with the referenced character
13301338 # This prevents spammers from hiding links from the filters
1331 - $pasteurized = self::replaceUnusualEscapes( $url );
 1339+ $pasteurized = Parser::replaceUnusualEscapes( $url );
13321340 $this->mOutput->addExternalLink( $pasteurized );
13331341 }
13341342
1335 - wfProfileOut( __METHOD__ );
 1343+ wfProfileOut( $fname );
13361344 return $s;
13371345 }
13381346
@@ -1341,7 +1349,8 @@
13421350 */
13431351 function replaceFreeExternalLinks( $text ) {
13441352 global $wgContLang;
1345 - wfProfileIn( __METHOD__ );
 1353+ $fname = 'Parser::replaceFreeExternalLinks';
 1354+ wfProfileIn( $fname );
13461355
13471356 $bits = preg_split( '/(\b(?:' . wfUrlProtocols() . '))/S', $text, -1, PREG_SPLIT_DELIM_CAPTURE );
13481357 $s = array_shift( $bits );
@@ -1403,7 +1412,7 @@
14041413 $text = $sk->makeExternalLink( $url, $wgContLang->markNoConversion($url), true, 'free', $this->mTitle->getNamespace() );
14051414 # Register it in the output object...
14061415 # Replace unnecessary URL escape codes with their equivalent characters
1407 - $pasteurized = self::replaceUnusualEscapes( $url );
 1416+ $pasteurized = Parser::replaceUnusualEscapes( $url );
14081417 $this->mOutput->addExternalLink( $pasteurized );
14091418 }
14101419 $s .= $text . $trail;
@@ -1411,7 +1420,7 @@
14121421 $s .= $protocol . $remainder;
14131422 }
14141423 }
1415 - wfProfileOut( __METHOD__ );
 1424+ wfProfileOut( $fname );
14161425 return $s;
14171426 }
14181427
@@ -1427,7 +1436,7 @@
14281437 */
14291438 static function replaceUnusualEscapes( $url ) {
14301439 return preg_replace_callback( '/%[0-9A-Fa-f]{2}/',
1431 - array( __CLASS__, 'replaceUnusualEscapesCallback' ), $url );
 1440+ array( 'Parser', 'replaceUnusualEscapesCallback' ), $url );
14321441 }
14331442
14341443 /**
@@ -1471,48 +1480,35 @@
14721481
14731482 /**
14741483 * Process [[ ]] wikilinks
1475 - * @return processed text
14761484 *
14771485 * @private
14781486 */
14791487 function replaceInternalLinks( $s ) {
1480 - $this->mLinkHolders->merge( $this->replaceInternalLinks2( $s ) );
1481 - return $s;
1482 - }
1483 -
1484 - /**
1485 - * Process [[ ]] wikilinks
1486 - * @return LinkHolderArray
1487 - *
1488 - * @private
1489 - */
1490 - function replaceInternalLinks2( &$s ) {
14911488 global $wgContLang;
 1489+ static $fname = 'Parser::replaceInternalLinks' ;
14921490
1493 - wfProfileIn( __METHOD__ );
 1491+ wfProfileIn( $fname );
14941492
1495 - wfProfileIn( __METHOD__.'-setup' );
1496 - static $tc = FALSE, $e1, $e1_img;
 1493+ wfProfileIn( $fname.'-setup' );
 1494+ static $tc = FALSE;
14971495 # the % is needed to support urlencoded titles as well
1498 - if ( !$tc ) {
1499 - $tc = Title::legalChars() . '#%';
1500 - # Match a link having the form [[namespace:link|alternate]]trail
1501 - $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD";
1502 - # Match cases where there is no "]]", which might still be images
1503 - $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD";
1504 - }
 1496+ if ( !$tc ) { $tc = Title::legalChars() . '#%'; }
15051497
15061498 $sk = $this->mOptions->getSkin();
1507 - $holders = new LinkHolderArray( $this );
15081499
15091500 #split the entire text string on occurences of [[
1510 - $a = StringUtils::explode( '[[', ' ' . $s );
 1501+ $a = explode( '[[', ' ' . $s );
15111502 #get the first element (all text up to first [[), and remove the space we added
1512 - $s = $a->current();
1513 - $a->next();
1514 - $line = $a->current(); # Workaround for broken ArrayIterator::next() that returns "void"
 1503+ $s = array_shift( $a );
15151504 $s = substr( $s, 1 );
15161505
 1506+ # Match a link having the form [[namespace:link|alternate]]trail
 1507+ static $e1 = FALSE;
 1508+ if ( !$e1 ) { $e1 = "/^([{$tc}]+)(?:\\|(.+?))?]](.*)\$/sD"; }
 1509+ # Match cases where there is no "]]", which might still be images
 1510+ static $e1_img = FALSE;
 1511+ if ( !$e1_img ) { $e1_img = "/^([{$tc}]+)\\|(.*)\$/sD"; }
 1512+
15171513 $useLinkPrefixExtension = $wgContLang->linkPrefixExtension();
15181514 $e2 = null;
15191515 if ( $useLinkPrefixExtension ) {
@@ -1522,8 +1518,8 @@
15231519 }
15241520
15251521 if( is_null( $this->mTitle ) ) {
1526 - wfProfileOut( __METHOD__.'-setup' );
1527 - wfProfileOut( __METHOD__ );
 1522+ wfProfileOut( $fname );
 1523+ wfProfileOut( $fname.'-setup' );
15281524 throw new MWException( __METHOD__.": \$this->mTitle is null\n" );
15291525 }
15301526 $nottalk = !$this->mTitle->isTalkPage();
@@ -1545,20 +1541,13 @@
15461542 $selflink = array($this->mTitle->getPrefixedText());
15471543 }
15481544 $useSubpages = $this->areSubpagesAllowed();
1549 - wfProfileOut( __METHOD__.'-setup' );
 1545+ wfProfileOut( $fname.'-setup' );
15501546
15511547 # Loop for each link
1552 - for ( ; $line !== false && $line !== null ; $a->next(), $line = $a->current() ) {
1553 - # Check for excessive memory usage
1554 - if ( $holders->isBig() ) {
1555 - # Too big
1556 - # Do the existence check, replace the link holders and clear the array
1557 - $holders->replace( $s );
1558 - $holders->clear();
1559 - }
1560 -
 1548+ for ($k = 0; isset( $a[$k] ); $k++) {
 1549+ $line = $a[$k];
15611550 if ( $useLinkPrefixExtension ) {
1562 - wfProfileIn( __METHOD__.'-prefixhandling' );
 1551+ wfProfileIn( $fname.'-prefixhandling' );
15631552 if ( preg_match( $e2, $s, $m ) ) {
15641553 $prefix = $m[2];
15651554 $s = $m[1];
@@ -1570,12 +1559,12 @@
15711560 $prefix = $first_prefix;
15721561 $first_prefix = false;
15731562 }
1574 - wfProfileOut( __METHOD__.'-prefixhandling' );
 1563+ wfProfileOut( $fname.'-prefixhandling' );
15751564 }
15761565
15771566 $might_be_img = false;
15781567
1579 - wfProfileIn( __METHOD__."-e1" );
 1568+ wfProfileIn( "$fname-e1" );
15801569 if ( preg_match( $e1, $line, $m ) ) { # page with normal text or alt
15811570 $text = $m[2];
15821571 # If we get a ] at the beginning of $m[3] that means we have a link that's something like:
@@ -1609,18 +1598,18 @@
16101599 $trail = "";
16111600 } else { # Invalid form; output directly
16121601 $s .= $prefix . '[[' . $line ;
1613 - wfProfileOut( __METHOD__."-e1" );
 1602+ wfProfileOut( "$fname-e1" );
16141603 continue;
16151604 }
1616 - wfProfileOut( __METHOD__."-e1" );
1617 - wfProfileIn( __METHOD__."-misc" );
 1605+ wfProfileOut( "$fname-e1" );
 1606+ wfProfileIn( "$fname-misc" );
16181607
16191608 # Don't allow internal links to pages containing
16201609 # PROTO: where PROTO is a valid URL protocol; these
16211610 # should be external links.
16221611 if (preg_match('/^\b(?:' . wfUrlProtocols() . ')/', $m[1])) {
16231612 $s .= $prefix . '[[' . $line ;
1624 - wfProfileOut( __METHOD__."-misc" );
 1613+ wfProfileOut( "$fname-misc" );
16251614 continue;
16261615 }
16271616
@@ -1631,36 +1620,33 @@
16321621 $link = $m[1];
16331622 }
16341623
1635 - $noforce = (substr($m[1], 0, 1) !== ':');
 1624+ $noforce = (substr($m[1], 0, 1) != ':');
16361625 if (!$noforce) {
16371626 # Strip off leading ':'
16381627 $link = substr($link, 1);
16391628 }
16401629
1641 - wfProfileOut( __METHOD__."-misc" );
1642 - wfProfileIn( __METHOD__."-title" );
 1630+ wfProfileOut( "$fname-misc" );
 1631+ wfProfileIn( "$fname-title" );
16431632 $nt = Title::newFromText( $this->mStripState->unstripNoWiki($link) );
16441633 if( !$nt ) {
16451634 $s .= $prefix . '[[' . $line;
1646 - wfProfileOut( __METHOD__."-title" );
 1635+ wfProfileOut( "$fname-title" );
16471636 continue;
16481637 }
16491638
16501639 $ns = $nt->getNamespace();
16511640 $iw = $nt->getInterWiki();
1652 - wfProfileOut( __METHOD__."-title" );
 1641+ wfProfileOut( "$fname-title" );
16531642
16541643 if ($might_be_img) { # if this is actually an invalid link
1655 - wfProfileIn( __METHOD__."-might_be_img" );
 1644+ wfProfileIn( "$fname-might_be_img" );
16561645 if ($ns == NS_IMAGE && $noforce) { #but might be an image
16571646 $found = false;
1658 - while ( true ) {
 1647+ while (isset ($a[$k+1]) ) {
16591648 #look at the next 'line' to see if we can close it there
1660 - $a->next();
1661 - $next_line = $a->current();
1662 - if ( $next_line === false || $next_line === null ) {
1663 - break;
1664 - }
 1649+ $spliced = array_splice( $a, $k + 1, 1 );
 1650+ $next_line = array_shift( $spliced );
16651651 $m = explode( ']]', $next_line, 3 );
16661652 if ( count( $m ) == 3 ) {
16671653 # the first ]] closes the inner link, the second the image
@@ -1680,19 +1666,19 @@
16811667 if ( !$found ) {
16821668 # we couldn't find the end of this imageLink, so output it raw
16831669 #but don't ignore what might be perfectly normal links in the text we've examined
1684 - $holders->merge( $this->replaceInternalLinks2( $text ) );
 1670+ $text = $this->replaceInternalLinks($text);
16851671 $s .= "{$prefix}[[$link|$text";
16861672 # note: no $trail, because without an end, there *is* no trail
1687 - wfProfileOut( __METHOD__."-might_be_img" );
 1673+ wfProfileOut( "$fname-might_be_img" );
16881674 continue;
16891675 }
16901676 } else { #it's not an image, so output it raw
16911677 $s .= "{$prefix}[[$link|$text";
16921678 # note: no $trail, because without an end, there *is* no trail
1693 - wfProfileOut( __METHOD__."-might_be_img" );
 1679+ wfProfileOut( "$fname-might_be_img" );
16941680 continue;
16951681 }
1696 - wfProfileOut( __METHOD__."-might_be_img" );
 1682+ wfProfileOut( "$fname-might_be_img" );
16971683 }
16981684
16991685 $wasblank = ( '' == $text );
@@ -1702,36 +1688,41 @@
17031689 if( $noforce ) {
17041690
17051691 # Interwikis
1706 - wfProfileIn( __METHOD__."-interwiki" );
 1692+ wfProfileIn( "$fname-interwiki" );
17071693 if( $iw && $this->mOptions->getInterwikiMagic() && $nottalk && $wgContLang->getLanguageName( $iw ) ) {
17081694 $this->mOutput->addLanguageLink( $nt->getFullText() );
17091695 $s = rtrim($s . $prefix);
17101696 $s .= trim($trail, "\n") == '' ? '': $prefix . $trail;
1711 - wfProfileOut( __METHOD__."-interwiki" );
 1697+ wfProfileOut( "$fname-interwiki" );
17121698 continue;
17131699 }
1714 - wfProfileOut( __METHOD__."-interwiki" );
 1700+ wfProfileOut( "$fname-interwiki" );
17151701
17161702 if ( $ns == NS_IMAGE ) {
1717 - wfProfileIn( __METHOD__."-image" );
 1703+ wfProfileIn( "$fname-image" );
17181704 if ( !wfIsBadImage( $nt->getDBkey(), $this->mTitle ) ) {
17191705 # recursively parse links inside the image caption
17201706 # actually, this will parse them in any other parameters, too,
17211707 # but it might be hard to fix that, and it doesn't matter ATM
17221708 $text = $this->replaceExternalLinks($text);
1723 - $holders->merge( $this->replaceInternalLinks2( $text ) );
 1709+ $text = $this->replaceInternalLinks($text);
17241710
17251711 # cloak any absolute URLs inside the image markup, so replaceExternalLinks() won't touch them
1726 - $s .= $prefix . $this->armorLinks( $this->makeImage( $nt, $text, $holders ) ) . $trail;
 1712+ $s .= $prefix . $this->armorLinks( $this->makeImage( $nt, $text ) ) . $trail;
 1713+ $this->mOutput->addImage( $nt->getDBkey() );
 1714+
 1715+ wfProfileOut( "$fname-image" );
 1716+ continue;
 1717+ } else {
 1718+ # We still need to record the image's presence on the page
 1719+ $this->mOutput->addImage( $nt->getDBkey() );
17271720 }
1728 - $this->mOutput->addImage( $nt->getDBkey() );
1729 - wfProfileOut( __METHOD__."-image" );
1730 - continue;
 1721+ wfProfileOut( "$fname-image" );
17311722
17321723 }
17331724
17341725 if ( $ns == NS_CATEGORY ) {
1735 - wfProfileIn( __METHOD__."-category" );
 1726+ wfProfileIn( "$fname-category" );
17361727 $s = rtrim($s . "\n"); # bug 87
17371728
17381729 if ( $wasblank ) {
@@ -1750,7 +1741,7 @@
17511742 */
17521743 $s .= trim($prefix . $trail, "\n") == '' ? '': $prefix . $trail;
17531744
1754 - wfProfileOut( __METHOD__."-category" );
 1745+ wfProfileOut( "$fname-category" );
17551746 continue;
17561747 }
17571748 }
@@ -1781,7 +1772,7 @@
17821773 if( SpecialPage::exists( $nt->getDBkey() ) ) {
17831774 $s .= $this->makeKnownLinkHolder( $nt, $text, '', $trail, $prefix );
17841775 } else {
1785 - $s .= $holders->makeHolder( $nt, $text, '', $trail, $prefix );
 1776+ $s .= $this->makeLinkHolder( $nt, $text, '', $trail, $prefix );
17861777 }
17871778 continue;
17881779 } elseif( $ns == NS_IMAGE ) {
@@ -1795,10 +1786,10 @@
17961787 continue;
17971788 }
17981789 }
1799 - $s .= $holders->makeHolder( $nt, $text, '', $trail, $prefix );
 1790+ $s .= $this->makeLinkHolder( $nt, $text, '', $trail, $prefix );
18001791 }
1801 - wfProfileOut( __METHOD__ );
1802 - return $holders;
 1792+ wfProfileOut( $fname );
 1793+ return $s;
18031794 }
18041795
18051796 /**
@@ -1807,10 +1798,32 @@
18081799 * parsing of interwiki links, and secondly to allow all existence checks and
18091800 * article length checks (for stub links) to be bundled into a single query.
18101801 *
1811 - * @deprecated
18121802 */
18131803 function makeLinkHolder( &$nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
1814 - return $this->mLinkHolders->makeHolder( $nt, $text, $query, $trail, $prefix );
 1804+ wfProfileIn( __METHOD__ );
 1805+ if ( ! is_object($nt) ) {
 1806+ # Fail gracefully
 1807+ $retVal = "<!-- ERROR -->{$prefix}{$text}{$trail}";
 1808+ } else {
 1809+ # Separate the link trail from the rest of the link
 1810+ list( $inside, $trail ) = Linker::splitTrail( $trail );
 1811+
 1812+ if ( $nt->isExternal() ) {
 1813+ $nr = array_push( $this->mInterwikiLinkHolders['texts'], $prefix.$text.$inside );
 1814+ $this->mInterwikiLinkHolders['titles'][] = $nt;
 1815+ $retVal = '<!--IWLINK '. ($nr-1) ."-->{$trail}";
 1816+ } else {
 1817+ $nr = array_push( $this->mLinkHolders['namespaces'], $nt->getNamespace() );
 1818+ $this->mLinkHolders['dbkeys'][] = $nt->getDBkey();
 1819+ $this->mLinkHolders['queries'][] = $query;
 1820+ $this->mLinkHolders['texts'][] = $prefix.$text.$inside;
 1821+ $this->mLinkHolders['titles'][] = $nt;
 1822+
 1823+ $retVal = '<!--LINK '. ($nr-1) ."-->{$trail}";
 1824+ }
 1825+ }
 1826+ wfProfileOut( __METHOD__ );
 1827+ return $retVal;
18151828 }
18161829
18171830 /**
@@ -1876,7 +1889,8 @@
18771890 # ../ -- convert to CurrentPage, from CurrentPage/CurrentSubPage
18781891 # ../Foobar -- convert to CurrentPage/Foobar, from CurrentPage/CurrentSubPage
18791892
1880 - wfProfileIn( __METHOD__ );
 1893+ $fname = 'Parser::maybeDoSubpageLink';
 1894+ wfProfileIn( $fname );
18811895 $ret = $target; # default return value is no change
18821896
18831897 # Some namespaces don't allow subpages,
@@ -1892,7 +1906,7 @@
18931907 # bug 7425
18941908 $target = trim( $target );
18951909 # Look at the first character
1896 - if( $target != '' && $target{0} === '/' ) {
 1910+ if( $target != '' && $target{0} == '/' ) {
18971911 # / at end means we don't want the slash to be shown
18981912 $m = array();
18991913 $trailingSlashes = preg_match_all( '%(/+)$%', $target, $m );
@@ -1919,7 +1933,7 @@
19201934 if( count( $exploded ) > $dotdotcount ) { # not allowed to go below top level page
19211935 $ret = implode( '/', array_slice( $exploded, 0, -$dotdotcount ) );
19221936 # / at the end means don't show full path
1923 - if( substr( $nodotdot, -1, 1 ) === '/' ) {
 1937+ if( substr( $nodotdot, -1, 1 ) == '/' ) {
19241938 $nodotdot = substr( $nodotdot, 0, -1 );
19251939 if( '' === $text ) {
19261940 $text = $nodotdot . $suffix;
@@ -1935,7 +1949,7 @@
19361950 }
19371951 }
19381952
1939 - wfProfileOut( __METHOD__ );
 1953+ wfProfileOut( $fname );
19401954 return $ret;
19411955 }
19421956
@@ -1955,7 +1969,7 @@
19561970 # getCommon() returns the length of the longest common substring
19571971 # of both arguments, starting at the beginning of both.
19581972 #
1959 - /* private */ static function getCommon( $st1, $st2 ) {
 1973+ /* private */ function getCommon( $st1, $st2 ) {
19601974 $fl = strlen( $st1 );
19611975 $shorter = strlen( $st2 );
19621976 if ( $fl < $shorter ) { $shorter = $fl; }
@@ -1971,10 +1985,10 @@
19721986 /* private */ function openList( $char ) {
19731987 $result = $this->closeParagraph();
19741988
1975 - if ( '*' === $char ) { $result .= '<ul><li>'; }
1976 - else if ( '#' === $char ) { $result .= '<ol><li>'; }
1977 - else if ( ':' === $char ) { $result .= '<dl><dd>'; }
1978 - else if ( ';' === $char ) {
 1989+ if ( '*' == $char ) { $result .= '<ul><li>'; }
 1990+ else if ( '#' == $char ) { $result .= '<ol><li>'; }
 1991+ else if ( ':' == $char ) { $result .= '<dl><dd>'; }
 1992+ else if ( ';' == $char ) {
19791993 $result .= '<dl><dt>';
19801994 $this->mDTopen = true;
19811995 }
@@ -1984,11 +1998,11 @@
19851999 }
19862000
19872001 /* private */ function nextItem( $char ) {
1988 - if ( '*' === $char || '#' === $char ) { return '</li><li>'; }
1989 - else if ( ':' === $char || ';' === $char ) {
 2002+ if ( '*' == $char || '#' == $char ) { return '</li><li>'; }
 2003+ else if ( ':' == $char || ';' == $char ) {
19902004 $close = '</dd>';
19912005 if ( $this->mDTopen ) { $close = '</dt>'; }
1992 - if ( ';' === $char ) {
 2006+ if ( ';' == $char ) {
19932007 $this->mDTopen = true;
19942008 return $close . '<dt>';
19952009 } else {
@@ -2000,9 +2014,9 @@
20012015 }
20022016
20032017 /* private */ function closeList( $char ) {
2004 - if ( '*' === $char ) { $text = '</li></ul>'; }
2005 - else if ( '#' === $char ) { $text = '</li></ol>'; }
2006 - else if ( ':' === $char ) {
 2018+ if ( '*' == $char ) { $text = '</li></ul>'; }
 2019+ else if ( '#' == $char ) { $text = '</li></ol>'; }
 2020+ else if ( ':' == $char ) {
20072021 if ( $this->mDTopen ) {
20082022 $this->mDTopen = false;
20092023 $text = '</dt></dl>';
@@ -2022,53 +2036,50 @@
20232037 * @return string the lists rendered as HTML
20242038 */
20252039 function doBlockLevels( $text, $linestart ) {
2026 - wfProfileIn( __METHOD__ );
 2040+ $fname = 'Parser::doBlockLevels';
 2041+ wfProfileIn( $fname );
20272042
20282043 # Parsing through the text line by line. The main thing
20292044 # happening here is handling of block-level elements p, pre,
20302045 # and making lists from lines starting with * # : etc.
20312046 #
2032 - $textLines = StringUtils::explode( "\n", $text );
 2047+ $textLines = explode( "\n", $text );
20332048
20342049 $lastPrefix = $output = '';
20352050 $this->mDTopen = $inBlockElem = false;
20362051 $prefixLength = 0;
20372052 $paragraphStack = false;
20382053
 2054+ if ( !$linestart ) {
 2055+ $output .= array_shift( $textLines );
 2056+ }
20392057 foreach ( $textLines as $oLine ) {
2040 - # Fix up $linestart
2041 - if ( !$linestart ) {
2042 - $output .= $oLine;
2043 - $linestart = true;
2044 - continue;
2045 - }
2046 -
20472058 $lastPrefixLength = strlen( $lastPrefix );
20482059 $preCloseMatch = preg_match('/<\\/pre/i', $oLine );
20492060 $preOpenMatch = preg_match('/<pre/i', $oLine );
20502061 if ( !$this->mInPre ) {
20512062 # Multiple prefixes may abut each other for nested lists.
20522063 $prefixLength = strspn( $oLine, '*#:;' );
2053 - $prefix = substr( $oLine, 0, $prefixLength );
 2064+ $pref = substr( $oLine, 0, $prefixLength );
20542065
20552066 # eh?
2056 - $prefix2 = str_replace( ';', ':', $prefix );
 2067+ $pref2 = str_replace( ';', ':', $pref );
20572068 $t = substr( $oLine, $prefixLength );
2058 - $this->mInPre = (bool)$preOpenMatch;
 2069+ $this->mInPre = !empty($preOpenMatch);
20592070 } else {
20602071 # Don't interpret any other prefixes in preformatted text
20612072 $prefixLength = 0;
2062 - $prefix = $prefix2 = '';
 2073+ $pref = $pref2 = '';
20632074 $t = $oLine;
20642075 }
20652076
20662077 # List generation
2067 - if( $prefixLength && $lastPrefix === $prefix2 ) {
 2078+ if( $prefixLength && 0 == strcmp( $lastPrefix, $pref2 ) ) {
20682079 # Same as the last item, so no need to deal with nesting or opening stuff
2069 - $output .= $this->nextItem( substr( $prefix, -1 ) );
 2080+ $output .= $this->nextItem( substr( $pref, -1 ) );
20702081 $paragraphStack = false;
20712082
2072 - if ( substr( $prefix, -1 ) === ';') {
 2083+ if ( substr( $pref, -1 ) == ';') {
20732084 # The one nasty exception: definition lists work like this:
20742085 # ; title : definition text
20752086 # So we check for : in the remainder text to split up the
@@ -2081,21 +2092,21 @@
20822093 }
20832094 } elseif( $prefixLength || $lastPrefixLength ) {
20842095 # Either open or close a level...
2085 - $commonPrefixLength = $this->getCommon( $prefix, $lastPrefix );
 2096+ $commonPrefixLength = $this->getCommon( $pref, $lastPrefix );
20862097 $paragraphStack = false;
20872098
20882099 while( $commonPrefixLength < $lastPrefixLength ) {
2089 - $output .= $this->closeList( $lastPrefix[$lastPrefixLength-1] );
 2100+ $output .= $this->closeList( $lastPrefix{$lastPrefixLength-1} );
20902101 --$lastPrefixLength;
20912102 }
20922103 if ( $prefixLength <= $commonPrefixLength && $commonPrefixLength > 0 ) {
2093 - $output .= $this->nextItem( $prefix[$commonPrefixLength-1] );
 2104+ $output .= $this->nextItem( $pref{$commonPrefixLength-1} );
20942105 }
20952106 while ( $prefixLength > $commonPrefixLength ) {
2096 - $char = substr( $prefix, $commonPrefixLength, 1 );
 2107+ $char = substr( $pref, $commonPrefixLength, 1 );
20972108 $output .= $this->openList( $char );
20982109
2099 - if ( ';' === $char ) {
 2110+ if ( ';' == $char ) {
21002111 # FIXME: This is dupe of code above
21012112 if ($this->findColonNoLinks($t, $term, $t2) !== false) {
21022113 $t = $t2;
@@ -2104,10 +2115,10 @@
21052116 }
21062117 ++$commonPrefixLength;
21072118 }
2108 - $lastPrefix = $prefix2;
 2119+ $lastPrefix = $pref2;
21092120 }
21102121 if( 0 == $prefixLength ) {
2111 - wfProfileIn( __METHOD__."-paragraph" );
 2122+ wfProfileIn( "$fname-paragraph" );
21122123 # No prefix (not in list)--go to paragraph mode
21132124 // XXX: use a stack for nestable elements like span, table and div
21142125 $openmatch = preg_match('/(?:<table|<blockquote|<h1|<h2|<h3|<h4|<h5|<h6|<pre|<tr|<p|<ul|<ol|<li|<\\/tr|<\\/td|<\\/th)/iS', $t );
@@ -2127,9 +2138,9 @@
21282139 $inBlockElem = true;
21292140 }
21302141 } else if ( !$inBlockElem && !$this->mInPre ) {
2131 - if ( ' ' == $t{0} and ( $this->mLastSection === 'pre' or trim($t) != '' ) ) {
 2142+ if ( ' ' == $t{0} and ( $this->mLastSection == 'pre' or trim($t) != '' ) ) {
21322143 // pre
2133 - if ($this->mLastSection !== 'pre') {
 2144+ if ($this->mLastSection != 'pre') {
21342145 $paragraphStack = false;
21352146 $output .= $this->closeParagraph().'<pre>';
21362147 $this->mLastSection = 'pre';
@@ -2143,7 +2154,7 @@
21442155 $paragraphStack = false;
21452156 $this->mLastSection = 'p';
21462157 } else {
2147 - if ($this->mLastSection !== 'p' ) {
 2158+ if ($this->mLastSection != 'p' ) {
21482159 $output .= $this->closeParagraph();
21492160 $this->mLastSection = '';
21502161 $paragraphStack = '<p>';
@@ -2156,14 +2167,14 @@
21572168 $output .= $paragraphStack;
21582169 $paragraphStack = false;
21592170 $this->mLastSection = 'p';
2160 - } else if ($this->mLastSection !== 'p') {
 2171+ } else if ($this->mLastSection != 'p') {
21612172 $output .= $this->closeParagraph().'<p>';
21622173 $this->mLastSection = 'p';
21632174 }
21642175 }
21652176 }
21662177 }
2167 - wfProfileOut( __METHOD__."-paragraph" );
 2178+ wfProfileOut( "$fname-paragraph" );
21682179 }
21692180 // somewhere above we forget to get out of pre block (bug 785)
21702181 if($preCloseMatch && $this->mInPre) {
@@ -2174,7 +2185,7 @@
21752186 }
21762187 }
21772188 while ( $prefixLength ) {
2178 - $output .= $this->closeList( $prefix2[$prefixLength-1] );
 2189+ $output .= $this->closeList( $pref2{$prefixLength-1} );
21792190 --$prefixLength;
21802191 }
21812192 if ( '' != $this->mLastSection ) {
@@ -2182,7 +2193,7 @@
21832194 $this->mLastSection = '';
21842195 }
21852196
2186 - wfProfileOut( __METHOD__ );
 2197+ wfProfileOut( $fname );
21872198 return $output;
21882199 }
21892200
@@ -2194,13 +2205,14 @@
21952206 * @param string &$after set to everything after the ':'
21962207 * return string the position of the ':', or false if none found
21972208 */
2198 - static function findColonNoLinks($str, &$before, &$after) {
2199 - wfProfileIn( __METHOD__ );
 2209+ function findColonNoLinks($str, &$before, &$after) {
 2210+ $fname = 'Parser::findColonNoLinks';
 2211+ wfProfileIn( $fname );
22002212
22012213 $pos = strpos( $str, ':' );
22022214 if( $pos === false ) {
22032215 // Nothing to find!
2204 - wfProfileOut( __METHOD__ );
 2216+ wfProfileOut( $fname );
22052217 return false;
22062218 }
22072219
@@ -2209,7 +2221,7 @@
22102222 // Easy; no tag nesting to worry about
22112223 $before = substr( $str, 0, $pos );
22122224 $after = substr( $str, $pos+1 );
2213 - wfProfileOut( __METHOD__ );
 2225+ wfProfileOut( $fname );
22142226 return $pos;
22152227 }
22162228
@@ -2233,7 +2245,7 @@
22342246 // We found it!
22352247 $before = substr( $str, 0, $i );
22362248 $after = substr( $str, $i + 1 );
2237 - wfProfileOut( __METHOD__ );
 2249+ wfProfileOut( $fname );
22382250 return $i;
22392251 }
22402252 // Embedded in a tag; don't break it.
@@ -2243,7 +2255,7 @@
22442256 $colon = strpos( $str, ':', $i );
22452257 if( $colon === false ) {
22462258 // Nothing else interesting
2247 - wfProfileOut( __METHOD__ );
 2259+ wfProfileOut( $fname );
22482260 return false;
22492261 }
22502262 $lt = strpos( $str, '<', $i );
@@ -2252,7 +2264,7 @@
22532265 // We found it!
22542266 $before = substr( $str, 0, $colon );
22552267 $after = substr( $str, $colon + 1 );
2256 - wfProfileOut( __METHOD__ );
 2268+ wfProfileOut( $fname );
22572269 return $i;
22582270 }
22592271 }
@@ -2299,18 +2311,18 @@
23002312 break;
23012313 case 3: // self::COLON_STATE_CLOSETAG:
23022314 // In a </tag>
2303 - if( $c === ">" ) {
 2315+ if( $c == ">" ) {
23042316 $stack--;
23052317 if( $stack < 0 ) {
2306 - wfDebug( __METHOD__.": Invalid input; too many close tags\n" );
2307 - wfProfileOut( __METHOD__ );
 2318+ wfDebug( "Invalid input in $fname; too many close tags\n" );
 2319+ wfProfileOut( $fname );
23082320 return false;
23092321 }
23102322 $state = self::COLON_STATE_TEXT;
23112323 }
23122324 break;
23132325 case self::COLON_STATE_TAGSLASH:
2314 - if( $c === ">" ) {
 2326+ if( $c == ">" ) {
23152327 // Yes, a self-closed tag <blah/>
23162328 $state = self::COLON_STATE_TEXT;
23172329 } else {
@@ -2319,33 +2331,33 @@
23202332 }
23212333 break;
23222334 case 5: // self::COLON_STATE_COMMENT:
2323 - if( $c === "-" ) {
 2335+ if( $c == "-" ) {
23242336 $state = self::COLON_STATE_COMMENTDASH;
23252337 }
23262338 break;
23272339 case self::COLON_STATE_COMMENTDASH:
2328 - if( $c === "-" ) {
 2340+ if( $c == "-" ) {
23292341 $state = self::COLON_STATE_COMMENTDASHDASH;
23302342 } else {
23312343 $state = self::COLON_STATE_COMMENT;
23322344 }
23332345 break;
23342346 case self::COLON_STATE_COMMENTDASHDASH:
2335 - if( $c === ">" ) {
 2347+ if( $c == ">" ) {
23362348 $state = self::COLON_STATE_TEXT;
23372349 } else {
23382350 $state = self::COLON_STATE_COMMENT;
23392351 }
23402352 break;
23412353 default:
2342 - throw new MWException( "State machine error in " . __METHOD__ );
 2354+ throw new MWException( "State machine error in $fname" );
23432355 }
23442356 }
23452357 if( $stack > 0 ) {
2346 - wfDebug( __METHOD__.": Invalid input; not enough close tags (stack $stack, state $state)\n" );
 2358+ wfDebug( "Invalid input in $fname; not enough close tags (stack $stack, state $state)\n" );
23472359 return false;
23482360 }
2349 - wfProfileOut( __METHOD__ );
 2361+ wfProfileOut( $fname );
23502362 return false;
23512363 }
23522364
@@ -2575,11 +2587,12 @@
25762588 * @private
25772589 */
25782590 function initialiseVariables() {
2579 - wfProfileIn( __METHOD__ );
 2591+ $fname = 'Parser::initialiseVariables';
 2592+ wfProfileIn( $fname );
25802593 $variableIDs = MagicWord::getVariableIDs();
25812594
25822595 $this->mVariables = new MagicWordArray( $variableIDs );
2583 - wfProfileOut( __METHOD__ );
 2596+ wfProfileOut( $fname );
25842597 }
25852598
25862599 /**
@@ -2648,7 +2661,8 @@
26492662 return $text;
26502663 }
26512664
2652 - wfProfileIn( __METHOD__ );
 2665+ $fname = __METHOD__;
 2666+ wfProfileIn( $fname );
26532667
26542668 if ( $frame === false ) {
26552669 $frame = $this->getPreprocessor()->newFrame();
@@ -2661,7 +2675,7 @@
26622676 $flags = $argsOnly ? PPFrame::NO_TEMPLATES : 0;
26632677 $text = $frame->expand( $dom, $flags );
26642678
2665 - wfProfileOut( __METHOD__ );
 2679+ wfProfileOut( $fname );
26662680 return $text;
26672681 }
26682682
@@ -2724,7 +2738,8 @@
27252739 */
27262740 function braceSubstitution( $piece, $frame ) {
27272741 global $wgContLang, $wgLang, $wgAllowDisplayTitle, $wgNonincludableNamespaces;
2728 - wfProfileIn( __METHOD__ );
 2742+ $fname = __METHOD__;
 2743+ wfProfileIn( $fname );
27292744 wfProfileIn( __METHOD__.'-setup' );
27302745
27312746 # Flags
@@ -2911,7 +2926,7 @@
29122927 }
29132928 } else if ( $wgNonincludableNamespaces && in_array( $title->getNamespace(), $wgNonincludableNamespaces ) ) {
29142929 $found = false; //access denied
2915 - wfDebug( __METHOD__.": template inclusion denied for " . $title->getPrefixedDBkey() );
 2930+ wfDebug( "$fname: template inclusion denied for " . $title->getPrefixedDBkey() );
29162931 } else {
29172932 list( $text, $title ) = $this->getTemplateDom( $title );
29182933 if ( $text !== false ) {
@@ -2945,7 +2960,7 @@
29462961 # Recover the source wikitext and return it
29472962 if ( !$found ) {
29482963 $text = $frame->virtualBracketedImplode( '{{', '|', '}}', $titleWithSpaces, $args );
2949 - wfProfileOut( __METHOD__ );
 2964+ wfProfileOut( $fname );
29502965 return array( 'object' => $text );
29512966 }
29522967
@@ -3004,7 +3019,7 @@
30053020 $ret = array( 'text' => $text );
30063021 }
30073022
3008 - wfProfileOut( __METHOD__ );
 3023+ wfProfileOut( $fname );
30093024 return $ret;
30103025 }
30113026
@@ -3143,7 +3158,7 @@
31443159 return $this->fetchScaryTemplateMaybeFromCache($url);
31453160 }
31463161
3147 - static function fetchScaryTemplateMaybeFromCache($url) {
 3162+ function fetchScaryTemplateMaybeFromCache($url) {
31483163 global $wgTranscludeCacheExpiry;
31493164 $dbr = wfGetDB(DB_SLAVE);
31503165 $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'),
@@ -3291,7 +3306,7 @@
32923307 }
32933308 }
32943309
3295 - if ( $name === 'html' || $name === 'nowiki' ) {
 3310+ if ( $name == 'html' || $name == 'nowiki' ) {
32963311 $this->mStripState->nowiki->setPair( $marker, $output );
32973312 } else {
32983313 $this->mStripState->general->setPair( $marker, $output );
@@ -3547,7 +3562,12 @@
35483563 # <!--LINK number-->
35493564 # turns into
35503565 # link text with suffix
3551 - $safeHeadline = $this->replaceLinkHoldersText( $safeHeadline );
 3566+ $safeHeadline = preg_replace( '/<!--LINK ([0-9]*)-->/e',
 3567+ "\$this->mLinkHolders['texts'][\$1]",
 3568+ $safeHeadline );
 3569+ $safeHeadline = preg_replace( '/<!--IWLINK ([0-9]*)-->/e',
 3570+ "\$this->mInterwikiLinkHolders['texts'][\$1]",
 3571+ $safeHeadline );
35523572
35533573 # Strip out HTML (other than plain <sup> and <sub>: bug 8393)
35543574 $tocline = preg_replace(
@@ -3623,7 +3643,7 @@
36243644 $i = 0;
36253645
36263646 foreach( $blocks as $block ) {
3627 - if( $showEditLink && $headlineCount > 0 && $i == 0 && $block !== "\n" ) {
 3647+ if( $showEditLink && $headlineCount > 0 && $i == 0 && $block != "\n" ) {
36283648 # This is the [edit] link that appears for the top block of text when
36293649 # section editing is enabled
36303650
@@ -3775,7 +3795,7 @@
37763796 } else {
37773797 # Failed to validate; fall back to the default
37783798 $nickname = $username;
3779 - wfDebug( __METHOD__.": $username has bad XML tags in signature.\n" );
 3799+ wfDebug( "Parser::getUserSig: $username has bad XML tags in signature.\n" );
37803800 }
37813801 }
37823802
@@ -3798,7 +3818,7 @@
37993819 * @param string $text
38003820 * @return mixed An expanded string, or false if invalid.
38013821 */
3802 - static function validateSig( $text ) {
 3822+ function validateSig( $text ) {
38033823 return( wfIsWellFormedXmlFragment( $text ) ? $text : false );
38043824 }
38053825
@@ -3850,7 +3870,7 @@
38513871 * @param string $text
38523872 * @return string Signature text with /~{3,5}/ removed
38533873 */
3854 - static function cleanSigInSig( $text ) {
 3874+ function cleanSigInSig( $text ) {
38553875 $text = preg_replace( '/~{3,5}/', '', $text );
38563876 return $text;
38573877 }
@@ -3881,17 +3901,19 @@
38823902 global $wgTitle;
38833903 static $executing = false;
38843904
 3905+ $fname = "Parser::transformMsg";
 3906+
38853907 # Guard against infinite recursion
38863908 if ( $executing ) {
38873909 return $text;
38883910 }
38893911 $executing = true;
38903912
3891 - wfProfileIn(__METHOD__);
 3913+ wfProfileIn($fname);
38923914 $text = $this->preprocess( $text, $wgTitle, $options );
38933915
38943916 $executing = false;
3895 - wfProfileOut(__METHOD__);
 3917+ wfProfileOut($fname);
38963918 return $text;
38973919 }
38983920
@@ -3988,7 +4010,7 @@
39894011 # Add to function cache
39904012 $mw = MagicWord::get( $id );
39914013 if( !$mw )
3992 - throw new MWException( __METHOD__.'() expecting a magic word identifier.' );
 4014+ throw new MWException( 'Parser::setFunctionHook() expecting a magic word identifier.' );
39934015
39944016 $synonyms = $mw->getSynonyms();
39954017 $sensitive = intval( $mw->isCaseSensitive() );
@@ -4003,7 +4025,7 @@
40044026 $syn = '#' . $syn;
40054027 }
40064028 # Remove trailing colon
4007 - if ( substr( $syn, -1, 1 ) === ':' ) {
 4029+ if ( substr( $syn, -1, 1 ) == ':' ) {
40084030 $syn = substr( $syn, 0, -1 );
40094031 }
40104032 $this->mFunctionSynonyms[$sensitive][$syn] = $id;
@@ -4024,9 +4046,266 @@
40254047 * Replace <!--LINK--> link placeholders with actual links, in the buffer
40264048 * Placeholders created in Skin::makeLinkObj()
40274049 * Returns an array of link CSS classes, indexed by PDBK.
 4050+ * $options is a bit field, RLH_FOR_UPDATE to select for update
40284051 */
40294052 function replaceLinkHolders( &$text, $options = 0 ) {
4030 - return $this->mLinkHolders->replace( $text );
 4053+ global $wgUser;
 4054+ global $wgContLang;
 4055+
 4056+ $fname = 'Parser::replaceLinkHolders';
 4057+ wfProfileIn( $fname );
 4058+
 4059+ $pdbks = array();
 4060+ $colours = array();
 4061+ $linkcolour_ids = array();
 4062+ $sk = $this->mOptions->getSkin();
 4063+ $linkCache = LinkCache::singleton();
 4064+
 4065+ if ( !empty( $this->mLinkHolders['namespaces'] ) ) {
 4066+ wfProfileIn( $fname.'-check' );
 4067+ $dbr = wfGetDB( DB_SLAVE );
 4068+ $page = $dbr->tableName( 'page' );
 4069+ $threshold = $wgUser->getOption('stubthreshold');
 4070+
 4071+ # Sort by namespace
 4072+ asort( $this->mLinkHolders['namespaces'] );
 4073+
 4074+ # Generate query
 4075+ $query = false;
 4076+ $current = null;
 4077+ foreach ( $this->mLinkHolders['namespaces'] as $key => $ns ) {
 4078+ # Make title object
 4079+ $title = $this->mLinkHolders['titles'][$key];
 4080+
 4081+ # Skip invalid entries.
 4082+ # Result will be ugly, but prevents crash.
 4083+ if ( is_null( $title ) ) {
 4084+ continue;
 4085+ }
 4086+ $pdbk = $pdbks[$key] = $title->getPrefixedDBkey();
 4087+
 4088+ # Check if it's a static known link, e.g. interwiki
 4089+ if ( $title->isAlwaysKnown() ) {
 4090+ $colours[$pdbk] = '';
 4091+ } elseif ( ( $id = $linkCache->getGoodLinkID( $pdbk ) ) != 0 ) {
 4092+ $colours[$pdbk] = '';
 4093+ $this->mOutput->addLink( $title, $id );
 4094+ } elseif ( $linkCache->isBadLink( $pdbk ) ) {
 4095+ $colours[$pdbk] = 'new';
 4096+ } elseif ( $title->getNamespace() == NS_SPECIAL && !SpecialPage::exists( $pdbk ) ) {
 4097+ $colours[$pdbk] = 'new';
 4098+ } else {
 4099+ # Not in the link cache, add it to the query
 4100+ if ( !isset( $current ) ) {
 4101+ $current = $ns;
 4102+ $query = "SELECT page_id, page_namespace, page_title, page_is_redirect, page_len";
 4103+ $query .= " FROM $page WHERE (page_namespace=$ns AND page_title IN(";
 4104+ } elseif ( $current != $ns ) {
 4105+ $current = $ns;
 4106+ $query .= ")) OR (page_namespace=$ns AND page_title IN(";
 4107+ } else {
 4108+ $query .= ', ';
 4109+ }
 4110+
 4111+ $query .= $dbr->addQuotes( $this->mLinkHolders['dbkeys'][$key] );
 4112+ }
 4113+ }
 4114+ if ( $query ) {
 4115+ $query .= '))';
 4116+ if ( $options & RLH_FOR_UPDATE ) {
 4117+ $query .= ' FOR UPDATE';
 4118+ }
 4119+
 4120+ $res = $dbr->query( $query, $fname );
 4121+
 4122+ # Fetch data and form into an associative array
 4123+ # non-existent = broken
 4124+ while ( $s = $dbr->fetchObject($res) ) {
 4125+ $title = Title::makeTitle( $s->page_namespace, $s->page_title );
 4126+ $pdbk = $title->getPrefixedDBkey();
 4127+ $linkCache->addGoodLinkObj( $s->page_id, $title, $s->page_len, $s->page_is_redirect );
 4128+ $this->mOutput->addLink( $title, $s->page_id );
 4129+ $colours[$pdbk] = $sk->getLinkColour( $title, $threshold );
 4130+ //add id to the extension todolist
 4131+ $linkcolour_ids[$s->page_id] = $pdbk;
 4132+ }
 4133+ //pass an array of page_ids to an extension
 4134+ wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
 4135+ }
 4136+ wfProfileOut( $fname.'-check' );
 4137+
 4138+ # Do a second query for different language variants of links and categories
 4139+ if($wgContLang->hasVariants()){
 4140+ $linkBatch = new LinkBatch();
 4141+ $variantMap = array(); // maps $pdbkey_Variant => $keys (of link holders)
 4142+ $categoryMap = array(); // maps $category_variant => $category (dbkeys)
 4143+ $varCategories = array(); // category replacements oldDBkey => newDBkey
 4144+
 4145+ $categories = $this->mOutput->getCategoryLinks();
 4146+
 4147+ // Add variants of links to link batch
 4148+ foreach ( $this->mLinkHolders['namespaces'] as $key => $ns ) {
 4149+ $title = $this->mLinkHolders['titles'][$key];
 4150+ if ( is_null( $title ) )
 4151+ continue;
 4152+
 4153+ $pdbk = $title->getPrefixedDBkey();
 4154+ $titleText = $title->getText();
 4155+
 4156+ // generate all variants of the link title text
 4157+ $allTextVariants = $wgContLang->convertLinkToAllVariants($titleText);
 4158+
 4159+ // if link was not found (in first query), add all variants to query
 4160+ if ( !isset($colours[$pdbk]) ){
 4161+ foreach($allTextVariants as $textVariant){
 4162+ if($textVariant != $titleText){
 4163+ $variantTitle = Title::makeTitle( $ns, $textVariant );
 4164+ if(is_null($variantTitle)) continue;
 4165+ $linkBatch->addObj( $variantTitle );
 4166+ $variantMap[$variantTitle->getPrefixedDBkey()][] = $key;
 4167+ }
 4168+ }
 4169+ }
 4170+ }
 4171+
 4172+ // process categories, check if a category exists in some variant
 4173+ foreach( $categories as $category ){
 4174+ $variants = $wgContLang->convertLinkToAllVariants($category);
 4175+ foreach($variants as $variant){
 4176+ if($variant != $category){
 4177+ $variantTitle = Title::newFromDBkey( Title::makeName(NS_CATEGORY,$variant) );
 4178+ if(is_null($variantTitle)) continue;
 4179+ $linkBatch->addObj( $variantTitle );
 4180+ $categoryMap[$variant] = $category;
 4181+ }
 4182+ }
 4183+ }
 4184+
 4185+
 4186+ if(!$linkBatch->isEmpty()){
 4187+ // construct query
 4188+ $titleClause = $linkBatch->constructSet('page', $dbr);
 4189+
 4190+ $variantQuery = "SELECT page_id, page_namespace, page_title, page_is_redirect, page_len";
 4191+
 4192+ $variantQuery .= " FROM $page WHERE $titleClause";
 4193+ if ( $options & RLH_FOR_UPDATE ) {
 4194+ $variantQuery .= ' FOR UPDATE';
 4195+ }
 4196+
 4197+ $varRes = $dbr->query( $variantQuery, $fname );
 4198+
 4199+ // for each found variants, figure out link holders and replace
 4200+ while ( $s = $dbr->fetchObject($varRes) ) {
 4201+
 4202+ $variantTitle = Title::makeTitle( $s->page_namespace, $s->page_title );
 4203+ $varPdbk = $variantTitle->getPrefixedDBkey();
 4204+ $vardbk = $variantTitle->getDBkey();
 4205+
 4206+ $holderKeys = array();
 4207+ if(isset($variantMap[$varPdbk])){
 4208+ $holderKeys = $variantMap[$varPdbk];
 4209+ $linkCache->addGoodLinkObj( $s->page_id, $variantTitle, $s->page_len, $s->page_is_redirect );
 4210+ $this->mOutput->addLink( $variantTitle, $s->page_id );
 4211+ }
 4212+
 4213+ // loop over link holders
 4214+ foreach($holderKeys as $key){
 4215+ $title = $this->mLinkHolders['titles'][$key];
 4216+ if ( is_null( $title ) ) continue;
 4217+
 4218+ $pdbk = $title->getPrefixedDBkey();
 4219+
 4220+ if(!isset($colours[$pdbk])){
 4221+ // found link in some of the variants, replace the link holder data
 4222+ $this->mLinkHolders['titles'][$key] = $variantTitle;
 4223+ $this->mLinkHolders['dbkeys'][$key] = $variantTitle->getDBkey();
 4224+
 4225+ // set pdbk and colour
 4226+ $pdbks[$key] = $varPdbk;
 4227+ $colours[$varPdbk] = $sk->getLinkColour( $variantTitle, $threshold );
 4228+ $linkcolour_ids[$s->page_id] = $pdbk;
 4229+ }
 4230+ wfRunHooks( 'GetLinkColours', array( $linkcolour_ids, &$colours ) );
 4231+ }
 4232+
 4233+ // check if the object is a variant of a category
 4234+ if(isset($categoryMap[$vardbk])){
 4235+ $oldkey = $categoryMap[$vardbk];
 4236+ if($oldkey != $vardbk)
 4237+ $varCategories[$oldkey]=$vardbk;
 4238+ }
 4239+ }
 4240+
 4241+ // rebuild the categories in original order (if there are replacements)
 4242+ if(count($varCategories)>0){
 4243+ $newCats = array();
 4244+ $originalCats = $this->mOutput->getCategories();
 4245+ foreach($originalCats as $cat => $sortkey){
 4246+ // make the replacement
 4247+ if( array_key_exists($cat,$varCategories) )
 4248+ $newCats[$varCategories[$cat]] = $sortkey;
 4249+ else $newCats[$cat] = $sortkey;
 4250+ }
 4251+ $this->mOutput->setCategoryLinks($newCats);
 4252+ }
 4253+ }
 4254+ }
 4255+
 4256+ # Construct search and replace arrays
 4257+ wfProfileIn( $fname.'-construct' );
 4258+ $replacePairs = array();
 4259+ foreach ( $this->mLinkHolders['namespaces'] as $key => $ns ) {
 4260+ $pdbk = $pdbks[$key];
 4261+ $searchkey = "<!--LINK $key-->";
 4262+ $title = $this->mLinkHolders['titles'][$key];
 4263+ if ( !isset( $colours[$pdbk] ) || $colours[$pdbk] == 'new' ) {
 4264+ $linkCache->addBadLinkObj( $title );
 4265+ $colours[$pdbk] = 'new';
 4266+ $this->mOutput->addLink( $title, 0 );
 4267+ $replacePairs[$searchkey] = $sk->makeBrokenLinkObj( $title,
 4268+ $this->mLinkHolders['texts'][$key],
 4269+ $this->mLinkHolders['queries'][$key] );
 4270+ } else {
 4271+ $replacePairs[$searchkey] = $sk->makeColouredLinkObj( $title, $colours[$pdbk],
 4272+ $this->mLinkHolders['texts'][$key],
 4273+ $this->mLinkHolders['queries'][$key] );
 4274+ }
 4275+ }
 4276+ $replacer = new HashtableReplacer( $replacePairs, 1 );
 4277+ wfProfileOut( $fname.'-construct' );
 4278+
 4279+ # Do the thing
 4280+ wfProfileIn( $fname.'-replace' );
 4281+ $text = preg_replace_callback(
 4282+ '/(<!--LINK .*?-->)/',
 4283+ $replacer->cb(),
 4284+ $text);
 4285+
 4286+ wfProfileOut( $fname.'-replace' );
 4287+ }
 4288+
 4289+ # Now process interwiki link holders
 4290+ # This is quite a bit simpler than internal links
 4291+ if ( !empty( $this->mInterwikiLinkHolders['texts'] ) ) {
 4292+ wfProfileIn( $fname.'-interwiki' );
 4293+ # Make interwiki link HTML
 4294+ $replacePairs = array();
 4295+ foreach( $this->mInterwikiLinkHolders['texts'] as $key => $link ) {
 4296+ $title = $this->mInterwikiLinkHolders['titles'][$key];
 4297+ $replacePairs[$key] = $sk->link( $title, $link );
 4298+ }
 4299+ $replacer = new HashtableReplacer( $replacePairs, 1 );
 4300+
 4301+ $text = preg_replace_callback(
 4302+ '/<!--IWLINK (.*?)-->/',
 4303+ $replacer->cb(),
 4304+ $text );
 4305+ wfProfileOut( $fname.'-interwiki' );
 4306+ }
 4307+
 4308+ wfProfileOut( $fname );
 4309+ return $colours;
40314310 }
40324311
40334312 /**
@@ -4036,13 +4315,42 @@
40374316 * @return string
40384317 */
40394318 function replaceLinkHoldersText( $text ) {
4040 - return $this->mLinkHolders->replaceText( $text );
 4319+ $fname = 'Parser::replaceLinkHoldersText';
 4320+ wfProfileIn( $fname );
 4321+
 4322+ $text = preg_replace_callback(
 4323+ '/<!--(LINK|IWLINK) (.*?)-->/',
 4324+ array( &$this, 'replaceLinkHoldersTextCallback' ),
 4325+ $text );
 4326+
 4327+ wfProfileOut( $fname );
 4328+ return $text;
40414329 }
40424330
40434331 /**
 4332+ * @param array $matches
 4333+ * @return string
 4334+ * @private
 4335+ */
 4336+ function replaceLinkHoldersTextCallback( $matches ) {
 4337+ $type = $matches[1];
 4338+ $key = $matches[2];
 4339+ if( $type == 'LINK' ) {
 4340+ if( isset( $this->mLinkHolders['texts'][$key] ) ) {
 4341+ return $this->mLinkHolders['texts'][$key];
 4342+ }
 4343+ } elseif( $type == 'IWLINK' ) {
 4344+ if( isset( $this->mInterwikiLinkHolders['texts'][$key] ) ) {
 4345+ return $this->mInterwikiLinkHolders['texts'][$key];
 4346+ }
 4347+ }
 4348+ return $matches[0];
 4349+ }
 4350+
 4351+ /**
40444352 * Tag hook handler for 'pre'.
40454353 */
4046 - static function renderPreTag( $text, $attribs ) {
 4354+ function renderPreTag( $text, $attribs ) {
40474355 // Backwards-compatibility hack
40484356 $content = StringUtils::delimiterReplace( '<nowiki>', '</nowiki>', '$1', $text, 'i' );
40494357
@@ -4090,7 +4398,7 @@
40914399
40924400 wfRunHooks( 'BeforeParserrenderImageGallery', array( &$this, &$ig ) );
40934401
4094 - $lines = StringUtils::explode( "\n", $text );
 4402+ $lines = explode( "\n", $text );
40954403 foreach ( $lines as $line ) {
40964404 # match lines like these:
40974405 # Image:someimage.jpg|This is some image
@@ -4103,7 +4411,7 @@
41044412
41054413 if ( strpos( $matches[0], '%' ) !== false )
41064414 $matches[1] = urldecode( $matches[1] );
4107 - $tp = Title::newFromText( $matches[1], NS_IMAGE );
 4415+ $tp = Title::newFromText( $matches[1] );
41084416 $nt =& $tp;
41094417 if( is_null( $nt ) ) {
41104418 # Bogus title. Ignore these so we don't bomb out later.
@@ -4169,11 +4477,8 @@
41704478
41714479 /**
41724480 * Parse image options text and use it to make an image
4173 - * @param Title $title
4174 - * @param string $options
4175 - * @param LinkHolderArray $holders
41764481 */
4177 - function makeImage( $title, $options, $holders = false ) {
 4482+ function makeImage( $title, $options ) {
41784483 # Check if the options text is of the form "options|alt text"
41794484 # Options are:
41804485 # * thumbnail make a thumbnail with enlarge-icon and caption, alignment depends on lang
@@ -4196,7 +4501,7 @@
41974502 # * bottom
41984503 # * text-bottom
41994504
4200 - $parts = StringUtils::explode( "|", $options );
 4505+ $parts = array_map( 'trim', explode( '|', $options) );
42014506 $sk = $this->mOptions->getSkin();
42024507
42034508 # Give extensions a chance to select the file revision for us
@@ -4224,7 +4529,7 @@
42254530 list( $type, $paramName ) = $paramMap[$magicName];
42264531
42274532 // Special case; width and height come in one variable together
4228 - if( $type === 'handler' && $paramName === 'width' ) {
 4533+ if( $type == 'handler' && $paramName == 'width' ) {
42294534 $m = array();
42304535 # (bug 13500) In both cases (width/height and width only),
42314536 # permit trailing "px" for backward compatibility.
@@ -4247,7 +4552,7 @@
42484553 }
42494554 } // else no validation -- bug 13436
42504555 } else {
4251 - if ( $type === 'handler' ) {
 4556+ if ( $type == 'handler' ) {
42524557 # Validate handler parameter
42534558 $validated = $handler->validateParam( $paramName, $value );
42544559 } else {
@@ -4283,13 +4588,7 @@
42844589 }
42854590
42864591 # Strip bad stuff out of the alt text
4287 - # We can't just use replaceLinkHoldersText() here, because if this function
4288 - # is called from replaceInternalLinks2(), mLinkHolders won't be up to date.
4289 - if ( $holders ) {
4290 - $alt = $holders->replaceText( $caption );
4291 - } else {
4292 - $alt = $this->replaceLinkHoldersText( $caption );
4293 - }
 4592+ $alt = $this->replaceLinkHoldersText( $caption );
42944593
42954594 # make sure there are no placeholders in thumbnail attributes
42964595 # that are later expanded to html- so expand them now and
@@ -4392,7 +4691,7 @@
43934692 $sectionParts = explode( '-', $section );
43944693 $sectionIndex = array_pop( $sectionParts );
43954694 foreach ( $sectionParts as $part ) {
4396 - if ( $part === 'T' ) {
 4695+ if ( $part == 'T' ) {
43974696 $flags |= self::PTD_FOR_INCLUSION;
43984697 }
43994698 }
@@ -4409,14 +4708,14 @@
44104709 $targetLevel = 1000;
44114710 } else {
44124711 while ( $node ) {
4413 - if ( $node->getName() === 'h' ) {
 4712+ if ( $node->getName() == 'h' ) {
44144713 $bits = $node->splitHeading();
44154714 if ( $bits['i'] == $sectionIndex ) {
44164715 $targetLevel = $bits['level'];
44174716 break;
44184717 }
44194718 }
4420 - if ( $mode === 'replace' ) {
 4719+ if ( $mode == 'replace' ) {
44214720 $outText .= $frame->expand( $node, PPFrame::RECOVER_ORIG );
44224721 }
44234722 $node = $node->getNextSibling();
@@ -4425,7 +4724,7 @@
44264725
44274726 if ( !$node ) {
44284727 // Not found
4429 - if ( $mode === 'get' ) {
 4728+ if ( $mode == 'get' ) {
44304729 return $newText;
44314730 } else {
44324731 return $text;
@@ -4434,21 +4733,21 @@
44354734
44364735 // Find the end of the section, including nested sections
44374736 do {
4438 - if ( $node->getName() === 'h' ) {
 4737+ if ( $node->getName() == 'h' ) {
44394738 $bits = $node->splitHeading();
44404739 $curLevel = $bits['level'];
44414740 if ( $bits['i'] != $sectionIndex && $curLevel <= $targetLevel ) {
44424741 break;
44434742 }
44444743 }
4445 - if ( $mode === 'get' ) {
 4744+ if ( $mode == 'get' ) {
44464745 $outText .= $frame->expand( $node, PPFrame::RECOVER_ORIG );
44474746 }
44484747 $node = $node->getNextSibling();
44494748 } while ( $node );
44504749
44514750 // Write out the remainder (in replace mode only)
4452 - if ( $mode === 'replace' ) {
 4751+ if ( $mode == 'replace' ) {
44534752 // Output the replacement text
44544753 // Add two newlines on -- trailing whitespace in $newText is conventionally
44554754 // stripped by the editor, so we need both newlines to restore the paragraph gap
@@ -4678,7 +4977,7 @@
46794978 do {
46804979 $oldText = $text;
46814980 $text = $this->general->replace( $text );
4682 - } while ( $text !== $oldText );
 4981+ } while ( $text != $oldText );
46834982 wfProfileOut( __METHOD__ );
46844983 return $text;
46854984 }
@@ -4688,7 +4987,7 @@
46894988 do {
46904989 $oldText = $text;
46914990 $text = $this->nowiki->replace( $text );
4692 - } while ( $text !== $oldText );
 4991+ } while ( $text != $oldText );
46934992 wfProfileOut( __METHOD__ );
46944993 return $text;
46954994 }
@@ -4699,7 +4998,7 @@
47004999 $oldText = $text;
47015000 $text = $this->general->replace( $text );
47025001 $text = $this->nowiki->replace( $text );
4703 - } while ( $text !== $oldText );
 5002+ } while ( $text != $oldText );
47045003 wfProfileOut( __METHOD__ );
47055004 return $text;
47065005 }
@@ -4713,7 +5012,7 @@
47145013 var $output = '';
47155014
47165015 function replace( $matches ) {
4717 - if ( substr( $matches[1], -1 ) === "\n" ) {
 5016+ if ( substr( $matches[1], -1 ) == "\n" ) {
47185017 $this->output .= substr( $matches[1], 0, -1 );
47195018 } else {
47205019 $this->output .= $matches[1];

Follow-up revisions

RevisionCommit summaryAuthorDate
r39949* Revert revert r39662 of my parser changes....tstarling16:08, 25 August 2008
r39980Revert r39949 "* Revert revert r39662 of my parser changes."...brion22:19, 25 August 2008

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r39295Catch php installs who have proc_open() disabled.demon16:23, 13 August 2008

Status & tagging log