/** @var string */
public $action = 'submit';
- /** @var bool */
+ /** @var bool Whether an edit conflict needs to be resolved. Detected based on whether
+ * $editRevId is different from the current revision. When a conflict has successfully
+ * been resolved by a 3-way-merge, this field is set to false.
+ */
public $isConflict = false;
/** @var bool New page or new section */
/** @var bool Has a summary been preset using GET parameter &summary= ? */
public $hasPresetSummary = false;
- /** @var Revision|bool|null */
+ /** @var Revision|bool|null A revision object corresponding to $this->editRevId. */
public $mBaseRevision = false;
/** @var bool */
/** @var string */
public $edittime = '';
- /** @var int */
+ /** @var int ID of the current revision at the time editing was initiated on the client.
+ * This is used to detect and resolve edit conflicts.
+ *
+ * @note 0 if the page did not exist at that time.
+ * @note When starting an edit from an old revision, this still records the current
+ * revision at the time , not the one the edit is based on.
+ *
+ * @see $oldid
+ * @see getBaseRevision()
+ */
private $editRevId = null;
/** @var string */
/** @var string */
public $starttime = '';
- /** @var int */
+ /** @var int Revision ID the edit is based on, or 0 if it's the current revision.
+ * @see $editRevId
+ */
public $oldid = 0;
- /** @var int */
+ /** @var int Revision ID the edit is based on, adjusted when an edit conflict is resolved.
+ * @see $editRevId
+ * @see $oldid
+ * @see getparentRevId()
+ */
public $parentRevId = 0;
/** @var string */
} else {
// If we receive the last parameter of the request, we can fairly
// claim the POST request has not been truncated.
-
- // TODO: softened the check for cutover. Once we determine
- // that it is safe, we should complete the transition by
- // removing the "edittime" clause.
- $this->incompleteForm = ( !$request->getVal( 'wpUltimateParam' )
- && is_null( $this->edittime ) );
+ $this->incompleteForm = !$request->getVal( 'wpUltimateParam' );
}
if ( $this->incompleteForm ) {
# If the form is incomplete, force to preview.
wfDebug( "timestamp: {$timestamp}, edittime: {$this->edittime}\n" );
- // Check editRevId if set, which handles same-second timestamp collisions
+ // An edit conflict is detected if the current revision is different from the
+ // revision that was current when editing was initiated on the client.
+ // This is checked based on the timestamp and revision ID.
+ // TODO: the timestamp based check can probably go away now.
if ( $timestamp != $this->edittime
|| ( $this->editRevId !== null && $this->editRevId != $latest )
) {
private function mergeChangesIntoContent( &$editContent ) {
$db = wfGetDB( DB_MASTER );
- // This is the revision the editor started from
+ // This is the revision that was current at the time editing was initiated on the client,
+ // even if the edit was based on an old revision.
$baseRevision = $this->getBaseRevision();
$baseContent = $baseRevision ? $baseRevision->getContent() : null;
}
/**
- * @note: this method is very poorly named. If the user opened the form with ?oldid=X,
- * one might think of X as the "base revision", which is NOT what this returns.
- * @return Revision|null Current version when the edit was started
+ * Returns the revision that was current at the time editing was initiated on the client,
+ * even if the edit was based on an old revision.
+ *
+ * @warning: this method is very poorly named. If the user opened the form with ?oldid=X,
+ * one might think of X as the "base revision", which is NOT what this returns,
+ * see oldid for that. One might further assume that this corresponds to the $baseRevId
+ * parameter of WikiPage::doEditContent, which is not the case either.
+ * getExpectedParentRevision() would perhaps be a better name.
+ *
+ * @return Revision|null Current version when editing was initiated on the client
*/
public function getBaseRevision() {
if ( !$this->mBaseRevision ) {
* Builds a standard summary input with a label.
*
* @param string $summary The value of the summary input
- * @param string $labelText The html to place inside the label
- * @param array $inputAttrs Array of attrs to use on the input
+ * @param string|null $labelText The html to place inside the label
+ * @param array|null $inputAttrs Array of attrs to use on the input
*
* @return OOUI\FieldLayout OOUI FieldLayout with Label and Input
*/
* The $textoverride method can be used by subclasses overriding showContentForm
* to pass back to this method.
*
- * @param array $customAttribs Array of html attributes to use in the textarea
- * @param string $textoverride Optional text to override $this->textarea1 with
+ * @param array|null $customAttribs Array of html attributes to use in the textarea
+ * @param string|null $textoverride Optional text to override $this->textarea1 with
*/
protected function showTextbox1( $customAttribs = null, $textoverride = null ) {
if ( $this->wasDeletedSinceLastEdit() && $this->formtype == 'save' ) {
* Shows a bulletin board style toolbar for common editing functions.
* It can be disabled in the user preferences.
*
- * @param Title $title Title object for the page being edited (optional)
+ * @param Title|null $title Title object for the page being edited (optional)
* @return string
*/
public static function getEditToolbar( $title = null ) {