Index: trunk/phase3/includes/revisiondelete/RevisionDelete.php |
— | — | @@ -1,6 +1,12 @@ |
2 | 2 | <?php |
3 | 3 | /** |
4 | 4 | * List for revision table items |
| 5 | + * |
| 6 | + * This will check both the 'revision' table for live revisions and the |
| 7 | + * 'archive' table for traditionally-deleted revisions that have an |
| 8 | + * ar_rev_id saved. |
| 9 | + * |
| 10 | + * See RevDel_RevisionItem and RevDel_ArchivedRevisionItem for items. |
5 | 11 | */ |
6 | 12 | class RevDel_RevisionList extends RevDel_List { |
7 | 13 | var $currentRevId; |
— | — | @@ -16,7 +22,7 @@ |
17 | 23 | */ |
18 | 24 | public function doQuery( $db ) { |
19 | 25 | $ids = array_map( 'intval', $this->ids ); |
20 | | - return $db->select( array('revision','page'), '*', |
| 26 | + $live = $db->select( array('revision','page'), '*', |
21 | 27 | array( |
22 | 28 | 'rev_page' => $this->title->getArticleID(), |
23 | 29 | 'rev_id' => $ids, |
— | — | @@ -25,10 +31,49 @@ |
26 | 32 | __METHOD__, |
27 | 33 | array( 'ORDER BY' => 'rev_id DESC' ) |
28 | 34 | ); |
| 35 | + |
| 36 | + if ( $live->numRows() >= count( $ids ) ) { |
| 37 | + // All requested revisions are live, keeps things simple! |
| 38 | + return $live; |
| 39 | + } |
| 40 | + |
| 41 | + // Check if any requested revisions are available fully deleted. |
| 42 | + $archived = $db->select( array( 'archive' ), '*', |
| 43 | + array( |
| 44 | + 'ar_rev_id' => $ids |
| 45 | + ), |
| 46 | + __METHOD__, |
| 47 | + array( 'ORDER BY' => 'ar_rev_id DESC' ) |
| 48 | + ); |
| 49 | + |
| 50 | + if ( $archived->numRows() == 0 ) { |
| 51 | + return $live; |
| 52 | + } else if ( $live->numRows() == 0 ) { |
| 53 | + return $archived; |
| 54 | + } else { |
| 55 | + // Combine the two! Whee |
| 56 | + $rows = array(); |
| 57 | + while ( $row = $live->fetchObject() ) { |
| 58 | + $rows[$row->rev_id] = $row; |
| 59 | + } |
| 60 | + while ( $row = $archived->fetchObject() ) { |
| 61 | + $rows[$row->ar_rev_id] = $row; |
| 62 | + } |
| 63 | + krsort( $rows ); |
| 64 | + return new FakeResultWrapper( array_values( $rows ) ); |
| 65 | + } |
29 | 66 | } |
30 | 67 | |
31 | 68 | public function newItem( $row ) { |
32 | | - return new RevDel_RevisionItem( $this, $row ); |
| 69 | + if ( isset( $row->rev_id ) ) { |
| 70 | + return new RevDel_RevisionItem( $this, $row ); |
| 71 | + } elseif ( isset( $row->ar_rev_id ) ) { |
| 72 | + return new RevDel_ArchivedRevisionItem( $this, $row ); |
| 73 | + } else { |
| 74 | + // This shouldn't happen. :) |
| 75 | + var_dump( $row ); |
| 76 | + throw new MWException( 'Invalid row type in RevDel_RevisionList' ); |
| 77 | + } |
33 | 78 | } |
34 | 79 | |
35 | 80 | public function getCurrent() { |
— | — | @@ -58,7 +103,7 @@ |
59 | 104 | } |
60 | 105 | |
61 | 106 | /** |
62 | | - * Item class for a revision table row |
| 107 | + * Item class for a live revision table row |
63 | 108 | */ |
64 | 109 | class RevDel_RevisionItem extends RevDel_Item { |
65 | 110 | var $revision; |
— | — | @@ -281,7 +326,36 @@ |
282 | 327 | } |
283 | 328 | } |
284 | 329 | |
| 330 | + |
285 | 331 | /** |
| 332 | + * Item class for a archive table row by ar_rev_id -- actually |
| 333 | + * used via RevDel_RevisionList. |
| 334 | + */ |
| 335 | +class RevDel_ArchivedRevisionItem extends RevDel_ArchiveItem { |
| 336 | + public function __construct( $list, $row ) { |
| 337 | + RevDel_Item::__construct( $list, $row ); |
| 338 | + |
| 339 | + $this->revision = Revision::newFromArchiveRow( $row, |
| 340 | + array( 'page' => $this->list->title->getArticleId() ) ); |
| 341 | + } |
| 342 | + |
| 343 | + public function getId() { |
| 344 | + return $this->revision->getId(); |
| 345 | + } |
| 346 | + |
| 347 | + public function setBits( $bits ) { |
| 348 | + $dbw = wfGetDB( DB_MASTER ); |
| 349 | + $dbw->update( 'archive', |
| 350 | + array( 'ar_deleted' => $bits ), |
| 351 | + array( 'ar_rev_id' => $this->row->ar_rev_id, |
| 352 | + 'ar_deleted' => $this->getBits() |
| 353 | + ), |
| 354 | + __METHOD__ ); |
| 355 | + return (bool)$dbw->affectedRows(); |
| 356 | + } |
| 357 | +} |
| 358 | + |
| 359 | +/** |
286 | 360 | * List for oldimage table items |
287 | 361 | */ |
288 | 362 | class RevDel_FileList extends RevDel_List { |
Index: trunk/phase3/includes/revisiondelete/RevisionDeleter.php |
— | — | @@ -178,24 +178,7 @@ |
179 | 179 | // This is not going to work if some revs are deleted and some |
180 | 180 | // aren't. |
181 | 181 | if ($key == 'revision') { |
182 | | - foreach( $Ids as $k => $id ) { |
183 | | - $existResult = |
184 | | - self::checkRevisionExistence( $title, $id ); |
185 | | - |
186 | | - if ($existResult !== true) { |
187 | | - $key = 'archive'; |
188 | | - $Ids[$k] = $existResult; |
189 | | - } else { |
190 | | - // Undeleted revision amidst deleted ones |
191 | | - unset($Ids[$k]); |
192 | | - $undeletedRevisions[] = $id; |
193 | | - } |
194 | | - } |
195 | | - |
196 | | - if ( $key == $originalKey ) { |
197 | | - $Ids = $undeletedRevisions; |
198 | | - $undeletedRevisions = array(); |
199 | | - } |
| 182 | + // Nothing to do; deleted revisions can still be looked up by ID. |
200 | 183 | } |
201 | 184 | |
202 | 185 | // Diff link for single rev deletions |
Index: trunk/phase3/includes/revisiondelete/RevisionDeleteAbstracts.php |
— | — | @@ -1,7 +1,10 @@ |
2 | 2 | <?php |
3 | 3 | |
4 | 4 | /** |
5 | | - * Abstract base class for a list of deletable items |
| 5 | + * Abstract base class for a list of deletable items. The list class |
| 6 | + * needs to be able to make a query from a set of identifiers to pull |
| 7 | + * relevant rows, to return RevDel_Item subclasses wrapping them, and |
| 8 | + * to wrap bulk update operations. |
6 | 9 | */ |
7 | 10 | abstract class RevDel_List { |
8 | 11 | |