MediaWiki  master
ResourceLoaderContext.php
Go to the documentation of this file.
1 <?php
25 
34  const DEFAULT_LANG = 'qqx';
35  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  $skinnames = Skin::getSkinNames();
92  if ( !$this->skin || !isset( $skinnames[$this->skin] ) ) {
93  // The 'skin' parameter is required. (Not yet enforced.)
94  // For requests without a known skin specified,
95  // use MediaWiki's 'fallback' skin for skin-specific decisions.
96  $this->skin = self::DEFAULT_SKIN;
97  }
98  }
99 
109  public static function newDummyContext() {
110  // This currently creates a non-empty instance of ResourceLoader (all modules registered),
111  // but that's probably not needed. So once that moves into ServiceWiring, this'll
112  // become more like the EmptyResourceLoader class we have in PHPUnit tests, which
113  // is what this should've had originally. If this turns out to be untrue, change to:
114  // `MediaWikiServices::getInstance()->getResourceLoader()` instead.
115  return new self( new ResourceLoader(
116  MediaWikiServices::getInstance()->getMainConfig(),
117  LoggerFactory::getInstance( 'resourceloader' )
118  ), new FauxRequest( [] ) );
119  }
120 
124  public function getResourceLoader() {
125  return $this->resourceLoader;
126  }
127 
134  public function getConfig() {
135  wfDeprecated( __METHOD__, '1.34' );
136  return $this->getResourceLoader()->getConfig();
137  }
138 
142  public function getRequest() {
143  return $this->request;
144  }
145 
152  public function getLogger() {
153  return $this->logger;
154  }
155 
159  public function getModules() {
160  return $this->modules;
161  }
162 
166  public function getLanguage() {
167  if ( $this->language === null ) {
168  // Must be a valid language code after this point (T64849)
169  // Only support uselang values that follow built-in conventions (T102058)
170  $lang = $this->getRequest()->getRawVal( 'lang', '' );
171  // Stricter version of RequestContext::sanitizeLangCode()
173  // The 'lang' parameter is required. (Not yet enforced.)
174  // If omitted, localise with the dummy language code.
175  $lang = self::DEFAULT_LANG;
176  }
177  $this->language = $lang;
178  }
179  return $this->language;
180  }
181 
185  public function getDirection() {
186  if ( $this->direction === null ) {
187  $direction = $this->getRequest()->getRawVal( 'dir' );
188  if ( $direction === 'ltr' || $direction === 'rtl' ) {
189  $this->direction = $direction;
190  } else {
191  // Determine directionality based on user language (T8100)
192  $this->direction = Language::factory( $this->getLanguage() )->getDir();
193  }
194  }
195  return $this->direction;
196  }
197 
201  public function getSkin() {
202  return $this->skin;
203  }
204 
208  public function getUser() {
209  return $this->user;
210  }
211 
221  public function msg( $key, ...$params ) {
222  return wfMessage( $key, ...$params )
223  ->inLanguage( $this->getLanguage() )
224  // Use a dummy title because there is no real title
225  // for this endpoint, and the cache won't vary on it
226  // anyways.
227  ->title( Title::newFromText( 'Dwimmerlaik' ) );
228  }
229 
236  public function getUserObj() {
237  if ( $this->userObj === null ) {
238  $username = $this->getUser();
239  if ( $username ) {
240  // Use provided username if valid, fallback to anonymous user
241  $this->userObj = User::newFromName( $username ) ?: new User;
242  } else {
243  // Anonymous user
244  $this->userObj = new User;
245  }
246  }
247 
248  return $this->userObj;
249  }
250 
254  public function getDebug() {
255  return $this->debug;
256  }
257 
261  public function getOnly() {
262  return $this->only;
263  }
264 
270  public function getVersion() {
271  return $this->version;
272  }
273 
277  public function getRaw() {
278  return $this->raw;
279  }
280 
284  public function getImage() {
285  return $this->image;
286  }
287 
291  public function getVariant() {
292  return $this->variant;
293  }
294 
298  public function getFormat() {
299  return $this->format;
300  }
301 
308  public function getImageObj() {
309  if ( $this->imageObj === null ) {
310  $this->imageObj = false;
311 
312  if ( !$this->image ) {
313  return $this->imageObj;
314  }
315 
316  $modules = $this->getModules();
317  if ( count( $modules ) !== 1 ) {
318  return $this->imageObj;
319  }
320 
321  $module = $this->getResourceLoader()->getModule( $modules[0] );
322  if ( !$module || !$module instanceof ResourceLoaderImageModule ) {
323  return $this->imageObj;
324  }
325 
326  $image = $module->getImage( $this->image, $this );
327  if ( !$image ) {
328  return $this->imageObj;
329  }
330 
331  $this->imageObj = $image;
332  }
333 
334  return $this->imageObj;
335  }
336 
349  public function getContentOverrideCallback() {
350  return null;
351  }
352 
356  public function shouldIncludeScripts() {
357  return $this->getOnly() === null || $this->getOnly() === 'scripts';
358  }
359 
363  public function shouldIncludeStyles() {
364  return $this->getOnly() === null || $this->getOnly() === 'styles';
365  }
366 
370  public function shouldIncludeMessages() {
371  return $this->getOnly() === null;
372  }
373 
385  public function getHash() {
386  if ( !isset( $this->hash ) ) {
387  $this->hash = implode( '|', [
388  // Module content vary
389  $this->getLanguage(),
390  $this->getSkin(),
391  $this->getDebug(),
392  $this->getUser(),
393  // Request vary
394  $this->getOnly(),
395  $this->getVersion(),
396  $this->getRaw(),
397  $this->getImage(),
398  $this->getVariant(),
399  $this->getFormat(),
400  ] );
401  }
402  return $this->hash;
403  }
404 
411  public function getReqBase() {
412  $reqBase = [];
413  if ( $this->getLanguage() !== self::DEFAULT_LANG ) {
414  $reqBase['lang'] = $this->getLanguage();
415  }
416  if ( $this->getSkin() !== self::DEFAULT_SKIN ) {
417  $reqBase['skin'] = $this->getSkin();
418  }
419  if ( $this->getDebug() ) {
420  $reqBase['debug'] = 'true';
421  }
422  return $reqBase;
423  }
424 
433  public function encodeJson( $data ) {
434  // Keep output as small as possible by disabling needless escape modes
435  // that PHP uses by default.
436  // However, while most module scripts are only served on HTTP responses
437  // for JavaScript, some modules can also be embedded in the HTML as inline
438  // scripts. This, and the fact that we sometimes need to export strings
439  // containing user-generated content and labels that may genuinely contain
440  // a sequences like "</script>", we need to encode either '/' or '<'.
441  // By default PHP escapes '/'. Let's escape '<' instead which is less common
442  // and allows URLs to mostly remain readable.
443  $jsonFlags = JSON_UNESCAPED_SLASHES |
444  JSON_UNESCAPED_UNICODE |
445  JSON_HEX_TAG |
446  JSON_HEX_AMP;
447  if ( $this->getDebug() ) {
448  $jsonFlags |= JSON_PRETTY_PRINT;
449  }
450  return json_encode( $data, $jsonFlags );
451  }
452 }
getRawVal( $name, $default=null)
Fetch a scalar from the input without normalization, or return $default if it&#39;s not set...
Definition: WebRequest.php:465
Module for generated and embedded images.
static newDummyContext()
Return a dummy ResourceLoaderContext object suitable for passing into things that don&#39;t "really" need...
if(!isset( $args[0])) $lang
static getSkinNames()
Fetch the set of available skins.
Definition: Skin.php:57
static isValidBuiltInCode( $code)
Returns true if a language code is of a valid form for the purposes of internal customisation of Medi...
Definition: Language.php:394
The User object encapsulates all of the user-specific settings (user_id, name, rights, email address, options, last login time).
Definition: User.php:51
getReqBase()
Get the request base parameters, omitting any defaults.
encodeJson( $data)
Wrapper around json_encode that avoids needless escapes, and pretty-prints in debug mode...
getContentOverrideCallback()
Return the replaced-content mapping callback.
getFuzzyBool( $name, $default=false)
Fetch a boolean value from the input or return $default if not set.
Definition: WebRequest.php:630
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:212
getUserObj()
Get the possibly-cached User object for the specified username.
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
static expandModuleNames( $modules)
Expand a string of the form jquery.foo,bar|jquery.ui.baz,quux to an array of module names like `[ &#39;jq...
getHash()
All factors that uniquely identify this request, except &#39;modules&#39;.
__construct(ResourceLoader $resourceLoader, WebRequest $request)
getImageObj()
If this is a request for an image, get the ResourceLoaderImage object.
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:515
ResourceLoaderImage false $imageObj
msg( $key,... $params)
Get a Message object with context set.
Context object that contains information about the state of a specific ResourceLoader web request...
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:319