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 
66  public function __construct( ResourceLoader $resourceLoader, WebRequest $request ) {
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() : ResourceLoaderContext {
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 
121  public function getResourceLoader() : ResourceLoader {
122  return $this->resourceLoader;
123  }
124 
131  public function getConfig() {
132  wfDeprecated( __METHOD__, '1.34' );
133  return $this->getResourceLoader()->getConfig();
134  }
135 
136  public function getRequest() : WebRequest {
137  return $this->request;
138  }
139 
146  public function getLogger() {
147  return $this->logger;
148  }
149 
150  public function getModules() : array {
151  return $this->modules;
152  }
153 
154  public function getLanguage() : string {
155  if ( $this->language === null ) {
156  // Must be a valid language code after this point (T64849)
157  // Only support uselang values that follow built-in conventions (T102058)
158  $lang = $this->getRequest()->getRawVal( 'lang', '' );
159  // Stricter version of RequestContext::sanitizeLangCode()
160  $validBuiltinCode = MediaWikiServices::getInstance()->getLanguageNameUtils()
161  ->isValidBuiltInCode( $lang );
162  if ( !$validBuiltinCode ) {
163  // The 'lang' parameter is required. (Not yet enforced.)
164  // If omitted, localise with the dummy language code.
166  }
167  $this->language = $lang;
168  }
169  return $this->language;
170  }
171 
172  public function getDirection() : string {
173  if ( $this->direction === null ) {
174  $direction = $this->getRequest()->getRawVal( 'dir' );
175  if ( $direction === 'ltr' || $direction === 'rtl' ) {
176  $this->direction = $direction;
177  } else {
178  // Determine directionality based on user language (T8100)
179  $this->direction = MediaWikiServices::getInstance()->getLanguageFactory()
180  ->getLanguage( $this->getLanguage() )->getDir();
181  }
182  }
183  return $this->direction;
184  }
185 
186  public function getSkin() : string {
187  return $this->skin;
188  }
189 
193  public function getUser() : ?string {
194  return $this->user;
195  }
196 
206  public function msg( $key, ...$params ) : Message {
207  return wfMessage( $key, ...$params )
208  ->inLanguage( $this->getLanguage() )
209  // Use a dummy title because there is no real title
210  // for this endpoint, and the cache won't vary on it
211  // anyways.
212  ->title( Title::newFromText( 'Dwimmerlaik' ) );
213  }
214 
221  public function getUserObj() : User {
222  if ( $this->userObj === null ) {
223  $username = $this->getUser();
224  if ( $username ) {
225  // Use provided username if valid, fallback to anonymous user
226  $this->userObj = User::newFromName( $username ) ?: new User;
227  } else {
228  // Anonymous user
229  $this->userObj = new User;
230  }
231  }
232 
233  return $this->userObj;
234  }
235 
236  public function getDebug() : bool {
237  return $this->debug;
238  }
239 
243  public function getOnly() : ?string {
244  return $this->only;
245  }
246 
252  public function getVersion() : ?string {
253  return $this->version;
254  }
255 
256  public function getRaw() : bool {
257  return $this->raw;
258  }
259 
263  public function getImage() : ?string {
264  return $this->image;
265  }
266 
270  public function getVariant() : ?string {
271  return $this->variant;
272  }
273 
277  public function getFormat() : ?string {
278  return $this->format;
279  }
280 
287  public function getImageObj() {
288  if ( $this->imageObj === null ) {
289  $this->imageObj = false;
290 
291  if ( !$this->image ) {
292  return $this->imageObj;
293  }
294 
295  $modules = $this->getModules();
296  if ( count( $modules ) !== 1 ) {
297  return $this->imageObj;
298  }
299 
300  $module = $this->getResourceLoader()->getModule( $modules[0] );
301  if ( !$module || !$module instanceof ResourceLoaderImageModule ) {
302  return $this->imageObj;
303  }
304 
305  $image = $module->getImage( $this->image, $this );
306  if ( !$image ) {
307  return $this->imageObj;
308  }
309 
310  $this->imageObj = $image;
311  }
312 
313  return $this->imageObj;
314  }
315 
328  public function getContentOverrideCallback() {
329  return null;
330  }
331 
332  public function shouldIncludeScripts() : bool {
333  return $this->getOnly() === null || $this->getOnly() === 'scripts';
334  }
335 
336  public function shouldIncludeStyles() : bool {
337  return $this->getOnly() === null || $this->getOnly() === 'styles';
338  }
339 
340  public function shouldIncludeMessages() : bool {
341  return $this->getOnly() === null;
342  }
343 
355  public function getHash() : string {
356  if ( !isset( $this->hash ) ) {
357  $this->hash = implode( '|', [
358  // Module content vary
359  $this->getLanguage(),
360  $this->getSkin(),
361  $this->getDebug(),
362  $this->getUser(),
363  // Request vary
364  $this->getOnly(),
365  $this->getVersion(),
366  $this->getRaw(),
367  $this->getImage(),
368  $this->getVariant(),
369  $this->getFormat(),
370  ] );
371  }
372  return $this->hash;
373  }
374 
381  public function getReqBase() : array {
382  $reqBase = [];
383  if ( $this->getLanguage() !== self::DEFAULT_LANG ) {
384  $reqBase['lang'] = $this->getLanguage();
385  }
386  if ( $this->getSkin() !== self::DEFAULT_SKIN ) {
387  $reqBase['skin'] = $this->getSkin();
388  }
389  if ( $this->getDebug() ) {
390  $reqBase['debug'] = 'true';
391  }
392  return $reqBase;
393  }
394 
403  public function encodeJson( $data ) {
404  // Keep output as small as possible by disabling needless escape modes
405  // that PHP uses by default.
406  // However, while most module scripts are only served on HTTP responses
407  // for JavaScript, some modules can also be embedded in the HTML as inline
408  // scripts. This, and the fact that we sometimes need to export strings
409  // containing user-generated content and labels that may genuinely contain
410  // a sequences like "</script>", we need to encode either '/' or '<'.
411  // By default PHP escapes '/'. Let's escape '<' instead which is less common
412  // and allows URLs to mostly remain readable.
413  $jsonFlags = JSON_UNESCAPED_SLASHES |
414  JSON_UNESCAPED_UNICODE |
415  JSON_HEX_TAG |
416  JSON_HEX_AMP;
417  if ( $this->getDebug() ) {
418  $jsonFlags |= JSON_PRETTY_PRINT;
419  }
420  return json_encode( $data, $jsonFlags );
421  }
422 }
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:381
ResourceLoaderContext\getConfig
getConfig()
Definition: ResourceLoaderContext.php:131
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: FauxRequest.php:33
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:335
ResourceLoaderContext\$logger
$logger
Definition: ResourceLoaderContext.php:39
ResourceLoaderContext\getDirection
getDirection()
Definition: ResourceLoaderContext.php:172
ResourceLoaderContext\newDummyContext
static newDummyContext()
Return a dummy ResourceLoaderContext object suitable for passing into things that don't "really" need...
Definition: ResourceLoaderContext.php:109
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:134
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:35
ResourceLoaderContext\getResourceLoader
getResourceLoader()
Definition: ResourceLoaderContext.php:121
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:263
ResourceLoaderContext\getModules
getModules()
Definition: ResourceLoaderContext.php:150
ResourceLoaderContext\getContentOverrideCallback
getContentOverrideCallback()
Return the replaced-content mapping callback.
Definition: ResourceLoaderContext.php:328
ResourceLoaderContext\$user
$user
Definition: ResourceLoaderContext.php:45
ResourceLoaderContext\$image
$image
Definition: ResourceLoaderContext.php:52
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:537
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1265
ResourceLoaderContext\getOnly
getOnly()
Definition: ResourceLoaderContext.php:243
Message
ResourceLoaderContext\getVariant
getVariant()
Definition: ResourceLoaderContext.php:270
ResourceLoaderContext\getFormat
getFormat()
Definition: ResourceLoaderContext.php:277
MessageLocalizer
Interface for localizing messages in MediaWiki.
Definition: MessageLocalizer.php:27
Skin\getSkinNames
static getSkinNames()
Fetch the set of available skins.
Definition: Skin.php:57
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:1045
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
ResourceLoaderContext\getRequest
getRequest()
Definition: ResourceLoaderContext.php:136
ResourceLoaderContext\$language
$language
Definition: ResourceLoaderContext.php:43
ResourceLoaderContext\getDebug
getDebug()
Definition: ResourceLoaderContext.php:236
ResourceLoaderContext\$raw
$raw
Definition: ResourceLoaderContext.php:51
ResourceLoaderContext\getLanguage
getLanguage()
Definition: ResourceLoaderContext.php:154
ResourceLoaderContext\getVersion
getVersion()
Definition: ResourceLoaderContext.php:252
ResourceLoaderContext\shouldIncludeStyles
shouldIncludeStyles()
Definition: ResourceLoaderContext.php:336
ResourceLoaderContext\$userObj
$userObj
Definition: ResourceLoaderContext.php:58
ResourceLoaderContext\msg
msg( $key,... $params)
Get a Message object with context set.
Definition: ResourceLoaderContext.php:206
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:340
ResourceLoaderContext\getSkin
getSkin()
Definition: ResourceLoaderContext.php:186
ResourceLoaderContext\shouldIncludeScripts
shouldIncludeScripts()
Definition: ResourceLoaderContext.php:332
ResourceLoaderContext\getUser
getUser()
Definition: ResourceLoaderContext.php:193
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:60
ResourceLoaderContext\$request
$request
Definition: ResourceLoaderContext.php:38
ResourceLoaderContext\getLogger
getLogger()
Definition: ResourceLoaderContext.php:146
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:355
ResourceLoaderContext\getImageObj
getImageObj()
If this is a request for an image, get the ResourceLoaderImage object.
Definition: ResourceLoaderContext.php:287
ResourceLoaderContext\getUserObj
getUserObj()
Get the possibly-cached User object for the specified username.
Definition: ResourceLoaderContext.php:221
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:52
ResourceLoaderContext\getRaw
getRaw()
Definition: ResourceLoaderContext.php:256
ResourceLoaderContext\encodeJson
encodeJson( $data)
Wrapper around json_encode that avoids needless escapes, and pretty-prints in debug mode.
Definition: ResourceLoaderContext.php:403