Index: trunk/phase3/includes/revisiondelete/RevisionDelete.php |
— | — | @@ -10,12 +10,15 @@ |
11 | 11 | */ |
12 | 12 | class RevDel_RevisionList extends RevDel_List { |
13 | 13 | var $currentRevId; |
14 | | - var $type = 'revision'; |
15 | | - var $idField = 'rev_id'; |
16 | | - var $dateField = 'rev_timestamp'; |
17 | | - var $authorIdField = 'rev_user'; |
18 | | - var $authorNameField = 'rev_user_text'; |
19 | 14 | |
| 15 | + public function getType() { |
| 16 | + return 'revision'; |
| 17 | + } |
| 18 | + |
| 19 | + public static function getRelationType() { |
| 20 | + return 'rev_id'; |
| 21 | + } |
| 22 | + |
20 | 23 | /** |
21 | 24 | * @param $db DatabaseBase |
22 | 25 | * @return mixed |
— | — | @@ -112,6 +115,22 @@ |
113 | 116 | $this->revision = new Revision( $row ); |
114 | 117 | } |
115 | 118 | |
| 119 | + public function getIdField() { |
| 120 | + return 'rev_id'; |
| 121 | + } |
| 122 | + |
| 123 | + public function getTimestampField() { |
| 124 | + return 'rev_timestamp'; |
| 125 | + } |
| 126 | + |
| 127 | + public function getAuthorIdField() { |
| 128 | + return 'rev_user'; |
| 129 | + } |
| 130 | + |
| 131 | + public function getAuthorNameField() { |
| 132 | + return 'rev_user_text'; |
| 133 | + } |
| 134 | + |
116 | 135 | public function canView() { |
117 | 136 | return $this->revision->userCan( Revision::DELETED_RESTRICTED ); |
118 | 137 | } |
— | — | @@ -170,7 +189,7 @@ |
171 | 190 | * Overridden by RevDel_ArchiveItem. |
172 | 191 | */ |
173 | 192 | protected function getRevisionLink() { |
174 | | - $date = $this->getLang()->timeanddate( $this->revision->getTimestamp(), true ); |
| 193 | + $date = $this->list->getLang()->timeanddate( $this->revision->getTimestamp(), true ); |
175 | 194 | if ( $this->isDeleted() && !$this->canViewContent() ) { |
176 | 195 | return $date; |
177 | 196 | } |
— | — | @@ -227,12 +246,14 @@ |
228 | 247 | * List for archive table items, i.e. revisions deleted via action=delete |
229 | 248 | */ |
230 | 249 | class RevDel_ArchiveList extends RevDel_RevisionList { |
231 | | - var $type = 'archive'; |
232 | | - var $idField = 'ar_timestamp'; |
233 | | - var $dateField = 'ar_timestamp'; |
234 | | - var $authorIdField = 'ar_user'; |
235 | | - var $authorNameField = 'ar_user_text'; |
| 250 | + public function getType() { |
| 251 | + return 'archive'; |
| 252 | + } |
236 | 253 | |
| 254 | + public static function getRelationType() { |
| 255 | + return 'ar_timestamp'; |
| 256 | + } |
| 257 | + |
237 | 258 | /** |
238 | 259 | * @param $db DatabaseBase |
239 | 260 | * @return mixed |
— | — | @@ -276,6 +297,22 @@ |
277 | 298 | array( 'page' => $this->list->title->getArticleId() ) ); |
278 | 299 | } |
279 | 300 | |
| 301 | + public function getIdField() { |
| 302 | + return 'ar_timestamp'; |
| 303 | + } |
| 304 | + |
| 305 | + public function getTimestampField() { |
| 306 | + return 'ar_timestamp'; |
| 307 | + } |
| 308 | + |
| 309 | + public function getAuthorIdField() { |
| 310 | + return 'ar_user'; |
| 311 | + } |
| 312 | + |
| 313 | + public function getAuthorNameField() { |
| 314 | + return 'ar_user_text'; |
| 315 | + } |
| 316 | + |
280 | 317 | public function getId() { |
281 | 318 | # Convert DB timestamp to MW timestamp |
282 | 319 | return $this->revision->getTimestamp(); |
— | — | @@ -285,12 +322,13 @@ |
286 | 323 | $dbw = wfGetDB( DB_MASTER ); |
287 | 324 | $dbw->update( 'archive', |
288 | 325 | array( 'ar_deleted' => $bits ), |
289 | | - array( 'ar_namespace' => $this->list->title->getNamespace(), |
290 | | - 'ar_title' => $this->list->title->getDBkey(), |
| 326 | + array( |
| 327 | + 'ar_namespace' => $this->list->title->getNamespace(), |
| 328 | + 'ar_title' => $this->list->title->getDBkey(), |
291 | 329 | // use timestamp for index |
292 | | - 'ar_timestamp' => $this->row->ar_timestamp, |
293 | | - 'ar_rev_id' => $this->row->ar_rev_id, |
294 | | - 'ar_deleted' => $this->getBits() |
| 330 | + 'ar_timestamp' => $this->row->ar_timestamp, |
| 331 | + 'ar_rev_id' => $this->row->ar_rev_id, |
| 332 | + 'ar_deleted' => $this->getBits() |
295 | 333 | ), |
296 | 334 | __METHOD__ ); |
297 | 335 | return (bool)$dbw->affectedRows(); |
— | — | @@ -298,7 +336,7 @@ |
299 | 337 | |
300 | 338 | protected function getRevisionLink() { |
301 | 339 | $undelete = SpecialPage::getTitleFor( 'Undelete' ); |
302 | | - $date = $this->getLang()->timeanddate( $this->revision->getTimestamp(), true ); |
| 340 | + $date = $this->list->getLang()->timeanddate( $this->revision->getTimestamp(), true ); |
303 | 341 | if ( $this->isDeleted() && !$this->canViewContent() ) { |
304 | 342 | return $date; |
305 | 343 | } |
— | — | @@ -336,6 +374,10 @@ |
337 | 375 | array( 'page' => $this->list->title->getArticleId() ) ); |
338 | 376 | } |
339 | 377 | |
| 378 | + public function getIdField() { |
| 379 | + return 'ar_rev_id'; |
| 380 | + } |
| 381 | + |
340 | 382 | public function getId() { |
341 | 383 | return $this->revision->getId(); |
342 | 384 | } |
— | — | @@ -356,11 +398,14 @@ |
357 | 399 | * List for oldimage table items |
358 | 400 | */ |
359 | 401 | class RevDel_FileList extends RevDel_List { |
360 | | - var $type = 'oldimage'; |
361 | | - var $idField = 'oi_archive_name'; |
362 | | - var $dateField = 'oi_timestamp'; |
363 | | - var $authorIdField = 'oi_user'; |
364 | | - var $authorNameField = 'oi_user_text'; |
| 402 | + public function getType() { |
| 403 | + return 'oldimage'; |
| 404 | + } |
| 405 | + |
| 406 | + public static function getRelationType() { |
| 407 | + return 'oi_archive_name'; |
| 408 | + } |
| 409 | + |
365 | 410 | var $storeBatch, $deleteBatch, $cleanupBatch; |
366 | 411 | |
367 | 412 | /** |
— | — | @@ -442,6 +487,22 @@ |
443 | 488 | $this->file = RepoGroup::singleton()->getLocalRepo()->newFileFromRow( $row ); |
444 | 489 | } |
445 | 490 | |
| 491 | + public function getIdField() { |
| 492 | + return 'oi_archive_name'; |
| 493 | + } |
| 494 | + |
| 495 | + public function getTimestampField() { |
| 496 | + return 'oi_timestamp'; |
| 497 | + } |
| 498 | + |
| 499 | + public function getAuthorIdField() { |
| 500 | + return 'oi_user'; |
| 501 | + } |
| 502 | + |
| 503 | + public function getAuthorNameField() { |
| 504 | + return 'oi_user_text'; |
| 505 | + } |
| 506 | + |
446 | 507 | public function getId() { |
447 | 508 | $parts = explode( '!', $this->row->oi_archive_name ); |
448 | 509 | return $parts[0]; |
— | — | @@ -506,7 +567,7 @@ |
507 | 568 | * Overridden by RevDel_ArchivedFileItem. |
508 | 569 | */ |
509 | 570 | protected function getLink() { |
510 | | - $date = $this->getLang()->timeanddate( $this->file->getTimestamp(), true ); |
| 571 | + $date = $this->list->getLang()->timeanddate( $this->file->getTimestamp(), true ); |
511 | 572 | if ( $this->isDeleted() ) { |
512 | 573 | # Hidden files... |
513 | 574 | if ( !$this->canViewContent() ) { |
— | — | @@ -518,7 +579,8 @@ |
519 | 580 | array( |
520 | 581 | 'target' => $this->list->title->getPrefixedText(), |
521 | 582 | 'file' => $this->file->getArchiveName(), |
522 | | - 'token' => $this->getUser()->editToken( $this->file->getArchiveName() ) |
| 583 | + 'token' => $this->list->getUser()->editToken( |
| 584 | + $this->file->getArchiveName() ) |
523 | 585 | ) |
524 | 586 | ); |
525 | 587 | } |
— | — | @@ -567,11 +629,11 @@ |
568 | 630 | $data = |
569 | 631 | wfMsg( |
570 | 632 | 'widthheight', |
571 | | - $this->getLang()->formatNum( $this->file->getWidth() ), |
572 | | - $this->getLang()->formatNum( $this->file->getHeight() ) |
| 633 | + $this->list->getLang()->formatNum( $this->file->getWidth() ), |
| 634 | + $this->list->getLang()->formatNum( $this->file->getHeight() ) |
573 | 635 | ) . |
574 | 636 | ' (' . |
575 | | - wfMsgExt( 'nbytes', 'parsemag', $this->getLang()->formatNum( $this->file->getSize() ) ) . |
| 637 | + wfMsgExt( 'nbytes', 'parsemag', $this->list->getLang()->formatNum( $this->file->getSize() ) ) . |
576 | 638 | ')'; |
577 | 639 | |
578 | 640 | return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' . |
— | — | @@ -583,12 +645,14 @@ |
584 | 646 | * List for filearchive table items |
585 | 647 | */ |
586 | 648 | class RevDel_ArchivedFileList extends RevDel_FileList { |
587 | | - var $type = 'filearchive'; |
588 | | - var $idField = 'fa_id'; |
589 | | - var $dateField = 'fa_timestamp'; |
590 | | - var $authorIdField = 'fa_user'; |
591 | | - var $authorNameField = 'fa_user_text'; |
| 649 | + public function getType() { |
| 650 | + return 'filearchive'; |
| 651 | + } |
592 | 652 | |
| 653 | + public static function getRelationType() { |
| 654 | + return 'fa_id'; |
| 655 | + } |
| 656 | + |
593 | 657 | /** |
594 | 658 | * @param $db DatabaseBase |
595 | 659 | * @return mixed |
— | — | @@ -619,6 +683,22 @@ |
620 | 684 | $this->file = ArchivedFile::newFromRow( $row ); |
621 | 685 | } |
622 | 686 | |
| 687 | + public function getIdField() { |
| 688 | + return 'fa_id'; |
| 689 | + } |
| 690 | + |
| 691 | + public function getTimestampField() { |
| 692 | + return 'fa_timestamp'; |
| 693 | + } |
| 694 | + |
| 695 | + public function getAuthorIdField() { |
| 696 | + return 'fa_user'; |
| 697 | + } |
| 698 | + |
| 699 | + public function getAuthorNameField() { |
| 700 | + return 'fa_user_text'; |
| 701 | + } |
| 702 | + |
623 | 703 | public function getId() { |
624 | 704 | return $this->row->fa_id; |
625 | 705 | } |
— | — | @@ -637,7 +717,7 @@ |
638 | 718 | } |
639 | 719 | |
640 | 720 | protected function getLink() { |
641 | | - $date = $this->getLang()->timeanddate( $this->file->getTimestamp(), true ); |
| 721 | + $date = $this->list->getLang()->timeanddate( $this->file->getTimestamp(), true ); |
642 | 722 | $undelete = SpecialPage::getTitleFor( 'Undelete' ); |
643 | 723 | $key = $this->file->getKey(); |
644 | 724 | # Hidden files... |
— | — | @@ -648,7 +728,7 @@ |
649 | 729 | array( |
650 | 730 | 'target' => $this->list->title->getPrefixedText(), |
651 | 731 | 'file' => $key, |
652 | | - 'token' => $this->getUser()->editToken( $key ) |
| 732 | + 'token' => $this->list->getUser()->editToken( $key ) |
653 | 733 | ) |
654 | 734 | ); |
655 | 735 | } |
— | — | @@ -663,12 +743,14 @@ |
664 | 744 | * List for logging table items |
665 | 745 | */ |
666 | 746 | class RevDel_LogList extends RevDel_List { |
667 | | - var $type = 'logging'; |
668 | | - var $idField = 'log_id'; |
669 | | - var $dateField = 'log_timestamp'; |
670 | | - var $authorIdField = 'log_user'; |
671 | | - var $authorNameField = 'log_user_text'; |
| 747 | + public function getType() { |
| 748 | + return 'logging'; |
| 749 | + } |
672 | 750 | |
| 751 | + public static function getRelationType() { |
| 752 | + return 'log_id'; |
| 753 | + } |
| 754 | + |
673 | 755 | /** |
674 | 756 | * @param $db DatabaseBase |
675 | 757 | * @return mixed |
— | — | @@ -707,6 +789,22 @@ |
708 | 790 | * Item class for a logging table row |
709 | 791 | */ |
710 | 792 | class RevDel_LogItem extends RevDel_Item { |
| 793 | + public function getIdField() { |
| 794 | + return 'log_id'; |
| 795 | + } |
| 796 | + |
| 797 | + public function getTimestampField() { |
| 798 | + return 'log_timestamp'; |
| 799 | + } |
| 800 | + |
| 801 | + public function getAuthorIdField() { |
| 802 | + return 'log_user'; |
| 803 | + } |
| 804 | + |
| 805 | + public function getAuthorNameField() { |
| 806 | + return 'log_user_text'; |
| 807 | + } |
| 808 | + |
711 | 809 | public function canView() { |
712 | 810 | return LogEventsList::userCan( $this->row, Revision::DELETED_RESTRICTED ); |
713 | 811 | } |
— | — | @@ -744,7 +842,7 @@ |
745 | 843 | } |
746 | 844 | |
747 | 845 | public function getHTML() { |
748 | | - $date = htmlspecialchars( $this->getLang()->timeanddate( $this->row->log_timestamp ) ); |
| 846 | + $date = htmlspecialchars( $this->list->getLang()->timeanddate( $this->row->log_timestamp ) ); |
749 | 847 | $paramArray = LogPage::extractParams( $this->row->log_params ); |
750 | 848 | $title = Title::makeTitle( $this->row->log_namespace, $this->row->log_title ); |
751 | 849 | |
— | — | @@ -771,7 +869,7 @@ |
772 | 870 | $userLink = '<span class="history-deleted">' . $userLink . '</span>'; |
773 | 871 | } |
774 | 872 | // Comment |
775 | | - $comment = $this->getLang()->getDirMark() . Linker::commentBlock( $this->row->log_comment ); |
| 873 | + $comment = $this->list->getLang()->getDirMark() . Linker::commentBlock( $this->row->log_comment ); |
776 | 874 | if( LogEventsList::isDeleted($this->row,LogPage::DELETED_COMMENT) ) { |
777 | 875 | $comment = '<span class="history-deleted">' . $comment . '</span>'; |
778 | 876 | } |
Index: trunk/phase3/includes/revisiondelete/RevisionDeleter.php |
— | — | @@ -119,8 +119,7 @@ |
120 | 120 | } |
121 | 121 | if ( isset( SpecialRevisionDelete::$allowedTypes[$typeName] ) ) { |
122 | 122 | $class = SpecialRevisionDelete::$allowedTypes[$typeName]['list-class']; |
123 | | - $list = new $class( null, null, null ); |
124 | | - return $list->getIdField(); |
| 123 | + return call_user_func( array( $class, 'getRelationType' ) ); |
125 | 124 | } else { |
126 | 125 | return null; |
127 | 126 | } |
Index: trunk/phase3/includes/revisiondelete/RevisionDeleteAbstracts.php |
— | — | @@ -6,66 +6,17 @@ |
7 | 7 | * relevant rows, to return RevDel_Item subclasses wrapping them, and |
8 | 8 | * to wrap bulk update operations. |
9 | 9 | */ |
10 | | -abstract class RevDel_List { |
11 | | - |
| 10 | +abstract class RevDel_List extends Rev_List { |
12 | 11 | /** |
13 | | - * @var Title |
| 12 | + * Get the DB field name associated with the ID list. |
| 13 | + * This used to populate the log_search table for finding log entries. |
| 14 | + * Override this function. |
14 | 15 | */ |
15 | | - var $title; |
16 | | - |
17 | | - var $special, $ids, $res, $current; |
18 | | - var $type = null; // override this |
19 | | - var $idField = null; // override this |
20 | | - var $dateField = false; // override this |
21 | | - var $authorIdField = false; // override this |
22 | | - var $authorNameField = false; // override this |
23 | | - |
24 | | - /** |
25 | | - * @param $special The parent SpecialPage |
26 | | - * @param $title The target title |
27 | | - * @param $ids Array of IDs |
28 | | - */ |
29 | | - public function __construct( $special, $title, $ids ) { |
30 | | - $this->special = $special; |
31 | | - $this->title = $title; |
32 | | - $this->ids = $ids; |
| 16 | + public static function getRelationType() { |
| 17 | + return null; |
33 | 18 | } |
34 | 19 | |
35 | 20 | /** |
36 | | - * Get the internal type name of this list. Equal to the table name. |
37 | | - */ |
38 | | - public function getType() { |
39 | | - return $this->type; |
40 | | - } |
41 | | - |
42 | | - /** |
43 | | - * Get the DB field name associated with the ID list |
44 | | - */ |
45 | | - public function getIdField() { |
46 | | - return $this->idField; |
47 | | - } |
48 | | - |
49 | | - /** |
50 | | - * Get the DB field name storing timestamps |
51 | | - */ |
52 | | - public function getTimestampField() { |
53 | | - return $this->dateField; |
54 | | - } |
55 | | - |
56 | | - /** |
57 | | - * Get the DB field name storing user ids |
58 | | - */ |
59 | | - public function getAuthorIdField() { |
60 | | - return $this->authorIdField; |
61 | | - } |
62 | | - |
63 | | - /** |
64 | | - * Get the DB field name storing user names |
65 | | - */ |
66 | | - public function getAuthorNameField() { |
67 | | - return $this->authorNameField; |
68 | | - } |
69 | | - /** |
70 | 21 | * Set the visibility for the revisions in this list. Logging and |
71 | 22 | * transactions are done here. |
72 | 23 | * |
— | — | @@ -253,59 +204,6 @@ |
254 | 205 | } |
255 | 206 | |
256 | 207 | /** |
257 | | - * Initialise the current iteration pointer |
258 | | - */ |
259 | | - protected function initCurrent() { |
260 | | - $row = $this->res->current(); |
261 | | - if ( $row ) { |
262 | | - $this->current = $this->newItem( $row ); |
263 | | - } else { |
264 | | - $this->current = false; |
265 | | - } |
266 | | - } |
267 | | - |
268 | | - /** |
269 | | - * Start iteration. This must be called before current() or next(). |
270 | | - * @return First list item |
271 | | - */ |
272 | | - public function reset() { |
273 | | - if ( !$this->res ) { |
274 | | - $this->res = $this->doQuery( wfGetDB( DB_SLAVE ) ); |
275 | | - } else { |
276 | | - $this->res->rewind(); |
277 | | - } |
278 | | - $this->initCurrent(); |
279 | | - return $this->current; |
280 | | - } |
281 | | - |
282 | | - /** |
283 | | - * Get the current list item, or false if we are at the end |
284 | | - */ |
285 | | - public function current() { |
286 | | - return $this->current; |
287 | | - } |
288 | | - |
289 | | - /** |
290 | | - * Move the iteration pointer to the next list item, and return it. |
291 | | - */ |
292 | | - public function next() { |
293 | | - $this->res->next(); |
294 | | - $this->initCurrent(); |
295 | | - return $this->current; |
296 | | - } |
297 | | - |
298 | | - /** |
299 | | - * Get the number of items in the list. |
300 | | - */ |
301 | | - public function length() { |
302 | | - if( !$this->res ) { |
303 | | - return 0; |
304 | | - } else { |
305 | | - return $this->res->numRows(); |
306 | | - } |
307 | | - } |
308 | | - |
309 | | - /** |
310 | 208 | * Clear any data structures needed for doPreCommitUpdates() and doPostCommitUpdates() |
311 | 209 | * STUB |
312 | 210 | */ |
— | — | @@ -331,36 +229,6 @@ |
332 | 230 | } |
333 | 231 | |
334 | 232 | /** |
335 | | - * Get the user doing the action |
336 | | - * |
337 | | - * @return User object |
338 | | - */ |
339 | | - public function getUser() { |
340 | | - return $this->special->getUser(); |
341 | | - } |
342 | | - |
343 | | - /** |
344 | | - * Get the language of the user doing the action |
345 | | - * |
346 | | - * @return Language object |
347 | | - */ |
348 | | - public function getLang() { |
349 | | - return $this->special->getLang(); |
350 | | - } |
351 | | - |
352 | | - /** |
353 | | - * Create an item object from a DB result row |
354 | | - * @param $row stdclass |
355 | | - */ |
356 | | - abstract public function newItem( $row ); |
357 | | - |
358 | | - /** |
359 | | - * Do the DB query to iterate through the objects. |
360 | | - * @param $db DatabaseBase object to use for the query |
361 | | - */ |
362 | | - abstract public function doQuery( $db ); |
363 | | - |
364 | | - /** |
365 | 233 | * Get the integer value of the flag used for suppression |
366 | 234 | */ |
367 | 235 | abstract public function getSuppressBit(); |
— | — | @@ -369,75 +237,8 @@ |
370 | 238 | /** |
371 | 239 | * Abstract base class for deletable items |
372 | 240 | */ |
373 | | -abstract class RevDel_Item { |
374 | | - /** The parent SpecialPage */ |
375 | | - var $special; |
376 | | - |
377 | | - /** The parent RevDel_List */ |
378 | | - var $list; |
379 | | - |
380 | | - /** The DB result row */ |
381 | | - var $row; |
382 | | - |
| 241 | +abstract class RevDel_Item extends Rev_Item { |
383 | 242 | /** |
384 | | - * @param $list RevDel_List |
385 | | - * @param $row DB result row |
386 | | - */ |
387 | | - public function __construct( $list, $row ) { |
388 | | - $this->special = $list->special; |
389 | | - $this->list = $list; |
390 | | - $this->row = $row; |
391 | | - } |
392 | | - |
393 | | - /** |
394 | | - * Get the ID, as it would appear in the ids URL parameter |
395 | | - */ |
396 | | - public function getId() { |
397 | | - $field = $this->list->getIdField(); |
398 | | - return $this->row->$field; |
399 | | - } |
400 | | - |
401 | | - /** |
402 | | - * Get the date, formatted with $wgLang |
403 | | - */ |
404 | | - public function formatDate() { |
405 | | - global $wgLang; |
406 | | - return $wgLang->date( $this->getTimestamp() ); |
407 | | - } |
408 | | - |
409 | | - /** |
410 | | - * Get the time, formatted with $wgLang |
411 | | - */ |
412 | | - public function formatTime() { |
413 | | - global $wgLang; |
414 | | - return $wgLang->time( $this->getTimestamp() ); |
415 | | - } |
416 | | - |
417 | | - /** |
418 | | - * Get the timestamp in MW 14-char form |
419 | | - */ |
420 | | - public function getTimestamp() { |
421 | | - $field = $this->list->getTimestampField(); |
422 | | - return wfTimestamp( TS_MW, $this->row->$field ); |
423 | | - } |
424 | | - |
425 | | - /** |
426 | | - * Get the author user ID |
427 | | - */ |
428 | | - public function getAuthorId() { |
429 | | - $field = $this->list->getAuthorIdField(); |
430 | | - return intval( $this->row->$field ); |
431 | | - } |
432 | | - |
433 | | - /** |
434 | | - * Get the author user name |
435 | | - */ |
436 | | - public function getAuthorName() { |
437 | | - $field = $this->list->getAuthorNameField(); |
438 | | - return strval( $this->row->$field ); |
439 | | - } |
440 | | - |
441 | | - /** |
442 | 243 | * Returns true if the item is "current", and the operation to set the given |
443 | 244 | * bits can't be executed for that reason |
444 | 245 | * STUB |
— | — | @@ -447,45 +248,11 @@ |
448 | 249 | } |
449 | 250 | |
450 | 251 | /** |
451 | | - * Get the user doing the action |
452 | | - * |
453 | | - * @return User object |
454 | | - */ |
455 | | - public function getUser() { |
456 | | - return $this->special->getUser(); |
457 | | - } |
458 | | - |
459 | | - /** |
460 | | - * Get the language of the user doing the action |
461 | | - * |
462 | | - * @return Language object |
463 | | - */ |
464 | | - public function getLang() { |
465 | | - return $this->special->getLang(); |
466 | | - } |
467 | | - |
468 | | - /** |
469 | | - * Returns true if the current user can view the item |
470 | | - */ |
471 | | - abstract public function canView(); |
472 | | - |
473 | | - /** |
474 | | - * Returns true if the current user can view the item text/file |
475 | | - */ |
476 | | - abstract public function canViewContent(); |
477 | | - |
478 | | - /** |
479 | 252 | * Get the current deletion bitfield value |
480 | 253 | */ |
481 | 254 | abstract public function getBits(); |
482 | 255 | |
483 | 256 | /** |
484 | | - * Get the HTML of the list item. Should be include <li></li> tags. |
485 | | - * This is used to show the list in HTML form, by the special page. |
486 | | - */ |
487 | | - abstract public function getHTML(); |
488 | | - |
489 | | - /** |
490 | 257 | * Set the visibility of the item. This should do any necessary DB queries. |
491 | 258 | * |
492 | 259 | * The DB update query should have a condition which forces it to only update |
Index: trunk/phase3/includes/AutoLoader.php |
— | — | @@ -187,7 +187,10 @@ |
188 | 188 | 'Replacer' => 'includes/StringUtils.php', |
189 | 189 | 'RequestContext' => 'includes/RequestContext.php', |
190 | 190 | 'ReverseChronologicalPager' => 'includes/Pager.php', |
| 191 | + 'Rev_Item' => 'includes/RevisionList.php', |
| 192 | + 'Rev_List' => 'includes/RevisionList.php', |
191 | 193 | 'Revision' => 'includes/Revision.php', |
| 194 | + 'RevisionList' => 'includes/RevisionList.php', |
192 | 195 | 'RSSFeed' => 'includes/Feed.php', |
193 | 196 | 'Sanitizer' => 'includes/Sanitizer.php', |
194 | 197 | 'SiteConfiguration' => 'includes/SiteConfiguration.php', |
Index: trunk/phase3/includes/specials/SpecialRevisiondelete.php |
— | — | @@ -61,39 +61,39 @@ |
62 | 62 | */ |
63 | 63 | static $allowedTypes = array( |
64 | 64 | 'revision' => array( |
65 | | - 'check-label' => 'revdelete-hide-text', |
| 65 | + 'check-label' => 'revdelete-hide-text', |
66 | 66 | 'deletion-bits' => Revision::DELETED_TEXT, |
67 | | - 'success' => 'revdelete-success', |
68 | | - 'failure' => 'revdelete-failure', |
69 | | - 'list-class' => 'RevDel_RevisionList', |
| 67 | + 'success' => 'revdelete-success', |
| 68 | + 'failure' => 'revdelete-failure', |
| 69 | + 'list-class' => 'RevDel_RevisionList', |
70 | 70 | ), |
71 | 71 | 'archive' => array( |
72 | | - 'check-label' => 'revdelete-hide-text', |
| 72 | + 'check-label' => 'revdelete-hide-text', |
73 | 73 | 'deletion-bits' => Revision::DELETED_TEXT, |
74 | | - 'success' => 'revdelete-success', |
75 | | - 'failure' => 'revdelete-failure', |
76 | | - 'list-class' => 'RevDel_ArchiveList', |
| 74 | + 'success' => 'revdelete-success', |
| 75 | + 'failure' => 'revdelete-failure', |
| 76 | + 'list-class' => 'RevDel_ArchiveList', |
77 | 77 | ), |
78 | 78 | 'oldimage'=> array( |
79 | | - 'check-label' => 'revdelete-hide-image', |
| 79 | + 'check-label' => 'revdelete-hide-image', |
80 | 80 | 'deletion-bits' => File::DELETED_FILE, |
81 | | - 'success' => 'revdelete-success', |
82 | | - 'failure' => 'revdelete-failure', |
83 | | - 'list-class' => 'RevDel_FileList', |
| 81 | + 'success' => 'revdelete-success', |
| 82 | + 'failure' => 'revdelete-failure', |
| 83 | + 'list-class' => 'RevDel_FileList', |
84 | 84 | ), |
85 | 85 | 'filearchive' => array( |
86 | | - 'check-label' => 'revdelete-hide-image', |
| 86 | + 'check-label' => 'revdelete-hide-image', |
87 | 87 | 'deletion-bits' => File::DELETED_FILE, |
88 | | - 'success' => 'revdelete-success', |
89 | | - 'failure' => 'revdelete-failure', |
90 | | - 'list-class' => 'RevDel_ArchivedFileList', |
| 88 | + 'success' => 'revdelete-success', |
| 89 | + 'failure' => 'revdelete-failure', |
| 90 | + 'list-class' => 'RevDel_ArchivedFileList', |
91 | 91 | ), |
92 | 92 | 'logging' => array( |
93 | | - 'check-label' => 'revdelete-hide-name', |
| 93 | + 'check-label' => 'revdelete-hide-name', |
94 | 94 | 'deletion-bits' => LogPage::DELETED_ACTION, |
95 | | - 'success' => 'logdelete-success', |
96 | | - 'failure' => 'logdelete-failure', |
97 | | - 'list-class' => 'RevDel_LogList', |
| 95 | + 'success' => 'logdelete-success', |
| 96 | + 'failure' => 'logdelete-failure', |
| 97 | + 'list-class' => 'RevDel_LogList', |
98 | 98 | ), |
99 | 99 | ); |
100 | 100 | |
— | — | @@ -258,7 +258,7 @@ |
259 | 259 | protected function getLogQueryCond() { |
260 | 260 | $conds = array(); |
261 | 261 | // Revision delete logs for these item |
262 | | - $conds['log_type'] = array('delete','suppress'); |
| 262 | + $conds['log_type'] = array( 'delete', 'suppress' ); |
263 | 263 | $conds['log_action'] = $this->getList()->getLogAction(); |
264 | 264 | $conds['ls_field'] = RevisionDeleter::getRelationType( $this->typeName ); |
265 | 265 | $conds['ls_value'] = $this->ids; |
— | — | @@ -328,7 +328,7 @@ |
329 | 329 | protected function getList() { |
330 | 330 | if ( is_null( $this->list ) ) { |
331 | 331 | $class = $this->typeInfo['list-class']; |
332 | | - $this->list = new $class( $this, $this->targetObj, $this->ids ); |
| 332 | + $this->list = new $class( $this->getContext(), $this->targetObj, $this->ids ); |
333 | 333 | } |
334 | 334 | return $this->list; |
335 | 335 | } |
— | — | @@ -506,7 +506,8 @@ |
507 | 507 | */ |
508 | 508 | protected function submit() { |
509 | 509 | # Check edit token on submission |
510 | | - if( $this->submitClicked && !$this->getUser()->matchEditToken( $this->getRequest()->getVal('wpEditToken') ) ) { |
| 510 | + $token = $this->getRequest()->getVal('wpEditToken'); |
| 511 | + if( $this->submitClicked && !$this->getUser()->matchEditToken( $token ) ) { |
511 | 512 | $this->getOutput()->addWikiMsg( 'sessionfailure' ); |
512 | 513 | return false; |
513 | 514 | } |
Index: trunk/phase3/includes/RevisionList.php |
— | — | @@ -0,0 +1,354 @@ |
| 2 | +<?php |
| 3 | +/** |
| 4 | + * List for revision table items for a single page |
| 5 | + */ |
| 6 | +abstract class Rev_List { |
| 7 | + /** |
| 8 | + * @var Title |
| 9 | + */ |
| 10 | + var $title; |
| 11 | + /** |
| 12 | + * @var RequestContext |
| 13 | + */ |
| 14 | + var $context; |
| 15 | + |
| 16 | + var $ids, $res, $current; |
| 17 | + |
| 18 | + function __construct( RequestContext $context, Title $title, array $ids ) { |
| 19 | + $this->context = $context; |
| 20 | + $this->title = $title; |
| 21 | + $this->ids = $ids; |
| 22 | + } |
| 23 | + |
| 24 | + /** |
| 25 | + * Get the internal type name of this list. Equal to the table name. |
| 26 | + * Override this function. |
| 27 | + */ |
| 28 | + public function getType() { |
| 29 | + return null; |
| 30 | + } |
| 31 | + |
| 32 | + /** |
| 33 | + * Initialise the current iteration pointer |
| 34 | + */ |
| 35 | + protected function initCurrent() { |
| 36 | + $row = $this->res->current(); |
| 37 | + if ( $row ) { |
| 38 | + $this->current = $this->newItem( $row ); |
| 39 | + } else { |
| 40 | + $this->current = false; |
| 41 | + } |
| 42 | + } |
| 43 | + |
| 44 | + /** |
| 45 | + * Start iteration. This must be called before current() or next(). |
| 46 | + * @return First list item |
| 47 | + */ |
| 48 | + public function reset() { |
| 49 | + if ( !$this->res ) { |
| 50 | + $this->res = $this->doQuery( wfGetDB( DB_SLAVE ) ); |
| 51 | + } else { |
| 52 | + $this->res->rewind(); |
| 53 | + } |
| 54 | + $this->initCurrent(); |
| 55 | + return $this->current; |
| 56 | + } |
| 57 | + |
| 58 | + /** |
| 59 | + * Get the current list item, or false if we are at the end |
| 60 | + */ |
| 61 | + public function current() { |
| 62 | + return $this->current; |
| 63 | + } |
| 64 | + |
| 65 | + /** |
| 66 | + * Move the iteration pointer to the next list item, and return it. |
| 67 | + */ |
| 68 | + public function next() { |
| 69 | + $this->res->next(); |
| 70 | + $this->initCurrent(); |
| 71 | + return $this->current; |
| 72 | + } |
| 73 | + |
| 74 | + /** |
| 75 | + * Get the number of items in the list. |
| 76 | + */ |
| 77 | + public function length() { |
| 78 | + if( !$this->res ) { |
| 79 | + return 0; |
| 80 | + } else { |
| 81 | + return $this->res->numRows(); |
| 82 | + } |
| 83 | + } |
| 84 | + |
| 85 | + /** |
| 86 | + * Do the DB query to iterate through the objects. |
| 87 | + * @param $db DatabaseBase object to use for the query |
| 88 | + */ |
| 89 | + abstract public function doQuery( $db ); |
| 90 | + |
| 91 | + /** |
| 92 | + * Create an item object from a DB result row |
| 93 | + * @param $row stdclass |
| 94 | + */ |
| 95 | + abstract public function newItem( $row ); |
| 96 | + |
| 97 | + /** |
| 98 | + * Get the language of the user doing the action |
| 99 | + * |
| 100 | + * @return Language object |
| 101 | + */ |
| 102 | + public function getLang() { |
| 103 | + return $this->context->getLang(); |
| 104 | + } |
| 105 | + |
| 106 | + /** |
| 107 | + * Get the user doing the action |
| 108 | + * |
| 109 | + * @return User object |
| 110 | + */ |
| 111 | + public function getUser() { |
| 112 | + return $this->context->getUser(); |
| 113 | + } |
| 114 | +} |
| 115 | + |
| 116 | +/** |
| 117 | + * Abstract base class for revision items |
| 118 | + */ |
| 119 | +abstract class Rev_Item { |
| 120 | + /** The parent Rev_List */ |
| 121 | + var $list; |
| 122 | + |
| 123 | + /** The DB result row */ |
| 124 | + var $row; |
| 125 | + |
| 126 | + /** |
| 127 | + * @param $list Rev_List |
| 128 | + * @param $row DB result row |
| 129 | + */ |
| 130 | + public function __construct( $list, $row ) { |
| 131 | + $this->list = $list; |
| 132 | + $this->row = $row; |
| 133 | + } |
| 134 | + |
| 135 | + /** |
| 136 | + * Get the DB field name associated with the ID list. |
| 137 | + * Override this function. |
| 138 | + */ |
| 139 | + public function getIdField() { |
| 140 | + return null; |
| 141 | + } |
| 142 | + |
| 143 | + /** |
| 144 | + * Get the DB field name storing timestamps. |
| 145 | + * Override this function. |
| 146 | + */ |
| 147 | + public function getTimestampField() { |
| 148 | + return false; |
| 149 | + } |
| 150 | + |
| 151 | + /** |
| 152 | + * Get the DB field name storing user ids. |
| 153 | + * Override this function. |
| 154 | + */ |
| 155 | + public function getAuthorIdField() { |
| 156 | + return false; |
| 157 | + } |
| 158 | + |
| 159 | + /** |
| 160 | + * Get the DB field name storing user names. |
| 161 | + * Override this function. |
| 162 | + */ |
| 163 | + public function getAuthorNameField() { |
| 164 | + return false; |
| 165 | + } |
| 166 | + |
| 167 | + /** |
| 168 | + * Get the ID, as it would appear in the ids URL parameter |
| 169 | + */ |
| 170 | + public function getId() { |
| 171 | + $field = $this->getIdField(); |
| 172 | + return $this->row->$field; |
| 173 | + } |
| 174 | + |
| 175 | + /** |
| 176 | + * Get the date, formatted with $wgLang |
| 177 | + */ |
| 178 | + public function formatDate() { |
| 179 | + global $wgLang; |
| 180 | + return $wgLang->date( $this->getTimestamp() ); |
| 181 | + } |
| 182 | + |
| 183 | + /** |
| 184 | + * Get the time, formatted with $wgLang |
| 185 | + */ |
| 186 | + public function formatTime() { |
| 187 | + global $wgLang; |
| 188 | + return $wgLang->time( $this->getTimestamp() ); |
| 189 | + } |
| 190 | + |
| 191 | + /** |
| 192 | + * Get the timestamp in MW 14-char form |
| 193 | + */ |
| 194 | + public function getTimestamp() { |
| 195 | + $field = $this->getTimestampField(); |
| 196 | + return wfTimestamp( TS_MW, $this->row->$field ); |
| 197 | + } |
| 198 | + |
| 199 | + /** |
| 200 | + * Get the author user ID |
| 201 | + */ |
| 202 | + public function getAuthorId() { |
| 203 | + $field = $this->getAuthorIdField(); |
| 204 | + return intval( $this->row->$field ); |
| 205 | + } |
| 206 | + |
| 207 | + /** |
| 208 | + * Get the author user name |
| 209 | + */ |
| 210 | + public function getAuthorName() { |
| 211 | + $field = $this->getAuthorNameField(); |
| 212 | + return strval( $this->row->$field ); |
| 213 | + } |
| 214 | + |
| 215 | + /** |
| 216 | + * Returns true if the current user can view the item |
| 217 | + */ |
| 218 | + abstract public function canView(); |
| 219 | + |
| 220 | + /** |
| 221 | + * Returns true if the current user can view the item text/file |
| 222 | + */ |
| 223 | + abstract public function canViewContent(); |
| 224 | + |
| 225 | + /** |
| 226 | + * Get the HTML of the list item. Should be include <li></li> tags. |
| 227 | + * This is used to show the list in HTML form, by the special page. |
| 228 | + */ |
| 229 | + abstract public function getHTML(); |
| 230 | +} |
| 231 | + |
| 232 | +class RevisionList extends Rev_List { |
| 233 | + public function getType() { |
| 234 | + return 'revision'; |
| 235 | + } |
| 236 | + |
| 237 | + /** |
| 238 | + * @param $db DatabaseBase |
| 239 | + * @return mixed |
| 240 | + */ |
| 241 | + public function doQuery( $db ) { |
| 242 | + $ids = array_map( 'intval', $this->ids ); |
| 243 | + return $db->select( array('revision','page'), '*', |
| 244 | + array( |
| 245 | + 'rev_page' => $this->title->getArticleID(), |
| 246 | + 'rev_id' => array_map( 'intval', $this->ids ), |
| 247 | + 'rev_page = page_id' |
| 248 | + ), |
| 249 | + __METHOD__, |
| 250 | + array( 'ORDER BY' => 'rev_id DESC' ) |
| 251 | + ); |
| 252 | + } |
| 253 | + |
| 254 | + public function newItem( $row ) { |
| 255 | + return new RevisionItem( $this, $row ); |
| 256 | + } |
| 257 | +} |
| 258 | + |
| 259 | +/** |
| 260 | + * Item class for a live revision table row |
| 261 | + */ |
| 262 | +class RevisionItem extends Rev_Item { |
| 263 | + var $revision, $context; |
| 264 | + |
| 265 | + public function __construct( $list, $row ) { |
| 266 | + parent::__construct( $list, $row ); |
| 267 | + $this->revision = new Revision( $row ); |
| 268 | + $this->context = $list->context; |
| 269 | + } |
| 270 | + |
| 271 | + public function getIdField() { |
| 272 | + return 'rev_id'; |
| 273 | + } |
| 274 | + |
| 275 | + public function getTimestampField() { |
| 276 | + return 'rev_timestamp'; |
| 277 | + } |
| 278 | + |
| 279 | + public function getAuthorIdField() { |
| 280 | + return 'rev_user'; |
| 281 | + } |
| 282 | + |
| 283 | + public function getAuthorNameField() { |
| 284 | + return 'rev_user_text'; |
| 285 | + } |
| 286 | + |
| 287 | + public function canView() { |
| 288 | + return $this->revision->userCan( Revision::DELETED_RESTRICTED ); |
| 289 | + } |
| 290 | + |
| 291 | + public function canViewContent() { |
| 292 | + return $this->revision->userCan( Revision::DELETED_TEXT ); |
| 293 | + } |
| 294 | + |
| 295 | + public function isDeleted() { |
| 296 | + return $this->revision->isDeleted( Revision::DELETED_TEXT ); |
| 297 | + } |
| 298 | + |
| 299 | + /** |
| 300 | + * Get the HTML link to the revision text. |
| 301 | + * Overridden by RevDel_ArchiveItem. |
| 302 | + */ |
| 303 | + protected function getRevisionLink() { |
| 304 | + $date = $this->list->getLang()->timeanddate( $this->revision->getTimestamp(), true ); |
| 305 | + if ( $this->isDeleted() && !$this->canViewContent() ) { |
| 306 | + return $date; |
| 307 | + } |
| 308 | + return Linker::link( |
| 309 | + $this->list->title, |
| 310 | + $date, |
| 311 | + array(), |
| 312 | + array( |
| 313 | + 'oldid' => $this->revision->getId(), |
| 314 | + 'unhide' => 1 |
| 315 | + ) |
| 316 | + ); |
| 317 | + } |
| 318 | + |
| 319 | + /** |
| 320 | + * Get the HTML link to the diff. |
| 321 | + * Overridden by RevDel_ArchiveItem |
| 322 | + */ |
| 323 | + protected function getDiffLink() { |
| 324 | + if ( $this->isDeleted() && !$this->canViewContent() ) { |
| 325 | + return wfMsgHtml('diff'); |
| 326 | + } else { |
| 327 | + return |
| 328 | + Linker::link( |
| 329 | + $this->list->title, |
| 330 | + wfMsgHtml('diff'), |
| 331 | + array(), |
| 332 | + array( |
| 333 | + 'diff' => $this->revision->getId(), |
| 334 | + 'oldid' => 'prev', |
| 335 | + 'unhide' => 1 |
| 336 | + ), |
| 337 | + array( |
| 338 | + 'known', |
| 339 | + 'noclasses' |
| 340 | + ) |
| 341 | + ); |
| 342 | + } |
| 343 | + } |
| 344 | + |
| 345 | + public function getHTML() { |
| 346 | + $difflink = $this->getDiffLink(); |
| 347 | + $revlink = $this->getRevisionLink(); |
| 348 | + $userlink = Linker::revUserLink( $this->revision ); |
| 349 | + $comment = Linker::revComment( $this->revision ); |
| 350 | + if ( $this->isDeleted() ) { |
| 351 | + $revlink = "<span class=\"history-deleted\">$revlink</span>"; |
| 352 | + } |
| 353 | + return "<li>($difflink) $revlink $userlink $comment</li>"; |
| 354 | + } |
| 355 | +} |
Property changes on: trunk/phase3/includes/RevisionList.php |
___________________________________________________________________ |
Added: svn:eol-style |
1 | 356 | + native |