public function getPages(ResourceLoaderContext $context)
 {
     $pages = array();
     $missingCallback = $context->getRequest()->getVal('missingCallback');
     if ($this->type) {
         foreach ($this->articles as $article) {
             $pageKey = $article['title'];
             $type = isset($article['type']) ? $article['type'] : $this->type;
             $pageInfo = array('type' => $type);
             if (isset($article['originalName'])) {
                 $pageInfo['originalName'] = $article['originalName'];
             }
             if ($missingCallback) {
                 $pageInfo['missingCallback'] = $missingCallback;
             }
             if (!empty($article['cityId'])) {
                 $pageIndex = 'fakename' . $this->id++;
                 $pageInfo['city_id'] = intval($article['cityId']);
                 $pageInfo['title'] = $article['title'];
                 // Unable to resolve wiki to cityId
             } else {
                 if (isset($article['cityId'])) {
                     $pageInfo['missing'] = true;
                 }
             }
             $pages[$pageKey] = $pageInfo;
         }
     }
     return $pages;
 }
 /**
  * @param ResourceLoaderContext $context
  * @return array List of pages
  */
 protected function getPages(ResourceLoaderContext $context)
 {
     $config = $this->getConfig();
     $user = $context->getUserObj();
     if ($user->isAnon()) {
         return [];
     }
     // Use localised/normalised variant to ensure $excludepage matches
     $userPage = $user->getUserPage()->getPrefixedDBkey();
     $pages = [];
     if ($config->get('AllowUserCss')) {
         $pages["{$userPage}/common.css"] = ['type' => 'style'];
         $pages["{$userPage}/" . $context->getSkin() . '.css'] = ['type' => 'style'];
     }
     // User group pages are maintained site-wide and enabled with site JS/CSS.
     if ($config->get('UseSiteCss')) {
         foreach ($user->getEffectiveGroups() as $group) {
             if ($group == '*') {
                 continue;
             }
             $pages["MediaWiki:Group-{$group}.css"] = ['type' => 'style'];
         }
     }
     // Hack for T28283: Allow excluding pages for preview on a CSS/JS page.
     // The excludepage parameter is set by OutputPage.
     $excludepage = $context->getRequest()->getVal('excludepage');
     if (isset($pages[$excludepage])) {
         unset($pages[$excludepage]);
     }
     return $pages;
 }
 /**
  * @param $context ResourceLoaderContext
  * @return array
  */
 protected function getPages(ResourceLoaderContext $context)
 {
     $username = $context->getUser();
     if ($username === null) {
         return array();
     }
     // Get the normalized title of the user's user page
     $userpageTitle = Title::makeTitleSafe(NS_USER, $username);
     if (!$userpageTitle instanceof Title) {
         return array();
     }
     $userpage = $userpageTitle->getPrefixedDBkey();
     // Needed so $excludepages works
     $pages = array("{$userpage}/common.js" => array('type' => 'script'), "{$userpage}/" . $context->getSkin() . '.js' => array('type' => 'script'), "{$userpage}/common.css" => array('type' => 'style'), "{$userpage}/" . $context->getSkin() . '.css' => array('type' => 'style'));
     // Hack for bug 26283: if we're on a preview page for a CSS/JS page,
     // we need to exclude that page from this module. In that case, the excludepage
     // parameter will be set to the name of the page we need to exclude.
     $excludepage = $context->getRequest()->getVal('excludepage');
     if (isset($pages[$excludepage])) {
         // This works because $excludepage is generated with getPrefixedDBkey(),
         // just like the keys in $pages[] above
         unset($pages[$excludepage]);
     }
     return $pages;
 }
 /**
  * Check if an RL request can be cached.
  * Caller is responsible for checking if any modules are private.
  * @param ResourceLoaderContext $context
  * @return bool
  */
 public static function useFileCache(ResourceLoaderContext $context)
 {
     global $wgUseFileCache, $wgDefaultSkin, $wgLanguageCode;
     if (!$wgUseFileCache) {
         return false;
     }
     // Get all query values
     $queryVals = $context->getRequest()->getValues();
     foreach ($queryVals as $query => $val) {
         if (in_array($query, array('modules', 'image', 'variant', 'version', '*'))) {
             // Use file cache regardless of the value of this parameter
             continue;
             // note: &* added as IE fix
         } elseif ($query === 'skin' && $val === $wgDefaultSkin) {
             continue;
         } elseif ($query === 'lang' && $val === $wgLanguageCode) {
             continue;
         } elseif ($query === 'only' && in_array($val, array('styles', 'scripts'))) {
             continue;
         } elseif ($query === 'debug' && $val === 'false') {
             continue;
         } elseif ($query === 'format' && $val === 'rasterized') {
             continue;
         }
         return false;
     }
     return true;
     // cacheable
 }
Пример #5
0
 /**
  * Check if an RL request can be cached.
  * Caller is responsible for checking if any modules are private.
  * @param $context ResourceLoaderContext
  * @return bool
  */
 public static function useFileCache(ResourceLoaderContext $context)
 {
     global $wgUseFileCache, $wgDefaultSkin, $wgLanguageCode;
     if (!$wgUseFileCache) {
         return false;
     }
     // Get all query values
     $queryVals = $context->getRequest()->getValues();
     foreach ($queryVals as $query => $val) {
         if ($query === 'modules' || $query === 'version' || $query === '*') {
             continue;
             // note: &* added as IE fix
         } elseif ($query === 'skin' && $val === $wgDefaultSkin) {
             continue;
         } elseif ($query === 'lang' && $val === $wgLanguageCode) {
             continue;
         } elseif ($query === 'only' && in_array($val, array('styles', 'scripts'))) {
             continue;
         } elseif ($query === 'debug' && $val === 'false') {
             continue;
         }
         return false;
     }
     return true;
     // cacheable
 }
 /**
  * Get list of pages used by this module
  *
  * @param ResourceLoaderContext $context
  * @return array List of pages
  */
 protected function getPages(ResourceLoaderContext $context)
 {
     $allowUserJs = $this->getConfig()->get('AllowUserJs');
     $allowUserCss = $this->getConfig()->get('AllowUserCss');
     if (!$allowUserJs && !$allowUserCss) {
         return array();
     }
     $user = $context->getUserObj();
     if (!$user || $user->isAnon()) {
         return array();
     }
     // Needed so $excludepages works
     $userPage = $user->getUserPage()->getPrefixedDBkey();
     $pages = array();
     if ($allowUserJs) {
         $pages["{$userPage}/common.js"] = array('type' => 'script');
         $pages["{$userPage}/" . $context->getSkin() . '.js'] = array('type' => 'script');
     }
     if ($allowUserCss) {
         $pages["{$userPage}/common.css"] = array('type' => 'style');
         $pages["{$userPage}/" . $context->getSkin() . '.css'] = array('type' => 'style');
     }
     // Hack for bug 26283: if we're on a preview page for a CSS/JS page,
     // we need to exclude that page from this module. In that case, the excludepage
     // parameter will be set to the name of the page we need to exclude.
     $excludepage = $context->getRequest()->getVal('excludepage');
     if (isset($pages[$excludepage])) {
         // This works because $excludepage is generated with getPrefixedDBkey(),
         // just like the keys in $pages[] above
         unset($pages[$excludepage]);
     }
     return $pages;
 }
 /**
  * Get registration code for all modules.
  *
  * @param ResourceLoaderContext $context object
  * @return string JavaScript code for registering all modules with the client loader
  */
 public static function getModuleRegistrations(ResourceLoaderContext $context)
 {
     global $wgCacheEpoch;
     wfProfileIn(__METHOD__);
     $resourceLoader = $context->getResourceLoader();
     $target = $context->getRequest()->getVal('target', 'desktop');
     $out = '';
     $registryData = array();
     // Get registry data
     foreach ($resourceLoader->getModuleNames() as $name) {
         $module = $resourceLoader->getModule($name);
         $moduleTargets = $module->getTargets();
         if (!in_array($target, $moduleTargets)) {
             continue;
         }
         // getModifiedTime() is supposed to return a UNIX timestamp, but it doesn't always
         // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX
         $moduleMtime = wfTimestamp(TS_UNIX, $module->getModifiedTime($context));
         $mtime = max($moduleMtime, wfTimestamp(TS_UNIX, $wgCacheEpoch));
         // FIXME: Convert to numbers, wfTimestamp always gives us stings, even for TS_UNIX
         $registryData[$name] = array('version' => $mtime, 'dependencies' => $module->getDependencies(), 'group' => $module->getGroup(), 'source' => $module->getSource(), 'loader' => $module->getLoaderScript());
     }
     // Register sources
     $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources());
     // Concatenate module loader scripts and figure out the different call
     // signatures for mw.loader.register
     $registrations = array();
     foreach ($registryData as $name => $data) {
         if ($data['loader'] !== false) {
             $out .= ResourceLoader::makeCustomLoaderScript($name, wfTimestamp(TS_ISO_8601_BASIC, $data['version']), $data['dependencies'], $data['group'], $data['source'], $data['loader']);
             continue;
         }
         if (!count($data['dependencies']) && $data['group'] === null && $data['source'] === 'local') {
             // Modules without dependencies, a group or a foreign source;
             // call mw.loader.register(name, timestamp)
             $registrations[] = array($name, $data['version']);
         } elseif ($data['group'] === null && $data['source'] === 'local') {
             // Modules with dependencies but no group or foreign source;
             // call mw.loader.register(name, timestamp, dependencies)
             $registrations[] = array($name, $data['version'], $data['dependencies']);
         } elseif ($data['source'] === 'local') {
             // Modules with a group but no foreign source;
             // call mw.loader.register(name, timestamp, dependencies, group)
             $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group']);
         } else {
             // Modules with a foreign source;
             // call mw.loader.register(name, timestamp, dependencies, group, source)
             $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source']);
         }
     }
     // Register modules
     $out .= ResourceLoader::makeLoaderRegisterScript($registrations);
     wfProfileOut(__METHOD__);
     return $out;
 }
 /**
  * Gets registration code for all modules
  *
  * @param $context ResourceLoaderContext object
  * @return String: JavaScript code for registering all modules with the client loader
  */
 public static function getModuleRegistrations(ResourceLoaderContext $context)
 {
     global $wgCacheEpoch;
     wfProfileIn(__METHOD__);
     $out = '';
     $registrations = array();
     $resourceLoader = $context->getResourceLoader();
     $target = $context->getRequest()->getVal('target', 'desktop');
     // Register sources
     $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources());
     // Register modules
     foreach ($resourceLoader->getModuleNames() as $name) {
         $module = $resourceLoader->getModule($name);
         $moduleTargets = $module->getTargets();
         if (!in_array($target, $moduleTargets)) {
             continue;
         }
         $deps = $module->getDependencies();
         $group = $module->getGroup();
         $source = $module->getSource();
         // Support module loader scripts
         $loader = $module->getLoaderScript();
         if ($loader !== false) {
             $version = wfTimestamp(TS_ISO_8601_BASIC, $module->getModifiedTime($context));
             $out .= ResourceLoader::makeCustomLoaderScript($name, $version, $deps, $group, $source, $loader);
             continue;
         }
         // Automatically register module
         // getModifiedTime() is supposed to return a UNIX timestamp, but it doesn't always
         // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX
         $moduleMtime = wfTimestamp(TS_UNIX, $module->getModifiedTime($context));
         $mtime = max($moduleMtime, wfTimestamp(TS_UNIX, $wgCacheEpoch));
         // Modules without dependencies, a group or a foreign source pass two arguments (name, timestamp) to
         // mw.loader.register()
         if (!count($deps) && $group === null && $source === 'local') {
             $registrations[] = array($name, $mtime);
         } elseif ($group === null && $source === 'local') {
             $registrations[] = array($name, $mtime, $deps);
         } elseif ($source === 'local') {
             $registrations[] = array($name, $mtime, $deps, $group);
         } else {
             $registrations[] = array($name, $mtime, $deps, $group, $source);
         }
     }
     $out .= ResourceLoader::makeLoaderRegisterScript($registrations);
     wfProfileOut(__METHOD__);
     return $out;
 }
 /**
  * Get list of pages used by this module
  *
  * @param ResourceLoaderContext $context
  * @return array List of pages
  */
 protected function getPages(ResourceLoaderContext $context)
 {
     $config = $this->getConfig();
     $user = $context->getUserObj();
     if ($user->isAnon()) {
         return [];
     }
     // Use localised/normalised variant to ensure $excludepage matches
     $userPage = $user->getUserPage()->getPrefixedDBkey();
     $pages = [];
     if ($config->get('AllowUserJs')) {
         $pages["{$userPage}/common.js"] = ['type' => 'script'];
         $pages["{$userPage}/" . $context->getSkin() . '.js'] = ['type' => 'script'];
     }
     if ($config->get('AllowUserCss')) {
         $pages["{$userPage}/common.css"] = ['type' => 'style'];
         $pages["{$userPage}/" . $context->getSkin() . '.css'] = ['type' => 'style'];
     }
     $useSiteJs = $config->get('UseSiteJs');
     $useSiteCss = $config->get('UseSiteCss');
     // User group pages are maintained site-wide and enabled with site JS/CSS.
     if ($useSiteJs || $useSiteCss) {
         foreach ($user->getEffectiveGroups() as $group) {
             if ($group == '*') {
                 continue;
             }
             if ($useSiteJs) {
                 $pages["MediaWiki:Group-{$group}.js"] = ['type' => 'script'];
             }
             if ($useSiteCss) {
                 $pages["MediaWiki:Group-{$group}.css"] = ['type' => 'style'];
             }
         }
     }
     // Hack for bug 26283: if we're on a preview page for a CSS/JS page,
     // we need to exclude that page from this module. In that case, the excludepage
     // parameter will be set to the name of the page we need to exclude.
     $excludepage = $context->getRequest()->getVal('excludepage');
     if (isset($pages[$excludepage])) {
         // This works because $excludepage is generated with getPrefixedDBkey(),
         // just like the keys in $pages[] above
         unset($pages[$excludepage]);
     }
     return $pages;
 }
 /**
  * Customize caching policy for RL modules
  *
  * * cache "static" modules for 30 days when cb param in the URL matches $wgStyleVersion
  * * cache "dynamic" modules for 30 days when version param is present in the URL and matches $mtime timestamp
  * * otherwise fallback to caching for 5 minutes
  *
  * @see BAC-1241
  *
  * @param ResourceLoader $rl
  * @param ResourceLoaderContext $context
  * @param $mtime int UNIX timestamp from module(s) calculated from filesystem
  * @param $maxage int UNIX timestamp for maxage
  * @param $smaxage int UNIX timestamp for smaxage
  * @return bool it's a hook
  */
 public static function onResourceLoaderModifyMaxAge(ResourceLoader $rl, ResourceLoaderContext $context, $mtime, &$maxage, &$smaxage)
 {
     global $wgStyleVersion, $wgResourceLoaderMaxage;
     // parse cb and version provided as URL parameters
     // version%3D123456-20140220T090000Z
     // cb%3D123456%26
     $version = explode('-', (string) $context->getVersion(), 2);
     if (count($version) === 2) {
         list($cb, $ts) = $version;
         $ts = strtotime($ts);
         // convert MW to UNIX timestamp
     } else {
         $cb = $context->getRequest()->getVal('cb', false);
         $ts = false;
     }
     // check if at least one of required modules serves dynamic content
     $hasDynamicModule = false;
     $modules = $context->getModules();
     foreach ($modules as $moduleName) {
         if (!$rl->getModule($moduleName) instanceof ResourceLoaderFileModule) {
             $hasDynamicModule = true;
             break;
         }
     }
     if ($hasDynamicModule) {
         // use long TTL when version value matches $mtime passed to the hook
         $useLongTTL = !empty($ts) && $ts <= $mtime;
     } else {
         // use long TTL when cache buster value from URL matches $wgStyleVersion
         $useLongTTL = !empty($cb) && $cb <= $wgStyleVersion;
     }
     // modify caching times
     if (!$useLongTTL) {
         WikiaLogger::instance()->info('rl.shortTTL', ['modules' => join(',', $modules), 'cb' => $cb, 'ts' => $ts]);
     }
     $cachingTimes = $wgResourceLoaderMaxage[$useLongTTL ? 'versioned' : 'unversioned'];
     $maxage = $cachingTimes['client'];
     $smaxage = $cachingTimes['server'];
     return true;
 }
 /**
  * Get registration code for all modules.
  *
  * @param ResourceLoaderContext $context
  * @return string JavaScript code for registering all modules with the client loader
  */
 public function getModuleRegistrations(ResourceLoaderContext $context)
 {
     $resourceLoader = $context->getResourceLoader();
     $target = $context->getRequest()->getVal('target', 'desktop');
     // Bypass target filter if this request is Special:JavaScriptTest.
     // To prevent misuse in production, this is only allowed if testing is enabled server-side.
     $byPassTargetFilter = $this->getConfig()->get('EnableJavaScriptTest') && $target === 'test';
     $out = '';
     $registryData = [];
     // Get registry data
     foreach ($resourceLoader->getModuleNames() as $name) {
         $module = $resourceLoader->getModule($name);
         $moduleTargets = $module->getTargets();
         if (!$byPassTargetFilter && !in_array($target, $moduleTargets)) {
             continue;
         }
         if ($module->isRaw()) {
             // Don't register "raw" modules (like 'jquery' and 'mediawiki') client-side because
             // depending on them is illegal anyway and would only lead to them being reloaded
             // causing any state to be lost (like jQuery plugins, mw.config etc.)
             continue;
         }
         $versionHash = $module->getVersionHash($context);
         if (strlen($versionHash) !== 8) {
             $context->getLogger()->warning("Module '{module}' produced an invalid version hash: '{version}'.", ['module' => $name, 'version' => $versionHash]);
             // Module implementation either broken or deviated from ResourceLoader::makeHash
             // Asserted by tests/phpunit/structure/ResourcesTest.
             $versionHash = ResourceLoader::makeHash($versionHash);
         }
         $skipFunction = $module->getSkipFunction();
         if ($skipFunction !== null && !ResourceLoader::inDebugMode()) {
             $skipFunction = ResourceLoader::filter('minify-js', $skipFunction);
         }
         $registryData[$name] = ['version' => $versionHash, 'dependencies' => $module->getDependencies($context), 'group' => $module->getGroup(), 'source' => $module->getSource(), 'skip' => $skipFunction];
     }
     self::compileUnresolvedDependencies($registryData);
     // Register sources
     $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources());
     // Figure out the different call signatures for mw.loader.register
     $registrations = [];
     foreach ($registryData as $name => $data) {
         // Call mw.loader.register(name, version, dependencies, group, source, skip)
         $registrations[] = [$name, $data['version'], $data['dependencies'], $data['group'], $data['source'] === 'local' ? null : $data['source'], $data['skip']];
     }
     // Register modules
     $out .= "\n" . ResourceLoader::makeLoaderRegisterScript($registrations);
     return $out;
 }
Пример #12
0
 /**
  * Add X-Served-By and X-Backend-Response-Time response headers to ResourceLoader
  *
  * See BAC-1319 for details
  *
  * @param ResourceLoader $rl
  * @param ResourceLoaderContext $context
  * @return bool
  * @author macbre
  */
 static function onResourceLoaderAfterRespond(ResourceLoader $rl, ResourceLoaderContext $context)
 {
     self::addExtraHeaders($context->getRequest()->response());
     return true;
 }
Пример #13
0
 /**
  * Respond with 304 Last Modified if appropiate.
  *
  * If there's an If-Modified-Since header, respond with a 304 appropriately
  * and clear out the output buffer. If the client cache is too old then do nothing.
  *
  * @param $context ResourceLoaderContext
  * @param string $mtime The TS_MW timestamp to check the header against
  * @return bool True if 304 header sent and output handled
  */
 protected function tryRespondLastModified(ResourceLoaderContext $context, $mtime)
 {
     // If there's an If-Modified-Since header, respond with a 304 appropriately
     // Some clients send "timestamp;length=123". Strip the part after the first ';'
     // so we get a valid timestamp.
     $ims = $context->getRequest()->getHeader('If-Modified-Since');
     // Never send 304s in debug mode
     if ($ims !== false && !$context->getDebug()) {
         $imsTS = strtok($ims, ';');
         if ($mtime <= wfTimestamp(TS_UNIX, $imsTS)) {
             // There's another bug in ob_gzhandler (see also the comment at
             // the top of this function) that causes it to gzip even empty
             // responses, meaning it's impossible to produce a truly empty
             // response (because the gzip header is always there). This is
             // a problem because 304 responses have to be completely empty
             // per the HTTP spec, and Firefox behaves buggily when they're not.
             // See also http://bugs.php.net/bug.php?id=51579
             // To work around this, we tear down all output buffering before
             // sending the 304.
             wfResetOutputBuffers(true);
             header('HTTP/1.0 304 Not Modified');
             header('Status: 304 Not Modified');
             return true;
         }
     }
     return false;
 }
 public function getRequest()
 {
     return $this->context->getRequest();
 }
Пример #15
0
 private static function makeContext(ResourceLoaderContext $mainContext, $group, $type, array $extraQuery = [])
 {
     // Create new ResourceLoaderContext so that $extraQuery may trigger isRaw().
     $req = new FauxRequest(array_merge($mainContext->getRequest()->getValues(), $extraQuery));
     // Set 'only' if not combined
     $req->setVal('only', $type === ResourceLoaderModule::TYPE_COMBINED ? null : $type);
     // Remove user parameter in most cases
     if ($group !== 'user' && $group !== 'private') {
         $req->setVal('user', null);
     }
     $context = new ResourceLoaderContext($mainContext->getResourceLoader(), $req);
     // Allow caller to setVersion() and setModules()
     return new DerivativeResourceLoaderContext($context);
 }
 /**
  * Get registration code for all modules.
  *
  * @param ResourceLoaderContext $context
  * @return string JavaScript code for registering all modules with the client loader
  */
 public function getModuleRegistrations(ResourceLoaderContext $context)
 {
     wfProfileIn(__METHOD__);
     $resourceLoader = $context->getResourceLoader();
     $target = $context->getRequest()->getVal('target', 'desktop');
     $out = '';
     $registryData = array();
     // Get registry data
     foreach ($resourceLoader->getModuleNames() as $name) {
         $module = $resourceLoader->getModule($name);
         $moduleTargets = $module->getTargets();
         if (!in_array($target, $moduleTargets)) {
             continue;
         }
         if ($module->isRaw()) {
             // Don't register "raw" modules (like 'jquery' and 'mediawiki') client-side because
             // depending on them is illegal anyway and would only lead to them being reloaded
             // causing any state to be lost (like jQuery plugins, mw.config etc.)
             continue;
         }
         // getModifiedTime() is supposed to return a UNIX timestamp, but it doesn't always
         // seem to do that, and custom implementations might forget. Coerce it to TS_UNIX
         $moduleMtime = wfTimestamp(TS_UNIX, $module->getModifiedTime($context));
         $mtime = max($moduleMtime, wfTimestamp(TS_UNIX, $this->getConfig()->get('CacheEpoch')));
         // FIXME: Convert to numbers, wfTimestamp always gives us stings, even for TS_UNIX
         $skipFunction = $module->getSkipFunction();
         if ($skipFunction !== null && !ResourceLoader::inDebugMode()) {
             $skipFunction = $resourceLoader->filter('minify-js', $skipFunction, false);
         }
         $registryData[$name] = array('version' => $mtime, 'dependencies' => $module->getDependencies(), 'group' => $module->getGroup(), 'source' => $module->getSource(), 'loader' => $module->getLoaderScript(), 'skip' => $skipFunction);
     }
     self::compileUnresolvedDependencies($registryData);
     // Register sources
     $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources());
     // Concatenate module loader scripts and figure out the different call
     // signatures for mw.loader.register
     $registrations = array();
     foreach ($registryData as $name => $data) {
         if ($data['loader'] !== false) {
             $out .= ResourceLoader::makeCustomLoaderScript($name, wfTimestamp(TS_ISO_8601_BASIC, $data['version']), $data['dependencies'], $data['group'], $data['source'], $data['loader']);
             continue;
         }
         if (!count($data['dependencies']) && $data['group'] === null && $data['source'] === 'local' && $data['skip'] === null) {
             // Modules with no dependencies, group, foreign source or skip function;
             // call mw.loader.register(name, timestamp)
             $registrations[] = array($name, $data['version']);
         } elseif ($data['group'] === null && $data['source'] === 'local' && $data['skip'] === null) {
             // Modules with dependencies but no group, foreign source or skip function;
             // call mw.loader.register(name, timestamp, dependencies)
             $registrations[] = array($name, $data['version'], $data['dependencies']);
         } elseif ($data['source'] === 'local' && $data['skip'] === null) {
             // Modules with a group but no foreign source or skip function;
             // call mw.loader.register(name, timestamp, dependencies, group)
             $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group']);
         } elseif ($data['skip'] === null) {
             // Modules with a foreign source but no skip function;
             // call mw.loader.register(name, timestamp, dependencies, group, source)
             $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source']);
         } else {
             // Modules with a skip function;
             // call mw.loader.register(name, timestamp, dependencies, group, source, skip)
             $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source'], $data['skip']);
         }
     }
     // Register modules
     $out .= ResourceLoader::makeLoaderRegisterScript($registrations);
     wfProfileOut(__METHOD__);
     return $out;
 }
 /**
  * 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;
 }
Пример #18
0
 /**
  * Get the URL or URLs to load for this module's CSS in debug mode.
  * The default behavior is to return a load.php?only=styles URL for
  * the module, but file-based modules will want to override this to
  * load the files directly. See also getScriptURLsForDebug()
  *
  * @param $context ResourceLoaderContext: Context object
  * @return Array: array( mediaType => array( URL1, URL2, ... ), ... )
  */
 public function getStyleURLsForDebug(ResourceLoaderContext $context)
 {
     $url = ResourceLoader::makeLoaderURL(array($this->getName()), $context->getLanguage(), $context->getSkin(), $context->getUser(), $context->getVersion(), true, 'styles', $context->getRequest()->getBool('printable'), $context->getRequest()->getBool('handheld'));
     return array('all' => array($url));
 }
 protected function getFileContents($fileName, ResourceLoaderContext $context)
 {
     switch (self::getFileType($fileName)) {
         case self::FILE_TYPE_REGULAR:
             return file_get_contents($fileName);
             break;
         case self::FILE_TYPE_SASS:
             $sass = new SassService($fileName);
             $params = $context->getRequest()->getVal('sass_params');
             $params = !empty($params) ? FormatJson::decode($params, true) : array();
             return $sass->getContents($params);
             break;
     }
 }
 public function testAccessors()
 {
     $ctx = new ResourceLoaderContext($this->getResourceLoader(), new FauxRequest([]));
     $this->assertInstanceOf(WebRequest::class, $ctx->getRequest());
     $this->assertInstanceOf(\Psr\Log\LoggerInterface::class, $ctx->getLogger());
 }
Пример #21
0
 /**
  * If there's an If-Modified-Since header, respond with a 304 appropriately
  * and clear out the output buffer. If the client cache is too old then do nothing.
  * @param $context ResourceLoaderContext
  * @param $mtime string The TS_MW timestamp to check the header against
  * @return bool True iff 304 header sent and output handled
  */
 protected function tryRespondLastModified(ResourceLoaderContext $context, $mtime)
 {
     // If there's an If-Modified-Since header, respond with a 304 appropriately
     // Some clients send "timestamp;length=123". Strip the part after the first ';'
     // so we get a valid timestamp.
     $ims = $context->getRequest()->getHeader('If-Modified-Since');
     // Never send 304s in debug mode
     if ($ims !== false && !$context->getDebug()) {
         $imsTS = strtok($ims, ';');
         if ($mtime <= wfTimestamp(TS_UNIX, $imsTS)) {
             // There's another bug in ob_gzhandler (see also the comment at
             // the top of this function) that causes it to gzip even empty
             // responses, meaning it's impossible to produce a truly empty
             // response (because the gzip header is always there). This is
             // a problem because 304 responses have to be completely empty
             // per the HTTP spec, and Firefox behaves buggily when they're not.
             // See also http://bugs.php.net/bug.php?id=51579
             // To work around this, we tear down all output buffering before
             // sending the 304.
             // On some setups, ob_get_level() doesn't seem to go down to zero
             // no matter how often we call ob_get_clean(), so instead of doing
             // the more intuitive while ( ob_get_level() > 0 ) ob_get_clean();
             // we have to be safe here and avoid an infinite loop.
             for ($i = 0; $i < ob_get_level(); $i++) {
                 ob_end_clean();
             }
             header('HTTP/1.0 304 Not Modified');
             header('Status: 304 Not Modified');
             return true;
         }
     }
     return false;
 }
 /**
  * Get registration code for all modules.
  *
  * @param ResourceLoaderContext $context
  * @return string JavaScript code for registering all modules with the client loader
  */
 public function getModuleRegistrations(ResourceLoaderContext $context)
 {
     $resourceLoader = $context->getResourceLoader();
     $target = $context->getRequest()->getVal('target', 'desktop');
     $out = '';
     $registryData = array();
     // Get registry data
     foreach ($resourceLoader->getModuleNames() as $name) {
         $module = $resourceLoader->getModule($name);
         $moduleTargets = $module->getTargets();
         if (!in_array($target, $moduleTargets)) {
             continue;
         }
         if ($module->isRaw()) {
             // Don't register "raw" modules (like 'jquery' and 'mediawiki') client-side because
             // depending on them is illegal anyway and would only lead to them being reloaded
             // causing any state to be lost (like jQuery plugins, mw.config etc.)
             continue;
         }
         $versionHash = $module->getVersionHash($context);
         if (strlen($versionHash) !== 8) {
             // Module implementation either broken or deviated from ResourceLoader::makeHash
             // Asserted by tests/phpunit/structure/ResourcesTest.
             $versionHash = ResourceLoader::makeHash($versionHash);
         }
         $skipFunction = $module->getSkipFunction();
         if ($skipFunction !== null && !ResourceLoader::inDebugMode()) {
             $skipFunction = $resourceLoader->filter('minify-js', $skipFunction, false);
         }
         $registryData[$name] = array('version' => $versionHash, 'dependencies' => $module->getDependencies($context), 'group' => $module->getGroup(), 'source' => $module->getSource(), 'loader' => $module->getLoaderScript(), 'skip' => $skipFunction);
     }
     self::compileUnresolvedDependencies($registryData);
     // Register sources
     $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources());
     // Concatenate module loader scripts and figure out the different call
     // signatures for mw.loader.register
     $registrations = array();
     foreach ($registryData as $name => $data) {
         if ($data['loader'] !== false) {
             $out .= ResourceLoader::makeCustomLoaderScript($name, $data['version'], $data['dependencies'], $data['group'], $data['source'], $data['loader']);
             continue;
         }
         // Call mw.loader.register(name, version, dependencies, group, source, skip)
         $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source'] === 'local' ? null : $data['source'], $data['skip']);
     }
     // Register modules
     $out .= "\n" . ResourceLoader::makeLoaderRegisterScript($registrations);
     return $out;
 }
Пример #23
0
 /**
  * Helper for createLoaderURL()
  *
  * @since 1.24
  * @see makeLoaderQuery
  * @param ResourceLoaderContext $context
  * @param array $extraQuery
  * @return array
  */
 public static function createLoaderQuery(ResourceLoaderContext $context, $extraQuery = array())
 {
     return self::makeLoaderQuery($context->getModules(), $context->getLanguage(), $context->getSkin(), $context->getUser(), $context->getVersion(), $context->getDebug(), $context->getOnly(), $context->getRequest()->getBool('printable'), $context->getRequest()->getBool('handheld'), $extraQuery);
 }
 /**
  * Get registration code for all modules.
  *
  * @param ResourceLoaderContext $context
  * @return string JavaScript code for registering all modules with the client loader
  */
 public function getModuleRegistrations(ResourceLoaderContext $context)
 {
     $resourceLoader = $context->getResourceLoader();
     $target = $context->getRequest()->getVal('target', 'desktop');
     $out = '';
     $registryData = array();
     // Get registry data
     foreach ($resourceLoader->getModuleNames() as $name) {
         $module = $resourceLoader->getModule($name);
         $moduleTargets = $module->getTargets();
         if (!in_array($target, $moduleTargets)) {
             continue;
         }
         if ($module->isRaw()) {
             // Don't register "raw" modules (like 'jquery' and 'mediawiki') client-side because
             // depending on them is illegal anyway and would only lead to them being reloaded
             // causing any state to be lost (like jQuery plugins, mw.config etc.)
             continue;
         }
         // Coerce module timestamp to UNIX timestamp.
         // getModifiedTime() is supposed to return a UNIX timestamp, but custom implementations
         // might forget. TODO: Maybe emit warning?
         $moduleMtime = wfTimestamp(TS_UNIX, $module->getModifiedTime($context));
         $skipFunction = $module->getSkipFunction();
         if ($skipFunction !== null && !ResourceLoader::inDebugMode()) {
             $skipFunction = $resourceLoader->filter('minify-js', $skipFunction, false);
         }
         $mtime = max($moduleMtime, wfTimestamp(TS_UNIX, $this->getConfig()->get('CacheEpoch')));
         $registryData[$name] = array('version' => (int) $mtime, 'dependencies' => $module->getDependencies(), 'group' => $module->getGroup(), 'source' => $module->getSource(), 'loader' => $module->getLoaderScript(), 'skip' => $skipFunction);
     }
     self::compileUnresolvedDependencies($registryData);
     // Register sources
     $out .= ResourceLoader::makeLoaderSourcesScript($resourceLoader->getSources());
     // Concatenate module loader scripts and figure out the different call
     // signatures for mw.loader.register
     $registrations = array();
     foreach ($registryData as $name => $data) {
         if ($data['loader'] !== false) {
             $out .= ResourceLoader::makeCustomLoaderScript($name, $data['version'], $data['dependencies'], $data['group'], $data['source'], $data['loader']);
             continue;
         }
         // Call mw.loader.register(name, timestamp, dependencies, group, source, skip)
         $registrations[] = array($name, $data['version'], $data['dependencies'], $data['group'], $data['source'] === 'local' ? null : $data['source'], $data['skip']);
     }
     // Register modules
     $out .= ResourceLoader::makeLoaderRegisterScript($registrations);
     return $out;
 }