Refactor the factory/i18n/list/etc static methods from SpecialPage into their own...
authorHappy-melon <happy-melon@users.mediawiki.org>
Sun, 17 Apr 2011 11:31:11 +0000 (11:31 +0000)
committerHappy-melon <happy-melon@users.mediawiki.org>
Sun, 17 Apr 2011 11:31:11 +0000 (11:31 +0000)
Also make a few changes to the functions available.  SpecialPageFactory::resolveAlias() now takes an optional subpage and returns array(<name>,<subpage>).  Similarly merge getPage() and getPageByAlias().  There were many examples of (extensions particularly) making dubious assumptions about the presence or absence of subpages or canonical-ness.

I didn't deprecate SpecialPage::getTitleFor() as it's got over six hundred calls.  I'm rather undecided on the best position of getPage()/executePath().  Although the latter needs cleanup anyway.

17 files changed:
includes/AutoLoader.php
includes/ChangesList.php
includes/Linker.php
includes/OutputPage.php
includes/PrefixSearch.php
includes/Skin.php
includes/SkinLegacy.php
includes/SkinTemplate.php
includes/SpecialPage.php
includes/SpecialPageFactory.php [new file with mode: 0644]
includes/Title.php
includes/Wiki.php
includes/api/ApiQuery.php
includes/parser/CoreParserFunctions.php
includes/parser/Parser.php
includes/specials/SpecialSpecialpages.php
maintenance/updateSpecialPages.php

index 1e384fa..185335e 100644 (file)
@@ -226,6 +226,7 @@ $wgAutoloadLocalClasses = array(
        'SpecialMypage' => 'includes/SpecialPage.php',
        'SpecialMytalk' => 'includes/SpecialPage.php',
        'SpecialPage' => 'includes/SpecialPage.php',
+       'SpecialPageFactory' => 'includes/SpecialPageFactory.php',
        'SpecialRedirectToSpecial' => 'includes/SpecialPage.php',
        'SquidUpdate' => 'includes/SquidUpdate.php',
        'SquidPurgeClient' => 'includes/SquidPurgeClient.php',
index 7bdca29..8732e6f 100644 (file)
@@ -558,7 +558,7 @@ class OldChangesList extends ChangesList {
                        $this->insertLog( $s, $logtitle, $rc->mAttribs['rc_log_type'] );
                // Log entries (old format) or log targets, and special pages
                } elseif( $rc->mAttribs['rc_namespace'] == NS_SPECIAL ) {
-                       list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $rc->mAttribs['rc_title'] );
+                       list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $rc->mAttribs['rc_title'] );
                        if( $name == 'Log' ) {
                                $this->insertLog( $s, $rc->getTitle(), $subpage );
                        }
@@ -694,7 +694,7 @@ class EnhancedChangesList extends ChangesList {
                        $watched = false;
                // Log entries (old format) and special pages
                } elseif( $rc->mAttribs['rc_namespace'] == NS_SPECIAL ) {
-                       list( $specialName, $logtype ) = SpecialPage::resolveAliasWithSubpage( $rc->mAttribs['rc_title'] );
+                       list( $specialName, $logtype ) = SpecialPageFactory::resolveAlias( $rc->mAttribs['rc_title'] );
                        if ( $specialName == 'Log' ) {
                                # Log updates, etc
                                $logname = LogPage::logName( $logtype );
index 25f21e2..4f2b833 100644 (file)
@@ -376,7 +376,7 @@ class Linker {
 
        static function normaliseSpecialPage( Title $title ) {
                if ( $title->getNamespace() == NS_SPECIAL ) {
-                       list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $title->getDBkey() );
+                       list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
                        if ( !$name ) {
                                return $title;
                        }
index 2f09342..120d55a 100644 (file)
@@ -2652,8 +2652,7 @@ class OutputPage {
                $ns = $title->getNamespace();
                $nsname = MWNamespace::exists( $ns ) ? MWNamespace::getCanonicalName( $ns ) : $title->getNsText();
                if ( $ns == NS_SPECIAL ) {
-                       $parts = SpecialPage::resolveAliasWithSubpage( $title->getDBkey() );
-                       $canonicalName = $parts[0];
+                       list( $canonicalName, /*...*/ ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
                } else {
                        $canonicalName = false; # bug 21115
                }
index ba11e3e..0efe1bd 100644 (file)
@@ -85,15 +85,13 @@ class PrefixSearch {
 
                // Unlike SpecialPage itself, we want the canonical forms of both
                // canonical and alias title forms...
-               SpecialPage::initList();
-               SpecialPage::initAliasList();
                $keys = array();
-               foreach( array_keys( SpecialPage::$mList ) as $page ) {
+               foreach( SpecialPageFactory::getList() as $page => $class ) {
                        $keys[$wgContLang->caseFold( $page )] = $page;
                }
 
                foreach( $wgContLang->getSpecialPageAliases() as $page => $aliases ) {
-                       if( !array_key_exists( $page, SpecialPage::$mList ) ) {# bug 20885
+                       if( !array_key_exists( $page, SpecialPageFactory::getList() ) ) {# bug 20885
                                continue;
                        }
 
index 1bf2883..08b238a 100644 (file)
@@ -303,6 +303,7 @@ abstract class Skin {
         * Special:Contributions mark the user which they are relevant to so that
         * things like the toolbox can display the information they usually are only
         * able to display on a user's userpage and talkpage.
+        * @return User
         */
        public function getRelevantUser() {
                if ( isset($this->mRelevantUser) ) {
@@ -485,7 +486,7 @@ abstract class Skin {
                if ( $title->getNamespace() == NS_SPECIAL ) {
                        $type = 'ns-special';
                        // bug 23315: provide a class based on the canonical special page name without subpages
-                       list( $canonicalName ) = SpecialPage::resolveAliasWithSubpage( $title->getDBkey() );
+                       list( $canonicalName ) = SpecialPageFactory::resolveAlias( $title->getDBkey() );
                        if ( $canonicalName ) {
                                $type .= ' ' . Sanitizer::escapeClass( "mw-special-$canonicalName" );
                        } else {
@@ -1128,7 +1129,7 @@ abstract class Skin {
        }
 
        static function makeSpecialUrl( $name, $urlaction = '' ) {
-               $title = SpecialPage::getTitleFor( $name );
+               $title = SpecialPage::getSafeTitleFor( $name );
                return $title->getLocalURL( $urlaction );
        }
 
index 50fe821..22d658a 100644 (file)
@@ -432,7 +432,7 @@ class LegacyTemplate extends BaseTemplate {
        function specialPagesList() {
                global $wgContLang, $wgServer, $wgRedirectScript;
 
-               $pages = SpecialPage::getUsablePages();
+               $pages = SpecialPageFactory::getUsablePages();
 
                foreach ( $pages as $name => $page ) {
                        $pages[$name] = $page->getDescription();
index 1148845..3f106c5 100644 (file)
@@ -608,8 +608,7 @@ class SkinTemplate extends Skin {
                        # contain the original alias-with-subpage.
                        $origTitle = Title::newFromText( $wgRequest->getText( 'title' ) );
                        if( $origTitle instanceof Title && $origTitle->getNamespace() == NS_SPECIAL ) {
-                               list( $spName, $spPar ) =
-                                       SpecialPage::resolveAliasWithSubpage( $origTitle->getText() );
+                               list( $spName, $spPar ) = SpecialPageFactory::resolveAlias( $origTitle->getText() );
                                $active = $spName == 'Contributions'
                                        && ( ( $spPar && $spPar == $this->username )
                                                || $wgRequest->getText( 'target' ) == $this->username );
index e85e0b7..6f2cc57 100644 (file)
@@ -201,64 +201,20 @@ class SpecialPage {
        static public $mAliases;
        static public $mListInitialised = false;
 
-       /**#@-*/
-
        /**
         * Initialise the special page list
         * This must be called before accessing SpecialPage::$mList
+        * @deprecated since 1.18
         */
        static function initList() {
-               global $wgSpecialPages;
-               global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
-
-               if ( self::$mListInitialised ) {
-                       return;
-               }
-               wfProfileIn( __METHOD__ );
-
-               # Better to set this now, to avoid infinite recursion in carelessly written hooks
-               self::$mListInitialised = true;
-
-               if( !$wgDisableCounters ) {
-                       self::$mList['Popularpages'] = 'PopularpagesPage';
-               }
-
-               if( !$wgDisableInternalSearch ) {
-                       self::$mList['Search'] = 'SpecialSearch';
-               }
-
-               if( $wgEmailAuthentication ) {
-                       self::$mList['Confirmemail'] = 'EmailConfirmation';
-                       self::$mList['Invalidateemail'] = 'EmailInvalidation';
-               }
-
-               # Add extension special pages
-               self::$mList = array_merge( self::$mList, $wgSpecialPages );
-
-               # Run hooks
-               # This hook can be used to remove undesired built-in special pages
-               wfRunHooks( 'SpecialPage_initList', array( &self::$mList ) );
-               wfProfileOut( __METHOD__ );
+               // Noop
        }
 
+       /**
+        * @deprecated since 1.18
+        */
        static function initAliasList() {
-               if ( !is_null( self::$mAliases ) ) {
-                       return;
-               }
-
-               global $wgContLang;
-               $aliases = $wgContLang->getSpecialPageAliases();
-               $missingPages = self::$mList;
-               self::$mAliases = array();
-               foreach ( $aliases as $realName => $aliasList ) {
-                       foreach ( $aliasList as $alias ) {
-                               self::$mAliases[$wgContLang->caseFold( $alias )] = $realName;
-                       }
-                       unset( $missingPages[$realName] );
-               }
-               foreach ( $missingPages as $name => $stuff ) {
-                       self::$mAliases[$wgContLang->caseFold( $name )] = $name;
-               }
+               // Noop
        }
 
        /**
@@ -267,19 +223,11 @@ class SpecialPage {
         *
         * @param $alias String
         * @return String or false
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function resolveAlias( $alias ) {
-               global $wgContLang;
-
-               if ( !self::$mListInitialised ) self::initList();
-               if ( is_null( self::$mAliases ) ) self::initAliasList();
-               $caseFoldedAlias = $wgContLang->caseFold( $alias );
-               $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
-               if ( isset( self::$mAliases[$caseFoldedAlias] ) ) {
-                       return self::$mAliases[$caseFoldedAlias];
-               } else {
-                       return false;
-               }
+               list( $name, /*...*/ ) = SpecialPageFactory::resolveAlias( $alias );
+               return $name;
        }
 
        /**
@@ -289,16 +237,10 @@ class SpecialPage {
         *
         * @param $alias String
         * @return Array
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function resolveAliasWithSubpage( $alias ) {
-               $bits = explode( '/', $alias, 2 );
-               $name = self::resolveAlias( $bits[0] );
-               if( !isset( $bits[1] ) ) { // bug 2087
-                       $par = null;
-               } else {
-                       $par = $bits[1];
-               }
-               return array( $name, $par );
+               return SpecialPageFactory::resolveAlias( $alias );
        }
 
        /**
@@ -307,14 +249,11 @@ class SpecialPage {
         * an associative record to $wgSpecialPages. This avoids autoloading SpecialPage.
         *
         * @param $page SpecialPage
-        * Deprecated in 1.7, warnings in 1.17, might be removed in 1.20
+        * @deprecated in 1.7, warnings in 1.17, might be removed in 1.20
         */
        static function addPage( &$page ) {
                wfDeprecated( __METHOD__ );
-               if ( !self::$mListInitialised ) {
-                       self::initList();
-               }
-               self::$mList[$page->mName] = $page;
+               SpecialPageFactory::getList()->{$page->mName} = $page;
        }
 
        /**
@@ -322,47 +261,30 @@ class SpecialPage {
         *
         * @param $page Mixed: SpecialPage or string
         * @param $group String
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function setGroup( $page, $group ) {
-               global $wgSpecialPageGroups;
-               $name = is_object($page) ? $page->mName : $page;
-               $wgSpecialPageGroups[$name] = $group;
+               return SpecialPageFactory::setGroup( $page, $group );
        }
 
        /**
         * Add a page to a certain display group for Special:SpecialPages
         *
         * @param $page SpecialPage
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getGroup( &$page ) {
-               global $wgSpecialPageGroups;
-               static $specialPageGroupsCache = array();
-               if( isset($specialPageGroupsCache[$page->mName]) ) {
-                       return $specialPageGroupsCache[$page->mName];
-               }
-               $msg = wfMessage('specialpages-specialpagegroup-'.strtolower($page->mName));
-               if ( !$msg->isBlank() ) {
-                       $group = $msg->text();
-               } else {
-                       $group = isset($wgSpecialPageGroups[$page->mName])
-                               ? $wgSpecialPageGroups[$page->mName]
-                               : '-';
-               }
-               if( $group == '-' ) $group = 'other';
-               $specialPageGroupsCache[$page->mName] = $group;
-               return $group;
+               return SpecialPageFactory::getGroup( $page );
        }
 
        /**
         * Remove a special page from the list
         * Formerly used to disable expensive or dangerous special pages. The
         * preferred method is now to add a SpecialPage_initList hook.
+        * @deprecated since 1.18
         */
        static function removePage( $name ) {
-               if ( !self::$mListInitialised ) {
-                       self::initList();
-               }
-               unset( self::$mList[$name] );
+               unset( SpecialPageFactory::getList()->$name );
        }
 
        /**
@@ -370,24 +292,10 @@ class SpecialPage {
         *
         * @param $name String: name of a special page
         * @return Boolean: true if a special page exists with this name
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function exists( $name ) {
-               global $wgContLang;
-               if ( !self::$mListInitialised ) {
-                       self::initList();
-               }
-               if( !self::$mAliases ) {
-                       self::initAliasList();
-               }
-
-               # Remove special pages inline parameters:
-               $bits = explode( '/', $name );
-               $name = $wgContLang->caseFold($bits[0]);
-
-               return
-                       array_key_exists( $name, self::$mList )
-                       or array_key_exists( $name, self::$mAliases )
-               ;
+               return SpecialPageFactory::exists( $name );
        }
 
        /**
@@ -395,26 +303,10 @@ class SpecialPage {
         *
         * @param $name String
         * @return SpecialPage object or null if the page doesn't exist
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getPage( $name ) {
-               if ( !self::$mListInitialised ) {
-                       self::initList();
-               }
-               if ( array_key_exists( $name, self::$mList ) ) {
-                       $rec = self::$mList[$name];
-                       if ( is_string( $rec ) ) {
-                               $className = $rec;
-                               self::$mList[$name] = new $className;
-                       } elseif ( is_array( $rec ) ) {
-                               // @deprecated officially since 1.18, unofficially since forever
-                               wfDebug( "Array syntax for \$wgSpecialPages is deprecated, define a subclass of SpecialPage instead." );
-                               $className = array_shift( $rec );
-                               self::$mList[$name] = MWFunction::newObj( $className, $rec );
-                       }
-                       return self::$mList[$name];
-               } else {
-                       return null;
-               }
+               return SpecialPageFactory::getPage( $name );
        }
 
        /**
@@ -422,14 +314,10 @@ class SpecialPage {
         * is no such special page.
         *
         * @return SpecialPage object or null if the page doesn't exist
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getPageByAlias( $alias ) {
-               $realName = self::resolveAlias( $alias );
-               if ( $realName ) {
-                       return self::getPage( $realName );
-               } else {
-                       return null;
-               }
+               return SpecialPageFactory::getPage( $alias );
        }
 
        /**
@@ -437,46 +325,20 @@ class SpecialPage {
         * for the current user, and everyone.
         *
         * @return Associative array mapping page's name to its SpecialPage object
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getUsablePages() {
-               global $wgUser;
-               if ( !self::$mListInitialised ) {
-                       self::initList();
-               }
-               $pages = array();
-
-               foreach ( self::$mList as $name => $rec ) {
-                       $page = self::getPage( $name );
-                       if ( $page->isListed()
-                               && (
-                                       !$page->isRestricted()
-                                       || $page->userCanExecute( $wgUser )
-                               )
-                       ) {
-                               $pages[$name] = $page;
-                       }
-               }
-               return $pages;
+               return SpecialPageFactory::getUsablePages();
        }
 
        /**
         * Return categorised listable special pages for all users
         *
         * @return Associative array mapping page's name to its SpecialPage object
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getRegularPages() {
-               if ( !self::$mListInitialised ) {
-                       self::initList();
-               }
-               $pages = array();
-
-               foreach ( self::$mList as $name => $rec ) {
-                       $page = self::getPage( $name );
-                       if ( $page->isListed() && !$page->isRestricted() ) {
-                               $pages[$name] = $page;
-                       }
-               }
-               return $pages;
+               return SpecialPageFactory::getRegularPages();
        }
 
        /**
@@ -484,25 +346,10 @@ class SpecialPage {
         * for the current user, but not for everyone
         *
         * @return Associative array mapping page's name to its SpecialPage object
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getRestrictedPages() {
-               global $wgUser;
-               if( !self::$mListInitialised ) {
-                       self::initList();
-               }
-               $pages = array();
-
-               foreach( self::$mList as $name => $rec ) {
-                       $page = self::getPage( $name );
-                       if(
-                               $page->isListed()
-                               && $page->isRestricted()
-                               && $page->userCanExecute( $wgUser )
-                       ) {
-                               $pages[$name] = $page;
-                       }
-               }
-               return $pages;
+               return SpecialPageFactory::getRestrictedPages();
        }
 
        /**
@@ -516,81 +363,10 @@ class SpecialPage {
         * @param $title          Title object
         * @param $context        RequestContext
         * @param $including      Bool output is being captured for use in {{special:whatever}}
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        public static function executePath( &$title, RequestContext &$context, $including = false ) {
-               wfProfileIn( __METHOD__ );
-
-               # FIXME: redirects broken due to this call
-               $bits = explode( '/', $title->getDBkey(), 2 );
-               $name = $bits[0];
-               if( !isset( $bits[1] ) ) { // bug 2087
-                       $par = null;
-               } else {
-                       $par = $bits[1];
-               }
-               $page = SpecialPage::getPageByAlias( $name );
-               # Nonexistent?
-               if ( !$page ) {
-                       $context->output->setArticleRelated( false );
-                       $context->output->setRobotPolicy( 'noindex,nofollow' );
-                       $context->output->setStatusCode( 404 );
-                       $context->output->showErrorPage( 'nosuchspecialpage', 'nospecialpagetext' );
-                       wfProfileOut( __METHOD__ );
-                       return false;
-               }
-               
-               # Page exists, set the context
-               $page->setContext( $context );
-
-               # Check for redirect
-               if ( !$including ) {
-                       $redirect = $page->getRedirect( $par );
-                       $query = $page->getRedirectQuery();
-                       if ( $redirect instanceof Title ) {
-                               $url = $redirect->getFullUrl( $query );
-                               $context->output->redirect( $url );
-                               wfProfileOut( __METHOD__ );
-                               return $redirect;
-                       } elseif( $redirect === true ) {
-                               global $wgScript;
-                               $url = $wgScript . '?' . wfArrayToCGI( $query );
-                               $context->output->redirect( $url );
-                               wfProfileOut( __METHOD__ );
-                               return $redirect;
-                       }
-               }
-
-               # Redirect to canonical alias for GET commands
-               # Not for POST, we'd lose the post data, so it's best to just distribute
-               # the request. Such POST requests are possible for old extensions that
-               # generate self-links without being aware that their default name has
-               # changed.
-               if ( !$including && $name != $page->getLocalName() && !$context->request->wasPosted() ) {
-                       $query = $_GET;
-                       unset( $query['title'] );
-                       $query = wfArrayToCGI( $query );
-                       $title = $page->getTitle( $par );
-                       $url = $title->getFullUrl( $query );
-                       $context->output->redirect( $url );
-                       wfProfileOut( __METHOD__ );
-                       return $redirect;
-               }
-
-               if ( $including && !$page->includable() ) {
-                       wfProfileOut( __METHOD__ );
-                       return false;
-               } elseif ( !$including ) {
-                       $context->title = $page->getTitle();
-               }
-               $page->including( $including );
-
-               // Execute special page
-               $profName = 'Special:' . $page->name();
-               wfProfileIn( $profName );
-               $page->execute( $par );
-               wfProfileOut( $profName );
-               wfProfileOut( __METHOD__ );
-               return true;
+               return SpecialPageFactory::executePath( $title, $context, $including );
        }
 
        /**
@@ -599,24 +375,10 @@ class SpecialPage {
         * a redirect.
         *
         * @return String: HTML fragment
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function capturePath( &$title ) {
-               global $wgOut, $wgTitle;
-
-               $oldTitle = $wgTitle;
-               $oldOut = $wgOut;
-               
-               $context = new RequestContext;
-               $context->setTitle( $title );
-               $wgOut = $context->getOutput();
-
-               $ret = SpecialPage::executePath( $title, $context, true );
-               if ( $ret === true ) {
-                       $ret = $wgOut->getHTML();
-               }
-               $wgTitle = $oldTitle;
-               $wgOut = $oldOut;
-               return $ret;
+               return SpecialPageFactory::capturePath( $title );
        }
 
        /**
@@ -626,33 +388,10 @@ class SpecialPage {
         * @param $subpage Mixed: boolean false, or string
         *
         * @return String
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getLocalNameFor( $name, $subpage = false ) {
-               global $wgContLang;
-               $aliases = $wgContLang->getSpecialPageAliases();
-               if ( isset( $aliases[$name][0] ) ) {
-                       $name = $aliases[$name][0];
-               } else {
-                       // Try harder in case someone misspelled the correct casing
-                       $found = false;
-                       foreach ( $aliases as $n => $values ) {
-                               if ( strcasecmp( $name, $n ) === 0 ) {
-                                       wfWarn( "Found alias defined for $n when searching for " .
-                                               "special page aliases for $name. Case mismatch?" );
-                                       $name = $values[0];
-                                       $found = true;
-                                       break;
-                               }
-                       }
-                       if ( !$found ) {
-                               wfWarn( "Did not find alias for special page '$name'. " .
-                                       "Perhaps no aliases are defined for it?" );
-                       }
-               }
-               if ( $subpage !== false && !is_null( $subpage ) ) {
-                       $name = "$name/$subpage";
-               }
-               return $wgContLang->ucfirst( $name );
+               return SpecialPageFactory::getLocalNameFor( $name, $subpage );
        }
 
        /**
@@ -660,8 +399,8 @@ class SpecialPage {
         *
         * @return Title object
         */
-       static function getTitleFor( $name, $subpage = false ) {
-               $name = self::getLocalNameFor( $name, $subpage );
+       public static function getTitleFor( $name, $subpage = false ) {
+               $name = SpecialPageFactory::getLocalNameFor( $name, $subpage );
                if ( $name ) {
                        return Title::makeTitle( NS_SPECIAL, $name );
                } else {
@@ -674,8 +413,8 @@ class SpecialPage {
         *
         * @return Title object or null if the page doesn't exist
         */
-       static function getSafeTitleFor( $name, $subpage = false ) {
-               $name = self::getLocalNameFor( $name, $subpage );
+       public static function getSafeTitleFor( $name, $subpage = false ) {
+               $name = SpecialPageFactory::getLocalNameFor( $name, $subpage );
                if ( $name ) {
                        return Title::makeTitleSafe( NS_SPECIAL, $name );
                } else {
@@ -687,14 +426,10 @@ class SpecialPage {
         * Get a title for a given alias
         *
         * @return Title or null if there is no such alias
+        * @deprecated since 1.18 call SpecialPageFactory method directly
         */
        static function getTitleForAlias( $alias ) {
-               $name = self::resolveAlias( $alias );
-               if ( $name ) {
-                       return self::getTitleFor( $name );
-               } else {
-                       return null;
-               }
+               return SpecialPageFactory::getTitleForAlias( $alias );
        }
 
        /**
@@ -800,7 +535,7 @@ class SpecialPage {
         */
        function getLocalName() {
                if ( !isset( $this->mLocalName ) ) {
-                       $this->mLocalName = self::getLocalNameFor( $this->mName );
+                       $this->mLocalName = SpecialPageFactory::getLocalNameFor( $this->mName );
                }
                return $this->mLocalName;
        }
@@ -846,7 +581,7 @@ class SpecialPage {
         * Output an error message telling the user what access level they have to have
         */
        function displayRestrictionError() {
-               $this->getOutput()->permissionRequired( $this->mRestriction );
+               throw new PermissionsError( $this->mRestriction );
        }
 
        /**
@@ -928,6 +663,8 @@ class SpecialPage {
 
        /**
         * Set whether this page is listed in Special:Specialpages, at run-time
+        *
+        * @return Bool
         */
        function setListed( $listed ) {
                return wfSetVar( $this->mListed, $listed );
@@ -936,6 +673,8 @@ class SpecialPage {
        /**
         * If the special page is a redirect, then get the Title object it redirects to.
         * False otherwise.
+        *
+        * @return Title|false
         */
        function getRedirect( $subpage ) {
                return false;
@@ -971,7 +710,7 @@ class SpecialPage {
         * @param $context RequestContext
         * @since 1.18
         */
-       protected function setContext( $context ) {
+       public function setContext( $context ) {
                $this->mContext = $context;
        }
 
@@ -1090,9 +829,9 @@ abstract class SpecialRedirectToSpecial extends UnlistedSpecialPage {
 
        function getRedirect( $subpage ) {
                if ( $this->redirSubpage === false ) {
-                       return SpecialPage::getTitleFor( $this->redirName, $subpage );
+                       return SpecialPageFactory::getTitleFor( $this->redirName, $subpage );
                } else {
-                       return SpecialPage::getTitleFor( $this->redirName, $this->redirSubpage );
+                       return SpecialPageFactory::getTitleFor( $this->redirName, $this->redirSubpage );
                }
        }
 }
@@ -1187,7 +926,7 @@ class SpecialMycontributions extends UnlistedSpecialPage {
 
        function getRedirect( $subpage ) {
                global $wgUser;
-               return SpecialPage::getTitleFor( 'Contributions', $wgUser->getName() );
+               return SpecialPageFactory::getTitleFor( 'Contributions', $wgUser->getName() );
        }
 }
 
@@ -1202,7 +941,7 @@ class SpecialMyuploads extends UnlistedSpecialPage {
 
        function getRedirect( $subpage ) {
                global $wgUser;
-               return SpecialPage::getTitleFor( 'Listfiles', $wgUser->getName() );
+               return SpecialPageFactory::getTitleFor( 'Listfiles', $wgUser->getName() );
        }
 }
 
diff --git a/includes/SpecialPageFactory.php b/includes/SpecialPageFactory.php
new file mode 100644 (file)
index 0000000..2ccf966
--- /dev/null
@@ -0,0 +1,543 @@
+<?php
+/**
+ * SpecialPage: handling special pages and lists thereof.
+ *
+ * To add a special page in an extension, add to $wgSpecialPages either
+ * an object instance or an array containing the name and constructor
+ * parameters. The latter is preferred for performance reasons.
+ *
+ * The object instantiated must be either an instance of SpecialPage or a
+ * sub-class thereof. It must have an execute() method, which sends the HTML
+ * for the special page to $wgOut. The parent class has an execute() method
+ * which distributes the call to the historical global functions. Additionally,
+ * execute() also checks if the user has the necessary access privileges
+ * and bails out if not.
+ *
+ * To add a core special page, use the similar static list in
+ * SpecialPage::$mList. To remove a core static special page at runtime, use
+ * a SpecialPage_initList hook.
+ *
+ * @file
+ * @ingroup SpecialPage
+ * @defgroup SpecialPage SpecialPage
+ */
+
+/**
+ * Factory for handling the special page list and generating SpecialPage objects
+ * @ingroup SpecialPage
+ */
+class SpecialPageFactory {
+
+       /**
+        * List of special page names to the subclass of SpecialPage which handles them.
+        */
+       private static $mList = array(
+               // Maintenance Reports
+               'BrokenRedirects'           => 'BrokenRedirectsPage',
+               'Deadendpages'              => 'DeadendpagesPage',
+               'DoubleRedirects'           => 'DoubleRedirectsPage',
+               'Longpages'                 => 'LongpagesPage',
+               'Ancientpages'              => 'AncientpagesPage',
+               'Lonelypages'               => 'LonelypagesPage',
+               'Fewestrevisions'           => 'FewestrevisionsPage',
+               'Withoutinterwiki'          => 'WithoutinterwikiPage',
+               'Protectedpages'            => 'SpecialProtectedpages',
+               'Protectedtitles'           => 'SpecialProtectedtitles',
+               'Shortpages'                => 'ShortpagesPage',
+               'Uncategorizedcategories'   => 'UncategorizedcategoriesPage',
+               'Uncategorizedimages'       => 'UncategorizedimagesPage',
+               'Uncategorizedpages'        => 'UncategorizedpagesPage',
+               'Uncategorizedtemplates'    => 'UncategorizedtemplatesPage',
+               'Unusedcategories'          => 'UnusedcategoriesPage',
+               'Unusedimages'              => 'UnusedimagesPage',
+               'Unusedtemplates'           => 'UnusedtemplatesPage',
+               'Unwatchedpages'            => 'UnwatchedpagesPage',
+               'Wantedcategories'          => 'WantedcategoriesPage',
+               'Wantedfiles'               => 'WantedfilesPage',
+               'Wantedpages'               => 'WantedpagesPage',
+               'Wantedtemplates'           => 'WantedtemplatesPage',
+
+               // List of pages
+               'Allpages'                  => 'SpecialAllpages',
+               'Prefixindex'               => 'SpecialPrefixindex',
+               'Categories'                => 'SpecialCategories',
+               'Disambiguations'           => 'DisambiguationsPage',
+               'Listredirects'             => 'ListredirectsPage',
+
+               // Login/create account
+               'Userlogin'                 => 'LoginForm',
+               'CreateAccount'             => 'SpecialCreateAccount',
+
+               // Users and rights
+               'Block'                     => 'SpecialBlock',
+               'Unblock'                   => 'SpecialUnblock',
+               'BlockList'                 => 'SpecialBlockList',
+               'Resetpass'                 => 'SpecialResetpass',
+               'DeletedContributions'      => 'DeletedContributionsPage',
+               'Preferences'               => 'SpecialPreferences',
+               'Contributions'             => 'SpecialContributions',
+               'Listgrouprights'           => 'SpecialListGroupRights',
+               'Listusers'                 => 'SpecialListUsers' ,
+               'Listadmins'                => 'SpecialListAdmins',
+               'Listbots'                  => 'SpecialListBots',
+               'Activeusers'               => 'SpecialActiveUsers',
+               'Userrights'                => 'UserrightsPage',
+               'EditWatchlist'             => 'SpecialEditWatchlist',
+
+               // Recent changes and logs
+               'Newimages'                 => 'SpecialNewFiles',
+               'Log'                       => 'SpecialLog',
+               'Watchlist'                 => 'SpecialWatchlist',
+               'Newpages'                  => 'SpecialNewpages',
+               'Recentchanges'             => 'SpecialRecentchanges',
+               'Recentchangeslinked'       => 'SpecialRecentchangeslinked',
+               'Tags'                      => 'SpecialTags',
+
+               // Media reports and uploads
+               'Listfiles'                 => 'SpecialListFiles',
+               'Filepath'                  => 'SpecialFilepath',
+               'MIMEsearch'                => 'MIMEsearchPage',
+               'FileDuplicateSearch'       => 'FileDuplicateSearchPage',
+               'Upload'                    => 'SpecialUpload',
+               'UploadStash'               => 'SpecialUploadStash',
+
+               // Wiki data and tools
+               'Statistics'                => 'SpecialStatistics',
+               'Allmessages'               => 'SpecialAllmessages',
+               'Version'                   => 'SpecialVersion',
+               'Lockdb'                    => 'SpecialLockdb',
+               'Unlockdb'                  => 'SpecialUnlockdb',
+
+               // Redirecting special pages
+               'LinkSearch'                => 'LinkSearchPage',
+               'Randompage'                => 'Randompage',
+               'Randomredirect'            => 'SpecialRandomredirect',
+
+               // High use pages
+               'Mostlinkedcategories'      => 'MostlinkedCategoriesPage',
+               'Mostimages'                => 'MostimagesPage',
+               'Mostlinked'                => 'MostlinkedPage',
+               'Mostlinkedtemplates'       => 'MostlinkedTemplatesPage',
+               'Mostcategories'            => 'MostcategoriesPage',
+               'Mostrevisions'             => 'MostrevisionsPage',
+
+               // Page tools
+               'ComparePages'              => 'SpecialComparePages',
+               'Export'                    => 'SpecialExport',
+               'Import'                    => 'SpecialImport',
+               'Undelete'                  => 'SpecialUndelete',
+               'Whatlinkshere'             => 'SpecialWhatlinkshere',
+               'MergeHistory'              => 'SpecialMergeHistory',
+
+               // Other
+               'Booksources'               => 'SpecialBookSources',
+
+               // Unlisted / redirects
+               'Blankpage'                 => 'SpecialBlankpage',
+               'Blockme'                   => 'SpecialBlockme',
+               'Emailuser'                 => 'SpecialEmailUser',
+               'Movepage'                  => 'MovePageForm',
+               'Mycontributions'           => 'SpecialMycontributions',
+               'Mypage'                    => 'SpecialMypage',
+               'Mytalk'                    => 'SpecialMytalk',
+               'Myuploads'                 => 'SpecialMyuploads',
+               'PermanentLink'             => 'SpecialPermanentLink',
+               'Revisiondelete'            => 'SpecialRevisionDelete',
+               'Specialpages'              => 'SpecialSpecialpages',
+               'Userlogout'                => 'SpecialUserlogout',
+       );
+
+       private static $mAliases;
+
+       /**
+        * Initialise the special page list
+        * This must be called before accessing SpecialPage::$mList
+        */
+       static function getList() {
+               global $wgSpecialPages;
+               global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication;
+
+               if ( !is_object( self::$mList ) ) {
+                       wfProfileIn( __METHOD__ );
+
+                       if ( !$wgDisableCounters ) {
+                               self::$mList['Popularpages'] = 'PopularpagesPage';
+                       }
+
+                       if ( !$wgDisableInternalSearch ) {
+                               self::$mList['Search'] = 'SpecialSearch';
+                       }
+
+                       if ( $wgEmailAuthentication ) {
+                               self::$mList['Confirmemail'] = 'EmailConfirmation';
+                               self::$mList['Invalidateemail'] = 'EmailInvalidation';
+                       }
+
+                       // Add extension special pages
+                       self::$mList = array_merge( self::$mList, $wgSpecialPages );
+
+                       // Run hooks
+                       // This hook can be used to remove undesired built-in special pages
+                       wfRunHooks( 'SpecialPage_initList', array( &self::$mList ) );
+
+                       // Cast to object: func()[$key] doesn't work, but func()->$key does
+                       settype( self::$mList, 'object' );
+
+                       wfProfileOut( __METHOD__ );
+               }
+               return self::$mList;
+       }
+
+       static function getAliasList() {
+               if ( !is_object( self::$mAliases ) ) {
+                       global $wgContLang;
+                       $aliases = $wgContLang->getSpecialPageAliases();
+
+                       // Objects are passed by reference by default, need to create a copy
+                       $missingPages = clone self::getList();
+
+                       self::$mAliases = array();
+                       foreach ( $aliases as $realName => $aliasList ) {
+                               foreach ( $aliasList as $alias ) {
+                                       self::$mAliases[$wgContLang->caseFold( $alias )] = $realName;
+                               }
+                               unset( $missingPages->$realName );
+                       }
+                       foreach ( $missingPages as $name => $stuff ) {
+                               self::$mAliases[$wgContLang->caseFold( $name )] = $name;
+                       }
+
+                       // Cast to object: func()[$key] doesn't work, but func()->$key does
+                       self::$mAliases = (object)self::$mAliases;
+               }
+               return self::$mAliases;
+       }
+
+       /**
+        * Given a special page name with a possible subpage, return an array
+        * where the first element is the special page name and the second is the
+        * subpage.
+        *
+        * @param $alias String
+        * @return Array( String, String|null ), or array( null, null ) if the page is invalid
+        */
+       public static function resolveAlias( $alias ) {
+               global $wgContLang;
+               $bits = explode( '/', $alias, 2 );
+
+               $caseFoldedAlias = $wgContLang->caseFold( $bits[0] );
+               $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias );
+               if ( isset( self::getAliasList()->$caseFoldedAlias ) ) {
+                       $name = self::getAliasList()->$caseFoldedAlias;
+               } else {
+                       return array( null, null );
+               }
+
+               if ( !isset( $bits[1] ) ) { // bug 2087
+                       $par = null;
+               } else {
+                       $par = $bits[1];
+               }
+
+               return array( $name, $par );
+       }
+
+       /**
+        * Add a page to a certain display group for Special:SpecialPages
+        *
+        * @param $page Mixed: SpecialPage or string
+        * @param $group String
+        */
+       public static function setGroup( $page, $group ) {
+               global $wgSpecialPageGroups;
+               $name = is_object( $page ) ? $page->mName : $page;
+               $wgSpecialPageGroups[$name] = $group;
+       }
+
+       /**
+        * Add a page to a certain display group for Special:SpecialPages
+        *
+        * @param $page SpecialPage
+        */
+       public static function getGroup( &$page ) {
+               global $wgSpecialPageGroups;
+               static $specialPageGroupsCache = array();
+               if ( isset( $specialPageGroupsCache[$page->mName] ) ) {
+                       return $specialPageGroupsCache[$page->mName];
+               }
+               $msg = wfMessage( 'specialpages-specialpagegroup-' . strtolower( $page->mName ) );
+               if ( !$msg->isBlank() ) {
+                       $group = $msg->text();
+               } else {
+                       $group = isset( $wgSpecialPageGroups[$page->mName] )
+                               ? $wgSpecialPageGroups[$page->mName]
+                               : '-';
+               }
+               if ( $group == '-' ) {
+                       $group = 'other';
+               }
+               $specialPageGroupsCache[$page->mName] = $group;
+               return $group;
+       }
+
+       /**
+        * Check if a given name exist as a special page or as a special page alias
+        *
+        * @param $name String: name of a special page
+        * @return Boolean: true if a special page exists with this name
+        */
+       public static function exists( $name ) {
+               list( $title, /*...*/ ) = self::resolveAlias( $name );
+               return property_exists( self::getList(), $title );
+       }
+
+       /**
+        * Find the object with a given name and return it (or NULL)
+        *
+        * @param $name String Special page name, may be localised and/or an alias
+        * @return SpecialPage object or null if the page doesn't exist
+        */
+       public static function getPage( $name ) {
+               list( $realName, /*...*/ ) = self::resolveAlias( $name );
+               if ( property_exists( self::getList(), $realName ) ) {
+                       $rec = self::getList()->$realName;
+                       if ( is_string( $rec ) ) {
+                               $className = $rec;
+                               self::getList()->$realName = new $className;
+                       } elseif ( is_array( $rec ) ) {
+                               // @deprecated, officially since 1.18, unofficially since forever
+                               wfDebug( "Array syntax for \$wgSpecialPages is deprecated, define a subclass of SpecialPage instead." );
+                               $className = array_shift( $rec );
+                               self::getList()->$realName = MWFunction::newObj( $className, $rec );
+                       }
+                       return self::getList()->$realName;
+               } else {
+                       return null;
+               }
+       }
+
+       /**
+        * Return categorised listable special pages which are available
+        * for the current user, and everyone.
+        *
+        * @return Array( String => Specialpage )
+        */
+       public static function getUsablePages() {
+               global $wgUser;
+               $pages = array();
+               foreach ( self::getList() as $name => $rec ) {
+                       $page = self::getPage( $name );
+                       if ( $page->isListed()
+                               && (
+                                       !$page->isRestricted()
+                                       || $page->userCanExecute( $wgUser )
+                               )
+                       ) {
+                               $pages[$name] = $page;
+                       }
+               }
+               return $pages;
+       }
+
+       /**
+        * Return categorised listable special pages for all users
+        *
+        * @return Array( String => Specialpage )
+        */
+       public static function getRegularPages() {
+               $pages = array();
+               foreach ( self::getList() as $name => $rec ) {
+                       $page = self::getPage( $name );
+                       if ( $page->isListed() && !$page->isRestricted() ) {
+                               $pages[$name] = $page;
+                       }
+               }
+               return $pages;
+       }
+
+       /**
+        * Return categorised listable special pages which are available
+        * for the current user, but not for everyone
+        *
+        * @return Array( String => Specialpage )
+        */
+       public static function getRestrictedPages() {
+               global $wgUser;
+               $pages = array();
+               foreach ( self::getList() as $name => $rec ) {
+                       $page = self::getPage( $name );
+                       if (
+                               $page->isListed()
+                               && $page->isRestricted()
+                               && $page->userCanExecute( $wgUser )
+                       ) {
+                               $pages[$name] = $page;
+                       }
+               }
+               return $pages;
+       }
+
+       /**
+        * Execute a special page path.
+        * The path may contain parameters, e.g. Special:Name/Params
+        * Extracts the special page name and call the execute method, passing the parameters
+        *
+        * Returns a title object if the page is redirected, false if there was no such special
+        * page, and true if it was successful.
+        *
+        * @param $title          Title object
+        * @param $context        RequestContext
+        * @param $including      Bool output is being captured for use in {{special:whatever}}
+        */
+       public static function executePath( Title &$title, RequestContext &$context, $including = false ) {
+               wfProfileIn( __METHOD__ );
+
+               // FIXME: redirects broken due to this call
+               $bits = explode( '/', $title->getDBkey(), 2 );
+               $name = $bits[0];
+               if ( !isset( $bits[1] ) ) { // bug 2087
+                       $par = null;
+               } else {
+                       $par = $bits[1];
+               }
+               $page = self::getPage( $name );
+               // Nonexistent?
+               if ( !$page ) {
+                       $context->output->setArticleRelated( false );
+                       $context->output->setRobotPolicy( 'noindex,nofollow' );
+                       $context->output->setStatusCode( 404 );
+                       $context->output->showErrorPage( 'nosuchspecialpage', 'nospecialpagetext' );
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+
+               // Page exists, set the context
+               $page->setContext( $context );
+
+               // Check for redirect
+               if ( !$including ) {
+                       $redirect = $page->getRedirect( $par );
+                       $query = $page->getRedirectQuery();
+                       if ( $redirect instanceof Title ) {
+                               $url = $redirect->getFullUrl( $query );
+                               $context->output->redirect( $url );
+                               wfProfileOut( __METHOD__ );
+                               return $redirect;
+                       } elseif ( $redirect === true ) {
+                               global $wgScript;
+                               $url = $wgScript . '?' . wfArrayToCGI( $query );
+                               $context->output->redirect( $url );
+                               wfProfileOut( __METHOD__ );
+                               return $redirect;
+                       }
+
+                       // Redirect to canonical alias for GET commands
+                       // Not for POST, we'd lose the post data, so it's best to just distribute
+                       // the request. Such POST requests are possible for old extensions that
+                       // generate self-links without being aware that their default name has
+                       // changed.
+                       if ( $name != $page->getLocalName() && !$context->request->wasPosted() ) {
+                               $query = $_GET;
+                               unset( $query['title'] );
+                               $query = wfArrayToCGI( $query );
+                               $title = $page->getTitle( $par );
+                               $url = $title->getFullUrl( $query );
+                               $context->output->redirect( $url );
+                               wfProfileOut( __METHOD__ );
+                               return $redirect;
+                       } else {
+                               $context->title = $page->getTitle();
+                       }
+
+               } elseif ( !$page->includable() ) {
+                       wfProfileOut( __METHOD__ );
+                       return false;
+               }
+
+               $page->including( $including );
+
+               // Execute special page
+               $profName = 'Special:' . $page->name();
+               wfProfileIn( $profName );
+               $page->execute( $par );
+               wfProfileOut( $profName );
+               wfProfileOut( __METHOD__ );
+               return true;
+       }
+
+       /**
+        * Just like executePath() except it returns the HTML instead of outputting it
+        * Returns false if there was no such special page, or a title object if it was
+        * a redirect.
+        *
+        * @return String: HTML fragment
+        */
+       static function capturePath( &$title ) {
+               global $wgOut, $wgTitle;
+
+               $oldTitle = $wgTitle;
+               $oldOut = $wgOut;
+
+               $context = new RequestContext;
+               $context->setTitle( $title );
+               $wgOut = $context->getOutput();
+
+               $ret = self::executePath( $title, $context, true );
+               if ( $ret === true ) {
+                       $ret = $wgOut->getHTML();
+               }
+               $wgTitle = $oldTitle;
+               $wgOut = $oldOut;
+               return $ret;
+       }
+
+       /**
+        * Get the local name for a specified canonical name
+        *
+        * @param $name String
+        * @param $subpage String|Bool
+        *
+        * @return String
+        */
+       static function getLocalNameFor( $name, $subpage = false ) {
+               global $wgContLang;
+               $aliases = $wgContLang->getSpecialPageAliases();
+               if ( isset( $aliases[$name][0] ) ) {
+                       $name = $aliases[$name][0];
+               } else {
+                       // Try harder in case someone misspelled the correct casing
+                       $found = false;
+                       foreach ( $aliases as $n => $values ) {
+                               if ( strcasecmp( $name, $n ) === 0 ) {
+                                       wfWarn( "Found alias defined for $n when searching for " .
+                                               "special page aliases for $name. Case mismatch?" );
+                                       $name = $values[0];
+                                       $found = true;
+                                       break;
+                               }
+                       }
+                       if ( !$found ) {
+                               wfWarn( "Did not find alias for special page '$name'. " .
+                                       "Perhaps no aliases are defined for it?" );
+                       }
+               }
+               if ( $subpage !== false && !is_null( $subpage ) ) {
+                       $name = "$name/$subpage";
+               }
+               return $wgContLang->ucfirst( $name );
+       }
+
+       /**
+        * Get a title for a given alias
+        *
+        * @return Title or null if there is no such alias
+        */
+       static function getTitleForAlias( $alias ) {
+               $name = self::resolveAlias( $alias );
+               if ( $name ) {
+                       return self::getTitleFor( $name );
+               } else {
+                       return null;
+               }
+       }
+}
\ No newline at end of file
index 819ec46..5f15032 100644 (file)
@@ -1812,7 +1812,7 @@ class Title {
                        # If it's a special page, ditch the subpage bit and check again
                        if ( $this->getNamespace() == NS_SPECIAL ) {
                                $name = $this->getDBkey();
-                               list( $name, /* $subpage */ ) = SpecialPage::resolveAliasWithSubpage( $name );
+                               list( $name, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $name );
                                if ( $name === false ) {
                                        # Invalid special page, but we show standard login required message
                                        return false;
@@ -3811,7 +3811,7 @@ class Title {
                                return (bool)wfFindFile( $this );
                        case NS_SPECIAL:
                                // valid special page
-                               return SpecialPage::exists( $this->getDBkey() );
+                               return SpecialPageFactory::exists( $this->getDBkey() );
                        case NS_MAIN:
                                // selflink, possibly with fragment
                                return $this->mDbkeyform == '';
@@ -4038,7 +4038,7 @@ class Title {
         */
        public function isSpecial( $name ) {
                if ( $this->getNamespace() == NS_SPECIAL ) {
-                       list( $thisName, /* $subpage */ ) = SpecialPage::resolveAliasWithSubpage( $this->getDBkey() );
+                       list( $thisName, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $this->getDBkey() );
                        if ( $name == $thisName ) {
                                return true;
                        }
@@ -4054,9 +4054,9 @@ class Title {
         */
        public function fixSpecialName() {
                if ( $this->getNamespace() == NS_SPECIAL ) {
-                       $canonicalName = SpecialPage::resolveAlias( $this->mDbkeyform );
+                       list( $canonicalName, /*...*/ ) = SpecialPageFactory::resolveAlias( $this->mDbkeyform );
                        if ( $canonicalName ) {
-                               $localName = SpecialPage::getLocalNameFor( $canonicalName );
+                               $localName = SpecialPageFactory::getLocalNameFor( $canonicalName );
                                if ( $localName != $this->mDbkeyform ) {
                                        return Title::makeTitle( NS_SPECIAL, $localName );
                                }
index d8ad709..e3c1726 100644 (file)
@@ -212,7 +212,7 @@ class MediaWiki {
                        && !count( array_diff( array_keys( $this->context->request->getValues() ), array( 'action', 'title' ) ) ) )
                {
                        if ( $this->context->title->getNamespace() == NS_SPECIAL ) {
-                               list( $name, $subpage ) = SpecialPage::resolveAliasWithSubpage( $this->context->title->getDBkey() );
+                               list( $name, $subpage ) = SpecialPageFactory::resolveAlias( $this->context->title->getDBkey() );
                                if ( $name ) {
                                        $this->context->title = SpecialPage::getTitleFor( $name, $subpage );
                                }
@@ -249,7 +249,7 @@ class MediaWiki {
                // Special pages
                } else if ( NS_SPECIAL == $this->context->title->getNamespace() ) {
                        // actions that need to be made when we have a special pages
-                       SpecialPage::executePath( $this->context->title, $this->context );
+                       SpecialPageFactory::executePath( $this->context->title, $this->context );
                } else {
                        // No match to special cases
                        wfProfileOut( __METHOD__ );
@@ -553,7 +553,7 @@ class MediaWiki {
                                break;
                        case 'revisiondelete':
                                // For show/hide submission from history page
-                               $special = SpecialPage::getPage( 'Revisiondelete' );
+                               $special = SpecialPageFactory::getPage( 'Revisiondelete' );
                                $special->execute( '' );
                                break;
                        default:
index 19a6d92..981bb87 100644 (file)
@@ -430,7 +430,7 @@ class ApiQuery extends ApiBase {
                        ApiQueryBase::addTitleInfo( $vals, $title );
                        $vals['special'] = '';
                        if ( $title->getNamespace() == NS_SPECIAL &&
-                                       !SpecialPage::exists( $title->getDbKey() ) ) {
+                                       !SpecialPageFactory::exists( $title->getDbKey() ) ) {
                                $vals['missing'] = '';
                        } elseif ( $title->getNamespace() == NS_MEDIA &&
                                        !wfFindFile( $title ) ) {
index e59550a..466c487 100644 (file)
@@ -653,7 +653,7 @@ class CoreParserFunctions {
        }
 
        static function special( $parser, $text ) {
-               list( $page, $subpage ) = SpecialPage::resolveAliasWithSubpage( $text );
+               list( $page, $subpage ) = SpecialPageFactory::resolveAlias( $text );
                if ( $page ) {
                        $title = SpecialPage::getTitleFor( $page, $subpage );
                        return $title;
index c367c89..13c91d8 100644 (file)
@@ -3252,7 +3252,7 @@ class Parser {
                                        && $this->mOptions->getAllowSpecialInclusion()
                                        && $this->ot['html'] )
                                {
-                                       $text = SpecialPage::capturePath( $title );
+                                       $text = SpecialPageFactory::capturePath( $title );
                                        if ( is_string( $text ) ) {
                                                $found = true;
                                                $isHTML = true;
index 6939bfb..13bc4c2 100644 (file)
@@ -51,7 +51,7 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
        private function getPageGroups() {
                global $wgSortSpecialPages;
 
-               $pages = SpecialPage::getUsablePages();
+               $pages = SpecialPageFactory::getUsablePages();
 
                if( !count( $pages ) ) {
                        # Yeah, that was pointless. Thanks for coming.
@@ -62,7 +62,7 @@ class SpecialSpecialpages extends UnlistedSpecialPage {
                $groups = array();
                foreach ( $pages as $page ) {
                        if ( $page->isListed() ) {
-                               $group = SpecialPage::getGroup( $page );
+                               $group = SpecialPageFactory::getGroup( $page );
                                if( !isset( $groups[$group] ) ) {
                                        $groups[$group] = array();
                                }
index df3cdf5..46d0fcc 100644 (file)
@@ -78,7 +78,7 @@ class UpdateSpecialPages extends Maintenance {
                                continue;
                        }
 
-                       $specialObj = SpecialPage::getPage( $special );
+                       $specialObj = SpecialPageFactory::getPage( $special );
                        if ( !$specialObj ) {
                                $this->output( "No such special page: $special\n" );
                                exit;