27 use Wikimedia\Assert\Assert;
30 use Wikimedia\Timestamp\ConvertibleTimestamp;
57 protected $origin = self::ORIGIN_USER_SITEWIDE;
91 if ( $options ===
null ) {
95 foreach ( $options as $member => $option ) {
101 $this->{$member} = $option;
130 foreach ( $this->scripts as $script ) {
131 $pages[$script] = [
'type' =>
'script' ];
136 foreach ( $this->styles as $style ) {
137 $pages[$style] = [
'type' =>
'style' ];
188 $handler =
$content->getContentHandler();
197 return $content->serialize( $format );
212 $content = $overrideCallback ? call_user_func( $overrideCallback,
$title ) :
null;
216 'Bad content override for "{title}" in ' . __METHOD__,
217 [
'title' =>
$title->getPrefixedText() ]
222 $revision = MediaWikiServices::getInstance()
223 ->getRevisionLookup()
224 ->getKnownCurrentRevision(
$title );
228 $content = $revision->getContent( SlotRecord::MAIN, RevisionRecord::RAW );
232 'Failed to load content of JS/CSS page "{title}" in ' . __METHOD__,
233 [
'title' =>
$title->getPrefixedText() ]
240 if ( $maxRedirects ===
null ) {
241 $maxRedirects = $this->
getConfig()->get(
'MaxRedirects' ) ?: 0;
243 if ( $maxRedirects > 0 ) {
244 $newTitle =
$content->getRedirectTarget();
245 return $newTitle ? $this->
getContentObj( $newTitle, $context, $maxRedirects - 1 ) :
null;
258 if ( $overrideCallback && $this->
getSource() ===
'local' ) {
259 foreach ( $this->
getPages( $context ) as $page => $info ) {
261 if (
$title && call_user_func( $overrideCallback,
$title ) !==
null ) {
267 return parent::shouldEmbedModule( $context );
276 foreach ( $this->
getPages( $context ) as $titleText => $options ) {
277 if ( $options[
'type'] !==
'script' ) {
280 $script = $this->
getContent( $titleText, $context );
281 if ( strval( $script ) !==
'' ) {
295 foreach ( $this->
getPages( $context ) as $titleText => $options ) {
296 if ( $options[
'type'] !==
'style' ) {
299 $media = $options[
'media'] ??
'all';
300 $style = $this->
getContent( $titleText, $context );
301 if ( strval( $style ) ===
'' ) {
304 if ( $this->
getFlip( $context ) ) {
305 $style = CSSJanus::transform( $style,
true,
false );
308 [ $style,
false, $this->
getConfig()->
get(
'ScriptPath' ),
true ] );
309 if ( !isset(
$styles[$media] ) ) {
337 $summary = parent::getDefinitionSummary( $context );
339 'pages' => $this->
getPages( $context ),
358 if ( $this->
getGroup() ===
'user' ) {
359 foreach ( $revisions as $revision ) {
360 if ( $revision[
'page_len'] > 0 ) {
371 return count( $revisions ) === 0;
380 return "{$title->getNamespace()}:{$title->getDBkey()}";
391 $pageNames = array_keys( $this->
getPages( $context ) );
393 $batchKey = implode(
'|', $pageNames );
394 if ( !isset( $this->titleInfo[$batchKey] ) ) {
395 $this->titleInfo[$batchKey] = static::fetchTitleInfo(
$dbr, $pageNames, __METHOD__ );
402 if ( $overrideCallback ) {
403 foreach ( $pageNames as $page ) {
409 'page_latest' =>
'TBD',
410 'page_touched' => ConvertibleTimestamp::now( TS_MW ),
427 $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
428 $batch = $linkBatchFactory->newLinkBatch();
429 foreach ( $pages as $titleText ) {
436 if ( !$batch->isEmpty() ) {
439 [
'page_namespace',
'page_title',
'page_touched',
'page_len',
'page_latest' ],
440 $batch->constructSet(
'page', $db ),
443 foreach (
$res as $row ) {
448 'page_len' => $row->page_len,
449 'page_latest' => $row->page_latest,
450 'page_touched' => $row->page_touched,
472 foreach ( $moduleNames as
$name ) {
473 $module = $rl->getModule(
$name );
474 if ( $module instanceof
self ) {
475 $mDB = $module->getDB();
477 if ( $mDB->getDomainID() === $db->
getDomainID() ) {
478 $wikiModules[] = $module;
479 $allPages += $module->getPages( $context );
484 if ( !$wikiModules ) {
489 $pageNames = array_keys( $allPages );
491 $hash = sha1( implode(
'|', $pageNames ) );
494 $func = [ static::class,
'fetchTitleInfo' ];
497 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
498 $allInfo =
$cache->getWithSetCallback(
501 function ( $curVal, &$ttl, array &$setOpts ) use ( $func, $pageNames, $db, $fname ) {
502 $setOpts += Database::getCacheSetOptions( $db );
504 return call_user_func( $func, $db, $pageNames, $fname );
512 foreach ( $wikiModules as $wikiModule ) {
513 $pages = $wikiModule->getPages( $context );
516 foreach ( $pages as $pageName => $unused ) {
522 $rl->getLogger()->info(
523 'Invalid wiki page title "{title}" in ' . __METHOD__,
524 [
'title' => $pageName ]
528 $info = array_intersect_key( $allInfo, $intersect );
529 $pageNames = array_keys( $pages );
531 $batchKey = implode(
'|', $pageNames );
532 $wikiModule->setTitleInfo( $batchKey, $info );
554 Assert::parameterType(
'string', $domain,
'$domain' );
560 $oldModel = $old->
getSlot( SlotRecord::MAIN, RevisionRecord::RAW )->getModel();
561 if ( in_array( $oldModel, $models ) ) {
566 if ( !$purge && $new ) {
567 $newModel = $new->
getSlot( SlotRecord::MAIN, RevisionRecord::RAW )->getModel();
568 if ( in_array( $newModel, $models ) ) {
574 $purge = (
$title->isSiteConfigPage() ||
$title->isUserConfigPage() );
578 $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
579 $key =
$cache->makeGlobalKey(
'resourceloader-titleinfo', $domain );
580 $cache->touchCheckKey( $key );
592 return ( $this->styles && !$this->scripts ) ? self::LOAD_STYLES : self::LOAD_GENERAL;