Revert r85288 (magic accessors for RequestContext); much more trouble than they're...
[lhc/web/wiklou.git] / includes / parser / Parser.php
index 6224ae4..76974c9 100644 (file)
@@ -68,7 +68,7 @@ class Parser {
 
        # Constants needed for external link processing
        # Everything except bracket, space, or control characters
-       const EXT_LINK_URL_CLASS = '(?:[^\]\[<>"\\x00-\\x20\\x7F]|(?:\[\]))';
+       const EXT_LINK_URL_CLASS = '[^][<>"\\x00-\\x20\\x7F]';
        const EXT_IMAGE_REGEX = '/^(http:\/\/|https:\/\/)([^][<>"\\x00-\\x20\\x7F]+)
                \\/([A-Za-z0-9_.,~%\\-+&;#*?!=()@\\x80-\\xFF]+)\\.((?i)gif|png|jpg|jpeg)$/Sx';
 
@@ -111,6 +111,10 @@ class Parser {
        var $mFirstCall = true;
 
        # Initialised by initialiseVariables()
+
+       /**
+        * @var MagicWordArray
+        */
        var $mVariables;
 
        /**
@@ -165,9 +169,14 @@ class Parser {
        var $mRevisionObject; # The revision object of the specified revision ID
        var $mRevisionId;   # ID to display in {{REVISIONID}} tags
        var $mRevisionTimestamp; # The timestamp of the specified revision ID
-       var $mRevisionUser; # Userto display in {{REVISIONUSER}} tag
+       var $mRevisionUser; # User to display in {{REVISIONUSER}} tag
        var $mRevIdForTs;   # The revision ID which was used to fetch the timestamp
 
+       /**
+        * @var string
+        */
+       var $mUniqPrefix;
+
        /**
         * Constructor
         */
@@ -175,9 +184,12 @@ class Parser {
                $this->mConf = $conf;
                $this->mUrlProtocols = wfUrlProtocols();
                $this->mExtLinkBracketedRegex = '/\[(\b(' . wfUrlProtocols() . ')'.
-                       '(?:[^\]\[<>"\x00-\x20\x7F]|\[\])+) *([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/S';
+                       '[^][<>"\\x00-\\x20\\x7F]+) *([^\]\\x00-\\x08\\x0a-\\x1F]*?)\]/S';
                if ( isset( $conf['preprocessorClass'] ) ) {
                        $this->mPreprocessorClass = $conf['preprocessorClass'];
+               } elseif ( defined( 'MW_COMPILED' ) ) {
+                       # Preprocessor_Hash is much faster than Preprocessor_DOM in compiled mode
+                       $this->mPreprocessorClass = 'Preprocessor_Hash';
                } elseif ( extension_loaded( 'domxml' ) ) {
                        # PECL extension that conflicts with the core DOM extension (bug 13770)
                        wfDebug( "Warning: you have the obsolete domxml extension for PHP. Please remove it!\n" );
@@ -187,6 +199,7 @@ class Parser {
                } else {
                        $this->mPreprocessorClass = 'Preprocessor_Hash';
                }
+               wfDebug( __CLASS__ . ": using preprocessor: {$this->mPreprocessorClass}\n" );
        }
 
        /**
@@ -460,6 +473,8 @@ class Parser {
         *
         * @param $text String: text extension wants to have parsed
         * @param $frame PPFrame: The frame to use for expanding any template variables
+        *
+        * @return string
         */
        function recursiveTagParse( $text, $frame=false ) {
                wfProfileIn( __METHOD__ );
@@ -507,6 +522,8 @@ class Parser {
 
        /**
         * Get a random string
+        *
+        * @return string
         */
        static public function getRandomString() {
                return dechex( mt_rand( 0, 0x7fffffff ) ) . dechex( mt_rand( 0, 0x7fffffff ) );
@@ -542,6 +559,8 @@ class Parser {
 
        /**
         * Set the context title
+        *
+        * @param $t Title
         */
        function setTitle( $t ) {
                if ( !$t || $t instanceof FakeTitle ) {
@@ -630,10 +649,16 @@ class Parser {
                return wfSetVar( $this->mOptions, $x );
        }
 
+       /**
+        * @return int
+        */
        function nextLinkID() {
                return $this->mLinkID++;
        }
 
+       /**
+        * @param $id int
+        */
        function setLinkID( $id ) {
                $this->mLinkID = $id;
        }
@@ -648,7 +673,7 @@ class Parser {
                if ( $target !== null ) {
                        return $target;
                } else {
-                       return $this->mOptions->getInterfaceMessage() ? $wgLang : $wgContLang;
+                       return $this->mOptions->getInterfaceMessage() ? $wgLang : $this->mTitle->getPageLanguage();
                }
        }
 
@@ -689,10 +714,10 @@ class Parser {
         *     array( 'param' => 'x' ),
         *     '<element param="x">tag content</element>' ) )
         *
-        * @param $elements list of element names. Comments are always extracted.
-        * @param $text Source text string.
-        * @param $matches Out parameter, Array: extracted tags
-        * @param $uniq_prefix
+        * @param $elements array list of element names. Comments are always extracted.
+        * @param $text string Source text string.
+        * @param $matches array Out parameter, Array: extracted tags
+        * @param $uniq_prefix string
         * @return String: stripped text
         */
        public static function extractTagsAndParams( $elements, $text, &$matches, $uniq_prefix = '' ) {
@@ -759,6 +784,8 @@ class Parser {
 
        /**
         * Get a list of strippable XML-like elements
+        *
+        * @return array
         */
        function getStripList() {
                return $this->mStripList;
@@ -768,8 +795,6 @@ class Parser {
         * Add an item to the strip state
         * Returns the unique tag which must be inserted into the stripped text
         * The tag will be replaced with the original text in unstrip()
-        *
-        * @private
         */
        function insertStripItem( $text ) {
                $rnd = "{$this->mUniqPrefix}-item-{$this->mMarkerIndex}-" . self::MARKER_SUFFIX;
@@ -818,11 +843,11 @@ class Parser {
                                if ( $attributes !== '' ) {
                                        $table['attributes'] = $attributes;
                                }
-                       } else if ( !isset( $tables[0] ) ) {
+                       } elseif ( !isset( $tables[0] ) ) {
                                // we're outside the table
 
                                $out .= $outLine . "\n";
-                       } else if ( $firstChars === '|}' ) {
+                       } elseif ( $firstChars === '|}' ) {
                                // trim the |} code from the line
                                $line = substr ( $line , 2 );
 
@@ -863,7 +888,7 @@ class Parser {
 
                                $output .= $o;
 
-                       } else if ( $firstChars === '|-' ) {
+                       } elseif ( $firstChars === '|-' ) {
                                // start a new row element
                                // but only when we haven't started one already
                                if ( count( $currentRow ) != 0 ) {
@@ -878,7 +903,7 @@ class Parser {
                                        $currentRow['attributes'] = $attributes;
                                }
 
-                       } else if ( $firstChars  === '|+' ) {
+                       } elseif ( $firstChars  === '|+' ) {
                                // a table caption, but only proceed if there isn't one already
                                if ( !isset ( $table['caption'] ) ) {
                                        $line = substr ( $line , 2 );
@@ -890,7 +915,7 @@ class Parser {
                                        unset( $c );
                                        $output =& $table['caption']['content'];
                                }
-                       } else if ( $firstChars === '|' || $firstChars === '!' || $firstChars === '!+' ) {
+                       } elseif ( $firstChars === '|' || $firstChars === '!' || $firstChars === '!+' ) {
                                // Which kind of cells are we dealing with
                                $currentTag = 'td';
                                $line = substr ( $line , 1 );
@@ -907,7 +932,7 @@ class Parser {
                                // decide whether thead to tbody
                                if ( !array_key_exists( 'type', $currentRow ) ) {
                                        $currentRow['type'] = ( $firstChars === '!' ) ? 'thead' : 'tbody' ;
-                               } else if ( $firstChars === '|' ) {
+                               } elseif ( $firstChars === '|' ) {
                                        $currentRow['type'] = 'tbody';
                                }
 
@@ -960,6 +985,9 @@ class Parser {
         * is repeated twice.
         *
         * @private
+        * @param $cell
+        * @param $tagName
+        * @return array
         */
        function getCellAttr ( $cell, $tagName ) {
                $attributes = null;
@@ -974,7 +1002,7 @@ class Parser {
                if ( strpos( $cellData[0], '[[' ) !== false ) {
                        $content = trim ( $cell );
                }
-               else if ( count ( $cellData ) == 1 ) {
+               elseif ( count ( $cellData ) == 1 ) {
                        $content = trim ( $cellData[0] );
                } else {
                        $attributes = $this->mStripState->unstripBoth( $cellData[0] );
@@ -991,7 +1019,7 @@ class Parser {
         *
         * @private
         */
-       function generateTableHTML ( &$table ) {
+       function generateTableHTML( &$table ) {
                $return = "";
                $return .= str_repeat( '<dl><dd>' , $table['indent'] );
                $return .= '<table';
@@ -1013,22 +1041,20 @@ class Parser {
                // If we only have tbodies, mark table as simple
                for ( $i = 0; isset( $table[$i] ); $i++ ) {
                        if ( !count( $table[$i] ) ) continue;
-                       if ( !isset( $table[$i]['type'] ) ) $table[$i]['type'] = 'tbody';
+                       if ( !isset( $table[$i]['type'] ) ) {
+                               $table[$i]['type'] = 'tbody';
+                       }
                        if ( !$lastSection ) {
                                $lastSection = $table[$i]['type'];
-                       } else if ( $lastSection != $table[$i]['type'] ) {
+                       } elseif ( $lastSection != $table[$i]['type'] ) {
                                $simple = false;
-                               break;
                        }
                }
                $lastSection = '';
                for ( $i = 0; isset( $table[$i] ); $i++ ) {
-                       // Check for empty tables
-                       if ( count( $table[$i] ) ) {
-                               $empty = false;
-                       } else {
-                               continue;
-                       }
+                       if ( !count( $table[$i] ) ) continue;
+                       $empty = false; // check for empty tables
+
                        if ( $table[$i]['type'] != $lastSection && !$simple ) {
                                $return .= "\n<" . $table[$i]['type'] . '>';
                        }
@@ -1176,6 +1202,11 @@ class Parser {
                return $text;
        }
 
+       /**
+        * @throws MWException
+        * @param $m array
+        * @return HTML|string
+        */
        function magicLinkCallback( $m ) {
                if ( isset( $m[1] ) && $m[1] !== '' ) {
                        # Skip anchor
@@ -3055,7 +3086,7 @@ class Parser {
                $args = ( null == $piece['parts'] ) ? array() : $piece['parts'];
                wfProfileOut( __METHOD__.'-setup' );
                wfProfileIn( __METHOD__."-title-$originalTitle" );
-               
+
                # SUBST
                wfProfileIn( __METHOD__.'-modifiers' );
                if ( !$found ) {
@@ -3981,7 +4012,10 @@ class Parser {
                                        if ( $dot ) {
                                                $numbering .= '.';
                                        }
-                                       $numbering .= $wgContLang->formatNum( $sublevelCount[$i] );
+                                       global $wgBetterDirectionality;
+                                       $pagelang = $this->mTitle->getPageLanguage();
+                                       $toclang = ( $wgBetterDirectionality ? $pagelang : $wgContLang );
+                                       $numbering .= $toclang->formatNum( $sublevelCount[$i] );
                                        $dot = 1;
                                }
                        }
@@ -4352,11 +4386,9 @@ class Parser {
                # If we're still here, make it a link to the user page
                $userText = wfEscapeWikiText( $username );
                $nickText = wfEscapeWikiText( $nickname );
-               if ( $user->isAnon() )  {
-                       return wfMsgExt( 'signature-anon', array( 'content', 'parsemag' ), $userText, $nickText );
-               } else {
-                       return wfMsgExt( 'signature', array( 'content', 'parsemag' ), $userText, $nickText );
-               }
+               $msgName = $user->isAnon() ? 'signature-anon' : 'signature';
+
+               return wfMessage( $msgName, $userText, $nickText )->inContentLanguage()->title( $this->getTitle() )->text();
        }
 
        /**
@@ -5092,6 +5124,7 @@ class Parser {
                $matches = array();
                $elements = array_keys( $this->mTransparentTagHooks );
                $text = self::extractTagsAndParams( $elements, $text, $matches, $this->mUniqPrefix );
+               $replacements = array();
 
                foreach ( $matches as $marker => $data ) {
                        list( $element, $content, $params, $tag ) = $data;
@@ -5101,9 +5134,9 @@ class Parser {
                        } else {
                                $output = $tag;
                        }
-                       $this->mStripState->addGeneral( $marker, $output );
+                       $replacements[$marker] = $output;
                }
-               return $text;
+               return strtr( $text, $replacements );
        }
 
        /**
@@ -5130,6 +5163,8 @@ class Parser {
         * @param $newText String: replacement text for section data.
         * @return String: for "get", the extracted section text.
         *                 for "replace", the whole page with the section replaced.
+        *                 If the page is empty and section 0 is requested, $text (as '')
+        *                  is returned
         */
        private function extractSections( $text, $section, $mode, $newText='' ) {
                global $wgTitle; # not generally used but removes an ugly failure mode
@@ -5431,10 +5466,7 @@ class Parser {
         *
         * @return string
         */
-       function testSrvus( $text, $title, ParserOptions $options, $outputType = self::OT_HTML ) {
-               if ( !$title instanceof Title ) {
-                       $title = Title::newFromText( $title );
-               }
+       function testSrvus( $text, Title $title, ParserOptions $options, $outputType = self::OT_HTML ) {
                $this->startParse( $title, $options, $outputType, true );
 
                $text = $this->replaceVariables( $text );
@@ -5443,18 +5475,11 @@ class Parser {
                return $text;
        }
 
-       function testPst( $text, $title, $options ) {
-               global $wgUser;
-               if ( !$title instanceof Title ) {
-                       $title = Title::newFromText( $title );
-               }
-               return $this->preSaveTransform( $text, $title, $wgUser, $options );
+       function testPst( $text, Title $title, ParserOptions $options ) {
+               return $this->preSaveTransform( $text, $title, $options->getUser(), $options );
        }
 
-       function testPreprocess( $text, $title, $options ) {
-               if ( !$title instanceof Title ) {
-                       $title = Title::newFromText( $title );
-               }
+       function testPreprocess( $text, Title $title, ParserOptions $options ) {
                return $this->testSrvus( $text, $title, $options, self::OT_PREPROCESS );
        }