/**
  * @param ResourceLoaderContext $context
  * @return array
  */
 protected function getConfigSettings($context)
 {
     $hash = $context->getHash();
     if (isset($this->configVars[$hash])) {
         return $this->configVars[$hash];
     }
     global $wgContLang;
     $mainPage = Title::newMainPage();
     /**
      * Namespace related preparation
      * - wgNamespaceIds: Key-value pairs of all localized, canonical and aliases for namespaces.
      * - wgCaseSensitiveNamespaces: Array of namespaces that are case-sensitive.
      */
     $namespaceIds = $wgContLang->getNamespaceIds();
     $caseSensitiveNamespaces = array();
     foreach (MWNamespace::getCanonicalNamespaces() as $index => $name) {
         $namespaceIds[$wgContLang->lc($name)] = $index;
         if (!MWNamespace::isCapitalized($index)) {
             $caseSensitiveNamespaces[] = $index;
         }
     }
     $conf = $this->getConfig();
     // Build list of variables
     $vars = array('wgLoadScript' => wfScript('load'), 'debug' => $context->getDebug(), 'skin' => $context->getSkin(), 'stylepath' => $conf->get('StylePath'), 'wgUrlProtocols' => wfUrlProtocols(), 'wgArticlePath' => $conf->get('ArticlePath'), 'wgScriptPath' => $conf->get('ScriptPath'), 'wgScriptExtension' => '.php', 'wgScript' => wfScript(), 'wgSearchType' => $conf->get('SearchType'), 'wgVariantArticlePath' => $conf->get('VariantArticlePath'), 'wgActionPaths' => (object) $conf->get('ActionPaths'), 'wgServer' => $conf->get('Server'), 'wgServerName' => $conf->get('ServerName'), 'wgUserLanguage' => $context->getLanguage(), 'wgContentLanguage' => $wgContLang->getCode(), 'wgTranslateNumerals' => $conf->get('TranslateNumerals'), 'wgVersion' => $conf->get('Version'), 'wgEnableAPI' => $conf->get('EnableAPI'), 'wgEnableWriteAPI' => $conf->get('EnableWriteAPI'), 'wgMainPageTitle' => $mainPage->getPrefixedText(), 'wgFormattedNamespaces' => $wgContLang->getFormattedNamespaces(), 'wgNamespaceIds' => $namespaceIds, 'wgContentNamespaces' => MWNamespace::getContentNamespaces(), 'wgSiteName' => $conf->get('Sitename'), 'wgDBname' => $conf->get('DBname'), 'wgExtraSignatureNamespaces' => $conf->get('ExtraSignatureNamespaces'), 'wgAvailableSkins' => Skin::getSkinNames(), 'wgExtensionAssetsPath' => $conf->get('ExtensionAssetsPath'), 'wgCookiePrefix' => $conf->get('CookiePrefix'), 'wgCookieDomain' => $conf->get('CookieDomain'), 'wgCookiePath' => $conf->get('CookiePath'), 'wgCookieExpiration' => $conf->get('CookieExpiration'), 'wgResourceLoaderMaxQueryLength' => $conf->get('ResourceLoaderMaxQueryLength'), 'wgCaseSensitiveNamespaces' => $caseSensitiveNamespaces, 'wgLegalTitleChars' => Title::convertByteClassToUnicodeClass(Title::legalChars()), 'wgResourceLoaderStorageVersion' => $conf->get('ResourceLoaderStorageVersion'), 'wgResourceLoaderStorageEnabled' => $conf->get('ResourceLoaderStorageEnabled'), 'wgResourceLoaderLegacyModules' => self::getLegacyModules(), 'wgForeignUploadTargets' => $conf->get('ForeignUploadTargets'), 'wgEnableUploads' => $conf->get('EnableUploads'));
     Hooks::run('ResourceLoaderGetConfigVars', array(&$vars));
     $this->configVars[$hash] = $vars;
     return $this->configVars[$hash];
 }
 /**
  * @param ResourceLoaderContext $context
  * @return array|int|mixed
  */
 public function getModifiedTime(ResourceLoaderContext $context)
 {
     $hash = $context->getHash();
     if (!isset($this->modifiedTime[$hash])) {
         $this->modifiedTime[$hash] = wfTimestamp(TS_UNIX, $context->getUserObj()->getTouched());
     }
     return $this->modifiedTime[$hash];
 }
 /**
  * @param $context ResourceLoaderContext
  * @return array|int|Mixed
  */
 public function getModifiedTime(ResourceLoaderContext $context)
 {
     $hash = $context->getHash();
     if (isset($this->modifiedTime[$hash])) {
         return $this->modifiedTime[$hash];
     }
     global $wgUser;
     return $this->modifiedTime[$hash] = wfTimestamp(TS_UNIX, $wgUser->getTouched());
 }
 public function getModifiedTime(ResourceLoaderContext $context)
 {
     $hash = $context->getHash();
     if (isset($this->modifiedTime[$hash])) {
         return $this->modifiedTime[$hash];
     }
     global $wgUser;
     if ($context->getUser() === $wgUser->getName()) {
         return $this->modifiedTime[$hash] = $wgUser->getTouched();
     } else {
         return 1;
     }
 }
 public function testTypicalRequest()
 {
     $ctx = new ResourceLoaderContext($this->getResourceLoader(), new FauxRequest(['debug' => 'false', 'lang' => 'zh', 'modules' => 'foo|foo.quux,baz,bar|baz.quux', 'only' => 'styles', 'skin' => 'fallback']));
     // Request parameters
     $this->assertEquals($ctx->getModules(), ['foo', 'foo.quux', 'foo.baz', 'foo.bar', 'baz.quux']);
     $this->assertEquals(false, $ctx->getDebug());
     $this->assertEquals('zh', $ctx->getLanguage());
     $this->assertEquals('styles', $ctx->getOnly());
     $this->assertEquals('fallback', $ctx->getSkin());
     $this->assertEquals(null, $ctx->getUser());
     // Misc
     $this->assertEquals('ltr', $ctx->getDirection());
     $this->assertEquals('zh|fallback|||styles|||||', $ctx->getHash());
 }
Пример #6
0
 /**
  * Construct an ResourceFileCache from a context
  * @param $context ResourceLoaderContext
  * @return ResourceFileCache
  */
 public static function newFromContext(ResourceLoaderContext $context)
 {
     $cache = new self();
     if ($context->getOnly() === 'styles') {
         $cache->mType = 'css';
     } else {
         $cache->mType = 'js';
     }
     $modules = array_unique($context->getModules());
     // remove duplicates
     sort($modules);
     // normalize the order (permutation => combination)
     $cache->mKey = sha1($context->getHash() . implode('|', $modules));
     if (count($modules) == 1) {
         $cache->mCacheWorthy = true;
         // won't take up much space
     }
     return $cache;
 }
 /**
  * @param $context ResourceLoaderContext
  * @return array|mixed
  */
 public function getModifiedTime(ResourceLoaderContext $context)
 {
     global $IP, $wgCacheEpoch;
     $hash = $context->getHash();
     if (isset($this->modifiedTime[$hash])) {
         return $this->modifiedTime[$hash];
     }
     // Call preloadModuleInfo() on ALL modules as we're about
     // to call getModifiedTime() on all of them
     $loader = $context->getResourceLoader();
     $loader->preloadModuleInfo($loader->getModuleNames(), $context);
     $this->modifiedTime[$hash] = filemtime("{$IP}/resources/startup.js");
     // ATTENTION!: Because of the line above, this is not going to cause
     // infinite recursion - think carefully before making changes to this
     // code!
     $time = wfTimestamp(TS_UNIX, $wgCacheEpoch);
     foreach ($loader->getModuleNames() as $name) {
         $module = $loader->getModule($name);
         $time = max($time, $module->getModifiedTime($context));
     }
     return $this->modifiedTime[$hash] = $time;
 }
 /**
  * Get the modification times of all titles that would be loaded for
  * a given context.
  * @param $context ResourceLoaderContext: Context object
  * @return array( prefixed DB key => UNIX timestamp ), nonexistent titles are dropped
  */
 protected function getTitleMtimes(ResourceLoaderContext $context)
 {
     $dbr = $this->getDB();
     if (!$dbr) {
         // We're dealing with a subclass that doesn't have a DB
         return array();
     }
     $hash = $context->getHash();
     if (isset($this->titleMtimes[$hash])) {
         return $this->titleMtimes[$hash];
     }
     $this->titleMtimes[$hash] = array();
     $batch = new LinkBatch();
     foreach ($this->getPages($context) as $titleText => $options) {
         $batch->addObj(Title::newFromText($titleText));
     }
     if (!$batch->isEmpty()) {
         $res = $dbr->select('page', array('page_namespace', 'page_title', 'page_touched'), $batch->constructSet('page', $dbr), __METHOD__);
         foreach ($res as $row) {
             $title = Title::makeTitle($row->page_namespace, $row->page_title);
             $this->titleMtimes[$hash][$title->getPrefixedDBkey()] = wfTimestamp(TS_UNIX, $row->page_touched);
         }
     }
     return $this->titleMtimes[$hash];
 }
 /**
  * Get the last modified timestamp of this module.
  *
  * Last modified timestamps are calculated from the highest last modified
  * timestamp of this module's constituent files as well as the files it
  * depends on. This function is context-sensitive, only performing
  * calculations on files relevant to the given language, skin and debug
  * mode.
  *
  * @param $context ResourceLoaderContext: Context in which to calculate
  *     the modified time
  * @return Integer: UNIX timestamp
  * @see ResourceLoaderModule::getFileDependencies
  */
 public function getModifiedTime(ResourceLoaderContext $context)
 {
     if (isset($this->modifiedTime[$context->getHash()])) {
         return $this->modifiedTime[$context->getHash()];
     }
     wfProfileIn(__METHOD__);
     $files = array();
     // Flatten style files into $files
     $styles = self::collateFilePathListByOption($this->styles, 'media', 'all');
     foreach ($styles as $styleFiles) {
         $files = array_merge($files, $styleFiles);
     }
     $skinFiles = self::tryForKey(self::collateFilePathListByOption($this->skinStyles, 'media', 'all'), $context->getSkin(), 'default');
     foreach ($skinFiles as $styleFiles) {
         $files = array_merge($files, $styleFiles);
     }
     // Final merge, this should result in a master list of dependent files
     $files = array_merge($files, $this->scripts, $context->getDebug() ? $this->debugScripts : array(), self::tryForKey($this->languageScripts, $context->getLanguage()), self::tryForKey($this->skinScripts, $context->getSkin(), 'default'), $this->loaderScripts);
     $files = array_map(array($this, 'getLocalPath'), $files);
     // File deps need to be treated separately because they're already prefixed
     $files = array_merge($files, $this->getFileDependencies($context->getSkin()));
     // If a module is nothing but a list of dependencies, we need to avoid
     // giving max() an empty array
     if (count($files) === 0) {
         wfProfileOut(__METHOD__);
         return $this->modifiedTime[$context->getHash()] = 1;
     }
     wfProfileIn(__METHOD__ . '-filemtime');
     $filesMtime = max(array_map(array(__CLASS__, 'safeFilemtime'), $files));
     wfProfileOut(__METHOD__ . '-filemtime');
     $this->modifiedTime[$context->getHash()] = max($filesMtime, $this->getMsgBlobMtime($context->getLanguage()));
     wfProfileOut(__METHOD__);
     return $this->modifiedTime[$context->getHash()];
 }
 /**
  * @param ResourceLoaderContext $context
  * @return array|mixed
  */
 public function getModifiedTime(ResourceLoaderContext $context)
 {
     global $IP, $wgCacheEpoch;
     $hash = $context->getHash();
     if (isset($this->modifiedTime[$hash])) {
         return $this->modifiedTime[$hash];
     }
     // Call preloadModuleInfo() on ALL modules as we're about
     // to call getModifiedTime() on all of them
     $loader = $context->getResourceLoader();
     $loader->preloadModuleInfo($loader->getModuleNames(), $context);
     $time = max(wfTimestamp(TS_UNIX, $wgCacheEpoch), filemtime("{$IP}/resources/src/startup.js"), $this->getHashMtime($context));
     // ATTENTION!: Because of the line below, this is not going to cause
     // infinite recursion - think carefully before making changes to this
     // code!
     // Pre-populate modifiedTime with something because the the loop over
     // all modules below includes the the startup module (this module).
     $this->modifiedTime[$hash] = 1;
     foreach ($loader->getModuleNames() as $name) {
         $module = $loader->getModule($name);
         $time = max($time, $module->getModifiedTime($context));
     }
     $this->modifiedTime[$hash] = $time;
     return $this->modifiedTime[$hash];
 }
 /**
  * Get an array of this module's resources. Ready for serving to the web.
  *
  * @since 1.26
  * @param ResourceLoaderContext $context
  * @return array
  */
 public function getModuleContent(ResourceLoaderContext $context)
 {
     $contextHash = $context->getHash();
     // Cache this expensive operation. This calls builds the scripts, styles, and messages
     // content which typically involves filesystem and/or database access.
     if (!array_key_exists($contextHash, $this->contents)) {
         $this->contents[$contextHash] = $this->buildContent($context);
     }
     return $this->contents[$contextHash];
 }
 /**
  * Get the modification times of all titles that would be loaded for
  * a given context.
  * Caches data from underlying layers.
  *
  * @param $context ResourceLoaderContext: Context object
  * @return array( prefixed DB key => UNIX timestamp ), nonexistent titles are dropped
  */
 protected function getTitleMtimes(ResourceLoaderContext $context)
 {
     $hash = $context->getHash();
     if (isset($this->titleMtimes[$hash])) {
         return $this->titleMtimes[$hash];
     }
     $this->titleMtimes[$hash] = $this->reallyGetTitleMtimes($context);
     return $this->titleMtimes[$hash];
 }
Пример #13
0
 /**
  * Get the modification times of all titles that would be loaded for
  * a given context.
  * Caches data from underlying layers.
  *
  * @param $context ResourceLoaderContext: Context object
  * @return array( prefixed DB key => UNIX timestamp ), nonexistent titles are dropped
  */
 protected function getTitleMtimes(ResourceLoaderContext $context)
 {
     global $wgMemc;
     wfProfileIn(__METHOD__);
     $hash = $context->getHash();
     if (isset($this->titleMtimes[$hash])) {
         wfProfileOut(__METHOD__);
         return $this->titleMtimes[$hash];
     }
     // Wikia change - begin - @author: wladek
     $memcKey = null;
     // silence PHPStorm
     if (!$context->getDebug()) {
         $memcKey = wfMemcKey('ResourceLoaderWikiModule', 'mtimes', $this->getName(), md5($hash));
         $mtimes = $wgMemc->get($memcKey);
         if (is_array($mtimes)) {
             wfProfileOut(__METHOD__);
             return $mtimes;
         }
     }
     // Wikia change - end
     $this->titleMtimes[$hash] = $this->reallyGetTitleMtimes($context);
     // Wikia change - begin - @author: wladek
     if (!$context->getDebug()) {
         $wgMemc->set($memcKey, $this->titleMtimes[$hash], self::MTIMES_CACHE_TTL);
     }
     // Wikia change - end
     wfProfileOut(__METHOD__);
     return $this->titleMtimes[$hash];
 }
 /**
  * Get the last modified timestamp of this module.
  *
  * Last modified timestamps are calculated from the highest last modified
  * timestamp of this module's constituent files as well as the files it
  * depends on. This function is context-sensitive, only performing
  * calculations on files relevant to the given language, skin and debug
  * mode.
  *
  * @param ResourceLoaderContext $context Context in which to calculate
  *     the modified time
  * @return int UNIX timestamp
  * @see ResourceLoaderModule::getFileDependencies
  */
 public function getModifiedTime(ResourceLoaderContext $context)
 {
     if (isset($this->modifiedTime[$context->getHash()])) {
         return $this->modifiedTime[$context->getHash()];
     }
     $files = array();
     // Flatten style files into $files
     $styles = self::collateFilePathListByOption($this->styles, 'media', 'all');
     foreach ($styles as $styleFiles) {
         $files = array_merge($files, $styleFiles);
     }
     $skinFiles = self::collateFilePathListByOption(self::tryForKey($this->skinStyles, $context->getSkin(), 'default'), 'media', 'all');
     foreach ($skinFiles as $styleFiles) {
         $files = array_merge($files, $styleFiles);
     }
     // Final merge, this should result in a master list of dependent files
     $files = array_merge($files, $this->scripts, $this->templates, $context->getDebug() ? $this->debugScripts : array(), $this->getLanguageScripts($context->getLanguage()), self::tryForKey($this->skinScripts, $context->getSkin(), 'default'), $this->loaderScripts);
     if ($this->skipFunction) {
         $files[] = $this->skipFunction;
     }
     $files = array_map(array($this, 'getLocalPath'), $files);
     // File deps need to be treated separately because they're already prefixed
     $files = array_merge($files, $this->getFileDependencies($context->getSkin()));
     // Filter out any duplicates from getFileDependencies() and others.
     // Most commonly introduced by compileLessFile(), which always includes the
     // entry point Less file we already know about.
     $files = array_values(array_unique($files));
     // If a module is nothing but a list of dependencies, we need to avoid
     // giving max() an empty array
     if (count($files) === 0) {
         $this->modifiedTime[$context->getHash()] = 1;
         return $this->modifiedTime[$context->getHash()];
     }
     $filesMtime = max(array_map(array(__CLASS__, 'safeFilemtime'), $files));
     $this->modifiedTime[$context->getHash()] = max($filesMtime, $this->getMsgBlobMtime($context->getLanguage()), $this->getDefinitionMtime($context));
     return $this->modifiedTime[$context->getHash()];
 }
 /**
  * Hook handler.
  *
  * If mode equals 'articles' in the request, bootstraps fake module and reinitialize
  * ResourceLoaderContext object to include the just-defined fake module.
  *
  * @param $resourceLoader ResourceLoader
  * @param $context ResourceLoaderContext
  * @return bool
  */
 public function onResourceLoaderBeforeRespond($resourceLoader, ResourceLoaderContext &$context)
 {
     /* @var $request WebRequest */
     $request = $context->getRequest();
     if ($request->getVal('mode') !== 'articles') {
         return true;
     }
     $only = $context->getOnly();
     $type = $this->getTypeByOnly($only);
     if (empty($type)) {
         return true;
     }
     $articles = $request->getVal('articles');
     $articles = explode('|', $articles);
     if (empty($articles)) {
         return true;
     }
     // prepare fake ResourceLoader module metadata
     $moduleName = md5(serialize(array($articles, $only, $context->getHash())));
     $moduleFullName = 'wikia.fake.articles.' . $moduleName;
     $moduleInfo = array('class' => 'ResourceLoaderCustomWikiModule', 'articles' => $this->parseArticleNames($articles), 'type' => $type);
     // register new fake module
     $resourceLoader->register($moduleFullName, $moduleInfo);
     // reinitialize ResourceLoader context
     $request->setVal('modules', $moduleFullName);
     $context = new ResourceLoaderContext($resourceLoader, $request);
     return true;
 }