MediaWiki  master
ResourceLoaderContext.php
Go to the documentation of this file.
1 <?php
26 
35  public const DEFAULT_LANG = 'qqx';
36  public const DEFAULT_SKIN = 'fallback';
37 
39  public const DEBUG_OFF = 0;
41  public const DEBUG_LEGACY = 1;
42  private const DEBUG_MAIN = 2;
43 
44  protected $resourceLoader;
45  protected $request;
46  protected $logger;
47 
48  // Module content vary
49  protected $skin;
50  protected $language;
52  protected $debug;
53  protected $user;
54 
55  // Request vary (in addition to cache vary)
56  protected $modules;
57  protected $only;
58  protected $version;
59  protected $raw;
60  protected $image;
61  protected $variant;
62  protected $format;
63 
64  protected $direction;
65  protected $hash;
66  protected $userObj;
68  protected $imageObj;
69 
75  $this->resourceLoader = $resourceLoader;
76  $this->request = $request;
77  $this->logger = $resourceLoader->getLogger();
78 
79  // Optimisation: Use WebRequest::getRawVal() instead of getVal(). We don't
80  // need the slow Language+UTF logic meant for user input here. (f303bb9360)
81 
82  // List of modules
83  $modules = $request->getRawVal( 'modules' );
84  $this->modules = $modules ? ResourceLoader::expandModuleNames( $modules ) : [];
85 
86  // Various parameters
87  $this->user = $request->getRawVal( 'user' );
88  $this->debug = self::debugFromString( $request->getRawVal( 'debug' ) );
89  $this->only = $request->getRawVal( 'only' );
90  $this->version = $request->getRawVal( 'version' );
91  $this->raw = $request->getFuzzyBool( 'raw' );
92 
93  // Image requests
94  $this->image = $request->getRawVal( 'image' );
95  $this->variant = $request->getRawVal( 'variant' );
96  $this->format = $request->getRawVal( 'format' );
97 
98  $this->skin = $request->getRawVal( 'skin' );
99  $skinFactory = MediaWikiServices::getInstance()->getSkinFactory();
100  $skinnames = $skinFactory->getInstalledSkins();
101 
102  if ( !$this->skin || !isset( $skinnames[$this->skin] ) ) {
103  // The 'skin' parameter is required. (Not yet enforced.)
104  // For requests without a known skin specified,
105  // use MediaWiki's 'fallback' skin for skin-specific decisions.
106  $this->skin = self::DEFAULT_SKIN;
107  }
108  }
109 
115  public static function debugFromString( ?string $debug ): int {
116  // The canonical way to enable debug mode is via debug=true
117  // This continues to map to v1 until v2 is ready (T85805).
118  if ( $debug === 'true' || $debug === '1' ) {
119  $ret = self::DEBUG_LEGACY;
120  } elseif ( $debug === '2' ) {
121  $ret = self::DEBUG_MAIN;
122  } else {
123  $ret = self::DEBUG_OFF;
124  }
125 
126  return $ret;
127  }
128 
138  public static function newDummyContext(): ResourceLoaderContext {
139  // This currently creates a non-empty instance of ResourceLoader (all modules registered),
140  // but that's probably not needed. So once that moves into ServiceWiring, this'll
141  // become more like the EmptyResourceLoader class we have in PHPUnit tests, which
142  // is what this should've had originally. If this turns out to be untrue, change to:
143  // `MediaWikiServices::getInstance()->getResourceLoader()` instead.
144  return new self( new ResourceLoader(
145  MediaWikiServices::getInstance()->getMainConfig(),
146  LoggerFactory::getInstance( 'resourceloader' )
147  ), new FauxRequest( [] ) );
148  }
149 
150  public function getResourceLoader(): ResourceLoader {
151  return $this->resourceLoader;
152  }
153 
160  public function getConfig() {
161  wfDeprecated( __METHOD__, '1.34' );
162  return $this->getResourceLoader()->getConfig();
163  }
164 
165  public function getRequest(): WebRequest {
166  return $this->request;
167  }
168 
175  public function getLogger() {
176  return $this->logger;
177  }
178 
179  public function getModules(): array {
180  return $this->modules;
181  }
182 
183  public function getLanguage(): string {
184  if ( $this->language === null ) {
185  // Must be a valid language code after this point (T64849)
186  // Only support uselang values that follow built-in conventions (T102058)
187  $lang = $this->getRequest()->getRawVal( 'lang', '' );
188  // Stricter version of RequestContext::sanitizeLangCode()
189  $validBuiltinCode = MediaWikiServices::getInstance()->getLanguageNameUtils()
190  ->isValidBuiltInCode( $lang );
191  if ( !$validBuiltinCode ) {
192  // The 'lang' parameter is required. (Not yet enforced.)
193  // If omitted, localise with the dummy language code.
195  }
196  $this->language = $lang;
197  }
198  return $this->language;
199  }
200 
201  public function getDirection(): string {
202  if ( $this->direction === null ) {
203  $direction = $this->getRequest()->getRawVal( 'dir' );
204  if ( $direction === 'ltr' || $direction === 'rtl' ) {
205  $this->direction = $direction;
206  } else {
207  // Determine directionality based on user language (T8100)
208  $this->direction = MediaWikiServices::getInstance()->getLanguageFactory()
209  ->getLanguage( $this->getLanguage() )->getDir();
210  }
211  }
212  return $this->direction;
213  }
214 
215  public function getSkin(): string {
216  return $this->skin;
217  }
218 
222  public function getUser(): ?string {
223  return $this->user;
224  }
225 
235  public function msg( $key, ...$params ): Message {
236  return wfMessage( $key, ...$params )
237  ->inLanguage( $this->getLanguage() )
238  // Use a dummy title because there is no real title
239  // for this endpoint, and the cache won't vary on it
240  // anyways.
241  ->page( PageReferenceValue::localReference( NS_MAIN, 'Dwimmerlaik' ) );
242  }
243 
250  public function getUserObj(): User {
251  if ( $this->userObj === null ) {
252  $username = $this->getUser();
253  if ( $username ) {
254  // Use provided username if valid, fallback to anonymous user
255  $this->userObj = User::newFromName( $username ) ?: new User;
256  } else {
257  // Anonymous user
258  $this->userObj = new User;
259  }
260  }
261 
262  return $this->userObj;
263  }
264 
265  public function getDebug(): int {
266  return $this->debug;
267  }
268 
272  public function getOnly(): ?string {
273  return $this->only;
274  }
275 
281  public function getVersion(): ?string {
282  return $this->version;
283  }
284 
285  public function getRaw(): bool {
286  return $this->raw;
287  }
288 
292  public function getImage(): ?string {
293  return $this->image;
294  }
295 
299  public function getVariant(): ?string {
300  return $this->variant;
301  }
302 
306  public function getFormat(): ?string {
307  return $this->format;
308  }
309 
316  public function getImageObj() {
317  if ( $this->imageObj === null ) {
318  $this->imageObj = false;
319 
320  if ( !$this->image ) {
321  return $this->imageObj;
322  }
323 
324  $modules = $this->getModules();
325  if ( count( $modules ) !== 1 ) {
326  return $this->imageObj;
327  }
328 
329  $module = $this->getResourceLoader()->getModule( $modules[0] );
330  if ( !$module || !$module instanceof ResourceLoaderImageModule ) {
331  return $this->imageObj;
332  }
333 
334  $image = $module->getImage( $this->image, $this );
335  if ( !$image ) {
336  return $this->imageObj;
337  }
338 
339  $this->imageObj = $image;
340  }
341 
342  return $this->imageObj;
343  }
344 
357  public function getContentOverrideCallback() {
358  return null;
359  }
360 
361  public function shouldIncludeScripts(): bool {
362  return $this->getOnly() === null || $this->getOnly() === 'scripts';
363  }
364 
365  public function shouldIncludeStyles(): bool {
366  return $this->getOnly() === null || $this->getOnly() === 'styles';
367  }
368 
369  public function shouldIncludeMessages(): bool {
370  return $this->getOnly() === null;
371  }
372 
384  public function getHash(): string {
385  if ( !isset( $this->hash ) ) {
386  $this->hash = implode( '|', [
387  // Module content vary
388  $this->getLanguage(),
389  $this->getSkin(),
390  $this->getDebug(),
391  $this->getUser(),
392  // Request vary
393  $this->getOnly(),
394  $this->getVersion(),
395  $this->getRaw(),
396  $this->getImage(),
397  $this->getVariant(),
398  $this->getFormat(),
399  ] );
400  }
401  return $this->hash;
402  }
403 
410  public function getReqBase(): array {
411  $reqBase = [];
412  if ( $this->getLanguage() !== self::DEFAULT_LANG ) {
413  $reqBase['lang'] = $this->getLanguage();
414  }
415  if ( $this->getSkin() !== self::DEFAULT_SKIN ) {
416  $reqBase['skin'] = $this->getSkin();
417  }
418  if ( $this->getDebug() !== self::DEBUG_OFF ) {
419  $reqBase['debug'] = strval( $this->getDebug() );
420  }
421  return $reqBase;
422  }
423 
432  public function encodeJson( $data ) {
433  // Keep output as small as possible by disabling needless escape modes
434  // that PHP uses by default.
435  // However, while most module scripts are only served on HTTP responses
436  // for JavaScript, some modules can also be embedded in the HTML as inline
437  // scripts. This, and the fact that we sometimes need to export strings
438  // containing user-generated content and labels that may genuinely contain
439  // a sequences like "</script>", we need to encode either '/' or '<'.
440  // By default PHP escapes '/'. Let's escape '<' instead which is less common
441  // and allows URLs to mostly remain readable.
442  $jsonFlags = JSON_UNESCAPED_SLASHES |
443  JSON_UNESCAPED_UNICODE |
444  JSON_HEX_TAG |
445  JSON_HEX_AMP;
446  if ( $this->getDebug() ) {
447  $jsonFlags |= JSON_PRETTY_PRINT;
448  }
449  return json_encode( $data, $jsonFlags );
450  }
451 }
ResourceLoaderContext\$hash
$hash
Definition: ResourceLoaderContext.php:65
ResourceLoaderContext
Context object that contains information about the state of a specific ResourceLoader web request.
Definition: ResourceLoaderContext.php:34
ResourceLoaderContext\getReqBase
getReqBase()
Get the request base parameters, omitting any defaults.
Definition: ResourceLoaderContext.php:410
ResourceLoaderContext\getConfig
getConfig()
Definition: ResourceLoaderContext.php:160
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:35
ResourceLoaderContext\$logger
$logger
Definition: ResourceLoaderContext.php:46
ResourceLoaderContext\getDirection
getDirection()
Definition: ResourceLoaderContext.php:201
ResourceLoaderContext\newDummyContext
static newDummyContext()
Return a dummy ResourceLoaderContext object suitable for passing into things that don't "really" need...
Definition: ResourceLoaderContext.php:138
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:193
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
ResourceLoaderContext\getResourceLoader
getResourceLoader()
Definition: ResourceLoaderContext.php:150
ResourceLoaderContext\$version
$version
Definition: ResourceLoaderContext.php:58
ResourceLoaderContext\$skin
$skin
Definition: ResourceLoaderContext.php:49
ResourceLoaderContext\$direction
$direction
Definition: ResourceLoaderContext.php:64
ResourceLoaderContext\getImage
getImage()
Definition: ResourceLoaderContext.php:292
ResourceLoaderContext\getModules
getModules()
Definition: ResourceLoaderContext.php:179
ResourceLoaderContext\getContentOverrideCallback
getContentOverrideCallback()
Return the replaced-content mapping callback.
Definition: ResourceLoaderContext.php:357
ResourceLoaderContext\$user
$user
Definition: ResourceLoaderContext.php:53
ResourceLoaderContext\$image
$image
Definition: ResourceLoaderContext.php:60
User\newFromName
static newFromName( $name, $validate='valid')
Definition: User.php:606
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1186
ResourceLoaderContext\getOnly
getOnly()
Definition: ResourceLoaderContext.php:272
ResourceLoaderContext\DEBUG_LEGACY
const DEBUG_LEGACY
Definition: ResourceLoaderContext.php:41
ResourceLoaderContext\getVariant
getVariant()
Definition: ResourceLoaderContext.php:299
ResourceLoaderContext\getFormat
getFormat()
Definition: ResourceLoaderContext.php:306
MessageLocalizer
Interface for localizing messages in MediaWiki.
Definition: MessageLocalizer.php:29
NS_MAIN
const NS_MAIN
Definition: Defines.php:64
ResourceLoaderContext\$modules
$modules
Definition: ResourceLoaderContext.php:56
ResourceLoaderContext\DEBUG_OFF
const DEBUG_OFF
Definition: ResourceLoaderContext.php:39
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that a deprecated feature was used.
Definition: GlobalFunctions.php:997
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
ResourceLoaderContext\getRequest
getRequest()
Definition: ResourceLoaderContext.php:165
ResourceLoaderContext\$language
$language
Definition: ResourceLoaderContext.php:50
ResourceLoaderContext\getDebug
getDebug()
Definition: ResourceLoaderContext.php:265
ResourceLoaderContext\$raw
$raw
Definition: ResourceLoaderContext.php:59
ResourceLoaderContext\getLanguage
getLanguage()
Definition: ResourceLoaderContext.php:183
ResourceLoaderContext\getVersion
getVersion()
Definition: ResourceLoaderContext.php:281
ResourceLoaderContext\shouldIncludeStyles
shouldIncludeStyles()
Definition: ResourceLoaderContext.php:365
ResourceLoaderContext\$userObj
$userObj
Definition: ResourceLoaderContext.php:66
ResourceLoaderContext\msg
msg( $key,... $params)
Get a Message object with context set.
Definition: ResourceLoaderContext.php:235
ResourceLoaderImage
Class encapsulating an image used in a ResourceLoaderImageModule.
Definition: ResourceLoaderImage.php:32
ResourceLoaderContext\$debug
int $debug
Definition: ResourceLoaderContext.php:52
ResourceLoaderContext\$resourceLoader
$resourceLoader
Definition: ResourceLoaderContext.php:44
ResourceLoaderContext\DEFAULT_SKIN
const DEFAULT_SKIN
Definition: ResourceLoaderContext.php:36
ResourceLoaderContext\__construct
__construct(ResourceLoader $resourceLoader, WebRequest $request)
Definition: ResourceLoaderContext.php:74
ResourceLoaderContext\DEFAULT_LANG
const DEFAULT_LANG
Definition: ResourceLoaderContext.php:35
ResourceLoaderContext\shouldIncludeMessages
shouldIncludeMessages()
Definition: ResourceLoaderContext.php:369
ResourceLoader\expandModuleNames
static expandModuleNames( $modules)
Expand a string of the form jquery.foo,bar|jquery.ui.baz,quux to an array of module names like ‘[ 'jq...
Definition: ResourceLoader.php:1671
ResourceLoaderContext\getSkin
getSkin()
Definition: ResourceLoaderContext.php:215
ResourceLoaderContext\shouldIncludeScripts
shouldIncludeScripts()
Definition: ResourceLoaderContext.php:361
ResourceLoaderContext\getUser
getUser()
Definition: ResourceLoaderContext.php:222
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:43
ResourceLoaderContext\$imageObj
ResourceLoaderImage false $imageObj
Definition: ResourceLoaderContext.php:68
ResourceLoaderContext\$request
$request
Definition: ResourceLoaderContext.php:45
ResourceLoaderContext\getLogger
getLogger()
Definition: ResourceLoaderContext.php:175
ResourceLoader
ResourceLoader is a loading system for JavaScript and CSS resources.
Definition: ResourceLoader.php:58
Page\PageReferenceValue
Immutable value object representing a page reference.
Definition: PageReferenceValue.php:42
Message
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition: Message.php:138
ResourceLoaderContext\$only
$only
Definition: ResourceLoaderContext.php:57
ResourceLoaderContext\$format
$format
Definition: ResourceLoaderContext.php:62
ResourceLoaderContext\$variant
$variant
Definition: ResourceLoaderContext.php:61
ResourceLoaderContext\debugFromString
static debugFromString(?string $debug)
Definition: ResourceLoaderContext.php:115
ResourceLoaderContext\getHash
getHash()
All factors that uniquely identify this request, except 'modules'.
Definition: ResourceLoaderContext.php:384
ResourceLoaderContext\getImageObj
getImageObj()
If this is a request for an image, get the ResourceLoaderImage object.
Definition: ResourceLoaderContext.php:316
ResourceLoaderContext\getUserObj
getUserObj()
Get the possibly-cached User object for the specified username.
Definition: ResourceLoaderContext.php:250
ResourceLoaderContext\DEBUG_MAIN
const DEBUG_MAIN
Definition: ResourceLoaderContext.php:42
ResourceLoaderImageModule
Module for generated and embedded images.
Definition: ResourceLoaderImageModule.php:29
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:68
ResourceLoaderContext\getRaw
getRaw()
Definition: ResourceLoaderContext.php:285
ResourceLoaderContext\encodeJson
encodeJson( $data)
Wrapper around json_encode that avoids needless escapes, and pretty-prints in debug mode.
Definition: ResourceLoaderContext.php:432