resourceLoader = $resourceLoader; $this->request = $request; $this->logger = $resourceLoader->getLogger(); // Future developers: Use WebRequest::getRawVal() instead getVal(). // The getVal() method performs slow Language+UTF logic. (f303bb9360) // List of modules $modules = $request->getRawVal( 'modules' ); $this->modules = $modules ? self::expandModuleNames( $modules ) : []; // Various parameters $this->user = $request->getRawVal( 'user' ); $this->debug = $request->getFuzzyBool( 'debug', $resourceLoader->getConfig()->get( 'ResourceLoaderDebug' ) ); $this->only = $request->getRawVal( 'only', null ); $this->version = $request->getRawVal( 'version', null ); $this->raw = $request->getFuzzyBool( 'raw' ); // Image requests $this->image = $request->getRawVal( 'image' ); $this->variant = $request->getRawVal( 'variant' ); $this->format = $request->getRawVal( 'format' ); $this->skin = $request->getRawVal( 'skin' ); $skinnames = Skin::getSkinNames(); // If no skin is specified, or we don't recognize the skin, use the default skin if ( !$this->skin || !isset( $skinnames[$this->skin] ) ) { $this->skin = $resourceLoader->getConfig()->get( 'DefaultSkin' ); } } /** * Expand a string of the form `jquery.foo,bar|jquery.ui.baz,quux` to * an array of module names like `[ 'jquery.foo', 'jquery.bar', * 'jquery.ui.baz', 'jquery.ui.quux' ]`. * * This process is reversed by ResourceLoader::makePackedModulesString(). * * @param string $modules Packed module name list * @return array Array of module names */ public static function expandModuleNames( $modules ) { $retval = []; $exploded = explode( '|', $modules ); foreach ( $exploded as $group ) { if ( strpos( $group, ',' ) === false ) { // This is not a set of modules in foo.bar,baz notation // but a single module $retval[] = $group; } else { // This is a set of modules in foo.bar,baz notation $pos = strrpos( $group, '.' ); if ( $pos === false ) { // Prefixless modules, i.e. without dots $retval = array_merge( $retval, explode( ',', $group ) ); } else { // We have a prefix and a bunch of suffixes $prefix = substr( $group, 0, $pos ); // 'foo' $suffixes = explode( ',', substr( $group, $pos + 1 ) ); // [ 'bar', 'baz' ] foreach ( $suffixes as $suffix ) { $retval[] = "$prefix.$suffix"; } } } } return $retval; } /** * Return a dummy ResourceLoaderContext object suitable for passing into * things that don't "really" need a context. * @return ResourceLoaderContext */ public static function newDummyContext() { return new self( new ResourceLoader( MediaWikiServices::getInstance()->getMainConfig(), LoggerFactory::getInstance( 'resourceloader' ) ), new FauxRequest( [] ) ); } /** * @return ResourceLoader */ public function getResourceLoader() { return $this->resourceLoader; } /** * @return WebRequest */ public function getRequest() { return $this->request; } /** * @since 1.27 * @return \Psr\Log\LoggerInterface */ public function getLogger() { return $this->logger; } /** * @return array */ public function getModules() { return $this->modules; } /** * @return string */ public function getLanguage() { if ( $this->language === null ) { // Must be a valid language code after this point (T64849) // Only support uselang values that follow built-in conventions (T102058) $lang = $this->getRequest()->getRawVal( 'lang', '' ); // Stricter version of RequestContext::sanitizeLangCode() if ( !Language::isValidBuiltInCode( $lang ) ) { $lang = $this->getResourceLoader()->getConfig()->get( 'LanguageCode' ); } $this->language = $lang; } return $this->language; } /** * @return string */ public function getDirection() { if ( $this->direction === null ) { $this->direction = $this->getRequest()->getRawVal( 'dir' ); if ( !$this->direction ) { // Determine directionality based on user language (T8100) $this->direction = Language::factory( $this->getLanguage() )->getDir(); } } return $this->direction; } /** * @return string */ public function getSkin() { return $this->skin; } /** * @return string|null */ public function getUser() { return $this->user; } /** * Get a Message object with context set. See wfMessage for parameters. * * @since 1.27 * @param string|string[]|MessageSpecifier $key Message key, or array of keys, * or a MessageSpecifier. * @param mixed $args,... * @return Message */ public function msg( $key ) { return call_user_func_array( 'wfMessage', func_get_args() ) ->inLanguage( $this->getLanguage() ) // Use a dummy title because there is no real title // for this endpoint, and the cache won't vary on it // anyways. ->title( Title::newFromText( 'Dwimmerlaik' ) ); } /** * Get the possibly-cached User object for the specified username * * @since 1.25 * @return User */ public function getUserObj() { if ( $this->userObj === null ) { $username = $this->getUser(); if ( $username ) { // Use provided username if valid, fallback to anonymous user $this->userObj = User::newFromName( $username ) ?: new User; } else { // Anonymous user $this->userObj = new User; } } return $this->userObj; } /** * @return bool */ public function getDebug() { return $this->debug; } /** * @return string|null */ public function getOnly() { return $this->only; } /** * @see ResourceLoaderModule::getVersionHash * @see ResourceLoaderClientHtml::makeLoad * @return string|null */ public function getVersion() { return $this->version; } /** * @return bool */ public function getRaw() { return $this->raw; } /** * @return string|null */ public function getImage() { return $this->image; } /** * @return string|null */ public function getVariant() { return $this->variant; } /** * @return string|null */ public function getFormat() { return $this->format; } /** * If this is a request for an image, get the ResourceLoaderImage object. * * @since 1.25 * @return ResourceLoaderImage|bool false if a valid object cannot be created */ public function getImageObj() { if ( $this->imageObj === null ) { $this->imageObj = false; if ( !$this->image ) { return $this->imageObj; } $modules = $this->getModules(); if ( count( $modules ) !== 1 ) { return $this->imageObj; } $module = $this->getResourceLoader()->getModule( $modules[0] ); if ( !$module || !$module instanceof ResourceLoaderImageModule ) { return $this->imageObj; } $image = $module->getImage( $this->image, $this ); if ( !$image ) { return $this->imageObj; } $this->imageObj = $image; } return $this->imageObj; } /** * @return bool */ public function shouldIncludeScripts() { return $this->getOnly() === null || $this->getOnly() === 'scripts'; } /** * @return bool */ public function shouldIncludeStyles() { return $this->getOnly() === null || $this->getOnly() === 'styles'; } /** * @return bool */ public function shouldIncludeMessages() { return $this->getOnly() === null; } /** * All factors that uniquely identify this request, except 'modules'. * * The list of modules is excluded here for legacy reasons as most callers already * split up handling of individual modules. Including it here would massively fragment * the cache and decrease its usefulness. * * E.g. Used by RequestFileCache to form a cache key for storing the reponse output. * * @return string */ public function getHash() { if ( !isset( $this->hash ) ) { $this->hash = implode( '|', [ // Module content vary $this->getLanguage(), $this->getSkin(), $this->getDebug(), $this->getUser(), // Request vary $this->getOnly(), $this->getVersion(), $this->getRaw(), $this->getImage(), $this->getVariant(), $this->getFormat(), ] ); } return $this->hash; } }