to message 'sidebar'
** (bug 6332) Lacking entry Mainpage-url
** (bug 8617) Separate main page url and name
+* Automatically add old redirects to the redirect table when needed
=== Bug fixes in 1.13 ===
var $mTouched; //!<
var $mUser; //!<
var $mUserText; //!<
+ var $mRedirectTarget; //!<
/**@}}*/
/**
$this->mRedirectedFrom = $from;
}
+ /**
+ * If this page is a redirect, get its target
+ *
+ * The target will be fetched from the redirect table if possible.
+ * If this page doesn't have an entry there, call insertRedirect()
+ * @return mixed Title object, or null if this page is not a redirect
+ */
+ public function getRedirectTarget() {
+ if(!$this->mTitle || !$this->mTitle->isRedirect())
+ return null;
+ if(!is_null($this->mRedirectTarget))
+ return $this->mRedirectTarget;
+
+ # Query the redirect table
+ $dbr = wfGetDb(DB_SLAVE);
+ $res = $dbr->select('redirect',
+ array('rd_namespace', 'rd_title'),
+ array('rd_from' => $this->getID()),
+ __METHOD__
+ );
+ $row = $dbr->fetchObject($res);
+ if($row)
+ return $this->mRedirectTarget = Title::makeTitle($row->rd_namespace, $row->rd_title);
+
+ # This page doesn't have an entry in the redirect table
+ return $this->mRedirectTarget = $this->insertRedirect();
+ }
+
+ /**
+ * Insert an entry for this page into the redirect table.
+ *
+ * Don't call this function directly unless you know what you're doing.
+ * @return Title object
+ */
+ public function insertRedirect() {
+ $retval = Title::newFromRedirect($this->getContent());
+ if(!$retval)
+ return null;
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->insert('redirect', array(
+ 'rd_from' => $this->getID(),
+ 'rd_namespace' => $retval->getNamespace(),
+ 'rd_title' => $retval->getDBKey()
+ ));
+ return $retval;
+ }
+
/**
* @return mixed false, Title of in-wiki target, or string with URL
*/
function followRedirect() {
- $text = $this->getContent();
- $rt = Title::newFromRedirect( $text );
+ $rt = $this->getRedirectTarget();
# process if title object is valid and not special:userlogout
if( $rt ) {
$this->mCurID = $this->mUser = $this->mCounter = -1; # Not loaded
$this->mRedirectedFrom = null; # Title object if set
+ $this->mRedirectTarget = null; # Title object if set
$this->mUserText =
$this->mTimestamp = $this->mComment = '';
$this->mGoodAdjustment = $this->mTotalAdjustment = 0;
}
- elseif ( $rt = Title::newFromRedirect( $text ) ) {
+ elseif ( $rt = $this->getRedirectTarget() ) {
# Display redirect
$imageDir = $wgContLang->isRTL() ? 'rtl' : 'ltr';
$imageUrl = $wgStylePath.'/common/images/redirect' . $imageDir . '.png';
$form->BlockEmail = $params['noemail'];
$form->BlockHideName = $params['hidename'];
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
$retval = $form->doBlock($userID, $expiry);
if(!empty($retval))
// We don't care about multiple errors, just report one of them
$this->dieUsageMsg($retval);
+ $this->getMain()->scheduleCommit();
- $dbw->commit();
$res['user'] = $params['user'];
$res['userID'] = $userID;
$res['expiry'] = ($expiry == Block::infinity() ? 'infinite' : $expiry);
$articleObj = new Article($titleObj);
$reason = (isset($params['reason']) ? $params['reason'] : NULL);
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
$retval = self::delete($articleObj, $params['token'], $reason);
if(!empty($retval))
$articleObj->doWatch();
else if($params['unwatch'])
$articleObj->doUnwatch();
- $dbw->commit();
+ $this->getMain()->scheduleCommit();
$r = array('title' => $titleObj->getPrefixedText(), 'reason' => $reason);
$this->getResult()->addValue(null, $this->getModuleName(), $r);
}
# but that breaks API mode detection through is_null($wgTitle)
global $wgTitle;
$wgTitle = null;
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
$retval = $ep->internalAttemptSave($result, $wgUser->isAllowed('bot') && $params['bot']);
- $dbw->commit();
+ $this->getMain()->scheduleCommit();
switch($retval)
{
case EditPage::AS_HOOK_ERROR:
'dbgfm' => 'ApiFormatDbg'
);
- private $mPrinter, $mModules, $mModuleNames, $mFormats, $mFormatNames;
+ private $mPrinter, $mModules, $mModuleNames, $mFormats, $mFormatNames, $mCommit;
private $mResult, $mAction, $mShowVersions, $mEnableWrite, $mRequest, $mInternalMode, $mSquidMaxage;
/**
$this->mRequest = & $request;
$this->mSquidMaxage = 0;
+ $this->mCommit = false;
}
/**
public function createPrinterByName($format) {
return new $this->mFormats[$format] ($this, $format);
}
+
+ /**
+ * Schedule a database commit
+ */
+ public function scheduleCommit() {
+ $this->mCommit = true;
+ }
/**
* Execute api request. Any errors will be handled if the API was called by the remote client.
$this->executeAction();
else
$this->executeActionWithErrorHandling();
+ if($this->mCommit)
+ {
+ $dbw = wfGetDb(DB_MASTER);
+ $dbw->immediateCommit();
+ }
$this->profileOut();
}
}
+
// We don't care about multiple errors, just report one of them
$this->dieUsageMsg(current($errors));
- $dbw = wfGetDB(DB_MASTER);
- $dbw->begin();
$retval = $fromTitle->moveTo($toTitle, true, $params['reason'], !$params['noredirect']);
if($retval !== true)
$this->dieUsageMsg(array($retval));
$wgUser->removeWatch($fromTitle);
$wgUser->removeWatch($toTitle);
}
- $dbw->commit(); // Make sure all changes are really written to the DB
+ $this->getMain()->scheduleCommit();
$this->getResult()->addValue(null, $this->getModuleName(), $r);
}
while($row = $db->fetchObject($res))
{
$rdfrom = intval($row->rd_from);
- $from = Title::newFromId($row->rd_from)->getPrefixedText();
+ $from = $this->mPendingRedirectIDs[$rdfrom]->getPrefixedText();
$to = Title::makeTitle($row->rd_namespace, $row->rd_title)->getPrefixedText();
unset($this->mPendingRedirectIDs[$rdfrom]);
if(!isset($this->mAllPages[$row->rd_namespace][$row->rd_title]))
}
$db->freeResult($res);
if(!empty($this->mPendingRedirectIDs))
- ApiBase :: dieDebug(__METHOD__, 'Invalid redirect IDs were found');
+ {
+ # We found pages that aren't in the redirect table
+ # Add them
+ foreach($this->mPendingRedirectIDs as $id => $title)
+ {
+ $article = new Article($title);
+ $rt = $article->insertRedirect();
+ if(!$rt)
+ # What the hell. Let's just ignore this
+ continue;
+ $lb->addObj($rt);
+ $this->mRedirectTitles[$title->getPrefixedText()] = $rt->getPrefixedText();
+ unset($this->mPendingRedirectIDs[$id]);
+ }
+ $this->getMain()->scheduleCommit();
+ }
return $lb;
}
}
}
+
$this->dieUsageMsg(array('missingtitles-createonly'));
}
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
if($titleObj->exists()) {
$articleObj = new Article($titleObj);
$ok = $articleObj->updateRestrictions($protections, $params['reason'], $params['cascade'], $expiry);
// This is very weird. Maybe the article was deleted or the user was blocked/desysopped in the meantime?
// Just throw an unknown error in this case, as it's very likely to be a race condition
$this->dieUsageMsg(array());
- $dbw->commit();
+ $this->getMain()->scheduleCommit();
$res = array('title' => $titleObj->getPrefixedText(), 'reason' => $params['reason']);
if($expiry == Block::infinity())
$res['expiry'] = 'infinity';
$articleObj = new Article($titleObj);
$summary = (isset($params['summary']) ? $params['summary'] : "");
$details = null;
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
$retval = $articleObj->doRollback($username, $summary, $params['token'], $params['markbot'], $details);
if(!empty($retval))
// We don't care about multiple errors, just report one of them
$this->dieUsageMsg(current($retval));
- $dbw->commit();
+ $this->getMain()->scheduleCommit();
$current = $target = $summary = NULL;
extract($details);
$id = $params['id'];
$user = $params['user'];
$reason = (is_null($params['reason']) ? '' : $params['reason']);
- $dbw = wfGetDb(DB_MASTER);
- $dbw->begin();
$retval = IPUnblockForm::doUnblock($id, $user, $reason, $range);
if(!empty($retval))
$this->dieUsageMsg($retval);
- $dbw->commit();
+ $this->getMain()->scheduleCommit();
$res['id'] = $id;
$res['user'] = $user;
$res['reason'] = $reason;
if(!is_array($retval))
$this->dieUsageMsg(array('cannotundelete'));
- $dbw->commit();
+ $this->getMain()->scheduleCommit();
$info['title'] = $titleObj->getPrefixedText();
$info['revisions'] = $retval[0];
$info['fileversions'] = $retval[1];