r105797 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r105796‎ | r105797 | r105798 >
Date:14:48, 11 December 2011
Author:ialex
Status:ok
Tags:
Comment:
Group related functions
Modified paths:
  • /trunk/phase3/includes/Title.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/Title.php
@@ -480,6 +480,33 @@
481481 }
482482
483483 /**
 484+ * Returns a simple regex that will match on characters and sequences invalid in titles.
 485+ * Note that this doesn't pick up many things that could be wrong with titles, but that
 486+ * replacing this regex with something valid will make many titles valid.
 487+ *
 488+ * @return String regex string
 489+ */
 490+ static function getTitleInvalidRegex() {
 491+ static $rxTc = false;
 492+ if ( !$rxTc ) {
 493+ # Matching titles will be held as illegal.
 494+ $rxTc = '/' .
 495+ # Any character not allowed is forbidden...
 496+ '[^' . self::legalChars() . ']' .
 497+ # URL percent encoding sequences interfere with the ability
 498+ # to round-trip titles -- you can't link to them consistently.
 499+ '|%[0-9A-Fa-f]{2}' .
 500+ # XML/HTML character references produce similar issues.
 501+ '|&[A-Za-z0-9\x80-\xff]+;' .
 502+ '|&#[0-9]+;' .
 503+ '|&#x[0-9A-Fa-f]+;' .
 504+ '/S';
 505+ }
 506+
 507+ return $rxTc;
 508+ }
 509+
 510+ /**
484511 * Get a string representation of a title suitable for
485512 * including in a search index
486513 *
@@ -545,6 +572,22 @@
546573 }
547574
548575 /**
 576+ * Callback for usort() to do title sorts by (namespace, title)
 577+ *
 578+ * @param $a Title
 579+ * @param $b Title
 580+ *
 581+ * @return Integer: result of string comparison, or namespace comparison
 582+ */
 583+ public static function compare( $a, $b ) {
 584+ if ( $a->getNamespace() == $b->getNamespace() ) {
 585+ return strcmp( $a->getText(), $b->getText() );
 586+ } else {
 587+ return $a->getNamespace() - $b->getNamespace();
 588+ }
 589+ }
 590+
 591+ /**
549592 * Determine whether the object refers to a page within
550593 * this project.
551594 *
@@ -631,6 +674,15 @@
632675 }
633676
634677 /**
 678+ * Get the DB key with the initial letter case as specified by the user
 679+ *
 680+ * @return String DB key
 681+ */
 682+ function getUserCaseDBKey() {
 683+ return $this->mUserCaseDBKey;
 684+ }
 685+
 686+ /**
635687 * Get the namespace index, i.e. one of the NS_xxxx constants.
636688 *
637689 * @return Integer: Namespace index
@@ -677,15 +729,6 @@
678730 }
679731
680732 /**
681 - * Get the DB key with the initial letter case as specified by the user
682 - *
683 - * @return String DB key
684 - */
685 - function getUserCaseDBKey() {
686 - return $this->mUserCaseDBKey;
687 - }
688 -
689 - /**
690733 * Get the namespace text of the subject (rather than talk) page
691734 *
692735 * @return String Namespace text
@@ -715,25 +758,290 @@
716759 }
717760
718761 /**
719 - * Get the Title fragment (i.e.\ the bit after the #) in text form
 762+ * Is this in a namespace that allows actual pages?
720763 *
721 - * @return String Title fragment
 764+ * @return Bool
 765+ * @internal note -- uses hardcoded namespace index instead of constants
722766 */
723 - public function getFragment() { return $this->mFragment; }
 767+ public function canExist() {
 768+ return $this->mNamespace >= 0 && $this->mNamespace != NS_MEDIA;
 769+ }
724770
725771 /**
726 - * Get the fragment in URL form, including the "#" character if there is one
727 - * @return String Fragment in URL form
 772+ * Can this title be added to a user's watchlist?
 773+ *
 774+ * @return Bool TRUE or FALSE
728775 */
729 - public function getFragmentForURL() {
730 - if ( $this->mFragment == '' ) {
731 - return '';
732 - } else {
733 - return '#' . Title::escapeFragmentForURL( $this->mFragment );
 776+ public function isWatchable() {
 777+ return !$this->isExternal() && MWNamespace::isWatchable( $this->getNamespace() );
 778+ }
 779+
 780+ /**
 781+ * Returns true if this is a special page.
 782+ *
 783+ * @return boolean
 784+ */
 785+ public function isSpecialPage() {
 786+ return $this->getNamespace() == NS_SPECIAL;
 787+ }
 788+
 789+ /**
 790+ * Returns true if this title resolves to the named special page
 791+ *
 792+ * @param $name String The special page name
 793+ * @return boolean
 794+ */
 795+ public function isSpecial( $name ) {
 796+ if ( $this->isSpecialPage() ) {
 797+ list( $thisName, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $this->getDBkey() );
 798+ if ( $name == $thisName ) {
 799+ return true;
 800+ }
734801 }
 802+ return false;
735803 }
736804
737805 /**
 806+ * If the Title refers to a special page alias which is not the local default, resolve
 807+ * the alias, and localise the name as necessary. Otherwise, return $this
 808+ *
 809+ * @return Title
 810+ */
 811+ public function fixSpecialName() {
 812+ if ( $this->isSpecialPage() ) {
 813+ list( $canonicalName, $par ) = SpecialPageFactory::resolveAlias( $this->mDbkeyform );
 814+ if ( $canonicalName ) {
 815+ $localName = SpecialPageFactory::getLocalNameFor( $canonicalName, $par );
 816+ if ( $localName != $this->mDbkeyform ) {
 817+ return Title::makeTitle( NS_SPECIAL, $localName );
 818+ }
 819+ }
 820+ }
 821+ return $this;
 822+ }
 823+
 824+ /**
 825+ * Returns true if the title is inside the specified namespace.
 826+ *
 827+ * Please make use of this instead of comparing to getNamespace()
 828+ * This function is much more resistant to changes we may make
 829+ * to namespaces than code that makes direct comparisons.
 830+ * @param $ns int The namespace
 831+ * @return bool
 832+ * @since 1.19
 833+ */
 834+ public function inNamespace( $ns ) {
 835+ return MWNamespace::equals( $this->getNamespace(), $ns );
 836+ }
 837+
 838+ /**
 839+ * Returns true if the title is inside one of the specified namespaces.
 840+ *
 841+ * @param ...$namespaces The namespaces to check for
 842+ * @return bool
 843+ * @since 1.19
 844+ */
 845+ public function inNamespaces( /* ... */ ) {
 846+ $namespaces = func_get_args();
 847+ if ( count( $namespaces ) > 0 && is_array( $namespaces[0] ) ) {
 848+ $namespaces = $namespaces[0];
 849+ }
 850+
 851+ foreach ( $namespaces as $ns ) {
 852+ if ( $this->inNamespace( $ns ) ) {
 853+ return true;
 854+ }
 855+ }
 856+
 857+ return false;
 858+ }
 859+
 860+ /**
 861+ * Returns true if the title has the same subject namespace as the
 862+ * namespace specified.
 863+ * For example this method will take NS_USER and return true if namespace
 864+ * is either NS_USER or NS_USER_TALK since both of them have NS_USER
 865+ * as their subject namespace.
 866+ *
 867+ * This is MUCH simpler than individually testing for equivilance
 868+ * against both NS_USER and NS_USER_TALK, and is also forward compatible.
 869+ * @since 1.19
 870+ */
 871+ public function hasSubjectNamespace( $ns ) {
 872+ return MWNamespace::subjectEquals( $this->getNamespace(), $ns );
 873+ }
 874+
 875+ /**
 876+ * Is this Title in a namespace which contains content?
 877+ * In other words, is this a content page, for the purposes of calculating
 878+ * statistics, etc?
 879+ *
 880+ * @return Boolean
 881+ */
 882+ public function isContentPage() {
 883+ return MWNamespace::isContent( $this->getNamespace() );
 884+ }
 885+
 886+ /**
 887+ * Would anybody with sufficient privileges be able to move this page?
 888+ * Some pages just aren't movable.
 889+ *
 890+ * @return Bool TRUE or FALSE
 891+ */
 892+ public function isMovable() {
 893+ if ( !MWNamespace::isMovable( $this->getNamespace() ) || $this->getInterwiki() != '' ) {
 894+ // Interwiki title or immovable namespace. Hooks don't get to override here
 895+ return false;
 896+ }
 897+
 898+ $result = true;
 899+ wfRunHooks( 'TitleIsMovable', array( $this, &$result ) );
 900+ return $result;
 901+ }
 902+
 903+ /**
 904+ * Is this the mainpage?
 905+ * @note Title::newFromText seams to be sufficiently optimized by the title
 906+ * cache that we don't need to over-optimize by doing direct comparisons and
 907+ * acidentally creating new bugs where $title->equals( Title::newFromText() )
 908+ * ends up reporting something differently than $title->isMainPage();
 909+ *
 910+ * @since 1.18
 911+ * @return Bool
 912+ */
 913+ public function isMainPage() {
 914+ return $this->equals( Title::newMainPage() );
 915+ }
 916+
 917+ /**
 918+ * Is this a subpage?
 919+ *
 920+ * @return Bool
 921+ */
 922+ public function isSubpage() {
 923+ return MWNamespace::hasSubpages( $this->mNamespace )
 924+ ? strpos( $this->getText(), '/' ) !== false
 925+ : false;
 926+ }
 927+
 928+ /**
 929+ * Is this a conversion table for the LanguageConverter?
 930+ *
 931+ * @return Bool
 932+ */
 933+ public function isConversionTable() {
 934+ return $this->getNamespace() == NS_MEDIAWIKI &&
 935+ strpos( $this->getText(), 'Conversiontable' ) !== false;
 936+ }
 937+
 938+ /**
 939+ * Does that page contain wikitext, or it is JS, CSS or whatever?
 940+ *
 941+ * @return Bool
 942+ */
 943+ public function isWikitextPage() {
 944+ $retval = !$this->isCssOrJsPage() && !$this->isCssJsSubpage();
 945+ wfRunHooks( 'TitleIsWikitextPage', array( $this, &$retval ) );
 946+ return $retval;
 947+ }
 948+
 949+ /**
 950+ * Could this page contain custom CSS or JavaScript, based
 951+ * on the title?
 952+ *
 953+ * @return Bool
 954+ */
 955+ public function isCssOrJsPage() {
 956+ $retval = $this->mNamespace == NS_MEDIAWIKI
 957+ && preg_match( '!\.(?:css|js)$!u', $this->mTextform ) > 0;
 958+ wfRunHooks( 'TitleIsCssOrJsPage', array( $this, &$retval ) );
 959+ return $retval;
 960+ }
 961+
 962+ /**
 963+ * Is this a .css or .js subpage of a user page?
 964+ * @return Bool
 965+ */
 966+ public function isCssJsSubpage() {
 967+ return ( NS_USER == $this->mNamespace and preg_match( "/\\/.*\\.(?:css|js)$/", $this->mTextform ) );
 968+ }
 969+
 970+ /**
 971+ * Is this a *valid* .css or .js subpage of a user page?
 972+ *
 973+ * @return Bool
 974+ * @deprecated since 1.17
 975+ */
 976+ public function isValidCssJsSubpage() {
 977+ return $this->isCssJsSubpage();
 978+ }
 979+
 980+ /**
 981+ * Trim down a .css or .js subpage title to get the corresponding skin name
 982+ *
 983+ * @return string containing skin name from .css or .js subpage title
 984+ */
 985+ public function getSkinFromCssJsSubpage() {
 986+ $subpage = explode( '/', $this->mTextform );
 987+ $subpage = $subpage[ count( $subpage ) - 1 ];
 988+ $lastdot = strrpos( $subpage, '.' );
 989+ if ( $lastdot === false )
 990+ return $subpage; # Never happens: only called for names ending in '.css' or '.js'
 991+ return substr( $subpage, 0, $lastdot );
 992+ }
 993+
 994+ /**
 995+ * Is this a .css subpage of a user page?
 996+ *
 997+ * @return Bool
 998+ */
 999+ public function isCssSubpage() {
 1000+ return ( NS_USER == $this->mNamespace && preg_match( "/\\/.*\\.css$/", $this->mTextform ) );
 1001+ }
 1002+
 1003+ /**
 1004+ * Is this a .js subpage of a user page?
 1005+ *
 1006+ * @return Bool
 1007+ */
 1008+ public function isJsSubpage() {
 1009+ return ( NS_USER == $this->mNamespace && preg_match( "/\\/.*\\.js$/", $this->mTextform ) );
 1010+ }
 1011+
 1012+ /**
 1013+ * Is this a talk page of some sort?
 1014+ *
 1015+ * @return Bool
 1016+ */
 1017+ public function isTalkPage() {
 1018+ return MWNamespace::isTalk( $this->getNamespace() );
 1019+ }
 1020+
 1021+ /**
 1022+ * Get a Title object associated with the talk page of this article
 1023+ *
 1024+ * @return Title the object for the talk page
 1025+ */
 1026+ public function getTalkPage() {
 1027+ return Title::makeTitle( MWNamespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
 1028+ }
 1029+
 1030+ /**
 1031+ * Get a title object associated with the subject page of this
 1032+ * talk page
 1033+ *
 1034+ * @return Title the object for the subject page
 1035+ */
 1036+ public function getSubjectPage() {
 1037+ // Is this the same title?
 1038+ $subjectNS = MWNamespace::getSubject( $this->getNamespace() );
 1039+ if ( $this->getNamespace() == $subjectNS ) {
 1040+ return $this;
 1041+ }
 1042+ return Title::makeTitle( $subjectNS, $this->getDBkey() );
 1043+ }
 1044+
 1045+ /**
7381046 * Get the default namespace index, for when there is no namespace
7391047 *
7401048 * @return Int Default namespace index
@@ -753,6 +1061,61 @@
7541062 }
7551063
7561064 /**
 1065+ * Get the Title fragment (i.e.\ the bit after the #) in text form
 1066+ *
 1067+ * @return String Title fragment
 1068+ */
 1069+ public function getFragment() {
 1070+ return $this->mFragment;
 1071+ }
 1072+
 1073+ /**
 1074+ * Get the fragment in URL form, including the "#" character if there is one
 1075+ * @return String Fragment in URL form
 1076+ */
 1077+ public function getFragmentForURL() {
 1078+ if ( $this->mFragment == '' ) {
 1079+ return '';
 1080+ } else {
 1081+ return '#' . Title::escapeFragmentForURL( $this->mFragment );
 1082+ }
 1083+ }
 1084+
 1085+ /**
 1086+ * Set the fragment for this title. Removes the first character from the
 1087+ * specified fragment before setting, so it assumes you're passing it with
 1088+ * an initial "#".
 1089+ *
 1090+ * Deprecated for public use, use Title::makeTitle() with fragment parameter.
 1091+ * Still in active use privately.
 1092+ *
 1093+ * @param $fragment String text
 1094+ */
 1095+ public function setFragment( $fragment ) {
 1096+ $this->mFragment = str_replace( '_', ' ', substr( $fragment, 1 ) );
 1097+ }
 1098+
 1099+ /**
 1100+ * Prefix some arbitrary text with the namespace or interwiki prefix
 1101+ * of this object
 1102+ *
 1103+ * @param $name String the text
 1104+ * @return String the prefixed text
 1105+ * @private
 1106+ */
 1107+ private function prefix( $name ) {
 1108+ $p = '';
 1109+ if ( $this->mInterwiki != '' ) {
 1110+ $p = $this->mInterwiki . ':';
 1111+ }
 1112+
 1113+ if ( 0 != $this->mNamespace ) {
 1114+ $p .= $this->getNsText() . ':';
 1115+ }
 1116+ return $p . $name;
 1117+ }
 1118+
 1119+ /**
7571120 * Get the prefixed database key form
7581121 *
7591122 * @return String the prefixed title, with underscores and
@@ -781,6 +1144,14 @@
7821145 }
7831146
7841147 /**
 1148+ * Return a string representation of this title
 1149+ *
 1150+ * @return String representation of this title
 1151+ */
 1152+ public function __toString() {
 1153+ return $this->getPrefixedText();
 1154+ }
 1155+
7851156 /**
7861157 * Get the prefixed title with spaces, plus any fragment
7871158 * (part beginning with '#')
@@ -1083,101 +1454,6 @@
10841455 }
10851456
10861457 /**
1087 - * Is this page "semi-protected" - the *only* protection is autoconfirm?
1088 - *
1089 - * @param $action String Action to check (default: edit)
1090 - * @return Bool
1091 - */
1092 - public function isSemiProtected( $action = 'edit' ) {
1093 - if ( $this->exists() ) {
1094 - $restrictions = $this->getRestrictions( $action );
1095 - if ( count( $restrictions ) > 0 ) {
1096 - foreach ( $restrictions as $restriction ) {
1097 - if ( strtolower( $restriction ) != 'autoconfirmed' ) {
1098 - return false;
1099 - }
1100 - }
1101 - } else {
1102 - # Not protected
1103 - return false;
1104 - }
1105 - return true;
1106 - } else {
1107 - # If it doesn't exist, it can't be protected
1108 - return false;
1109 - }
1110 - }
1111 -
1112 - /**
1113 - * Does the title correspond to a protected article?
1114 - *
1115 - * @param $action String the action the page is protected from,
1116 - * by default checks all actions.
1117 - * @return Bool
1118 - */
1119 - public function isProtected( $action = '' ) {
1120 - global $wgRestrictionLevels;
1121 -
1122 - $restrictionTypes = $this->getRestrictionTypes();
1123 -
1124 - # Special pages have inherent protection
1125 - if( $this->isSpecialPage() ) {
1126 - return true;
1127 - }
1128 -
1129 - # Check regular protection levels
1130 - foreach ( $restrictionTypes as $type ) {
1131 - if ( $action == $type || $action == '' ) {
1132 - $r = $this->getRestrictions( $type );
1133 - foreach ( $wgRestrictionLevels as $level ) {
1134 - if ( in_array( $level, $r ) && $level != '' ) {
1135 - return true;
1136 - }
1137 - }
1138 - }
1139 - }
1140 -
1141 - return false;
1142 - }
1143 -
1144 - /**
1145 - * Determines if $user is unable to edit this page because it has been protected
1146 - * by $wgNamespaceProtection.
1147 - *
1148 - * @param $user User object to check permissions
1149 - * @return Bool
1150 - */
1151 - public function isNamespaceProtected( User $user ) {
1152 - global $wgNamespaceProtection;
1153 -
1154 - if ( isset( $wgNamespaceProtection[$this->mNamespace] ) ) {
1155 - foreach ( (array)$wgNamespaceProtection[$this->mNamespace] as $right ) {
1156 - if ( $right != '' && !$user->isAllowed( $right ) ) {
1157 - return true;
1158 - }
1159 - }
1160 - }
1161 - return false;
1162 - }
1163 -
1164 - /**
1165 - * Is this a conversion table for the LanguageConverter?
1166 - *
1167 - * @return Bool
1168 - */
1169 - public function isConversionTable() {
1170 - if(
1171 - $this->getNamespace() == NS_MEDIAWIKI &&
1172 - strpos( $this->getText(), 'Conversiontable' ) !== false
1173 - )
1174 - {
1175 - return true;
1176 - }
1177 -
1178 - return false;
1179 - }
1180 -
1181 - /**
11821458 * Is $wgUser watching this page?
11831459 *
11841460 * @return Bool
@@ -1796,6 +2072,79 @@
17972073 }
17982074
17992075 /**
 2076+ * Protect css subpages of user pages: can $wgUser edit
 2077+ * this page?
 2078+ *
 2079+ * @deprecated in 1.19; will be removed in 1.20. Use getUserPermissionsErrors() instead.
 2080+ * @return Bool
 2081+ */
 2082+ public function userCanEditCssSubpage() {
 2083+ global $wgUser;
 2084+ wfDeprecated( __METHOD__ );
 2085+ return ( ( $wgUser->isAllowedAll( 'editusercssjs', 'editusercss' ) )
 2086+ || preg_match( '/^' . preg_quote( $wgUser->getName(), '/' ) . '\//', $this->mTextform ) );
 2087+ }
 2088+
 2089+ /**
 2090+ * Protect js subpages of user pages: can $wgUser edit
 2091+ * this page?
 2092+ *
 2093+ * @deprecated in 1.19; will be removed in 1.20. Use getUserPermissionsErrors() instead.
 2094+ * @return Bool
 2095+ */
 2096+ public function userCanEditJsSubpage() {
 2097+ global $wgUser;
 2098+ wfDeprecated( __METHOD__ );
 2099+ return ( ( $wgUser->isAllowedAll( 'editusercssjs', 'edituserjs' ) )
 2100+ || preg_match( '/^' . preg_quote( $wgUser->getName(), '/' ) . '\//', $this->mTextform ) );
 2101+ }
 2102+
 2103+ /**
 2104+ * Get a filtered list of all restriction types supported by this wiki.
 2105+ * @param bool $exists True to get all restriction types that apply to
 2106+ * titles that do exist, False for all restriction types that apply to
 2107+ * titles that do not exist
 2108+ * @return array
 2109+ */
 2110+ public static function getFilteredRestrictionTypes( $exists = true ) {
 2111+ global $wgRestrictionTypes;
 2112+ $types = $wgRestrictionTypes;
 2113+ if ( $exists ) {
 2114+ # Remove the create restriction for existing titles
 2115+ $types = array_diff( $types, array( 'create' ) );
 2116+ } else {
 2117+ # Only the create and upload restrictions apply to non-existing titles
 2118+ $types = array_intersect( $types, array( 'create', 'upload' ) );
 2119+ }
 2120+ return $types;
 2121+ }
 2122+
 2123+ /**
 2124+ * Returns restriction types for the current Title
 2125+ *
 2126+ * @return array applicable restriction types
 2127+ */
 2128+ public function getRestrictionTypes() {
 2129+ if ( $this->isSpecialPage() ) {
 2130+ return array();
 2131+ }
 2132+
 2133+ $types = self::getFilteredRestrictionTypes( $this->exists() );
 2134+
 2135+ if ( $this->getNamespace() != NS_FILE ) {
 2136+ # Remove the upload restriction for non-file titles
 2137+ $types = array_diff( $types, array( 'upload' ) );
 2138+ }
 2139+
 2140+ wfRunHooks( 'TitleGetRestrictionTypes', array( $this, &$types ) );
 2141+
 2142+ wfDebug( __METHOD__ . ': applicable restrictions to [[' .
 2143+ $this->getPrefixedText() . ']] are {' . implode( ',', $types ) . "}\n" );
 2144+
 2145+ return $types;
 2146+ }
 2147+
 2148+ /**
18002149 * Is this title subject to title protection?
18012150 * Title protection is the one applied against creation of such title.
18022151 *
@@ -1905,86 +2254,57 @@
19062255 }
19072256
19082257 /**
1909 - * Would anybody with sufficient privileges be able to move this page?
1910 - * Some pages just aren't movable.
 2258+ * Is this page "semi-protected" - the *only* protection is autoconfirm?
19112259 *
1912 - * @return Bool TRUE or FALSE
 2260+ * @param $action String Action to check (default: edit)
 2261+ * @return Bool
19132262 */
1914 - public function isMovable() {
1915 - if ( !MWNamespace::isMovable( $this->getNamespace() ) || $this->getInterwiki() != '' ) {
1916 - // Interwiki title or immovable namespace. Hooks don't get to override here
 2263+ public function isSemiProtected( $action = 'edit' ) {
 2264+ if ( $this->exists() ) {
 2265+ $restrictions = $this->getRestrictions( $action );
 2266+ if ( count( $restrictions ) > 0 ) {
 2267+ foreach ( $restrictions as $restriction ) {
 2268+ if ( strtolower( $restriction ) != 'autoconfirmed' ) {
 2269+ return false;
 2270+ }
 2271+ }
 2272+ } else {
 2273+ # Not protected
 2274+ return false;
 2275+ }
 2276+ return true;
 2277+ } else {
 2278+ # If it doesn't exist, it can't be protected
19172279 return false;
19182280 }
1919 -
1920 - $result = true;
1921 - wfRunHooks( 'TitleIsMovable', array( $this, &$result ) );
1922 - return $result;
19232281 }
19242282
19252283 /**
1926 - * Is this the mainpage?
1927 - * @note Title::newFromText seams to be sufficiently optimized by the title
1928 - * cache that we don't need to over-optimize by doing direct comparisons and
1929 - * acidentally creating new bugs where $title->equals( Title::newFromText() )
1930 - * ends up reporting something differently than $title->isMainPage();
 2284+ * Does the title correspond to a protected article?
19312285 *
1932 - * @since 1.18
 2286+ * @param $action String the action the page is protected from,
 2287+ * by default checks all actions.
19332288 * @return Bool
19342289 */
1935 - public function isMainPage() {
1936 - return $this->equals( Title::newMainPage() );
1937 - }
 2290+ public function isProtected( $action = '' ) {
 2291+ global $wgRestrictionLevels;
19382292
1939 - /**
1940 - * Is this a talk page of some sort?
1941 - *
1942 - * @return Bool
1943 - */
1944 - public function isTalkPage() {
1945 - return MWNamespace::isTalk( $this->getNamespace() );
1946 - }
 2293+ $restrictionTypes = $this->getRestrictionTypes();
19472294
1948 - /**
1949 - * Is this a subpage?
1950 - *
1951 - * @return Bool
1952 - */
1953 - public function isSubpage() {
1954 - return MWNamespace::hasSubpages( $this->mNamespace )
1955 - ? strpos( $this->getText(), '/' ) !== false
1956 - : false;
1957 - }
1958 -
1959 - /**
1960 - * Returns true if the title is inside the specified namespace.
1961 - *
1962 - * Please make use of this instead of comparing to getNamespace()
1963 - * This function is much more resistant to changes we may make
1964 - * to namespaces than code that makes direct comparisons.
1965 - * @param $ns int The namespace
1966 - * @return bool
1967 - * @since 1.19
1968 - */
1969 - public function inNamespace( $ns ) {
1970 - return MWNamespace::equals( $this->getNamespace(), $ns );
1971 - }
1972 -
1973 - /**
1974 - * Returns true if the title is inside one of the specified namespaces.
1975 - *
1976 - * @param ...$namespaces The namespaces to check for
1977 - * @return bool
1978 - * @since 1.19
1979 - */
1980 - public function inNamespaces( /* ... */ ) {
1981 - $namespaces = func_get_args();
1982 - if ( count( $namespaces ) > 0 && is_array( $namespaces[0] ) ) {
1983 - $namespaces = $namespaces[0];
 2295+ # Special pages have inherent protection
 2296+ if( $this->isSpecialPage() ) {
 2297+ return true;
19842298 }
19852299
1986 - foreach ( $namespaces as $ns ) {
1987 - if ( $this->inNamespace( $ns ) ) {
1988 - return true;
 2300+ # Check regular protection levels
 2301+ foreach ( $restrictionTypes as $type ) {
 2302+ if ( $action == $type || $action == '' ) {
 2303+ $r = $this->getRestrictions( $type );
 2304+ foreach ( $wgRestrictionLevels as $level ) {
 2305+ if ( in_array( $level, $r ) && $level != '' ) {
 2306+ return true;
 2307+ }
 2308+ }
19892309 }
19902310 }
19912311
@@ -1992,178 +2312,26 @@
19932313 }
19942314
19952315 /**
1996 - * Returns true if the title has the same subject namespace as the
1997 - * namespace specified.
1998 - * For example this method will take NS_USER and return true if namespace
1999 - * is either NS_USER or NS_USER_TALK since both of them have NS_USER
2000 - * as their subject namespace.
 2316+ * Determines if $user is unable to edit this page because it has been protected
 2317+ * by $wgNamespaceProtection.
20012318 *
2002 - * This is MUCH simpler than individually testing for equivilance
2003 - * against both NS_USER and NS_USER_TALK, and is also forward compatible.
2004 - * @since 1.19
2005 - */
2006 - public function hasSubjectNamespace( $ns ) {
2007 - return MWNamespace::subjectEquals( $this->getNamespace(), $ns );
2008 - }
2009 -
2010 - /**
2011 - * Does this have subpages? (Warning, usually requires an extra DB query.)
2012 - *
 2319+ * @param $user User object to check permissions
20132320 * @return Bool
20142321 */
2015 - public function hasSubpages() {
2016 - if ( !MWNamespace::hasSubpages( $this->mNamespace ) ) {
2017 - # Duh
2018 - return false;
2019 - }
 2322+ public function isNamespaceProtected( User $user ) {
 2323+ global $wgNamespaceProtection;
20202324
2021 - # We dynamically add a member variable for the purpose of this method
2022 - # alone to cache the result. There's no point in having it hanging
2023 - # around uninitialized in every Title object; therefore we only add it
2024 - # if needed and don't declare it statically.
2025 - if ( isset( $this->mHasSubpages ) ) {
2026 - return $this->mHasSubpages;
 2325+ if ( isset( $wgNamespaceProtection[$this->mNamespace] ) ) {
 2326+ foreach ( (array)$wgNamespaceProtection[$this->mNamespace] as $right ) {
 2327+ if ( $right != '' && !$user->isAllowed( $right ) ) {
 2328+ return true;
 2329+ }
 2330+ }
20272331 }
2028 -
2029 - $subpages = $this->getSubpages( 1 );
2030 - if ( $subpages instanceof TitleArray ) {
2031 - return $this->mHasSubpages = (bool)$subpages->count();
2032 - }
2033 - return $this->mHasSubpages = false;
 2332+ return false;
20342333 }
20352334
20362335 /**
2037 - * Get all subpages of this page.
2038 - *
2039 - * @param $limit Int maximum number of subpages to fetch; -1 for no limit
2040 - * @return mixed TitleArray, or empty array if this page's namespace
2041 - * doesn't allow subpages
2042 - */
2043 - public function getSubpages( $limit = -1 ) {
2044 - if ( !MWNamespace::hasSubpages( $this->getNamespace() ) ) {
2045 - return array();
2046 - }
2047 -
2048 - $dbr = wfGetDB( DB_SLAVE );
2049 - $conds['page_namespace'] = $this->getNamespace();
2050 - $conds[] = 'page_title ' . $dbr->buildLike( $this->getDBkey() . '/', $dbr->anyString() );
2051 - $options = array();
2052 - if ( $limit > -1 ) {
2053 - $options['LIMIT'] = $limit;
2054 - }
2055 - return $this->mSubpages = TitleArray::newFromResult(
2056 - $dbr->select( 'page',
2057 - array( 'page_id', 'page_namespace', 'page_title', 'page_is_redirect' ),
2058 - $conds,
2059 - __METHOD__,
2060 - $options
2061 - )
2062 - );
2063 - }
2064 -
2065 - /**
2066 - * Does that page contain wikitext, or it is JS, CSS or whatever?
2067 - *
2068 - * @return Bool
2069 - */
2070 - public function isWikitextPage() {
2071 - $retval = !$this->isCssOrJsPage() && !$this->isCssJsSubpage();
2072 - wfRunHooks( 'TitleIsWikitextPage', array( $this, &$retval ) );
2073 - return $retval;
2074 - }
2075 -
2076 - /**
2077 - * Could this page contain custom CSS or JavaScript, based
2078 - * on the title?
2079 - *
2080 - * @return Bool
2081 - */
2082 - public function isCssOrJsPage() {
2083 - $retval = $this->mNamespace == NS_MEDIAWIKI
2084 - && preg_match( '!\.(?:css|js)$!u', $this->mTextform ) > 0;
2085 - wfRunHooks( 'TitleIsCssOrJsPage', array( $this, &$retval ) );
2086 - return $retval;
2087 - }
2088 -
2089 - /**
2090 - * Is this a .css or .js subpage of a user page?
2091 - * @return Bool
2092 - */
2093 - public function isCssJsSubpage() {
2094 - return ( NS_USER == $this->mNamespace and preg_match( "/\\/.*\\.(?:css|js)$/", $this->mTextform ) );
2095 - }
2096 -
2097 - /**
2098 - * Is this a *valid* .css or .js subpage of a user page?
2099 - *
2100 - * @return Bool
2101 - * @deprecated since 1.17
2102 - */
2103 - public function isValidCssJsSubpage() {
2104 - return $this->isCssJsSubpage();
2105 - }
2106 -
2107 - /**
2108 - * Trim down a .css or .js subpage title to get the corresponding skin name
2109 - *
2110 - * @return string containing skin name from .css or .js subpage title
2111 - */
2112 - public function getSkinFromCssJsSubpage() {
2113 - $subpage = explode( '/', $this->mTextform );
2114 - $subpage = $subpage[ count( $subpage ) - 1 ];
2115 - $lastdot = strrpos( $subpage, '.' );
2116 - if ( $lastdot === false )
2117 - return $subpage; # Never happens: only called for names ending in '.css' or '.js'
2118 - return substr( $subpage, 0, $lastdot );
2119 - }
2120 -
2121 - /**
2122 - * Is this a .css subpage of a user page?
2123 - *
2124 - * @return Bool
2125 - */
2126 - public function isCssSubpage() {
2127 - return ( NS_USER == $this->mNamespace && preg_match( "/\\/.*\\.css$/", $this->mTextform ) );
2128 - }
2129 -
2130 - /**
2131 - * Is this a .js subpage of a user page?
2132 - *
2133 - * @return Bool
2134 - */
2135 - public function isJsSubpage() {
2136 - return ( NS_USER == $this->mNamespace && preg_match( "/\\/.*\\.js$/", $this->mTextform ) );
2137 - }
2138 -
2139 - /**
2140 - * Protect css subpages of user pages: can $wgUser edit
2141 - * this page?
2142 - *
2143 - * @deprecated in 1.19; will be removed in 1.20. Use getUserPermissionsErrors() instead.
2144 - * @return Bool
2145 - */
2146 - public function userCanEditCssSubpage() {
2147 - global $wgUser;
2148 - wfDeprecated( __METHOD__ );
2149 - return ( ( $wgUser->isAllowedAll( 'editusercssjs', 'editusercss' ) )
2150 - || preg_match( '/^' . preg_quote( $wgUser->getName(), '/' ) . '\//', $this->mTextform ) );
2151 - }
2152 -
2153 - /**
2154 - * Protect js subpages of user pages: can $wgUser edit
2155 - * this page?
2156 - *
2157 - * @deprecated in 1.19; will be removed in 1.20. Use getUserPermissionsErrors() instead.
2158 - * @return Bool
2159 - */
2160 - public function userCanEditJsSubpage() {
2161 - global $wgUser;
2162 - wfDeprecated( __METHOD__ );
2163 - return ( ( $wgUser->isAllowedAll( 'editusercssjs', 'edituserjs' ) )
2164 - || preg_match( '/^' . preg_quote( $wgUser->getName(), '/' ) . '\//', $this->mTextform ) );
2165 - }
2166 -
2167 - /**
21682336 * Cascading protection: Return true if cascading restrictions apply to this page, false if not.
21692337 *
21702338 * @return Bool If the page is subject to cascading restrictions.
@@ -2272,6 +2440,34 @@
22732441 }
22742442
22752443 /**
 2444+ * Accessor/initialisation for mRestrictions
 2445+ *
 2446+ * @param $action String action that permission needs to be checked for
 2447+ * @return Array of Strings the array of groups allowed to edit this article
 2448+ */
 2449+ public function getRestrictions( $action ) {
 2450+ if ( !$this->mRestrictionsLoaded ) {
 2451+ $this->loadRestrictions();
 2452+ }
 2453+ return isset( $this->mRestrictions[$action] )
 2454+ ? $this->mRestrictions[$action]
 2455+ : array();
 2456+ }
 2457+
 2458+ /**
 2459+ * Get the expiry time for the restriction against a given action
 2460+ *
 2461+ * @return String|Bool 14-char timestamp, or 'infinity' if the page is protected forever
 2462+ * or not protected at all, or false if the action is not recognised.
 2463+ */
 2464+ public function getRestrictionExpiry( $action ) {
 2465+ if ( !$this->mRestrictionsLoaded ) {
 2466+ $this->loadRestrictions();
 2467+ }
 2468+ return isset( $this->mRestrictionsExpiry[$action] ) ? $this->mRestrictionsExpiry[$action] : false;
 2469+ }
 2470+
 2471+ /**
22762472 * Returns cascading restrictions for the current article
22772473 *
22782474 * @return Boolean
@@ -2445,31 +2641,58 @@
24462642 }
24472643
24482644 /**
2449 - * Accessor/initialisation for mRestrictions
 2645+ * Does this have subpages? (Warning, usually requires an extra DB query.)
24502646 *
2451 - * @param $action String action that permission needs to be checked for
2452 - * @return Array of Strings the array of groups allowed to edit this article
 2647+ * @return Bool
24532648 */
2454 - public function getRestrictions( $action ) {
2455 - if ( !$this->mRestrictionsLoaded ) {
2456 - $this->loadRestrictions();
 2649+ public function hasSubpages() {
 2650+ if ( !MWNamespace::hasSubpages( $this->mNamespace ) ) {
 2651+ # Duh
 2652+ return false;
24572653 }
2458 - return isset( $this->mRestrictions[$action] )
2459 - ? $this->mRestrictions[$action]
2460 - : array();
 2654+
 2655+ # We dynamically add a member variable for the purpose of this method
 2656+ # alone to cache the result. There's no point in having it hanging
 2657+ # around uninitialized in every Title object; therefore we only add it
 2658+ # if needed and don't declare it statically.
 2659+ if ( isset( $this->mHasSubpages ) ) {
 2660+ return $this->mHasSubpages;
 2661+ }
 2662+
 2663+ $subpages = $this->getSubpages( 1 );
 2664+ if ( $subpages instanceof TitleArray ) {
 2665+ return $this->mHasSubpages = (bool)$subpages->count();
 2666+ }
 2667+ return $this->mHasSubpages = false;
24612668 }
24622669
24632670 /**
2464 - * Get the expiry time for the restriction against a given action
 2671+ * Get all subpages of this page.
24652672 *
2466 - * @return String|Bool 14-char timestamp, or 'infinity' if the page is protected forever
2467 - * or not protected at all, or false if the action is not recognised.
 2673+ * @param $limit Int maximum number of subpages to fetch; -1 for no limit
 2674+ * @return mixed TitleArray, or empty array if this page's namespace
 2675+ * doesn't allow subpages
24682676 */
2469 - public function getRestrictionExpiry( $action ) {
2470 - if ( !$this->mRestrictionsLoaded ) {
2471 - $this->loadRestrictions();
 2677+ public function getSubpages( $limit = -1 ) {
 2678+ if ( !MWNamespace::hasSubpages( $this->getNamespace() ) ) {
 2679+ return array();
24722680 }
2473 - return isset( $this->mRestrictionsExpiry[$action] ) ? $this->mRestrictionsExpiry[$action] : false;
 2681+
 2682+ $dbr = wfGetDB( DB_SLAVE );
 2683+ $conds['page_namespace'] = $this->getNamespace();
 2684+ $conds[] = 'page_title ' . $dbr->buildLike( $this->getDBkey() . '/', $dbr->anyString() );
 2685+ $options = array();
 2686+ if ( $limit > -1 ) {
 2687+ $options['LIMIT'] = $limit;
 2688+ }
 2689+ return $this->mSubpages = TitleArray::newFromResult(
 2690+ $dbr->select( 'page',
 2691+ array( 'page_id', 'page_namespace', 'page_title', 'page_is_redirect' ),
 2692+ $conds,
 2693+ __METHOD__,
 2694+ $options
 2695+ )
 2696+ );
24742697 }
24752698
24762699 /**
@@ -2658,73 +2881,6 @@
26592882 }
26602883
26612884 /**
2662 - * Updates page_touched for this page; called from LinksUpdate.php
2663 - *
2664 - * @return Bool true if the update succeded
2665 - */
2666 - public function invalidateCache() {
2667 - if ( wfReadOnly() ) {
2668 - return false;
2669 - }
2670 - $dbw = wfGetDB( DB_MASTER );
2671 - $success = $dbw->update(
2672 - 'page',
2673 - array( 'page_touched' => $dbw->timestamp() ),
2674 - $this->pageCond(),
2675 - __METHOD__
2676 - );
2677 - HTMLFileCache::clearFileCache( $this );
2678 - return $success;
2679 - }
2680 -
2681 - /**
2682 - * Prefix some arbitrary text with the namespace or interwiki prefix
2683 - * of this object
2684 - *
2685 - * @param $name String the text
2686 - * @return String the prefixed text
2687 - * @private
2688 - */
2689 - private function prefix( $name ) {
2690 - $p = '';
2691 - if ( $this->mInterwiki != '' ) {
2692 - $p = $this->mInterwiki . ':';
2693 - }
2694 -
2695 - if ( 0 != $this->mNamespace ) {
2696 - $p .= $this->getNsText() . ':';
2697 - }
2698 - return $p . $name;
2699 - }
2700 -
2701 - /**
2702 - * Returns a simple regex that will match on characters and sequences invalid in titles.
2703 - * Note that this doesn't pick up many things that could be wrong with titles, but that
2704 - * replacing this regex with something valid will make many titles valid.
2705 - *
2706 - * @return String regex string
2707 - */
2708 - static function getTitleInvalidRegex() {
2709 - static $rxTc = false;
2710 - if ( !$rxTc ) {
2711 - # Matching titles will be held as illegal.
2712 - $rxTc = '/' .
2713 - # Any character not allowed is forbidden...
2714 - '[^' . Title::legalChars() . ']' .
2715 - # URL percent encoding sequences interfere with the ability
2716 - # to round-trip titles -- you can't link to them consistently.
2717 - '|%[0-9A-Fa-f]{2}' .
2718 - # XML/HTML character references produce similar issues.
2719 - '|&[A-Za-z0-9\x80-\xff]+;' .
2720 - '|&#[0-9]+;' .
2721 - '|&#x[0-9A-Fa-f]+;' .
2722 - '/S';
2723 - }
2724 -
2725 - return $rxTc;
2726 - }
2727 -
2728 - /**
27292885 * Capitalize a text string for a title if it belongs to a namespace that capitalizes
27302886 *
27312887 * @param $text String containing title to capitalize
@@ -2939,44 +3095,6 @@
29403096 }
29413097
29423098 /**
2943 - * Set the fragment for this title. Removes the first character from the
2944 - * specified fragment before setting, so it assumes you're passing it with
2945 - * an initial "#".
2946 - *
2947 - * Deprecated for public use, use Title::makeTitle() with fragment parameter.
2948 - * Still in active use privately.
2949 - *
2950 - * @param $fragment String text
2951 - */
2952 - public function setFragment( $fragment ) {
2953 - $this->mFragment = str_replace( '_', ' ', substr( $fragment, 1 ) );
2954 - }
2955 -
2956 - /**
2957 - * Get a Title object associated with the talk page of this article
2958 - *
2959 - * @return Title the object for the talk page
2960 - */
2961 - public function getTalkPage() {
2962 - return Title::makeTitle( MWNamespace::getTalk( $this->getNamespace() ), $this->getDBkey() );
2963 - }
2964 -
2965 - /**
2966 - * Get a title object associated with the subject page of this
2967 - * talk page
2968 - *
2969 - * @return Title the object for the subject page
2970 - */
2971 - public function getSubjectPage() {
2972 - // Is this the same title?
2973 - $subjectNS = MWNamespace::getSubject( $this->getNamespace() );
2974 - if ( $this->getNamespace() == $subjectNS ) {
2975 - return $this;
2976 - }
2977 - return Title::makeTitle( $subjectNS, $this->getDBkey() );
2978 - }
2979 -
2980 - /**
29813099 * Get an array of Title objects linking to this Title
29823100 * Also stores the IDs in the link cache.
29833101 *
@@ -3714,15 +3832,6 @@
37153833 }
37163834
37173835 /**
3718 - * Can this title be added to a user's watchlist?
3719 - *
3720 - * @return Bool TRUE or FALSE
3721 - */
3722 - public function isWatchable() {
3723 - return !$this->isExternal() && MWNamespace::isWatchable( $this->getNamespace() );
3724 - }
3725 -
3726 - /**
37273836 * Get categories to which this Title belongs and return an array of
37283837 * categories' names.
37293838 *
@@ -3968,31 +4077,6 @@
39694078 }
39704079
39714080 /**
3972 - * Callback for usort() to do title sorts by (namespace, title)
3973 - *
3974 - * @param $a Title
3975 - * @param $b Title
3976 - *
3977 - * @return Integer: result of string comparison, or namespace comparison
3978 - */
3979 - public static function compare( $a, $b ) {
3980 - if ( $a->getNamespace() == $b->getNamespace() ) {
3981 - return strcmp( $a->getText(), $b->getText() );
3982 - } else {
3983 - return $a->getNamespace() - $b->getNamespace();
3984 - }
3985 - }
3986 -
3987 - /**
3988 - * Return a string representation of this title
3989 - *
3990 - * @return String representation of this title
3991 - */
3992 - public function __toString() {
3993 - return $this->getPrefixedText();
3994 - }
3995 -
3996 - /**
39974081 * Check if page exists. For historical reasons, this function simply
39984082 * checks for the existence of the title in the page table, and will
39994083 * thus return false for interwiki links, special pages and the like.
@@ -4103,13 +4187,23 @@
41044188 }
41054189
41064190 /**
4107 - * Is this in a namespace that allows actual pages?
 4191+ * Updates page_touched for this page; called from LinksUpdate.php
41084192 *
4109 - * @return Bool
4110 - * @internal note -- uses hardcoded namespace index instead of constants
 4193+ * @return Bool true if the update succeded
41114194 */
4112 - public function canExist() {
4113 - return $this->mNamespace >= 0 && $this->mNamespace != NS_MEDIA;
 4195+ public function invalidateCache() {
 4196+ if ( wfReadOnly() ) {
 4197+ return false;
 4198+ }
 4199+ $dbw = wfGetDB( DB_MASTER );
 4200+ $success = $dbw->update(
 4201+ 'page',
 4202+ array( 'page_touched' => $dbw->timestamp() ),
 4203+ $this->pageCond(),
 4204+ __METHOD__
 4205+ );
 4206+ HTMLFileCache::clearFileCache( $this );
 4207+ return $success;
41144208 }
41154209
41164210 /**
@@ -4208,61 +4302,6 @@
42094303 }
42104304
42114305 /**
4212 - * Returns true if this is a special page.
4213 - *
4214 - * @return boolean
4215 - */
4216 - public function isSpecialPage() {
4217 - return $this->getNamespace() == NS_SPECIAL;
4218 - }
4219 -
4220 - /**
4221 - * Returns true if this title resolves to the named special page
4222 - *
4223 - * @param $name String The special page name
4224 - * @return boolean
4225 - */
4226 - public function isSpecial( $name ) {
4227 - if ( $this->isSpecialPage() ) {
4228 - list( $thisName, /* $subpage */ ) = SpecialPageFactory::resolveAlias( $this->getDBkey() );
4229 - if ( $name == $thisName ) {
4230 - return true;
4231 - }
4232 - }
4233 - return false;
4234 - }
4235 -
4236 - /**
4237 - * If the Title refers to a special page alias which is not the local default, resolve
4238 - * the alias, and localise the name as necessary. Otherwise, return $this
4239 - *
4240 - * @return Title
4241 - */
4242 - public function fixSpecialName() {
4243 - if ( $this->isSpecialPage() ) {
4244 - list( $canonicalName, $par ) = SpecialPageFactory::resolveAlias( $this->mDbkeyform );
4245 - if ( $canonicalName ) {
4246 - $localName = SpecialPageFactory::getLocalNameFor( $canonicalName, $par );
4247 - if ( $localName != $this->mDbkeyform ) {
4248 - return Title::makeTitle( NS_SPECIAL, $localName );
4249 - }
4250 - }
4251 - }
4252 - return $this;
4253 - }
4254 -
4255 - /**
4256 - * Is this Title in a namespace which contains content?
4257 - * In other words, is this a content page, for the purposes of calculating
4258 - * statistics, etc?
4259 - *
4260 - * @return Boolean
4261 - */
4262 - public function isContentPage() {
4263 - return MWNamespace::isContent( $this->getNamespace() );
4264 - }
4265 -
4266 - /**
42674306 * Get all extant redirects to this Title
42684307 *
42694308 * @param $ns Int|Null Single namespace to consider; NULL to consider all namespaces
@@ -4345,50 +4384,6 @@
43464385 }
43474386
43484387 /**
4349 - * Returns restriction types for the current Title
4350 - *
4351 - * @return array applicable restriction types
4352 - */
4353 - public function getRestrictionTypes() {
4354 - if ( $this->isSpecialPage() ) {
4355 - return array();
4356 - }
4357 -
4358 - $types = self::getFilteredRestrictionTypes( $this->exists() );
4359 -
4360 - if ( $this->getNamespace() != NS_FILE ) {
4361 - # Remove the upload restriction for non-file titles
4362 - $types = array_diff( $types, array( 'upload' ) );
4363 - }
4364 -
4365 - wfRunHooks( 'TitleGetRestrictionTypes', array( $this, &$types ) );
4366 -
4367 - wfDebug( __METHOD__ . ': applicable restrictions to [[' .
4368 - $this->getPrefixedText() . ']] are {' . implode( ',', $types ) . "}\n" );
4369 -
4370 - return $types;
4371 - }
4372 - /**
4373 - * Get a filtered list of all restriction types supported by this wiki.
4374 - * @param bool $exists True to get all restriction types that apply to
4375 - * titles that do exist, False for all restriction types that apply to
4376 - * titles that do not exist
4377 - * @return array
4378 - */
4379 - public static function getFilteredRestrictionTypes( $exists = true ) {
4380 - global $wgRestrictionTypes;
4381 - $types = $wgRestrictionTypes;
4382 - if ( $exists ) {
4383 - # Remove the create restriction for existing titles
4384 - $types = array_diff( $types, array( 'create' ) );
4385 - } else {
4386 - # Only the create and upload restrictions apply to non-existing titles
4387 - $types = array_intersect( $types, array( 'create', 'upload' ) );
4388 - }
4389 - return $types;
4390 - }
4391 -
4392 - /**
43934388 * Returns the raw sort key to be used for categories, with the specified
43944389 * prefix. This will be fed to Collation::getSortKey() to get a
43954390 * binary sortkey that can be used for actual sorting.

Sign-offs

UserFlagDate
Hasharinspected09:50, 12 December 2011

Status & tagging log