public function setUp()
 {
     global $wgOut, $wgUser, $wgMessageCache;
     $wgOut = $this;
     $wgUser = new User(2);
     $wgMessageCache = new MessageCache();
     $wgMessageCache->addMessages(array('rdf' => 'Rdf', 'rdf-inpage' => "Embedded In-page Turtle", 'rdf-dcmes' => "Dublin Core Metadata Element Set", 'rdf-cc' => "Creative Commons", 'rdf-image' => "Embedded images", 'rdf-linksfrom' => "Links from the page", 'rdf-links' => "All links", 'rdf-history' => "Historical versions", 'rdf-interwiki' => "Interwiki links", 'rdf-categories' => "Categories", 'rdf-target' => "Target page", 'rdf-modelnames' => "Model(s)", 'rdf-format' => "Output format", 'rdf-output-xml' => "XML", 'rdf-output-turtle' => "Turtle", 'rdf-output-ntriples' => "NTriples", 'rdf-instructions' => "Select the target page and RDF models you're interested in."));
     MwRdf::$ModelMakers = array('MwRdf_CreativeCommons_Modeler', 'MwRdf_LinksFrom_Modeler', 'MwRdf_LinksTo_Modeler', 'MwRdf_InPage_Modeler', 'MwRdf_DCmes_Modeler', 'MwRdf_History_Modeler', 'MwRdf_Image_Modeler', 'MwRdf_Categories_Modeler', 'MwRdf_Interwiki_Modeler');
     MwRdf::ShowForm();
 }
Exemple #2
0
 /** Build $this->messages array */
 private function initMessagesHref()
 {
     # List of default messages for the sidebar:
     $URL_messages = array('mainpage', 'portal-url', 'currentevents-url', 'recentchanges-url', 'randompage-url', 'helppage');
     foreach ($URL_messages as $m) {
         $titleName = MessageCache::singleton()->get($m);
         $title = Title::newFromText($titleName);
         $this->messages[$m]['href'] = $title->getLocalURL();
     }
 }
 protected function setUp()
 {
     global $wgLanguageCode, $wgContLang;
     if ($wgLanguageCode != $wgContLang->getCode()) {
         throw new MWException("Error in MediaWikiLangTestCase::setUp(): " . "\$wgLanguageCode ('{$wgLanguageCode}') is different from " . "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")");
     }
     parent::setUp();
     $this->setUserLang('en');
     // For mainpage to be 'Main Page'
     $this->setContentLang('en');
     MessageCache::singleton()->disable();
 }
 protected function setUp()
 {
     global $wgLanguageCode, $wgContLang;
     parent::setUp();
     if ($wgLanguageCode != $wgContLang->getCode()) {
         throw new MWException("Error in MediaWikiLangTestCase::setUp(): " . "\$wgLanguageCode ('{$wgLanguageCode}') is different from " . "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")");
     }
     $langCode = 'en';
     # For mainpage to be 'Main Page'
     $langObj = Language::factory($langCode);
     $this->setMwGlobals(array('wgLanguageCode' => $langCode, 'wgLang' => $langObj, 'wgContLang' => $langObj));
     MessageCache::singleton()->disable();
 }
 public function setUp()
 {
     global $wgLanguageCode, $wgLang, $wgContLang;
     self::$oldLang = $wgLang;
     self::$oldContLang = $wgContLang;
     if ($wgLanguageCode != $wgContLang->getCode()) {
         throw new MWException("Error in MediaWikiLangTestCase::setUp(): " . "\$wgLanguageCode ('{$wgLanguageCode}') is different from " . "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")");
     }
     $wgLanguageCode = 'en';
     # For mainpage to be 'Main Page'
     $wgContLang = $wgLang = Language::factory($wgLanguageCode);
     MessageCache::singleton()->disable();
 }
 public function setUp()
 {
     global $wgLanguageCode, $wgLang, $wgContLang;
     self::$oldLang = $wgLang;
     self::$oldContLang = $wgContLang;
     if ($wgLanguageCode != $wgContLang->getCode()) {
         die("nooo!");
     }
     $wgLanguageCode = 'en';
     # For mainpage to be 'Main Page'
     $wgContLang = $wgLang = Language::factory($wgLanguageCode);
     MessageCache::singleton()->disable();
 }
 /**
  * From WikimediaMessages
  *
  * @return bool
  */
 public static function onMessageCacheGet(&$lcKey)
 {
     global $wgLanguageCode;
     static $keys = array('centralauth-groupname');
     if (in_array($lcKey, $keys, true)) {
         $prefixedKey = "miraheze-{$lcKey}";
         // MessageCache uses ucfirst if ord( key ) is < 128, which is true of all
         // of the above.  Revisit if non-ASCII keys are used.
         $ucKey = ucfirst($lcKey);
         $cache = MessageCache::singleton();
         if ($cache->getMsgFromNamespace($ucKey, $wgLanguageCode) === false) {
             $lcKey = $prefixedKey;
         }
     }
     return true;
 }
 protected function setUp()
 {
     global $wgLanguageCode, $wgContLang;
     parent::setUp();
     if ($wgLanguageCode != $wgContLang->getCode()) {
         throw new MWException("Error in MediaWikiLangTestCase::setUp(): " . "\$wgLanguageCode ('{$wgLanguageCode}') is different from " . "\$wgContLang->getCode() (" . $wgContLang->getCode() . ")");
     }
     // HACK: Call getLanguage() so the real $wgContLang is cached as the user language
     // rather than our fake one. This is to avoid breaking other, unrelated tests.
     RequestContext::getMain()->getLanguage();
     $langCode = 'en';
     # For mainpage to be 'Main Page'
     $langObj = Language::factory($langCode);
     $this->setMwGlobals(array('wgLanguageCode' => $langCode, 'wgLang' => $langObj, 'wgContLang' => $langObj));
     MessageCache::singleton()->disable();
 }
 /**
  * When core requests certain messages, change the key to a Kol-Zchut version.
  *
  * @note Don't make this a closure, it causes the Database Dumps to fail.
  *   See https://bugs.php.net/bug.php?id=52144
  *
  * @param String &$lcKey message key to check and possibly convert
  *
  * @return bool
  */
 public static function onMessageCacheGet(&$lcKey)
 {
     global $wgLanguageCode;
     static $keys = array('aboutpage', 'aboutsite', 'copyright', 'copyrightwarning', 'deletereason-dropdown', 'edithelppage', 'hidetoc', 'showtoc', 'lastmodifiedat', 'lastmodifiedatby', 'login', 'logouttext', 'nav-login-createaccount', 'userlogin', 'userloginnocreate', 'logout', 'userlogout', 'notloggedin', 'nologin', 'gotaccountlink', 'createaccounterror', 'signupstart', 'noarticletext', 'noarticletext-nopermission', 'protect-dropdown', 'siteuser', 'siteusers', 'tagline', 'tooltip-p-logo', 'tooltip-n-mainpage', 'tooltip-n-mainpage-description', "accesskey-p-logo", "accesskey-n-mainpage", 'enotif_body_intro_deleted', 'enotif_body_intro_created', 'enotif_body_intro_moved', 'enotif_body_intro_restored', 'enotif_body_intro_changed', 'enotif_lastvisited', 'enotif_lastdiff', 'enotif_body', 'search-nonefound', 'upload', 'userpage', 'helena-disclaimers', 'wr-langlinks-label');
     if (in_array($lcKey, $keys, true)) {
         $prefixedKey = "kz-{$lcKey}";
         // MessageCache uses ucfirst if ord( key ) is < 128, which is true of all
         // of the above.  Revisit if non-ASCII keys are used.
         $ucKey = ucfirst($lcKey);
         $cache = MessageCache::singleton();
         if ($cache->getMsgFromNamespace($ucKey, $wgLanguageCode) === false) {
             $lcKey = $prefixedKey;
         }
     }
     return true;
 }
 /**
  * @param $title Title
  * @return null|string
  */
 protected function getContent($title)
 {
     if ($title->getNamespace() === NS_MEDIAWIKI) {
         // The first "true" is to use the database, the second is to use the content langue
         // and the last one is to specify the message key already contains the language in it ("/de", etc.)
         $text = MessageCache::singleton()->get($title->getDBkey(), true, true, true);
         return $text === false ? '' : $text;
     }
     if (!$title->isCssJsSubpage() && !$title->isCssOrJsPage()) {
         return null;
     }
     $revision = Revision::newFromTitle($title, false, Revision::READ_NORMAL);
     if (!$revision) {
         return null;
     }
     return $revision->getRawText();
 }
 /** Build $this->messages array */
 private function initMessagesHref()
 {
     # List of default messages for the sidebar. The sidebar doesn't care at
     # all whether they are full URLs, interwiki links or local titles.
     $URL_messages = array('mainpage', 'portal-url', 'currentevents-url', 'recentchanges-url', 'randompage-url', 'helppage');
     # We're assuming that isValidURI works as advertised: it's also
     # tested separately, in tests/phpunit/includes/HttpTest.php.
     foreach ($URL_messages as $m) {
         $titleName = MessageCache::singleton()->get($m);
         if (Http::isValidURI($titleName)) {
             $this->messages[$m]['href'] = $titleName;
         } else {
             $title = Title::newFromText($titleName);
             $this->messages[$m]['href'] = $title->getLocalURL();
         }
     }
 }
/**
 *
 */
function wfSpecialAllmessages()
{
    global $wgOut, $wgRequest, $wgMessageCache, $wgTitle;
    global $wgUseDatabaseMessages;
    # The page isn't much use if the MediaWiki namespace is not being used
    if (!$wgUseDatabaseMessages) {
        $wgOut->addWikiText(wfMsg('allmessagesnotsupportedDB'));
        return;
    }
    $fname = "wfSpecialAllMessages";
    wfProfileIn($fname);
    wfProfileIn("{$fname}-setup");
    $ot = $wgRequest->getText('ot');
    $navText = wfMsg('allmessagestext');
    # Make sure all extension messages are available
    MessageCache::loadAllMessages();
    $first = true;
    $sortedArray = array_merge(Language::getMessagesFor('en'), $wgMessageCache->getExtensionMessagesFor('en'));
    ksort($sortedArray);
    $messages = array();
    $wgMessageCache->disableTransform();
    foreach ($sortedArray as $key => $value) {
        $messages[$key]['enmsg'] = $value;
        $messages[$key]['statmsg'] = wfMsgNoDb($key);
        $messages[$key]['msg'] = wfMsg($key);
    }
    $wgMessageCache->enableTransform();
    wfProfileOut("{$fname}-setup");
    wfProfileIn("{$fname}-output");
    if ($ot == 'php') {
        $navText .= makePhp($messages);
        $wgOut->addHTML('PHP | <a href="' . $wgTitle->escapeLocalUrl('ot=html') . '">HTML</a><pre>' . htmlspecialchars($navText) . '</pre>');
    } else {
        $wgOut->addHTML('<a href="' . $wgTitle->escapeLocalUrl('ot=php') . '">PHP</a> | HTML');
        $wgOut->addWikiText($navText);
        $wgOut->addHTML(makeHTMLText($messages));
    }
    wfProfileOut("{$fname}-output");
    wfProfileOut($fname);
}
Exemple #13
0
 /**
  * Set up the global variables for a consistent environment for each test.
  * Ideally this should replace the global configuration entirely.
  * @param array $opts
  * @param string $config
  * @return RequestContext
  */
 protected function setupGlobals($opts = array(), $config = '')
 {
     global $wgFileBackends;
     # Find out values for some special options.
     $lang = self::getOptionValue('language', $opts, 'en');
     $variant = self::getOptionValue('variant', $opts, false);
     $maxtoclevel = self::getOptionValue('wgMaxTocLevel', $opts, 999);
     $linkHolderBatchSize = self::getOptionValue('wgLinkHolderBatchSize', $opts, 1000);
     $uploadDir = $this->getUploadDir();
     if ($this->getCliArg('use-filebackend')) {
         if (self::$backendToUse) {
             $backend = self::$backendToUse;
         } else {
             $name = $this->getCliArg('use-filebackend');
             $useConfig = array();
             foreach ($wgFileBackends as $conf) {
                 if ($conf['name'] == $name) {
                     $useConfig = $conf;
                 }
             }
             $useConfig['name'] = 'local-backend';
             // swap name
             unset($useConfig['lockManager']);
             unset($useConfig['fileJournal']);
             $class = $useConfig['class'];
             self::$backendToUse = new $class($useConfig);
             $backend = self::$backendToUse;
         }
     } else {
         # Replace with a mock. We do not care about generating real
         # files on the filesystem, just need to expose the file
         # informations.
         $backend = new MockFileBackend(array('name' => 'local-backend', 'wikiId' => wfWikiId()));
     }
     $settings = array('wgLocalFileRepo' => array('class' => 'LocalRepo', 'name' => 'local', 'url' => 'http://example.com/images', 'hashLevels' => 2, 'transformVia404' => false, 'backend' => $backend), 'wgEnableUploads' => self::getOptionValue('wgEnableUploads', $opts, true), 'wgLanguageCode' => $lang, 'wgDBprefix' => $this->db->getType() != 'oracle' ? 'unittest_' : 'ut_', 'wgRawHtml' => self::getOptionValue('wgRawHtml', $opts, false), 'wgNamespacesWithSubpages' => array(NS_MAIN => isset($opts['subpage'])), 'wgAllowExternalImages' => self::getOptionValue('wgAllowExternalImages', $opts, true), 'wgThumbLimits' => array(self::getOptionValue('thumbsize', $opts, 180)), 'wgMaxTocLevel' => $maxtoclevel, 'wgUseTeX' => isset($opts['math']) || isset($opts['texvc']), 'wgMathDirectory' => $uploadDir . '/math', 'wgDefaultLanguageVariant' => $variant, 'wgLinkHolderBatchSize' => $linkHolderBatchSize, 'wgUseTidy' => isset($opts['tidy']));
     if ($config) {
         $configLines = explode("\n", $config);
         foreach ($configLines as $line) {
             list($var, $value) = explode('=', $line, 2);
             $settings[$var] = eval("return {$value};");
             // ???
         }
     }
     $this->savedGlobals = array();
     /** @since 1.20 */
     Hooks::run('ParserTestGlobals', array(&$settings));
     $langObj = Language::factory($lang);
     $settings['wgContLang'] = $langObj;
     $settings['wgLang'] = $langObj;
     $context = new RequestContext();
     $settings['wgOut'] = $context->getOutput();
     $settings['wgUser'] = $context->getUser();
     $settings['wgRequest'] = $context->getRequest();
     // We (re)set $wgThumbLimits to a single-element array above.
     $context->getUser()->setOption('thumbsize', 0);
     foreach ($settings as $var => $val) {
         if (array_key_exists($var, $GLOBALS)) {
             $this->savedGlobals[$var] = $GLOBALS[$var];
         }
         $GLOBALS[$var] = $val;
     }
     MWTidy::destroySingleton();
     MagicWord::clearCache();
     # The entries saved into RepoGroup cache with previous globals will be wrong.
     RepoGroup::destroySingleton();
     FileBackendGroup::destroySingleton();
     # Create dummy files in storage
     $this->setupUploads();
     # Publish the articles after we have the final language set
     $this->publishTestArticles();
     MessageCache::destroyInstance();
     return $context;
 }
Exemple #14
0
 /**
  * Clears caches when article is deleted
  *
  * @param Title $title
  */
 public static function onArticleDelete(Title $title)
 {
     global $wgContLang;
     // Update existence markers on article/talk tabs...
     $other = $title->getOtherPage();
     $other->purgeSquid();
     $title->touchLinks();
     $title->purgeSquid();
     MediaWikiServices::getInstance()->getLinkCache()->invalidateTitle($title);
     // File cache
     HTMLFileCache::clearFileCache($title);
     InfoAction::invalidateCache($title);
     // Messages
     if ($title->getNamespace() == NS_MEDIAWIKI) {
         MessageCache::singleton()->replace($title->getDBkey(), false);
         if ($wgContLang->hasVariants()) {
             $wgContLang->updateConversionTable($title);
         }
     }
     // Images
     if ($title->getNamespace() == NS_FILE) {
         DeferredUpdates::addUpdate(new HTMLCacheUpdate($title, 'imagelinks'));
     }
     // User talk pages
     if ($title->getNamespace() == NS_USER_TALK) {
         $user = User::newFromName($title->getText(), false);
         if ($user) {
             $user->setNewtalk(false);
         }
     }
     // Image redirects
     RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect($title);
 }
Exemple #15
0
/**
 * Since wfMsg() and co suck, they don't return false if the message key they
 * looked up didn't exist but instead the key wrapped in <>'s, this function checks for the
 * nonexistence of messages by checking the MessageCache::get() result directly.
 *
 * @deprecated since 1.18. Use Message::isDisabled().
 *
 * @param string $key The message key looked up
 * @return bool True if the message *doesn't* exist.
 */
function wfEmptyMsg($key)
{
    wfDeprecated(__METHOD__, '1.21');
    return MessageCache::singleton()->get($key, true, false) === false;
}
<?php

/**
 * Bootstrapping for MediaWiki PHPUnit tests
 * This file is included by phpunit and is NOT in the global scope.
 *
 * @file
 */
if (!defined('MW_PHPUNIT_TEST')) {
    echo <<<EOF
You are running these tests directly from phpunit. You may not have all globals correctly set.
Running phpunit.php instead is recommended.
EOF;
    require_once __DIR__ . "/phpunit.php";
}
// Output a notice when running with older versions of PHPUnit
if (version_compare(PHPUnit_Runner_Version::id(), "3.6.7", "<")) {
    echo <<<EOF
********************************************************************************

These tests run best with version PHPUnit 3.6.7 or better. Earlier versions may
show failures because earlier versions of PHPUnit do not properly implement
dependencies.

********************************************************************************

EOF;
}
/** @todo Check if this is really needed */
MessageCache::destroyInstance();
 /**
  * @dataProvider provideNormalizeKey
  */
 public function testNormalizeKey($key, $expected)
 {
     $actual = MessageCache::normalizeKey($key);
     $this->assertEquals($expected, $actual);
 }
Exemple #18
0
 /**
  * Generate the generic "this page has been changed" e-mail text.
  */
 private function composeCommonMailtext()
 {
     global $wgPasswordSender, $wgNoReplyAddress;
     global $wgEnotifFromEditor, $wgEnotifRevealEditorAddress;
     global $wgEnotifImpersonal, $wgEnotifUseRealName;
     $this->composed_common = true;
     # You as the WikiAdmin and Sysops can make use of plenty of
     # named variables when composing your notification emails while
     # simply editing the Meta pages
     $keys = array();
     $postTransformKeys = array();
     $pageTitleUrl = $this->title->getCanonicalURL();
     $pageTitle = $this->title->getPrefixedText();
     if ($this->oldid) {
         // Always show a link to the diff which triggered the mail. See bug 32210.
         $keys['$NEWPAGE'] = "\n\n" . wfMessage('enotif_lastdiff', $this->title->getCanonicalURL(array('diff' => 'next', 'oldid' => $this->oldid)))->inContentLanguage()->text();
         if (!$wgEnotifImpersonal) {
             // For personal mail, also show a link to the diff of all changes
             // since last visited.
             $keys['$NEWPAGE'] .= "\n\n" . wfMessage('enotif_lastvisited', $this->title->getCanonicalURL(array('diff' => '0', 'oldid' => $this->oldid)))->inContentLanguage()->text();
         }
         $keys['$OLDID'] = $this->oldid;
         // Deprecated since MediaWiki 1.21, not used by default. Kept for backwards-compatibility.
         $keys['$CHANGEDORCREATED'] = wfMessage('changed')->inContentLanguage()->text();
     } else {
         # clear $OLDID placeholder in the message template
         $keys['$OLDID'] = '';
         $keys['$NEWPAGE'] = '';
         // Deprecated since MediaWiki 1.21, not used by default. Kept for backwards-compatibility.
         $keys['$CHANGEDORCREATED'] = wfMessage('created')->inContentLanguage()->text();
     }
     $keys['$PAGETITLE'] = $this->title->getPrefixedText();
     $keys['$PAGETITLE_URL'] = $this->title->getCanonicalURL();
     $keys['$PAGEMINOREDIT'] = $this->minorEdit ? wfMessage('minoredit')->inContentLanguage()->text() : '';
     $keys['$UNWATCHURL'] = $this->title->getCanonicalURL('action=unwatch');
     if ($this->editor->isAnon()) {
         # real anon (user:xxx.xxx.xxx.xxx)
         $keys['$PAGEEDITOR'] = wfMessage('enotif_anon_editor', $this->editor->getName())->inContentLanguage()->text();
         $keys['$PAGEEDITOR_EMAIL'] = wfMessage('noemailtitle')->inContentLanguage()->text();
     } else {
         $keys['$PAGEEDITOR'] = $wgEnotifUseRealName && $this->editor->getRealName() !== '' ? $this->editor->getRealName() : $this->editor->getName();
         $emailPage = SpecialPage::getSafeTitleFor('Emailuser', $this->editor->getName());
         $keys['$PAGEEDITOR_EMAIL'] = $emailPage->getCanonicalURL();
     }
     $keys['$PAGEEDITOR_WIKI'] = $this->editor->getUserPage()->getCanonicalURL();
     $keys['$HELPPAGE'] = wfExpandUrl(Skin::makeInternalOrExternalUrl(wfMessage('helppage')->inContentLanguage()->text()));
     # Replace this after transforming the message, bug 35019
     $postTransformKeys['$PAGESUMMARY'] = $this->summary == '' ? ' - ' : $this->summary;
     // Now build message's subject and body
     // Messages:
     // enotif_subject_deleted, enotif_subject_created, enotif_subject_moved,
     // enotif_subject_restored, enotif_subject_changed
     $this->subject = wfMessage('enotif_subject_' . $this->pageStatus)->inContentLanguage()->params($pageTitle, $keys['$PAGEEDITOR'])->text();
     // Messages:
     // enotif_body_intro_deleted, enotif_body_intro_created, enotif_body_intro_moved,
     // enotif_body_intro_restored, enotif_body_intro_changed
     $keys['$PAGEINTRO'] = wfMessage('enotif_body_intro_' . $this->pageStatus)->inContentLanguage()->params($pageTitle, $keys['$PAGEEDITOR'], $pageTitleUrl)->text();
     $body = wfMessage('enotif_body')->inContentLanguage()->plain();
     $body = strtr($body, $keys);
     $body = MessageCache::singleton()->transform($body, false, null, $this->title);
     $this->body = wordwrap(strtr($body, $postTransformKeys), 72);
     # Reveal the page editor's address as REPLY-TO address only if
     # the user has not opted-out and the option is enabled at the
     # global configuration level.
     $adminAddress = new MailAddress($wgPasswordSender, wfMessage('emailsender')->inContentLanguage()->text());
     if ($wgEnotifRevealEditorAddress && $this->editor->getEmail() != '' && $this->editor->getOption('enotifrevealaddr')) {
         $editorAddress = MailAddress::newFromUser($this->editor);
         if ($wgEnotifFromEditor) {
             $this->from = $editorAddress;
         } else {
             $this->from = $adminAddress;
             $this->replyto = $editorAddress;
         }
     } else {
         $this->from = $adminAddress;
         $this->replyto = new MailAddress($wgNoReplyAddress);
     }
 }
 /**
  * Add content from plain text
  * @since 1.17
  * @param $bar array
  * @param $text string
  * @return Array
  */
 function addToSidebarPlain(&$bar, $text)
 {
     $lines = explode("\n", $text);
     $heading = '';
     foreach ($lines as $line) {
         if (strpos($line, '*') !== 0) {
             continue;
         }
         $line = rtrim($line, "\r");
         // for Windows compat
         if (strpos($line, '**') !== 0) {
             $heading = trim($line, '* ');
             if (!array_key_exists($heading, $bar)) {
                 $bar[$heading] = array();
             }
         } else {
             $line = trim($line, '* ');
             if (strpos($line, '|') !== false) {
                 // sanity check
                 $line = MessageCache::singleton()->transform($line, false, null, $this->getTitle());
                 $line = array_map('trim', explode('|', $line, 2));
                 if (count($line) !== 2) {
                     // Second sanity check, could be hit by people doing
                     // funky stuff with parserfuncs... (bug 33321)
                     continue;
                 }
                 $extraAttribs = array();
                 $msgLink = $this->msg($line[0])->inContentLanguage();
                 if ($msgLink->exists()) {
                     $link = $msgLink->text();
                     if ($link == '-') {
                         continue;
                     }
                 } else {
                     $link = $line[0];
                 }
                 $msgText = $this->msg($line[1]);
                 if ($msgText->exists()) {
                     $text = $msgText->text();
                 } else {
                     $text = $line[1];
                 }
                 if (preg_match('/^(?i:' . wfUrlProtocols() . ')/', $link)) {
                     $href = $link;
                     // Parser::getExternalLinkAttribs won't work here because of the Namespace things
                     global $wgNoFollowLinks, $wgNoFollowDomainExceptions;
                     if ($wgNoFollowLinks && !wfMatchesDomainList($href, $wgNoFollowDomainExceptions)) {
                         $extraAttribs['rel'] = 'nofollow';
                     }
                     global $wgExternalLinkTarget;
                     if ($wgExternalLinkTarget) {
                         $extraAttribs['target'] = $wgExternalLinkTarget;
                     }
                 } else {
                     $title = Title::newFromText($link);
                     if ($title) {
                         $title = $title->fixSpecialName();
                         $href = $title->getLinkURL();
                     } else {
                         $href = 'INVALID-TITLE';
                     }
                 }
                 $bar[$heading][] = array_merge(array('text' => $text, 'href' => $href, 'id' => 'n-' . Sanitizer::escapeId(strtr($line[1], ' ', '-'), 'noninitial'), 'active' => false), $extraAttribs);
             } else {
                 continue;
             }
         }
     }
     return $bar;
 }
Exemple #20
0
 /**
  * Get the language in which the content of this page is written.
  * Defaults to $wgContLang, but in certain cases it can be e.g.
  * $wgLang (such as special pages, which are in the user language).
  *
  * @since 1.18
  * @return object Language
  */
 public function getPageLanguage()
 {
     global $wgLang;
     if ($this->getNamespace() == NS_SPECIAL) {
         // special pages are in the user language
         return $wgLang;
     } elseif ($this->isRedirect()) {
         // the arrow on a redirect page is aligned according to the user language
         return $wgLang;
     } elseif ($this->isCssOrJsPage()) {
         // css/js should always be LTR and is, in fact, English
         return wfGetLangObj('en');
     } elseif ($this->getNamespace() == NS_MEDIAWIKI) {
         // Parse mediawiki messages with correct target language
         list(, $lang) = MessageCache::singleton()->figureMessage($this->getText());
         return wfGetLangObj($lang);
     }
     global $wgContLang;
     // If nothing special, it should be in the wiki content language
     $pageLang = $wgContLang;
     // Hook at the end because we don't want to override the above stuff
     wfRunHooks('PageContentLanguage', array($this, &$pageLang, $wgLang));
     return wfGetLangObj($pageLang);
 }
 /**
  * Get the language in which the content of the given page is written.
  *
  * This default implementation just returns $wgContLang (except for pages
  * in the MediaWiki namespace)
  *
  * Note that the pages language is not cacheable, since it may in some
  * cases depend on user settings.
  *
  * Also note that the page language may or may not depend on the actual content of the page,
  * that is, this method may load the content in order to determine the language.
  *
  * @since 1.21
  *
  * @param Title $title The page to determine the language for.
  * @param Content $content The page's content, if you have it handy, to avoid reloading it.
  *
  * @return Language The page's language
  */
 public function getPageLanguage(Title $title, Content $content = null)
 {
     global $wgContLang, $wgLang;
     $pageLang = $wgContLang;
     if ($title->getNamespace() == NS_MEDIAWIKI) {
         // Parse mediawiki messages with correct target language
         list(, $lang) = MessageCache::singleton()->figureMessage($title->getText());
         $pageLang = wfGetLangObj($lang);
     }
     wfRunHooks('PageContentLanguage', array($title, &$pageLang, $wgLang));
     return wfGetLangObj($pageLang);
 }
Exemple #22
0
 /**
  * Wrapper for what ever method we use to get message contents.
  *
  * @since 1.17
  *
  * @return string
  * @throws MWException If message key array is empty.
  */
 protected function fetchMessage()
 {
     if ($this->message === null) {
         $cache = MessageCache::singleton();
         foreach ($this->keysToTry as $key) {
             $message = $cache->get($key, $this->useDatabase, $this->language);
             if ($message !== false && $message !== '') {
                 break;
             }
         }
         // NOTE: The constructor makes sure keysToTry isn't empty,
         //       so we know that $key and $message are initialized.
         $this->key = $key;
         $this->message = $message;
     }
     return $this->message;
 }
Exemple #23
0
	/**
	 * Clears caches when article is deleted
	 *
	 * @param $title Title
	 */
	public static function onArticleDelete( $title ) {
		// Update existence markers on article/talk tabs...
		if ( $title->isTalkPage() ) {
			$other = $title->getSubjectPage();
		} else {
			$other = $title->getTalkPage();
		}

		$other->invalidateCache();
		$other->purgeSquid();

		$title->touchLinks();
		$title->purgeSquid();

		// File cache
		HTMLFileCache::clearFileCache( $title );
		InfoAction::invalidateCache( $title );

		// Messages
		if ( $title->getNamespace() == NS_MEDIAWIKI ) {
			MessageCache::singleton()->replace( $title->getDBkey(), false );
		}

		// Images
		if ( $title->getNamespace() == NS_FILE ) {
			$update = new HTMLCacheUpdate( $title, 'imagelinks' );
			$update->doUpdate();
		}

		// User talk pages
		if ( $title->getNamespace() == NS_USER_TALK ) {
			$user = User::newFromName( $title->getText(), false );
			if ( $user ) {
				$user->setNewtalk( false );
			}
		}

		// Image redirects
		RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect( $title );
	}
 /**
  * Get a message from either the content language or the user language.
  *
  * First, assemble a list of languages to attempt getting the message from. This
  * chain begins with the requested language and its fallbacks and then continues with
  * the content language and its fallbacks. For each language in the chain, the following
  * process will occur (in this order):
  *  1. If a language-specific override, i.e., [[MW:msg/lang]], is available, use that.
  *     Note: for the content language, there is no /lang subpage.
  *  2. Fetch from the static CDB cache.
  *  3. If available, check the database for fallback language overrides.
  *
  * This process provides a number of guarantees. When changing this code, make sure all
  * of these guarantees are preserved.
  *  * If the requested language is *not* the content language, then the CDB cache for that
  *    specific language will take precedence over the root database page ([[MW:msg]]).
  *  * Fallbacks will be just that: fallbacks. A fallback language will never be reached if
  *    the message is available *anywhere* in the language for which it is a fallback.
  *
  * @param string $key The message key
  * @param bool $useDB If true, look for the message in the DB, false
  *   to use only the compiled l10n cache.
  * @param bool|string|object $langcode Code of the language to get the message for.
  *   - If string and a valid code, will create a standard language object
  *   - If string but not a valid code, will create a basic language object
  *   - If boolean and false, create object from the current users language
  *   - If boolean and true, create object from the wikis content language
  *   - If language object, use it as given
  * @param bool $isFullKey Specifies whether $key is a two part key "msg/lang".
  *
  * @throws MWException When given an invalid key
  * @return string|bool False if the message doesn't exist, otherwise the
  *   message (which can be empty)
  */
 function get($key, $useDB = true, $langcode = true, $isFullKey = false)
 {
     global $wgContLang;
     if (is_int($key)) {
         // Fix numerical strings that somehow become ints
         // on their way here
         $key = (string) $key;
     } elseif (!is_string($key)) {
         throw new MWException('Non-string key given');
     } elseif ($key === '') {
         // Shortcut: the empty key is always missing
         return false;
     }
     // For full keys, get the language code from the key
     $pos = strrpos($key, '/');
     if ($isFullKey && $pos !== false) {
         $langcode = substr($key, $pos + 1);
         $key = substr($key, 0, $pos);
     }
     // Normalise title-case input (with some inlining)
     $lckey = MessageCache::normalizeKey($key);
     Hooks::run('MessageCache::get', array(&$lckey));
     if (ord($lckey) < 128) {
         $uckey = ucfirst($lckey);
     } else {
         $uckey = $wgContLang->ucfirst($lckey);
     }
     // Loop through each language in the fallback list until we find something useful
     $lang = wfGetLangObj($langcode);
     $message = $this->getMessageFromFallbackChain($lang, $lckey, $uckey, !$this->mDisable && $useDB);
     // If we still have no message, maybe the key was in fact a full key so try that
     if ($message === false) {
         $parts = explode('/', $lckey);
         // We may get calls for things that are http-urls from sidebar
         // Let's not load nonexistent languages for those
         // They usually have more than one slash.
         if (count($parts) == 2 && $parts[1] !== '') {
             $message = Language::getMessageFor($parts[0], $parts[1]);
             if ($message === null) {
                 $message = false;
             }
         }
     }
     // Post-processing if the message exists
     if ($message !== false) {
         // Fix whitespace
         $message = str_replace(array('&#32;', '&nbsp;', '&#160;'), array(' ', " ", " "), $message);
     }
     return $message;
 }
Exemple #25
0
 /**
  * This function commits all DB changes as needed before
  * the user can receive a response (in case commit fails)
  *
  * @param IContextSource $context
  * @param callable $postCommitWork [default: null]
  * @since 1.27
  */
 public static function preOutputCommit(IContextSource $context, callable $postCommitWork = null)
 {
     // Either all DBs should commit or none
     ignore_user_abort(true);
     $config = $context->getConfig();
     $request = $context->getRequest();
     $output = $context->getOutput();
     $lbFactory = MediaWikiServices::getInstance()->getDBLoadBalancerFactory();
     // Commit all changes
     $lbFactory->commitMasterChanges(__METHOD__, ['maxWriteDuration' => $config->get('MaxUserDBWriteDuration')]);
     wfDebug(__METHOD__ . ': primary transaction round committed');
     // Run updates that need to block the user or affect output (this is the last chance)
     DeferredUpdates::doUpdates('enqueue', DeferredUpdates::PRESEND);
     wfDebug(__METHOD__ . ': pre-send deferred updates completed');
     // Decide when clients block on ChronologyProtector DB position writes
     $urlDomainDistance = $request->wasPosted() && $output->getRedirect() && $lbFactory->hasOrMadeRecentMasterChanges(INF) ? self::getUrlDomainDistance($output->getRedirect(), $context) : false;
     if ($urlDomainDistance === 'local' || $urlDomainDistance === 'remote') {
         // OutputPage::output() will be fast; $postCommitWork will not be useful for
         // masking the latency of syncing DB positions accross all datacenters synchronously.
         // Instead, make use of the RTT time of the client follow redirects.
         $flags = $lbFactory::SHUTDOWN_CHRONPROT_ASYNC;
         $cpPosTime = microtime(true);
         // Client's next request should see 1+ positions with this DBMasterPos::asOf() time
         if ($urlDomainDistance === 'local') {
             // Client will stay on this domain, so set an unobtrusive cookie
             $expires = time() + ChronologyProtector::POSITION_TTL;
             $options = ['prefix' => ''];
             $request->response()->setCookie('cpPosTime', $cpPosTime, $expires, $options);
         } else {
             // Cookies may not work across wiki domains, so use a URL parameter
             $safeUrl = $lbFactory->appendPreShutdownTimeAsQuery($output->getRedirect(), $cpPosTime);
             $output->redirect($safeUrl);
         }
     } else {
         // OutputPage::output() is fairly slow; run it in $postCommitWork to mask
         // the latency of syncing DB positions accross all datacenters synchronously
         $flags = $lbFactory::SHUTDOWN_CHRONPROT_SYNC;
         if ($lbFactory->hasOrMadeRecentMasterChanges(INF)) {
             $cpPosTime = microtime(true);
             // Set a cookie in case the DB position store cannot sync accross datacenters.
             // This will at least cover the common case of the user staying on the domain.
             $expires = time() + ChronologyProtector::POSITION_TTL;
             $options = ['prefix' => ''];
             $request->response()->setCookie('cpPosTime', $cpPosTime, $expires, $options);
         }
     }
     // Record ChronologyProtector positions for DBs affected in this request at this point
     $lbFactory->shutdown($flags, $postCommitWork);
     wfDebug(__METHOD__ . ': LBFactory shutdown completed');
     // Set a cookie to tell all CDN edge nodes to "stick" the user to the DC that handles this
     // POST request (e.g. the "master" data center). Also have the user briefly bypass CDN so
     // ChronologyProtector works for cacheable URLs.
     if ($request->wasPosted() && $lbFactory->hasOrMadeRecentMasterChanges()) {
         $expires = time() + $config->get('DataCenterUpdateStickTTL');
         $options = ['prefix' => ''];
         $request->response()->setCookie('UseDC', 'master', $expires, $options);
         $request->response()->setCookie('UseCDNCache', 'false', $expires, $options);
     }
     // Avoid letting a few seconds of replica DB lag cause a month of stale data. This logic is
     // also intimately related to the value of $wgCdnReboundPurgeDelay.
     if ($lbFactory->laggedReplicaUsed()) {
         $maxAge = $config->get('CdnMaxageLagged');
         $output->lowerCdnMaxage($maxAge);
         $request->response()->header("X-Database-Lagged: true");
         wfDebugLog('replication', "Lagged DB used; CDN cache TTL limited to {$maxAge} seconds");
     }
     // Avoid long-term cache pollution due to message cache rebuild timeouts (T133069)
     if (MessageCache::singleton()->isDisabled()) {
         $maxAge = $config->get('CdnMaxageSubstitute');
         $output->lowerCdnMaxage($maxAge);
         $request->response()->header("X-Response-Substitute: true");
     }
 }
Exemple #26
0
 /**
  * Get the error message as HTML. This is done by parsing the wikitext error
  * message.
  * @param string $shortContext A short enclosing context message name, to
  *        be used when there is a single error
  * @param string $longContext A long enclosing context message name, for a list
  * @return string
  */
 public function getHTML($shortContext = false, $longContext = false)
 {
     $text = $this->getWikiText($shortContext, $longContext);
     $out = MessageCache::singleton()->parse($text, null, true, true);
     return $out instanceof ParserOutput ? $out->getText() : $out;
 }
Exemple #27
0
 /**
  * Get the default message text or false if the message doesn't exist
  *
  * @return string|bool
  */
 public function getDefaultMessageText()
 {
     global $wgContLang;
     if ($this->getNamespace() != NS_MEDIAWIKI) {
         // Just in case
         return false;
     }
     list($name, $lang) = MessageCache::singleton()->figureMessage($wgContLang->lcfirst($this->getText()));
     $message = wfMessage($name)->inLanguage($lang)->useDatabase(false);
     if ($message->exists()) {
         return $message->plain();
     } else {
         return false;
     }
 }
Exemple #28
0
 /**
  * Wrapper for what ever method we use to get message contents
  *
  * @return string
  */
 protected function fetchMessage()
 {
     if (!isset($this->message)) {
         $cache = MessageCache::singleton();
         if (is_array($this->key)) {
             if (!count($this->key)) {
                 throw new MWException("Given empty message key array.");
             }
             foreach ($this->key as $key) {
                 $message = $cache->get($key, $this->useDatabase, $this->language, false, $this->fixWhitespace);
                 if ($message !== false && $message !== '') {
                     break;
                 }
             }
             $this->message = $message;
         } else {
             $this->message = $cache->get($this->key, $this->useDatabase, $this->language, false, $this->fixWhitespace);
         }
     }
     return $this->message;
 }
 /**
  * Parse the conversion table stored in the cache.
  *
  * The tables should be in blocks of the following form:
  *		-{
  *			word => word ;
  *			word => word ;
  *			...
  *		}-
  *
  * To make the tables more manageable, subpages are allowed
  * and will be parsed recursively if $recursive == true.
  *
  * @param string $code Language code
  * @param string $subpage Subpage name
  * @param bool $recursive Parse subpages recursively? Defaults to true.
  *
  * @return array
  */
 function parseCachedTable($code, $subpage = '', $recursive = true)
 {
     static $parsed = [];
     $key = 'Conversiontable/' . $code;
     if ($subpage) {
         $key .= '/' . $subpage;
     }
     if (array_key_exists($key, $parsed)) {
         return [];
     }
     $parsed[$key] = true;
     if ($subpage === '') {
         $txt = MessageCache::singleton()->getMsgFromNamespace($key, $code);
     } else {
         $txt = false;
         $title = Title::makeTitleSafe(NS_MEDIAWIKI, $key);
         if ($title && $title->exists()) {
             $revision = Revision::newFromTitle($title);
             if ($revision) {
                 if ($revision->getContentModel() == CONTENT_MODEL_WIKITEXT) {
                     $txt = $revision->getContent(Revision::RAW)->getNativeData();
                 }
                 // @todo in the future, use a specialized content model, perhaps based on json!
             }
         }
     }
     # Nothing to parse if there's no text
     if ($txt === false || $txt === null || $txt === '') {
         return [];
     }
     // get all subpage links of the form
     // [[MediaWiki:Conversiontable/zh-xx/...|...]]
     $linkhead = $this->mLangObj->getNsText(NS_MEDIAWIKI) . ':Conversiontable';
     $subs = StringUtils::explode('[[', $txt);
     $sublinks = [];
     foreach ($subs as $sub) {
         $link = explode(']]', $sub, 2);
         if (count($link) != 2) {
             continue;
         }
         $b = explode('|', $link[0], 2);
         $b = explode('/', trim($b[0]), 3);
         if (count($b) == 3) {
             $sublink = $b[2];
         } else {
             $sublink = '';
         }
         if ($b[0] == $linkhead && $b[1] == $code) {
             $sublinks[] = $sublink;
         }
     }
     // parse the mappings in this page
     $blocks = StringUtils::explode('-{', $txt);
     $ret = [];
     $first = true;
     foreach ($blocks as $block) {
         if ($first) {
             // Skip the part before the first -{
             $first = false;
             continue;
         }
         $mappings = explode('}-', $block, 2)[0];
         $stripped = str_replace(["'", '"', '*', '#'], '', $mappings);
         $table = StringUtils::explode(';', $stripped);
         foreach ($table as $t) {
             $m = explode('=>', $t, 3);
             if (count($m) != 2) {
                 continue;
             }
             // trim any trailling comments starting with '//'
             $tt = explode('//', $m[1], 2);
             $ret[trim($m[0])] = trim($tt[0]);
         }
     }
     // recursively parse the subpages
     if ($recursive) {
         foreach ($sublinks as $link) {
             $s = $this->parseCachedTable($code, $link, $recursive);
             $ret = $s + $ret;
         }
     }
     if ($this->mUcfirst) {
         foreach ($ret as $k => $v) {
             $ret[$this->mLangObj->ucfirst($k)] = $this->mLangObj->ucfirst($v);
         }
     }
     return $ret;
 }
Exemple #30
0
 /**
  * @return string Safe HTML
  */
 function getHTML()
 {
     global $wgShowDBErrorBacktrace, $wgShowHostnames, $wgShowSQLErrors;
     $sorry = htmlspecialchars($this->msg('dberr-problems', 'Sorry! This site is experiencing technical difficulties.'));
     $again = htmlspecialchars($this->msg('dberr-again', 'Try waiting a few minutes and reloading.'));
     if ($wgShowHostnames || $wgShowSQLErrors) {
         $info = str_replace('$1', Html::element('span', array('dir' => 'ltr'), $this->error), htmlspecialchars($this->msg('dberr-info', '(Cannot access the database: $1)')));
     } else {
         $info = htmlspecialchars($this->msg('dberr-info-hidden', '(Cannot access the database)'));
     }
     # No database access
     MessageCache::singleton()->disable();
     $html = "<h1>{$sorry}</h1><p>{$again}</p><p><small>{$info}</small></p>";
     if ($wgShowDBErrorBacktrace) {
         $html .= '<p>Backtrace:</p><pre>' . htmlspecialchars($this->getTraceAsString()) . '</pre>';
     }
     $html .= '<hr />';
     $html .= $this->searchForm();
     return $html;
 }