protected function processRow( $row ) { global $wgContLang; $display = Title::makeName( $row->page_namespace, $row->page_title ); $verified = $wgContLang->normalize( $display ); $title = Title::newFromText( $verified ); if( !is_null( $title ) && $title->canExist() && $title->getNamespace() == $row->page_namespace && $title->getDBkey() === $row->page_title ) { return $this->progress( 0 ); // all is fine } if( $row->page_namespace == NS_FILE && $this->fileExists( $row->page_title ) ) { $this->output( "file $row->page_title needs cleanup, please run cleanupImages.php.\n" ); return $this->progress( 0 ); } elseif( is_null( $title ) ) { $this->output( "page $row->page_id ($display) is illegal.\n" ); $this->moveIllegalPage( $row ); return $this->progress( 1 ); } else { $this->output( "page $row->page_id ($display) doesn't match self.\n" ); $this->moveInconsistentPage( $row, $title ); return $this->progress( 1 ); } }
function wfExtensionCommentbox_Add(&$op, &$text) { global $wgUser, $wgRequest, $wgCommentboxNamespaces, $wgCommentboxRows, $wgCommentboxColumns; $title = $op->getTitle(); if (!$title->exists()) { return true; } if (!$title->userCan('edit', true)) { return true; } if (!array_key_exists($title->getNamespace(), $wgCommentboxNamespaces) || !$wgCommentboxNamespaces[$title->getNamespace()]) { return true; } $action = $wgRequest->getVal('action', 'view'); if (!($action == 'view' || $action == 'purge' || $action == 'submit')) { return true; } if ($wgRequest->getCheck('wpPreview') || $wgRequest->getCheck('wpLivePreview') || $wgRequest->getCheck('wpDiff')) { return true; } if (!is_null($wgRequest->getVal('preview'))) { return true; } if (!is_null($wgRequest->getVal('diff'))) { return true; } $newaction = Title::newFromText('AddComment', NS_SPECIAL)->escapeFullURL(); $name = ''; if (!$wgUser->isLoggedIn()) { $namecomment = wfMsgExt('commentbox-name-explanation', 'parseinline'); $namelabel = wfMsgExt('commentbox-name', 'parseinline'); $name = '<br />' . $namelabel; $name .= ' <input name="wpAuthor" tabindex="2" type="text" size="30" maxlength="50" /> '; $name .= $namecomment; } $inhalt = wfMsgNoTrans('commentbox-prefill'); $save = wfMsgExt('commentbox-savebutton', 'escapenoentities'); $texttitle = htmlspecialchars(Title::makeName($title->getNamespace(), $title->getText())); $intro = wfMsgExt('commentbox-intro', 'parse'); $text .= <<<END \t<form id="commentform" name="commentform" method="post" action="{$newaction}" enctype="multipart/form-data"> \t{$intro} \t<textarea tabindex='1' accesskey="," name="wpComment" id="wpComment" \t rows='{$wgCommentboxRows}' cols='{$wgCommentboxColumns}' \t\t >{$inhalt}</textarea> \t{$name} \t<br /> \t<input type="hidden" name="wpPageName" value="{$texttitle}" /> \t<input id="wpSave" name="wpSave" type="submit" tabindex="3" value="{$save}" \t accesskey="s" title="{$save} [alt-s]" /> \t</form> END; return true; }
function GodAuth_hook() { global $wgUser; global $wgRequest; $title = $wgRequest->getVal('title'); if ($title == Title::makeName(NS_SPECIAL, 'Userlogout') || $title == Title::makeName(NS_SPECIAL, 'Userlogin')) { return; } $user = User::newFromSession(); if (!$user->isAnon()) { return; // User is already logged in and not anonymous. } if (!isset($wgCommandLineMode) && !isset($_COOKIE[session_name()])) { wfSetupSession(); } # # Create a new MediaWiki account if needed # $_user = GodAuth_getUser(); $id = User::idFromName($_user); if (is_null($id)) { $u = User::newFromName($_user); $user->setName($_user); $user->setRealName(''); $user->setEmail(GodAuth_getEmail()); $user->mEmailAuthenticated = wfTimestampNow(); $user->setToken(); $user->saveSettings(); $user->addToDatabase(); } else { $user->mId = $id; $user->loadFromId(); } $wgUser = $user; $wgUser->setCookies(); return; }
/** * Create a new Title from a namespace index and a DB key. * The parameters will be checked for validity, which is a bit slower * than makeTitle() but safer for user-provided data. * * @param int $ns The namespace of the article * @param string $title Database key form * @param string $fragment The link fragment (after the "#") * @param string $interwiki Interwiki prefix * @return Title The new object, or null on an error */ public static function makeTitleSafe($ns, $title, $fragment = '', $interwiki = '') { if (!MWNamespace::exists($ns)) { return null; } $t = new Title(); $t->mDbkeyform = Title::makeName($ns, $title, $fragment, $interwiki, true); try { $t->secureAndSplit(); return $t; } catch (MalformedTitleException $ex) { return null; } }
/** * deleteComplete -- hook * * @static * @access public * * @param WikiPage $oArticle, * @param User $oUser, * @param String $reason, * @param String $articleId, * * @author Piotr Molski (MoLi) * @return true */ public static function deleteComplete(&$oArticle, &$oUser, $reason, $articleId) { global $wgCityId; wfProfileIn(__METHOD__); $use_api = 0; if (is_object($oArticle) && $oUser instanceof User) { $pageId = !empty($articleId) ? $articleId : $oArticle->getID(); $logid = 0; if ($pageId > 0) { if ($use_api == 1) { $oTitle = $oArticle->getTitle(); $pageName = Title::makeName($oTitle->getNamespace(), $oTitle->getDBkey()); $oFauxRequest = new FauxRequest(array('action' => 'query', 'list' => 'logevents', 'letype' => 'delete', 'letitle' => $pageName, 'lelimit' => 1)); $oApi = new ApiMain($oFauxRequest); try { #--- $oApi->execute(); $aResult = $oApi->GetResultData(); if (isset($aResult['query']['logevents']) && !empty($aResult['query']['logevents'])) { list($row) = $aResult['query']['logevents']; if (isset($row['logid'])) { $logid = $row['logid']; } } } catch (Exception $e) { Wikia::log(__METHOD__, 'cannot fetch data from logging table via API request', $e->getMessage()); } } else { $table = 'recentchanges'; $oTitle = $oArticle->getTitle(); $what = array('rc_logid'); $cond = array('rc_title' => $oTitle->getDBkey(), 'rc_namespace' => $oTitle->getNamespace(), 'rc_log_action' => 'delete', 'rc_user' => $oUser->getID()); $options = array('ORDER BY' => 'rc_id DESC'); $dbr = wfGetDB(DB_MASTER); $oRow = $dbr->selectRow($table, $what, $cond, __METHOD__, $options); if ($oRow) { $logid = $oRow->rc_logid; } } if ($logid > 0) { #--- $oScribeProducer = new ScribeProducer('delete', $pageId, 0, $logid, 0); if (is_object($oScribeProducer)) { $oScribeProducer->send_log(); } } else { $title = $oArticle->getTitle()->getText(); Wikia::log(__METHOD__, "error", "Cannot send log via scribe ({$wgCityId}): log id not found: {$title}"); } } else { $title = $oArticle->getTitle()->getText(); Wikia::log(__METHOD__, "error", "Cannot send log via scribe ({$wgCityId}): page ID is empty: {$title}"); } } else { $isArticle = is_object($oArticle); $isUser = is_object($oUser); Wikia::log(__METHOD__, "error", "Cannot send log via scribe ({$wgCityId}): invalid user: {$isUser}, invalid article: {$isArticle}"); } wfProfileOut(__METHOD__); return true; }
/** * Get the prefixed DB key associated with an ID * @param int $id the page_id of the article * @return Title an object representing the article, or NULL * if no such article was found * @static * @access public */ function nameOf($id) { $fname = 'Title::nameOf'; $dbr = wfGetDB(DB_SLAVE); $s = $dbr->selectRow('page', array('page_namespace', 'page_title'), array('page_id' => $id), $fname); if ($s === false) { return NULL; } $n = Title::makeName($s->page_namespace, $s->page_title); return $n; }
/** * Create a new Title from a namespace index and a DB key. * The parameters will be checked for validity, which is a bit slower * than makeTitle() but safer for user-provided data. * * @param $ns Int the namespace of the article * @param $title String database key form * @param $fragment String the link fragment (after the "#") * @param $interwiki String interwiki prefix * @return Title the new object, or NULL on an error */ public static function makeTitleSafe($ns, $title, $fragment = '', $interwiki = '') { $t = new Title(); $t->mDbkeyform = Title::makeName($ns, $title, $fragment, $interwiki); if ($t->secureAndSplit()) { return $t; } else { return null; } }
function doSubmit() { global $wgOut, $wgUser, $wgMaximumMovedPages, $wgLang; global $wgFixDoubleRedirects; if ($wgUser->pingLimiter('move')) { $wgOut->rateLimited(); return; } $ot = $this->oldTitle; $nt = $this->newTitle; # Delete to make way if requested if ($wgUser->isAllowed('delete') && $this->deleteAndMove) { $article = new Article($nt); # Disallow deletions of big articles $bigHistory = $article->isBigDeletion(); if ($bigHistory && !$nt->userCan('bigdelete')) { global $wgDeleteRevisionsLimit; $this->showForm(array('delete-toobig', $wgLang->formatNum($wgDeleteRevisionsLimit))); return; } // Delete an associated image if there is $file = wfLocalFile($nt); if ($file->exists()) { $file->delete(wfMsgForContent('delete_and_move_reason'), false); } // This may output an error message and exit $article->doDelete(wfMsgForContent('delete_and_move_reason')); } # don't allow moving to pages with # in if (!$nt || $nt->getFragment() != '') { $this->showForm('badtitletext'); return; } # Show a warning if the target file exists on a shared repo if ($nt->getNamespace() == NS_FILE && !($this->moveOverShared && $wgUser->isAllowed('reupload-shared')) && !RepoGroup::singleton()->getLocalRepo()->findFile($nt) && wfFindFile($nt)) { $this->showForm(array('file-exists-sharedrepo')); return; } if ($wgUser->isAllowed('suppressredirect')) { $createRedirect = $this->leaveRedirect; } else { $createRedirect = true; } # Do the actual move. $error = $ot->moveTo($nt, true, $this->reason, $createRedirect); if ($error !== true) { # @todo FIXME: Show all the errors in a list, not just the first one $this->showForm(reset($error)); return; } if ($wgFixDoubleRedirects && $this->fixRedirects) { DoubleRedirectJob::fixRedirects('move', $ot, $nt); } wfRunHooks('SpecialMovepageAfterMove', array(&$this, &$ot, &$nt)); $wgOut->setPagetitle(wfMsg('pagemovedsub')); $oldUrl = $ot->getFullUrl('redirect=no'); $newUrl = $nt->getFullUrl(); $oldText = $ot->getPrefixedText(); $newText = $nt->getPrefixedText(); $oldLink = "<span class='plainlinks'>[{$oldUrl} {$oldText}]</span>"; $newLink = "<span class='plainlinks'>[{$newUrl} {$newText}]</span>"; $msgName = $createRedirect ? 'movepage-moved-redirect' : 'movepage-moved-noredirect'; $wgOut->addWikiMsg('movepage-moved', $oldLink, $newLink, $oldText, $newText); $wgOut->addWikiMsg($msgName); # Now we move extra pages we've been asked to move: subpages and talk # pages. First, if the old page or the new page is a talk page, we # can't move any talk pages: cancel that. if ($ot->isTalkPage() || $nt->isTalkPage()) { $this->moveTalk = false; } if (!$ot->userCan('move-subpages')) { $this->moveSubpages = false; } # Next make a list of id's. This might be marginally less efficient # than a more direct method, but this is not a highly performance-cri- # tical code path and readable code is more important here. # # Note: this query works nicely on MySQL 5, but the optimizer in MySQL # 4 might get confused. If so, consider rewriting as a UNION. # # If the target namespace doesn't allow subpages, moving with subpages # would mean that you couldn't move them back in one operation, which # is bad. # @todo FIXME: A specific error message should be given in this case. // @todo FIXME: Use Title::moveSubpages() here $dbr = wfGetDB(DB_MASTER); if ($this->moveSubpages && (MWNamespace::hasSubpages($nt->getNamespace()) || $this->moveTalk && MWNamespace::hasSubpages($nt->getTalkPage()->getNamespace()))) { $conds = array('page_title' . $dbr->buildLike($ot->getDBkey() . '/', $dbr->anyString()) . ' OR page_title = ' . $dbr->addQuotes($ot->getDBkey())); $conds['page_namespace'] = array(); if (MWNamespace::hasSubpages($nt->getNamespace())) { $conds['page_namespace'][] = $ot->getNamespace(); } if ($this->moveTalk && MWNamespace::hasSubpages($nt->getTalkPage()->getNamespace())) { $conds['page_namespace'][] = $ot->getTalkPage()->getNamespace(); } } elseif ($this->moveTalk) { $conds = array('page_namespace' => $ot->getTalkPage()->getNamespace(), 'page_title' => $ot->getDBkey()); } else { # Skip the query $conds = null; } $extraPages = array(); if (!is_null($conds)) { $extraPages = TitleArray::newFromResult($dbr->select('page', array('page_id', 'page_namespace', 'page_title'), $conds, __METHOD__)); } $extraOutput = array(); $skin = $this->getSkin(); $count = 1; foreach ($extraPages as $oldSubpage) { if ($ot->equals($oldSubpage)) { # Already did this one. continue; } $newPageName = preg_replace('#^' . preg_quote($ot->getDBkey(), '#') . '#', StringUtils::escapeRegexReplacement($nt->getDBkey()), $oldSubpage->getDBkey()); if ($oldSubpage->isTalkPage()) { $newNs = $nt->getTalkPage()->getNamespace(); } else { $newNs = $nt->getSubjectPage()->getNamespace(); } # Bug 14385: we need makeTitleSafe because the new page names may # be longer than 255 characters. $newSubpage = Title::makeTitleSafe($newNs, $newPageName); if (!$newSubpage) { $oldLink = $skin->linkKnown($oldSubpage); $extraOutput[] = wfMsgHtml('movepage-page-unmoved', $oldLink, htmlspecialchars(Title::makeName($newNs, $newPageName))); continue; } # This was copy-pasted from Renameuser, bleh. if ($newSubpage->exists() && !$oldSubpage->isValidMoveTarget($newSubpage)) { $link = $skin->linkKnown($newSubpage); $extraOutput[] = wfMsgHtml('movepage-page-exists', $link); } else { $success = $oldSubpage->moveTo($newSubpage, true, $this->reason, $createRedirect); if ($success === true) { if ($this->fixRedirects) { DoubleRedirectJob::fixRedirects('move', $oldSubpage, $newSubpage); } $oldLink = $skin->linkKnown($oldSubpage, null, array(), array('redirect' => 'no')); $newLink = $skin->linkKnown($newSubpage); $extraOutput[] = wfMsgHtml('movepage-page-moved', $oldLink, $newLink); ++$count; if ($count >= $wgMaximumMovedPages) { $extraOutput[] = wfMsgExt('movepage-max-pages', array('parsemag', 'escape'), $wgLang->formatNum($wgMaximumMovedPages)); break; } } else { $oldLink = $skin->linkKnown($oldSubpage); $newLink = $skin->link($newSubpage); $extraOutput[] = wfMsgHtml('movepage-page-unmoved', $oldLink, $newLink); } } } if ($extraOutput !== array()) { $wgOut->addHTML("<ul>\n<li>" . implode("</li>\n<li>", $extraOutput) . "</li>\n</ul>"); } # Deal with watches (we don't watch subpages) if ($this->watch && $wgUser->isLoggedIn()) { $wgUser->addWatch($ot); $wgUser->addWatch($nt); } else { $wgUser->removeWatch($ot); $wgUser->removeWatch($nt); } # Re-clear the file redirect cache, which may have been polluted by # parsing in messages above. See CR r56745. # @todo FIXME: Needs a more robust solution inside FileRepo. if ($ot->getNamespace() == NS_FILE) { RepoGroup::singleton()->getLocalRepo()->invalidateImageRedirect($ot); } }
function doSubmit() { $user = $this->getUser(); if ($user->pingLimiter('move')) { throw new ThrottledError(); } $ot = $this->oldTitle; $nt = $this->newTitle; # don't allow moving to pages with # in if (!$nt || $nt->hasFragment()) { $this->showForm(array(array('badtitletext'))); return; } # Show a warning if the target file exists on a shared repo if ($nt->getNamespace() == NS_FILE && !($this->moveOverShared && $user->isAllowed('reupload-shared')) && !RepoGroup::singleton()->getLocalRepo()->findFile($nt) && wfFindFile($nt)) { $this->showForm(array(array('file-exists-sharedrepo'))); return; } # Delete to make way if requested if ($this->deleteAndMove) { $permErrors = $nt->getUserPermissionsErrors('delete', $user); if (count($permErrors)) { # Only show the first error $this->showForm($permErrors); return; } $reason = $this->msg('delete_and_move_reason', $ot)->inContentLanguage()->text(); // Delete an associated image if there is if ($nt->getNamespace() == NS_FILE) { $file = wfLocalFile($nt); $file->load(File::READ_LATEST); if ($file->exists()) { $file->delete($reason, false, $user); } } $error = ''; // passed by ref $page = WikiPage::factory($nt); $deleteStatus = $page->doDeleteArticleReal($reason, false, 0, true, $error, $user); if (!$deleteStatus->isGood()) { $this->showForm($deleteStatus->getErrorsArray()); return; } } $handler = ContentHandler::getForTitle($ot); if (!$handler->supportsRedirects()) { $createRedirect = false; } elseif ($user->isAllowed('suppressredirect')) { $createRedirect = $this->leaveRedirect; } else { $createRedirect = true; } # Do the actual move. $mp = new MovePage($ot, $nt); $valid = $mp->isValidMove(); if (!$valid->isOK()) { $this->showForm($valid->getErrorsArray()); return; } $permStatus = $mp->checkPermissions($user, $this->reason); if (!$permStatus->isOK()) { $this->showForm($permStatus->getErrorsArray()); return; } $status = $mp->move($user, $this->reason, $createRedirect); if (!$status->isOK()) { $this->showForm($status->getErrorsArray()); return; } if ($this->getConfig()->get('FixDoubleRedirects') && $this->fixRedirects) { DoubleRedirectJob::fixRedirects('move', $ot, $nt); } $out = $this->getOutput(); $out->setPageTitle($this->msg('pagemovedsub')); $oldLink = Linker::link($ot, null, array('id' => 'movepage-oldlink'), array('redirect' => 'no')); $newLink = Linker::linkKnown($nt, null, array('id' => 'movepage-newlink')); $oldText = $ot->getPrefixedText(); $newText = $nt->getPrefixedText(); if ($ot->exists()) { // NOTE: we assume that if the old title exists, it's because it was re-created as // a redirect to the new title. This is not safe, but what we did before was // even worse: we just determined whether a redirect should have been created, // and reported that it was created if it should have, without any checks. // Also note that isRedirect() is unreliable because of bug 37209. $msgName = 'movepage-moved-redirect'; } else { $msgName = 'movepage-moved-noredirect'; } $out->addHTML($this->msg('movepage-moved')->rawParams($oldLink, $newLink)->params($oldText, $newText)->parseAsBlock()); $out->addWikiMsg($msgName); Hooks::run('SpecialMovepageAfterMove', array(&$this, &$ot, &$nt)); # Now we move extra pages we've been asked to move: subpages and talk # pages. First, if the old page or the new page is a talk page, we # can't move any talk pages: cancel that. if ($ot->isTalkPage() || $nt->isTalkPage()) { $this->moveTalk = false; } if (count($ot->getUserPermissionsErrors('move-subpages', $user))) { $this->moveSubpages = false; } # Next make a list of id's. This might be marginally less efficient # than a more direct method, but this is not a highly performance-cri- # tical code path and readable code is more important here. # # Note: this query works nicely on MySQL 5, but the optimizer in MySQL # 4 might get confused. If so, consider rewriting as a UNION. # # If the target namespace doesn't allow subpages, moving with subpages # would mean that you couldn't move them back in one operation, which # is bad. # @todo FIXME: A specific error message should be given in this case. // @todo FIXME: Use Title::moveSubpages() here $dbr = wfGetDB(DB_MASTER); if ($this->moveSubpages && (MWNamespace::hasSubpages($nt->getNamespace()) || $this->moveTalk && MWNamespace::hasSubpages($nt->getTalkPage()->getNamespace()))) { $conds = array('page_title' . $dbr->buildLike($ot->getDBkey() . '/', $dbr->anyString()) . ' OR page_title = ' . $dbr->addQuotes($ot->getDBkey())); $conds['page_namespace'] = array(); if (MWNamespace::hasSubpages($nt->getNamespace())) { $conds['page_namespace'][] = $ot->getNamespace(); } if ($this->moveTalk && MWNamespace::hasSubpages($nt->getTalkPage()->getNamespace())) { $conds['page_namespace'][] = $ot->getTalkPage()->getNamespace(); } } elseif ($this->moveTalk) { $conds = array('page_namespace' => $ot->getTalkPage()->getNamespace(), 'page_title' => $ot->getDBkey()); } else { # Skip the query $conds = null; } $extraPages = array(); if (!is_null($conds)) { $extraPages = TitleArray::newFromResult($dbr->select('page', array('page_id', 'page_namespace', 'page_title'), $conds, __METHOD__)); } $extraOutput = array(); $count = 1; foreach ($extraPages as $oldSubpage) { if ($ot->equals($oldSubpage) || $nt->equals($oldSubpage)) { # Already did this one. continue; } $newPageName = preg_replace('#^' . preg_quote($ot->getDBkey(), '#') . '#', StringUtils::escapeRegexReplacement($nt->getDBkey()), $oldSubpage->getDBkey()); if ($oldSubpage->isSubpage() && ($ot->isTalkPage() xor $nt->isTalkPage())) { // Moving a subpage from a subject namespace to a talk namespace or vice-versa $newNs = $nt->getNamespace(); } elseif ($oldSubpage->isTalkPage()) { $newNs = $nt->getTalkPage()->getNamespace(); } else { $newNs = $nt->getSubjectPage()->getNamespace(); } # Bug 14385: we need makeTitleSafe because the new page names may # be longer than 255 characters. $newSubpage = Title::makeTitleSafe($newNs, $newPageName); if (!$newSubpage) { $oldLink = Linker::linkKnown($oldSubpage); $extraOutput[] = $this->msg('movepage-page-unmoved')->rawParams($oldLink)->params(Title::makeName($newNs, $newPageName))->escaped(); continue; } # This was copy-pasted from Renameuser, bleh. if ($newSubpage->exists() && !$oldSubpage->isValidMoveTarget($newSubpage)) { $link = Linker::linkKnown($newSubpage); $extraOutput[] = $this->msg('movepage-page-exists')->rawParams($link)->escaped(); } else { $success = $oldSubpage->moveTo($newSubpage, true, $this->reason, $createRedirect); if ($success === true) { if ($this->fixRedirects) { DoubleRedirectJob::fixRedirects('move', $oldSubpage, $newSubpage); } $oldLink = Linker::link($oldSubpage, null, array(), array('redirect' => 'no')); $newLink = Linker::linkKnown($newSubpage); $extraOutput[] = $this->msg('movepage-page-moved')->rawParams($oldLink, $newLink)->escaped(); ++$count; $maximumMovedPages = $this->getConfig()->get('MaximumMovedPages'); if ($count >= $maximumMovedPages) { $extraOutput[] = $this->msg('movepage-max-pages')->numParams($maximumMovedPages)->escaped(); break; } } else { $oldLink = Linker::linkKnown($oldSubpage); $newLink = Linker::link($newSubpage); $extraOutput[] = $this->msg('movepage-page-unmoved')->rawParams($oldLink, $newLink)->escaped(); } } } if ($extraOutput !== array()) { $out->addHTML("<ul>\n<li>" . implode("</li>\n<li>", $extraOutput) . "</li>\n</ul>"); } # Deal with watches (we don't watch subpages) WatchAction::doWatchOrUnwatch($this->watch, $ot, $user); WatchAction::doWatchOrUnwatch($this->watch, $nt, $user); }
/** * Modify $this->internals and $colours according to language variant linking rules */ protected function doVariants(&$colours) { global $wgContLang; $linkBatch = new LinkBatch(); $variantMap = array(); // maps $pdbkey_Variant => $keys (of link holders) $output = $this->parent->getOutput(); $linkCache = LinkCache::singleton(); $threshold = $this->parent->getOptions()->getStubThreshold(); $titlesToBeConverted = ''; $titlesAttrs = array(); // Concatenate titles to a single string, thus we only need auto convert the // single string to all variants. This would improve parser's performance // significantly. foreach ($this->internals as $ns => $entries) { foreach ($entries as $index => $entry) { $pdbk = $entry['pdbk']; // we only deal with new links (in its first query) if (!isset($colours[$pdbk]) || $colours[$pdbk] === 'new') { $title = $entry['title']; $titleText = $title->getText(); $titlesAttrs[] = array('ns' => $ns, 'key' => "{$ns}:{$index}", 'titleText' => $titleText); // separate titles with \0 because it would never appears // in a valid title $titlesToBeConverted .= $titleText . ""; } } } // Now do the conversion and explode string to text of titles $titlesAllVariants = $wgContLang->autoConvertToAllVariants(rtrim($titlesToBeConverted, "")); $allVariantsName = array_keys($titlesAllVariants); foreach ($titlesAllVariants as &$titlesVariant) { $titlesVariant = explode("", $titlesVariant); } $l = count($titlesAttrs); // Then add variants of links to link batch for ($i = 0; $i < $l; $i++) { foreach ($allVariantsName as $variantName) { $textVariant = $titlesAllVariants[$variantName][$i]; if ($textVariant != $titlesAttrs[$i]['titleText']) { $variantTitle = Title::makeTitle($titlesAttrs[$i]['ns'], $textVariant); if (is_null($variantTitle)) { continue; } $linkBatch->addObj($variantTitle); $variantMap[$variantTitle->getPrefixedDBkey()][] = $titlesAttrs[$i]['key']; } } } // process categories, check if a category exists in some variant $categoryMap = array(); // maps $category_variant => $category (dbkeys) $varCategories = array(); // category replacements oldDBkey => newDBkey foreach ($output->getCategoryLinks() as $category) { $variants = $wgContLang->autoConvertToAllVariants($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 $dbr = wfGetDB(DB_SLAVE); $varRes = $dbr->select('page', array('page_id', 'page_namespace', 'page_title', 'page_is_redirect', 'page_len', 'page_latest'), $linkBatch->constructSet('page', $dbr), __METHOD__); $linkcolour_ids = array(); // for each found variants, figure out link holders and replace foreach ($varRes as $s) { $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->addGoodLinkObjFromRow($variantTitle, $s); $output->addLink($variantTitle, $s->page_id); } // loop over link holders foreach ($holderKeys as $key) { list($ns, $index) = explode(':', $key, 2); $entry =& $this->internals[$ns][$index]; $pdbk = $entry['pdbk']; if (!isset($colours[$pdbk]) || $colours[$pdbk] === 'new') { // found link in some of the variants, replace the link holder data $entry['title'] = $variantTitle; $entry['pdbk'] = $varPdbk; // set pdbk and colour # @todo FIXME: Convoluted data flow # The redirect status and length is passed to getLinkColour via the LinkCache # Use formal parameters instead $colours[$varPdbk] = Linker::getLinkColour($variantTitle, $threshold); $linkcolour_ids[$s->page_id] = $pdbk; } } // check if the object is a variant of a category if (isset($categoryMap[$vardbk])) { $oldkey = $categoryMap[$vardbk]; if ($oldkey != $vardbk) { $varCategories[$oldkey] = $vardbk; } } } wfRunHooks('GetLinkColours', array($linkcolour_ids, &$colours)); // rebuild the categories in original order (if there are replacements) if (count($varCategories) > 0) { $newCats = array(); $originalCats = $output->getCategories(); foreach ($originalCats as $cat => $sortkey) { // make the replacement if (array_key_exists($cat, $varCategories)) { $newCats[$varCategories[$cat]] = $sortkey; } else { $newCats[$cat] = $sortkey; } } $output->setCategoryLinks($newCats); } } }
if (!defined('MEDIAWIKI')) { die("This is a MediaWiki extension, and must be run from within MediaWiki.\n"); } $GLOBALS['wgExtensionCredits']['other'][] = array('path' => __FILE__, 'name' => 'AccessDenied', 'version' => '0.1', 'author' => 'James Montalvo', 'license-name' => 'LGPL-3.0+', 'descriptionmsg' => 'ext-accessdenied-desc'); $GLOBALS['egAccessDeniedViewerGroup'] = false; $GLOBALS['egAccessDeniedDenialPage'] = 'Access_Denied'; $GLOBALS['egAccessDeniedDenialNS'] = NS_PROJECT; // Function called after MediaWiki is initialized $wgExtensionFunctions[] = function () { global $wgRequest, $wgUser, $egAccessDeniedViewerGroup, $egAccessDeniedDenialPage, $egAccessDeniedDenialNS; $title = $wgRequest->getVal('title'); $accessDeniedTitle = Title::makeTitle($egAccessDeniedDenialNS, $egAccessDeniedDenialPage); $accessDeniedTitleText = $accessDeniedTitle->getPrefixedDBkey(); $accessDeniedTitleTalkText = $accessDeniedTitle->getTalkPage()->getPrefixedDBkey(); // if title is the access-denied page anyone is allowed through if ($title == $accessDeniedTitle || $title == $accessDeniedTitleTalkText) { return true; } // if set, only members of group $egAccessDeniedViewerGroup will be allowed to view wiki if ($egAccessDeniedViewerGroup) { $userInGroup = in_array($egAccessDeniedViewerGroup, $wgUser->getEffectiveGroups(true)); // Only users in group $egAccessDeniedViewerGroup may enter the entirety of the wiki. // Non-members of the group are able to view the "access denied" page (and its talk page), // and will be redirected to "access denied" page if they attempt to view other pages. if (!$userInGroup) { // redirect user to "access denied" page $wgRequest->setVal("title", Title::makeName($egAccessDeniedDenialNS, $egAccessDeniedDenialPage)); } } return true; };
/** * 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; }
private function getRedirectName(ApiResult $result) { $res =& $result->getData(); if (isset($res['query']) && isset($res['query']['pages'])) { foreach ($this->getPageSet()->getGoodTitles() as $page_id => $oTitle) { $res['query']['pages'][$page_id]['redirectto'] = ""; if ($oTitle->isRedirect()) { $oArticle = new Article($oTitle); $oRedirTitle = $oArticle->getRedirectTarget(); if ($oRedirTitle instanceof Title) { $result->addValue(array("query", "pages", $page_id), "redirectto", Title::makeName($oRedirTitle->getNamespace(), $oRedirTitle->getDBkey())); } } } } }
/** * Modify $this->internals and $colours according to language variant linking rules */ protected function doVariants(&$colours) { global $wgContLang; $linkBatch = new LinkBatch(); $variantMap = array(); // maps $pdbkey_Variant => $keys (of link holders) $output = $this->parent->getOutput(); $linkCache = LinkCache::singleton(); $sk = $this->parent->getOptions()->getSkin(); $threshold = $this->getStubThreshold(); // Add variants of links to link batch foreach ($this->internals as $ns => $entries) { foreach ($entries as $index => $entry) { $key = "{$ns}:{$index}"; $pdbk = $entry['pdbk']; $title = $entry['title']; $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 $categoryMap = array(); // maps $category_variant => $category (dbkeys) $varCategories = array(); // category replacements oldDBkey => newDBkey foreach ($output->getCategoryLinks() 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 $dbr = wfGetDB(DB_SLAVE); $page = $dbr->tableName('page'); $titleClause = $linkBatch->constructSet('page', $dbr); $variantQuery = "SELECT page_id, page_namespace, page_title, page_is_redirect, page_len"; $variantQuery .= " FROM {$page} WHERE {$titleClause}"; $varRes = $dbr->query($variantQuery, __METHOD__); $linkcolour_ids = array(); // 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, $s->page_len, $s->page_is_redirect); $output->addLink($variantTitle, $s->page_id); } // loop over link holders foreach ($holderKeys as $key) { list($ns, $index) = explode(':', $key, 2); $entry =& $this->internals[$ns][$index]; $pdbk = $entry['pdbk']; if (!isset($colours[$pdbk])) { // found link in some of the variants, replace the link holder data $entry['title'] = $variantTitle; $entry['pdbk'] = $varPdbk; // set pdbk and colour # FIXME: convoluted data flow # The redirect status and length is passed to getLinkColour via the LinkCache # Use formal parameters instead $colours[$varPdbk] = $sk->getLinkColour($variantTitle, $threshold); $linkcolour_ids[$s->page_id] = $pdbk; } } // check if the object is a variant of a category if (isset($categoryMap[$vardbk])) { $oldkey = $categoryMap[$vardbk]; if ($oldkey != $vardbk) { $varCategories[$oldkey] = $vardbk; } } } wfRunHooks('GetLinkColours', array($linkcolour_ids, &$colours)); // rebuild the categories in original order (if there are replacements) if (count($varCategories) > 0) { $newCats = array(); $originalCats = $output->getCategories(); foreach ($originalCats as $cat => $sortkey) { // make the replacement if (array_key_exists($cat, $varCategories)) { $newCats[$varCategories[$cat]] = $sortkey; } else { $newCats[$cat] = $sortkey; } } $output->setCategoryLinks($newCats); } } }
/** * This hook is registered by the Auth_remoteuser constructor. It will be * called on every page load. It serves the function of automatically logging * in the user. The Auth_remoteuser class is an AuthPlugin and handles the * actual authentication, user creation, etc. * * Details: * 1. Check to see if the user has a session and is not anonymous. If this is * true, check whether REMOTE_USER matches the session user. If so, we can * just return; otherwise we must logout the session user and login as the * REMOTE_USER. * 2. If the user doesn't have a session, we create a login form with our own * fake request and ask the form to authenticate the user. If the user does * not exist authenticateUserData will attempt to create one. The login form * uses our Auth_remoteuser class as an AuthPlugin. * * Note: If cookies are disabled, an infinite loop /might/ occur? */ function Auth_remote_user_hook() { global $wgUser, $wgRequest, $wgAuthRemoteuserDomain, $wgAuth; // For a few special pages, don't do anything. $title = $wgRequest->getVal('title'); if ($title == Title::makeName(NS_SPECIAL, 'UserLogout') || $title == Title::makeName(NS_SPECIAL, 'UserLogin')) { return; } // Process the username if required if (!isset($_SERVER['REMOTE_USER'])) { return; } if (isset($wgAuthRemoteuserDomain) && strlen($wgAuthRemoteuserDomain)) { $username = str_replace("{$wgAuthRemoteuserDomain}\\", "", $_SERVER['REMOTE_USER']); $username = str_replace("@{$wgAuthRemoteuserDomain}", "", $username); } else { $username = $_SERVER['REMOTE_USER']; } // Check for valid session $user = User::newFromSession(); if (!$user->isAnon()) { if ($user->getName() == $wgAuth->getCanonicalName($username)) { return; // Correct user is already logged in. } else { $user->doLogout(); // Logout mismatched user. } } // Copied from includes/SpecialUserlogin.php if (!isset($wgCommandLineMode) && !isset($_COOKIE[session_name()])) { wfSetupSession(); } // If the login form returns NEED_TOKEN try once more with the right token $trycount = 0; $token = ''; $errormessage = ''; do { $tryagain = false; // Submit a fake login form to authenticate the user. $params = new FauxRequest(array('wpName' => $username, 'wpPassword' => '', 'wpDomain' => '', 'wpLoginToken' => $token, 'wpRemember' => '')); // Authenticate user data will automatically create new users. $loginForm = new LoginForm($params); $result = $loginForm->authenticateUserData(); switch ($result) { case LoginForm::SUCCESS: $wgUser->setOption('rememberpassword', 1); $wgUser->setCookies(); break; case LoginForm::NEED_TOKEN: $token = $loginForm->getLoginToken(); $tryagain = $trycount == 0; break; case LoginForm::WRONG_TOKEN: $errormessage = 'WrongToken'; break; case LoginForm::NO_NAME: $errormessage = 'NoName'; break; case LoginForm::ILLEGAL: $errormessage = 'Illegal'; break; case LoginForm::WRONG_PLUGIN_PASS: $errormessage = 'WrongPluginPass'; break; case LoginForm::NOT_EXISTS: $errormessage = 'NotExists'; break; case LoginForm::WRONG_PASS: $errormessage = 'WrongPass'; break; case LoginForm::EMPTY_PASS: $errormessage = 'EmptyPass'; break; default: $errormessage = 'Unknown'; break; } if ($result != LoginForm::SUCCESS && $result != LoginForm::NEED_TOKEN) { error_log('Unexpected REMOTE_USER authentication failure. Login Error was:' . $errormessage); } $trycount++; } while ($tryagain); return; }