/**
  * @covers SkinFactory::getSkinNames
  */
 public function testGetSkinNames()
 {
     $factory = new SkinFactory();
     // A fake callback we can use that will never be called
     $callback = function () {
         // NOP
     };
     $factory->register('skin1', 'Skin1', $callback);
     $factory->register('skin2', 'Skin2', $callback);
     $names = $factory->getSkinNames();
     $this->assertArrayHasKey('skin1', $names);
     $this->assertArrayHasKey('skin2', $names);
     $this->assertEquals('Skin1', $names['skin1']);
     $this->assertEquals('Skin2', $names['skin2']);
 }
Example #2
0
 public function execute()
 {
     $params = $this->extractRequestParams();
     $modules = array();
     foreach ($params['modules'] as $path) {
         $modules[] = $this->getModuleFromPath($path);
     }
     // Get the help
     $context = new DerivativeContext($this->getMain()->getContext());
     $context->setSkin(SkinFactory::getDefaultInstance()->makeSkin('apioutput'));
     $context->setLanguage($this->getMain()->getLanguage());
     $context->setTitle(SpecialPage::getTitleFor('ApiHelp'));
     $out = new OutputPage($context);
     $out->setCopyrightUrl('https://www.mediawiki.org/wiki/Special:MyLanguage/Copyright');
     $context->setOutput($out);
     self::getHelp($context, $modules, $params);
     // Grab the output from the skin
     ob_start();
     $context->getOutput()->output();
     $html = ob_get_clean();
     $result = $this->getResult();
     if ($params['wrap']) {
         $data = array('mime' => 'text/html', 'help' => $html);
         ApiResult::setSubelementsList($data, 'help');
         $result->addValue(null, $this->getModuleName(), $data);
     } else {
         $result->reset();
         $result->addValue(null, 'text', $html, ApiResult::NO_SIZE_CHECK);
         $result->addValue(null, 'mime', 'text/html', ApiResult::NO_SIZE_CHECK);
     }
 }
 public static function getDefaultInstance()
 {
     if (!self::$self) {
         self::$self = new self();
     }
     return self::$self;
 }
 protected function setUp()
 {
     parent::setUp();
     // The return value of the closure shouldn't matter since this test should
     // never call it
     SkinFactory::getDefaultInstance()->register('fakeskin', 'FakeSkin', function () {
     });
 }
Example #5
0
 /**
  * Inform the user why they are seeing this skin.
  *
  * @return string
  */
 private function buildHelpfulInformationMessage()
 {
     $defaultSkin = $this->config->get('DefaultSkin');
     $installedSkins = $this->findInstalledSkins();
     $enabledSkins = SkinFactory::getDefaultInstance()->getSkinNames();
     $enabledSkins = array_change_key_case($enabledSkins, CASE_LOWER);
     if ($installedSkins) {
         $skinsInstalledText = array();
         $skinsInstalledSnippet = array();
         foreach ($installedSkins as $skin) {
             $normalizedKey = strtolower($skin);
             $isEnabled = array_key_exists($normalizedKey, $enabledSkins);
             if ($isEnabled) {
                 $skinsInstalledText[] = $this->getMsg('default-skin-not-found-row-enabled')->params($normalizedKey, $skin)->plain();
             } else {
                 $skinsInstalledText[] = $this->getMsg('default-skin-not-found-row-disabled')->params($normalizedKey, $skin)->plain();
                 $skinsInstalledSnippet[] = "require_once \"\$IP/skins/{$skin}/{$skin}.php\";";
             }
         }
         return $this->getMsg('default-skin-not-found')->params($defaultSkin, implode("\n", $skinsInstalledText), implode("\n", $skinsInstalledSnippet))->parseAsBlock();
     } else {
         return $this->getMsg('default-skin-not-found-no-skins')->params($defaultSkin)->parseAsBlock();
     }
 }
Example #6
0
 /**
  * Finish printing and output buffered data.
  */
 public function closePrinter()
 {
     if ($this->mDisabled) {
         return;
     }
     $mime = $this->getMimeType();
     if ($this->getIsHtml() && $mime !== null) {
         $format = $this->getFormat();
         $lcformat = strtolower($format);
         $result = $this->getBuffer();
         $context = new DerivativeContext($this->getMain());
         $context->setSkin(SkinFactory::getDefaultInstance()->makeSkin('apioutput'));
         $context->setTitle(SpecialPage::getTitleFor('ApiHelp'));
         $out = new OutputPage($context);
         $context->setOutput($out);
         $out->addModuleStyles('mediawiki.apipretty');
         $out->setPageTitle($context->msg('api-format-title'));
         if (!$this->getIsWrappedHtml()) {
             // When the format without suffix 'fm' is defined, there is a non-html version
             if ($this->getMain()->getModuleManager()->isDefined($lcformat, 'format')) {
                 $msg = $context->msg('api-format-prettyprint-header')->params($format, $lcformat);
             } else {
                 $msg = $context->msg('api-format-prettyprint-header-only-html')->params($format);
             }
             $header = $msg->parseAsBlock();
             $out->addHTML(Html::rawElement('div', ['class' => 'api-pretty-header'], ApiHelp::fixHelpLinks($header)));
         }
         if (Hooks::run('ApiFormatHighlight', [$context, $result, $mime, $format])) {
             $out->addHTML(Html::element('pre', ['class' => 'api-pretty-content'], $result));
         }
         if ($this->getIsWrappedHtml()) {
             // This is a special output mode mainly intended for ApiSandbox use
             $time = microtime(true) - $this->getConfig()->get('RequestTime');
             $json = FormatJson::encode(['html' => $out->getHTML(), 'modules' => array_values(array_unique(array_merge($out->getModules(), $out->getModuleScripts(), $out->getModuleStyles()))), 'time' => round($time * 1000)], false, FormatJson::ALL_OK);
             // Bug 66776: wfMangleFlashPolicy() is needed to avoid a nasty bug in
             // Flash, but what it does isn't friendly for the API, so we need to
             // work around it.
             if (preg_match('/\\<\\s*cross-domain-policy\\s*\\>/i', $json)) {
                 $json = preg_replace('/\\<(\\s*cross-domain-policy\\s*)\\>/i', '\\u003C$1\\u003E', $json);
             }
             echo $json;
         } else {
             // API handles its own clickjacking protection.
             // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
             $out->allowClickjacking();
             $out->output();
         }
     } else {
         // For non-HTML output, clear all errors that might have been
         // displayed if display_errors=On
         ob_clean();
         echo $this->getBuffer();
     }
 }
Example #7
0
    // @codingStandardsIgnoreStart Generic.CodeAnalysis.ForLoopWithTestFunctionCall.NotAllowed
    for ($i = 0; $i < count($wgRCLinkDays); $i++) {
        // @codingStandardsIgnoreEnd
        if ($wgRCLinkDays[$i] >= $wgRCMaxAge / (3600 * 24)) {
            $wgRCLinkDays = array_slice($wgRCLinkDays, 0, $i + 1, false);
            break;
        }
    }
}
if ($wgSkipSkin) {
    $wgSkipSkins[] = $wgSkipSkin;
}
// Register skins
// Use a closure to avoid leaking into global state
call_user_func(function () use($wgValidSkinNames) {
    $factory = SkinFactory::getDefaultInstance();
    foreach ($wgValidSkinNames as $name => $skin) {
        $factory->register($name, $skin, function () use($name, $skin) {
            $class = "Skin{$skin}";
            return new $class($name);
        });
    }
    // Register a hidden "fallback" skin
    $factory->register('fallback', 'Fallback', function () {
        return new SkinFallback();
    });
    // Register a hidden skin for api output
    $factory->register('apioutput', 'ApiOutput', function () {
        return new SkinApi();
    });
});
Example #8
0
 /**
  * Get the Skin object
  *
  * @return Skin
  */
 public function getSkin()
 {
     if ($this->skin === null) {
         $skin = null;
         Hooks::run('RequestContextCreateSkin', [$this, &$skin]);
         $factory = SkinFactory::getDefaultInstance();
         // If the hook worked try to set a skin from it
         if ($skin instanceof Skin) {
             $this->skin = $skin;
         } elseif (is_string($skin)) {
             // Normalize the key, just in case the hook did something weird.
             $normalized = Skin::normalizeKey($skin);
             $this->skin = $factory->makeSkin($normalized);
         }
         // If this is still null (the hook didn't run or didn't work)
         // then go through the normal processing to load a skin
         if ($this->skin === null) {
             if (!in_array('skin', $this->getConfig()->get('HiddenPrefs'))) {
                 # get the user skin
                 $userSkin = $this->getUser()->getOption('skin');
                 $userSkin = $this->getRequest()->getVal('useskin', $userSkin);
             } else {
                 # if we're not allowing users to override, then use the default
                 $userSkin = $this->getConfig()->get('DefaultSkin');
             }
             // Normalize the key in case the user is passing gibberish
             // or has old preferences (bug 69566).
             $normalized = Skin::normalizeKey($userSkin);
             // Skin::normalizeKey will also validate it, so
             // this won't throw an exception
             $this->skin = $factory->makeSkin($normalized);
         }
         // After all that set a context on whatever skin got created
         $this->skin->setContext($this);
     }
     return $this->skin;
 }
Example #9
0
 /**
  * Factory method for loading a skin of a given type
  * @param string $key 'monobook', 'vector', etc.
  * @return Skin
  * @deprecated since 1.24; Use SkinFactory instead
  */
 static function &newFromKey($key)
 {
     wfDeprecated(__METHOD__, '1.24');
     $key = Skin::normalizeKey($key);
     $factory = SkinFactory::getDefaultInstance();
     // normalizeKey() guarantees that a skin with this key will exist.
     $skin = $factory->makeSkin($key);
     return $skin;
 }
Example #10
0
 /**
  * Finish printing and output buffered data.
  */
 public function closePrinter()
 {
     if ($this->mDisabled) {
         return;
     }
     $mime = $this->getMimeType();
     if ($this->getIsHtml() && $mime !== null) {
         $format = $this->getFormat();
         $lcformat = strtolower($format);
         $result = $this->getBuffer();
         $context = new DerivativeContext($this->getMain());
         $context->setSkin(SkinFactory::getDefaultInstance()->makeSkin('apioutput'));
         $context->setTitle(SpecialPage::getTitleFor('ApiHelp'));
         $out = new OutputPage($context);
         $context->setOutput($out);
         $out->addModuleStyles('mediawiki.apipretty');
         $out->setPageTitle($context->msg('api-format-title'));
         // When the format without suffix 'fm' is defined, there is a non-html version
         if ($this->getMain()->getModuleManager()->isDefined($lcformat, 'format')) {
             $msg = $context->msg('api-format-prettyprint-header')->params($format, $lcformat);
         } else {
             $msg = $context->msg('api-format-prettyprint-header-only-html')->params($format);
         }
         $header = $msg->parseAsBlock();
         $out->addHTML(Html::rawElement('div', array('class' => 'api-pretty-header'), ApiHelp::fixHelpLinks($header)));
         if (Hooks::run('ApiFormatHighlight', array($context, $result, $mime, $format))) {
             $out->addHTML(Html::element('pre', array('class' => 'api-pretty-content'), $result));
         }
         // API handles its own clickjacking protection.
         // Note, that $wgBreakFrames will still override $wgApiFrameOptions for format mode.
         $out->allowClickJacking();
         $out->output();
     } else {
         // For non-HTML output, clear all errors that might have been
         // displayed if display_errors=On
         ob_clean();
         echo $this->getBuffer();
     }
 }
Example #11
0
 /**
  * @dataProvider provideMakeResourceLoaderLink
  * @covers OutputPage::makeResourceLoaderLink
  * @covers ResourceLoader::makeLoaderImplementScript
  * @covers ResourceLoader::makeModuleResponse
  * @covers ResourceLoader::makeInlineScript
  * @covers ResourceLoader::makeLoaderStateScript
  * @covers ResourceLoader::createLoaderURL
  */
 public function testMakeResourceLoaderLink($args, $expectedHtml)
 {
     $this->setMwGlobals(array('wgResourceLoaderDebug' => false, 'wgLoadScript' => 'http://127.0.0.1:8080/w/load.php', 'wgWellFormedXml' => false));
     $class = new ReflectionClass('OutputPage');
     $method = $class->getMethod('makeResourceLoaderLink');
     $method->setAccessible(true);
     $ctx = new RequestContext();
     $ctx->setSkin(SkinFactory::getDefaultInstance()->makeSkin('fallback'));
     $ctx->setLanguage('en');
     $out = new OutputPage($ctx);
     $rl = $out->getResourceLoader();
     $rl->setMessageBlobStore(new NullMessageBlobStore());
     $rl->register(array('test.foo' => new ResourceLoaderTestModule(array('script' => 'mw.test.foo( { a: true } );', 'styles' => '.mw-test-foo { content: "style"; }')), 'test.bar' => new ResourceLoaderTestModule(array('script' => 'mw.test.bar( { a: true } );', 'styles' => '.mw-test-bar { content: "style"; }')), 'test.baz' => new ResourceLoaderTestModule(array('script' => 'mw.test.baz( { a: true } );', 'styles' => '.mw-test-baz { content: "style"; }')), 'test.quux' => new ResourceLoaderTestModule(array('script' => 'mw.test.baz( { token: 123 } );', 'styles' => '/* pref-animate=off */ .mw-icon { transition: none; }', 'group' => 'private')), 'test.raw' => new ResourceLoaderTestModule(array('script' => 'mw.test.baz( { token: 123 } );', 'isRaw' => true)), 'test.noscript' => new ResourceLoaderTestModule(array('styles' => '.mw-test-noscript { content: "style"; }', 'group' => 'noscript')), 'test.group.bar' => new ResourceLoaderTestModule(array('styles' => '.mw-group-bar { content: "style"; }', 'group' => 'bar')), 'test.group.foo' => new ResourceLoaderTestModule(array('styles' => '.mw-group-foo { content: "style"; }', 'group' => 'foo'))));
     $links = $method->invokeArgs($out, $args);
     $actualHtml = implode("\n", $links['html']);
     $this->assertEquals($expectedHtml, $actualHtml);
 }
Example #12
0
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 * http://www.gnu.org/copyleft/gpl.html
 *
 * @file
 * @ingroup Skins
 */
$GLOBALS['wgExtensionCredits']['skin'][] = array('path' => __FILE__, 'name' => 'Vector', 'namemsg' => 'skinname-vector', 'descriptionmsg' => 'vector-skin-desc', 'url' => 'https://www.mediawiki.org/wiki/Skin:Vector', 'author' => array('Trevor Parscal', 'Roan Kattouw', '...'), 'license-name' => 'GPLv2+');
// Register files
$GLOBALS['wgAutoloadClasses']['SkinVector'] = __DIR__ . '/SkinVector.php';
$GLOBALS['wgAutoloadClasses']['VectorTemplate'] = __DIR__ . '/VectorTemplate.php';
$GLOBALS['wgMessagesDirs']['Vector'] = __DIR__ . '/i18n';
// Register skin
SkinFactory::getDefaultInstance()->register('vector', 'Vector', function () {
    $config = ConfigFactory::getDefaultInstance()->makeConfig('vector');
    return new SkinVector($config);
});
// Register config
$GLOBALS['wgConfigRegistry']['vector'] = 'GlobalVarConfig::newInstance';
// Configuration options
/**
 * Search form look.
 *  - true = use an icon search button
 *  - false = use Go & Search buttons
 */
$GLOBALS['wgVectorUseSimpleSearch'] = true;
/**
 * Watch and unwatch as an icon rather than a link.
 *  - true = use an icon watch/unwatch button
Example #13
0
 /**
  * Fetch the set of available skins.
  * @return array Associative array of strings
  */
 static function getSkinNames()
 {
     return SkinFactory::getDefaultInstance()->getSkinNames();
 }
Example #14
0
}, 'InterwikiLookup' => function (MediaWikiServices $services) {
    global $wgContLang;
    // TODO: manage $wgContLang as a service
    $config = $services->getMainConfig();
    return new ClassicInterwikiLookup($wgContLang, ObjectCache::getMainWANInstance(), $config->get('InterwikiExpiry'), $config->get('InterwikiCache'), $config->get('InterwikiScopes'), $config->get('InterwikiFallbackSite'));
}, 'StatsdDataFactory' => function (MediaWikiServices $services) {
    return new BufferingStatsdDataFactory(rtrim($services->getMainConfig()->get('StatsdMetricPrefix'), '.'));
}, 'EventRelayerGroup' => function (MediaWikiServices $services) {
    return new EventRelayerGroup($services->getMainConfig()->get('EventRelayerConfig'));
}, 'SearchEngineFactory' => function (MediaWikiServices $services) {
    return new SearchEngineFactory($services->getSearchEngineConfig());
}, 'SearchEngineConfig' => function (MediaWikiServices $services) {
    global $wgContLang;
    return new SearchEngineConfig($services->getMainConfig(), $wgContLang);
}, 'SkinFactory' => function (MediaWikiServices $services) {
    $factory = new SkinFactory();
    $names = $services->getMainConfig()->get('ValidSkinNames');
    foreach ($names as $name => $skin) {
        $factory->register($name, $skin, function () use($name, $skin) {
            $class = "Skin{$skin}";
            return new $class($name);
        });
    }
    // Register a hidden "fallback" skin
    $factory->register('fallback', 'Fallback', function () {
        return new SkinFallback();
    });
    // Register a hidden skin for api output
    $factory->register('apioutput', 'ApiOutput', function () {
        return new SkinApi();
    });