The war on redundant ampersand usage!
[lhc/web/wiklou.git] / includes / Parser.php
index 2c6f3a6..8f04aa2 100644 (file)
@@ -2,8 +2,7 @@
 /**
  * File for Parser and related classes
  *
- * @package MediaWiki
- * @subpackage Parser
+ * @addtogroup Parser
  */
 
 /**
@@ -86,10 +85,10 @@ define( 'MW_COLON_STATE_COMMENTDASHDASH', 7 );
  *  * only within ParserOptions
  * </pre>
  *
- * @package MediaWiki
  */
 class Parser
 {
+       const VERSION = MW_PARSER_VERSION;
        /**#@+
         * @private
         */
@@ -114,7 +113,7 @@ class Parser
                $ot,            // Shortcut alias, see setOutputType()
                $mRevisionId,   // ID to display in {{REVISIONID}} tags
                $mRevisionTimestamp, // The timestamp of the specified revision ID
-               $mRevIdForTs;   // The revision ID which was used to fetch the timestamp  
+               $mRevIdForTs;   // The revision ID which was used to fetch the timestamp
 
        /**#@-*/
 
@@ -211,7 +210,7 @@ class Parser
                        'titles' => array()
                );
                $this->mRevisionTimestamp = $this->mRevisionId = null;
-               
+
                /**
                 * Prefix for temporary replacement strings for the multipass parser.
                 * \x07 should never appear in input as it's disallowed in XML.
@@ -871,7 +870,7 @@ class Parser
                                array_push ( $td_history , false );
                                array_push ( $last_tag_history , '' );
                        }
-                       else if ( $first_character == '|' || $first_character == '!' || substr ( $line , 0 , 2 )  == '|+' ) { 
+                       else if ( $first_character == '|' || $first_character == '!' || substr ( $line , 0 , 2 )  == '|+' ) {
                                // This might be cell elements, td, th or captions
                                if ( substr ( $line , 0 , 2 ) == '|+' ) {
                                        $first_character = '+';
@@ -1085,7 +1084,7 @@ class Parser
                        }
 
                        $url = wfMsg( $urlmsg, $id);
-                       $sk =& $this->mOptions->getSkin();
+                       $sk = $this->mOptions->getSkin();
                        $la = $sk->getExternalLinkAttributes( $url, $keyword.$id );
                        $text = "<a href=\"{$url}\"{$la}>{$keyword} {$id}</a>";
                }
@@ -1305,7 +1304,7 @@ class Parser
                $fname = 'Parser::replaceExternalLinks';
                wfProfileIn( $fname );
 
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
 
                $bits = preg_split( EXT_LINK_BRACKETED, $text, -1, PREG_SPLIT_DELIM_CAPTURE );
 
@@ -1394,7 +1393,7 @@ class Parser
                $s = array_shift( $bits );
                $i = 0;
 
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
 
                while ( $i < count( $bits ) ){
                        $protocol = $bits[$i++];
@@ -1502,7 +1501,7 @@ class Parser
         * @private
         */
        function maybeMakeExternalImage( $url ) {
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
                $imagesfrom = $this->mOptions->getAllowExternalImagesFrom();
                $imagesexception = !empty($imagesfrom);
                $text = false;
@@ -1532,7 +1531,7 @@ class Parser
                # the % is needed to support urlencoded titles as well
                if ( !$tc ) { $tc = Title::legalChars() . '#%'; }
 
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
 
                #split the entire text string on occurences of [[
                $a = explode( '[[', ' ' . $s );
@@ -1782,7 +1781,7 @@ class Parser
                                if( in_array( $nt->getPrefixedText(), $selflink, true ) ) {
                                        $s .= $prefix . $sk->makeSelfLinkObj( $nt, $text, '', $trail );
                                        continue;
-                               }                       
+                               }
                        }
 
                        # Special and Media are pseudo-namespaces; no pages actually exist in them
@@ -1862,7 +1861,7 @@ class Parser
         */
        function makeKnownLinkHolder( $nt, $text = '', $query = '', $trail = '', $prefix = '' ) {
                list( $inside, $trail ) = Linker::splitTrail( $trail );
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
                $link = $sk->makeKnownLinkObj( $nt, $text, $query, $inside, $prefix );
                return $this->armorLinks( $link ) . $trail;
        }
@@ -1923,9 +1922,9 @@ class Parser
                        # Look at the first character
                        if( $target != '' && $target{0} == '/' ) {
                                # / at end means we don't want the slash to be shown
-                               if( substr( $target, -1, 1 ) == '/' ) {
-                                       $target = substr( $target, 1, -1 );
-                                       $noslash = $target;
+                               $trailingSlashes = preg_match_all( '%(/+)$%', $target, $m );
+                               if( $trailingSlashes ) {
+                                       $noslash = $target = substr( $target, 1, -strlen($m[0][0]) );
                                } else {
                                        $noslash = substr( $target, 1 );
                                }
@@ -2852,7 +2851,7 @@ class Parser
                return $text;
        }
 
-               
+
        /// Clean up argument array - refactored in 1.9 so parserfunctions can use it, too.
        static function createAssocArgs( $args ) {
                $assocArgs = array();
@@ -2872,10 +2871,10 @@ class Parser
                                }
                        }
                }
-               
+
                return $assocArgs;
        }
-       
+
        /**
         * Return the text of a template, after recursively
         * replacing any variables or templates within the template.
@@ -3271,7 +3270,7 @@ class Parser
                        return wfMsg('scarytranscludedisabled');
 
                $url = $title->getFullUrl( "action=$action" );
-               
+
                if (strlen($url) > 255)
                        return wfMsg('scarytranscludetoolong');
                return $this->fetchScaryTemplateMaybeFromCache($url);
@@ -3279,7 +3278,7 @@ class Parser
 
        function fetchScaryTemplateMaybeFromCache($url) {
                global $wgTranscludeCacheExpiry;
-               $dbr =& wfGetDB(DB_SLAVE);
+               $dbr = wfGetDB(DB_SLAVE);
                $obj = $dbr->selectRow('transcache', array('tc_time', 'tc_contents'),
                                array('tc_url' => $url));
                if ($obj) {
@@ -3294,7 +3293,7 @@ class Parser
                if (!$text)
                        return wfMsg('scarytranscludefailed', $url);
 
-               $dbw =& wfGetDB(DB_MASTER);
+               $dbw = wfGetDB(DB_MASTER);
                $dbw->replace('transcache', array('tc_url'), array(
                        'tc_url' => $url,
                        'tc_time' => time(),
@@ -3437,7 +3436,7 @@ class Parser
                }
 
                # We need this to perform operations on the HTML
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
 
                # headline counter
                $headlineCount = 0;
@@ -3962,12 +3961,12 @@ class Parser
 
                $pdbks = array();
                $colours = array();
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
                $linkCache =& LinkCache::singleton();
 
                if ( !empty( $this->mLinkHolders['namespaces'] ) ) {
                        wfProfileIn( $fname.'-check' );
-                       $dbr =& wfGetDB( DB_SLAVE );
+                       $dbr = wfGetDB( DB_SLAVE );
                        $page = $dbr->tableName( 'page' );
                        $threshold = $wgUser->getOption('stubthreshold');
 
@@ -4157,8 +4156,8 @@ class Parser
                                                if(isset($categoryMap[$vardbk])){
                                                        $oldkey = $categoryMap[$vardbk];
                                                        if($oldkey != $vardbk)
-                                                               $varCategories[$oldkey]=$vardbk;                                                        
-                                               }                                               
+                                                               $varCategories[$oldkey]=$vardbk;
+                                               }
                                        }
 
                                        // rebuild the categories in original order (if there are replacements)
@@ -4299,6 +4298,7 @@ class Parser
         */
        function renderImageGallery( $text, $params ) {
                $ig = new ImageGallery();
+               $ig->setContextTitle( $this->mTitle );
                $ig->setShowBytes( false );
                $ig->setShowFilename( false );
                $ig->setParsing();
@@ -4435,7 +4435,7 @@ class Parser
                $alt = Sanitizer::stripAllTags( $alt );
 
                # Linker does the rest
-               $sk =& $this->mOptions->getSkin();
+               $sk = $this->mOptions->getSkin();
                return $sk->makeImageLinkObj( $nt, $caption, $alt, $align, $width, $height, $framed, $thumb, $manual_thumb, $page );
        }
 
@@ -4635,23 +4635,23 @@ class Parser
        }
 
        /**
-        * Get the timestamp associated with the current revision, adjusted for 
+        * Get the timestamp associated with the current revision, adjusted for
         * the default server-local timestamp
         */
        function getRevisionTimestamp() {
                if ( is_null( $this->mRevisionTimestamp ) ) {
                        wfProfileIn( __METHOD__ );
                        global $wgContLang;
-                       $dbr =& wfGetDB( DB_SLAVE );
+                       $dbr = wfGetDB( DB_SLAVE );
                        $timestamp = $dbr->selectField( 'revision', 'rev_timestamp',
                                        array( 'rev_id' => $this->mRevisionId ), __METHOD__ );
-                       
+
                        // Normalize timestamp to internal MW format for timezone processing.
                        // This has the added side-effect of replacing a null value with
                        // the current time, which gives us more sensible behavior for
                        // previews.
                        $timestamp = wfTimestamp( TS_MW, $timestamp );
-                       
+
                        // The cryptic '' timezone parameter tells to use the site-default
                        // timezone offset instead of the user settings.
                        //
@@ -4659,12 +4659,12 @@ class Parser
                        // to other users, and potentially even used inside links and such,
                        // it needs to be consistent for all visitors.
                        $this->mRevisionTimestamp = $wgContLang->userAdjust( $timestamp, '' );
-                       
+
                        wfProfileOut( __METHOD__ );
                }
                return $this->mRevisionTimestamp;
        }
-       
+
        /**
         * Mutator for $mDefaultSort
         *
@@ -4673,7 +4673,7 @@ class Parser
        public function setDefaultSort( $sort ) {
                $this->mDefaultSort = $sort;
        }
-       
+
        /**
         * Accessor for $mDefaultSort
         * Will use the title/prefixed title if none is set
@@ -4689,239 +4689,7 @@ class Parser
                                        : $this->mTitle->getPrefixedText();
                }
        }
-       
-}
-
-/**
- * @todo document
- * @package MediaWiki
- */
-class ParserOutput
-{
-       var $mText,             # The output text
-               $mLanguageLinks,    # List of the full text of language links, in the order they appear
-               $mCategories,       # Map of category names to sort keys
-               $mContainsOldMagic, # Boolean variable indicating if the input contained variables like {{CURRENTDAY}}
-               $mCacheTime,        # Time when this object was generated, or -1 for uncacheable. Used in ParserCache.
-               $mVersion,          # Compatibility check
-               $mTitleText,        # title text of the chosen language variant
-               $mLinks,            # 2-D map of NS/DBK to ID for the links in the document. ID=zero for broken.
-               $mTemplates,        # 2-D map of NS/DBK to ID for the template references. ID=zero for broken.
-               $mImages,           # DB keys of the images used, in the array key only
-               $mExternalLinks,    # External link URLs, in the key only
-               $mHTMLtitle,            # Display HTML title
-               $mSubtitle,                     # Additional subtitle
-               $mNewSection,           # Show a new section link?
-               $mNoGallery;            # No gallery on category page? (__NOGALLERY__)
-
-       function ParserOutput( $text = '', $languageLinks = array(), $categoryLinks = array(),
-               $containsOldMagic = false, $titletext = '' )
-       {
-               $this->mText = $text;
-               $this->mLanguageLinks = $languageLinks;
-               $this->mCategories = $categoryLinks;
-               $this->mContainsOldMagic = $containsOldMagic;
-               $this->mCacheTime = '';
-               $this->mVersion = MW_PARSER_VERSION;
-               $this->mTitleText = $titletext;
-               $this->mLinks = array();
-               $this->mTemplates = array();
-               $this->mImages = array();
-               $this->mExternalLinks = array();
-               $this->mHTMLtitle = "" ;
-               $this->mSubtitle = "" ;
-               $this->mNewSection = false;
-               $this->mNoGallery = false;
-       }
-
-       function getText()                   { return $this->mText; }
-       function &getLanguageLinks()          { return $this->mLanguageLinks; }
-       function getCategoryLinks()          { return array_keys( $this->mCategories ); }
-       function &getCategories()            { return $this->mCategories; }
-       function getCacheTime()              { return $this->mCacheTime; }
-       function getTitleText()              { return $this->mTitleText; }
-       function &getLinks()                 { return $this->mLinks; }
-       function &getTemplates()             { return $this->mTemplates; }
-       function &getImages()                { return $this->mImages; }
-       function &getExternalLinks()         { return $this->mExternalLinks; }
-       function getNoGallery()              { return $this->mNoGallery; }
-       function getSubtitle()               { return $this->mSubtitle; }
-
-       function containsOldMagic()          { return $this->mContainsOldMagic; }
-       function setText( $text )            { return wfSetVar( $this->mText, $text ); }
-       function setLanguageLinks( $ll )     { return wfSetVar( $this->mLanguageLinks, $ll ); }
-       function setCategoryLinks( $cl )     { return wfSetVar( $this->mCategories, $cl ); }
-       function setContainsOldMagic( $com ) { return wfSetVar( $this->mContainsOldMagic, $com ); }
-       function setCacheTime( $t )          { return wfSetVar( $this->mCacheTime, $t ); }
-       function setTitleText( $t )          { return wfSetVar($this->mTitleText, $t); }
-       function setSubtitle( $st )          { return wfSetVar( $this->mSubtitle, $st ); }
-
-       function addCategory( $c, $sort )    { $this->mCategories[$c] = $sort; }
-       function addImage( $name )           { $this->mImages[$name] = 1; }
-       function addLanguageLink( $t )       { $this->mLanguageLinks[] = $t; }
-       function addExternalLink( $url )     { $this->mExternalLinks[$url] = 1; }
-
-       function setNewSection( $value ) {
-               $this->mNewSection = (bool)$value;
-       }
-       function getNewSection() {
-               return (bool)$this->mNewSection;
-       }
-
-       function addLink( $title, $id = null ) {
-               $ns = $title->getNamespace();
-               $dbk = $title->getDBkey();
-               if ( !isset( $this->mLinks[$ns] ) ) {
-                       $this->mLinks[$ns] = array();
-               }
-               if ( is_null( $id ) ) {
-                       $id = $title->getArticleID();
-               }
-               $this->mLinks[$ns][$dbk] = $id;
-       }
-
-       function addTemplate( $title, $id ) {
-               $ns = $title->getNamespace();
-               $dbk = $title->getDBkey();
-               if ( !isset( $this->mTemplates[$ns] ) ) {
-                       $this->mTemplates[$ns] = array();
-               }
-               $this->mTemplates[$ns][$dbk] = $id;
-       }
-
-       /**
-        * Return true if this cached output object predates the global or
-        * per-article cache invalidation timestamps, or if it comes from
-        * an incompatible older version.
-        *
-        * @param string $touched the affected article's last touched timestamp
-        * @return bool
-        * @public
-        */
-       function expired( $touched ) {
-               global $wgCacheEpoch;
-               return $this->getCacheTime() == -1 || // parser says it's uncacheable
-                      $this->getCacheTime() < $touched ||
-                      $this->getCacheTime() <= $wgCacheEpoch ||
-                      !isset( $this->mVersion ) ||
-                      version_compare( $this->mVersion, MW_PARSER_VERSION, "lt" );
-       }
-}
-
-/**
- * Set options of the Parser
- * @todo document
- * @package MediaWiki
- */
-class ParserOptions
-{
-       # All variables are supposed to be private in theory, although in practise this is not the case.
-       var $mUseTeX;                    # Use texvc to expand <math> tags
-       var $mUseDynamicDates;           # Use DateFormatter to format dates
-       var $mInterwikiMagic;            # Interlanguage links are removed and returned in an array
-       var $mAllowExternalImages;       # Allow external images inline
-       var $mAllowExternalImagesFrom;   # If not, any exception?
-       var $mSkin;                      # Reference to the preferred skin
-       var $mDateFormat;                # Date format index
-       var $mEditSection;               # Create "edit section" links
-       var $mNumberHeadings;            # Automatically number headings
-       var $mAllowSpecialInclusion;     # Allow inclusion of special pages
-       var $mTidy;                      # Ask for tidy cleanup
-       var $mInterfaceMessage;          # Which lang to call for PLURAL and GRAMMAR
-       var $mMaxIncludeSize;            # Maximum size of template expansions, in bytes
-       var $mRemoveComments;            # Remove HTML comments. ONLY APPLIES TO PREPROCESS OPERATIONS
-
-       var $mUser;                      # Stored user object, just used to initialise the skin
-
-       function getUseTeX()                        { return $this->mUseTeX; }
-       function getUseDynamicDates()               { return $this->mUseDynamicDates; }
-       function getInterwikiMagic()                { return $this->mInterwikiMagic; }
-       function getAllowExternalImages()           { return $this->mAllowExternalImages; }
-       function getAllowExternalImagesFrom()       { return $this->mAllowExternalImagesFrom; }
-       function getEditSection()                   { return $this->mEditSection; }
-       function getNumberHeadings()                { return $this->mNumberHeadings; }
-       function getAllowSpecialInclusion()         { return $this->mAllowSpecialInclusion; }
-       function getTidy()                          { return $this->mTidy; }
-       function getInterfaceMessage()              { return $this->mInterfaceMessage; }
-       function getMaxIncludeSize()                { return $this->mMaxIncludeSize; }
-       function getRemoveComments()                { return $this->mRemoveComments; }
-
-       function &getSkin() {
-               if ( !isset( $this->mSkin ) ) {
-                       $this->mSkin = $this->mUser->getSkin();
-               }
-               return $this->mSkin;
-       }
-
-       function getDateFormat() {
-               if ( !isset( $this->mDateFormat ) ) {
-                       $this->mDateFormat = $this->mUser->getDatePreference();
-               }
-               return $this->mDateFormat;
-       }
 
-       function setUseTeX( $x )                    { return wfSetVar( $this->mUseTeX, $x ); }
-       function setUseDynamicDates( $x )           { return wfSetVar( $this->mUseDynamicDates, $x ); }
-       function setInterwikiMagic( $x )            { return wfSetVar( $this->mInterwikiMagic, $x ); }
-       function setAllowExternalImages( $x )       { return wfSetVar( $this->mAllowExternalImages, $x ); }
-       function setAllowExternalImagesFrom( $x )   { return wfSetVar( $this->mAllowExternalImagesFrom, $x ); }
-       function setDateFormat( $x )                { return wfSetVar( $this->mDateFormat, $x ); }
-       function setEditSection( $x )               { return wfSetVar( $this->mEditSection, $x ); }
-       function setNumberHeadings( $x )            { return wfSetVar( $this->mNumberHeadings, $x ); }
-       function setAllowSpecialInclusion( $x )     { return wfSetVar( $this->mAllowSpecialInclusion, $x ); }
-       function setTidy( $x )                      { return wfSetVar( $this->mTidy, $x); }
-       function setSkin( $x )                      { $this->mSkin = $x; }
-       function setInterfaceMessage( $x )          { return wfSetVar( $this->mInterfaceMessage, $x); }
-       function setMaxIncludeSize( $x )            { return wfSetVar( $this->mMaxIncludeSize, $x ); }
-       function setRemoveComments( $x )            { return wfSetVar( $this->mRemoveComments, $x ); }
-
-       function ParserOptions( $user = null ) {
-               $this->initialiseFromUser( $user );
-       }
-
-       /**
-        * Get parser options
-        * @static
-        */
-       static function newFromUser( $user ) {
-               return new ParserOptions( $user );
-       }
-
-       /** Get user options */
-       function initialiseFromUser( $userInput ) {
-               global $wgUseTeX, $wgUseDynamicDates, $wgInterwikiMagic, $wgAllowExternalImages;
-               global $wgAllowExternalImagesFrom, $wgAllowSpecialInclusion, $wgMaxArticleSize;
-               $fname = 'ParserOptions::initialiseFromUser';
-               wfProfileIn( $fname );
-               if ( !$userInput ) {
-                       global $wgUser;
-                       if ( isset( $wgUser ) ) {
-                               $user = $wgUser;
-                       } else {
-                               $user = new User;
-                       }
-               } else {
-                       $user =& $userInput;
-               }
-
-               $this->mUser = $user;
-
-               $this->mUseTeX = $wgUseTeX;
-               $this->mUseDynamicDates = $wgUseDynamicDates;
-               $this->mInterwikiMagic = $wgInterwikiMagic;
-               $this->mAllowExternalImages = $wgAllowExternalImages;
-               $this->mAllowExternalImagesFrom = $wgAllowExternalImagesFrom;
-               $this->mSkin = null; # Deferred
-               $this->mDateFormat = null; # Deferred
-               $this->mEditSection = true;
-               $this->mNumberHeadings = $user->getOption( 'numberheadings' );
-               $this->mAllowSpecialInclusion = $wgAllowSpecialInclusion;
-               $this->mTidy = false;
-               $this->mInterfaceMessage = false;
-               $this->mMaxIncludeSize = $wgMaxArticleSize * 1024;
-               $this->mRemoveComments = true;
-               wfProfileOut( $fname );
-       }
 }
 
 class OnlyIncludeReplacer {