removed. See https://www.mediawiki.org/wiki/Manual:Skin_autodiscovery for
migration guide for creators and users of custom skins that relied on it.
* Javascript variable 'wgFileCanRotate' now only available on Special:Upload.
-* (bug 56257) Set site logo url in ResourceLoaderSiteModule instead of inline
- styles in the HTML output.
== Compatibility ==
}
}
+ if ( !is_null( $params['group'] ) && !is_null( $params['excludegroup'] ) ) {
+ $this->dieUsage( 'group and excludegroup cannot be used together', 'group-excludegroup' );
+ }
+
if ( !is_null( $params['group'] ) && count( $params['group'] ) ) {
+ $useIndex = false;
// Filter only users that belong to a given group
- $this->addWhere( 'EXISTS (' . $db->selectSQLText(
- 'user_groups', '1', array( 'ug_user=user_id', 'ug_group' => $params['group'] )
- ) . ')' );
+ $this->addTables( 'user_groups', 'ug1' );
+ $this->addJoinConds( array( 'ug1' => array( 'INNER JOIN', array( 'ug1.ug_user=user_id',
+ 'ug1.ug_group' => $params['group'] ) ) ) );
}
if ( !is_null( $params['excludegroup'] ) && count( $params['excludegroup'] ) ) {
+ $useIndex = false;
// Filter only users don't belong to a given group
- $this->addWhere( 'NOT EXISTS (' . $db->selectSQLText(
- 'user_groups', '1', array( 'ug_user=user_id', 'ug_group' => $params['excludegroup'] )
- ) . ')' );
+ $this->addTables( 'user_groups', 'ug1' );
+
+ if ( count( $params['excludegroup'] ) == 1 ) {
+ $exclude = array( 'ug1.ug_group' => $params['excludegroup'][0] );
+ } else {
+ $exclude = array( $db->makeList(
+ array( 'ug1.ug_group' => $params['excludegroup'] ),
+ LIST_OR
+ ) );
+ }
+ $this->addJoinConds( array( 'ug1' => array( 'LEFT OUTER JOIN',
+ array_merge( array( 'ug1.ug_user=user_id' ), $exclude )
+ ) ) );
+ $this->addWhere( 'ug1.ug_user IS NULL' );
}
if ( $params['witheditsonly'] ) {
* @since 1.23
*/
private static function getCachedRevisionObject( $parser, $title = null ) {
- static $cache = null;
- if ( $cache == null ) {
- $cache = new MapCacheLRU( 50 );
- }
-
if ( is_null( $title ) ) {
return null;
}
// Normalize name for cache
$page = $title->getPrefixedDBkey();
- if ( $cache->has( $page ) ) { // cache contains null values
- return $cache->get( $page );
+ if ( !( $parser->currentRevisionCache && $parser->currentRevisionCache->has( $page ) )
+ && !$parser->incrementExpensiveFunctionCount() ) {
+ return null;
}
- if ( $parser->incrementExpensiveFunctionCount() ) {
- $rev = Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
- $pageID = $rev ? $rev->getPage() : 0;
- $revID = $rev ? $rev->getId() : 0;
- $cache->set( $page, $rev ); // maybe null
+ $rev = $parser->fetchCurrentRevisionOfTitle( $title );
+ $pageID = $rev ? $rev->getPage() : 0;
+ $revID = $rev ? $rev->getId() : 0;
- // Register dependency in templatelinks
- $parser->getOutput()->addTemplate( $title, $pageID, $revID );
+ // Register dependency in templatelinks
+ $parser->getOutput()->addTemplate( $title, $pageID, $revID );
- return $rev;
- }
- $cache->set( $page, null );
- return null;
+ return $rev;
}
/**
*/
public $mLangLinkLanguages;
+ /**
+ * @var MapCacheLRU|null
+ * @since 1.24
+ *
+ * A cache of the current revisions of titles. Keys are $title->getPrefixedDbKey()
+ */
+ public $currentRevisionCache;
+
/**
* @var bool Recursive call protection.
* This variable should be treated as if it were private.
$this->mVarCache = array();
$this->mUser = null;
$this->mLangLinkLanguages = array();
+ $this->currentRevisionCache = null;
/**
* Prefix for temporary replacement strings for the multipass parser.
$this->startParse( $title, $options, self::OT_HTML, $clearState );
+ $this->currentRevisionCache = null;
$this->mInputSize = strlen( $text );
if ( $this->mOptions->getEnableLimitReport() ) {
$this->mOutput->resetParseStartTime();
$this->mRevisionUser = $oldRevisionUser;
$this->mRevisionSize = $oldRevisionSize;
$this->mInputSize = false;
+ $this->currentRevisionCache = null;
wfProfileOut( $fname );
wfProfileOut( __METHOD__ );
return array( $dom, $title );
}
+ /**
+ * Fetch the current revision of a given title. Note that the revision
+ * (and even the title) may not exist in the database, so everything
+ * contributing to the output of the parser should use this method
+ * where possible, rather than getting the revisions themselves. This
+ * method also caches its results, so using it benefits performance.
+ *
+ * @since 1.24
+ * @param Title $title
+ * @return Revision
+ */
+ public function fetchCurrentRevisionOfTitle( $title ) {
+ $cacheKey = $title->getPrefixedDBkey();
+ if ( !$this->currentRevisionCache ) {
+ $this->currentRevisionCache = new MapCacheLRU( 100 );
+ }
+ if ( !$this->currentRevisionCache->has( $cacheKey ) ) {
+ $this->currentRevisionCache->set( $cacheKey,
+ // Defaults to Parser::statelessFetchRevision()
+ call_user_func( $this->mOptions->getCurrentRevisionCallback(), $title, $this )
+ );
+ }
+ return $this->currentRevisionCache->get( $cacheKey );
+ }
+
+ /**
+ * Wrapper around Revision::newFromTitle to allow passing additional parameters
+ * without passing them on to it.
+ *
+ * @since 1.24
+ * @param Title $title
+ * @param Parser|bool $parser
+ * @return Revision
+ */
+ public static function statelessFetchRevision( $title, $parser = false ) {
+ return Revision::newFromTitle( $title );
+ }
+
/**
* Fetch the unparsed text of a template and register a reference to it.
* @param Title $title
break;
}
# Get the revision
- $rev = $id
- ? Revision::newFromId( $id )
- : Revision::newFromTitle( $title, false, Revision::READ_NORMAL );
+ if ( $id ) {
+ $rev = Revision::newFromId( $id );
+ } elseif ( $parser ) {
+ $rev = $parser->fetchCurrentRevisionOfTitle( $title );
+ } else {
+ $rev = Revision::newFromTitle( $title );
+ }
$rev_id = $rev ? $rev->getId() : 0;
# If there is no current revision, there is no page
if ( $id === false && !$rev ) {
*/
public $mRemoveComments = true;
+ /**
+ * Callback for current revision fetching. Used as first argument to call_user_func().
+ */
+ public $mCurrentRevisionCallback =
+ array( 'Parser', 'statelessFetchRevision' );
+
/**
* Callback for template fetching. Used as first argument to call_user_func().
*/
return $this->mRemoveComments;
}
+ /* @since 1.24 */
+ public function getCurrentRevisionCallback() {
+ return $this->mCurrentRevisionCallback;
+ }
+
public function getTemplateCallback() {
return $this->mTemplateCallback;
}
return wfSetVar( $this->mRemoveComments, $x );
}
+ /* @since 1.24 */
+ public function setCurrentRevisionCallback( $x ) {
+ return wfSetVar( $this->mCurrentRevisionCallback, $x );
+ }
+
public function setTemplateCallback( $x ) {
return wfSetVar( $this->mTemplateCallback, $x );
}
/* Methods */
- /**
- * @param $context ResourceLoaderContext
- * @return array
- */
- public function getStyles( ResourceLoaderContext $context ) {
- global $wgLogo;
-
- $styles = parent::getStyles( $context );
- $styles['all'][] = '.mw-wiki-logo { background-image: ' .
- CSSMin::buildUrlValue( $wgLogo ) .
- '; }';
-
- return $styles;
- }
-
- /**
- * @param $context ResourceLoaderContext
- * @return boolean
- */
- public function isKnownEmpty( ResourceLoaderContext $context ) {
- // Regardless of whether the wiki page(s) exist, we always
- // provide mw-wiki-logo styles.
- return false;
- }
-
- /**
- * @param $context ResourceLoaderContext
- * @return int|mixed
- */
- public function getModifiedTime( ResourceLoaderContext $context ) {
- $parentMTime = parent::getModifiedTime( $context );
- return max( $parentMTime, $this->getHashMtime( $context ) );
- }
-
- /**
- * @param $context ResourceLoaderContext
- * @return string: Hash
- */
- public function getModifiedHash( ResourceLoaderContext $context ) {
- global $wgLogo;
- return md5( parent::getModifiedHash( $context ) . $wgLogo );
- }
-
/**
* Gets group name
*
jsonlint: {
all: [
'.jscsrc',
- '{languages,languages,maintenance,resources}/**/*.json',
+ '{languages,maintenance,resources}/**/*.json',
'tests/frontend/package.json'
]
},