예제 #1
0
function wfGlobalInterwikis($prefix, &$iwData)
{
    global $wgInterwikiCentralDB;
    // docs/hooks.txt says: Return true without providing an interwiki to continue interwiki search.
    if ($wgInterwikiCentralDB === null || $wgInterwikiCentralDB === wfWikiId()) {
        // No global set or this is global, nothing to add
        return true;
    }
    if (!Language::fetchLanguageName($prefix)) {
        // Check if prefix exists locally and skip
        foreach (Interwiki::getAllPrefixes(null) as $id => $localPrefixInfo) {
            if ($prefix === $localPrefixInfo['iw_prefix']) {
                return true;
            }
        }
        $dbr = wfGetDB(DB_SLAVE, array(), $wgInterwikiCentralDB);
        $res = $dbr->selectRow('interwiki', '*', array('iw_prefix' => $prefix), __METHOD__);
        if (!$res) {
            return true;
        }
        // Excplicitly make this an array since it's expected to be one
        $iwData = (array) $res;
        // At this point, we can safely return false because we know that we have something
        return false;
    }
    return true;
}
 /**
  * Execute the job
  *
  * @return bool
  */
 public function run()
 {
     //sleep() could be added here to reduce unnecessary use
     $ill = $this->params['ill'];
     foreach ($ill as $lang => $pages) {
         $iw = Interwiki::fetch($lang);
         if (!$iw) {
             continue;
         }
         $apiUrl = $iw->getAPI();
         if (!$apiUrl) {
             continue;
         }
         $apiUrl .= '?' . wfArrayToCGI(array('action' => 'purge', 'format' => 'json', 'titles' => implode('|', array_keys($pages))));
         Http::post($apiUrl);
         //TODO: error handling
     }
     return true;
 }
예제 #3
0
 /**
  * Load the interwiki, trying first memcached then the DB
  *
  * @param string $prefix The interwiki prefix
  * @return Interwiki|bool Interwiki if $prefix is valid, otherwise false
  */
 protected static function load($prefix)
 {
     global $wgInterwikiExpiry;
     $iwData = array();
     if (!Hooks::run('InterwikiLoadPrefix', array($prefix, &$iwData))) {
         return Interwiki::loadFromArray($iwData);
     }
     $cache = ObjectCache::getMainWANInstance();
     if (!$iwData) {
         $key = wfMemcKey('interwiki', $prefix);
         $iwData = $cache->get($key);
         if ($iwData === '!NONEXISTENT') {
             // negative cache hit
             return false;
         }
     }
     // is_array is hack for old keys
     if ($iwData && is_array($iwData)) {
         $iw = Interwiki::loadFromArray($iwData);
         if ($iw) {
             return $iw;
         }
     }
     $db = wfGetDB(DB_SLAVE);
     $row = $db->fetchRow($db->select('interwiki', self::selectFields(), array('iw_prefix' => $prefix), __METHOD__));
     $iw = Interwiki::loadFromArray($row);
     if ($iw) {
         $mc = array('iw_url' => $iw->mURL, 'iw_api' => $iw->mAPI, 'iw_local' => $iw->mLocal, 'iw_trans' => $iw->mTrans);
         $cache->set($key, $mc, $wgInterwikiExpiry);
         return $iw;
     }
     // negative cache hit
     $cache->set($key, '!NONEXISTENT', $wgInterwikiExpiry);
     return false;
 }
예제 #4
0
 /**
  * Normalizes and splits a title string.
  *
  * This function removes illegal characters, splits off the interwiki and
  * namespace prefixes, sets the other forms, and canonicalizes
  * everything.
  *
  * @todo this method is only exposed as a temporary measure to ease refactoring.
  * It was copied with minimal changes from Title::secureAndSplit().
  *
  * @todo This method should be split up and an appropriate interface
  * defined for use by the Title class.
  *
  * @param string $text
  * @param int $defaultNamespace
  *
  * @throws MalformedTitleException If $text is not a valid title string.
  * @return array A mapp with the fields 'interwiki', 'fragment', 'namespace',
  *         'user_case_dbkey', and 'dbkey'.
  */
 public function splitTitleString($text, $defaultNamespace = NS_MAIN)
 {
     $dbkey = str_replace(' ', '_', $text);
     # Initialisation
     $parts = array('interwiki' => '', 'local_interwiki' => false, 'fragment' => '', 'namespace' => $defaultNamespace, 'dbkey' => $dbkey, 'user_case_dbkey' => $dbkey);
     # Strip Unicode bidi override characters.
     # Sometimes they slip into cut-n-pasted page titles, where the
     # override chars get included in list displays.
     $dbkey = preg_replace('/\\xE2\\x80[\\x8E\\x8F\\xAA-\\xAE]/S', '', $dbkey);
     # Clean up whitespace
     # Note: use of the /u option on preg_replace here will cause
     # input with invalid UTF-8 sequences to be nullified out in PHP 5.2.x,
     # conveniently disabling them.
     $dbkey = preg_replace('/[ _\\xA0\\x{1680}\\x{180E}\\x{2000}-\\x{200A}\\x{2028}\\x{2029}\\x{202F}\\x{205F}\\x{3000}]+/u', '_', $dbkey);
     $dbkey = trim($dbkey, '_');
     if (strpos($dbkey, UtfNormal\Constants::UTF8_REPLACEMENT) !== false) {
         # Contained illegal UTF-8 sequences or forbidden Unicode chars.
         throw new MalformedTitleException('title-invalid-utf8', $text);
     }
     $parts['dbkey'] = $dbkey;
     # Initial colon indicates main namespace rather than specified default
     # but should not create invalid {ns,title} pairs such as {0,Project:Foo}
     if ($dbkey !== '' && ':' == $dbkey[0]) {
         $parts['namespace'] = NS_MAIN;
         $dbkey = substr($dbkey, 1);
         # remove the colon but continue processing
         $dbkey = trim($dbkey, '_');
         # remove any subsequent whitespace
     }
     if ($dbkey == '') {
         throw new MalformedTitleException('title-invalid-empty', $text);
     }
     # Namespace or interwiki prefix
     $prefixRegexp = "/^(.+?)_*:_*(.*)\$/S";
     do {
         $m = array();
         if (preg_match($prefixRegexp, $dbkey, $m)) {
             $p = $m[1];
             if (($ns = $this->language->getNsIndex($p)) !== false) {
                 # Ordinary namespace
                 $dbkey = $m[2];
                 $parts['namespace'] = $ns;
                 # For Talk:X pages, check if X has a "namespace" prefix
                 if ($ns == NS_TALK && preg_match($prefixRegexp, $dbkey, $x)) {
                     if ($this->language->getNsIndex($x[1])) {
                         # Disallow Talk:File:x type titles...
                         throw new MalformedTitleException('title-invalid-talk-namespace', $text);
                     } elseif (Interwiki::isValidInterwiki($x[1])) {
                         // TODO: get rid of global state!
                         # Disallow Talk:Interwiki:x type titles...
                         throw new MalformedTitleException('title-invalid-talk-namespace', $text);
                     }
                 }
             } elseif (Interwiki::isValidInterwiki($p)) {
                 # Interwiki link
                 $dbkey = $m[2];
                 $parts['interwiki'] = $this->language->lc($p);
                 # Redundant interwiki prefix to the local wiki
                 foreach ($this->localInterwikis as $localIW) {
                     if (0 == strcasecmp($parts['interwiki'], $localIW)) {
                         if ($dbkey == '') {
                             # Empty self-links should point to the Main Page, to ensure
                             # compatibility with cross-wiki transclusions and the like.
                             $mainPage = Title::newMainPage();
                             return array('interwiki' => $mainPage->getInterwiki(), 'local_interwiki' => true, 'fragment' => $mainPage->getFragment(), 'namespace' => $mainPage->getNamespace(), 'dbkey' => $mainPage->getDBkey(), 'user_case_dbkey' => $mainPage->getUserCaseDBKey());
                         }
                         $parts['interwiki'] = '';
                         # local interwikis should behave like initial-colon links
                         $parts['local_interwiki'] = true;
                         # Do another namespace split...
                         continue 2;
                     }
                 }
                 # If there's an initial colon after the interwiki, that also
                 # resets the default namespace
                 if ($dbkey !== '' && $dbkey[0] == ':') {
                     $parts['namespace'] = NS_MAIN;
                     $dbkey = substr($dbkey, 1);
                 }
             }
             # If there's no recognized interwiki or namespace,
             # then let the colon expression be part of the title.
         }
         break;
     } while (true);
     $fragment = strstr($dbkey, '#');
     if (false !== $fragment) {
         $parts['fragment'] = str_replace('_', ' ', substr($fragment, 1));
         $dbkey = substr($dbkey, 0, strlen($dbkey) - strlen($fragment));
         # remove whitespace again: prevents "Foo_bar_#"
         # becoming "Foo_bar_"
         $dbkey = preg_replace('/_*$/', '', $dbkey);
     }
     # Reject illegal characters.
     $rxTc = self::getTitleInvalidRegex();
     $matches = array();
     if (preg_match($rxTc, $dbkey, $matches)) {
         throw new MalformedTitleException('title-invalid-characters', $text, array($matches[0]));
     }
     # Pages with "/./" or "/../" appearing in the URLs will often be un-
     # reachable due to the way web browsers deal with 'relative' URLs.
     # Also, they conflict with subpage syntax.  Forbid them explicitly.
     if (strpos($dbkey, '.') !== false && ($dbkey === '.' || $dbkey === '..' || strpos($dbkey, './') === 0 || strpos($dbkey, '../') === 0 || strpos($dbkey, '/./') !== false || strpos($dbkey, '/../') !== false || substr($dbkey, -2) == '/.' || substr($dbkey, -3) == '/..')) {
         throw new MalformedTitleException('title-invalid-relative', $text);
     }
     # Magic tilde sequences? Nu-uh!
     if (strpos($dbkey, '~~~') !== false) {
         throw new MalformedTitleException('title-invalid-magic-tilde', $text);
     }
     # Limit the size of titles to 255 bytes. This is typically the size of the
     # underlying database field. We make an exception for special pages, which
     # don't need to be stored in the database, and may edge over 255 bytes due
     # to subpage syntax for long titles, e.g. [[Special:Block/Long name]]
     $maxLength = $parts['namespace'] != NS_SPECIAL ? 255 : 512;
     if (strlen($dbkey) > $maxLength) {
         throw new MalformedTitleException('title-invalid-too-long', $text, array(Message::numParam($maxLength)));
     }
     # Normally, all wiki links are forced to have an initial capital letter so [[foo]]
     # and [[Foo]] point to the same place.  Don't force it for interwikis, since the
     # other site might be case-sensitive.
     $parts['user_case_dbkey'] = $dbkey;
     if ($parts['interwiki'] === '') {
         $dbkey = Title::capitalize($dbkey, $parts['namespace']);
     }
     # Can't make a link to a namespace alone... "empty" local links can only be
     # self-links with a fragment identifier.
     if ($dbkey == '' && $parts['interwiki'] === '') {
         if ($parts['namespace'] != NS_MAIN) {
             throw new MalformedTitleException('title-invalid-empty', $text);
         }
     }
     // Allow IPv6 usernames to start with '::' by canonicalizing IPv6 titles.
     // IP names are not allowed for accounts, and can only be referring to
     // edits from the IP. Given '::' abbreviations and caps/lowercaps,
     // there are numerous ways to present the same IP. Having sp:contribs scan
     // them all is silly and having some show the edits and others not is
     // inconsistent. Same for talk/userpages. Keep them normalized instead.
     if ($parts['namespace'] == NS_USER || $parts['namespace'] == NS_USER_TALK) {
         $dbkey = IP::sanitizeIP($dbkey);
     }
     // Any remaining initial :s are illegal.
     if ($dbkey !== '' && ':' == $dbkey[0]) {
         throw new MalformedTitleException('title-invalid-leading-colon', $text);
     }
     # Fill fields
     $parts['dbkey'] = $dbkey;
     return $parts;
 }
예제 #5
0
 function showList()
 {
     global $wgInterwikiCentralDB, $wgInterwikiViewOnly;
     $canModify = $this->canModify();
     // Build lists
     if (!method_exists('Interwiki', 'getAllPrefixes')) {
         // version 2.0 is not backwards compatible (but will still display a nice error)
         $this->error('interwiki_error');
         return;
     }
     $iwPrefixes = Interwiki::getAllPrefixes(null);
     $iwGlobalPrefixes = array();
     if ($wgInterwikiCentralDB !== null && $wgInterwikiCentralDB !== wfWikiId()) {
         // Fetch list from global table
         $dbrCentralDB = wfGetDB(DB_SLAVE, array(), $wgInterwikiCentralDB);
         $res = $dbrCentralDB->select('interwiki', '*', false, __METHOD__);
         $retval = array();
         foreach ($res as $row) {
             $row = (array) $row;
             if (!Language::fetchLanguageName($row['iw_prefix'])) {
                 $retval[] = $row;
             }
         }
         $iwGlobalPrefixes = $retval;
     }
     // Split out language links
     $iwLocalPrefixes = array();
     $iwLanguagePrefixes = array();
     foreach ($iwPrefixes as $iwPrefix) {
         if (Language::fetchLanguageName($iwPrefix['iw_prefix'])) {
             $iwLanguagePrefixes[] = $iwPrefix;
         } else {
             $iwLocalPrefixes[] = $iwPrefix;
         }
     }
     // Page intro content
     $this->getOutput()->addWikiMsg('interwiki_intro');
     // Add 'view log' link when possible
     if ($wgInterwikiViewOnly === false) {
         $logLink = Linker::link(SpecialPage::getTitleFor('Log', 'interwiki'), $this->msg('interwiki-logtext')->escaped());
         $this->getOutput()->addHTML('<p class="mw-interwiki-log">' . $logLink . '</p>');
     }
     // Add 'add' link
     if ($canModify) {
         if (count($iwGlobalPrefixes) !== 0) {
             $addtext = $this->msg('interwiki-addtext-local')->escaped();
         } else {
             $addtext = $this->msg('interwiki_addtext')->escaped();
         }
         $addlink = Linker::linkKnown($this->getPageTitle('add'), $addtext);
         $this->getOutput()->addHTML('<p class="mw-interwiki-addlink">' . $addlink . '</p>');
     }
     $this->getOutput()->addWikiMsg('interwiki-legend');
     if (!is_array($iwPrefixes) || count($iwPrefixes) === 0) {
         if (!is_array($iwGlobalPrefixes) || count($iwGlobalPrefixes) === 0) {
             // If the interwiki table(s) are empty, display an error message
             $this->error('interwiki_error');
             return;
         }
     }
     // Add the global table
     if (count($iwGlobalPrefixes) !== 0) {
         $this->getOutput()->addHTML('<h2 id="interwikitable-global">' . $this->msg('interwiki-global-links')->parse() . '</h2>');
         $this->getOutput()->addWikiMsg('interwiki-global-description');
         // $canModify is false here because this is just a display of remote data
         $this->makeTable(false, $iwGlobalPrefixes);
     }
     // Add the local table
     if (count($iwLocalPrefixes) !== 0) {
         if (count($iwGlobalPrefixes) !== 0) {
             $this->getOutput()->addHTML('<h2 id="interwikitable-local">' . $this->msg('interwiki-local-links')->parse() . '</h2>');
             $this->getOutput()->addWikiMsg('interwiki-local-description');
         } else {
             $this->getOutput()->addHTML('<h2 id="interwikitable-local">' . $this->msg('interwiki-links')->parse() . '</h2>');
             $this->getOutput()->addWikiMsg('interwiki-description');
         }
         $this->makeTable($canModify, $iwLocalPrefixes);
     }
     // Add the language table
     if (count($iwLanguagePrefixes) !== 0) {
         $this->getOutput()->addHTML('<h2 id="interwikitable-language">' . $this->msg('interwiki-language-links')->parse() . '</h2>');
         $this->getOutput()->addWikiMsg('interwiki-language-description');
         $this->makeTable($canModify, $iwLanguagePrefixes);
     }
 }
 protected function appendInterwikiMap($property, $filter)
 {
     $local = null;
     if ($filter === 'local') {
         $local = 1;
     } elseif ($filter === '!local') {
         $local = 0;
     } elseif ($filter) {
         ApiBase::dieDebug(__METHOD__, "Unknown filter={$filter}");
     }
     $params = $this->extractRequestParams();
     $langCode = isset($params['inlanguagecode']) ? $params['inlanguagecode'] : '';
     $langNames = Language::fetchLanguageNames($langCode);
     $getPrefixes = Interwiki::getAllPrefixes($local);
     $extraLangPrefixes = $this->getConfig()->get('ExtraInterlanguageLinkPrefixes');
     $localInterwikis = $this->getConfig()->get('LocalInterwikis');
     $data = array();
     foreach ($getPrefixes as $row) {
         $prefix = $row['iw_prefix'];
         $val = array();
         $val['prefix'] = $prefix;
         if (isset($row['iw_local']) && $row['iw_local'] == '1') {
             $val['local'] = '';
         }
         if ($row['iw_trans'] == '1') {
             $val['trans'] = '';
         }
         if (isset($langNames[$prefix])) {
             $val['language'] = $langNames[$prefix];
         }
         if (in_array($prefix, $localInterwikis)) {
             $val['localinterwiki'] = '';
         }
         if (in_array($prefix, $extraLangPrefixes)) {
             $val['extralanglink'] = '';
             $linktext = wfMessage("interlanguage-link-{$prefix}");
             if (!$linktext->isDisabled()) {
                 $val['linktext'] = $linktext->text();
             }
             $sitename = wfMessage("interlanguage-link-sitename-{$prefix}");
             if (!$sitename->isDisabled()) {
                 $val['sitename'] = $sitename->text();
             }
         }
         $val['url'] = wfExpandUrl($row['iw_url'], PROTO_CURRENT);
         if (substr($row['iw_url'], 0, 2) == '//') {
             $val['protorel'] = '';
         }
         if (isset($row['iw_wikiid'])) {
             $val['wikiid'] = $row['iw_wikiid'];
         }
         if (isset($row['iw_api'])) {
             $val['api'] = $row['iw_api'];
         }
         $data[] = $val;
     }
     $this->getResult()->setIndexedTagName($data, 'iw');
     return $this->getResult()->addValue('query', $property, $data);
 }
예제 #7
0
 /**
  * Secure and split - main initialisation function for this object
  *
  * Assumes that mDbkeyform has been set, and is urldecoded
  * and uses underscores, but not otherwise munged.  This function
  * removes illegal characters, splits off the interwiki and
  * namespace prefixes, sets the other forms, and canonicalizes
  * everything.
  * @return \type{\bool} true on success
  */
 private function secureAndSplit()
 {
     global $wgContLang, $wgLocalInterwiki, $wgCapitalLinks;
     # Initialisation
     static $rxTc = false;
     if (!$rxTc) {
         # Matching titles will be held as illegal.
         $rxTc = '/' . '[^' . Title::legalChars() . ']' . '|%[0-9A-Fa-f]{2}' . '|&[A-Za-z0-9\\x80-\\xff]+;' . '|&#[0-9]+;' . '|&#x[0-9A-Fa-f]+;' . '/S';
     }
     $this->mInterwiki = $this->mFragment = '';
     $this->mNamespace = $this->mDefaultNamespace;
     # Usually NS_MAIN
     $dbkey = $this->mDbkeyform;
     # Strip Unicode bidi override characters.
     # Sometimes they slip into cut-n-pasted page titles, where the
     # override chars get included in list displays.
     $dbkey = preg_replace('/\\xE2\\x80[\\x8E\\x8F\\xAA-\\xAE]/S', '', $dbkey);
     # Clean up whitespace
     #
     $dbkey = preg_replace('/[ _]+/', '_', $dbkey);
     $dbkey = trim($dbkey, '_');
     if ('' == $dbkey) {
         return false;
     }
     if (false !== strpos($dbkey, UTF8_REPLACEMENT)) {
         # Contained illegal UTF-8 sequences or forbidden Unicode chars.
         return false;
     }
     $this->mDbkeyform = $dbkey;
     # Initial colon indicates main namespace rather than specified default
     # but should not create invalid {ns,title} pairs such as {0,Project:Foo}
     if (':' == $dbkey[0]) {
         $this->mNamespace = NS_MAIN;
         $dbkey = substr($dbkey, 1);
         # remove the colon but continue processing
         $dbkey = trim($dbkey, '_');
         # remove any subsequent whitespace
     }
     # Namespace or interwiki prefix
     $firstPass = true;
     do {
         $m = array();
         if (preg_match("/^(.+?)_*:_*(.*)\$/S", $dbkey, $m)) {
             $p = $m[1];
             if ($ns = $wgContLang->getNsIndex($p)) {
                 # Ordinary namespace
                 $dbkey = $m[2];
                 $this->mNamespace = $ns;
             } elseif (Interwiki::isValidInterwiki($p)) {
                 if (!$firstPass) {
                     # Can't make a local interwiki link to an interwiki link.
                     # That's just crazy!
                     return false;
                 }
                 # Interwiki link
                 $dbkey = $m[2];
                 $this->mInterwiki = $wgContLang->lc($p);
                 # Redundant interwiki prefix to the local wiki
                 if (0 == strcasecmp($this->mInterwiki, $wgLocalInterwiki)) {
                     if ($dbkey == '') {
                         # Can't have an empty self-link
                         return false;
                     }
                     $this->mInterwiki = '';
                     $firstPass = false;
                     # Do another namespace split...
                     continue;
                 }
                 # If there's an initial colon after the interwiki, that also
                 # resets the default namespace
                 if ($dbkey !== '' && $dbkey[0] == ':') {
                     $this->mNamespace = NS_MAIN;
                     $dbkey = substr($dbkey, 1);
                 }
             }
             # If there's no recognized interwiki or namespace,
             # then let the colon expression be part of the title.
         }
         break;
     } while (true);
     # We already know that some pages won't be in the database!
     #
     if ('' != $this->mInterwiki || NS_SPECIAL == $this->mNamespace) {
         $this->mArticleID = 0;
     }
     $fragment = strstr($dbkey, '#');
     if (false !== $fragment) {
         $this->setFragment($fragment);
         $dbkey = substr($dbkey, 0, strlen($dbkey) - strlen($fragment));
         # remove whitespace again: prevents "Foo_bar_#"
         # becoming "Foo_bar_"
         $dbkey = preg_replace('/_*$/', '', $dbkey);
     }
     # Reject illegal characters.
     #
     if (preg_match($rxTc, $dbkey)) {
         return false;
     }
     /**
      * Pages with "/./" or "/../" appearing in the URLs will often be un-
      * reachable due to the way web browsers deal with 'relative' URLs.
      * Also, they conflict with subpage syntax.  Forbid them explicitly.
      */
     if (strpos($dbkey, '.') !== false && ($dbkey === '.' || $dbkey === '..' || strpos($dbkey, './') === 0 || strpos($dbkey, '../') === 0 || strpos($dbkey, '/./') !== false || strpos($dbkey, '/../') !== false || substr($dbkey, -2) == '/.' || substr($dbkey, -3) == '/..')) {
         return false;
     }
     /**
      * Magic tilde sequences? Nu-uh!
      */
     if (strpos($dbkey, '~~~') !== false) {
         return false;
     }
     /**
      * Limit the size of titles to 255 bytes.
      * This is typically the size of the underlying database field.
      * We make an exception for special pages, which don't need to be stored
      * in the database, and may edge over 255 bytes due to subpage syntax
      * for long titles, e.g. [[Special:Block/Long name]]
      */
     if ($this->mNamespace != NS_SPECIAL && strlen($dbkey) > 255 || strlen($dbkey) > 512) {
         return false;
     }
     /**
      * Normally, all wiki links are forced to have
      * an initial capital letter so [[foo]] and [[Foo]]
      * point to the same place.
      *
      * Don't force it for interwikis, since the other
      * site might be case-sensitive.
      */
     $this->mUserCaseDBKey = $dbkey;
     if ($wgCapitalLinks && $this->mInterwiki == '') {
         $dbkey = $wgContLang->ucfirst($dbkey);
     }
     /**
      * Can't make a link to a namespace alone...
      * "empty" local links can only be self-links
      * with a fragment identifier.
      */
     if ($dbkey == '' && $this->mInterwiki == '' && $this->mNamespace != NS_MAIN) {
         return false;
     }
     // Allow IPv6 usernames to start with '::' by canonicalizing IPv6 titles.
     // IP names are not allowed for accounts, and can only be referring to
     // edits from the IP. Given '::' abbreviations and caps/lowercaps,
     // there are numerous ways to present the same IP. Having sp:contribs scan
     // them all is silly and having some show the edits and others not is
     // inconsistent. Same for talk/userpages. Keep them normalized instead.
     $dbkey = $this->mNamespace == NS_USER || $this->mNamespace == NS_USER_TALK ? IP::sanitizeIP($dbkey) : $dbkey;
     // Any remaining initial :s are illegal.
     if ($dbkey !== '' && ':' == $dbkey[0]) {
         return false;
     }
     # Fill fields
     $this->mDbkeyform = $dbkey;
     $this->mUrlform = wfUrlencode($dbkey);
     $this->mTextform = str_replace('_', ' ', $dbkey);
     return true;
 }
예제 #8
0
 /**
  * Get a URL with no fragment or server name (relative URL) from a Title object.
  * If this page is generated with action=render, however,
  * $wgServer is prepended to make an absolute URL.
  *
  * @see self::getFullURL to always get an absolute URL.
  * @see self::getLinkURL to always get a URL that's the simplest URL that will be
  *  valid to link, locally, to the current Title.
  * @see self::newFromText to produce a Title object.
  *
  * @param string|array $query An optional query string,
  *   not used for interwiki links. Can be specified as an associative array as well,
  *   e.g., array( 'action' => 'edit' ) (keys and values will be URL-escaped).
  *   Some query patterns will trigger various shorturl path replacements.
  * @param array $query2 An optional secondary query array. This one MUST
  *   be an array. If a string is passed it will be interpreted as a deprecated
  *   variant argument and urlencoded into a variant= argument.
  *   This second query argument will be added to the $query
  *   The second parameter is deprecated since 1.19. Pass it as a key,value
  *   pair in the first parameter array instead.
  *
  * @return string String of the URL.
  */
 public function getLocalURL($query = '', $query2 = false)
 {
     global $wgArticlePath, $wgScript, $wgServer, $wgRequest;
     $query = self::fixUrlQueryArgs($query, $query2);
     $interwiki = Interwiki::fetch($this->mInterwiki);
     if ($interwiki) {
         $namespace = $this->getNsText();
         if ($namespace != '') {
             # Can this actually happen? Interwikis shouldn't be parsed.
             # Yes! It can in interwiki transclusion. But... it probably shouldn't.
             $namespace .= ':';
         }
         $url = $interwiki->getURL($namespace . $this->getDBkey());
         $url = wfAppendQuery($url, $query);
     } else {
         $dbkey = wfUrlencode($this->getPrefixedDBkey());
         if ($query == '') {
             $url = str_replace('$1', $dbkey, $wgArticlePath);
             Hooks::run('GetLocalURL::Article', array(&$this, &$url));
         } else {
             global $wgVariantArticlePath, $wgActionPaths, $wgContLang;
             $url = false;
             $matches = array();
             if (!empty($wgActionPaths) && preg_match('/^(.*&|)action=([^&]*)(&(.*)|)$/', $query, $matches)) {
                 $action = urldecode($matches[2]);
                 if (isset($wgActionPaths[$action])) {
                     $query = $matches[1];
                     if (isset($matches[4])) {
                         $query .= $matches[4];
                     }
                     $url = str_replace('$1', $dbkey, $wgActionPaths[$action]);
                     if ($query != '') {
                         $url = wfAppendQuery($url, $query);
                     }
                 }
             }
             if ($url === false && $wgVariantArticlePath && $wgContLang->getCode() === $this->getPageLanguage()->getCode() && $this->getPageLanguage()->hasVariants() && preg_match('/^variant=([^&]*)$/', $query, $matches)) {
                 $variant = urldecode($matches[1]);
                 if ($this->getPageLanguage()->hasVariant($variant)) {
                     // Only do the variant replacement if the given variant is a valid
                     // variant for the page's language.
                     $url = str_replace('$2', urlencode($variant), $wgVariantArticlePath);
                     $url = str_replace('$1', $dbkey, $url);
                 }
             }
             if ($url === false) {
                 if ($query == '-') {
                     $query = '';
                 }
                 $url = "{$wgScript}?title={$dbkey}&{$query}";
             }
         }
         Hooks::run('GetLocalURL::Internal', array(&$this, &$url, $query));
         // @todo FIXME: This causes breakage in various places when we
         // actually expected a local URL and end up with dupe prefixes.
         if ($wgRequest->getVal('action') == 'render') {
             $url = $wgServer . $url;
         }
     }
     Hooks::run('GetLocalURL', array(&$this, &$url, $query));
     return $url;
 }
예제 #9
0
 protected function appendInterwikiMap($property, $filter)
 {
     $local = null;
     if ($filter === 'local') {
         $local = 1;
     } elseif ($filter === '!local') {
         $local = 0;
     } elseif ($filter) {
         ApiBase::dieDebug(__METHOD__, "Unknown filter={$filter}");
     }
     $params = $this->extractRequestParams();
     $langCode = isset($params['inlanguagecode']) ? $params['inlanguagecode'] : '';
     if ($langCode) {
         $langNames = Language::getTranslatedLanguageNames($langCode);
     } else {
         $langNames = Language::getLanguageNames();
     }
     $getPrefixes = Interwiki::getAllPrefixes($local);
     $data = array();
     foreach ($getPrefixes as $row) {
         $prefix = $row['iw_prefix'];
         $val = array();
         $val['prefix'] = $prefix;
         if ($row['iw_local'] == '1') {
             $val['local'] = '';
         }
         // $val['trans'] = intval( $row['iw_trans'] ); // should this be exposed?
         if (isset($langNames[$prefix])) {
             $val['language'] = $langNames[$prefix];
         }
         $val['url'] = wfExpandUrl($row['iw_url'], PROTO_CURRENT);
         if (isset($row['iw_wikiid'])) {
             $val['wikiid'] = $row['iw_wikiid'];
         }
         if (isset($row['iw_api'])) {
             $val['api'] = $row['iw_api'];
         }
         $data[] = $val;
     }
     $this->getResult()->setIndexedTagName($data, 'iw');
     return $this->getResult()->addValue('query', $property, $data);
 }
예제 #10
0
 /**
  * Load the interwiki, trying first memcached then the DB
  *
  * @param string $prefix The interwiki prefix
  * @return Interwiki|bool Interwiki if $prefix is valid, otherwise false
  */
 protected static function load($prefix)
 {
     global $wgInterwikiExpiry;
     $iwData = array();
     if (!Hooks::run('InterwikiLoadPrefix', array($prefix, &$iwData))) {
         return Interwiki::loadFromArray($iwData);
     }
     if (is_array($iwData)) {
         $iw = Interwiki::loadFromArray($iwData);
         if ($iw) {
             return $iw;
             // handled by hook
         }
     }
     $iwData = ObjectCache::getMainWANInstance()->getWithSetCallback(wfMemcKey('interwiki', $prefix), $wgInterwikiExpiry, function ($oldValue, &$ttl, array &$setOpts) use($prefix) {
         $dbr = wfGetDB(DB_SLAVE);
         $setOpts += Database::getCacheSetOptions($dbr);
         $row = $dbr->selectRow('interwiki', Interwiki::selectFields(), array('iw_prefix' => $prefix), __METHOD__);
         return $row ? (array) $row : '!NONEXISTENT';
     });
     if (is_array($iwData)) {
         return Interwiki::loadFromArray($iwData) ?: false;
     }
     return false;
 }
예제 #11
0
 public function testArrayStorage()
 {
     $dewiki = ['iw_prefix' => 'de', 'iw_url' => 'http://de.wikipedia.org/wiki/', 'iw_local' => 1];
     $zzwiki = ['iw_prefix' => 'zz', 'iw_url' => 'http://zzwiki.org/wiki/', 'iw_local' => 0];
     $cdbData = $this->populateHash('en', [$dewiki], [$zzwiki]);
     $this->setWgInterwikiCache($cdbData);
     $this->assertEquals([$dewiki, $zzwiki], Interwiki::getAllPrefixes(), 'getAllPrefixes()');
     $this->assertTrue(Interwiki::isValidInterwiki('de'), 'known prefix is valid');
     $this->assertTrue(Interwiki::isValidInterwiki('zz'), 'known prefix is valid');
     $interwiki = Interwiki::fetch('de');
     $this->assertInstanceOf('Interwiki', $interwiki);
     $this->assertSame('http://de.wikipedia.org/wiki/', $interwiki->getURL(), 'getURL');
     $this->assertSame(true, $interwiki->isLocal(), 'isLocal');
     $interwiki = Interwiki::fetch('zz');
     $this->assertInstanceOf('Interwiki', $interwiki);
     $this->assertSame('http://zzwiki.org/wiki/', $interwiki->getURL(), 'getURL');
     $this->assertSame(false, $interwiki->isLocal(), 'isLocal');
 }
 /**
  * Generate the URL out of the object reference
  *
  * @param string $objRef
  * @return bool|string
  */
 private function getButtonHrefByObjectReference($objRef)
 {
     $arrObjRef = explode('|', $objRef);
     if (count($arrObjRef) > 1) {
         list($wiki, $title) = $arrObjRef;
         if (Interwiki::isValidInterwiki($wiki)) {
             return str_replace('$1', $title, Interwiki::fetch($wiki)->getURL());
         }
     }
     return false;
 }
예제 #13
0
 public function interwikiMap($filter = null)
 {
     global $wgLocalInterwikis, $wgExtraInterlanguageLinkPrefixes;
     $this->checkTypeOptional('interwikiMap', 1, $filter, 'string', null);
     $local = null;
     if ($filter === 'local') {
         $local = 1;
     } elseif ($filter === '!local') {
         $local = 0;
     } elseif ($filter !== null) {
         throw new Scribunto_LuaError("bad argument #1 to 'interwikiMap' (unknown filter '{$filter}')");
     }
     $cacheKey = $filter === null ? 'null' : $filter;
     if (!isset(self::$interwikiMapCache[$cacheKey])) {
         // Not expensive because we can have a max of three cache misses in the
         // entire page parse.
         $interwikiMap = array();
         $prefixes = Interwiki::getAllPrefixes($local);
         foreach ($prefixes as $row) {
             $prefix = $row['iw_prefix'];
             $val = array('prefix' => $prefix, 'url' => wfExpandUrl($row['iw_url'], PROTO_RELATIVE), 'isProtocolRelative' => substr($row['iw_url'], 0, 2) === '//', 'isLocal' => isset($row['iw_local']) && $row['iw_local'] == '1', 'isTranscludable' => isset($row['iw_trans']) && $row['iw_trans'] == '1', 'isCurrentWiki' => in_array($prefix, $wgLocalInterwikis), 'isExtraLanguageLink' => in_array($prefix, $wgExtraInterlanguageLinkPrefixes));
             if ($val['isExtraLanguageLink']) {
                 $displayText = wfMessage("interlanguage-link-{$prefix}");
                 if (!$displayText->isDisabled()) {
                     $val['displayText'] = $displayText->text();
                 }
                 $tooltip = wfMessage("interlanguage-link-sitename-{$prefix}");
                 if (!$tooltip->isDisabled()) {
                     $val['tooltip'] = $tooltip->text();
                 }
             }
             $interwikiMap[$prefix] = $val;
         }
         self::$interwikiMapCache[$cacheKey] = $interwikiMap;
     }
     return array(self::$interwikiMapCache[$cacheKey]);
 }
예제 #14
0
 /**
  * Load the interwiki, trying first memcached then the DB
  *
  * @param $prefix The interwiki prefix
  * @return bool The prefix is valid
  * @static
  *
  */
 protected static function load($prefix)
 {
     global $wgMemc, $wgInterwikiExpiry;
     global $wgLanguageNames;
     $key = wfMemcKey('interwiki', $prefix);
     $mc = $wgMemc->get($key);
     $iw = false;
     if ($mc && is_array($mc)) {
         // is_array is hack for old keys
         $iw = Interwiki::loadFromArray($mc);
         if ($iw) {
             return $iw;
         }
     }
     # $$$ Sean: This is a hack to get the interwiki links working
     # but only accept a prefix that is a valid language
     if (isset($prefix, $wgLanguageNames[$prefix]) && '' != $wgLanguageNames[$prefix]) {
         $iw = new Interwiki();
         $iw->mURL = $prefix . '.wiki';
         $iw->mLocal = 0;
         $iw->mTrans = 0;
     } else {
         $iw = false;
     }
     /*
     $db = wfGetDB( DB_SLAVE );
     
     $row = $db->fetchRow( $db->select( 'interwiki', '*', array( 'iw_prefix' => $prefix ),
     	__METHOD__ ) );
     $iw = Interwiki::loadFromArray( $row );
     */
     # $$$ end of hack
     if ($iw) {
         $mc = array('iw_url' => $iw->mURL, 'iw_local' => $iw->mLocal, 'iw_trans' => $iw->mTrans);
         $wgMemc->add($key, $mc, $wgInterwikiExpiry);
         return $iw;
     }
     return false;
 }
예제 #15
0
 /**
  * Load the interwiki, trying first memcached then the DB
  *
  * @param $prefix string The interwiki prefix
  * @return Boolean: the prefix is valid
  */
 protected static function load($prefix)
 {
     global $wgMemc, $wgInterwikiExpiry;
     $iwData = false;
     if (!wfRunHooks('InterwikiLoadPrefix', array($prefix, &$iwData))) {
         return Interwiki::loadFromArray($iwData);
     }
     if (!$iwData) {
         $key = wfMemcKey('interwiki', md5($prefix));
         $iwData = $wgMemc->get($key);
         if ($iwData === '!NONEXISTENT') {
             return false;
             // negative cache hit
         }
     }
     if ($iwData && is_array($iwData)) {
         // is_array is hack for old keys
         $iw = Interwiki::loadFromArray($iwData);
         if ($iw) {
             return $iw;
         }
     }
     $db = wfGetDB(DB_SLAVE);
     $row = $db->fetchRow($db->select('interwiki', '*', array('iw_prefix' => $prefix), __METHOD__));
     $iw = Interwiki::loadFromArray($row);
     if ($iw) {
         $mc = array('iw_url' => $iw->mURL, 'iw_api' => $iw->mAPI, 'iw_local' => $iw->mLocal, 'iw_trans' => $iw->mTrans);
         $wgMemc->add($key, $mc, $wgInterwikiExpiry);
         return $iw;
     } else {
         $wgMemc->add($key, '!NONEXISTENT', $wgInterwikiExpiry);
         // negative cache hit
     }
     return false;
 }
예제 #16
0
 /**
  * Secure and split - main initialisation function for this object
  *
  * Assumes that mDbkeyform has been set, and is urldecoded
  * and uses underscores, but not otherwise munged.  This function
  * removes illegal characters, splits off the interwiki and
  * namespace prefixes, sets the other forms, and canonicalizes
  * everything.
  *
  * @return Bool true on success
  */
 private function secureAndSplit()
 {
     global $wgContLang, $wgLocalInterwiki;
     # Initialisation
     $this->mInterwiki = $this->mFragment = '';
     $this->mNamespace = $this->mDefaultNamespace;
     # Usually NS_MAIN
     $dbkey = $this->mDbkeyform;
     # Strip Unicode bidi override characters.
     # Sometimes they slip into cut-n-pasted page titles, where the
     # override chars get included in list displays.
     $dbkey = preg_replace('/\\xE2\\x80[\\x8E\\x8F\\xAA-\\xAE]/S', '', $dbkey);
     # Clean up whitespace
     # Note: use of the /u option on preg_replace here will cause
     # input with invalid UTF-8 sequences to be nullified out in PHP 5.2.x,
     # conveniently disabling them.
     $dbkey = preg_replace('/[ _\\xA0\\x{1680}\\x{180E}\\x{2000}-\\x{200A}\\x{2028}\\x{2029}\\x{202F}\\x{205F}\\x{3000}]+/u', '_', $dbkey);
     $dbkey = trim($dbkey, '_');
     if ($dbkey == '') {
         return false;
     }
     if (false !== strpos($dbkey, UTF8_REPLACEMENT)) {
         # Contained illegal UTF-8 sequences or forbidden Unicode chars.
         return false;
     }
     $this->mDbkeyform = $dbkey;
     # Initial colon indicates main namespace rather than specified default
     # but should not create invalid {ns,title} pairs such as {0,Project:Foo}
     if (':' == $dbkey[0]) {
         $this->mNamespace = NS_MAIN;
         $dbkey = substr($dbkey, 1);
         # remove the colon but continue processing
         $dbkey = trim($dbkey, '_');
         # remove any subsequent whitespace
     }
     # Namespace or interwiki prefix
     $firstPass = true;
     $prefixRegexp = "/^(.+?)_*:_*(.*)\$/S";
     do {
         $m = array();
         if (preg_match($prefixRegexp, $dbkey, $m)) {
             $p = $m[1];
             if (($ns = $wgContLang->getNsIndex($p)) !== false) {
                 # Ordinary namespace
                 $dbkey = $m[2];
                 $this->mNamespace = $ns;
                 # For Talk:X pages, check if X has a "namespace" prefix
                 if ($ns == NS_TALK && preg_match($prefixRegexp, $dbkey, $x)) {
                     if ($wgContLang->getNsIndex($x[1])) {
                         # Disallow Talk:File:x type titles...
                         return false;
                     } elseif (Interwiki::isValidInterwiki($x[1])) {
                         # Disallow Talk:Interwiki:x type titles...
                         return false;
                     }
                 }
             } elseif (Interwiki::isValidInterwiki($p)) {
                 if (!$firstPass) {
                     # Can't make a local interwiki link to an interwiki link.
                     # That's just crazy!
                     return false;
                 }
                 # Interwiki link
                 $dbkey = $m[2];
                 $this->mInterwiki = $wgContLang->lc($p);
                 # Redundant interwiki prefix to the local wiki
                 if ($wgLocalInterwiki !== false && 0 == strcasecmp($this->mInterwiki, $wgLocalInterwiki)) {
                     if ($dbkey == '') {
                         # Can't have an empty self-link
                         return false;
                     }
                     $this->mInterwiki = '';
                     $firstPass = false;
                     # Do another namespace split...
                     continue;
                 }
                 # If there's an initial colon after the interwiki, that also
                 # resets the default namespace
                 if ($dbkey !== '' && $dbkey[0] == ':') {
                     $this->mNamespace = NS_MAIN;
                     $dbkey = substr($dbkey, 1);
                 }
             }
             # If there's no recognized interwiki or namespace,
             # then let the colon expression be part of the title.
         }
         break;
     } while (true);
     # We already know that some pages won't be in the database!
     if ($this->mInterwiki != '' || NS_SPECIAL == $this->mNamespace) {
         $this->mArticleID = 0;
     }
     $fragment = strstr($dbkey, '#');
     if (false !== $fragment) {
         $this->setFragment($fragment);
         $dbkey = substr($dbkey, 0, strlen($dbkey) - strlen($fragment));
         # remove whitespace again: prevents "Foo_bar_#"
         # becoming "Foo_bar_"
         $dbkey = preg_replace('/_*$/', '', $dbkey);
     }
     # Reject illegal characters.
     $rxTc = self::getTitleInvalidRegex();
     if (preg_match($rxTc, $dbkey)) {
         return false;
     }
     # Pages with "/./" or "/../" appearing in the URLs will often be un-
     # reachable due to the way web browsers deal with 'relative' URLs.
     # Also, they conflict with subpage syntax.  Forbid them explicitly.
     if (strpos($dbkey, '.') !== false && ($dbkey === '.' || $dbkey === '..' || strpos($dbkey, './') === 0 || strpos($dbkey, '../') === 0 || strpos($dbkey, '/./') !== false || strpos($dbkey, '/../') !== false || substr($dbkey, -2) == '/.' || substr($dbkey, -3) == '/..')) {
         return false;
     }
     # Magic tilde sequences? Nu-uh!
     if (strpos($dbkey, '~~~') !== false) {
         return false;
     }
     # Limit the size of titles to 255 bytes. This is typically the size of the
     # underlying database field. We make an exception for special pages, which
     # don't need to be stored in the database, and may edge over 255 bytes due
     # to subpage syntax for long titles, e.g. [[Special:Block/Long name]]
     if ($this->mNamespace != NS_SPECIAL && strlen($dbkey) > 255 || strlen($dbkey) > 512) {
         return false;
     }
     # Normally, all wiki links are forced to have an initial capital letter so [[foo]]
     # and [[Foo]] point to the same place.  Don't force it for interwikis, since the
     # other site might be case-sensitive.
     $this->mUserCaseDBKey = $dbkey;
     if ($this->mInterwiki == '') {
         $dbkey = self::capitalize($dbkey, $this->mNamespace);
     }
     # Can't make a link to a namespace alone... "empty" local links can only be
     # self-links with a fragment identifier.
     if ($dbkey == '' && $this->mInterwiki == '' && $this->mNamespace != NS_MAIN) {
         return false;
     }
     // Allow IPv6 usernames to start with '::' by canonicalizing IPv6 titles.
     // IP names are not allowed for accounts, and can only be referring to
     // edits from the IP. Given '::' abbreviations and caps/lowercaps,
     // there are numerous ways to present the same IP. Having sp:contribs scan
     // them all is silly and having some show the edits and others not is
     // inconsistent. Same for talk/userpages. Keep them normalized instead.
     $dbkey = $this->mNamespace == NS_USER || $this->mNamespace == NS_USER_TALK ? IP::sanitizeIP($dbkey) : $dbkey;
     // Any remaining initial :s are illegal.
     if ($dbkey !== '' && ':' == $dbkey[0]) {
         return false;
     }
     # Fill fields
     $this->mDbkeyform = $dbkey;
     $this->mUrlform = wfUrlencode($dbkey);
     $this->mTextform = str_replace('_', ' ', $dbkey);
     return true;
 }
예제 #17
0
 function showList()
 {
     $canModify = $this->canModify();
     $this->getOutput()->addWikiMsg('interwiki_intro');
     $this->getOutput()->addHTML(Html::rawElement('table', array('class' => 'mw-interwikitable wikitable intro'), self::addInfoRow('start', 'interwiki_prefix', 'interwiki_prefix_intro') . self::addInfoRow('start', 'interwiki_url', 'interwiki_url_intro') . self::addInfoRow('start', 'interwiki_local', 'interwiki_local_intro') . self::addInfoRow('end', 'interwiki_0', 'interwiki_local_0_intro') . self::addInfoRow('end', 'interwiki_1', 'interwiki_local_1_intro') . self::addInfoRow('start', 'interwiki_trans', 'interwiki_trans_intro') . self::addInfoRow('end', 'interwiki_0', 'interwiki_trans_0_intro') . self::addInfoRow('end', 'interwiki_1', 'interwiki_trans_1_intro')) . "\n");
     $this->getOutput()->addWikiMsg('interwiki_intro_footer');
     if ($canModify) {
         $addtext = wfMessage('interwiki_addtext')->escaped();
         $addlink = Linker::linkKnown($this->getTitle('add'), $addtext);
         $this->getOutput()->addHTML('<p class="mw-interwiki-addlink">' . $addlink . '</p>');
     }
     if (!method_exists('Interwiki', 'getAllPrefixes')) {
         # version 2.0 is not backwards compatible (but still display nice error)
         $this->error('interwiki_error');
         return;
     }
     $iwPrefixes = Interwiki::getAllPrefixes(null);
     if (!is_array($iwPrefixes) || count($iwPrefixes) == 0) {
         # If the interwiki table is empty, display an error message
         $this->error('interwiki_error');
         return;
     }
     $out = '';
     # Output the table header
     $out .= Html::openElement('table', array('class' => 'mw-interwikitable wikitable sortable body')) . "\n";
     $out .= Html::openElement('tr', array('id' => 'interwikitable-header')) . Html::element('th', null, wfMessage('interwiki_prefix')) . Html::element('th', null, wfMessage('interwiki_url')) . Html::element('th', null, wfMessage('interwiki_local')) . Html::element('th', null, wfMessage('interwiki_trans')) . ($canModify ? Html::element('th', array('class' => 'unsortable'), wfMessage('interwiki_edit')) : '');
     $out .= Html::closeElement('tr') . "\n";
     $selfTitle = $this->getTitle();
     foreach ($iwPrefixes as $i => $iwPrefix) {
         $out .= Html::openElement('tr', array('class' => 'mw-interwikitable-row'));
         $out .= Html::element('td', array('class' => 'mw-interwikitable-prefix'), htmlspecialchars($iwPrefix['iw_prefix']));
         $out .= Html::element('td', array('class' => 'mw-interwikitable-url'), $iwPrefix['iw_url']);
         $out .= Html::element('td', array('class' => 'mw-interwikitable-local'), isset($iwPrefix['iw_local']) ? wfMessage('interwiki_' . $iwPrefix['iw_local']) : '-');
         $out .= Html::element('td', array('class' => 'mw-interwikitable-trans'), isset($iwPrefix['iw_trans']) ? wfMessage('interwiki_' . $iwPrefix['iw_trans']) : '-');
         if ($canModify) {
             $out .= Html::rawElement('td', array('class' => 'mw-interwikitable-modify'), Linker::linkKnown($selfTitle, wfMessage('edit')->escaped(), array(), array('action' => 'edit', 'prefix' => $iwPrefix['iw_prefix'])) . wfMessage('comma-separator') . Linker::linkKnown($selfTitle, wfMessage('delete')->escaped(), array(), array('action' => 'delete', 'prefix' => $iwPrefix['iw_prefix'])));
         }
         $out .= Html::closeElement('tr') . "\n";
     }
     $out .= Html::closeElement('table');
     $this->getOutput()->addHTML($out);
 }
예제 #18
0
 function showList()
 {
     $canModify = $this->canModify();
     $this->getOutput()->addWikiMsg('interwiki_intro');
     // Make collapsible.
     $this->getOutput()->addHTML(Html::openElement('div', array('class' => 'mw-collapsible mw-collapsed', 'data-collapsetext' => $this->msg('interwiki-legend-hide')->escaped(), 'data-expandtext' => $this->msg('interwiki-legend-show')->escaped())));
     $this->getOutput()->addHTML(Html::rawElement('table', array('class' => 'mw-interwikitable wikitable intro'), $this->addInfoRow('start', 'interwiki_prefix', 'interwiki_prefix_intro') . "\n" . $this->addInfoRow('start', 'interwiki_url', 'interwiki_url_intro') . "\n" . $this->addInfoRow('start', 'interwiki_local', 'interwiki_local_intro') . "\n" . $this->addInfoRow('end', 'interwiki_0', 'interwiki_local_0_intro') . "\n" . $this->addInfoRow('end', 'interwiki_1', 'interwiki_local_1_intro') . "\n" . $this->addInfoRow('start', 'interwiki_trans', 'interwiki_trans_intro') . "\n" . $this->addInfoRow('end', 'interwiki_0', 'interwiki_trans_0_intro') . "\n" . $this->addInfoRow('end', 'interwiki_1', 'interwiki_trans_1_intro') . "\n"));
     $this->getOutput()->addHTML(Html::closeElement('div'));
     // end collapsible.
     if ($canModify) {
         $this->getOutput()->addHTML("<br />" . $this->msg('interwiki_intro_footer')->parse());
         $addtext = $this->msg('interwiki_addtext')->escaped();
         $addlink = Linker::linkKnown($this->getTitle('add'), $addtext);
         $this->getOutput()->addHTML('<p class="mw-interwiki-addlink">' . $addlink . '</p>');
     }
     if (!method_exists('Interwiki', 'getAllPrefixes')) {
         # version 2.0 is not backwards compatible (but still display nice error)
         $this->error('interwiki_error');
         return;
     }
     $iwPrefixes = Interwiki::getAllPrefixes(null);
     if (!is_array($iwPrefixes) || count($iwPrefixes) === 0) {
         # If the interwiki table is empty, display an error message
         $this->error('interwiki_error');
         return;
     }
     # Output the existing Interwiki prefixes table header
     $out = '';
     $out .= Html::openElement('table', array('class' => 'mw-interwikitable wikitable sortable body')) . "\n";
     $out .= Html::openElement('tr', array('id' => 'interwikitable-header')) . Html::element('th', null, $this->msg('interwiki_prefix')->text()) . Html::element('th', null, $this->msg('interwiki_url')->text()) . Html::element('th', null, $this->msg('interwiki_local')->text()) . Html::element('th', null, $this->msg('interwiki_trans')->text()) . ($canModify ? Html::element('th', array('class' => 'unsortable'), $this->msg('interwiki_edit')->text()) : '');
     $out .= Html::closeElement('tr') . "\n";
     $selfTitle = $this->getTitle();
     # Output the existing Interwiki prefixes table rows
     foreach ($iwPrefixes as $iwPrefix) {
         $out .= Html::openElement('tr', array('class' => 'mw-interwikitable-row'));
         $out .= Html::element('td', array('class' => 'mw-interwikitable-prefix'), $iwPrefix['iw_prefix']);
         $out .= Html::element('td', array('class' => 'mw-interwikitable-url'), $iwPrefix['iw_url']);
         $attribs = array('class' => 'mw-interwikitable-local');
         // Green background for cells with "yes".
         if ($iwPrefix['iw_local']) {
             $attribs['style'] = 'background: lime;';
         }
         // The messages interwiki_0 and interwiki_1 are used here.
         $contents = isset($iwPrefix['iw_local']) ? $this->msg('interwiki_' . $iwPrefix['iw_local'])->text() : '-';
         $out .= Html::element('td', $attribs, $contents);
         $attribs = array('class' => 'mw-interwikitable-trans');
         // Green background for cells with "yes".
         if ($iwPrefix['iw_trans']) {
             $attribs['style'] = 'background: lime;';
         }
         // The messages interwiki_0 and interwiki_1 are used here.
         $contents = isset($iwPrefix['iw_trans']) ? $this->msg('interwiki_' . $iwPrefix['iw_trans'])->text() : '-';
         $out .= Html::element('td', $attribs, $contents);
         // Additional column when the interwiki table can be modified.
         if ($canModify) {
             $out .= Html::rawElement('td', array('class' => 'mw-interwikitable-modify'), Linker::linkKnown($selfTitle, $this->msg('edit')->escaped(), array(), array('action' => 'edit', 'prefix' => $iwPrefix['iw_prefix'])) . $this->msg('comma-separator') . Linker::linkKnown($selfTitle, $this->msg('delete')->escaped(), array(), array('action' => 'delete', 'prefix' => $iwPrefix['iw_prefix'])));
         }
         $out .= Html::closeElement('tr') . "\n";
     }
     $out .= Html::closeElement('table');
     $this->getOutput()->addHTML($out);
 }
    /**
     * Get a list of languages available for this project
     * @return string parsed Html
     */
    private function getSiteSelector()
    {
        $selector = '';
        $count = 0;
        $language = $this->getLanguage();
        foreach (Interwiki::getAllPrefixes(true) as $interwiki) {
            $code = $interwiki['iw_prefix'];
            $name = $language->fetchLanguageName($code);
            if (!$name) {
                continue;
            }
            $title = Title::newFromText("{$code}:");
            if ($title) {
                $url = $title->getFullURL();
            } else {
                $url = '';
            }
            $attrs = array('href' => $url);
            $count++;
            if ($code == $this->getConfig()->get('LanguageCode')) {
                $attrs['class'] = 'selected';
            }
            $selector .= Html::openElement('li');
            $selector .= Html::element('a', $attrs, $name);
            $selector .= Html::closeElement('li');
        }
        if ($selector && $count > 1) {
            $selector = <<<HTML
\t\t\t<p>{$this->msg('mobile-frontend-settings-site-description', $count)->parse()}</p>
\t\t\t<ul id='mw-mf-language-list'>
\t\t\t\t{$selector}
\t\t\t</ul>
HTML;
        }
        return $selector;
    }
예제 #20
0
 /**
  * @param string $interwiki
  * @param string $page
  * @param bool $history
  * @param bool $templates
  * @param int $pageLinkDepth
  * @return Status
  */
 public static function newFromInterwiki($interwiki, $page, $history = false, $templates = false, $pageLinkDepth = 0)
 {
     if ($page == '') {
         return Status::newFatal('import-noarticle');
     }
     # Look up the first interwiki prefix, and let the foreign site handle
     # subsequent interwiki prefixes
     $firstIwPrefix = strtok($interwiki, ':');
     $firstIw = Interwiki::fetch($firstIwPrefix);
     if (!$firstIw) {
         return Status::newFatal('importbadinterwiki');
     }
     $additionalIwPrefixes = strtok('');
     if ($additionalIwPrefixes) {
         $additionalIwPrefixes .= ':';
     }
     # Have to do a DB-key replacement ourselves; otherwise spaces get
     # URL-encoded to +, which is wrong in this case. Similar to logic in
     # Title::getLocalURL
     $link = $firstIw->getURL(strtr("{$additionalIwPrefixes}Special:Export/{$page}", ' ', '_'));
     $params = array();
     if ($history) {
         $params['history'] = 1;
     }
     if ($templates) {
         $params['templates'] = 1;
     }
     if ($pageLinkDepth) {
         $params['pagelink-depth'] = $pageLinkDepth;
     }
     $url = wfAppendQuery($link, $params);
     # For interwikis, use POST to avoid redirects.
     return ImportStreamSource::newFromURL($url, "POST");
 }
예제 #21
0
 /**
  * Get the interwiki list
  *
  * @return array
  */
 private function getInterwikiList()
 {
     $result = Interwiki::getAllPrefixes();
     $prefixes = array();
     foreach ($result as $row) {
         $prefixes[] = $row['iw_prefix'];
     }
     return $prefixes;
 }
예제 #22
0
 /**
  * Load the interwiki, trying first memcached then the DB
  *
  * @param $prefix The interwiki prefix
  * @return Boolean: the prefix is valid
  */
 protected static function load($prefix)
 {
     global $wgMemc, $wgInterwikiExpiry;
     $key = wfMemcKey('interwiki', $prefix);
     $mc = $wgMemc->get($key);
     if ($mc && is_array($mc)) {
         // is_array is hack for old keys
         $iw = Interwiki::loadFromArray($mc);
         if ($iw) {
             return $iw;
         }
     }
     $db = wfGetDB(DB_SLAVE);
     $row = $db->fetchRow($db->select('interwiki', '*', array('iw_prefix' => $prefix), __METHOD__));
     $iw = Interwiki::loadFromArray($row);
     if ($iw) {
         $mc = array('iw_url' => $iw->mURL, 'iw_api' => $iw->mAPI, 'iw_local' => $iw->mLocal, 'iw_trans' => $iw->mTrans);
         $wgMemc->add($key, $mc, $wgInterwikiExpiry);
         return $iw;
     }
     return false;
 }