MediaWiki  master
ResourceLoaderWikiModule.php
Go to the documentation of this file.
1 <?php
28 use Wikimedia\Minify\CSSMin;
31 use Wikimedia\Timestamp\ConvertibleTimestamp;
32 
58  protected $origin = self::ORIGIN_USER_SITEWIDE;
59 
76  protected $titleInfo = [];
77 
79  protected $styles = [];
80 
82  protected $scripts = [];
83 
85  protected $datas = [];
86 
88  protected $group;
89 
94  public function __construct( array $options = null ) {
95  if ( $options === null ) {
96  return;
97  }
98 
99  foreach ( $options as $member => $option ) {
100  switch ( $member ) {
101  case 'styles':
102  case 'scripts':
103  case 'datas':
104  case 'group':
105  case 'targets':
106  $this->{$member} = $option;
107  break;
108  }
109  }
110  }
111 
130  protected function getPages( ResourceLoaderContext $context ) {
131  $config = $this->getConfig();
132  $pages = [];
133 
134  // Filter out pages from origins not allowed by the current wiki configuration.
135  if ( $config->get( 'UseSiteJs' ) ) {
136  foreach ( $this->scripts as $script ) {
137  $pages[$script] = [ 'type' => 'script' ];
138  }
139  foreach ( $this->datas as $data ) {
140  $pages[$data] = [ 'type' => 'data' ];
141  }
142  }
143 
144  if ( $config->get( 'UseSiteCss' ) ) {
145  foreach ( $this->styles as $style ) {
146  $pages[$style] = [ 'type' => 'style' ];
147  }
148  }
149 
150  return $pages;
151  }
152 
158  public function getGroup() {
159  return $this->group;
160  }
161 
176  protected function getDB() {
177  return wfGetDB( DB_REPLICA );
178  }
179 
186  protected function getContent( $titleText, ResourceLoaderContext $context ) {
187  $pageStore = MediaWikiServices::getInstance()->getPageStore();
188  $title = $pageStore->getPageByText( $titleText );
189  if ( !$title ) {
190  return null; // Bad title
191  }
192 
193  $content = $this->getContentObj( $title, $context );
194  if ( !$content ) {
195  return null; // No content found
196  }
197 
198  $handler = $content->getContentHandler();
199  if ( $handler->isSupportedFormat( CONTENT_FORMAT_CSS ) ) {
200  $format = CONTENT_FORMAT_CSS;
201  } elseif ( $handler->isSupportedFormat( CONTENT_FORMAT_JAVASCRIPT ) ) {
202  $format = CONTENT_FORMAT_JAVASCRIPT;
203  } elseif ( $handler->isSupportedFormat( CONTENT_FORMAT_JSON ) ) {
204  $format = CONTENT_FORMAT_JSON;
205  } else {
206  return null; // Bad content model
207  }
208 
209  return $content->serialize( $format );
210  }
211 
220  protected function getContentObj(
221  PageIdentity $page, ResourceLoaderContext $context, $maxRedirects = null
222  ) {
223  $overrideCallback = $context->getContentOverrideCallback();
224  $content = $overrideCallback ? call_user_func( $overrideCallback, $page ) : null;
225  if ( $content ) {
226  if ( !$content instanceof Content ) {
227  $this->getLogger()->error(
228  'Bad content override for "{title}" in ' . __METHOD__,
229  [ 'title' => (string)$page ]
230  );
231  return null;
232  }
233  } else {
234  $revision = MediaWikiServices::getInstance()
235  ->getRevisionLookup()
236  ->getKnownCurrentRevision( $page );
237  if ( !$revision ) {
238  return null;
239  }
240  $content = $revision->getContent( SlotRecord::MAIN, RevisionRecord::RAW );
241 
242  if ( !$content ) {
243  $this->getLogger()->error(
244  'Failed to load content of CSS/JS/JSON page "{title}" in ' . __METHOD__,
245  [ 'title' => (string)$page ]
246  );
247  return null;
248  }
249  }
250 
251  if ( $content->isRedirect() ) {
252  if ( $maxRedirects === null ) {
253  $maxRedirects = $this->getConfig()->get( 'MaxRedirects' ) ?: 0;
254  }
255  if ( $maxRedirects > 0 ) {
256  $newTitle = $content->getRedirectTarget();
257  return $newTitle ? $this->getContentObj( $newTitle, $context, $maxRedirects - 1 ) : null;
258  }
259  }
260 
261  return $content;
262  }
263 
268  public function shouldEmbedModule( ResourceLoaderContext $context ) {
269  $overrideCallback = $context->getContentOverrideCallback();
270  if ( $overrideCallback && $this->getSource() === 'local' ) {
271  foreach ( $this->getPages( $context ) as $page => $info ) {
272  $title = Title::newFromText( $page );
273  if ( $title && call_user_func( $overrideCallback, $title ) !== null ) {
274  return true;
275  }
276  }
277  }
278 
279  return parent::shouldEmbedModule( $context );
280  }
281 
286  public function getScript( ResourceLoaderContext $context ) {
287  if ( $this->isPackaged() ) {
288  return $this->getPackageFiles( $context );
289  } else {
290  $scripts = '';
291  foreach ( $this->getPages( $context ) as $titleText => $options ) {
292  if ( $options['type'] !== 'script' ) {
293  continue;
294  }
295  $script = $this->getContent( $titleText, $context );
296  if ( strval( $script ) !== '' ) {
297  $script = $this->validateScriptFile( $titleText, $script );
298  $scripts .= ResourceLoader::makeComment( $titleText ) . $script . "\n";
299  }
300  }
301  return $scripts;
302  }
303  }
304 
319  protected function isPackaged(): bool {
320  // Packaged mode is disabled by default for backwards compatibility.
321  // Subclasses may opt-in to this feature.
322  return false;
323  }
324 
328  public function supportsURLLoading() {
329  // If package files are involved, don't support URL loading
330  return !$this->isPackaged();
331  }
332 
343  protected function getRequireKey( string $titleText ): string {
344  return $titleText;
345  }
346 
352  private function getPackageFiles( ResourceLoaderContext $context ): array {
353  $main = null;
354 
355  $files = [];
356  foreach ( $this->getPages( $context ) as $titleText => $options ) {
357  if ( $options['type'] !== 'script' && $options['type'] !== 'data' ) {
358  continue;
359  }
360  $content = $this->getContent( $titleText, $context );
361  if ( strval( $content ) !== '' ) {
362  $fileKey = $this->getRequireKey( $titleText );
363  if ( $options['type'] === 'script' ) {
364  $script = $this->validateScriptFile( $titleText, $content );
365  $files[$fileKey] = [
366  'type' => 'script',
367  'content' => $script,
368  ];
369  // First script becomes the "main" script
370  if ( $main === null ) {
371  $main = $fileKey;
372  }
373  } elseif ( $options['type'] === 'data' ) {
374  $data = FormatJson::decode( $content );
375  if ( $data == null ) {
376  // This is unlikely to happen since we only load JSON from
377  // wiki pages with a JSON content model, which are validated
378  // during edit save.
379  $data = [ 'error' => 'Invalid JSON' ];
380  }
381  $files[$fileKey] = [
382  'type' => 'data',
383  'content' => $data,
384  ];
385  }
386  }
387  }
388 
389  return [
390  'main' => $main,
391  'files' => $files,
392  ];
393  }
394 
399  public function getStyles( ResourceLoaderContext $context ) {
400  $styles = [];
401  foreach ( $this->getPages( $context ) as $titleText => $options ) {
402  if ( $options['type'] !== 'style' ) {
403  continue;
404  }
405  $media = $options['media'] ?? 'all';
406  $style = $this->getContent( $titleText, $context );
407  if ( strval( $style ) === '' ) {
408  continue;
409  }
410  if ( $this->getFlip( $context ) ) {
411  $style = CSSJanus::transform( $style, true, false );
412  }
413  $remoteDir = $this->getConfig()->get( 'ScriptPath' );
414  if ( $remoteDir === '' ) {
415  // When the site is configured with the script path at the
416  // document root, MediaWiki uses an empty string but that is
417  // not a valid URI path. Expand to a slash to avoid fatals
418  // later in CSSMin::resolveUrl().
419  // See also ResourceLoaderFilePath::extractBasePaths, T282280.
420  $remoteDir = '/';
421  }
422 
423  $style = MemoizedCallable::call(
424  [ CSSMin::class, 'remap' ],
425  [ $style, false, $remoteDir, true ]
426  );
427  if ( !isset( $styles[$media] ) ) {
428  $styles[$media] = [];
429  }
430  $style = ResourceLoader::makeComment( $titleText ) . $style;
431  $styles[$media][] = $style;
432  }
433  return $styles;
434  }
435 
446  public function enableModuleContentVersion() {
447  return false;
448  }
449 
454  public function getDefinitionSummary( ResourceLoaderContext $context ) {
455  $summary = parent::getDefinitionSummary( $context );
456  $summary[] = [
457  'pages' => $this->getPages( $context ),
458  // Includes meta data of current revisions
459  'titleInfo' => $this->getTitleInfo( $context ),
460  ];
461  return $summary;
462  }
463 
468  public function isKnownEmpty( ResourceLoaderContext $context ) {
469  $revisions = $this->getTitleInfo( $context );
470 
471  // If a module has dependencies it cannot be empty. An empty array will be cast to false
472  if ( $this->getDependencies() ) {
473  return false;
474  }
475  // For user modules, don't needlessly load if there are no non-empty pages
476  if ( $this->getGroup() === self::GROUP_USER ) {
477  foreach ( $revisions as $revision ) {
478  if ( $revision['page_len'] > 0 ) {
479  // At least one non-empty page, module should be loaded
480  return false;
481  }
482  }
483  return true;
484  }
485 
486  // T70488: For other modules (i.e. ones that are called in cached html output) only check
487  // page existence. This ensures that, if some pages in a module are temporarily blanked,
488  // we don't end omit the module's script or link tag on some pages.
489  return count( $revisions ) === 0;
490  }
491 
492  private function setTitleInfo( $batchKey, array $titleInfo ) {
493  $this->titleInfo[$batchKey] = $titleInfo;
494  }
495 
496  private static function makeTitleKey( LinkTarget $title ) {
497  // Used for keys in titleInfo.
498  return "{$title->getNamespace()}:{$title->getDBkey()}";
499  }
500 
506  protected function getTitleInfo( ResourceLoaderContext $context ) {
507  $dbr = $this->getDB();
508 
509  $pageNames = array_keys( $this->getPages( $context ) );
510  sort( $pageNames );
511  $batchKey = implode( '|', $pageNames );
512  if ( !isset( $this->titleInfo[$batchKey] ) ) {
513  $this->titleInfo[$batchKey] = static::fetchTitleInfo( $dbr, $pageNames, __METHOD__ );
514  }
515 
516  $titleInfo = $this->titleInfo[$batchKey];
517 
518  // Override the title info from the overrides, if any
519  $overrideCallback = $context->getContentOverrideCallback();
520  if ( $overrideCallback ) {
521  foreach ( $pageNames as $page ) {
522  $title = Title::newFromText( $page );
523  $content = $title ? call_user_func( $overrideCallback, $title ) : null;
524  if ( $content !== null ) {
525  $titleInfo[$title->getPrefixedText()] = [
526  'page_len' => $content->getSize(),
527  'page_latest' => 'TBD', // None available
528  'page_touched' => ConvertibleTimestamp::now( TS_MW ),
529  ];
530  }
531  }
532  }
533 
534  return $titleInfo;
535  }
536 
543  protected static function fetchTitleInfo( IDatabase $db, array $pages, $fname = __METHOD__ ) {
544  $titleInfo = [];
545  $linkBatchFactory = MediaWikiServices::getInstance()->getLinkBatchFactory();
546  $batch = $linkBatchFactory->newLinkBatch();
547  foreach ( $pages as $titleText ) {
548  $title = Title::newFromText( $titleText );
549  if ( $title ) {
550  // Page name may be invalid if user-provided (e.g. gadgets)
551  $batch->addObj( $title );
552  }
553  }
554  if ( !$batch->isEmpty() ) {
555  $res = $db->select( 'page',
556  // Include page_touched to allow purging if cache is poisoned (T117587, T113916)
557  [ 'page_namespace', 'page_title', 'page_touched', 'page_len', 'page_latest' ],
558  $batch->constructSet( 'page', $db ),
559  $fname
560  );
561  foreach ( $res as $row ) {
562  // Avoid including ids or timestamps of revision/page tables so
563  // that versions are not wasted
564  $title = new TitleValue( (int)$row->page_namespace, $row->page_title );
566  'page_len' => $row->page_len,
567  'page_latest' => $row->page_latest,
568  'page_touched' => $row->page_touched,
569  ];
570  }
571  }
572  return $titleInfo;
573  }
574 
581  public static function preloadTitleInfo(
582  ResourceLoaderContext $context, IDatabase $db, array $moduleNames
583  ) {
584  $rl = $context->getResourceLoader();
585  // getDB() can be overridden to point to a foreign database.
586  // For now, only preload local. In the future, we could preload by wikiID.
587  $allPages = [];
589  $wikiModules = [];
590  foreach ( $moduleNames as $name ) {
591  $module = $rl->getModule( $name );
592  if ( $module instanceof self ) {
593  $mDB = $module->getDB();
594  // Subclasses may implement getDB differently
595  if ( $mDB->getDomainID() === $db->getDomainID() ) {
596  $wikiModules[] = $module;
597  $allPages += $module->getPages( $context );
598  }
599  }
600  }
601 
602  if ( !$wikiModules ) {
603  // Nothing to preload
604  return;
605  }
606 
607  $pageNames = array_keys( $allPages );
608  sort( $pageNames );
609  $hash = sha1( implode( '|', $pageNames ) );
610 
611  // Avoid Zend bug where "static::" does not apply LSB in the closure
612  $func = [ static::class, 'fetchTitleInfo' ];
613  $fname = __METHOD__;
614 
615  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
616  $allInfo = $cache->getWithSetCallback(
617  $cache->makeGlobalKey( 'resourceloader-titleinfo', $db->getDomainID(), $hash ),
618  $cache::TTL_HOUR,
619  static function ( $curVal, &$ttl, array &$setOpts ) use ( $func, $pageNames, $db, $fname ) {
620  $setOpts += Database::getCacheSetOptions( $db );
621 
622  return call_user_func( $func, $db, $pageNames, $fname );
623  },
624  [
625  'checkKeys' => [
626  $cache->makeGlobalKey( 'resourceloader-titleinfo', $db->getDomainID() ) ]
627  ]
628  );
629 
630  foreach ( $wikiModules as $wikiModule ) {
631  $pages = $wikiModule->getPages( $context );
632  // Before we intersect, map the names to canonical form (T145673).
633  $intersect = [];
634  foreach ( $pages as $pageName => $unused ) {
635  $title = Title::newFromText( $pageName );
636  if ( $title ) {
637  $intersect[ self::makeTitleKey( $title ) ] = 1;
638  } else {
639  // Page name may be invalid if user-provided (e.g. gadgets)
640  $rl->getLogger()->info(
641  'Invalid wiki page title "{title}" in ' . __METHOD__,
642  [ 'title' => $pageName ]
643  );
644  }
645  }
646  $info = array_intersect_key( $allInfo, $intersect );
647  $pageNames = array_keys( $pages );
648  sort( $pageNames );
649  $batchKey = implode( '|', $pageNames );
650  $wikiModule->setTitleInfo( $batchKey, $info );
651  }
652  }
653 
664  public static function invalidateModuleCache(
665  PageIdentity $page,
666  ?RevisionRecord $old,
667  ?RevisionRecord $new,
668  string $domain
669  ) {
670  static $models = [ CONTENT_MODEL_CSS, CONTENT_MODEL_JAVASCRIPT ];
671 
672  $purge = false;
673  // TODO: MCR: differentiate between page functionality and content model!
674  // Not all pages containing CSS or JS have to be modules! [PageType]
675  if ( $old ) {
676  $oldModel = $old->getSlot( SlotRecord::MAIN, RevisionRecord::RAW )->getModel();
677  if ( in_array( $oldModel, $models ) ) {
678  $purge = true;
679  }
680  }
681 
682  if ( !$purge && $new ) {
683  $newModel = $new->getSlot( SlotRecord::MAIN, RevisionRecord::RAW )->getModel();
684  if ( in_array( $newModel, $models ) ) {
685  $purge = true;
686  }
687  }
688 
689  if ( !$purge ) {
691  $purge = ( $title->isSiteConfigPage() || $title->isUserConfigPage() );
692  }
693 
694  if ( $purge ) {
695  $cache = MediaWikiServices::getInstance()->getMainWANObjectCache();
696  $key = $cache->makeGlobalKey( 'resourceloader-titleinfo', $domain );
697  $cache->touchCheckKey( $key );
698  }
699  }
700 
705  public function getType() {
706  // Check both because subclasses don't always pass pages via the constructor,
707  // they may also override getPages() instead, in which case we should keep
708  // defaulting to LOAD_GENERAL and allow them to override getType() separately.
709  return ( $this->styles && !$this->scripts ) ? self::LOAD_STYLES : self::LOAD_GENERAL;
710  }
711 }
Page\PageIdentity
Interface for objects (potentially) representing an editable wiki page.
Definition: PageIdentity.php:64
ResourceLoaderContext
Context object that contains information about the state of a specific ResourceLoader web request.
Definition: ResourceLoaderContext.php:37
Wikimedia\Rdbms\Database
Relational database abstraction object.
Definition: Database.php:52
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:377
ResourceLoaderWikiModule\isPackaged
isPackaged()
Get whether this module is a packaged module.
Definition: ResourceLoaderWikiModule.php:319
MediaWiki\Revision\RevisionRecord
Page revision base class.
Definition: RevisionRecord.php:47
ResourceLoaderModule\getFlip
getFlip(ResourceLoaderContext $context)
Definition: ResourceLoaderModule.php:178
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:203
ResourceLoaderWikiModule\getRequireKey
getRequireKey(string $titleText)
Convert a namespace-formatted page title to a virtual package file name.
Definition: ResourceLoaderWikiModule.php:343
ResourceLoaderContext\getResourceLoader
getResourceLoader()
Definition: ResourceLoaderContext.php:171
ResourceLoaderWikiModule\getDB
getDB()
Get the Database handle used for computing the module version.
Definition: ResourceLoaderWikiModule.php:176
ResourceLoaderWikiModule\getStyles
getStyles(ResourceLoaderContext $context)
Definition: ResourceLoaderWikiModule.php:399
ResourceLoaderWikiModule
Abstraction for ResourceLoader modules which pull from wiki pages.
Definition: ResourceLoaderWikiModule.php:56
ResourceLoaderContext\getContentOverrideCallback
getContentOverrideCallback()
Return the replaced-content mapping callback.
Definition: ResourceLoaderContext.php:406
ResourceLoaderWikiModule\getGroup
getGroup()
Get group name.
Definition: ResourceLoaderWikiModule.php:158
ResourceLoaderWikiModule\getScript
getScript(ResourceLoaderContext $context)
Definition: ResourceLoaderWikiModule.php:286
ResourceLoaderWikiModule\setTitleInfo
setTitleInfo( $batchKey, array $titleInfo)
Definition: ResourceLoaderWikiModule.php:492
CONTENT_FORMAT_CSS
const CONTENT_FORMAT_CSS
For CSS pages.
Definition: Defines.php:228
$res
$res
Definition: testCompression.php:57
ResourceLoaderWikiModule\isKnownEmpty
isKnownEmpty(ResourceLoaderContext $context)
Definition: ResourceLoaderWikiModule.php:468
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
ResourceLoaderWikiModule\$origin
string $origin
Origin defaults to users with sitewide authority.
Definition: ResourceLoaderWikiModule.php:58
Title\castFromPageIdentity
static castFromPageIdentity(?PageIdentity $pageIdentity)
Return a Title for a given PageIdentity.
Definition: Title.php:326
$dbr
$dbr
Definition: testCompression.php:54
MemoizedCallable\call
static call( $callable, array $args=[], $ttl=3600)
Shortcut method for creating a MemoizedCallable and invoking it with the specified arguments.
Definition: MemoizedCallable.php:151
ResourceLoaderWikiModule\getPackageFiles
getPackageFiles(ResourceLoaderContext $context)
Definition: ResourceLoaderWikiModule.php:352
FormatJson\decode
static decode( $value, $assoc=false)
Decodes a JSON string.
Definition: FormatJson.php:146
ResourceLoaderWikiModule\invalidateModuleCache
static invalidateModuleCache(PageIdentity $page, ?RevisionRecord $old, ?RevisionRecord $new, string $domain)
Clear the preloadTitleInfo() cache for all wiki modules on this wiki on page change if it was a JS or...
Definition: ResourceLoaderWikiModule.php:664
ResourceLoaderWikiModule\getType
getType()
Definition: ResourceLoaderWikiModule.php:705
ResourceLoaderModule\getLogger
getLogger()
Definition: ResourceLoaderModule.php:271
ResourceLoaderWikiModule\preloadTitleInfo
static preloadTitleInfo(ResourceLoaderContext $context, IDatabase $db, array $moduleNames)
Definition: ResourceLoaderWikiModule.php:581
Config\get
get( $name)
Get a configuration variable such as "Sitename" or "UploadMaintenance.".
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2186
ResourceLoaderWikiModule\enableModuleContentVersion
enableModuleContentVersion()
Disable module content versioning.
Definition: ResourceLoaderWikiModule.php:446
ResourceLoaderWikiModule\$titleInfo
array $titleInfo
In-process cache for title info, structured as an array [ <batchKey> // Pipe-separated list of sorted...
Definition: ResourceLoaderWikiModule.php:76
ResourceLoaderWikiModule\$styles
array $styles
List of page names that contain CSS.
Definition: ResourceLoaderWikiModule.php:79
$title
$title
Definition: testCompression.php:38
ResourceLoader\makeComment
static makeComment( $text)
Generate a CSS or JS comment block.
Definition: ResourceLoader.php:1054
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
ResourceLoaderWikiModule\$scripts
array $scripts
List of page names that contain JavaScript.
Definition: ResourceLoaderWikiModule.php:82
ResourceLoaderWikiModule\fetchTitleInfo
static fetchTitleInfo(IDatabase $db, array $pages, $fname=__METHOD__)
Definition: ResourceLoaderWikiModule.php:543
$content
$content
Definition: router.php:76
ResourceLoaderModule\$name
string null $name
Module name.
Definition: ResourceLoaderModule.php:55
ResourceLoaderModule\getDependencies
getDependencies(ResourceLoaderContext $context=null)
Get a list of modules this module depends on.
Definition: ResourceLoaderModule.php:446
Wikimedia\Rdbms\IDatabase\getDomainID
getDomainID()
Return the currently selected domain ID.
CONTENT_FORMAT_JSON
const CONTENT_FORMAT_JSON
For future use with the API, and for use by extensions.
Definition: Defines.php:236
ResourceLoaderWikiModule\__construct
__construct(array $options=null)
Definition: ResourceLoaderWikiModule.php:94
ResourceLoaderModule\validateScriptFile
validateScriptFile( $fileName, $contents)
Validate a user-provided JavaScript blob.
Definition: ResourceLoaderModule.php:1021
ResourceLoaderWikiModule\supportsURLLoading
supportsURLLoading()
Definition: ResourceLoaderWikiModule.php:328
Content
Base interface for content objects.
Definition: Content.php:35
ResourceLoaderModule
Abstraction for ResourceLoader modules, with name registration and maxage functionality.
Definition: ResourceLoaderModule.php:39
ResourceLoaderModule\$config
Config $config
Definition: ResourceLoaderModule.php:41
ResourceLoaderWikiModule\getContentObj
getContentObj(PageIdentity $page, ResourceLoaderContext $context, $maxRedirects=null)
Definition: ResourceLoaderWikiModule.php:220
$cache
$cache
Definition: mcc.php:33
ResourceLoaderWikiModule\shouldEmbedModule
shouldEmbedModule(ResourceLoaderContext $context)
Definition: ResourceLoaderWikiModule.php:268
CONTENT_MODEL_JAVASCRIPT
const CONTENT_MODEL_JAVASCRIPT
Definition: Defines.php:209
ResourceLoaderWikiModule\getContent
getContent( $titleText, ResourceLoaderContext $context)
Definition: ResourceLoaderWikiModule.php:186
ResourceLoaderWikiModule\getDefinitionSummary
getDefinitionSummary(ResourceLoaderContext $context)
Definition: ResourceLoaderWikiModule.php:454
ResourceLoaderWikiModule\makeTitleKey
static makeTitleKey(LinkTarget $title)
Definition: ResourceLoaderWikiModule.php:496
Wikimedia\Rdbms\IDatabase\select
select( $table, $vars, $conds='', $fname=__METHOD__, $options=[], $join_conds=[])
Execute a SELECT query constructed using the various parameters provided.
ResourceLoaderModule\getSource
getSource()
Get the source of this module.
Definition: ResourceLoaderModule.php:428
ResourceLoaderWikiModule\getPages
getPages(ResourceLoaderContext $context)
Subclasses should return an associative array of resources in the module.
Definition: ResourceLoaderWikiModule.php:130
ResourceLoaderWikiModule\$group
string null $group
Group of module.
Definition: ResourceLoaderWikiModule.php:88
ResourceLoaderWikiModule\$datas
array $datas
List of page names that contain JSON.
Definition: ResourceLoaderWikiModule.php:85
MediaWiki\Linker\LinkTarget
Definition: LinkTarget.php:26
CONTENT_MODEL_CSS
const CONTENT_MODEL_CSS
Definition: Defines.php:210
CONTENT_FORMAT_JAVASCRIPT
const CONTENT_FORMAT_JAVASCRIPT
For JS pages.
Definition: Defines.php:226
ResourceLoaderModule\getConfig
getConfig()
Definition: ResourceLoaderModule.php:243
ResourceLoaderWikiModule\getTitleInfo
getTitleInfo(ResourceLoaderContext $context)
Get the information about the wiki pages for a given context.
Definition: ResourceLoaderWikiModule.php:506
MediaWiki\Revision\RevisionRecord\getSlot
getSlot( $role, $audience=self::FOR_PUBLIC, Authority $performer=null)
Returns meta-data for the given slot.
Definition: RevisionRecord.php:180
MediaWiki\Revision\SlotRecord
Value object representing a content slot associated with a page revision.
Definition: SlotRecord.php:40
TitleValue
Represents a page (or page fragment) title within MediaWiki.
Definition: TitleValue.php:40