X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2FEditPage.php;h=d6d714d794250eb0a2965fbff0866cd0c185113f;hb=8e7ea374a79e19f97a09f09631a0775639d8b3ea;hp=a97558f73bc1224313e19008740a0a90f97fd26a;hpb=9cc44a6aed735d3e73ce188ddff56f7821d6dc90;p=lhc%2Fweb%2Fwiklou.git
diff --git a/includes/EditPage.php b/includes/EditPage.php
index a97558f73b..d6d714d794 100644
--- a/includes/EditPage.php
+++ b/includes/EditPage.php
@@ -17,14 +17,21 @@ class EditPage {
var $mArticle;
var $mTitle;
var $mMetaData = '';
-
+ var $isConflict = false;
+ var $isCssJsSubpage = false;
+ var $deletedSinceEdit = false;
+ var $formtype;
+ var $firsttime;
+ var $lastDelete;
+ var $mTokenOk = true;
+
# Form values
var $save = false, $preview = false, $diff = false;
- var $minoredit = false, $watchthis = false;
+ var $minoredit = false, $watchthis = false, $recreate = false;
var $textbox1 = '', $textbox2 = '', $summary = '';
- var $edittime = '', $section = '';
- var $oldid = 0;
-
+ var $edittime = '', $section = '', $starttime = '';
+ var $oldid = 0, $editintro = '', $scrolltop = null;
+
/**
* @todo document
* @param $article
@@ -97,7 +104,7 @@ class EditPage {
{
$sat[] = strtolower ( $x ) ;
}
-
+
}
# Templates, but only some
@@ -130,66 +137,164 @@ class EditPage {
$this->mMetaData = $s ;
}
+ function submit() {
+ $this->edit();
+ }
+
/**
- * This is the function that gets called for "action=edit".
+ * This is the function that gets called for "action=edit". It
+ * sets up various member variables, then passes execution to
+ * another function, usually showEditForm()
+ *
+ * The edit form is self-submitting, so that when things like
+ * preview and edit conflicts occur, we get the same form back
+ * with the extra stuff added. Only when the final submission
+ * is made and all is well do we actually save and redirect to
+ * the newly-edited page.
*/
function edit() {
- global $wgOut, $wgUser, $wgRequest;
+ global $wgOut, $wgUser, $wgRequest, $wgTitle;
+
+ if ( ! wfRunHooks( 'AlternateEdit', array( &$this ) ) )
+ return;
+
+ $fname = 'EditPage::edit';
+ wfProfileIn( $fname );
+ wfDebug( "$fname: enter\n" );
+
// this is not an article
$wgOut->setArticleFlag(false);
$this->importFormData( $wgRequest );
-
+ $this->firsttime = false;
+
if( $this->live ) {
$this->livePreview();
+ wfProfileOut( $fname );
return;
}
if ( ! $this->mTitle->userCanEdit() ) {
+ wfDebug( "$fname: user can't edit\n" );
$wgOut->readOnlyPage( $this->mArticle->getContent( true ), true );
+ wfProfileOut( $fname );
return;
}
- if ( !$this->preview && !$this->diff && $wgUser->isBlocked( !$this->save ) ) {
+ wfDebug( "$fname: Checking blocks\n" );
+ if ( !$this->preview && !$this->diff && $wgUser->isBlockedFrom( $this->mTitle, !$this->save ) ) {
# When previewing, don't check blocked state - will get caught at save time.
# Also, check when starting edition is done against slave to improve performance.
+ wfDebug( "$fname: user is blocked\n" );
$this->blockedIPpage();
+ wfProfileOut( $fname );
return;
}
if ( !$wgUser->isAllowed('edit') ) {
if ( $wgUser->isAnon() ) {
+ wfDebug( "$fname: user must log in\n" );
$this->userNotLoggedInPage();
+ wfProfileOut( $fname );
return;
} else {
+ wfDebug( "$fname: read-only page\n" );
$wgOut->readOnlyPage( $this->mArticle->getContent( true ), true );
+ wfProfileOut( $fname );
return;
}
}
+ if ( !$this->mTitle->userCan( 'create' ) && !$this->mTitle->exists() ) {
+ wfDebug( "$fname: no create permission\n" );
+ $this->noCreatePermission();
+ wfProfileOut( $fname );
+ return;
+ }
if ( wfReadOnly() ) {
+ wfDebug( "$fname: read-only mode is engaged\n" );
if( $this->save || $this->preview ) {
- $this->editForm( 'preview' );
+ $this->formtype = 'preview';
} else if ( $this->diff ) {
- $this->editForm( 'diff' );
+ $this->formtype = 'diff';
} else {
$wgOut->readOnlyPage( $this->mArticle->getContent( true ) );
+ wfProfileOut( $fname );
+ return;
+ }
+ } else {
+ if ( $this->save ) {
+ $this->formtype = 'save';
+ } else if ( $this->preview ) {
+ $this->formtype = 'preview';
+ } else if ( $this->diff ) {
+ $this->formtype = 'diff';
+ } else { # First time through
+ $this->firsttime = true;
+ if( $this->previewOnOpen() ) {
+ $this->formtype = 'preview';
+ } else {
+ $this->extractMetaDataFromArticle () ;
+ $this->formtype = 'initial';
+ }
}
- return;
}
- if ( $this->save ) {
- $this->editForm( 'save' );
- } else if ( $this->preview ) {
- $this->editForm( 'preview' );
- } else if ( $this->diff ) {
- $this->editForm( 'diff' );
- } else { # First time through
- if( $this->previewOnOpen() ) {
- $this->editForm( 'preview', true );
- } else {
- $this->extractMetaDataFromArticle () ;
- $this->editForm( 'initial', true );
+
+ wfProfileIn( "$fname-business-end" );
+
+ $this->isConflict = false;
+ // css / js subpages of user pages get a special treatment
+ $this->isCssJsSubpage = $wgTitle->isCssJsSubpage();
+
+ /* Notice that we can't use isDeleted, because it returns true if article is ever deleted
+ * no matter it's current state
+ */
+ $this->deletedSinceEdit = false;
+ if ( $this->edittime != '' ) {
+ /* Note that we rely on logging table, which hasn't been always there,
+ * but that doesn't matter, because this only applies to brand new
+ * deletes. This is done on every preview and save request. Move it further down
+ * to only perform it on saves
+ */
+ if ( $this->mTitle->isDeleted() ) {
+ $this->lastDelete = $this->getLastDelete();
+ if ( !is_null($this->lastDelete) ) {
+ $deletetime = $this->lastDelete->log_timestamp;
+ if ( ($deletetime - $this->starttime) > 0 ) {
+ $this->deletedSinceEdit = true;
+ }
+ }
}
}
+
+ if(!$this->mTitle->getArticleID() && ('initial' == $this->formtype || $this->firsttime )) { # new article
+ $this->showIntro();
+ }
+ if( $this->mTitle->isTalkPage() ) {
+ $wgOut->addWikiText( wfMsg( 'talkpagetext' ) );
+ }
+
+ # Attempt submission here. This will check for edit conflicts,
+ # and redundantly check for locked database, blocked IPs, etc.
+ # that edit() already checked just in case someone tries to sneak
+ # in the back door with a hand-edited submission URL.
+
+ if ( 'save' == $this->formtype ) {
+ if ( !$this->attemptSave() ) {
+ wfProfileOut( "$fname-business-end" );
+ wfProfileOut( $fname );
+ return;
+ }
+ }
+
+ # First time through: get contents, set time for conflict
+ # checking, etc.
+ if ( 'initial' == $this->formtype || $this->firsttime ) {
+ $this->initialiseForm();
+ }
+
+ $this->showEditForm();
+ wfProfileOut( "$fname-business-end" );
+ wfProfileOut( $fname );
}
-
+
/**
* Return true if this page should be previewed when the edit form
* is initially opened.
@@ -207,60 +312,88 @@ class EditPage {
* @todo document
*/
function importFormData( &$request ) {
+ global $wgLang ;
+ $fname = 'EditPage::importFormData';
+ wfProfileIn( $fname );
+
if( $request->wasPosted() ) {
# These fields need to be checked for encoding.
# Also remove trailing whitespace, but don't remove _initial_
# whitespace from the text boxes. This may be significant formatting.
- $this->textbox1 = rtrim( $request->getText( 'wpTextbox1' ) );
- $this->textbox2 = rtrim( $request->getText( 'wpTextbox2' ) );
+ $this->textbox1 = $this->safeUnicodeInput( $request, 'wpTextbox1' );
+ $this->textbox2 = $this->safeUnicodeInput( $request, 'wpTextbox2' );
$this->mMetaData = rtrim( $request->getText( 'metadata' ) );
- $this->summary = $request->getText( 'wpSummary' );
-
+ # Truncate for whole multibyte characters. +5 bytes for ellipsis
+ $this->summary = $wgLang->truncate( $request->getText( 'wpSummary' ), 250 );
+
$this->edittime = $request->getVal( 'wpEdittime' );
+ $this->starttime = $request->getVal( 'wpStarttime' );
+
+ $this->scrolltop = $request->getIntOrNull( 'wpScrolltop' );
+
if( is_null( $this->edittime ) ) {
# If the form is incomplete, force to preview.
+ wfDebug( "$fname: Form data appears to be incomplete\n" );
+ wfDebug( "POST DATA: " . var_export( $_POST, true ) . "\n" );
$this->preview = true;
} else {
- if( $this->tokenOk( $request ) ) {
- # Some browsers will not report any submit button
- # if the user hits enter in the comment box.
- # The unmarked state will be assumed to be a save,
- # if the form seems otherwise complete.
- $this->preview = $request->getCheck( 'wpPreview' );
- $this->diff = $request->getCheck( 'wpDiff' );
- } else {
- # Page might be a hack attempt posted from
- # an external site. Preview instead of saving.
- $this->preview = true;
+ $this->preview = $request->getCheck( 'wpPreview' );
+ $this->diff = $request->getCheck( 'wpDiff' );
+
+ if( !$this->preview ) {
+ if ( $this->tokenOk( $request ) ) {
+ # Some browsers will not report any submit button
+ # if the user hits enter in the comment box.
+ # The unmarked state will be assumed to be a save,
+ # if the form seems otherwise complete.
+ wfDebug( "$fname: Passed token check.\n" );
+ } else {
+ # Page might be a hack attempt posted from
+ # an external site. Preview instead of saving.
+ wfDebug( "$fname: Failed token check; forcing preview\n" );
+ $this->preview = true;
+ }
}
}
$this->save = ! ( $this->preview OR $this->diff );
if( !preg_match( '/^\d{14}$/', $this->edittime )) {
$this->edittime = null;
}
+
+ if( !preg_match( '/^\d{14}$/', $this->starttime )) {
+ $this->starttime = null;
+ }
+ $this->recreate = $request->getCheck( 'wpRecreate' );
+
$this->minoredit = $request->getCheck( 'wpMinoredit' );
$this->watchthis = $request->getCheck( 'wpWatchthis' );
} else {
# Not a posted form? Start with nothing.
+ wfDebug( "$fname: Not a posted form.\n" );
$this->textbox1 = '';
$this->textbox2 = '';
$this->mMetaData = '';
$this->summary = '';
$this->edittime = '';
+ $this->starttime = wfTimestampNow();
$this->preview = false;
$this->save = false;
$this->diff = false;
$this->minoredit = false;
$this->watchthis = false;
+ $this->recreate = false;
}
$this->oldid = $request->getInt( 'oldid' );
# Section edit can come from either the form or a link
$this->section = $request->getVal( 'wpSection', $request->getVal( 'section' ) );
-
+
$this->live = $request->getCheck( 'live' );
+ $this->editintro = $request->getText( 'editintro' );
+
+ wfProfileOut( $fname );
}
/**
@@ -275,207 +408,262 @@ class EditPage {
if( $wgUser->isAnon() ) {
# Anonymous users may not have a session
# open. Don't tokenize.
- return true;
+ $this->mTokenOk = true;
} else {
- return $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
+ $this->mTokenOk = $wgUser->matchEditToken( $request->getVal( 'wpEditToken' ) );
}
+ return $this->mTokenOk;
}
-
- function submit() {
- $this->edit();
+
+ function showIntro() {
+ global $wgOut, $wgUser;
+ $addstandardintro=true;
+ if($this->editintro) {
+ $introtitle=Title::newFromText($this->editintro);
+ if(isset($introtitle) && $introtitle->userCanRead()) {
+ $rev=Revision::newFromTitle($introtitle);
+ if($rev) {
+ $wgOut->addWikiText($rev->getText());
+ $addstandardintro=false;
+ }
+ }
+ }
+ if($addstandardintro) {
+ if ( $wgUser->isLoggedIn() )
+ $wgOut->addWikiText( wfMsg( 'newarticletext' ) );
+ else
+ $wgOut->addWikiText( wfMsg( 'newarticletextanon' ) );
+ }
}
/**
- * The edit form is self-submitting, so that when things like
- * preview and edit conflicts occur, we get the same form back
- * with the extra stuff added. Only when the final submission
- * is made and all is well do we actually save and redirect to
- * the newly-edited page.
- *
- * @param string $formtype Type of form either : save, initial, diff or preview
- * @param bool $firsttime True to load form data from db
+ * Attempt submission
+ * @return bool false if output is done, true if the rest of the form should be displayed
*/
- function editForm( $formtype, $firsttime = false ) {
- global $wgOut, $wgUser;
- global $wgLang, $wgContLang, $wgParser, $wgTitle;
- global $wgAllowAnonymousMinor;
- global $wgSpamRegex, $wgFilterCallback;
-
- $sk = $wgUser->getSkin();
- $isConflict = false;
- // css / js subpages of user pages get a special treatment
- $isCssJsSubpage = $wgTitle->isCssJsSubpage();
+ function attemptSave() {
+ global $wgSpamRegex, $wgFilterCallback, $wgUser, $wgOut;
+ $fname = 'EditPage::attemptSave';
+ wfProfileIn( $fname );
+ wfProfileIn( "$fname-checks" );
- if(!$this->mTitle->getArticleID()) { # new article
- $wgOut->addWikiText(wfmsg('newarticletext'));
- }
+ # Reintegrate metadata
+ if ( $this->mMetaData != '' ) $this->textbox1 .= "\n" . $this->mMetaData ;
+ $this->mMetaData = '' ;
- if( $this->mTitle->isTalkPage() ) {
- $wgOut->addWikiText(wfmsg('talkpagetext'));
+ # Check for spam
+ if ( $wgSpamRegex && preg_match( $wgSpamRegex, $this->textbox1, $matches ) ) {
+ $this->spamPage ( $matches[0] );
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ if ( $wgFilterCallback && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section ) ) {
+ # Error messages or other handling should be performed by the filter function
+ wfProfileOut( $fname );
+ wfProfileOut( "$fname-checks" );
+ return false;
+ }
+ if ( !wfRunHooks( 'EditFilter', array( &$this, $this->textbox1, $this->section ) ) ) {
+ # Error messages or other handling should be performed by the filter function
+ wfProfileOut( $fname );
+ wfProfileOut( "$fname-checks" );
+ return false;
+ }
+ if ( $wgUser->isBlockedFrom( $this->mTitle, false ) ) {
+ # Check block state against master, thus 'false'.
+ $this->blockedIPpage();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
}
- # Attempt submission here. This will check for edit conflicts,
- # and redundantly check for locked database, blocked IPs, etc.
- # that edit() already checked just in case someone tries to sneak
- # in the back door with a hand-edited submission URL.
-
- if ( 'save' == $formtype ) {
- # Reintegrate metadata
- if ( $this->mMetaData != '' ) $this->textbox1 .= "\n" . $this->mMetaData ;
- $this->mMetaData = '' ;
-
- # Check for spam
- if ( $wgSpamRegex && preg_match( $wgSpamRegex, $this->textbox1, $matches ) ) {
- $this->spamPage ( $matches[0] );
- return;
- }
- if ( $wgFilterCallback && $wgFilterCallback( $this->mTitle, $this->textbox1, $this->section ) ) {
- # Error messages or other handling should be performed by the filter function
- return;
- }
- if ( $wgUser->isBlocked( false ) ) {
- # Check block state against master, thus 'false'.
- $this->blockedIPpage();
- return;
- }
-
- if ( !$wgUser->isAllowed('edit') ) {
- if ( $wgUser->isAnon() ) {
+ if ( !$wgUser->isAllowed('edit') ) {
+ if ( $wgUser->isAnon() ) {
$this->userNotLoggedInPage();
- return;
- }
- else {
- $wgOut->readOnlyPage();
- return;
- }
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
}
-
- if ( wfReadOnly() ) {
+ else {
$wgOut->readOnlyPage();
- return;
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
}
- if ( $wgUser->pingLimiter() ) {
- $wgOut->rateLimited();
+ }
+
+ if ( wfReadOnly() ) {
+ $wgOut->readOnlyPage();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+ if ( $wgUser->pingLimiter() ) {
+ $wgOut->rateLimited();
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ # If the article has been deleted while editing, don't save it without
+ # confirmation
+ if ( $this->deletedSinceEdit && !$this->recreate ) {
+ wfProfileOut( "$fname-checks" );
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ wfProfileOut( "$fname-checks" );
+
+ # If article is new, insert it.
+ $aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
+ if ( 0 == $aid ) {
+ // Late check for create permission, just in case *PARANOIA*
+ if ( !$this->mTitle->userCan( 'create' ) ) {
+ wfDebug( "$fname: no create permission\n" );
+ $this->noCreatePermission();
+ wfProfileOut( $fname );
return;
}
-
- # If article is new, insert it.
- $aid = $this->mTitle->getArticleID( GAID_FOR_UPDATE );
- if ( 0 == $aid ) {
- # Don't save a new article if it's blank.
- if ( ( '' == $this->textbox1 ) ||
- ( wfMsg( 'newarticletext' ) == $this->textbox1 ) ) {
+
+ # Don't save a new article if it's blank.
+ if ( ( '' == $this->textbox1 ) ) {
$wgOut->redirect( $this->mTitle->getFullURL() );
- return;
- }
- if (wfRunHooks('ArticleSave', array(&$this->mArticle, &$wgUser, &$this->textbox1,
- &$this->summary, &$this->minoredit, &$this->watchthis, NULL)))
- {
- $this->mArticle->insertNewArticle( $this->textbox1, $this->summary,
- $this->minoredit, $this->watchthis );
- wfRunHooks('ArticleSaveComplete', array(&$this->mArticle, &$wgUser, $this->textbox1,
- $this->summary, $this->minoredit,
- $this->watchthis, NULL));
- }
- return;
+ wfProfileOut( $fname );
+ return false;
}
- # Article exists. Check for edit conflict.
+ $isComment=($this->section=='new');
+ $this->mArticle->insertNewArticle( $this->textbox1, $this->summary,
+ $this->minoredit, $this->watchthis, false, $isComment);
+
+ wfProfileOut( $fname );
+ return false;
+ }
+
+ # Article exists. Check for edit conflict.
- $this->mArticle->clear(); # Force reload of dates, etc.
- $this->mArticle->forUpdate( true ); # Lock the article
+ $this->mArticle->clear(); # Force reload of dates, etc.
+ $this->mArticle->forUpdate( true ); # Lock the article
- if( ( $this->section != 'new' ) &&
- ($this->mArticle->getTimestamp() != $this->edittime ) ) {
- $isConflict = true;
- }
- $userid = $wgUser->getID();
+ if( ( $this->section != 'new' ) &&
+ ($this->mArticle->getTimestamp() != $this->edittime ) )
+ {
+ $this->isConflict = true;
+ }
+ $userid = $wgUser->getID();
- if ( $isConflict) {
- wfDebug( "EditPage::editForm conflict! getting section '$this->section' for time '$this->edittime' (article time '" .
- $this->mArticle->getTimestamp() . "'\n" );
- $text = $this->mArticle->getTextOfLastEditWithSectionReplacedOrAdded(
- $this->section, $this->textbox1, $this->summary, $this->edittime);
- }
- else {
- wfDebug( "EditPage::editForm getting section '$this->section'\n" );
- $text = $this->mArticle->getTextOfLastEditWithSectionReplacedOrAdded(
- $this->section, $this->textbox1, $this->summary);
- }
- # Suppress edit conflict with self
+ if ( $this->isConflict) {
+ wfDebug( "EditPage::editForm conflict! getting section '$this->section' for time '$this->edittime' (article time '" .
+ $this->mArticle->getTimestamp() . "'\n" );
+ $text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $this->summary, $this->edittime);
+ }
+ else {
+ wfDebug( "EditPage::editForm getting section '$this->section'\n" );
+ $text = $this->mArticle->replaceSection( $this->section, $this->textbox1, $this->summary);
+ }
+ if( is_null( $text ) ) {
+ wfDebug( "EditPage::editForm activating conflict; section replace failed.\n" );
+ $this->isConflict = true;
+ $text = $this->textbox1;
+ }
- if ( ( 0 != $userid ) && ( $this->mArticle->getUser() == $userid ) ) {
- wfDebug( "Suppressing edit conflict, same user.\n" );
- $isConflict = false;
- } else {
- # switch from section editing to normal editing in edit conflict
- if($isConflict) {
- # Attempt merge
- if( $this->mergeChangesInto( $text ) ){
- // Successful merge! Maybe we should tell the user the good news?
- $isConflict = false;
- wfDebug( "Suppressing edit conflict, successful merge.\n" );
- } else {
- $this->section = '';
- $this->textbox1 = $text;
- wfDebug( "Keeping edit conflict, failed merge.\n" );
- }
+ # Suppress edit conflict with self, except for section edits where merging is required.
+ if ( ( $this->section == '' ) && ( 0 != $userid ) && ( $this->mArticle->getUser() == $userid ) ) {
+ wfDebug( "Suppressing edit conflict, same user.\n" );
+ $this->isConflict = false;
+ } else {
+ # switch from section editing to normal editing in edit conflict
+ if($this->isConflict) {
+ # Attempt merge
+ if( $this->mergeChangesInto( $text ) ){
+ // Successful merge! Maybe we should tell the user the good news?
+ $this->isConflict = false;
+ wfDebug( "Suppressing edit conflict, successful merge.\n" );
+ } else {
+ $this->section = '';
+ $this->textbox1 = $text;
+ wfDebug( "Keeping edit conflict, failed merge.\n" );
}
}
- if ( ! $isConflict ) {
- # All's well
- $sectionanchor = '';
- if( $this->section == 'new' ) {
- if( $this->summary != '' ) {
- $sectionanchor = $this->sectionAnchor( $this->summary );
- }
- } elseif( $this->section != '' ) {
- # Try to get a section anchor from the section source, redirect to edited section if header found
- # XXX: might be better to integrate this into Article::getTextOfLastEditWithSectionReplacedOrAdded
- # for duplicate heading checking and maybe parsing
- $hasmatch = preg_match( "/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
- # we can't deal with anchors, includes, html etc in the header for now,
- # headline would need to be parsed to improve this
- #if($hasmatch and strlen($matches[2]) > 0 and !preg_match( "/[\\['{<>]/", $matches[2])) {
- if($hasmatch and strlen($matches[2]) > 0) {
- $sectionanchor = $this->sectionAnchor( $matches[2] );
- }
- }
-
- if (wfRunHooks('ArticleSave', array(&$this->mArticle, &$wgUser, &$text,
- &$this->summary, &$this->minoredit,
- &$this->watchthis, &$sectionanchor)))
- {
- # update the article here
- if($this->mArticle->updateArticle( $text, $this->summary, $this->minoredit,
- $this->watchthis, '', $sectionanchor ))
- {
- wfRunHooks('ArticleSaveComplete', array(&$this->mArticle, &$wgUser, $text,
- $this->summary, $this->minoredit,
- $this->watchthis, $sectionanchor));
- return;
- }
- else
- $isConflict = true;
- }
+ }
+
+ if ( $this->isConflict ) {
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ # All's well
+ wfProfileIn( "$fname-sectionanchor" );
+ $sectionanchor = '';
+ if( $this->section == 'new' ) {
+ if( $this->summary != '' ) {
+ $sectionanchor = $this->sectionAnchor( $this->summary );
+ }
+ } elseif( $this->section != '' ) {
+ # Try to get a section anchor from the section source, redirect to edited section if header found
+ # XXX: might be better to integrate this into Article::replaceSection
+ # for duplicate heading checking and maybe parsing
+ $hasmatch = preg_match( "/^ *([=]{1,6})(.*?)(\\1) *\\n/i", $this->textbox1, $matches );
+ # we can't deal with anchors, includes, html etc in the header for now,
+ # headline would need to be parsed to improve this
+ if($hasmatch and strlen($matches[2]) > 0) {
+ $sectionanchor = $this->sectionAnchor( $matches[2] );
}
}
- # First time through: get contents, set time for conflict
- # checking, etc.
-
- if ( 'initial' == $formtype || $firsttime ) {
- $this->edittime = $this->mArticle->getTimestamp();
- $this->textbox1 = $this->mArticle->getContent( true );
- $this->summary = '';
- $this->proxyCheck();
+ wfProfileOut( "$fname-sectionanchor" );
+
+ // Save errors may fall down to the edit form, but we've now
+ // merged the section into full text. Clear the section field
+ // so that later submission of conflict forms won't try to
+ // replace that into a duplicated mess.
+ $this->textbox1 = $text;
+ $this->section = '';
+
+ # update the article here
+ if( $this->mArticle->updateArticle( $text, $this->summary, $this->minoredit,
+ $this->watchthis, '', $sectionanchor ) ) {
+ wfProfileOut( $fname );
+ return false;
+ } else {
+ $this->isConflict = true;
}
+ wfProfileOut( $fname );
+ return true;
+ }
+
+ /**
+ * Initialise form fields in the object
+ * Called on the first invocation, e.g. when a user clicks an edit link
+ */
+ function initialiseForm() {
+ $this->edittime = $this->mArticle->getTimestamp();
+ $this->textbox1 = $this->mArticle->getContent( true );
+ $this->summary = '';
+ wfProxyCheck();
+ }
+
+ /**
+ * Send the edit form and related headers to $wgOut
+ * @param $formCallback Optional callable that takes an OutputPage
+ * parameter; will be called during form output
+ * near the top, for captchas and the like.
+ */
+ function showEditForm( $formCallback=null ) {
+ global $wgOut, $wgUser, $wgAllowAnonymousMinor, $wgLang, $wgContLang;
+
+ $fname = 'EditPage::showEditForm';
+ wfProfileIn( $fname );
+
+ $sk =& $wgUser->getSkin();
+
$wgOut->setRobotpolicy( 'noindex,nofollow' );
# Enabled article-related sidebar, toplinks, etc.
$wgOut->setArticleRelated( true );
- if ( $isConflict ) {
+ if ( $this->isConflict ) {
$s = wfMsg( 'editconflict', $this->mTitle->getPrefixedText() );
$wgOut->setPageTitle( $s );
$wgOut->addWikiText( wfMsg( 'explainconflict' ) );
@@ -490,34 +678,33 @@ class EditPage {
$s = wfMsg('editingcomment', $this->mTitle->getPrefixedText() );
} else {
$s = wfMsg('editingsection', $this->mTitle->getPrefixedText() );
- }
- if( !$this->preview && !$this->diff ) {
- preg_match( "/^(=+)(.+)\\1/mi",
- $this->textbox1,
- $matches );
- if( !empty( $matches[2] ) ) {
- $this->summary = "/* ". trim($matches[2])." */ ";
- }
+ if( !$this->preview && !$this->diff ) {
+ preg_match( "/^(=+)(.+)\\1/mi",
+ $this->textbox1,
+ $matches );
+ if( !empty( $matches[2] ) ) {
+ $this->summary = "/* ". trim($matches[2])." */ ";
+ }
+ }
}
} else {
$s = wfMsg( 'editing', $this->mTitle->getPrefixedText() );
}
$wgOut->setPageTitle( $s );
if ( !$this->checkUnicodeCompliantBrowser() ) {
- $this->mArticle->setOldSubtitle();
$wgOut->addWikiText( wfMsg( 'nonunicodebrowser') );
}
if ( isset( $this->mArticle )
&& isset( $this->mArticle->mRevision )
&& !$this->mArticle->mRevision->isCurrent() ) {
- $this->mArticle->setOldSubtitle();
+ $this->mArticle->setOldSubtitle( $this->mArticle->mRevision->getId() );
$wgOut->addWikiText( wfMsg( 'editingold' ) );
}
}
if( wfReadOnly() ) {
$wgOut->addWikiText( wfMsg( 'readonlywarning' ) );
- } else if ( $isCssJsSubpage and 'preview' != $formtype) {
+ } else if ( $this->isCssJsSubpage and 'preview' != $this->formtype) {
$wgOut->addWikiText( wfMsg( 'usercssjsyoucanpreview' ));
}
if( $this->mTitle->isProtected('edit') ) {
@@ -561,7 +748,7 @@ class EditPage {
'[[' . wfMsgForContent( 'copyrightpage' ) . ']]',
$wgRightsText ) . "\n";
- if( $wgUser->getOption('showtoolbar') and !$isCssJsSubpage ) {
+ if( $wgUser->getOption('showtoolbar') and !$this->isCssJsSubpage ) {
# prepare toolbar for edit buttons
$toolbar = $this->getEditToolbar();
} else {
@@ -591,26 +778,19 @@ class EditPage {
$watchhtml = '';
if ( $wgUser->isLoggedIn() ) {
- $watchhtml = "watchthis?" checked='checked'":"").
- " accesskey='".wfMsg('accesskey-watch')."' id='wpWatchthis' />".
- "";
+ $watchhtml = "watchthis?" checked='checked'":"").
+ " accesskey=\"".htmlspecialchars(wfMsg('accesskey-watch'))."\" id='wpWatchthis' />".
+ "";
}
- $checkboxhtml = $minoredithtml . $watchhtml . '
';
+ $checkboxhtml = $minoredithtml . $watchhtml;
- $wgOut->addHTML( '
" . htmlspecialchars( wfMsg( 'previewnote' ) ) . "
\n"; - if ( $isConflict ) { - $previewhead.='