$links = '';
foreach ( $groups as $group => $modules ) {
- $query['modules'] = implode( '|', array_keys( $modules ) );
// Special handling for user-specific groups
if ( ( $group === 'user' || $group === 'private' ) && $wgUser->isLoggedIn() ) {
$query['user'] = $wgUser->getName();
}
+
+ // Create a fake request based on the one we are about to make so modules return
+ // correct timestamp and emptiness data
+ $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) );
+ // Drop modules that know they're empty
+ foreach ( $modules as $key => $module ) {
+ if ( $module->isKnownEmpty( $context ) ) {
+ unset( $modules[$key] );
+ }
+ }
+ // If there are no modules left, skip this group
+ if ( $modules === array() ) {
+ continue;
+ }
+
+ $query['modules'] = implode( '|', array_keys( $modules ) );
+
// Support inlining of private modules if configured as such
if ( $group === 'private' && $wgResourceLoaderInlinePrivateModules ) {
- $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) );
if ( $only == ResourceLoaderModule::TYPE_STYLES ) {
$links .= Html::inlineStyle(
$resourceLoader->makeModuleResponse( $context, $modules )
// on-wiki like site or user pages, or user preferences; we need to find the highest
// timestamp of these user-changable modules so we can ensure cache misses on change
if ( $group === 'user' || $group === 'site' ) {
- // Create a fake request based on the one we are about to make so modules return
- // correct times
- $context = new ResourceLoaderContext( $resourceLoader, new FauxRequest( $query ) );
// Get the maximum timestamp
$timestamp = 1;
foreach ( $modules as $module ) {
# Origin is user-supplied code
protected $origin = self::ORIGIN_USER_SITEWIDE;
- // In-object cache for modified time
- protected $modifiedTime = array();
+ // In-object cache for title mtimes
+ protected $titleMtimes = array();
/* Abstract Protected Methods */
}
public function getModifiedTime( ResourceLoaderContext $context ) {
- $hash = $context->getHash();
- if ( isset( $this->modifiedTime[$hash] ) ) {
- return $this->modifiedTime[$hash];
- }
-
- $batch = new LinkBatch;
- foreach ( $this->getPages( $context ) as $titleText => $options ) {
- $batch->addObj( Title::newFromText( $titleText ) );
- }
-
$modifiedTime = 1; // wfTimestamp() interprets 0 as "now"
- if ( !$batch->isEmpty() ) {
- $dbr = wfGetDB( DB_SLAVE );
- $latest = $dbr->selectField( 'page', 'MAX(page_touched)',
- $batch->constructSet( 'page', $dbr ),
- __METHOD__ );
-
- if ( $latest ) {
- $modifiedTime = wfTimestamp( TS_UNIX, $latest );
- }
+ $mtimes = $this->getTitleMtimes( $context );
+ if ( count( $mtimes ) ) {
+ $modifiedTime = max( $modifiedTime, max( $mtimes ) );
}
-
- $this->modifiedTime[$hash] = $modifiedTime;
return $modifiedTime;
}
-
+
+ public function isKnownEmpty( ResourceLoaderContext $context ) {
+ return count( $this->getTitleMtimes( $context ) ) == 0;
+ }
+
/**
* @param $context ResourceLoaderContext
* @return bool
return $wgContLang->getDir() !== $context->getDirection();
}
+
+ /**
+ * Get the modification times of all titles that would be loaded for
+ * a given context.
+ * @param $context ResourceLoaderContext: Context object
+ * @return array( prefixed DB key => UNIX timestamp ), nonexistent titles are dropped
+ */
+ protected function getTitleMtimes( ResourceLoaderContext $context ) {
+ $hash = $context->getHash();
+ if ( isset( $this->titleMtimes[$hash] ) ) {
+ return $this->titleMtimes[$hash];
+ }
+
+ $this->titleMtimes[$hash] = array();
+ $batch = new LinkBatch;
+ foreach ( $this->getPages( $context ) as $titleText => $options ) {
+ $batch->addObj( Title::newFromText( $titleText ) );
+ }
+
+ if ( !$batch->isEmpty() ) {
+ $dbr = wfGetDB( DB_SLAVE );
+ $res = $dbr->select( 'page',
+ array( 'page_namespace', 'page_title', 'page_touched' ),
+ $batch->constructSet( 'page', $dbr ),
+ __METHOD__
+ );
+ foreach ( $res as $row ) {
+ $title = Title::makeTitle( $row->page_namespace, $row->page_title );
+ $this->titleMtimes[$hash][$title->getPrefixedDBkey()] =
+ wfTimestamp( TS_UNIX, $row->page_touched );
+ }
+ }
+ return $this->titleMtimes[$hash];
+ }
}