<?php
/**
- * Contains the EditPage class
+ * Page edition user interface.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
* @file
*/
*/
const AS_HOOK_ERROR = 210;
- /**
- * Status: The filter function set in $wgFilterCallback returned true (= block it)
- */
- const AS_FILTERING = 211;
-
/**
* Status: A hook function returned an error
*/
# If we just undid one rev, use an autosummary
$firstrev = $oldrev->getNext();
- if ( $firstrev->getId() == $undo ) {
+ if ( $firstrev && $firstrev->getId() == $undo ) {
$undoSummary = wfMsgForContent( 'undo-summary', $undo, $undorev->getUserText() );
if ( $this->summary === '' ) {
$this->summary = $undoSummary;
$bot = $wgUser->isAllowed( 'bot' ) && $this->bot;
$status = $this->internalAttemptSave( $resultDetails, $bot );
// FIXME: once the interface for internalAttemptSave() is made nicer, this should use the message in $status
-
if ( $status->value == self::AS_SUCCESS_UPDATE || $status->value == self::AS_SUCCESS_NEW_ARTICLE ) {
$this->didSave = true;
}
return true;
case self::AS_HOOK_ERROR:
- case self::AS_FILTERING:
return false;
case self::AS_SUCCESS_NEW_ARTICLE:
$permission = $this->mTitle->isTalkPage() ? 'createtalk' : 'createpage';
throw new PermissionsError( $permission );
+ default:
+ // We don't recognize $status->value. The only way that can happen
+ // is if an extension hook aborted from inside ArticleSave.
+ // Render the status object into $this->hookError
+ // FIXME this sucks, we should just use the Status object throughout
+ $this->hookError = '<div class="error">' . $status->getWikitext() .
+ '</div>';
+ return true;
}
return false;
}
* AS_CONTENT_TOO_BIG and AS_BLOCKED_PAGE_FOR_USER. All that stuff needs to be cleaned up some time.
*/
function internalAttemptSave( &$result, $bot = false ) {
- global $wgFilterCallback, $wgUser, $wgRequest, $wgParser;
- global $wgMaxArticleSize;
+ global $wgUser, $wgRequest, $wgParser, $wgMaxArticleSize;
$status = Status::newGood();
wfProfileOut( __METHOD__ );
return $status;
}
- if ( $wgFilterCallback && is_callable( $wgFilterCallback ) && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section, $this->hookError, $this->summary ) ) {
- # Error messages or other handling should be performed by the filter function
- $status->setResult( false, self::AS_FILTERING );
- wfProfileOut( __METHOD__ . '-checks' );
- wfProfileOut( __METHOD__ );
- return $status;
- }
if ( !wfRunHooks( 'EditFilter', array( $this, $this->textbox1, $this->section, &$this->hookError, $this->summary ) ) ) {
# Error messages etc. could be handled within the hook...
$status->fatal( 'hookaborted' );
wfProfileOut( __METHOD__ . '-checks' );
- # If article is new, insert it.
- $aid = $this->mTitle->getArticleID( Title::GAID_FOR_UPDATE );
- $new = ( $aid == 0 );
+ // Use SELECT FOR UPDATE here to avoid transaction collision in
+ // WikiPage::updateRevisionOn() and ending in the self::AS_END case.
+ $this->mArticle->loadPageData( 'forupdate' );
+ $new = !$this->mArticle->exists();
if ( $new ) {
// Late check for create permission, just in case *PARANOIA*
} else {
# Article exists. Check for edit conflict.
-
- $this->mArticle->clear(); # Force reload of dates, etc.
$timestamp = $this->mArticle->getTimestamp();
-
wfDebug( "timestamp: {$timestamp}, edittime: {$this->edittime}\n" );
if ( $timestamp != $this->edittime ) {
wfProfileOut( __METHOD__ );
return $status;
} else {
- $this->isConflict = true;
- $doEditStatus->value = self::AS_END; // Destroys data doEdit() put in $status->value but who cares
+ // Failure from doEdit()
+ // Show the edit conflict page for certain recognized errors from doEdit(),
+ // but don't show it for errors from extension hooks
+ $errors = $doEditStatus->getErrorsArray();
+ if ( in_array( $errors[0][0], array( 'edit-gone-missing', 'edit-conflict',
+ 'edit-already-exists' ) ) )
+ {
+ $this->isConflict = true;
+ // Destroys data doEdit() put in $status->value but who cares
+ $doEditStatus->value = self::AS_END;
+ }
wfProfileOut( __METHOD__ );
return $doEditStatus;
}
# Optional notices on a per-namespace and per-page basis
$editnotice_ns = 'editnotice-' . $this->mTitle->getNamespace();
- $editnotice_ns_message = wfMessage( $editnotice_ns )->inContentLanguage();
+ $editnotice_ns_message = wfMessage( $editnotice_ns );
if ( $editnotice_ns_message->exists() ) {
$wgOut->addWikiText( $editnotice_ns_message->plain() );
}
$editnotice_base = $editnotice_ns;
while ( count( $parts ) > 0 ) {
$editnotice_base .= '-' . array_shift( $parts );
- $editnotice_base_msg = wfMessage( $editnotice_base )->inContentLanguage();
+ $editnotice_base_msg = wfMessage( $editnotice_base );
if ( $editnotice_base_msg->exists() ) {
$wgOut->addWikiText( $editnotice_base_msg->plain() );
}
} else {
# Even if there are no subpages in namespace, we still don't want / in MW ns.
$editnoticeText = $editnotice_ns . '-' . str_replace( '/', '-', $this->mTitle->getDBkey() );
- $editnoticeMsg = wfMessage( $editnoticeText )->inContentLanguage();
+ $editnoticeMsg = wfMessage( $editnoticeText );
if ( $editnoticeMsg->exists() ) {
$wgOut->addWikiText( $editnoticeMsg->plain() );
}