X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FTitle.php;h=ec9840a228f2c84ff36afc61e0e9adc824dcb6ec;hb=a3a9b8d440c10e0f1937b20d36cd9e1004843197;hp=1be986376f9a55898885dd05fbb8f47ea2bfb2cc;hpb=8fd5a99f4e261d37cd7237a1992b1bcf03a764d3;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Title.php b/includes/Title.php index 1be986376f..ec9840a228 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -625,20 +625,6 @@ class Title implements LinkTarget { return $wgLegalTitleChars; } - /** - * Returns a simple regex that will match on characters and sequences invalid in titles. - * Note that this doesn't pick up many things that could be wrong with titles, but that - * replacing this regex with something valid will make many titles valid. - * - * @deprecated since 1.25, use MediaWikiTitleCodec::getTitleInvalidRegex() instead - * - * @return string Regex string - */ - static function getTitleInvalidRegex() { - wfDeprecated( __METHOD__, '1.25' ); - return MediaWikiTitleCodec::getTitleInvalidRegex(); - } - /** * Utility method for converting a character sequence from bytes to Unicode. * @@ -1041,12 +1027,11 @@ class Title implements LinkTarget { */ public function getNsText() { if ( $this->isExternal() ) { - // This probably shouldn't even happen, - // but for interwiki transclusion it sometimes does. - // Use the canonical namespaces if possible to try to - // resolve a foreign namespace. - if ( MWNamespace::exists( $this->mNamespace ) ) { - return MWNamespace::getCanonicalName( $this->mNamespace ); + // This probably shouldn't even happen, except for interwiki transclusion. + // If possible, use the canonical name for the foreign namespace. + $nsText = MWNamespace::getCanonicalName( $this->mNamespace ); + if ( $nsText !== false ) { + return $nsText; } } @@ -1292,71 +1277,153 @@ class Title implements LinkTarget { } /** - * Could this page contain custom CSS or JavaScript for the global UI. - * This is generally true for pages in the MediaWiki namespace having CONTENT_MODEL_CSS - * or CONTENT_MODEL_JAVASCRIPT. + * Could this MediaWiki namespace page contain custom CSS, JSON, or JavaScript for the + * global UI. This is generally true for pages in the MediaWiki namespace having + * CONTENT_MODEL_CSS, CONTENT_MODEL_JSON, or CONTENT_MODEL_JAVASCRIPT. * - * This method does *not* return true for per-user JS/CSS. Use isCssJsSubpage() + * This method does *not* return true for per-user JS/JSON/CSS. Use isUserConfigPage() * for that! * - * Note that this method should not return true for pages that contain and - * show "inactive" CSS or JS. + * Note that this method should not return true for pages that contain and show + * "inactive" CSS, JSON, or JS. * * @return bool - * @todo FIXME: Rename to isSiteConfigPage() and remove deprecated hook + * @since 1.31 + */ + public function isSiteConfigPage() { + return ( + NS_MEDIAWIKI == $this->mNamespace + && ( + $this->hasContentModel( CONTENT_MODEL_CSS ) + || $this->hasContentModel( CONTENT_MODEL_JSON ) + || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) + ) + ); + } + + /** + * @return bool + * @deprecated Since 1.31; use ::isSiteConfigPage() instead (which also checks for JSON pages) */ public function isCssOrJsPage() { - $isCssOrJsPage = NS_MEDIAWIKI == $this->mNamespace - && ( $this->hasContentModel( CONTENT_MODEL_CSS ) - || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ); + wfDeprecated( __METHOD__, '1.31' ); + return ( NS_MEDIAWIKI == $this->mNamespace + && ( $this->hasContentModel( CONTENT_MODEL_CSS ) + || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ) ); + } - return $isCssOrJsPage; + /** + * Is this a "config" (.css, .json, or .js) sub-page of a user page? + * + * @return bool + * @since 1.31 + */ + public function isUserConfigPage() { + return ( + NS_USER == $this->mNamespace + && $this->isSubpage() + && ( + $this->hasContentModel( CONTENT_MODEL_CSS ) + || $this->hasContentModel( CONTENT_MODEL_JSON ) + || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) + ) + ); } /** - * Is this a .css or .js subpage of a user page? * @return bool - * @todo FIXME: Rename to isUserConfigPage() + * @deprecated Since 1.31; use ::isUserConfigPage() instead (which also checks for JSON pages) */ public function isCssJsSubpage() { + wfDeprecated( __METHOD__, '1.31' ); return ( NS_USER == $this->mNamespace && $this->isSubpage() && ( $this->hasContentModel( CONTENT_MODEL_CSS ) || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ) ); } /** - * Trim down a .css or .js subpage title to get the corresponding skin name + * Trim down a .css, .json, or .js subpage title to get the corresponding skin name * - * @return string Containing skin name from .css or .js subpage title + * @return string Containing skin name from .css, .json, or .js subpage title + * @since 1.31 */ - public function getSkinFromCssJsSubpage() { + public function getSkinFromConfigSubpage() { $subpage = explode( '/', $this->mTextform ); $subpage = $subpage[count( $subpage ) - 1]; $lastdot = strrpos( $subpage, '.' ); if ( $lastdot === false ) { - return $subpage; # Never happens: only called for names ending in '.css' or '.js' + return $subpage; # Never happens: only called for names ending in '.css'/'.json'/'.js' } return substr( $subpage, 0, $lastdot ); } /** - * Is this a .css subpage of a user page? + * @deprecated Since 1.31; use ::getSkinFromConfigSubpage() instead + * @return string Containing skin name from .css, .json, or .js subpage title + */ + public function getSkinFromCssJsSubpage() { + wfDeprecated( __METHOD__, '1.31' ); + return $this->getSkinFromConfigSubpage(); + } + + /** + * Is this a CSS "config" sub-page of a user page? * * @return bool + * @since 1.31 + */ + public function isUserCssConfigPage() { + return ( + NS_USER == $this->mNamespace + && $this->isSubpage() + && $this->hasContentModel( CONTENT_MODEL_CSS ) + ); + } + + /** + * @deprecated Since 1.31; use ::isUserCssConfigPage() + * @return bool */ public function isCssSubpage() { - return ( NS_USER == $this->mNamespace && $this->isSubpage() - && $this->hasContentModel( CONTENT_MODEL_CSS ) ); + wfDeprecated( __METHOD__, '1.31' ); + return $this->isUserCssConfigPage(); } /** - * Is this a .js subpage of a user page? + * Is this a JSON "config" sub-page of a user page? * * @return bool + * @since 1.31 + */ + public function isUserJsonConfigPage() { + return ( + NS_USER == $this->mNamespace + && $this->isSubpage() + && $this->hasContentModel( CONTENT_MODEL_JSON ) + ); + } + + /** + * Is this a JS "config" sub-page of a user page? + * + * @return bool + * @since 1.31 + */ + public function isUserJsConfigPage() { + return ( + NS_USER == $this->mNamespace + && $this->isSubpage() + && $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) + ); + } + + /** + * @deprecated Since 1.31; use ::isUserJsConfigPage() + * @return bool */ public function isJsSubpage() { - return ( NS_USER == $this->mNamespace && $this->isSubpage() - && $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ); + wfDeprecated( __METHOD__, '1.31' ); + return $this->isUserJsConfigPage(); } /** @@ -2250,7 +2317,7 @@ class Title implements LinkTarget { } /** - * Check CSS/JS sub-page permissions + * Check CSS/JSON/JS sub-page permissions * * @param string $action The action to check * @param User $user User to check @@ -2260,20 +2327,43 @@ class Title implements LinkTarget { * * @return array List of errors */ - private function checkCSSandJSPermissions( $action, $user, $errors, $rigor, $short ) { - # Protect css/js subpages of user pages + private function checkUserConfigPermissions( $action, $user, $errors, $rigor, $short ) { + # Protect css/json/js subpages of user pages # XXX: this might be better using restrictions + if ( $action != 'patrol' ) { if ( preg_match( '/^' . preg_quote( $user->getName(), '/' ) . '\//', $this->mTextform ) ) { - if ( $this->isCssSubpage() && !$user->isAllowedAny( 'editmyusercss', 'editusercss' ) ) { + if ( + $this->isUserCssConfigPage() + && !$user->isAllowedAny( 'editmyusercss', 'editusercss' ) + ) { $errors[] = [ 'mycustomcssprotected', $action ]; - } elseif ( $this->isJsSubpage() && !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' ) ) { + } elseif ( + $this->isUserJsonConfigPage() + && !$user->isAllowedAny( 'editmyuserjson', 'edituserjson' ) + ) { + $errors[] = [ 'mycustomjsonprotected', $action ]; + } elseif ( + $this->isUserJsConfigPage() + && !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' ) + ) { $errors[] = [ 'mycustomjsprotected', $action ]; } } else { - if ( $this->isCssSubpage() && !$user->isAllowed( 'editusercss' ) ) { + if ( + $this->isUserCssConfigPage() + && !$user->isAllowed( 'editusercss' ) + ) { $errors[] = [ 'customcssprotected', $action ]; - } elseif ( $this->isJsSubpage() && !$user->isAllowed( 'edituserjs' ) ) { + } elseif ( + $this->isUserJsonConfigPage() + && !$user->isAllowed( 'edituserjson' ) + ) { + $errors[] = [ 'customjsonprotected', $action ]; + } elseif ( + $this->isUserJsConfigPage() + && !$user->isAllowed( 'edituserjs' ) + ) { $errors[] = [ 'customjsprotected', $action ]; } } @@ -2330,7 +2420,7 @@ class Title implements LinkTarget { * @return array List of errors */ private function checkCascadingSourcesRestrictions( $action, $user, $errors, $rigor, $short ) { - if ( $rigor !== 'quick' && !$this->isCssJsSubpage() ) { + if ( $rigor !== 'quick' && !$this->isUserConfigPage() ) { # We /could/ use the protection level on the source page, but it's # fairly ugly as we have to establish a precedence hierarchy for pages # included by multiple cascade-protected pages. So just restrict @@ -2466,7 +2556,10 @@ class Title implements LinkTarget { return $errors; } - if ( $wgEmailConfirmToEdit && !$user->isEmailConfirmed() ) { + if ( $wgEmailConfirmToEdit + && !$user->isEmailConfirmed() + && $action === 'edit' + ) { $errors[] = [ 'confirmedittext' ]; } @@ -2611,7 +2704,7 @@ class Title implements LinkTarget { 'checkReadPermissions', 'checkUserBlock', // for wgBlockDisablesLogin ]; - # Don't call checkSpecialsAndNSPermissions or checkCSSandJSPermissions + # Don't call checkSpecialsAndNSPermissions or checkUserConfigPermissions # here as it will lead to duplicate error messages. This is okay to do # since anywhere that checks for create will also check for edit, and # those checks are called for edit. @@ -2629,7 +2722,7 @@ class Title implements LinkTarget { 'checkQuickPermissions', 'checkPermissionHooks', 'checkSpecialsAndNSPermissions', - 'checkCSSandJSPermissions', + 'checkUserConfigPermissions', 'checkPageRestrictions', 'checkCascadingSourcesRestrictions', 'checkActionPermissions', @@ -3743,9 +3836,11 @@ class Title implements LinkTarget { } // If we are looking at a css/js user subpage, purge the action=raw. - if ( $this->isJsSubpage() ) { + if ( $this->isUserJsConfigPage() ) { $urls[] = $this->getInternalURL( 'action=raw&ctype=text/javascript' ); - } elseif ( $this->isCssSubpage() ) { + } elseif ( $this->isUserJsonConfigPage() ) { + $urls[] = $this->getInternalURL( 'action=raw&ctype=application/json' ); + } elseif ( $this->isUserCssConfigPage() ) { $urls[] = $this->getInternalURL( 'action=raw&ctype=text/css' ); } @@ -4389,17 +4484,18 @@ class Title implements LinkTarget { return $authors; } $dbr = wfGetDB( DB_REPLICA ); - $res = $dbr->select( 'revision', 'DISTINCT rev_user_text', + $revQuery = Revision::getQueryInfo(); + $authors = $dbr->selectFieldValues( + $revQuery['tables'], + $revQuery['fields']['rev_user_text'], [ 'rev_page' => $this->getArticleID(), "rev_timestamp $old_cmp " . $dbr->addQuotes( $dbr->timestamp( $old->getTimestamp() ) ), "rev_timestamp $new_cmp " . $dbr->addQuotes( $dbr->timestamp( $new->getTimestamp() ) ) ], __METHOD__, - [ 'LIMIT' => $limit + 1 ] // add one so caller knows it was truncated + [ 'DISTINCT', 'LIMIT' => $limit + 1 ], // add one so caller knows it was truncated + $revQuery['joins'] ); - foreach ( $res as $row ) { - $authors[] = $row->rev_user_text; - } return $authors; } @@ -4701,14 +4797,12 @@ class Title implements LinkTarget { */ public function getNamespaceKey( $prepend = 'nstab-' ) { global $wgContLang; - // Gets the subject namespace if this title - $namespace = MWNamespace::getSubject( $this->getNamespace() ); - // Checks if canonical namespace name exists for namespace - if ( MWNamespace::exists( $this->getNamespace() ) ) { - // Uses canonical namespace name - $namespaceKey = MWNamespace::getCanonicalName( $namespace ); - } else { - // Uses text of namespace + // Gets the subject namespace of this title + $subjectNS = MWNamespace::getSubject( $this->getNamespace() ); + // Prefer canonical namespace name for HTML IDs + $namespaceKey = MWNamespace::getCanonicalName( $subjectNS ); + if ( $namespaceKey === false ) { + // Fallback to localised text $namespaceKey = $this->getSubjectNsText(); } // Makes namespace key lowercase