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.
*
*/
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;
}
}
}
/**
- * 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
* @since 1.31
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
+ * @deprecated Since 1.31; use ::isSiteConfigPage() instead (which also checks for JSON pages)
*/
public function isCssOrJsPage() {
- // wfDeprecated( __METHOD__, '1.31' );
+ wfDeprecated( __METHOD__, '1.31' );
return ( NS_MEDIAWIKI == $this->mNamespace
&& ( $this->hasContentModel( CONTENT_MODEL_CSS )
|| $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT ) ) );
}
/**
- * Is this a "config" (.css or .js) sub-page of a user page?
+ * Is this a "config" (.css, .json, or .js) sub-page of a user page?
*
* @return bool
* @since 1.31
&& $this->isSubpage()
&& (
$this->hasContentModel( CONTENT_MODEL_CSS )
+ || $this->hasContentModel( CONTENT_MODEL_JSON )
|| $this->hasContentModel( CONTENT_MODEL_JAVASCRIPT )
)
);
/**
* @return bool
- * @deprecated Since 1.31; use ::isUserConfigPage() instead
+ * @deprecated Since 1.31; use ::isUserConfigPage() instead (which also checks for JSON pages)
*/
public function isCssJsSubpage() {
- // wfDeprecated( __METHOD__, '1.31' );
+ 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 getSkinFromConfigSubpage() {
$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 );
}
/**
* @deprecated Since 1.31; use ::getSkinFromConfigSubpage() instead
- * @return string Containing skin name from .css or .js subpage title
+ * @return string Containing skin name from .css, .json, or .js subpage title
*/
public function getSkinFromCssJsSubpage() {
wfDeprecated( __METHOD__, '1.31' );
* @return bool
*/
public function isCssSubpage() {
- // wfDeprecated( __METHOD__, '1.31' );
+ 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
}
/**
- * @deprecated Since 1.31; use ::isUserCssConfigPage()
+ * @deprecated Since 1.31; use ::isUserJsConfigPage()
* @return bool
*/
public function isJsSubpage() {
- // wfDeprecated( __METHOD__, '1.31' );
+ wfDeprecated( __METHOD__, '1.31' );
return $this->isUserJsConfigPage();
}
}
/**
- * 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
* @return array List of errors
*/
private function checkUserConfigPermissions( $action, $user, $errors, $rigor, $short ) {
- # Protect css/js subpages of user pages
+ # Protect css/json/js subpages of user pages
# XXX: this might be better using restrictions
if ( $action != 'patrol' ) {
&& !$user->isAllowedAny( 'editmyusercss', 'editusercss' )
) {
$errors[] = [ 'mycustomcssprotected', $action ];
+ } elseif (
+ $this->isUserJsonConfigPage()
+ && !$user->isAllowedAny( 'editmyuserjson', 'edituserjson' )
+ ) {
+ $errors[] = [ 'mycustomjsonprotected', $action ];
} elseif (
$this->isUserJsConfigPage()
&& !$user->isAllowedAny( 'editmyuserjs', 'edituserjs' )
&& !$user->isAllowed( 'editusercss' )
) {
$errors[] = [ 'customcssprotected', $action ];
+ } elseif (
+ $this->isUserJsonConfigPage()
+ && !$user->isAllowed( 'edituserjson' )
+ ) {
+ $errors[] = [ 'customjsonprotected', $action ];
} elseif (
$this->isUserJsConfigPage()
&& !$user->isAllowed( 'edituserjs' )
return $errors;
}
- if ( $wgEmailConfirmToEdit && !$user->isEmailConfirmed() ) {
+ if ( $wgEmailConfirmToEdit
+ && !$user->isEmailConfirmed()
+ && $action === 'edit'
+ ) {
$errors[] = [ 'confirmedittext' ];
}
// If we are looking at a css/js user subpage, purge the action=raw.
if ( $this->isUserJsConfigPage() ) {
$urls[] = $this->getInternalURL( 'action=raw&ctype=text/javascript' );
+ } elseif ( $this->isUserJsonConfigPage() ) {
+ $urls[] = $this->getInternalURL( 'action=raw&ctype=application/json' );
} elseif ( $this->isUserCssConfigPage() ) {
$urls[] = $this->getInternalURL( 'action=raw&ctype=text/css' );
}
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;
}
*/
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