[ Index ] |
PHP Cross Reference of MediaWiki-1.24.0 |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * Factory for handling the special page list and generating SpecialPage objects. 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License along 16 * with this program; if not, write to the Free Software Foundation, Inc., 17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 18 * http://www.gnu.org/copyleft/gpl.html 19 * 20 * @file 21 * @ingroup SpecialPage 22 * @defgroup SpecialPage SpecialPage 23 */ 24 25 /** 26 * Factory for handling the special page list and generating SpecialPage objects. 27 * 28 * To add a special page in an extension, add to $wgSpecialPages either 29 * an object instance or an array containing the name and constructor 30 * parameters. The latter is preferred for performance reasons. 31 * 32 * The object instantiated must be either an instance of SpecialPage or a 33 * sub-class thereof. It must have an execute() method, which sends the HTML 34 * for the special page to $wgOut. The parent class has an execute() method 35 * which distributes the call to the historical global functions. Additionally, 36 * execute() also checks if the user has the necessary access privileges 37 * and bails out if not. 38 * 39 * To add a core special page, use the similar static list in 40 * SpecialPageFactory::$list. To remove a core static special page at runtime, use 41 * a SpecialPage_initList hook. 42 * 43 * @ingroup SpecialPage 44 * @since 1.17 45 */ 46 class SpecialPageFactory { 47 /** 48 * List of special page names to the subclass of SpecialPage which handles them. 49 */ 50 private static $list = array( 51 // Maintenance Reports 52 'BrokenRedirects' => 'BrokenRedirectsPage', 53 'Deadendpages' => 'DeadendPagesPage', 54 'DoubleRedirects' => 'DoubleRedirectsPage', 55 'Longpages' => 'LongPagesPage', 56 'Ancientpages' => 'AncientPagesPage', 57 'Lonelypages' => 'LonelyPagesPage', 58 'Fewestrevisions' => 'FewestrevisionsPage', 59 'Withoutinterwiki' => 'WithoutInterwikiPage', 60 'Protectedpages' => 'SpecialProtectedpages', 61 'Protectedtitles' => 'SpecialProtectedtitles', 62 'Shortpages' => 'ShortpagesPage', 63 'Uncategorizedcategories' => 'UncategorizedCategoriesPage', 64 'Uncategorizedimages' => 'UncategorizedImagesPage', 65 'Uncategorizedpages' => 'UncategorizedPagesPage', 66 'Uncategorizedtemplates' => 'UncategorizedTemplatesPage', 67 'Unusedcategories' => 'UnusedCategoriesPage', 68 'Unusedimages' => 'UnusedimagesPage', 69 'Unusedtemplates' => 'UnusedtemplatesPage', 70 'Unwatchedpages' => 'UnwatchedpagesPage', 71 'Wantedcategories' => 'WantedCategoriesPage', 72 'Wantedfiles' => 'WantedFilesPage', 73 'Wantedpages' => 'WantedPagesPage', 74 'Wantedtemplates' => 'WantedTemplatesPage', 75 76 // List of pages 77 'Allpages' => 'SpecialAllpages', 78 'Prefixindex' => 'SpecialPrefixindex', 79 'Categories' => 'SpecialCategories', 80 'Listredirects' => 'ListredirectsPage', 81 'PagesWithProp' => 'SpecialPagesWithProp', 82 'TrackingCategories' => 'SpecialTrackingCategories', 83 84 // Login/create account 85 'Userlogin' => 'LoginForm', 86 'CreateAccount' => 'SpecialCreateAccount', 87 88 // Users and rights 89 'Block' => 'SpecialBlock', 90 'Unblock' => 'SpecialUnblock', 91 'BlockList' => 'SpecialBlockList', 92 'ChangePassword' => 'SpecialChangePassword', 93 'PasswordReset' => 'SpecialPasswordReset', 94 'DeletedContributions' => 'DeletedContributionsPage', 95 'Preferences' => 'SpecialPreferences', 96 'ResetTokens' => 'SpecialResetTokens', 97 'Contributions' => 'SpecialContributions', 98 'Listgrouprights' => 'SpecialListGroupRights', 99 'Listusers' => 'SpecialListUsers', 100 'Listadmins' => 'SpecialListAdmins', 101 'Listbots' => 'SpecialListBots', 102 'Userrights' => 'UserrightsPage', 103 'EditWatchlist' => 'SpecialEditWatchlist', 104 105 // Recent changes and logs 106 'Newimages' => 'SpecialNewFiles', 107 'Log' => 'SpecialLog', 108 'Watchlist' => 'SpecialWatchlist', 109 'Newpages' => 'SpecialNewpages', 110 'Recentchanges' => 'SpecialRecentChanges', 111 'Recentchangeslinked' => 'SpecialRecentChangesLinked', 112 'Tags' => 'SpecialTags', 113 114 // Media reports and uploads 115 'Listfiles' => 'SpecialListFiles', 116 'Filepath' => 'SpecialFilepath', 117 'MediaStatistics' => 'MediaStatisticsPage', 118 'MIMEsearch' => 'MIMEsearchPage', 119 'FileDuplicateSearch' => 'FileDuplicateSearchPage', 120 'Upload' => 'SpecialUpload', 121 'UploadStash' => 'SpecialUploadStash', 122 'ListDuplicatedFiles' => 'ListDuplicatedFilesPage', 123 124 // Data and tools 125 'Statistics' => 'SpecialStatistics', 126 'Allmessages' => 'SpecialAllmessages', 127 'Version' => 'SpecialVersion', 128 'Lockdb' => 'SpecialLockdb', 129 'Unlockdb' => 'SpecialUnlockdb', 130 131 // Redirecting special pages 132 'LinkSearch' => 'LinkSearchPage', 133 'Randompage' => 'RandomPage', 134 'RandomInCategory' => 'SpecialRandomInCategory', 135 'Randomredirect' => 'SpecialRandomredirect', 136 137 // High use pages 138 'Mostlinkedcategories' => 'MostlinkedCategoriesPage', 139 'Mostimages' => 'MostimagesPage', 140 'Mostinterwikis' => 'MostinterwikisPage', 141 'Mostlinked' => 'MostlinkedPage', 142 'Mostlinkedtemplates' => 'MostlinkedTemplatesPage', 143 'Mostcategories' => 'MostcategoriesPage', 144 'Mostrevisions' => 'MostrevisionsPage', 145 146 // Page tools 147 'ComparePages' => 'SpecialComparePages', 148 'Export' => 'SpecialExport', 149 'Import' => 'SpecialImport', 150 'Undelete' => 'SpecialUndelete', 151 'Whatlinkshere' => 'SpecialWhatLinksHere', 152 'MergeHistory' => 'SpecialMergeHistory', 153 'ExpandTemplates' => 'SpecialExpandTemplates', 154 155 // Other 156 'Booksources' => 'SpecialBookSources', 157 158 // Unlisted / redirects 159 'Blankpage' => 'SpecialBlankpage', 160 'Diff' => 'SpecialDiff', 161 'Emailuser' => 'SpecialEmailUser', 162 'Movepage' => 'MovePageForm', 163 'Mycontributions' => 'SpecialMycontributions', 164 'MyLanguage' => 'SpecialMyLanguage', 165 'Mypage' => 'SpecialMypage', 166 'Mytalk' => 'SpecialMytalk', 167 'Myuploads' => 'SpecialMyuploads', 168 'AllMyUploads' => 'SpecialAllMyUploads', 169 'PermanentLink' => 'SpecialPermanentLink', 170 'Redirect' => 'SpecialRedirect', 171 'Revisiondelete' => 'SpecialRevisionDelete', 172 'RunJobs' => 'SpecialRunJobs', 173 'Specialpages' => 'SpecialSpecialpages', 174 'Userlogout' => 'SpecialUserlogout', 175 ); 176 177 private static $aliases; 178 179 /** 180 * Reset the internal list of special pages. Useful when changing $wgSpecialPages after 181 * the internal list has already been initialized, e.g. during testing. 182 */ 183 public static function resetList() { 184 self::$list = null; 185 self::$aliases = null; 186 } 187 188 /** 189 * Returns a list of canonical special page names. 190 * May be used to iterate over all registered special pages. 191 * 192 * @return string[] 193 */ 194 public static function getNames() { 195 return array_keys( self::getPageList() ); 196 } 197 198 /** 199 * Get the special page list as an array 200 * 201 * @deprecated since 1.24, use getNames() instead. 202 * @return array 203 */ 204 public static function getList() { 205 wfDeprecated( __FUNCTION__, '1.24' ); 206 return self::getPageList(); 207 } 208 209 /** 210 * Get the special page list as an array 211 * 212 * @return array 213 */ 214 private static function getPageList() { 215 global $wgSpecialPages; 216 global $wgDisableCounters, $wgDisableInternalSearch, $wgEmailAuthentication; 217 global $wgEnableEmail, $wgEnableJavaScriptTest; 218 global $wgPageLanguageUseDB; 219 220 if ( !is_object( self::$list ) ) { 221 wfProfileIn( __METHOD__ ); 222 223 if ( !$wgDisableCounters ) { 224 self::$list['Popularpages'] = 'PopularPagesPage'; 225 } 226 227 if ( !$wgDisableInternalSearch ) { 228 self::$list['Search'] = 'SpecialSearch'; 229 } 230 231 if ( $wgEmailAuthentication ) { 232 self::$list['Confirmemail'] = 'EmailConfirmation'; 233 self::$list['Invalidateemail'] = 'EmailInvalidation'; 234 } 235 236 if ( $wgEnableEmail ) { 237 self::$list['ChangeEmail'] = 'SpecialChangeEmail'; 238 } 239 240 if ( $wgEnableJavaScriptTest ) { 241 self::$list['JavaScriptTest'] = 'SpecialJavaScriptTest'; 242 } 243 244 if ( $wgPageLanguageUseDB ) { 245 self::$list['PageLanguage'] = 'SpecialPageLanguage'; 246 } 247 248 self::$list['Activeusers'] = 'SpecialActiveUsers'; 249 250 // Add extension special pages 251 self::$list = array_merge( self::$list, $wgSpecialPages ); 252 253 // Run hooks 254 // This hook can be used to remove undesired built-in special pages 255 wfRunHooks( 'SpecialPage_initList', array( &self::$list ) ); 256 257 wfProfileOut( __METHOD__ ); 258 } 259 260 return self::$list; 261 } 262 263 /** 264 * Initialise and return the list of special page aliases. Returns an object with 265 * properties which can be accessed $obj->pagename - each property name is an 266 * alias, with the value being the canonical name of the special page. All 267 * registered special pages are guaranteed to map to themselves. 268 * @return object 269 */ 270 private static function getAliasListObject() { 271 if ( !is_object( self::$aliases ) ) { 272 global $wgContLang; 273 $aliases = $wgContLang->getSpecialPageAliases(); 274 275 self::$aliases = array(); 276 $keepAlias = array(); 277 278 // Force every canonical name to be an alias for itself. 279 foreach ( self::getPageList() as $name => $stuff ) { 280 $caseFoldedAlias = $wgContLang->caseFold( $name ); 281 self::$aliases[$caseFoldedAlias] = $name; 282 $keepAlias[$caseFoldedAlias] = 'canonical'; 283 } 284 285 // Check for $aliases being an array since Language::getSpecialPageAliases can return null 286 if ( is_array( $aliases ) ) { 287 foreach ( $aliases as $realName => $aliasList ) { 288 $aliasList = array_values( $aliasList ); 289 foreach ( $aliasList as $i => $alias ) { 290 $caseFoldedAlias = $wgContLang->caseFold( $alias ); 291 292 if ( isset( self::$aliases[$caseFoldedAlias] ) && 293 $realName === self::$aliases[$caseFoldedAlias] 294 ) { 295 // Ignore same-realName conflicts 296 continue; 297 } 298 299 if ( !isset( $keepAlias[$caseFoldedAlias] ) ) { 300 self::$aliases[$caseFoldedAlias] = $realName; 301 if ( !$i ) { 302 $keepAlias[$caseFoldedAlias] = 'first'; 303 } 304 } elseif ( !$i ) { 305 wfWarn( "First alias '$alias' for $realName conflicts with " . 306 "{$keepAlias[$caseFoldedAlias]} alias for " . 307 self::$aliases[$caseFoldedAlias] 308 ); 309 } 310 } 311 } 312 } 313 314 // Cast to object: func()[$key] doesn't work, but func()->$key does 315 self::$aliases = (object)self::$aliases; 316 } 317 318 return self::$aliases; 319 } 320 321 /** 322 * Given a special page name with a possible subpage, return an array 323 * where the first element is the special page name and the second is the 324 * subpage. 325 * 326 * @param string $alias 327 * @return array Array( String, String|null ), or array( null, null ) if the page is invalid 328 */ 329 public static function resolveAlias( $alias ) { 330 global $wgContLang; 331 $bits = explode( '/', $alias, 2 ); 332 333 $caseFoldedAlias = $wgContLang->caseFold( $bits[0] ); 334 $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias ); 335 if ( isset( self::getAliasListObject()->$caseFoldedAlias ) ) { 336 $name = self::getAliasListObject()->$caseFoldedAlias; 337 } else { 338 return array( null, null ); 339 } 340 341 if ( !isset( $bits[1] ) ) { // bug 2087 342 $par = null; 343 } else { 344 $par = $bits[1]; 345 } 346 347 return array( $name, $par ); 348 } 349 350 /** 351 * Add a page to a certain display group for Special:SpecialPages 352 * 353 * @param SpecialPage|string $page 354 * @param string $group 355 * @deprecated since 1.21 Override SpecialPage::getGroupName 356 */ 357 public static function setGroup( $page, $group ) { 358 wfDeprecated( __METHOD__, '1.21' ); 359 360 global $wgSpecialPageGroups; 361 $name = is_object( $page ) ? $page->getName() : $page; 362 $wgSpecialPageGroups[$name] = $group; 363 } 364 365 /** 366 * Get the group that the special page belongs in on Special:SpecialPage 367 * 368 * @param SpecialPage $page 369 * @return string 370 * @deprecated since 1.21 Use SpecialPage::getFinalGroupName 371 */ 372 public static function getGroup( &$page ) { 373 wfDeprecated( __METHOD__, '1.21' ); 374 375 return $page->getFinalGroupName(); 376 } 377 378 /** 379 * Check if a given name exist as a special page or as a special page alias 380 * 381 * @param string $name Name of a special page 382 * @return bool True if a special page exists with this name 383 */ 384 public static function exists( $name ) { 385 list( $title, /*...*/ ) = self::resolveAlias( $name ); 386 387 $specialPageList = self::getPageList(); 388 return isset( $specialPageList[$title] ); 389 } 390 391 /** 392 * Find the object with a given name and return it (or NULL) 393 * 394 * @param string $name Special page name, may be localised and/or an alias 395 * @return SpecialPage|null SpecialPage object or null if the page doesn't exist 396 */ 397 public static function getPage( $name ) { 398 list( $realName, /*...*/ ) = self::resolveAlias( $name ); 399 400 $specialPageList = self::getPageList(); 401 402 if ( isset( $specialPageList[$realName] ) ) { 403 $rec = $specialPageList[$realName]; 404 405 if ( is_callable( $rec ) ) { 406 // Use callback to instantiate the special page 407 $page = call_user_func( $rec ); 408 } elseif ( is_string( $rec ) ) { 409 $className = $rec; 410 $page = new $className; 411 } elseif ( is_array( $rec ) ) { 412 $className = array_shift( $rec ); 413 // @deprecated, officially since 1.18, unofficially since forever 414 wfDeprecated( "Array syntax for \$wgSpecialPages is deprecated ($className), " . 415 "define a subclass of SpecialPage instead.", '1.18' ); 416 $page = MWFunction::newObj( $className, $rec ); 417 } elseif ( $rec instanceof SpecialPage ) { 418 $page = $rec; //XXX: we should deep clone here 419 } else { 420 $page = null; 421 } 422 423 if ( $page instanceof SpecialPage ) { 424 return $page; 425 } else { 426 // It's not a classname, nor a callback, nor a legacy constructor array, 427 // nor a special page object. Give up. 428 wfLogWarning( "Cannot instantiate special page $realName: bad spec!" ); 429 return null; 430 } 431 432 } else { 433 return null; 434 } 435 } 436 437 /** 438 * Return categorised listable special pages which are available 439 * for the current user, and everyone. 440 * 441 * @param User $user User object to check permissions, $wgUser will be used 442 * if not provided 443 * @return array ( string => Specialpage ) 444 */ 445 public static function getUsablePages( User $user = null ) { 446 $pages = array(); 447 if ( $user === null ) { 448 global $wgUser; 449 $user = $wgUser; 450 } 451 foreach ( self::getPageList() as $name => $rec ) { 452 $page = self::getPage( $name ); 453 if ( $page ) { // not null 454 $page->setContext( RequestContext::getMain() ); 455 if ( $page->isListed() 456 && ( !$page->isRestricted() || $page->userCanExecute( $user ) ) 457 ) { 458 $pages[$name] = $page; 459 } 460 } 461 } 462 463 return $pages; 464 } 465 466 /** 467 * Return categorised listable special pages for all users 468 * 469 * @return array ( string => Specialpage ) 470 */ 471 public static function getRegularPages() { 472 $pages = array(); 473 foreach ( self::getPageList() as $name => $rec ) { 474 $page = self::getPage( $name ); 475 if ( $page->isListed() && !$page->isRestricted() ) { 476 $pages[$name] = $page; 477 } 478 } 479 480 return $pages; 481 } 482 483 /** 484 * Return categorised listable special pages which are available 485 * for the current user, but not for everyone 486 * 487 * @param User|null $user User object to use or null for $wgUser 488 * @return array ( string => Specialpage ) 489 */ 490 public static function getRestrictedPages( User $user = null ) { 491 $pages = array(); 492 if ( $user === null ) { 493 global $wgUser; 494 $user = $wgUser; 495 } 496 foreach ( self::getPageList() as $name => $rec ) { 497 $page = self::getPage( $name ); 498 if ( 499 $page->isListed() 500 && $page->isRestricted() 501 && $page->userCanExecute( $user ) 502 ) { 503 $pages[$name] = $page; 504 } 505 } 506 507 return $pages; 508 } 509 510 /** 511 * Execute a special page path. 512 * The path may contain parameters, e.g. Special:Name/Params 513 * Extracts the special page name and call the execute method, passing the parameters 514 * 515 * Returns a title object if the page is redirected, false if there was no such special 516 * page, and true if it was successful. 517 * 518 * @param Title $title 519 * @param IContextSource $context 520 * @param bool $including Bool output is being captured for use in {{special:whatever}} 521 * 522 * @return bool 523 */ 524 public static function executePath( Title &$title, IContextSource &$context, $including = false ) { 525 wfProfileIn( __METHOD__ ); 526 527 // @todo FIXME: Redirects broken due to this call 528 $bits = explode( '/', $title->getDBkey(), 2 ); 529 $name = $bits[0]; 530 if ( !isset( $bits[1] ) ) { // bug 2087 531 $par = null; 532 } else { 533 $par = $bits[1]; 534 } 535 $page = self::getPage( $name ); 536 // Nonexistent? 537 if ( !$page ) { 538 $context->getOutput()->setArticleRelated( false ); 539 $context->getOutput()->setRobotPolicy( 'noindex,nofollow' ); 540 541 global $wgSend404Code; 542 if ( $wgSend404Code ) { 543 $context->getOutput()->setStatusCode( 404 ); 544 } 545 546 $context->getOutput()->showErrorPage( 'nosuchspecialpage', 'nospecialpagetext' ); 547 wfProfileOut( __METHOD__ ); 548 549 return false; 550 } 551 552 // Page exists, set the context 553 $page->setContext( $context ); 554 555 if ( !$including ) { 556 // Redirect to canonical alias for GET commands 557 // Not for POST, we'd lose the post data, so it's best to just distribute 558 // the request. Such POST requests are possible for old extensions that 559 // generate self-links without being aware that their default name has 560 // changed. 561 if ( $name != $page->getLocalName() && !$context->getRequest()->wasPosted() ) { 562 $query = $context->getRequest()->getQueryValues(); 563 unset( $query['title'] ); 564 $title = $page->getPageTitle( $par ); 565 $url = $title->getFullURL( $query ); 566 $context->getOutput()->redirect( $url ); 567 wfProfileOut( __METHOD__ ); 568 569 return $title; 570 } else { 571 $context->setTitle( $page->getPageTitle( $par ) ); 572 } 573 } elseif ( !$page->isIncludable() ) { 574 wfProfileOut( __METHOD__ ); 575 576 return false; 577 } 578 579 $page->including( $including ); 580 581 // Execute special page 582 $profName = 'Special:' . $page->getName(); 583 wfProfileIn( $profName ); 584 $page->run( $par ); 585 wfProfileOut( $profName ); 586 wfProfileOut( __METHOD__ ); 587 588 return true; 589 } 590 591 /** 592 * Just like executePath() but will override global variables and execute 593 * the page in "inclusion" mode. Returns true if the execution was 594 * successful or false if there was no such special page, or a title object 595 * if it was a redirect. 596 * 597 * Also saves the current $wgTitle, $wgOut, $wgRequest, $wgUser and $wgLang 598 * variables so that the special page will get the context it'd expect on a 599 * normal request, and then restores them to their previous values after. 600 * 601 * @param Title $title 602 * @param IContextSource $context 603 * @return string HTML fragment 604 */ 605 public static function capturePath( Title $title, IContextSource $context ) { 606 global $wgOut, $wgTitle, $wgRequest, $wgUser, $wgLang; 607 608 // Save current globals 609 $oldTitle = $wgTitle; 610 $oldOut = $wgOut; 611 $oldRequest = $wgRequest; 612 $oldUser = $wgUser; 613 $oldLang = $wgLang; 614 615 // Set the globals to the current context 616 $wgTitle = $title; 617 $wgOut = $context->getOutput(); 618 $wgRequest = $context->getRequest(); 619 $wgUser = $context->getUser(); 620 $wgLang = $context->getLanguage(); 621 622 // The useful part 623 $ret = self::executePath( $title, $context, true ); 624 625 // And restore the old globals 626 $wgTitle = $oldTitle; 627 $wgOut = $oldOut; 628 $wgRequest = $oldRequest; 629 $wgUser = $oldUser; 630 $wgLang = $oldLang; 631 632 return $ret; 633 } 634 635 /** 636 * Get the local name for a specified canonical name 637 * 638 * @param string $name 639 * @param string|bool $subpage 640 * @return string 641 */ 642 public static function getLocalNameFor( $name, $subpage = false ) { 643 global $wgContLang; 644 $aliases = $wgContLang->getSpecialPageAliases(); 645 $aliasList = self::getAliasListObject(); 646 647 // Find the first alias that maps back to $name 648 if ( isset( $aliases[$name] ) ) { 649 $found = false; 650 foreach ( $aliases[$name] as $alias ) { 651 $caseFoldedAlias = $wgContLang->caseFold( $alias ); 652 $caseFoldedAlias = str_replace( ' ', '_', $caseFoldedAlias ); 653 if ( isset( $aliasList->$caseFoldedAlias ) && 654 $aliasList->$caseFoldedAlias === $name 655 ) { 656 $name = $alias; 657 $found = true; 658 break; 659 } 660 } 661 if ( !$found ) { 662 wfWarn( "Did not find a usable alias for special page '$name'. " . 663 "It seems all defined aliases conflict?" ); 664 } 665 } else { 666 // Check if someone misspelled the correct casing 667 if ( is_array( $aliases ) ) { 668 foreach ( $aliases as $n => $values ) { 669 if ( strcasecmp( $name, $n ) === 0 ) { 670 wfWarn( "Found alias defined for $n when searching for " . 671 "special page aliases for $name. Case mismatch?" ); 672 return self::getLocalNameFor( $n, $subpage ); 673 } 674 } 675 } 676 677 wfWarn( "Did not find alias for special page '$name'. " . 678 "Perhaps no aliases are defined for it?" ); 679 } 680 681 if ( $subpage !== false && !is_null( $subpage ) ) { 682 $name = "$name/$subpage"; 683 } 684 685 return $wgContLang->ucfirst( $name ); 686 } 687 688 /** 689 * Get a title for a given alias 690 * 691 * @param string $alias 692 * @return Title|null Title or null if there is no such alias 693 */ 694 public static function getTitleForAlias( $alias ) { 695 list( $name, $subpage ) = self::resolveAlias( $alias ); 696 if ( $name != null ) { 697 return SpecialPage::getTitleFor( $name, $subpage ); 698 } else { 699 return null; 700 } 701 } 702 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Fri Nov 28 14:03:12 2014 | Cross-referenced by PHPXref 0.7.1 |