r91344 MediaWiki - Code Review archive

Repository:MediaWiki
Revision:r91343‎ | r91344 | r91345 >
Date:09:04, 2 July 2011
Author:aaron
Status:resolved (Comments)
Tags:
Comment:
* Added generic Rev_List revision listing class and refactored RevDelete_List stuff to use it
* Fixed bug in revdelete where all list Items where assumed to be of the same type (no longer holds since r87804). This was causing "Undefined property: stdClass::$rev_timestamp" errors for deleted revs.
* Cleaned up RevisionDeleter::getRelationType()
* Minor cleanups to SpecialRevisionDelete
Modified paths:
  • /trunk/phase3/includes/AutoLoader.php (modified) (history)
  • /trunk/phase3/includes/RevisionList.php (added) (history)
  • /trunk/phase3/includes/revisiondelete/RevisionDelete.php (modified) (history)
  • /trunk/phase3/includes/revisiondelete/RevisionDeleteAbstracts.php (modified) (history)
  • /trunk/phase3/includes/revisiondelete/RevisionDeleter.php (modified) (history)
  • /trunk/phase3/includes/specials/SpecialRevisiondelete.php (modified) (history)

Diff [purge]

Index: trunk/phase3/includes/revisiondelete/RevisionDelete.php
@@ -10,12 +10,15 @@
1111 */
1212 class RevDel_RevisionList extends RevDel_List {
1313 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';
1914
 15+ public function getType() {
 16+ return 'revision';
 17+ }
 18+
 19+ public static function getRelationType() {
 20+ return 'rev_id';
 21+ }
 22+
2023 /**
2124 * @param $db DatabaseBase
2225 * @return mixed
@@ -112,6 +115,22 @@
113116 $this->revision = new Revision( $row );
114117 }
115118
 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+
116135 public function canView() {
117136 return $this->revision->userCan( Revision::DELETED_RESTRICTED );
118137 }
@@ -170,7 +189,7 @@
171190 * Overridden by RevDel_ArchiveItem.
172191 */
173192 protected function getRevisionLink() {
174 - $date = $this->getLang()->timeanddate( $this->revision->getTimestamp(), true );
 193+ $date = $this->list->getLang()->timeanddate( $this->revision->getTimestamp(), true );
175194 if ( $this->isDeleted() && !$this->canViewContent() ) {
176195 return $date;
177196 }
@@ -227,12 +246,14 @@
228247 * List for archive table items, i.e. revisions deleted via action=delete
229248 */
230249 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+ }
236253
 254+ public static function getRelationType() {
 255+ return 'ar_timestamp';
 256+ }
 257+
237258 /**
238259 * @param $db DatabaseBase
239260 * @return mixed
@@ -276,6 +297,22 @@
277298 array( 'page' => $this->list->title->getArticleId() ) );
278299 }
279300
 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+
280317 public function getId() {
281318 # Convert DB timestamp to MW timestamp
282319 return $this->revision->getTimestamp();
@@ -285,12 +322,13 @@
286323 $dbw = wfGetDB( DB_MASTER );
287324 $dbw->update( 'archive',
288325 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(),
291329 // 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()
295333 ),
296334 __METHOD__ );
297335 return (bool)$dbw->affectedRows();
@@ -298,7 +336,7 @@
299337
300338 protected function getRevisionLink() {
301339 $undelete = SpecialPage::getTitleFor( 'Undelete' );
302 - $date = $this->getLang()->timeanddate( $this->revision->getTimestamp(), true );
 340+ $date = $this->list->getLang()->timeanddate( $this->revision->getTimestamp(), true );
303341 if ( $this->isDeleted() && !$this->canViewContent() ) {
304342 return $date;
305343 }
@@ -336,6 +374,10 @@
337375 array( 'page' => $this->list->title->getArticleId() ) );
338376 }
339377
 378+ public function getIdField() {
 379+ return 'ar_rev_id';
 380+ }
 381+
340382 public function getId() {
341383 return $this->revision->getId();
342384 }
@@ -356,11 +398,14 @@
357399 * List for oldimage table items
358400 */
359401 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+
365410 var $storeBatch, $deleteBatch, $cleanupBatch;
366411
367412 /**
@@ -442,6 +487,22 @@
443488 $this->file = RepoGroup::singleton()->getLocalRepo()->newFileFromRow( $row );
444489 }
445490
 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+
446507 public function getId() {
447508 $parts = explode( '!', $this->row->oi_archive_name );
448509 return $parts[0];
@@ -506,7 +567,7 @@
507568 * Overridden by RevDel_ArchivedFileItem.
508569 */
509570 protected function getLink() {
510 - $date = $this->getLang()->timeanddate( $this->file->getTimestamp(), true );
 571+ $date = $this->list->getLang()->timeanddate( $this->file->getTimestamp(), true );
511572 if ( $this->isDeleted() ) {
512573 # Hidden files...
513574 if ( !$this->canViewContent() ) {
@@ -518,7 +579,8 @@
519580 array(
520581 'target' => $this->list->title->getPrefixedText(),
521582 'file' => $this->file->getArchiveName(),
522 - 'token' => $this->getUser()->editToken( $this->file->getArchiveName() )
 583+ 'token' => $this->list->getUser()->editToken(
 584+ $this->file->getArchiveName() )
523585 )
524586 );
525587 }
@@ -567,11 +629,11 @@
568630 $data =
569631 wfMsg(
570632 '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() )
573635 ) .
574636 ' (' .
575 - wfMsgExt( 'nbytes', 'parsemag', $this->getLang()->formatNum( $this->file->getSize() ) ) .
 637+ wfMsgExt( 'nbytes', 'parsemag', $this->list->getLang()->formatNum( $this->file->getSize() ) ) .
576638 ')';
577639
578640 return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' .
@@ -583,12 +645,14 @@
584646 * List for filearchive table items
585647 */
586648 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+ }
592652
 653+ public static function getRelationType() {
 654+ return 'fa_id';
 655+ }
 656+
593657 /**
594658 * @param $db DatabaseBase
595659 * @return mixed
@@ -619,6 +683,22 @@
620684 $this->file = ArchivedFile::newFromRow( $row );
621685 }
622686
 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+
623703 public function getId() {
624704 return $this->row->fa_id;
625705 }
@@ -637,7 +717,7 @@
638718 }
639719
640720 protected function getLink() {
641 - $date = $this->getLang()->timeanddate( $this->file->getTimestamp(), true );
 721+ $date = $this->list->getLang()->timeanddate( $this->file->getTimestamp(), true );
642722 $undelete = SpecialPage::getTitleFor( 'Undelete' );
643723 $key = $this->file->getKey();
644724 # Hidden files...
@@ -648,7 +728,7 @@
649729 array(
650730 'target' => $this->list->title->getPrefixedText(),
651731 'file' => $key,
652 - 'token' => $this->getUser()->editToken( $key )
 732+ 'token' => $this->list->getUser()->editToken( $key )
653733 )
654734 );
655735 }
@@ -663,12 +743,14 @@
664744 * List for logging table items
665745 */
666746 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+ }
672750
 751+ public static function getRelationType() {
 752+ return 'log_id';
 753+ }
 754+
673755 /**
674756 * @param $db DatabaseBase
675757 * @return mixed
@@ -707,6 +789,22 @@
708790 * Item class for a logging table row
709791 */
710792 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+
711809 public function canView() {
712810 return LogEventsList::userCan( $this->row, Revision::DELETED_RESTRICTED );
713811 }
@@ -744,7 +842,7 @@
745843 }
746844
747845 public function getHTML() {
748 - $date = htmlspecialchars( $this->getLang()->timeanddate( $this->row->log_timestamp ) );
 846+ $date = htmlspecialchars( $this->list->getLang()->timeanddate( $this->row->log_timestamp ) );
749847 $paramArray = LogPage::extractParams( $this->row->log_params );
750848 $title = Title::makeTitle( $this->row->log_namespace, $this->row->log_title );
751849
@@ -771,7 +869,7 @@
772870 $userLink = '<span class="history-deleted">' . $userLink . '</span>';
773871 }
774872 // Comment
775 - $comment = $this->getLang()->getDirMark() . Linker::commentBlock( $this->row->log_comment );
 873+ $comment = $this->list->getLang()->getDirMark() . Linker::commentBlock( $this->row->log_comment );
776874 if( LogEventsList::isDeleted($this->row,LogPage::DELETED_COMMENT) ) {
777875 $comment = '<span class="history-deleted">' . $comment . '</span>';
778876 }
Index: trunk/phase3/includes/revisiondelete/RevisionDeleter.php
@@ -119,8 +119,7 @@
120120 }
121121 if ( isset( SpecialRevisionDelete::$allowedTypes[$typeName] ) ) {
122122 $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' ) );
125124 } else {
126125 return null;
127126 }
Index: trunk/phase3/includes/revisiondelete/RevisionDeleteAbstracts.php
@@ -6,66 +6,17 @@
77 * relevant rows, to return RevDel_Item subclasses wrapping them, and
88 * to wrap bulk update operations.
99 */
10 -abstract class RevDel_List {
11 -
 10+abstract class RevDel_List extends Rev_List {
1211 /**
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.
1415 */
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;
3318 }
3419
3520 /**
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 - /**
7021 * Set the visibility for the revisions in this list. Logging and
7122 * transactions are done here.
7223 *
@@ -253,59 +204,6 @@
254205 }
255206
256207 /**
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 - /**
310208 * Clear any data structures needed for doPreCommitUpdates() and doPostCommitUpdates()
311209 * STUB
312210 */
@@ -331,36 +229,6 @@
332230 }
333231
334232 /**
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 - /**
365233 * Get the integer value of the flag used for suppression
366234 */
367235 abstract public function getSuppressBit();
@@ -369,75 +237,8 @@
370238 /**
371239 * Abstract base class for deletable items
372240 */
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 {
383242 /**
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 - /**
442243 * Returns true if the item is "current", and the operation to set the given
443244 * bits can't be executed for that reason
444245 * STUB
@@ -447,45 +248,11 @@
448249 }
449250
450251 /**
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 - /**
479252 * Get the current deletion bitfield value
480253 */
481254 abstract public function getBits();
482255
483256 /**
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 - /**
490257 * Set the visibility of the item. This should do any necessary DB queries.
491258 *
492259 * The DB update query should have a condition which forces it to only update
Index: trunk/phase3/includes/AutoLoader.php
@@ -187,7 +187,10 @@
188188 'Replacer' => 'includes/StringUtils.php',
189189 'RequestContext' => 'includes/RequestContext.php',
190190 'ReverseChronologicalPager' => 'includes/Pager.php',
 191+ 'Rev_Item' => 'includes/RevisionList.php',
 192+ 'Rev_List' => 'includes/RevisionList.php',
191193 'Revision' => 'includes/Revision.php',
 194+ 'RevisionList' => 'includes/RevisionList.php',
192195 'RSSFeed' => 'includes/Feed.php',
193196 'Sanitizer' => 'includes/Sanitizer.php',
194197 'SiteConfiguration' => 'includes/SiteConfiguration.php',
Index: trunk/phase3/includes/specials/SpecialRevisiondelete.php
@@ -61,39 +61,39 @@
6262 */
6363 static $allowedTypes = array(
6464 'revision' => array(
65 - 'check-label' => 'revdelete-hide-text',
 65+ 'check-label' => 'revdelete-hide-text',
6666 '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',
7070 ),
7171 'archive' => array(
72 - 'check-label' => 'revdelete-hide-text',
 72+ 'check-label' => 'revdelete-hide-text',
7373 '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',
7777 ),
7878 'oldimage'=> array(
79 - 'check-label' => 'revdelete-hide-image',
 79+ 'check-label' => 'revdelete-hide-image',
8080 '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',
8484 ),
8585 'filearchive' => array(
86 - 'check-label' => 'revdelete-hide-image',
 86+ 'check-label' => 'revdelete-hide-image',
8787 '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',
9191 ),
9292 'logging' => array(
93 - 'check-label' => 'revdelete-hide-name',
 93+ 'check-label' => 'revdelete-hide-name',
9494 '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',
9898 ),
9999 );
100100
@@ -258,7 +258,7 @@
259259 protected function getLogQueryCond() {
260260 $conds = array();
261261 // Revision delete logs for these item
262 - $conds['log_type'] = array('delete','suppress');
 262+ $conds['log_type'] = array( 'delete', 'suppress' );
263263 $conds['log_action'] = $this->getList()->getLogAction();
264264 $conds['ls_field'] = RevisionDeleter::getRelationType( $this->typeName );
265265 $conds['ls_value'] = $this->ids;
@@ -328,7 +328,7 @@
329329 protected function getList() {
330330 if ( is_null( $this->list ) ) {
331331 $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 );
333333 }
334334 return $this->list;
335335 }
@@ -506,7 +506,8 @@
507507 */
508508 protected function submit() {
509509 # 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 ) ) {
511512 $this->getOutput()->addWikiMsg( 'sessionfailure' );
512513 return false;
513514 }
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
1356 + native

Follow-up revisions

RevisionCommit summaryAuthorDate
r91345Made FlaggedRevs use new RevisionList class (r91344) instead of revdelete hackaaron09:05, 2 July 2011
r91359Fix for r91344: removed straggling instances of $this->special in item classesaaron17:27, 2 July 2011
r96697Renamed Rev_List/Rev_Item classes to RevisionListBase/RevisionItemBaseaaron21:25, 9 September 2011

Past revisions this follows-up on

RevisionCommit summaryAuthorDate
r87804* (bug 21279) Special:RevisionDelete now uses revision ID for deleted-page re...brion01:11, 10 May 2011

Comments

#Comment by Siebrand (talk | contribs)   17:13, 2 July 2011

Seeing the the underscores in the class names looked odd to me, but checking autoloader.php I see that it is used more often. I think that the class names RevisionList and Rev_List may be confusing. Anything you can see that can be done to prevent that?

#Comment by Aaron Schulz (talk | contribs)   17:14, 2 July 2011

I thought about calling RevisionList "LiveRevisionList". Not sure...

Status & tagging log