X-Git-Url: https://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FTitle.php;h=01a28f5f7dac9c94c148b54941768469cb4b6410;hb=8af8ff84c0666a78dac14ba811daf1d9aa7de9aa;hp=b583554ab40660967151bc080d030126113d2df8;hpb=7a25cd388c8adcce60f4c055295baed71e730616;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/Title.php b/includes/Title.php index b583554ab4..01a28f5f7d 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -306,6 +306,10 @@ class Title implements LinkTarget { public static function newFromTextThrow( $text, $defaultNamespace = NS_MAIN ) { if ( is_object( $text ) ) { throw new MWException( '$text must be a string, given an object' ); + } elseif ( $text === null ) { + // Legacy code relies on MalformedTitleException being thrown in this case + // (happens when URL with no title in it is parsed). TODO fix + throw new MalformedTitleException( 'title-invalid-empty' ); } $titleCache = self::getTitleCache(); @@ -741,12 +745,10 @@ class Title implements LinkTarget { public static function makeName( $ns, $title, $fragment = '', $interwiki = '', $canonicalNamespace = false ) { - global $wgContLang; - if ( $canonicalNamespace ) { $namespace = MWNamespace::getCanonicalName( $ns ); } else { - $namespace = $wgContLang->getNsText( $ns ); + $namespace = MediaWikiServices::getInstance()->getContentLanguage()->getNsText( $ns ); } $name = $namespace == '' ? $title : "$namespace:$title"; if ( strval( $interwiki ) != '' ) { @@ -1047,8 +1049,8 @@ class Title implements LinkTarget { * @return string Namespace text */ public function getSubjectNsText() { - global $wgContLang; - return $wgContLang->getNsText( MWNamespace::getSubject( $this->mNamespace ) ); + return MediaWikiServices::getInstance()->getContentLanguage()-> + getNsText( MWNamespace::getSubject( $this->mNamespace ) ); } /** @@ -1057,8 +1059,8 @@ class Title implements LinkTarget { * @return string Namespace text */ public function getTalkNsText() { - global $wgContLang; - return $wgContLang->getNsText( MWNamespace::getTalk( $this->mNamespace ) ); + return MediaWikiServices::getInstance()->getContentLanguage()-> + getNsText( MWNamespace::getTalk( $this->mNamespace ) ); } /** @@ -1289,12 +1291,9 @@ class Title implements LinkTarget { */ public function isSiteConfigPage() { return ( - NS_MEDIAWIKI == $this->mNamespace - && ( - $this->hasContentModel( CONTENT_MODEL_CSS ) - || $this->hasContentModel( CONTENT_MODEL_JSON ) - || $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) - ) + $this->isSiteCssConfigPage() + || $this->isSiteJsonConfigPage() + || $this->isSiteJsConfigPage() ); } @@ -1317,13 +1316,9 @@ class Title implements LinkTarget { */ 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 ) - ) + $this->isUserCssConfigPage() + || $this->isUserJsonConfigPage() + || $this->isUserJsConfigPage() ); } @@ -1423,6 +1418,60 @@ class Title implements LinkTarget { return $this->isUserJsConfigPage(); } + /** + * Is this a sitewide CSS "config" page? + * + * @return bool + * @since 1.32 + */ + public function isSiteCssConfigPage() { + return ( + NS_MEDIAWIKI == $this->mNamespace + && ( + $this->hasContentModel( CONTENT_MODEL_CSS ) + // paranoia - a MediaWiki: namespace page with mismatching extension and content + // model is probably by mistake and might get handled incorrectly (see e.g. T112937) + || substr( $this->getDBkey(), -4 ) === '.css' + ) + ); + } + + /** + * Is this a sitewide JSON "config" page? + * + * @return bool + * @since 1.32 + */ + public function isSiteJsonConfigPage() { + return ( + NS_MEDIAWIKI == $this->mNamespace + && ( + $this->hasContentModel( CONTENT_MODEL_JSON ) + // paranoia - a MediaWiki: namespace page with mismatching extension and content + // model is probably by mistake and might get handled incorrectly (see e.g. T112937) + || substr( $this->getDBkey(), -5 ) === '.json' + ) + ); + } + + /** + * Is this a sitewide JS "config" page? + * + * @return bool + * @since 1.31 + */ + public function isSiteJsConfigPage() { + return ( + NS_MEDIAWIKI == $this->mNamespace + && ( + $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) + // paranoia - a MediaWiki: namespace page with mismatching extension and content + // model is probably by mistake and might get handled incorrectly (see e.g. T112937) + || substr( $this->getDBkey(), -3 ) === '.js' + ) + ); + } + /** * Is this a talk page of some sort? * @@ -1581,8 +1630,6 @@ class Title implements LinkTarget { * @return string The prefixed text */ private function prefix( $name ) { - global $wgContLang; - $p = ''; if ( $this->isExternal() ) { $p = $this->mInterwiki . ':'; @@ -1593,7 +1640,8 @@ class Title implements LinkTarget { if ( $nsText === false ) { // See T165149. Awkward, but better than erroneously linking to the main namespace. - $nsText = $wgContLang->getNsText( NS_SPECIAL ) . ":Badtitle/NS{$this->mNamespace}"; + $nsText = MediaWikiServices::getInstance()->getContentLanguage()-> + getNsText( NS_SPECIAL ) . ":Badtitle/NS{$this->mNamespace}"; } $p .= $nsText . ':'; @@ -1928,7 +1976,7 @@ class Title implements LinkTarget { $titleRef = $this; Hooks::run( 'GetLocalURL::Article', [ &$titleRef, &$url ] ); } else { - global $wgVariantArticlePath, $wgActionPaths, $wgContLang; + global $wgVariantArticlePath, $wgActionPaths; $url = false; $matches = []; @@ -1951,7 +1999,8 @@ class Title implements LinkTarget { if ( $url === false && $wgVariantArticlePath && preg_match( '/^variant=([^&]*)$/', $query, $matches ) - && $this->getPageLanguage()->equals( $wgContLang ) + && $this->getPageLanguage()->equals( + MediaWikiServices::getInstance()->getContentLanguage() ) && $this->getPageLanguage()->hasVariants() ) { $variant = urldecode( $matches[1] ); @@ -2313,6 +2362,44 @@ class Title implements LinkTarget { return $errors; } + /** + * Check sitewide CSS/JSON/JS permissions + * + * @param string $action The action to check + * @param User $user User to check + * @param array $errors List of current errors + * @param string $rigor Same format as Title::getUserPermissionsErrors() + * @param bool $short Short circuit on first error + * + * @return array List of errors + */ + private function checkSiteConfigPermissions( $action, $user, $errors, $rigor, $short ) { + if ( $action != 'patrol' ) { + $error = null; + // Sitewide CSS/JSON/JS changes, like all NS_MEDIAWIKI changes, also require the + // editinterface right. That's implemented as a restriction so no check needed here. + if ( $this->isSiteCssConfigPage() && !$user->isAllowed( 'editsitecss' ) ) { + $error = [ 'sitecssprotected', $action ]; + } elseif ( $this->isSiteJsonConfigPage() && !$user->isAllowed( 'editsitejson' ) ) { + $error = [ 'sitejsonprotected', $action ]; + } elseif ( $this->isSiteJsConfigPage() && !$user->isAllowed( 'editsitejs' ) ) { + $error = [ 'sitejsprotected', $action ]; + } + + if ( $error ) { + if ( $user->isAllowed( 'editinterface' ) ) { + // Most users / site admins will probably find out about the new, more restrictive + // permissions by failing to edit something. Give them more info. + // TODO remove this a few release cycles after 1.32 + $error = [ 'interfaceadmin-info', wfMessage( $error[0], $error[1] ) ]; + } + $errors[] = $error; + } + } + + return $errors; + } + /** * Check CSS/JSON/JS sub-page permissions * @@ -2701,10 +2788,10 @@ class Title implements LinkTarget { 'checkReadPermissions', 'checkUserBlock', // for wgBlockDisablesLogin ]; - # 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. + # Don't call checkSpecialsAndNSPermissions, checkSiteConfigPermissions + # 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. } elseif ( $action == 'create' ) { $checks = [ 'checkQuickPermissions', @@ -2719,6 +2806,7 @@ class Title implements LinkTarget { 'checkQuickPermissions', 'checkPermissionHooks', 'checkSpecialsAndNSPermissions', + 'checkSiteConfigPermissions', 'checkUserConfigPermissions', 'checkPageRestrictions', 'checkCascadingSourcesRestrictions', @@ -3587,10 +3675,8 @@ class Title implements LinkTarget { * @return string Containing capitalized title */ public static function capitalize( $text, $ns = NS_MAIN ) { - global $wgContLang; - if ( MWNamespace::isCapitalized( $ns ) ) { - return $wgContLang->ucfirst( $text ); + return MediaWikiServices::getInstance()->getContentLanguage()->ucfirst( $text ); } else { return $text; } @@ -3609,13 +3695,6 @@ class Title implements LinkTarget { * @return bool True on success */ private function secureAndSplit() { - # Initialisation - $this->mInterwiki = ''; - $this->mFragment = ''; - $this->mNamespace = $this->mDefaultNamespace; # Usually NS_MAIN - - $dbkey = $this->mDbkeyform; - // @note: splitTitleString() is a temporary hack to allow MediaWikiTitleCodec to share // the parsing code with Title, while avoiding massive refactoring. // @todo: get rid of secureAndSplit, refactor parsing code. @@ -3623,7 +3702,7 @@ class Title implements LinkTarget { // splitTitleString method, but the only implementation (MediaWikiTitleCodec) does $titleCodec = MediaWikiServices::getInstance()->getTitleParser(); // MalformedTitleException can be thrown here - $parts = $titleCodec->splitTitleString( $dbkey, $this->getDefaultNamespace() ); + $parts = $titleCodec->splitTitleString( $this->mDbkeyform, $this->getDefaultNamespace() ); # Fill fields $this->setFragment( '#' . $parts['fragment'] ); @@ -4137,8 +4216,6 @@ class Title implements LinkTarget { * $parent => $currentarticle */ public function getParentCategories() { - global $wgContLang; - $data = []; $titleKey = $this->getArticleID(); @@ -4157,9 +4234,11 @@ class Title implements LinkTarget { ); if ( $res->numRows() > 0 ) { + $contLang = MediaWikiServices::getInstance()->getContentLanguage(); foreach ( $res as $row ) { - // $data[] = Title::newFromText($wgContLang->getNsText ( NS_CATEGORY ).':'.$row->cl_to); - $data[$wgContLang->getNsText( NS_CATEGORY ) . ':' . $row->cl_to] = $this->getFullText(); + // $data[] = Title::newFromText( $contLang->getNsText ( NS_CATEGORY ).':'.$row->cl_to); + $data[$contLang->getNsText( NS_CATEGORY ) . ':' . $row->cl_to] = + $this->getFullText(); } } return $data; @@ -4643,11 +4722,11 @@ class Title implements LinkTarget { // message content will be displayed, same for language subpages- // Use always content language to avoid loading hundreds of languages // to get the link color. - global $wgContLang; + $contLang = MediaWikiServices::getInstance()->getContentLanguage(); list( $name, ) = MessageCache::singleton()->figureMessage( - $wgContLang->lcfirst( $this->getText() ) + $contLang->lcfirst( $this->getText() ) ); - $message = wfMessage( $name )->inLanguage( $wgContLang )->useDatabase( false ); + $message = wfMessage( $name )->inLanguage( $contLang )->useDatabase( false ); return $message->exists(); } @@ -4660,14 +4739,12 @@ class Title implements LinkTarget { * @return string|bool */ public function getDefaultMessageText() { - global $wgContLang; - if ( $this->getNamespace() != NS_MEDIAWIKI ) { // Just in case return false; } list( $name, $lang ) = MessageCache::singleton()->figureMessage( - $wgContLang->lcfirst( $this->getText() ) + MediaWikiServices::getInstance()->getContentLanguage()->lcfirst( $this->getText() ) ); $message = wfMessage( $name )->inLanguage( $lang )->useDatabase( false ); @@ -4794,7 +4871,6 @@ class Title implements LinkTarget { * @return string XML 'id' name */ public function getNamespaceKey( $prepend = 'nstab-' ) { - global $wgContLang; // Gets the subject namespace of this title $subjectNS = MWNamespace::getSubject( $this->getNamespace() ); // Prefer canonical namespace name for HTML IDs @@ -4804,7 +4880,7 @@ class Title implements LinkTarget { $namespaceKey = $this->getSubjectNsText(); } // Makes namespace key lowercase - $namespaceKey = $wgContLang->lc( $namespaceKey ); + $namespaceKey = MediaWikiServices::getInstance()->getContentLanguage()->lc( $namespaceKey ); // Uses main if ( $namespaceKey == '' ) { $namespaceKey = 'main'; @@ -4953,7 +5029,7 @@ class Title implements LinkTarget { /** * Get the language in which the content of this page is written in - * wikitext. Defaults to $wgContLang, but in certain cases it can be + * wikitext. Defaults to content language, but in certain cases it can be * e.g. $wgLang (such as special pages, which are in the user language). * * @since 1.18 @@ -4991,7 +5067,7 @@ class Title implements LinkTarget { /** * Get the language in which the content of this page is written when - * viewed by user. Defaults to $wgContLang, but in certain cases it can be + * viewed by user. Defaults to content language, but in certain cases it can be * e.g. $wgLang (such as special pages, which are in the user language). * * @since 1.20