Index: trunk/phase3/includes/SpecialMergeHistory.php |
— | — | @@ -290,14 +290,14 @@ |
291 | 291 | $destTitle = Title::newFromID( $this->mDestID ); |
292 | 292 | if( is_null($targetTitle) || is_null($destTitle) ) |
293 | 293 | return false; // validate these |
294 | | - if( $targetTitle->getArticleID() == $destTitle->getArticleId() ) |
| 294 | + if( $targetTitle->getArticleId() == $destTitle->getArticleId() ) |
295 | 295 | return false; |
296 | 296 | # Verify that this timestamp is valid |
297 | 297 | # Must be older than the destination page |
298 | 298 | $dbw = wfGetDB( DB_MASTER ); |
299 | 299 | # Get timestamp into DB format |
300 | 300 | $this->mTimestamp = $this->mTimestamp ? $dbw->timestamp($this->mTimestamp) : ''; |
301 | | - |
| 301 | + # Max timestamp should be min of destination page |
302 | 302 | $maxtimestamp = $dbw->selectField( 'revision', 'MIN(rev_timestamp)', |
303 | 303 | array('rev_page' => $this->mDestID ), |
304 | 304 | __METHOD__ ); |
— | — | @@ -306,14 +306,12 @@ |
307 | 307 | $wgOut->addWikiMsg('mergehistory-fail'); |
308 | 308 | return false; |
309 | 309 | } |
310 | | - # Leave the latest version no matter what |
311 | | - $lasttime = $dbw->selectField( array('page','revision'), |
| 310 | + # Get the latest timestamp of the source |
| 311 | + $lasttimestamp = $dbw->selectField( array('page','revision'), |
312 | 312 | 'rev_timestamp', |
313 | 313 | array('page_id' => $this->mTargetID, 'page_latest = rev_id' ), |
314 | 314 | __METHOD__ ); |
315 | | - # Take the most restrictive of the twain |
316 | | - $maxtimestamp = ($lasttime < $maxtimestamp) ? $lasttime : $maxtimestamp; |
317 | | - // $this->mTimestamp must be less than $maxtimestamp |
| 315 | + # $this->mTimestamp must be older than $maxtimestamp |
318 | 316 | if( $this->mTimestamp >= $maxtimestamp ) { |
319 | 317 | $wgOut->addWikiMsg('mergehistory-fail'); |
320 | 318 | return false; |
— | — | @@ -323,17 +321,56 @@ |
324 | 322 | $timewhere = "rev_timestamp <= {$this->mTimestamp}"; |
325 | 323 | $TimestampLimit = wfTimestamp(TS_MW,$this->mTimestamp); |
326 | 324 | } else { |
327 | | - $timewhere = "rev_timestamp < {$maxtimestamp}"; |
328 | | - $TimestampLimit = wfTimestamp(TS_MW,$maxtimestamp); |
| 325 | + $timewhere = "rev_timestamp <= {$maxtimestamp}"; |
| 326 | + $TimestampLimit = wfTimestamp(TS_MW,$lasttimestamp); |
329 | 327 | } |
330 | | - |
| 328 | + # Do the moving... |
331 | 329 | $dbw->update( 'revision', |
332 | 330 | array( 'rev_page' => $this->mDestID ), |
333 | 331 | array( 'rev_page' => $this->mTargetID, |
334 | 332 | $timewhere ), |
335 | 333 | __METHOD__ ); |
| 334 | + |
| 335 | + $count = $dbw->affectedRows(); |
| 336 | + # Make the source page a redirect if no revisions are left |
| 337 | + $haveRevisions = $dbw->selectField( 'revision', |
| 338 | + 'rev_timestamp', |
| 339 | + array( 'rev_page' => $this->mTargetID ), |
| 340 | + __METHOD__, |
| 341 | + array( 'FOR UPDATE' ) ); |
| 342 | + if( !$haveRevisions ) { |
| 343 | + if( $this->mComment ) { |
| 344 | + $comment = wfMsgForContent( 'mergehistory-comment', $targetTitle->getPrefixedText(), |
| 345 | + $destTitle->getPrefixedText(), $this->mComment ); |
| 346 | + } else { |
| 347 | + $comment = wfMsgForContent( 'mergehistory-autocomment', $targetTitle->getPrefixedText(), |
| 348 | + $destTitle->getPrefixedText() ); |
| 349 | + } |
| 350 | + $mwRedir = MagicWord::get( 'redirect' ); |
| 351 | + $redirectText = $mwRedir->getSynonym( 0 ) . ' [[' . $destTitle->getPrefixedText() . "]]\n"; |
| 352 | + $redirectArticle = new Article( $targetTitle ); |
| 353 | + $redirectRevision = new Revision( array( |
| 354 | + 'page' => $this->mTargetID, |
| 355 | + 'comment' => $comment, |
| 356 | + 'text' => $redirectText ) ); |
| 357 | + $redirectRevision->insertOn( $dbw ); |
| 358 | + $redirectArticle->updateRevisionOn( $dbw, $redirectRevision ); |
| 359 | + |
| 360 | + # Now, we record the link from the redirect to the new title. |
| 361 | + # It should have no other outgoing links... |
| 362 | + $dbw->delete( 'pagelinks', array( 'pl_from' => $this->mDestID ), __METHOD__ ); |
| 363 | + $dbw->insert( 'pagelinks', |
| 364 | + array( |
| 365 | + 'pl_from' => $this->mDestID, |
| 366 | + 'pl_namespace' => $destTitle->getNamespace(), |
| 367 | + 'pl_title' => $destTitle->getDBkey() ), |
| 368 | + __METHOD__ ); |
| 369 | + } else { |
| 370 | + $targetTitle->invalidateCache(); // update histories |
| 371 | + } |
| 372 | + $destTitle->invalidateCache(); // update histories |
336 | 373 | # Check if this did anything |
337 | | - if( !$count = $dbw->affectedRows() ) { |
| 374 | + if( !$count ) { |
338 | 375 | $wgOut->addWikiMsg('mergehistory-fail'); |
339 | 376 | return false; |
340 | 377 | } |
— | — | @@ -354,15 +391,15 @@ |
355 | 392 | class MergeHistoryPager extends ReverseChronologicalPager { |
356 | 393 | public $mForm, $mConds; |
357 | 394 | |
358 | | - function __construct( $form, $conds = array(), $title, $title2 ) { |
| 395 | + function __construct( $form, $conds = array(), $source, $dest ) { |
359 | 396 | $this->mForm = $form; |
360 | 397 | $this->mConds = $conds; |
361 | | - $this->title = $title; |
362 | | - $this->articleID = $title->getArticleID(); |
| 398 | + $this->title = $source; |
| 399 | + $this->articleID = $source->getArticleID(); |
363 | 400 | |
364 | 401 | $dbr = wfGetDB( DB_SLAVE ); |
365 | 402 | $maxtimestamp = $dbr->selectField( 'revision', 'MIN(rev_timestamp)', |
366 | | - array('rev_page' => $title2->getArticleID() ), |
| 403 | + array('rev_page' => $dest->getArticleID() ), |
367 | 404 | __METHOD__ ); |
368 | 405 | $this->maxTimestamp = $maxtimestamp; |
369 | 406 | |
— | — | @@ -405,9 +442,6 @@ |
406 | 443 | $conds = $this->mConds; |
407 | 444 | $conds['rev_page'] = $this->articleID; |
408 | 445 | $conds[] = "rev_timestamp < {$this->maxTimestamp}"; |
409 | | - # Skip the latest one, as that could cause problems |
410 | | - if( $page = $this->title->getLatestRevID() ) |
411 | | - $conds[] = "rev_id != {$page}"; |
412 | 446 | |
413 | 447 | return array( |
414 | 448 | 'tables' => array('revision'), |
Index: trunk/phase3/languages/messages/MessagesEn.php |
— | — | @@ -1184,9 +1184,7 @@ |
1185 | 1185 | # History merging |
1186 | 1186 | 'mergehistory' => 'Merge page histories', |
1187 | 1187 | 'mergehistory-header' => "This page lets you merge revisions of the history of one source page into a newer page. |
1188 | | -Make sure that this change will maintain historical page continuity. |
1189 | | - |
1190 | | -'''At least the current revision of the source page must remain.'''", |
| 1188 | +Make sure that this change will maintain historical page continuity.", |
1191 | 1189 | 'mergehistory-box' => 'Merge revisions of two pages:', |
1192 | 1190 | 'mergehistory-from' => 'Source page:', |
1193 | 1191 | 'mergehistory-into' => 'Destination page:', |
— | — | @@ -1195,12 +1193,14 @@ |
1196 | 1194 | 'mergehistory-go' => 'Show mergeable edits', |
1197 | 1195 | 'mergehistory-submit' => 'Merge revisions', |
1198 | 1196 | 'mergehistory-empty' => 'No revisions can be merged', |
1199 | | -'mergehistory-success' => '$3 revisions of [[:$1]] successfully merged into [[:$2]].', |
| 1197 | +'mergehistory-success' => '$3 {{PLURAL:$3|revision|revisions}} of [[:$1]] successfully merged into [[:$2]].', |
1200 | 1198 | 'mergehistory-fail' => 'Unable to perform history merge, please recheck the page and time parameters.', |
1201 | 1199 | 'mergehistory-no-source' => 'Source page $1 does not exist.', |
1202 | 1200 | 'mergehistory-no-destination' => 'Destination page $1 does not exist.', |
1203 | 1201 | 'mergehistory-invalid-source' => 'Source page must be a valid title.', |
1204 | 1202 | 'mergehistory-invalid-destination' => 'Destination page must be a valid title.', |
| 1203 | +'mergehistory-autocomment' => 'Merged [[:$1]] into [[:$2]]', |
| 1204 | +'mergehistory-comment' => 'Merged [[:$1]] into [[:$2]]: $3', |
1205 | 1205 | |
1206 | 1206 | # Merge log |
1207 | 1207 | 'mergelog' => 'Merge log', |