/**
  * @param ResourceLoader $resourceLoader
  * @param WebRequest $request
  */
 public function __construct(ResourceLoader $resourceLoader, WebRequest $request)
 {
     $this->resourceLoader = $resourceLoader;
     $this->request = $request;
     // Interpret request
     // List of modules
     $modules = $request->getVal('modules');
     $this->modules = $modules ? self::expandModuleNames($modules) : array();
     // Various parameters
     $this->skin = $request->getVal('skin');
     $this->user = $request->getVal('user');
     $this->debug = $request->getFuzzyBool('debug', $resourceLoader->getConfig()->get('ResourceLoaderDebug'));
     $this->only = $request->getVal('only');
     $this->version = $request->getVal('version');
     $this->raw = $request->getFuzzyBool('raw');
     // Image requests
     $this->image = $request->getVal('image');
     $this->variant = $request->getVal('variant');
     $this->format = $request->getVal('format');
     $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');
     }
 }
 /**
  * @param ResourceLoader $resourceLoader
  * @param WebRequest $request
  */
 public function __construct(ResourceLoader $resourceLoader, WebRequest $request)
 {
     $this->resourceLoader = $resourceLoader;
     $this->request = $request;
     $this->logger = $resourceLoader->getLogger();
     // Future developers: Avoid use of getVal() in this class, which performs
     // expensive UTF normalisation by default. Use getRawVal() instead.
     // Values here are either one of a finite number of internal IDs,
     // or previously-stored user input (e.g. titles, user names) that were passed
     // to this endpoint by ResourceLoader itself from the canonical value.
     // Values do not come directly from user input and need not match.
     // 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');
     }
 }
 /**
  * Get the message blobs for a set of modules from the database.
  * Modules whose blobs are not in the database are silently dropped.
  *
  * @param ResourceLoader $resourceLoader
  * @param array $modules Array of module names
  * @param string $lang Language code
  * @throws MWException
  * @return array Array mapping module names to blobs
  */
 private function getFromDB(ResourceLoader $resourceLoader, $modules, $lang)
 {
     if (!count($modules)) {
         return array();
     }
     $config = $resourceLoader->getConfig();
     $retval = array();
     $dbr = wfGetDB(DB_SLAVE);
     $res = $dbr->select('msg_resource', array('mr_blob', 'mr_resource', 'mr_timestamp'), array('mr_resource' => $modules, 'mr_lang' => $lang), __METHOD__);
     foreach ($res as $row) {
         $module = $resourceLoader->getModule($row->mr_resource);
         if (!$module) {
             // This shouldn't be possible
             throw new MWException(__METHOD__ . ' passed an invalid module name');
         }
         // Update the module's blobs if the set of messages changed or if the blob is
         // older than the CacheEpoch setting
         $keys = array_keys(FormatJson::decode($row->mr_blob, true));
         $values = array_values(array_unique($module->getMessages()));
         if ($keys !== $values || wfTimestamp(TS_MW, $row->mr_timestamp) <= $config->get('CacheEpoch')) {
             $retval[$row->mr_resource] = $this->updateModule($row->mr_resource, $module, $lang);
         } else {
             $retval[$row->mr_resource] = $row->mr_blob;
         }
     }
     return $retval;
 }
 /**
  * Conditionally register the jquery.uls.data and jquery.i18n modules, in case they've already
  * been registered by the UniversalLanguageSelector extension or the TemplateData extension.
  *
  * @param ResourceLoader $resourceLoader
  * @return boolean true
  */
 public static function onResourceLoaderRegisterModules(ResourceLoader &$resourceLoader)
 {
     $resourceModules = $resourceLoader->getConfig()->get('ResourceModules');
     $veResourceTemplate = array('localBasePath' => __DIR__, 'remoteExtPath' => 'VisualEditor');
     $libModules = array('jquery.uls.data' => $veResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.uls/src/jquery.uls.data.js', 'lib/ve/lib/jquery.uls/src/jquery.uls.data.utils.js'), 'targets' => array('desktop', 'mobile')), 'jquery.i18n' => $veResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.i18n/src/jquery.i18n.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.messagestore.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.parser.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.emitter.js', 'lib/ve/lib/jquery.i18n/src/jquery.i18n.language.js'), 'dependencies' => 'mediawiki.libs.pluralruleparser', 'languageScripts' => array('bs' => 'lib/ve/lib/jquery.i18n/src/languages/bs.js', 'dsb' => 'lib/ve/lib/jquery.i18n/src/languages/dsb.js', 'fi' => 'lib/ve/lib/jquery.i18n/src/languages/fi.js', 'ga' => 'lib/ve/lib/jquery.i18n/src/languages/ga.js', 'he' => 'lib/ve/lib/jquery.i18n/src/languages/he.js', 'hsb' => 'lib/ve/lib/jquery.i18n/src/languages/hsb.js', 'hu' => 'lib/ve/lib/jquery.i18n/src/languages/hu.js', 'hy' => 'lib/ve/lib/jquery.i18n/src/languages/hy.js', 'la' => 'lib/ve/lib/jquery.i18n/src/languages/la.js', 'ml' => 'lib/ve/lib/jquery.i18n/src/languages/ml.js', 'os' => 'lib/ve/lib/jquery.i18n/src/languages/os.js', 'ru' => 'lib/ve/lib/jquery.i18n/src/languages/ru.js', 'sl' => 'lib/ve/lib/jquery.i18n/src/languages/sl.js', 'uk' => 'lib/ve/lib/jquery.i18n/src/languages/uk.js'), 'targets' => array('desktop', 'mobile')));
     $addModules = array();
     foreach ($libModules as $name => $data) {
         if (!isset($resourceModules[$name]) && !$resourceLoader->isModuleRegistered($name)) {
             $addModules[$name] = $data;
         }
     }
     $resourceLoader->register($addModules);
     return true;
 }
 /**
  * Conditionally register the jquery.uls.data and jquery.i18n modules, in case they've already
  * been registered by the UniversalLanguageSelector extension or the TemplateData extension.
  *
  * @param ResourceLoader $resourceLoader
  * @return boolean true
  */
 public static function onResourceLoaderRegisterModules(ResourceLoader &$resourceLoader)
 {
     $resourceModules = $resourceLoader->getConfig()->get('ResourceModules');
     $veResourceTemplate = array('localBasePath' => __DIR__, 'remoteExtPath' => 'VisualEditor');
     // Only pull in VisualEditor core's local version of jquery.uls.data if it hasn't been
     // installed locally already (presumably, by the UniversalLanguageSelector extension).
     if (!isset($resourceModules['jquery.uls.data']) && !$resourceLoader->isModuleRegistered('jquery.uls.data')) {
         $resourceLoader->register(array('jquery.uls.data' => $veResourceTemplate + array('scripts' => array('lib/ve/lib/jquery.uls/src/jquery.uls.data.js', 'lib/ve/lib/jquery.uls/src/jquery.uls.data.utils.js'), 'targets' => array('desktop', 'mobile'))));
     }
     // Register ext.visualEditor.mwreference here, as it depends on the new
     // Cite CSS style module ext.cite.style only if the Cite extension is
     // present.
     // This is a temporary hack, once the Cite extension uses the new CSS
     // for everything (and it takes care of loading ext.cite.style itself),
     // it can be removed from here and put back in extension.json.
     $mwreferenceModule = $veResourceTemplate + array('scripts' => array('modules/ve-mw/ui/widgets/ve.ui.MWReferenceGroupInputWidget.js', 'modules/ve-mw/ui/widgets/ve.ui.MWReferenceSearchWidget.js', 'modules/ve-mw/ui/widgets/ve.ui.MWReferenceResultWidget.js', 'modules/ve-mw/ui/commands/ve.ui.MWUseExistingReferenceCommand.js', 'modules/ve-mw/ui/dialogs/ve.ui.MWCitationDialog.js', 'modules/ve-mw/ui/dialogs/ve.ui.MWReferencesListDialog.js', 'modules/ve-mw/ui/dialogs/ve.ui.MWReferenceDialog.js', 'modules/ve-mw/ui/tools/ve.ui.MWReferenceDialogTool.js', 'modules/ve-mw/ui/tools/ve.ui.MWCitationDialogTool.js', 'modules/ve-mw/ui/contextitems/ve.ui.MWReferenceContextItem.js', 'modules/ve-mw/ui/contextitems/ve.ui.MWReferencesListContextItem.js', 'modules/ve-mw/ui/contextitems/ve.ui.MWCitationContextItem.js', 'modules/ve-mw/ui/actions/ve.ui.MWCitationAction.js'), 'styles' => array('modules/ve-mw/ui/styles/contextitems/ve.ui.MWReferenceContextItem.css', 'modules/ve-mw/ui/styles/widgets/ve.ui.MWReferenceGroupInputWidget.css', 'modules/ve-mw/ui/styles/widgets/ve.ui.MWReferenceResultWidget.css', 'modules/ve-mw/ui/styles/widgets/ve.ui.MWReferenceSearchWidget.css'), 'dependencies' => array('ext.visualEditor.mwreference.core', 'ext.visualEditor.mwtransclusion', 'ext.visualEditor.mediawiki'), 'messages' => array('visualeditor-dialog-reference-editing-reused', 'visualeditor-dialog-reference-options-group-label', 'visualeditor-dialog-reference-options-group-placeholder', 'visualeditor-dialog-reference-options-name-label', 'visualeditor-dialog-reference-options-section', 'visualeditor-dialog-reference-title', 'visualeditor-dialog-reference-useexisting-full-label', 'visualeditor-dialog-reference-useexisting-label', 'visualeditor-dialog-reference-useexisting-tool', 'visualeditor-dialog-referenceslist-contextitem-description-general', 'visualeditor-dialog-referenceslist-contextitem-description-named', 'visualeditor-dialog-referenceslist-title', 'visualeditor-dialogbutton-reference-full-label', 'visualeditor-dialogbutton-reference-tooltip', 'visualeditor-dialogbutton-reference-title', 'visualeditor-dialogbutton-referenceslist-tooltip', 'visualeditor-reference-input-placeholder'), 'targets' => array('desktop', 'mobile'));
     if (isset($resourceModules['ext.cite.style']) || $resourceLoader->isModuleRegistered('ext.cite.style')) {
         $mwreferenceModule['dependencies'][] = 'ext.cite.style';
     }
     $resourceLoader->register(array('ext.visualEditor.mwreference' => $mwreferenceModule));
     return true;
 }