27 use Wikimedia\Timestamp\TimestampException;
77 $firstDestTimestamp = $this->dbw->selectField(
80 [
'rev_page' => $this->dest->getArticleID() ],
83 $this->maxTimestamp =
new MWTimestamp( $firstDestTimestamp );
91 $lastWorkingTimestamp = $this->dbw->selectField(
96 $this->dbw->addQuotes( $this->dbw->timestamp( $mwTimestamp ) ),
97 'rev_page' => $this->
source->getArticleID()
101 $mwLastWorkingTimestamp =
new MWTimestamp( $lastWorkingTimestamp );
103 $timeInsert = $mwLastWorkingTimestamp;
104 $this->timestampLimit = $mwLastWorkingTimestamp;
110 $lastSourceTimestamp = $this->dbw->selectField(
111 [
'page',
'revision' ],
113 [
'page_id' => $this->
source->getArticleID(),
114 'page_latest = rev_id'
118 $lasttimestamp =
new MWTimestamp( $lastSourceTimestamp );
121 $this->timestampLimit = $lasttimestamp;
124 $this->timeWhere =
"rev_timestamp <= " .
125 $this->dbw->addQuotes( $this->dbw->timestamp( $timeInsert ) );
126 }
catch ( TimestampException $ex ) {
129 $this->timestampLimit =
false;
138 $count = $this->dbw->selectRowCount(
'revision',
'1',
141 [
'LIMIT' => self::REVISION_LIMIT + 1 ]
167 $this->
source->getUserPermissionsErrors(
'edit', $user ),
168 $this->dest->getUserPermissionsErrors(
'edit',
$user )
173 foreach ( $errors
as $error ) {
174 call_user_func_array( [
$status,
'fatal' ], $error );
181 $status->fatal(
'spamprotectiontext' );
185 if ( !
$user->isAllowed(
'mergehistory' ) ) {
187 $status->fatal(
'mergehistory-fail-permission' );
204 if ( $this->
source->getArticleID() === 0 ) {
205 $status->fatal(
'mergehistory-fail-invalid-source' );
207 if ( $this->dest->getArticleID() === 0 ) {
208 $status->fatal(
'mergehistory-fail-invalid-dest' );
212 if ( $this->
source->equals( $this->dest ) ) {
213 $status->fatal(
'mergehistory-fail-self-merge' );
217 if ( !$this->timestampLimit ) {
218 $status->fatal(
'mergehistory-fail-bad-timestamp' );
222 if ( $this->timestampLimit > $this->maxTimestamp ) {
223 $status->fatal(
'mergehistory-fail-timestamps-overlap' );
227 if ( $this->timestampLimit && $this->
getRevisionCount() > self::REVISION_LIMIT ) {
228 $status->fatal(
'mergehistory-fail-toobig', Message::numParam( self::REVISION_LIMIT ) );
253 if ( !$validCheck->isOK() ) {
257 if ( !$permCheck->isOK() ) {
263 [
'rev_page' => $this->dest->getArticleID() ],
269 $this->revisionsMerged = $this->dbw->affectedRows();
270 if ( $this->revisionsMerged < 1 ) {
271 $status->fatal(
'mergehistory-fail-no-change' );
276 $haveRevisions = $this->dbw->selectField(
279 [
'rev_page' => $this->
source->getArticleID() ],
283 if ( !$haveRevisions ) {
286 'mergehistory-comment',
287 $this->
source->getPrefixedText(),
288 $this->dest->getPrefixedText(),
290 )->inContentLanguage()->text();
293 'mergehistory-autocomment',
294 $this->
source->getPrefixedText(),
295 $this->dest->getPrefixedText()
296 )->inContentLanguage()->text();
300 $redirectContent = $contentHandler->makeRedirectContent(
302 wfMessage(
'mergehistory-redirect-text' )->inContentLanguage()->
plain()
305 if ( $redirectContent ) {
309 'page' => $this->
source->getArticleID(),
310 'comment' => $reason,
311 'content' => $redirectContent ] );
312 $redirectRevision->
insertOn( $this->dbw );
313 $redirectPage->updateRevisionOn( $this->dbw, $redirectRevision );
319 [
'pl_from' => $this->dest->getArticleID() ],
322 $this->dbw->insert(
'pagelinks',
324 'pl_from' => $this->dest->getArticleID(),
325 'pl_from_namespace' => $this->dest->getNamespace(),
326 'pl_namespace' => $this->dest->getNamespace(),
327 'pl_title' => $this->dest->getDBkey() ],
332 $status->warning(
'mergehistory-warning-redirect-not-created' );
335 $this->
source->invalidateCache();
337 $this->dest->invalidateCache();
341 $logEntry->setPerformer(
$user );
342 $logEntry->setComment( $reason );
343 $logEntry->setTarget( $this->
source );
344 $logEntry->setParameters( [
345 '4::dest' => $this->dest->getPrefixedText(),
346 '5::mergepoint' => $this->timestampLimit->getTimestamp( TS_MW )
348 $logId = $logEntry->insert();
349 $logEntry->publish( $logId );