24 namespace MediaWiki\Specials;
102 parent::__construct(
'MergeHistory',
'mergehistory' );
103 $this->mergeHistoryFactory = $mergeHistoryFactory;
104 $this->linkBatchFactory = $linkBatchFactory;
105 $this->dbProvider = $dbProvider;
106 $this->revisionStore = $revisionStore;
107 $this->commentFormatter = $commentFormatter;
117 private function loadRequestParams() {
119 $this->mAction = $request->getRawVal(
'action' );
120 $this->mTarget = $request->getVal(
'target',
'' );
121 $this->mDest = $request->getVal(
'dest',
'' );
122 $this->mSubmitted = $request->getBool(
'submitted' );
124 $this->mTargetID = intval( $request->getVal(
'targetID' ) );
125 $this->mDestID = intval( $request->getVal(
'destID' ) );
126 $this->mTimestamp = $request->getVal(
'mergepoint' );
127 if ( $this->mTimestamp ===
null || !preg_match(
'/[0-9]{14}/', $this->mTimestamp ) ) {
128 $this->mTimestamp =
'';
130 $this->mComment = $request->getText(
'wpComment' );
132 $this->mMerge = $request->wasPosted()
133 && $this->
getContext()->getCsrfTokenSet()->matchToken( $request->getVal(
'wpEditToken' ) );
136 if ( $this->mSubmitted ) {
140 $this->mTargetObj =
null;
141 $this->mDestObj =
null;
151 $this->loadRequestParams();
157 if ( $this->mTargetID && $this->mDestID && $this->mAction ==
'submit' && $this->mMerge ) {
163 if ( !$this->mSubmitted ) {
164 $this->showMergeForm();
169 if ( !$this->mTargetObj instanceof
Title ) {
171 } elseif ( !$this->mTargetObj->exists() ) {
173 'mergehistory-no-source',
178 if ( !$this->mDestObj instanceof
Title ) {
180 } elseif ( !$this->mDestObj->exists() ) {
182 'mergehistory-no-destination',
187 if ( $this->mTargetObj && $this->mDestObj && $this->mTargetObj->equals( $this->mDestObj ) ) {
191 $this->mStatus = $status;
193 $this->showMergeForm();
195 if ( $this->mStatus->isGood() ) {
196 $this->showHistory();
200 private function showMergeForm() {
202 $out->addWikiMsg(
'mergehistory-header' );
208 'name' =>
'submitted'
218 'name' =>
'mergepoint'
222 'label-message' =>
'mergehistory-from',
229 'label-message' =>
'mergehistory-into',
237 $form->setWrapperLegendMsg(
'mergehistory-box' )
238 ->setSubmitTextMsg(
'mergehistory-go' )
241 ->displayForm( $this->mStatus );
246 private function showHistory() {
247 # List all stored revisions
248 $revisions =
new MergeHistoryPager(
251 $this->linkBatchFactory,
253 $this->revisionStore,
254 $this->commentFormatter,
260 $haveRevisions = $revisions->getNumRows() > 0;
263 $out->addModuleStyles( [
264 'mediawiki.interface.helpers.styles',
268 $action = $titleObj->getLocalURL( [
'action' =>
'submit' ] );
269 # Start the form here
273 'name' =>
'targetID',
274 'default' => $this->mTargetObj->getArticleID()
279 'default' => $this->mDestObj->getArticleID()
292 if ( $haveRevisions ) {
296 'default' => $this->
msg(
'mergehistory-merge', $this->mTargetObj->getPrefixedText(),
297 $this->mDestObj->getPrefixedText() )->parse(),
299 'cssclass' =>
'mw-mergehistory-explanation',
300 'section' =>
'mergehistory-submit'
304 'name' =>
'wpComment',
305 'label-message' =>
'mergehistory-reason',
308 'section' =>
'mergehistory-submit'
312 'default' => $this->
msg(
'mergehistory-submit' ),
313 'section' =>
'mergehistory-submit',
314 'id' =>
'mw-merge-submit',
320 $form->addHiddenField(
'wpEditToken', $form->getCsrfTokenSet()->getToken() )
322 ->setAction( $action )
323 ->suppressDefaultSubmit();
325 if ( $haveRevisions ) {
326 $form->setFooterHtml(
327 '<h2 id="mw-mergehistory">' . $this->
msg(
'mergehistory-list' )->escaped() .
'</h2>' .
328 $revisions->getNavigationBar() .
329 $revisions->getBody() .
330 $revisions->getNavigationBar()
333 $form->setFooterHtml( $this->
msg(
'mergehistory-empty' ) );
336 $form->prepareForm()->displayForm(
false );
338 # Show relevant lines from the merge log:
339 $mergeLogPage =
new LogPage(
'merge' );
340 $out->addHTML(
'<h2>' . $mergeLogPage->getName()->escaped() .
"</h2>\n" );
358 private function merge() {
359 # Get the titles directly from the IDs, in case the target page params
360 # were spoofed. The queries are done based on the IDs, so it's best to
361 # keep it consistent...
364 if ( $targetTitle ===
null || $destTitle ===
null ) {
367 if ( $targetTitle->getArticleID() == $destTitle->getArticleID() ) {
372 $mh = $this->mergeHistoryFactory->newMergeHistory( $targetTitle, $destTitle, $this->mTimestamp );
375 $mergeStatus = $mh->merge( $this->
getAuthority(), $this->mComment );
376 if ( !$mergeStatus->isOK() ) {
378 $this->
getOutput()->addWikiMsg( $mergeStatus->getMessage() );
384 $targetLink = $linkRenderer->makeLink(
388 [
'redirect' =>
'no' ]
392 $append = ( $mergeStatus->getValue() ===
'source-deleted' )
393 ? $this->
msg(
'mergehistory-source-deleted', $targetTitle->getPrefixedText() ) :
'';
395 $this->
getOutput()->addWikiMsg( $this->
msg(
'mergehistory-done' )
396 ->rawParams( $targetLink )
397 ->params( $destTitle->getPrefixedText(), $append )
398 ->numParams( $mh->getMergedRevisionCount() )
413 class_alias( SpecialMergeHistory::class,
'SpecialMergeHistory' );
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
static showLogExtract(&$out, $types=[], $page='', $user='', $param=[])
Show log extract.
Class to simplify the use of log pages.
Parent class for all special pages.
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
getPageTitle( $subpage=false)
Get a self-referential title object.
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
checkReadOnly()
If the wiki is currently in readonly mode, throws a ReadOnlyError.
getContext()
Gets the context this SpecialPage is executed in.
getRequest()
Get the WebRequest being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getOutput()
Get the OutputPage being used for this instance.
getAuthority()
Shortcut to get the Authority executing this instance.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
addHelpLink( $to, $overrideBaseUrl=false)
Adds help link with an icon via page indicators.
Special page allowing users with the appropriate permissions to merge article histories,...
bool $mSubmitted
Was submitted?
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
doesWrites()
Indicates whether this special page may perform database writes.
execute( $par)
Default execute method Checks user permissions.
__construct(MergeHistoryFactory $mergeHistoryFactory, LinkBatchFactory $linkBatchFactory, IConnectionProvider $dbProvider, RevisionStore $revisionStore, CommentFormatter $commentFormatter)
static newFatal( $message,... $parameters)
Factory function for fatal errors.
static newGood( $value=null)
Factory function for good results.
Service for mergehistory actions.