X-Git-Url: http://git.heureux-cyclage.org/?a=blobdiff_plain;f=includes%2Fspecials%2FSpecialMergeHistory.php;h=f122db8a37d87a90c5a43447798c9b004fee19bc;hb=4187f85473958bd6560d48c8891511e2f9bcf1d4;hp=162ef60d8fd64614d5ae207e5b12c551ac8d90db;hpb=4944ed20d4505172cfbc8c65444fcc39953ce044;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/specials/SpecialMergeHistory.php b/includes/specials/SpecialMergeHistory.php index 162ef60d8f..f122db8a37 100644 --- a/includes/specials/SpecialMergeHistory.php +++ b/includes/specials/SpecialMergeHistory.php @@ -28,14 +28,38 @@ * @ingroup SpecialPage */ class SpecialMergeHistory extends SpecialPage { - /** @var FormOptions */ - protected $mOpts; + /** @var string */ + protected $mAction; - /** @var Status */ - protected $mStatus; + /** @var string */ + protected $mTarget; - /** @var Title|null */ - protected $mTargetObj, $mDestObj; + /** @var string */ + protected $mDest; + + /** @var string */ + protected $mTimestamp; + + /** @var int */ + protected $mTargetID; + + /** @var int */ + protected $mDestID; + + /** @var string */ + protected $mComment; + + /** @var bool Was posted? */ + protected $mMerge; + + /** @var bool Was submitted? */ + protected $mSubmitted; + + /** @var Title */ + protected $mTargetObj; + + /** @var Title */ + protected $mDestObj; /** @var int[] */ public $prevId; @@ -48,107 +72,124 @@ class SpecialMergeHistory extends SpecialPage { return true; } + /** + * @return void + */ + private function loadRequestParams() { + $request = $this->getRequest(); + $this->mAction = $request->getVal( 'action' ); + $this->mTarget = $request->getVal( 'target' ); + $this->mDest = $request->getVal( 'dest' ); + $this->mSubmitted = $request->getBool( 'submitted' ); + + $this->mTargetID = intval( $request->getVal( 'targetID' ) ); + $this->mDestID = intval( $request->getVal( 'destID' ) ); + $this->mTimestamp = $request->getVal( 'mergepoint' ); + if ( !preg_match( '/[0-9]{14}/', $this->mTimestamp ) ) { + $this->mTimestamp = ''; + } + $this->mComment = $request->getText( 'wpComment' ); + + $this->mMerge = $request->wasPosted() + && $this->getUser()->matchEditToken( $request->getVal( 'wpEditToken' ) ); + + // target page + if ( $this->mSubmitted ) { + $this->mTargetObj = Title::newFromText( $this->mTarget ); + $this->mDestObj = Title::newFromText( $this->mDest ); + } else { + $this->mTargetObj = null; + $this->mDestObj = null; + } + } + public function execute( $par ) { $this->useTransactionalTimeLimit(); $this->checkPermissions(); $this->checkReadOnly(); + $this->loadRequestParams(); + $this->setHeaders(); $this->outputHeader(); - $this->addHelpLink( 'Help:Merge history' ); - - $opts = new FormOptions(); - - $opts->add( 'target', '' ); - $opts->add( 'dest', '' ); - $opts->add( 'target', '' ); - $opts->add( 'mergepoint', '' ); - $opts->add( 'reason', '' ); - $opts->add( 'merge', false ); - - $opts->fetchValuesFromRequest( $this->getRequest() ); - - $target = $opts->getValue( 'target' ); - $dest = $opts->getValue( 'dest' ); - $targetObj = Title::newFromText( $target ); - $destObj = Title::newFromText( $dest ); - $status = Status::newGood(); - - $this->mOpts = $opts; - $this->mTargetObj = $targetObj; - $this->mDestObj = $destObj; - - if ( $opts->getValue( 'merge' ) && $targetObj && - $destObj && $opts->getValue( 'mergepoint' ) !== '' ) { + if ( $this->mTargetID && $this->mDestID && $this->mAction == 'submit' && $this->mMerge ) { $this->merge(); return; } - if ( $target === '' && $dest === '' ) { + if ( !$this->mSubmitted ) { $this->showMergeForm(); return; } - if ( !$targetObj instanceof Title ) { - $status->merge( Status::newFatal( 'mergehistory-invalid-source' ) ); - } elseif ( !$targetObj->exists() ) { - $status->merge( Status::newFatal( 'mergehistory-no-source', - wfEscapeWikiText( $targetObj->getPrefixedText() ) - ) ); + $errors = []; + if ( !$this->mTargetObj instanceof Title ) { + $errors[] = $this->msg( 'mergehistory-invalid-source' )->parseAsBlock(); + } elseif ( !$this->mTargetObj->exists() ) { + $errors[] = $this->msg( 'mergehistory-no-source', + wfEscapeWikiText( $this->mTargetObj->getPrefixedText() ) + )->parseAsBlock(); } - if ( !$destObj instanceof Title ) { - $status->merge( Status::newFatal( 'mergehistory-invalid-destination' ) ); - } elseif ( !$destObj->exists() ) { - $status->merge( Status::newFatal( 'mergehistory-no-destination', - wfEscapeWikiText( $destObj->getPrefixedText() ) - ) ); + if ( !$this->mDestObj instanceof Title ) { + $errors[] = $this->msg( 'mergehistory-invalid-destination' )->parseAsBlock(); + } elseif ( !$this->mDestObj->exists() ) { + $errors[] = $this->msg( 'mergehistory-no-destination', + wfEscapeWikiText( $this->mDestObj->getPrefixedText() ) + )->parseAsBlock(); } - if ( $targetObj && $destObj && $targetObj->equals( $destObj ) ) { - $status->merge( Status::newFatal( 'mergehistory-same-destination' ) ); + if ( $this->mTargetObj && $this->mDestObj && $this->mTargetObj->equals( $this->mDestObj ) ) { + $errors[] = $this->msg( 'mergehistory-same-destination' )->parseAsBlock(); } - $this->mStatus = $status; - - $this->showMergeForm(); - - if ( $status->isOK() ) { + if ( count( $errors ) ) { + $this->showMergeForm(); + $this->getOutput()->addHTML( implode( "\n", $errors ) ); + } else { $this->showHistory(); } } function showMergeForm() { - $formDescriptor = [ - 'target' => [ - 'type' => 'title', - 'name' => 'target', - 'label-message' => 'mergehistory-from', - 'required' => true, - ], - - 'dest' => [ - 'type' => 'title', - 'name' => 'dest', - 'label-message' => 'mergehistory-into', - 'required' => true, - ], - ]; - - $form = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ) - ->setIntro( $this->msg( 'mergehistory-header' ) ) - ->setWrapperLegendMsg( 'mergehistory-box' ) - ->setSubmitTextMsg( 'mergehistory-go' ) - ->setMethod( 'post' ) - ->prepareForm() - ->displayForm( $this->mStatus ); + $out = $this->getOutput(); + $out->addWikiMsg( 'mergehistory-header' ); + + $out->addHTML( + Xml::openElement( 'form', [ + 'method' => 'get', + 'action' => wfScript() ] ) . + '
' . + Xml::element( 'legend', [], + $this->msg( 'mergehistory-box' )->text() ) . + Html::hidden( 'title', $this->getPageTitle()->getPrefixedDBkey() ) . + Html::hidden( 'submitted', '1' ) . + Html::hidden( 'mergepoint', $this->mTimestamp ) . + Xml::openElement( 'table' ) . + ' + ' . Xml::label( $this->msg( 'mergehistory-from' )->text(), 'target' ) . ' + ' . Xml::input( 'target', 30, $this->mTarget, [ 'id' => 'target' ] ) . ' + + ' . Xml::label( $this->msg( 'mergehistory-into' )->text(), 'dest' ) . ' + ' . Xml::input( 'dest', 30, $this->mDest, [ 'id' => 'dest' ] ) . ' + ' . + Xml::submitButton( $this->msg( 'mergehistory-go' )->text() ) . + '' . + Xml::closeElement( 'table' ) . + '
' . + '' + ); + + $this->addHelpLink( 'Help:Merge history' ); } private function showHistory() { + $this->showMergeForm(); + # List all stored revisions $revisions = new MergeHistoryPager( $this, [], $this->mTargetObj, $this->mDestObj @@ -156,46 +197,62 @@ class SpecialMergeHistory extends SpecialPage { $haveRevisions = $revisions && $revisions->getNumRows() > 0; $out = $this->getOutput(); - $header = '

' . - $this->msg( 'mergehistory-list' )->escaped() . "

\n"; + $titleObj = $this->getPageTitle(); + $action = $titleObj->getLocalURL( [ 'action' => 'submit' ] ); + # Start the form here + $top = Xml::openElement( + 'form', + [ + 'method' => 'post', + 'action' => $action, + 'id' => 'merge' + ] + ); + $out->addHTML( $top ); if ( $haveRevisions ) { - $hiddenFields = [ - 'merge' => true, - 'target' => $this->mOpts->getValue( 'target' ), - 'dest' => $this->mOpts->getValue( 'dest' ), - ]; - - $formDescriptor = [ - 'reason' => [ - 'type' => 'text', - 'name' => 'reason', - 'label-message' => 'mergehistory-reason', - ], - ]; - - $mergeText = $this->msg( 'mergehistory-merge', - $this->mTargetObj->getPrefixedText(), - $this->mDestObj->getPrefixedText() - )->parse(); - - $history = $header . - $revisions->getNavigationBar() . - '' . - $revisions->getNavigationBar(); - - $form = HTMLForm::factory( 'ooui', $formDescriptor, $this->getContext() ) - ->addHiddenFields( $hiddenFields ) - ->setPreText( $mergeText ) - ->setFooterText( $history ) - ->setSubmitTextMsg( 'mergehistory-submit' ) - ->setMethod( 'post' ) - ->prepareForm() - ->displayForm( false ); + # Format the user-visible controls (comment field, submission button) + # in a nice little table + $table = + Xml::openElement( 'fieldset' ) . + $this->msg( 'mergehistory-merge', $this->mTargetObj->getPrefixedText(), + $this->mDestObj->getPrefixedText() )->parse() . + Xml::openElement( 'table', [ 'id' => 'mw-mergehistory-table' ] ) . + ' + ' . + Xml::label( $this->msg( 'mergehistory-reason' )->text(), 'wpComment' ) . + ' + ' . + Xml::input( 'wpComment', 50, $this->mComment, [ 'id' => 'wpComment' ] ) . + ' + + +   + ' . + Xml::submitButton( + $this->msg( 'mergehistory-submit' )->text(), + [ 'name' => 'merge', 'id' => 'mw-merge-submit' ] + ) . + ' + ' . + Xml::closeElement( 'table' ) . + Xml::closeElement( 'fieldset' ); + + $out->addHTML( $table ); + } + + $out->addHTML( + '

' . + $this->msg( 'mergehistory-list' )->escaped() . "

\n" + ); + + if ( $haveRevisions ) { + $out->addHTML( $revisions->getNavigationBar() ); + $out->addHTML( '' ); + $out->addHTML( $revisions->getNavigationBar() ); } else { - $out->addHTML( $header ); $out->addWikiMsg( 'mergehistory-empty' ); } @@ -203,22 +260,36 @@ class SpecialMergeHistory extends SpecialPage { $mergeLogPage = new LogPage( 'merge' ); $out->addHTML( '

' . $mergeLogPage->getName()->escaped() . "

\n" ); LogEventsList::showLogExtract( $out, 'merge', $this->mTargetObj ); + + # When we submit, go by page ID to avoid some nasty but unlikely collisions. + # Such would happen if a page was renamed after the form loaded, but before submit + $misc = Html::hidden( 'targetID', $this->mTargetObj->getArticleID() ); + $misc .= Html::hidden( 'destID', $this->mDestObj->getArticleID() ); + $misc .= Html::hidden( 'target', $this->mTarget ); + $misc .= Html::hidden( 'dest', $this->mDest ); + $misc .= Html::hidden( 'wpEditToken', $this->getUser()->getEditToken() ); + $misc .= Xml::closeElement( 'form' ); + $out->addHTML( $misc ); + + return true; } function formatRevisionRow( $row ) { $rev = new Revision( $row ); + $linkRenderer = $this->getLinkRenderer(); + $stxt = ''; $last = $this->msg( 'last' )->escaped(); $ts = wfTimestamp( TS_MW, $row->rev_timestamp ); - $checkBox = Xml::radio( 'mergepoint', $ts, ( $this->mOpts->getValue( 'mergepoint' ) === $ts ) ); + $checkBox = Xml::radio( 'mergepoint', $ts, ( $this->mTimestamp === $ts ) ); $user = $this->getUser(); - $pageLink = Linker::linkKnown( + $pageLink = $linkRenderer->makeKnownLink( $rev->getTitle(), - htmlspecialchars( $this->getLanguage()->userTimeAndDate( $ts, $user ) ), + $this->getLanguage()->userTimeAndDate( $ts, $user ), [], [ 'oldid' => $rev->getId() ] ); @@ -230,9 +301,9 @@ class SpecialMergeHistory extends SpecialPage { if ( !$rev->userCan( Revision::DELETED_TEXT, $user ) ) { $last = $this->msg( 'last' )->escaped(); } elseif ( isset( $this->prevId[$row->rev_id] ) ) { - $last = Linker::linkKnown( + $last = $linkRenderer->makeKnownLink( $rev->getTitle(), - $this->msg( 'last' )->escaped(), + $this->msg( 'last' )->text(), [], [ 'diff' => $row->rev_id, @@ -267,32 +338,33 @@ class SpecialMergeHistory extends SpecialPage { * @return bool Success */ function merge() { - $opts = $this->mOpts; - # Get the titles directly from the IDs, in case the target page params # were spoofed. The queries are done based on the IDs, so it's best to # keep it consistent... - $targetObj = $this->mTargetObj; - $destObj = $this->mDestObj; - - if ( is_null( $targetObj ) || is_null( $destObj ) || - $targetObj->getArticleID() == $destObj->getArticleID() ) { + $targetTitle = Title::newFromID( $this->mTargetID ); + $destTitle = Title::newFromID( $this->mDestID ); + if ( is_null( $targetTitle ) || is_null( $destTitle ) ) { + return false; // validate these + } + if ( $targetTitle->getArticleID() == $destTitle->getArticleID() ) { return false; } // MergeHistory object - $mh = new MergeHistory( $targetObj, $destObj, $opts->getValue( 'mergepoint' ) ); + $mh = new MergeHistory( $targetTitle, $destTitle, $this->mTimestamp ); // Merge! - $mergeStatus = $mh->merge( $this->getUser(), $opts->getValue( 'reason' ) ); + $mergeStatus = $mh->merge( $this->getUser(), $this->mComment ); if ( !$mergeStatus->isOK() ) { // Failed merge $this->getOutput()->addWikiMsg( $mergeStatus->getMessage() ); return false; } - $targetLink = Linker::link( - $targetObj, + $linkRenderer = $this->getLinkRenderer(); + + $targetLink = $linkRenderer->makeLink( + $targetTitle, null, [], [ 'redirect' => 'no' ] @@ -300,7 +372,7 @@ class SpecialMergeHistory extends SpecialPage { $this->getOutput()->addWikiMsg( $this->msg( 'mergehistory-done' ) ->rawParams( $targetLink ) - ->params( $destObj->getPrefixedText() ) + ->params( $destTitle->getPrefixedText() ) ->numParams( $mh->getMergedRevisionCount() ) );