MediaWiki  master
ResourceLoaderContext.php
Go to the documentation of this file.
1 <?php
25 
34  public const DEFAULT_LANG = 'qqx';
35  public const DEFAULT_SKIN = 'fallback';
36 
37  protected $resourceLoader;
38  protected $request;
39  protected $logger;
40 
41  // Module content vary
42  protected $skin;
43  protected $language;
44  protected $debug;
45  protected $user;
46 
47  // Request vary (in addition to cache vary)
48  protected $modules;
49  protected $only;
50  protected $version;
51  protected $raw;
52  protected $image;
53  protected $variant;
54  protected $format;
55 
56  protected $direction;
57  protected $hash;
58  protected $userObj;
60  protected $imageObj;
61 
67  $this->resourceLoader = $resourceLoader;
68  $this->request = $request;
69  $this->logger = $resourceLoader->getLogger();
70 
71  // Optimisation: Use WebRequest::getRawVal() instead of getVal(). We don't
72  // need the slow Language+UTF logic meant for user input here. (f303bb9360)
73 
74  // List of modules
75  $modules = $request->getRawVal( 'modules' );
76  $this->modules = $modules ? ResourceLoader::expandModuleNames( $modules ) : [];
77 
78  // Various parameters
79  $this->user = $request->getRawVal( 'user' );
80  $this->debug = $request->getRawVal( 'debug' ) === 'true';
81  $this->only = $request->getRawVal( 'only' );
82  $this->version = $request->getRawVal( 'version' );
83  $this->raw = $request->getFuzzyBool( 'raw' );
84 
85  // Image requests
86  $this->image = $request->getRawVal( 'image' );
87  $this->variant = $request->getRawVal( 'variant' );
88  $this->format = $request->getRawVal( 'format' );
89 
90  $this->skin = $request->getRawVal( 'skin' );
91  $skinFactory = MediaWikiServices::getInstance()->getSkinFactory();
92  $skinnames = $skinFactory->getSkinNames();
93 
94  if ( !$this->skin || !isset( $skinnames[$this->skin] ) ) {
95  // The 'skin' parameter is required. (Not yet enforced.)
96  // For requests without a known skin specified,
97  // use MediaWiki's 'fallback' skin for skin-specific decisions.
98  $this->skin = self::DEFAULT_SKIN;
99  }
100  }
101 
111  public static function newDummyContext() : ResourceLoaderContext {
112  // This currently creates a non-empty instance of ResourceLoader (all modules registered),
113  // but that's probably not needed. So once that moves into ServiceWiring, this'll
114  // become more like the EmptyResourceLoader class we have in PHPUnit tests, which
115  // is what this should've had originally. If this turns out to be untrue, change to:
116  // `MediaWikiServices::getInstance()->getResourceLoader()` instead.
117  return new self( new ResourceLoader(
118  MediaWikiServices::getInstance()->getMainConfig(),
119  LoggerFactory::getInstance( 'resourceloader' )
120  ), new FauxRequest( [] ) );
121  }
122 
123  public function getResourceLoader() : ResourceLoader {
124  return $this->resourceLoader;
125  }
126 
133  public function getConfig() {
134  wfDeprecated( __METHOD__, '1.34' );
135  return $this->getResourceLoader()->getConfig();
136  }
137 
138  public function getRequest() : WebRequest {
139  return $this->request;
140  }
141 
148  public function getLogger() {
149  return $this->logger;
150  }
151 
152  public function getModules() : array {
153  return $this->modules;
154  }
155 
156  public function getLanguage() : string {
157  if ( $this->language === null ) {
158  // Must be a valid language code after this point (T64849)
159  // Only support uselang values that follow built-in conventions (T102058)
160  $lang = $this->getRequest()->getRawVal( 'lang', '' );
161  // Stricter version of RequestContext::sanitizeLangCode()
162  $validBuiltinCode = MediaWikiServices::getInstance()->getLanguageNameUtils()
163  ->isValidBuiltInCode( $lang );
164  if ( !$validBuiltinCode ) {
165  // The 'lang' parameter is required. (Not yet enforced.)
166  // If omitted, localise with the dummy language code.
168  }
169  $this->language = $lang;
170  }
171  return $this->language;
172  }
173 
174  public function getDirection() : string {
175  if ( $this->direction === null ) {
176  $direction = $this->getRequest()->getRawVal( 'dir' );
177  if ( $direction === 'ltr' || $direction === 'rtl' ) {
178  $this->direction = $direction;
179  } else {
180  // Determine directionality based on user language (T8100)
181  $this->direction = MediaWikiServices::getInstance()->getLanguageFactory()
182  ->getLanguage( $this->getLanguage() )->getDir();
183  }
184  }
185  return $this->direction;
186  }
187 
188  public function getSkin() : string {
189  return $this->skin;
190  }
191 
195  public function getUser() : ?string {
196  return $this->user;
197  }
198 
208  public function msg( $key, ...$params ) : Message {
209  return wfMessage( $key, ...$params )
210  ->inLanguage( $this->getLanguage() )
211  // Use a dummy title because there is no real title
212  // for this endpoint, and the cache won't vary on it
213  // anyways.
214  ->title( Title::newFromText( 'Dwimmerlaik' ) );
215  }
216 
223  public function getUserObj() : User {
224  if ( $this->userObj === null ) {
225  $username = $this->getUser();
226  if ( $username ) {
227  // Use provided username if valid, fallback to anonymous user
228  $this->userObj = User::newFromName( $username ) ?: new User;
229  } else {
230  // Anonymous user
231  $this->userObj = new User;
232  }
233  }
234 
235  return $this->userObj;
236  }
237 
238  public function getDebug() : bool {
239  return $this->debug;
240  }
241 
245  public function getOnly() : ?string {
246  return $this->only;
247  }
248 
254  public function getVersion() : ?string {
255  return $this->version;
256  }
257 
258  public function getRaw() : bool {
259  return $this->raw;
260  }
261 
265  public function getImage() : ?string {
266  return $this->image;
267  }
268 
272  public function getVariant() : ?string {
273  return $this->variant;
274  }
275 
279  public function getFormat() : ?string {
280  return $this->format;
281  }
282 
289  public function getImageObj() {
290  if ( $this->imageObj === null ) {
291  $this->imageObj = false;
292 
293  if ( !$this->image ) {
294  return $this->imageObj;
295  }
296 
297  $modules = $this->getModules();
298  if ( count( $modules ) !== 1 ) {
299  return $this->imageObj;
300  }
301 
302  $module = $this->getResourceLoader()->getModule( $modules[0] );
303  if ( !$module || !$module instanceof ResourceLoaderImageModule ) {
304  return $this->imageObj;
305  }
306 
307  $image = $module->getImage( $this->image, $this );
308  if ( !$image ) {
309  return $this->imageObj;
310  }
311 
312  $this->imageObj = $image;
313  }
314 
315  return $this->imageObj;
316  }
317 
330  public function getContentOverrideCallback() {
331  return null;
332  }
333 
334  public function shouldIncludeScripts() : bool {
335  return $this->getOnly() === null || $this->getOnly() === 'scripts';
336  }
337 
338  public function shouldIncludeStyles() : bool {
339  return $this->getOnly() === null || $this->getOnly() === 'styles';
340  }
341 
342  public function shouldIncludeMessages() : bool {
343  return $this->getOnly() === null;
344  }
345 
357  public function getHash() : string {
358  if ( !isset( $this->hash ) ) {
359  $this->hash = implode( '|', [
360  // Module content vary
361  $this->getLanguage(),
362  $this->getSkin(),
363  $this->getDebug(),
364  $this->getUser(),
365  // Request vary
366  $this->getOnly(),
367  $this->getVersion(),
368  $this->getRaw(),
369  $this->getImage(),
370  $this->getVariant(),
371  $this->getFormat(),
372  ] );
373  }
374  return $this->hash;
375  }
376 
383  public function getReqBase() : array {
384  $reqBase = [];
385  if ( $this->getLanguage() !== self::DEFAULT_LANG ) {
386  $reqBase['lang'] = $this->getLanguage();
387  }
388  if ( $this->getSkin() !== self::DEFAULT_SKIN ) {
389  $reqBase['skin'] = $this->getSkin();
390  }
391  if ( $this->getDebug() ) {
392  $reqBase['debug'] = 'true';
393  }
394  return $reqBase;
395  }
396 
405  public function encodeJson( $data ) {
406  // Keep output as small as possible by disabling needless escape modes
407  // that PHP uses by default.
408  // However, while most module scripts are only served on HTTP responses
409  // for JavaScript, some modules can also be embedded in the HTML as inline
410  // scripts. This, and the fact that we sometimes need to export strings
411  // containing user-generated content and labels that may genuinely contain
412  // a sequences like "</script>", we need to encode either '/' or '<'.
413  // By default PHP escapes '/'. Let's escape '<' instead which is less common
414  // and allows URLs to mostly remain readable.
415  $jsonFlags = JSON_UNESCAPED_SLASHES |
416  JSON_UNESCAPED_UNICODE |
417  JSON_HEX_TAG |
418  JSON_HEX_AMP;
419  if ( $this->getDebug() ) {
420  $jsonFlags |= JSON_PRETTY_PRINT;
421  }
422  return json_encode( $data, $jsonFlags );
423  }
424 }
ResourceLoaderContext\$hash
$hash
Definition: ResourceLoaderContext.php:57
ResourceLoaderContext
Context object that contains information about the state of a specific ResourceLoader web request.
Definition: ResourceLoaderContext.php:33
ResourceLoaderContext\getReqBase
getReqBase()
Get the request base parameters, omitting any defaults.
Definition: ResourceLoaderContext.php:383
ResourceLoaderContext\getConfig
getConfig()
Definition: ResourceLoaderContext.php:133
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:35
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:328
ResourceLoaderContext\$logger
$logger
Definition: ResourceLoaderContext.php:39
ResourceLoaderContext\getDirection
getDirection()
Definition: ResourceLoaderContext.php:174
ResourceLoaderContext\newDummyContext
static newDummyContext()
Return a dummy ResourceLoaderContext object suitable for passing into things that don't "really" need...
Definition: ResourceLoaderContext.php:111
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:163
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
ResourceLoaderContext\getResourceLoader
getResourceLoader()
Definition: ResourceLoaderContext.php:123
ResourceLoaderContext\$version
$version
Definition: ResourceLoaderContext.php:50
ResourceLoaderContext\$skin
$skin
Definition: ResourceLoaderContext.php:42
ResourceLoaderContext\$direction
$direction
Definition: ResourceLoaderContext.php:56
ResourceLoaderContext\getImage
getImage()
Definition: ResourceLoaderContext.php:265
ResourceLoaderContext\getModules
getModules()
Definition: ResourceLoaderContext.php:152
ResourceLoaderContext\getContentOverrideCallback
getContentOverrideCallback()
Return the replaced-content mapping callback.
Definition: ResourceLoaderContext.php:330
ResourceLoaderContext\$user
$user
Definition: ResourceLoaderContext.php:45
ResourceLoaderContext\$image
$image
Definition: ResourceLoaderContext.php:52
User\newFromName
static newFromName( $name, $validate='valid')
Definition: User.php:545
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1220
ResourceLoaderContext\getOnly
getOnly()
Definition: ResourceLoaderContext.php:245
ResourceLoaderContext\getVariant
getVariant()
Definition: ResourceLoaderContext.php:272
ResourceLoaderContext\getFormat
getFormat()
Definition: ResourceLoaderContext.php:279
MessageLocalizer
Interface for localizing messages in MediaWiki.
Definition: MessageLocalizer.php:29
ResourceLoaderContext\$modules
$modules
Definition: ResourceLoaderContext.php:48
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Logs a warning that $function is deprecated.
Definition: GlobalFunctions.php:1027
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
ResourceLoaderContext\getRequest
getRequest()
Definition: ResourceLoaderContext.php:138
ResourceLoaderContext\$language
$language
Definition: ResourceLoaderContext.php:43
ResourceLoaderContext\getDebug
getDebug()
Definition: ResourceLoaderContext.php:238
ResourceLoaderContext\$raw
$raw
Definition: ResourceLoaderContext.php:51
ResourceLoaderContext\getLanguage
getLanguage()
Definition: ResourceLoaderContext.php:156
ResourceLoaderContext\getVersion
getVersion()
Definition: ResourceLoaderContext.php:254
ResourceLoaderContext\shouldIncludeStyles
shouldIncludeStyles()
Definition: ResourceLoaderContext.php:338
ResourceLoaderContext\$userObj
$userObj
Definition: ResourceLoaderContext.php:58
ResourceLoaderContext\msg
msg( $key,... $params)
Get a Message object with context set.
Definition: ResourceLoaderContext.php:208
ResourceLoaderImage
Class encapsulating an image used in a ResourceLoaderImageModule.
Definition: ResourceLoaderImage.php:31
ResourceLoaderContext\$resourceLoader
$resourceLoader
Definition: ResourceLoaderContext.php:37
ResourceLoaderContext\DEFAULT_SKIN
const DEFAULT_SKIN
Definition: ResourceLoaderContext.php:35
ResourceLoaderContext\__construct
__construct(ResourceLoader $resourceLoader, WebRequest $request)
Definition: ResourceLoaderContext.php:66
ResourceLoaderContext\$debug
$debug
Definition: ResourceLoaderContext.php:44
ResourceLoaderContext\DEFAULT_LANG
const DEFAULT_LANG
Definition: ResourceLoaderContext.php:34
ResourceLoaderContext\shouldIncludeMessages
shouldIncludeMessages()
Definition: ResourceLoaderContext.php:342
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:1724
ResourceLoaderContext\getSkin
getSkin()
Definition: ResourceLoaderContext.php:188
ResourceLoaderContext\shouldIncludeScripts
shouldIncludeScripts()
Definition: ResourceLoaderContext.php:334
ResourceLoaderContext\getUser
getUser()
Definition: ResourceLoaderContext.php:195
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:42
ResourceLoaderContext\$imageObj
ResourceLoaderImage false $imageObj
Definition: ResourceLoaderContext.php:60
ResourceLoaderContext\$request
$request
Definition: ResourceLoaderContext.php:38
ResourceLoaderContext\getLogger
getLogger()
Definition: ResourceLoaderContext.php:148
ResourceLoader
ResourceLoader is a loading system for JavaScript and CSS resources.
Definition: ResourceLoader.php:56
Message
The Message class deals with fetching and processing of interface message into a variety of formats.
Definition: Message.php:161
ResourceLoaderContext\$only
$only
Definition: ResourceLoaderContext.php:49
ResourceLoaderContext\$format
$format
Definition: ResourceLoaderContext.php:54
ResourceLoaderContext\$variant
$variant
Definition: ResourceLoaderContext.php:53
ResourceLoaderContext\getHash
getHash()
All factors that uniquely identify this request, except 'modules'.
Definition: ResourceLoaderContext.php:357
ResourceLoaderContext\getImageObj
getImageObj()
If this is a request for an image, get the ResourceLoaderImage object.
Definition: ResourceLoaderContext.php:289
ResourceLoaderContext\getUserObj
getUserObj()
Get the possibly-cached User object for the specified username.
Definition: ResourceLoaderContext.php:223
ResourceLoaderImageModule
Module for generated and embedded images.
Definition: ResourceLoaderImageModule.php:28
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
ResourceLoaderContext\getRaw
getRaw()
Definition: ResourceLoaderContext.php:258
ResourceLoaderContext\encodeJson
encodeJson( $data)
Wrapper around json_encode that avoids needless escapes, and pretty-prints in debug mode.
Definition: ResourceLoaderContext.php:405