107 if ( $loadBalancer ===
null ) {
109 ' was deprecated in MediaWiki 1.35',
'1.35' );
110 $services = MediaWikiServices::getInstance();
112 $loadBalancer = $services->getDBLoadBalancer();
125 $this->dbw = $loadBalancer->getConnection(
DB_MASTER );
134 $firstDestTimestamp = $this->dbw->selectField(
136 'MIN(rev_timestamp)',
137 [
'rev_page' => $this->dest->getArticleID() ],
140 $this->maxTimestamp =
new MWTimestamp( $firstDestTimestamp );
148 $lastWorkingTimestamp = $this->dbw->selectField(
150 'MAX(rev_timestamp)',
152 'rev_timestamp <= ' .
153 $this->dbw->addQuotes( $this->dbw->timestamp( $mwTimestamp ) ),
154 'rev_page' => $this->source->getArticleID()
158 $mwLastWorkingTimestamp =
new MWTimestamp( $lastWorkingTimestamp );
160 $timeInsert = $mwLastWorkingTimestamp;
161 $this->timestampLimit = $mwLastWorkingTimestamp;
167 $lastSourceTimestamp = $this->dbw->selectField(
168 [
'page',
'revision' ],
170 [
'page_id' => $this->source->getArticleID(),
171 'page_latest = rev_id'
175 $lasttimestamp =
new MWTimestamp( $lastSourceTimestamp );
177 $timeInsert = $this->maxTimestamp;
178 $this->timestampLimit = $lasttimestamp;
181 $this->timeWhere =
"rev_timestamp <= " .
182 $this->dbw->addQuotes( $this->dbw->timestamp( $timeInsert ) );
183 }
catch ( TimestampException $ex ) {
186 $this->timestampLimit =
false;
310 if ( !$validCheck->isOK() ) {
314 if ( !$permCheck->isOK() ) {
318 $this->dbw->startAtomic( __METHOD__ );
322 [
'rev_page' => $this->dest->getArticleID() ],
323 [
'rev_page' => $this->source->getArticleID(), $this->timeWhere ],
328 $this->revisionsMerged = $this->dbw->affectedRows();
329 if ( $this->revisionsMerged < 1 ) {
330 $this->dbw->endAtomic( __METHOD__ );
331 $status->fatal(
'mergehistory-fail-no-change' );
338 'revision_actor_temp',
339 [
'revactor_page' => $this->dest->getArticleID() ],
341 'revactor_page' => $this->source->getArticleID(),
343 str_replace(
'rev_timestamp',
'revactor_timestamp', $this->timeWhere )
349 $haveRevisions = $this->dbw->lockForUpdate(
351 [
'rev_page' => $this->source->getArticleID() ],
355 if ( !$haveRevisions ) {
358 'mergehistory-comment',
359 $this->source->getPrefixedText(),
360 $this->dest->getPrefixedText(),
362 )->inContentLanguage()->text();
365 'mergehistory-autocomment',
366 $this->source->getPrefixedText(),
367 $this->dest->getPrefixedText()
368 )->inContentLanguage()->text();
371 $redirectContent = $this->contentHandlerFactory
372 ->getContentHandler( $this->source->getContentModel() )
373 ->makeRedirectContent(
375 wfMessage(
'mergehistory-redirect-text' )->inContentLanguage()->plain()
378 if ( $redirectContent ) {
379 $redirectComment = CommentStoreComment::newUnsavedComment( $reason );
382 $redirectRevRecord->setContent( SlotRecord::MAIN, $redirectContent );
383 $redirectRevRecord->setPageId( $this->source->getArticleID() );
384 $redirectRevRecord->setComment( $redirectComment );
385 $redirectRevRecord->setUser( $user );
388 $insertedRevRecord = $this->revisionStore->insertRevisionOn(
393 $redirectPage = WikiPage::factory( $this->source );
394 $redirectPage->updateRevisionOn( $this->dbw, $insertedRevRecord );
400 [
'pl_from' => $this->dest->getArticleID() ],
403 $this->dbw->insert(
'pagelinks',
405 'pl_from' => $this->dest->getArticleID(),
406 'pl_from_namespace' => $this->dest->getNamespace(),
407 'pl_namespace' => $this->dest->getNamespace(),
408 'pl_title' => $this->dest->getDBkey() ],
413 $status->warning(
'mergehistory-warning-redirect-not-created' );
416 $this->source->invalidateCache();
418 $this->dest->invalidateCache();
421 $this->watchedItemStore->duplicateAllAssociatedEntries( $this->source, $this->dest );
425 $logEntry->setPerformer( $user );
426 $logEntry->setComment( $reason );
427 $logEntry->setTarget( $this->source );
428 $logEntry->setParameters( [
429 '4::dest' => $this->dest->getPrefixedText(),
430 '5::mergepoint' => $this->timestampLimit->getTimestamp( TS_MW )
432 $logId = $logEntry->insert();
433 $logEntry->publish( $logId );
435 Hooks::runner()->onArticleMergeComplete( $this->source, $this->dest );
437 $this->dbw->endAtomic( __METHOD__ );