public static function ifexistCommon($parser, $frame, $titletext = '', $then = '', $else = '')
 {
     global $wgContLang;
     $title = Title::newFromText($titletext);
     $wgContLang->findVariantLink($titletext, $title, true);
     if ($title) {
         if ($title->getNamespace() == NS_MEDIA) {
             /* If namespace is specified as NS_MEDIA, then we want to
              * check the physical file, not the "description" page.
              */
             if (!self::incrementIfexistCount($parser, $frame)) {
                 return $else;
             }
             $file = wfFindFile($title);
             if (!$file) {
                 return $else;
             }
             $parser->mOutput->addImage($file->getName(), $file->getTimestamp(), $file->getSha1());
             return $file->exists() ? $then : $else;
         } elseif ($title->getNamespace() == NS_SPECIAL) {
             /* Don't bother with the count for special pages,
              * since their existence can be checked without
              * accessing the database.
              */
             return SpecialPage::exists($title->getDBkey()) ? $then : $else;
         } elseif ($title->isExternal()) {
             /* Can't check the existence of pages on other sites,
              * so just return $else.  Makes a sort of sense, since
              * they don't exist _locally_.
              */
             return $else;
         } else {
             $pdbk = $title->getPrefixedDBkey();
             $lc = LinkCache::singleton();
             if (!self::incrementIfexistCount($parser, $frame)) {
                 return $else;
             }
             if (0 != ($id = $lc->getGoodLinkID($pdbk))) {
                 $parser->mOutput->addLink($title, $id);
                 return $then;
             } elseif ($lc->isBadLink($pdbk)) {
                 $parser->mOutput->addLink($title, 0);
                 return $else;
             }
             $id = $title->getArticleID();
             $parser->mOutput->addLink($title, $id);
             if ($id) {
                 return $then;
             }
         }
     }
     return $else;
 }
Пример #2
0
 private function shouldFollow(&$title)
 {
     global $wgUser;
     if ($title) {
         $namespace = $title->getNamespace();
         if (!Misc::allowRedirectFromLogin($title)) {
             return false;
         }
         //leaving in case we open it back up
         /*if( $namespace == NS_MAIN && $title->exists() ) {
         			return true;
         		}*/
         if ($namespace == NS_SPECIAL && SpecialPage::exists($title->getText())) {
             $requiresLogin = Misc::requiresLogin($title);
             if ($wgUser->getID() > 0 || !$requiresLogin) {
                 return true;
             }
         }
     }
     return false;
 }
Пример #3
0
 /**
  * Appends an element for each page in the current pageSet with the
  * most general information (id, title), plus any title normalizations
  * and missing or invalid title/pageids/revids.
  */
 private function outputGeneralPageInfo()
 {
     $pageSet = $this->getPageSet();
     $result = $this->getResult();
     // We don't check for a full result set here because we can't be adding
     // more than 380K. The maximum revision size is in the megabyte range,
     // and the maximum result size must be even higher than that.
     // Title normalizations
     $normValues = array();
     foreach ($pageSet->getNormalizedTitles() as $rawTitleStr => $titleStr) {
         $normValues[] = array('from' => $rawTitleStr, 'to' => $titleStr);
     }
     if (count($normValues)) {
         $result->setIndexedTagName($normValues, 'n');
         $result->addValue('query', 'normalized', $normValues);
     }
     // Title conversions
     $convValues = array();
     foreach ($pageSet->getConvertedTitles() as $rawTitleStr => $titleStr) {
         $convValues[] = array('from' => $rawTitleStr, 'to' => $titleStr);
     }
     if (count($convValues)) {
         $result->setIndexedTagName($convValues, 'c');
         $result->addValue('query', 'converted', $convValues);
     }
     // Interwiki titles
     $intrwValues = array();
     foreach ($pageSet->getInterwikiTitles() as $rawTitleStr => $interwikiStr) {
         $intrwValues[] = array('title' => $rawTitleStr, 'iw' => $interwikiStr);
     }
     if (count($intrwValues)) {
         $result->setIndexedTagName($intrwValues, 'i');
         $result->addValue('query', 'interwiki', $intrwValues);
     }
     // Show redirect information
     $redirValues = array();
     foreach ($pageSet->getRedirectTitles() as $titleStrFrom => $titleStrTo) {
         $redirValues[] = array('from' => strval($titleStrFrom), 'to' => $titleStrTo);
     }
     if (count($redirValues)) {
         $result->setIndexedTagName($redirValues, 'r');
         $result->addValue('query', 'redirects', $redirValues);
     }
     // Missing revision elements
     $missingRevIDs = $pageSet->getMissingRevisionIDs();
     if (count($missingRevIDs)) {
         $revids = array();
         foreach ($missingRevIDs as $revid) {
             $revids[$revid] = array('revid' => $revid);
         }
         $result->setIndexedTagName($revids, 'rev');
         $result->addValue('query', 'badrevids', $revids);
     }
     // Page elements
     $pages = array();
     // Report any missing titles
     foreach ($pageSet->getMissingTitles() as $fakeId => $title) {
         $vals = array();
         ApiQueryBase::addTitleInfo($vals, $title);
         $vals['missing'] = '';
         $pages[$fakeId] = $vals;
     }
     // Report any invalid titles
     foreach ($pageSet->getInvalidTitles() as $fakeId => $title) {
         $pages[$fakeId] = array('title' => $title, 'invalid' => '');
     }
     // Report any missing page ids
     foreach ($pageSet->getMissingPageIDs() as $pageid) {
         $pages[$pageid] = array('pageid' => $pageid, 'missing' => '');
     }
     // Report special pages
     foreach ($pageSet->getSpecialTitles() as $fakeId => $title) {
         $vals = array();
         ApiQueryBase::addTitleInfo($vals, $title);
         $vals['special'] = '';
         if ($title->getNamespace() == NS_SPECIAL && !SpecialPage::exists($title->getDbKey())) {
             $vals['missing'] = '';
         } elseif ($title->getNamespace() == NS_MEDIA && !wfFindFile($title)) {
             $vals['missing'] = '';
         }
         $pages[$fakeId] = $vals;
     }
     // Output general page information for found titles
     foreach ($pageSet->getGoodTitles() as $pageid => $title) {
         $vals = array();
         $vals['pageid'] = $pageid;
         ApiQueryBase::addTitleInfo($vals, $title);
         $pages[$pageid] = $vals;
     }
     if (count($pages)) {
         if ($this->params['indexpageids']) {
             $pageIDs = array_keys($pages);
             // json treats all map keys as strings - converting to match
             $pageIDs = array_map('strval', $pageIDs);
             $result->setIndexedTagName($pageIDs, 'id');
             $result->addValue('query', 'pageids', $pageIDs);
         }
         $result->setIndexedTagName($pages, 'page');
         $result->addValue('query', 'pages', $pages);
     }
     if ($this->params['export']) {
         $this->doExport($pageSet, $result);
     }
 }
Пример #4
0
 /**
  * Replace <!--LINK--> link placeholders with actual links, in the buffer
  * Placeholders created in Skin::makeLinkObj()
  * Returns an array of link CSS classes, indexed by PDBK.
  * $options is a bit field, RLH_FOR_UPDATE to select for update
  */
 function replaceLinkHolders(&$text, $options = 0)
 {
     global $wgUser;
     global $wgContLang;
     $fname = 'Parser::replaceLinkHolders';
     wfProfileIn($fname);
     $pdbks = array();
     $colours = array();
     $linkcolour_ids = array();
     $sk = $this->mOptions->getSkin();
     $linkCache =& LinkCache::singleton();
     if (!empty($this->mLinkHolders['namespaces'])) {
         wfProfileIn($fname . '-check');
         $dbr = wfGetDB(DB_SLAVE);
         $page = $dbr->tableName('page');
         $threshold = $wgUser->getOption('stubthreshold');
         # Sort by namespace
         asort($this->mLinkHolders['namespaces']);
         # Generate query
         $query = false;
         $current = null;
         foreach ($this->mLinkHolders['namespaces'] as $key => $ns) {
             # Make title object
             $title = $this->mLinkHolders['titles'][$key];
             # Skip invalid entries.
             # Result will be ugly, but prevents crash.
             if (is_null($title)) {
                 continue;
             }
             $pdbk = $pdbks[$key] = $title->getPrefixedDBkey();
             # Check if it's a static known link, e.g. interwiki
             if ($title->isAlwaysKnown()) {
                 $colours[$pdbk] = '';
             } elseif (($id = $linkCache->getGoodLinkID($pdbk)) != 0) {
                 $colours[$pdbk] = '';
                 $this->mOutput->addLink($title, $id);
             } elseif ($linkCache->isBadLink($pdbk)) {
                 $colours[$pdbk] = 'new';
             } elseif ($title->getNamespace() == NS_SPECIAL && !SpecialPage::exists($pdbk)) {
                 $colours[$pdbk] = 'new';
             } else {
                 # Not in the link cache, add it to the query
                 if (!isset($current)) {
                     $current = $ns;
                     $query = "SELECT page_id, page_namespace, page_title, page_is_redirect";
                     if ($threshold > 0) {
                         $query .= ', page_len';
                     }
                     $query .= " FROM {$page} WHERE (page_namespace={$ns} AND page_title IN(";
                 } elseif ($current != $ns) {
                     $current = $ns;
                     $query .= ")) OR (page_namespace={$ns} AND page_title IN(";
                 } else {
                     $query .= ', ';
                 }
                 $query .= $dbr->addQuotes($this->mLinkHolders['dbkeys'][$key]);
             }
         }
         if ($query) {
             $query .= '))';
             if ($options & RLH_FOR_UPDATE) {
                 $query .= ' FOR UPDATE';
             }
             $res = $dbr->query($query, $fname);
             # Fetch data and form into an associative array
             # non-existent = broken
             while ($s = $dbr->fetchObject($res)) {
                 $title = Title::makeTitle($s->page_namespace, $s->page_title);
                 $pdbk = $title->getPrefixedDBkey();
                 $linkCache->addGoodLinkObj($s->page_id, $title);
                 $this->mOutput->addLink($title, $s->page_id);
                 $colours[$pdbk] = $sk->getLinkColour($s, $threshold);
                 //add id to the extension todolist
                 $linkcolour_ids[$s->page_id] = $pdbk;
             }
             //pass an array of page_ids to an extension
             wfRunHooks('GetLinkColours', array($linkcolour_ids, &$colours));
         }
         wfProfileOut($fname . '-check');
         # Do a second query for different language variants of links and categories
         if ($wgContLang->hasVariants()) {
             $linkBatch = new LinkBatch();
             $variantMap = array();
             // maps $pdbkey_Variant => $keys (of link holders)
             $categoryMap = array();
             // maps $category_variant => $category (dbkeys)
             $varCategories = array();
             // category replacements oldDBkey => newDBkey
             $categories = $this->mOutput->getCategoryLinks();
             // Add variants of links to link batch
             foreach ($this->mLinkHolders['namespaces'] as $key => $ns) {
                 $title = $this->mLinkHolders['titles'][$key];
                 if (is_null($title)) {
                     continue;
                 }
                 $pdbk = $title->getPrefixedDBkey();
                 $titleText = $title->getText();
                 // generate all variants of the link title text
                 $allTextVariants = $wgContLang->convertLinkToAllVariants($titleText);
                 // if link was not found (in first query), add all variants to query
                 if (!isset($colours[$pdbk])) {
                     foreach ($allTextVariants as $textVariant) {
                         if ($textVariant != $titleText) {
                             $variantTitle = Title::makeTitle($ns, $textVariant);
                             if (is_null($variantTitle)) {
                                 continue;
                             }
                             $linkBatch->addObj($variantTitle);
                             $variantMap[$variantTitle->getPrefixedDBkey()][] = $key;
                         }
                     }
                 }
             }
             // process categories, check if a category exists in some variant
             foreach ($categories as $category) {
                 $variants = $wgContLang->convertLinkToAllVariants($category);
                 foreach ($variants as $variant) {
                     if ($variant != $category) {
                         $variantTitle = Title::newFromDBkey(Title::makeName(NS_CATEGORY, $variant));
                         if (is_null($variantTitle)) {
                             continue;
                         }
                         $linkBatch->addObj($variantTitle);
                         $categoryMap[$variant] = $category;
                     }
                 }
             }
             if (!$linkBatch->isEmpty()) {
                 // construct query
                 $titleClause = $linkBatch->constructSet('page', $dbr);
                 $variantQuery = "SELECT page_id, page_namespace, page_title, page_is_redirect";
                 if ($threshold > 0) {
                     $variantQuery .= ', page_len';
                 }
                 $variantQuery .= " FROM {$page} WHERE {$titleClause}";
                 if ($options & RLH_FOR_UPDATE) {
                     $variantQuery .= ' FOR UPDATE';
                 }
                 $varRes = $dbr->query($variantQuery, $fname);
                 // for each found variants, figure out link holders and replace
                 while ($s = $dbr->fetchObject($varRes)) {
                     $variantTitle = Title::makeTitle($s->page_namespace, $s->page_title);
                     $varPdbk = $variantTitle->getPrefixedDBkey();
                     $vardbk = $variantTitle->getDBkey();
                     $holderKeys = array();
                     if (isset($variantMap[$varPdbk])) {
                         $holderKeys = $variantMap[$varPdbk];
                         $linkCache->addGoodLinkObj($s->page_id, $variantTitle);
                         $this->mOutput->addLink($variantTitle, $s->page_id);
                     }
                     // loop over link holders
                     foreach ($holderKeys as $key) {
                         $title = $this->mLinkHolders['titles'][$key];
                         if (is_null($title)) {
                             continue;
                         }
                         $pdbk = $title->getPrefixedDBkey();
                         if (!isset($colours[$pdbk])) {
                             // found link in some of the variants, replace the link holder data
                             $this->mLinkHolders['titles'][$key] = $variantTitle;
                             $this->mLinkHolders['dbkeys'][$key] = $variantTitle->getDBkey();
                             // set pdbk and colour
                             $pdbks[$key] = $varPdbk;
                             $colours[$varPdbk] = $sk->getLinkColour($s, $threshold);
                             $linkcolour_ids[$s->page_id] = $pdbk;
                         }
                         wfRunHooks('GetLinkColours', array($linkcolour_ids, &$colours));
                     }
                     // check if the object is a variant of a category
                     if (isset($categoryMap[$vardbk])) {
                         $oldkey = $categoryMap[$vardbk];
                         if ($oldkey != $vardbk) {
                             $varCategories[$oldkey] = $vardbk;
                         }
                     }
                 }
                 // rebuild the categories in original order (if there are replacements)
                 if (count($varCategories) > 0) {
                     $newCats = array();
                     $originalCats = $this->mOutput->getCategories();
                     foreach ($originalCats as $cat => $sortkey) {
                         // make the replacement
                         if (array_key_exists($cat, $varCategories)) {
                             $newCats[$varCategories[$cat]] = $sortkey;
                         } else {
                             $newCats[$cat] = $sortkey;
                         }
                     }
                     $this->mOutput->setCategoryLinks($newCats);
                 }
             }
         }
         # Construct search and replace arrays
         wfProfileIn($fname . '-construct');
         $replacePairs = array();
         foreach ($this->mLinkHolders['namespaces'] as $key => $ns) {
             $pdbk = $pdbks[$key];
             $searchkey = "<!--LINK {$key}-->";
             $title = $this->mLinkHolders['titles'][$key];
             if (!isset($colours[$pdbk]) || $colours[$pdbk] == 'new') {
                 $linkCache->addBadLinkObj($title);
                 $colours[$pdbk] = 'new';
                 $this->mOutput->addLink($title, 0);
                 $replacePairs[$searchkey] = $sk->makeBrokenLinkObj($title, $this->mLinkHolders['texts'][$key], $this->mLinkHolders['queries'][$key]);
             } else {
                 $replacePairs[$searchkey] = $sk->makeColouredLinkObj($title, $colours[$pdbk], $this->mLinkHolders['texts'][$key], $this->mLinkHolders['queries'][$key]);
             }
         }
         $replacer = new HashtableReplacer($replacePairs, 1);
         wfProfileOut($fname . '-construct');
         # Do the thing
         wfProfileIn($fname . '-replace');
         $text = preg_replace_callback('/(<!--LINK .*?-->)/', $replacer->cb(), $text);
         wfProfileOut($fname . '-replace');
     }
     # Now process interwiki link holders
     # This is quite a bit simpler than internal links
     if (!empty($this->mInterwikiLinkHolders['texts'])) {
         wfProfileIn($fname . '-interwiki');
         # Make interwiki link HTML
         $replacePairs = array();
         foreach ($this->mInterwikiLinkHolders['texts'] as $key => $link) {
             $title = $this->mInterwikiLinkHolders['titles'][$key];
             $replacePairs[$key] = $sk->makeLinkObj($title, $link);
         }
         $replacer = new HashtableReplacer($replacePairs, 1);
         $text = preg_replace_callback('/<!--IWLINK (.*?)-->/', $replacer->cb(), $text);
         wfProfileOut($fname . '-interwiki');
     }
     wfProfileOut($fname);
     return $colours;
 }
Пример #5
0
 /**
  * Should links to this title be shown as potentially viewable (i.e. as
  * "bluelinks"), even if there's no record by this title in the page
  * table?
  *
  * This function is semi-deprecated for public use, as well as somewhat
  * misleadingly named.  You probably just want to call isKnown(), which
  * calls this function internally.
  *
  * (ISSUE: Most of these checks are cheap, but the file existence check
  * can potentially be quite expensive.  Including it here fixes a lot of
  * existing code, but we might want to add an optional parameter to skip
  * it and any other expensive checks.)
  *
  * @return \type{\bool}
  */
 public function isAlwaysKnown()
 {
     if ($this->mInterwiki != '') {
         return true;
         // any interwiki link might be viewable, for all we know
     }
     switch ($this->mNamespace) {
         case NS_MEDIA:
         case NS_FILE:
             return (bool) wfFindFile($this);
             // file exists, possibly in a foreign repo
         // file exists, possibly in a foreign repo
         case NS_SPECIAL:
             return SpecialPage::exists($this->getDBkey());
             // valid special page
         // valid special page
         case NS_MAIN:
             return $this->mDbkeyform == '';
             // selflink, possibly with fragment
         // selflink, possibly with fragment
         case NS_MEDIAWIKI:
             // If the page is form Mediawiki:message/lang, calling wfMsgWeirdKey causes
             // the full l10n of that language to be loaded. That takes much memory and
             // isn't needed. So we strip the language part away.
             list($basename, ) = explode('/', $this->mDbkeyform, 2);
             return (bool) wfMsgWeirdKey($basename);
             // known system message
         // known system message
         default:
             return false;
     }
 }
Пример #6
0
 /**
  * Make a link for a title which may or may not be in the database. If you need to
  * call this lots of times, pre-fill the link cache with a LinkBatch, otherwise each
  * call to this will result in a DB query.
  * 
  * @param $nt     Title: the title object to make the link from, e.g. from
  *                      Title::newFromText.
  * @param $text  String: link text
  * @param $query String: optional query part
  * @param $trail String: optional trail. Alphabetic characters at the start of this string will
  *                      be included in the link text. Other characters will be appended after
  *                      the end of the link.
  * @param $prefix String: optional prefix. As trail, only before instead of after.
  */
 function makeLinkObj($nt, $text = '', $query = '', $trail = '', $prefix = '')
 {
     global $wgUser;
     wfProfileIn(__METHOD__);
     if (!$nt instanceof Title) {
         # Fail gracefully
         wfProfileOut(__METHOD__);
         return "<!-- ERROR -->{$prefix}{$text}{$trail}";
     }
     if ($nt->isExternal()) {
         $u = $nt->getFullURL();
         $link = $nt->getPrefixedURL();
         if ('' == $text) {
             $text = $nt->getPrefixedText();
         }
         $style = $this->getInterwikiLinkAttributes($link, $text, 'extiw');
         $inside = '';
         if ('' != $trail) {
             $m = array();
             if (preg_match('/^([a-z]+)(.*)$$/sD', $trail, $m)) {
                 $inside = $m[1];
                 $trail = $m[2];
             }
         }
         $t = "<a href=\"{$u}\"{$style}>{$text}{$inside}</a>";
         wfProfileOut(__METHOD__);
         return $t;
     } elseif ($nt->isAlwaysKnown()) {
         # Image links, special page links and self-links with fragements are always known.
         $retVal = $this->makeKnownLinkObj($nt, $text, $query, $trail, $prefix);
     } else {
         wfProfileIn(__METHOD__ . '-immediate');
         # Handles links to special pages which do not exist in the database:
         if ($nt->getNamespace() == NS_SPECIAL) {
             if (SpecialPage::exists($nt->getDBkey())) {
                 $retVal = $this->makeKnownLinkObj($nt, $text, $query, $trail, $prefix);
             } else {
                 $retVal = $this->makeBrokenLinkObj($nt, $text, $query, $trail, $prefix);
             }
             wfProfileOut(__METHOD__ . '-immediate');
             wfProfileOut(__METHOD__);
             return $retVal;
         }
         # Work out link colour immediately
         $aid = $nt->getArticleID();
         if (0 == $aid) {
             $retVal = $this->makeBrokenLinkObj($nt, $text, $query, $trail, $prefix);
         } else {
             $colour = '';
             if ($nt->isContentPage()) {
                 # FIXME: This is stupid, we should combine this query with
                 # the Title::getArticleID() query above.
                 $threshold = $wgUser->getOption('stubthreshold');
                 $dbr = wfGetDB(DB_SLAVE);
                 $s = $dbr->selectRow(array('page'), array('page_len', 'page_is_redirect', 'page_namespace'), array('page_id' => $aid), __METHOD__);
                 $colour = $this->getLinkColour($s, $threshold);
             }
             $retVal = $this->makeColouredLinkObj($nt, $colour, $text, $query, $trail, $prefix);
         }
         wfProfileOut(__METHOD__ . '-immediate');
     }
     wfProfileOut(__METHOD__);
     return $retVal;
 }