X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fspecialpage%2FSpecialPageFactory.php;h=7904140e2f69a8330859d3215785fd5789dfdeeb;hb=ad522beeea5037ced24781df515b880cf75733ca;hp=07b6b4e0f24f256cde148f9f8cc895bc6a392df9;hpb=723a59730757cf31629027a567785145c5c131fa;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/specialpage/SpecialPageFactory.php b/includes/specialpage/SpecialPageFactory.php index 07b6b4e0f2..7904140e2f 100644 --- a/includes/specialpage/SpecialPageFactory.php +++ b/includes/specialpage/SpecialPageFactory.php @@ -114,6 +114,7 @@ class SpecialPageFactory { // Media reports and uploads 'Listfiles' => 'SpecialListFiles', 'Filepath' => 'SpecialFilepath', + 'MediaStatistics' => 'MediaStatisticsPage', 'MIMEsearch' => 'MIMEsearchPage', 'FileDuplicateSearch' => 'FileDuplicateSearchPage', 'Upload' => 'SpecialUpload', @@ -176,11 +177,41 @@ class SpecialPageFactory { private static $aliases; /** - * Get the special page list + * Reset the internal list of special pages. Useful when changing $wgSpecialPages after + * the internal list has already been initialized, e.g. during testing. + */ + public static function resetList() { + self::$list = null; + self::$aliases = null; + } + + /** + * Returns a list of canonical special page names. + * May be used to iterate over all registered special pages. * + * @return string[] + */ + public static function getNames() { + return array_keys( self::getPageList() ); + } + + /** + * Get the special page list as an array + * + * @deprecated since 1.24, use getNames() instead. * @return array */ - static function getList() { + public static function getList() { + wfDeprecated( __FUNCTION__, '1.24' ); + return self::getPageList(); + } + + /** + * Get the special page list as an array + * + * @return array + */ + private static function getPageList() { global $wgSpecialPages; global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication; global $wgEnableEmail, $wgEnableJavaScriptTest; @@ -223,9 +254,6 @@ class SpecialPageFactory { // This hook can be used to remove undesired built-in special pages wfRunHooks( 'SpecialPage_initList', array( &self::$list ) ); - // Cast to object: func()[$key] doesn't work, but func()->$key does - settype( self::$list, 'object' ); - wfProfileOut( __METHOD__ ); } @@ -234,33 +262,54 @@ class SpecialPageFactory { /** * Initialise and return the list of special page aliases. Returns an object with - * properties which can be accessed $obj->pagename - each property is an array of - * aliases; the first in the array is the canonical alias. All registered special - * pages are guaranteed to have a property entry, and for that property array to - * contain at least one entry (English fallbacks will be added if necessary). + * properties which can be accessed $obj->pagename - each property name is an + * alias, with the value being the canonical name of the special page. All + * registered special pages are guaranteed to map to themselves. * @return object */ - static function getAliasList() { + private static function getAliasListObject() { if ( !is_object( self::$aliases ) ) { global $wgContLang; $aliases = $wgContLang->getSpecialPageAliases(); - // Objects are passed by reference by default, need to create a copy - $missingPages = clone self::getList(); - self::$aliases = array(); + $keepAlias = array(); + + // Force every canonical name to be an alias for itself. + foreach ( self::getPageList() as $name => $stuff ) { + $caseFoldedAlias = $wgContLang->caseFold( $name ); + self::$aliases[$caseFoldedAlias] = $name; + $keepAlias[$caseFoldedAlias] = 'canonical'; + } + // Check for $aliases being an array since Language::getSpecialPageAliases can return null if ( is_array( $aliases ) ) { foreach ( $aliases as $realName => $aliasList ) { - foreach ( $aliasList as $alias ) { - self::$aliases[$wgContLang->caseFold( $alias )] = $realName; + $aliasList = array_values( $aliasList ); + foreach ( $aliasList as $i => $alias ) { + $caseFoldedAlias = $wgContLang->caseFold( $alias ); + + if ( isset( self::$aliases[$caseFoldedAlias] ) && + $realName === self::$aliases[$caseFoldedAlias] + ) { + // Ignore same-realName conflicts + continue; + } + + if ( !isset( $keepAlias[$caseFoldedAlias] ) ) { + self::$aliases[$caseFoldedAlias] = $realName; + if ( !$i ) { + $keepAlias[$caseFoldedAlias] = 'first'; + } + } elseif ( !$i ) { + wfWarn( "First alias '$alias' for $realName conflicts with " . + "{$keepAlias[$caseFoldedAlias]} alias for " . + self::$aliases[$caseFoldedAlias] + ); + } } - unset( $missingPages->$realName ); } } - foreach ( $missingPages as $name => $stuff ) { - self::$aliases[$wgContLang->caseFold( $name )] = $name; - } // Cast to object: func()[$key] doesn't work, but func()->$key does self::$aliases = (object)self::$aliases; @@ -283,8 +332,8 @@ class SpecialPageFactory { $caseFoldedAlias = $wgContLang->caseFold( $bits[0] ); $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias ); - if ( isset( self::getAliasList()->$caseFoldedAlias ) ) { - $name = self::getAliasList()->$caseFoldedAlias; + if ( isset( self::getAliasListObject()->$caseFoldedAlias ) ) { + $name = self::getAliasListObject()->$caseFoldedAlias; } else { return array( null, null ); } @@ -335,7 +384,8 @@ class SpecialPageFactory { public static function exists( $name ) { list( $title, /*...*/ ) = self::resolveAlias( $name ); - return property_exists( self::getList(), $title ); + $specialPageList = self::getPageList(); + return isset( $specialPageList[$title] ); } /** @@ -346,21 +396,39 @@ class SpecialPageFactory { */ public static function getPage( $name ) { list( $realName, /*...*/ ) = self::resolveAlias( $name ); - if ( property_exists( self::getList(), $realName ) ) { - $rec = self::getList()->$realName; + + $specialPageList = self::getPageList(); + + if ( isset( $specialPageList[$realName] ) ) { + $rec = $specialPageList[$realName]; + if ( is_string( $rec ) ) { $className = $rec; - - return new $className; + $page = new $className; + } elseif ( is_callable( $rec ) ) { + // Use callback to instantiate the special page + $page = call_user_func( $rec ); } elseif ( is_array( $rec ) ) { $className = array_shift( $rec ); // @deprecated, officially since 1.18, unofficially since forever wfDeprecated( "Array syntax for \$wgSpecialPages is deprecated ($className), " . "define a subclass of SpecialPage instead.", '1.18' ); - self::getList()->$realName = MWFunction::newObj( $className, $rec ); + $page = MWFunction::newObj( $className, $rec ); + } elseif ( $rec instanceof SpecialPage ) { + $page = $rec; //XXX: we should deep clone here + } else { + $page = null; + } + + if ( $page instanceof SpecialPage ) { + return $page; + } else { + // It's not a classname, nor a callback, nor a legacy constructor array, + // nor a special page object. Give up. + wfLogWarning( "Cannot instantiate special page $realName: bad spec!" ); + return null; } - return self::getList()->$realName; } else { return null; } @@ -380,7 +448,7 @@ class SpecialPageFactory { global $wgUser; $user = $wgUser; } - foreach ( self::getList() as $name => $rec ) { + foreach ( self::getPageList() as $name => $rec ) { $page = self::getPage( $name ); if ( $page ) { // not null $page->setContext( RequestContext::getMain() ); @@ -402,7 +470,7 @@ class SpecialPageFactory { */ public static function getRegularPages() { $pages = array(); - foreach ( self::getList() as $name => $rec ) { + foreach ( self::getPageList() as $name => $rec ) { $page = self::getPage( $name ); if ( $page->isListed() && !$page->isRestricted() ) { $pages[$name] = $page; @@ -425,7 +493,7 @@ class SpecialPageFactory { global $wgUser; $user = $wgUser; } - foreach ( self::getList() as $name => $rec ) { + foreach ( self::getPageList() as $name => $rec ) { $page = self::getPage( $name ); if ( $page->isListed() @@ -534,7 +602,7 @@ class SpecialPageFactory { * @param IContextSource $context * @return string HTML fragment */ - static function capturePath( Title $title, IContextSource $context ) { + public static function capturePath( Title $title, IContextSource $context ) { global $wgOut, $wgTitle, $wgRequest, $wgUser, $wgLang; // Save current globals @@ -571,32 +639,45 @@ class SpecialPageFactory { * @param string|bool $subpage * @return string */ - static function getLocalNameFor( $name, $subpage = false ) { + public static function getLocalNameFor( $name, $subpage = false ) { global $wgContLang; $aliases = $wgContLang->getSpecialPageAliases(); + $aliasList = self::getAliasListObject(); - if ( isset( $aliases[$name][0] ) ) { - $name = $aliases[$name][0]; - } else { - // Try harder in case someone misspelled the correct casing + // Find the first alias that maps back to $name + if ( isset( $aliases[$name] ) ) { $found = false; - // Check for $aliases being an array since Language::getSpecialPageAliases can return null + foreach ( $aliases[$name] as $alias ) { + $caseFoldedAlias = $wgContLang->caseFold( $alias ); + $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias ); + if ( isset( $aliasList->$caseFoldedAlias ) && + $aliasList->$caseFoldedAlias === $name + ) { + $name = $alias; + $found = true; + break; + } + } + if ( !$found ) { + wfWarn( "Did not find a usable alias for special page '$name'. " . + "It seems all defined aliases conflict?" ); + } + } else { + // Check if someone misspelled the correct casing if ( is_array( $aliases ) ) { 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; + return self::getLocalNameFor( $n, $subpage ); } } } - if ( !$found ) { - wfWarn( "Did not find alias for special page '$name'. " . - "Perhaps no aliases are defined for it?" ); - } + + 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"; } @@ -610,10 +691,10 @@ class SpecialPageFactory { * @param string $alias * @return Title|null Title or null if there is no such alias */ - static function getTitleForAlias( $alias ) { - $name = self::resolveAlias( $alias ); - if ( $name ) { - return SpecialPage::getTitleFor( $name ); + public static function getTitleForAlias( $alias ) { + list( $name, $subpage ) = self::resolveAlias( $alias ); + if ( $name != null ) { + return SpecialPage::getTitleFor( $name, $subpage ); } else { return null; }