MediaWiki
REL1_21
|
00001 <?php 00033 class RevDel_RevisionList extends RevDel_List { 00034 var $currentRevId; 00035 00036 public function getType() { 00037 return 'revision'; 00038 } 00039 00040 public static function getRelationType() { 00041 return 'rev_id'; 00042 } 00043 00048 public function doQuery( $db ) { 00049 $ids = array_map( 'intval', $this->ids ); 00050 $live = $db->select( 00051 array( 'revision', 'page', 'user' ), 00052 array_merge( Revision::selectFields(), Revision::selectUserFields() ), 00053 array( 00054 'rev_page' => $this->title->getArticleID(), 00055 'rev_id' => $ids, 00056 ), 00057 __METHOD__, 00058 array( 'ORDER BY' => 'rev_id DESC' ), 00059 array( 00060 'page' => Revision::pageJoinCond(), 00061 'user' => Revision::userJoinCond() ) 00062 ); 00063 00064 if ( $live->numRows() >= count( $ids ) ) { 00065 // All requested revisions are live, keeps things simple! 00066 return $live; 00067 } 00068 00069 // Check if any requested revisions are available fully deleted. 00070 $archived = $db->select( array( 'archive' ), '*', 00071 array( 00072 'ar_rev_id' => $ids 00073 ), 00074 __METHOD__, 00075 array( 'ORDER BY' => 'ar_rev_id DESC' ) 00076 ); 00077 00078 if ( $archived->numRows() == 0 ) { 00079 return $live; 00080 } elseif ( $live->numRows() == 0 ) { 00081 return $archived; 00082 } else { 00083 // Combine the two! Whee 00084 $rows = array(); 00085 foreach ( $live as $row ) { 00086 $rows[$row->rev_id] = $row; 00087 } 00088 foreach ( $archived as $row ) { 00089 $rows[$row->ar_rev_id] = $row; 00090 } 00091 krsort( $rows ); 00092 return new FakeResultWrapper( array_values( $rows ) ); 00093 } 00094 } 00095 00096 public function newItem( $row ) { 00097 if ( isset( $row->rev_id ) ) { 00098 return new RevDel_RevisionItem( $this, $row ); 00099 } elseif ( isset( $row->ar_rev_id ) ) { 00100 return new RevDel_ArchivedRevisionItem( $this, $row ); 00101 } else { 00102 // This shouldn't happen. :) 00103 throw new MWException( 'Invalid row type in RevDel_RevisionList' ); 00104 } 00105 } 00106 00107 public function getCurrent() { 00108 if ( is_null( $this->currentRevId ) ) { 00109 $dbw = wfGetDB( DB_MASTER ); 00110 $this->currentRevId = $dbw->selectField( 00111 'page', 'page_latest', $this->title->pageCond(), __METHOD__ ); 00112 } 00113 return $this->currentRevId; 00114 } 00115 00116 public function getSuppressBit() { 00117 return Revision::DELETED_RESTRICTED; 00118 } 00119 00120 public function doPreCommitUpdates() { 00121 $this->title->invalidateCache(); 00122 return Status::newGood(); 00123 } 00124 00125 public function doPostCommitUpdates() { 00126 $this->title->purgeSquid(); 00127 // Extensions that require referencing previous revisions may need this 00128 wfRunHooks( 'ArticleRevisionVisibilitySet', array( &$this->title ) ); 00129 return Status::newGood(); 00130 } 00131 } 00132 00136 class RevDel_RevisionItem extends RevDel_Item { 00137 var $revision; 00138 00139 public function __construct( $list, $row ) { 00140 parent::__construct( $list, $row ); 00141 $this->revision = new Revision( $row ); 00142 } 00143 00144 public function getIdField() { 00145 return 'rev_id'; 00146 } 00147 00148 public function getTimestampField() { 00149 return 'rev_timestamp'; 00150 } 00151 00152 public function getAuthorIdField() { 00153 return 'rev_user'; 00154 } 00155 00156 public function getAuthorNameField() { 00157 return 'user_name'; // see Revision::selectUserFields() 00158 } 00159 00160 public function canView() { 00161 return $this->revision->userCan( Revision::DELETED_RESTRICTED, $this->list->getUser() ); 00162 } 00163 00164 public function canViewContent() { 00165 return $this->revision->userCan( Revision::DELETED_TEXT, $this->list->getUser() ); 00166 } 00167 00168 public function getBits() { 00169 return $this->revision->getVisibility(); 00170 } 00171 00172 public function setBits( $bits ) { 00173 $dbw = wfGetDB( DB_MASTER ); 00174 // Update revision table 00175 $dbw->update( 'revision', 00176 array( 'rev_deleted' => $bits ), 00177 array( 00178 'rev_id' => $this->revision->getId(), 00179 'rev_page' => $this->revision->getPage(), 00180 'rev_deleted' => $this->getBits() 00181 ), 00182 __METHOD__ 00183 ); 00184 if ( !$dbw->affectedRows() ) { 00185 // Concurrent fail! 00186 return false; 00187 } 00188 // Update recentchanges table 00189 $dbw->update( 'recentchanges', 00190 array( 00191 'rc_deleted' => $bits, 00192 'rc_patrolled' => 1 00193 ), 00194 array( 00195 'rc_this_oldid' => $this->revision->getId(), // condition 00196 // non-unique timestamp index 00197 'rc_timestamp' => $dbw->timestamp( $this->revision->getTimestamp() ), 00198 ), 00199 __METHOD__ 00200 ); 00201 return true; 00202 } 00203 00204 public function isDeleted() { 00205 return $this->revision->isDeleted( Revision::DELETED_TEXT ); 00206 } 00207 00208 public function isHideCurrentOp( $newBits ) { 00209 return ( $newBits & Revision::DELETED_TEXT ) 00210 && $this->list->getCurrent() == $this->getId(); 00211 } 00212 00218 protected function getRevisionLink() { 00219 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00220 $this->revision->getTimestamp(), $this->list->getUser() ) ); 00221 00222 if ( $this->isDeleted() && !$this->canViewContent() ) { 00223 return $date; 00224 } 00225 return Linker::linkKnown( 00226 $this->list->title, 00227 $date, 00228 array(), 00229 array( 00230 'oldid' => $this->revision->getId(), 00231 'unhide' => 1 00232 ) 00233 ); 00234 } 00235 00241 protected function getDiffLink() { 00242 if ( $this->isDeleted() && !$this->canViewContent() ) { 00243 return $this->list->msg( 'diff' )->escaped(); 00244 } else { 00245 return 00246 Linker::linkKnown( 00247 $this->list->title, 00248 $this->list->msg( 'diff' )->escaped(), 00249 array(), 00250 array( 00251 'diff' => $this->revision->getId(), 00252 'oldid' => 'prev', 00253 'unhide' => 1 00254 ) 00255 ); 00256 } 00257 } 00258 00259 public function getHTML() { 00260 $difflink = $this->list->msg( 'parentheses' ) 00261 ->rawParams( $this->getDiffLink() )->escaped(); 00262 $revlink = $this->getRevisionLink(); 00263 $userlink = Linker::revUserLink( $this->revision ); 00264 $comment = Linker::revComment( $this->revision ); 00265 if ( $this->isDeleted() ) { 00266 $revlink = "<span class=\"history-deleted\">$revlink</span>"; 00267 } 00268 return "<li>$difflink $revlink $userlink $comment</li>"; 00269 } 00270 } 00271 00275 class RevDel_ArchiveList extends RevDel_RevisionList { 00276 public function getType() { 00277 return 'archive'; 00278 } 00279 00280 public static function getRelationType() { 00281 return 'ar_timestamp'; 00282 } 00283 00288 public function doQuery( $db ) { 00289 $timestamps = array(); 00290 foreach ( $this->ids as $id ) { 00291 $timestamps[] = $db->timestamp( $id ); 00292 } 00293 return $db->select( 'archive', '*', 00294 array( 00295 'ar_namespace' => $this->title->getNamespace(), 00296 'ar_title' => $this->title->getDBkey(), 00297 'ar_timestamp' => $timestamps 00298 ), 00299 __METHOD__, 00300 array( 'ORDER BY' => 'ar_timestamp DESC' ) 00301 ); 00302 } 00303 00304 public function newItem( $row ) { 00305 return new RevDel_ArchiveItem( $this, $row ); 00306 } 00307 00308 public function doPreCommitUpdates() { 00309 return Status::newGood(); 00310 } 00311 00312 public function doPostCommitUpdates() { 00313 return Status::newGood(); 00314 } 00315 } 00316 00320 class RevDel_ArchiveItem extends RevDel_RevisionItem { 00321 public function __construct( $list, $row ) { 00322 RevDel_Item::__construct( $list, $row ); 00323 $this->revision = Revision::newFromArchiveRow( $row, 00324 array( 'page' => $this->list->title->getArticleID() ) ); 00325 } 00326 00327 public function getIdField() { 00328 return 'ar_timestamp'; 00329 } 00330 00331 public function getTimestampField() { 00332 return 'ar_timestamp'; 00333 } 00334 00335 public function getAuthorIdField() { 00336 return 'ar_user'; 00337 } 00338 00339 public function getAuthorNameField() { 00340 return 'ar_user_text'; 00341 } 00342 00343 public function getId() { 00344 # Convert DB timestamp to MW timestamp 00345 return $this->revision->getTimestamp(); 00346 } 00347 00348 public function setBits( $bits ) { 00349 $dbw = wfGetDB( DB_MASTER ); 00350 $dbw->update( 'archive', 00351 array( 'ar_deleted' => $bits ), 00352 array( 00353 'ar_namespace' => $this->list->title->getNamespace(), 00354 'ar_title' => $this->list->title->getDBkey(), 00355 // use timestamp for index 00356 'ar_timestamp' => $this->row->ar_timestamp, 00357 'ar_rev_id' => $this->row->ar_rev_id, 00358 'ar_deleted' => $this->getBits() 00359 ), 00360 __METHOD__ ); 00361 return (bool)$dbw->affectedRows(); 00362 } 00363 00364 protected function getRevisionLink() { 00365 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00366 $this->revision->getTimestamp(), $this->list->getUser() ) ); 00367 00368 if ( $this->isDeleted() && !$this->canViewContent() ) { 00369 return $date; 00370 } 00371 00372 return Linker::link( 00373 SpecialPage::getTitleFor( 'Undelete' ), 00374 $date, 00375 array(), 00376 array( 00377 'target' => $this->list->title->getPrefixedText(), 00378 'timestamp' => $this->revision->getTimestamp() 00379 ) 00380 ); 00381 } 00382 00383 protected function getDiffLink() { 00384 if ( $this->isDeleted() && !$this->canViewContent() ) { 00385 return $this->list->msg( 'diff' )->escaped(); 00386 } 00387 00388 return Linker::link( 00389 SpecialPage::getTitleFor( 'Undelete' ), 00390 $this->list->msg( 'diff' )->escaped(), 00391 array(), 00392 array( 00393 'target' => $this->list->title->getPrefixedText(), 00394 'diff' => 'prev', 00395 'timestamp' => $this->revision->getTimestamp() 00396 ) 00397 ); 00398 } 00399 } 00400 00405 class RevDel_ArchivedRevisionItem extends RevDel_ArchiveItem { 00406 public function __construct( $list, $row ) { 00407 RevDel_Item::__construct( $list, $row ); 00408 00409 $this->revision = Revision::newFromArchiveRow( $row, 00410 array( 'page' => $this->list->title->getArticleID() ) ); 00411 } 00412 00413 public function getIdField() { 00414 return 'ar_rev_id'; 00415 } 00416 00417 public function getId() { 00418 return $this->revision->getId(); 00419 } 00420 00421 public function setBits( $bits ) { 00422 $dbw = wfGetDB( DB_MASTER ); 00423 $dbw->update( 'archive', 00424 array( 'ar_deleted' => $bits ), 00425 array( 'ar_rev_id' => $this->row->ar_rev_id, 00426 'ar_deleted' => $this->getBits() 00427 ), 00428 __METHOD__ ); 00429 return (bool)$dbw->affectedRows(); 00430 } 00431 } 00432 00436 class RevDel_FileList extends RevDel_List { 00437 public function getType() { 00438 return 'oldimage'; 00439 } 00440 00441 public static function getRelationType() { 00442 return 'oi_archive_name'; 00443 } 00444 00445 var $storeBatch, $deleteBatch, $cleanupBatch; 00446 00451 public function doQuery( $db ) { 00452 $archiveNames = array(); 00453 foreach( $this->ids as $timestamp ) { 00454 $archiveNames[] = $timestamp . '!' . $this->title->getDBkey(); 00455 } 00456 return $db->select( 00457 'oldimage', 00458 OldLocalFile::selectFields(), 00459 array( 00460 'oi_name' => $this->title->getDBkey(), 00461 'oi_archive_name' => $archiveNames 00462 ), 00463 __METHOD__, 00464 array( 'ORDER BY' => 'oi_timestamp DESC' ) 00465 ); 00466 } 00467 00468 public function newItem( $row ) { 00469 return new RevDel_FileItem( $this, $row ); 00470 } 00471 00472 public function clearFileOps() { 00473 $this->deleteBatch = array(); 00474 $this->storeBatch = array(); 00475 $this->cleanupBatch = array(); 00476 } 00477 00478 public function doPreCommitUpdates() { 00479 $status = Status::newGood(); 00480 $repo = RepoGroup::singleton()->getLocalRepo(); 00481 if ( $this->storeBatch ) { 00482 $status->merge( $repo->storeBatch( $this->storeBatch, FileRepo::OVERWRITE_SAME ) ); 00483 } 00484 if ( !$status->isOK() ) { 00485 return $status; 00486 } 00487 if ( $this->deleteBatch ) { 00488 $status->merge( $repo->deleteBatch( $this->deleteBatch ) ); 00489 } 00490 if ( !$status->isOK() ) { 00491 // Running cleanupDeletedBatch() after a failed storeBatch() with the DB already 00492 // modified (but destined for rollback) causes data loss 00493 return $status; 00494 } 00495 if ( $this->cleanupBatch ) { 00496 $status->merge( $repo->cleanupDeletedBatch( $this->cleanupBatch ) ); 00497 } 00498 return $status; 00499 } 00500 00501 public function doPostCommitUpdates() { 00502 global $wgUseSquid; 00503 $file = wfLocalFile( $this->title ); 00504 $file->purgeCache(); 00505 $file->purgeDescription(); 00506 $purgeUrls = array(); 00507 foreach ( $this->ids as $timestamp ) { 00508 $archiveName = $timestamp . '!' . $this->title->getDBkey(); 00509 $file->purgeOldThumbnails( $archiveName ); 00510 $purgeUrls[] = $file->getArchiveUrl( $archiveName ); 00511 } 00512 if ( $wgUseSquid ) { 00513 // purge full images from cache 00514 SquidUpdate::purge( $purgeUrls ); 00515 } 00516 return Status::newGood(); 00517 } 00518 00519 public function getSuppressBit() { 00520 return File::DELETED_RESTRICTED; 00521 } 00522 } 00523 00527 class RevDel_FileItem extends RevDel_Item { 00528 00532 var $file; 00533 00534 public function __construct( $list, $row ) { 00535 parent::__construct( $list, $row ); 00536 $this->file = RepoGroup::singleton()->getLocalRepo()->newFileFromRow( $row ); 00537 } 00538 00539 public function getIdField() { 00540 return 'oi_archive_name'; 00541 } 00542 00543 public function getTimestampField() { 00544 return 'oi_timestamp'; 00545 } 00546 00547 public function getAuthorIdField() { 00548 return 'oi_user'; 00549 } 00550 00551 public function getAuthorNameField() { 00552 return 'oi_user_text'; 00553 } 00554 00555 public function getId() { 00556 $parts = explode( '!', $this->row->oi_archive_name ); 00557 return $parts[0]; 00558 } 00559 00560 public function canView() { 00561 return $this->file->userCan( File::DELETED_RESTRICTED, $this->list->getUser() ); 00562 } 00563 00564 public function canViewContent() { 00565 return $this->file->userCan( File::DELETED_FILE, $this->list->getUser() ); 00566 } 00567 00568 public function getBits() { 00569 return $this->file->getVisibility(); 00570 } 00571 00572 public function setBits( $bits ) { 00573 # Queue the file op 00574 # @todo FIXME: Move to LocalFile.php 00575 if ( $this->isDeleted() ) { 00576 if ( $bits & File::DELETED_FILE ) { 00577 # Still deleted 00578 } else { 00579 # Newly undeleted 00580 $key = $this->file->getStorageKey(); 00581 $srcRel = $this->file->repo->getDeletedHashPath( $key ) . $key; 00582 $this->list->storeBatch[] = array( 00583 $this->file->repo->getVirtualUrl( 'deleted' ) . '/' . $srcRel, 00584 'public', 00585 $this->file->getRel() 00586 ); 00587 $this->list->cleanupBatch[] = $key; 00588 } 00589 } elseif ( $bits & File::DELETED_FILE ) { 00590 # Newly deleted 00591 $key = $this->file->getStorageKey(); 00592 $dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key; 00593 $this->list->deleteBatch[] = array( $this->file->getRel(), $dstRel ); 00594 } 00595 00596 # Do the database operations 00597 $dbw = wfGetDB( DB_MASTER ); 00598 $dbw->update( 'oldimage', 00599 array( 'oi_deleted' => $bits ), 00600 array( 00601 'oi_name' => $this->row->oi_name, 00602 'oi_timestamp' => $this->row->oi_timestamp, 00603 'oi_deleted' => $this->getBits() 00604 ), 00605 __METHOD__ 00606 ); 00607 return (bool)$dbw->affectedRows(); 00608 } 00609 00610 public function isDeleted() { 00611 return $this->file->isDeleted( File::DELETED_FILE ); 00612 } 00613 00619 protected function getLink() { 00620 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00621 $this->file->getTimestamp(), $this->list->getUser() ) ); 00622 00623 if ( !$this->isDeleted() ) { 00624 # Regular files... 00625 return Html::rawElement( 'a', array( 'href' => $this->file->getUrl() ), $date ); 00626 } 00627 00628 # Hidden files... 00629 if ( !$this->canViewContent() ) { 00630 $link = $date; 00631 } else { 00632 $link = Linker::link( 00633 SpecialPage::getTitleFor( 'Revisiondelete' ), 00634 $date, 00635 array(), 00636 array( 00637 'target' => $this->list->title->getPrefixedText(), 00638 'file' => $this->file->getArchiveName(), 00639 'token' => $this->list->getUser()->getEditToken( 00640 $this->file->getArchiveName() ) 00641 ) 00642 ); 00643 } 00644 return '<span class="history-deleted">' . $link . '</span>'; 00645 } 00650 protected function getUserTools() { 00651 if( $this->file->userCan( Revision::DELETED_USER, $this->list->getUser() ) ) { 00652 $link = Linker::userLink( $this->file->user, $this->file->user_text ) . 00653 Linker::userToolLinks( $this->file->user, $this->file->user_text ); 00654 } else { 00655 $link = $this->list->msg( 'rev-deleted-user' )->escaped(); 00656 } 00657 if( $this->file->isDeleted( Revision::DELETED_USER ) ) { 00658 return '<span class="history-deleted">' . $link . '</span>'; 00659 } 00660 return $link; 00661 } 00662 00669 protected function getComment() { 00670 if( $this->file->userCan( File::DELETED_COMMENT, $this->list->getUser() ) ) { 00671 $block = Linker::commentBlock( $this->file->description ); 00672 } else { 00673 $block = ' ' . $this->list->msg( 'rev-deleted-comment' )->escaped(); 00674 } 00675 if( $this->file->isDeleted( File::DELETED_COMMENT ) ) { 00676 return "<span class=\"history-deleted\">$block</span>"; 00677 } 00678 return $block; 00679 } 00680 00681 public function getHTML() { 00682 $data = 00683 $this->list->msg( 'widthheight' )->numParams( 00684 $this->file->getWidth(), $this->file->getHeight() )->text() . 00685 ' (' . $this->list->msg( 'nbytes' )->numParams( $this->file->getSize() )->text() . ')'; 00686 00687 return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' . 00688 $data . ' ' . $this->getComment(). '</li>'; 00689 } 00690 } 00691 00695 class RevDel_ArchivedFileList extends RevDel_FileList { 00696 public function getType() { 00697 return 'filearchive'; 00698 } 00699 00700 public static function getRelationType() { 00701 return 'fa_id'; 00702 } 00703 00708 public function doQuery( $db ) { 00709 $ids = array_map( 'intval', $this->ids ); 00710 return $db->select( 00711 'filearchive', 00712 ArchivedFile::selectFields(), 00713 array( 00714 'fa_name' => $this->title->getDBkey(), 00715 'fa_id' => $ids 00716 ), 00717 __METHOD__, 00718 array( 'ORDER BY' => 'fa_id DESC' ) 00719 ); 00720 } 00721 00722 public function newItem( $row ) { 00723 return new RevDel_ArchivedFileItem( $this, $row ); 00724 } 00725 } 00726 00730 class RevDel_ArchivedFileItem extends RevDel_FileItem { 00731 public function __construct( $list, $row ) { 00732 RevDel_Item::__construct( $list, $row ); 00733 $this->file = ArchivedFile::newFromRow( $row ); 00734 } 00735 00736 public function getIdField() { 00737 return 'fa_id'; 00738 } 00739 00740 public function getTimestampField() { 00741 return 'fa_timestamp'; 00742 } 00743 00744 public function getAuthorIdField() { 00745 return 'fa_user'; 00746 } 00747 00748 public function getAuthorNameField() { 00749 return 'fa_user_text'; 00750 } 00751 00752 public function getId() { 00753 return $this->row->fa_id; 00754 } 00755 00756 public function setBits( $bits ) { 00757 $dbw = wfGetDB( DB_MASTER ); 00758 $dbw->update( 'filearchive', 00759 array( 'fa_deleted' => $bits ), 00760 array( 00761 'fa_id' => $this->row->fa_id, 00762 'fa_deleted' => $this->getBits(), 00763 ), 00764 __METHOD__ 00765 ); 00766 return (bool)$dbw->affectedRows(); 00767 } 00768 00769 protected function getLink() { 00770 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00771 $this->file->getTimestamp(), $this->list->getUser() ) ); 00772 00773 # Hidden files... 00774 if( !$this->canViewContent() ) { 00775 $link = $date; 00776 } else { 00777 $undelete = SpecialPage::getTitleFor( 'Undelete' ); 00778 $key = $this->file->getKey(); 00779 $link = Linker::link( $undelete, $date, array(), 00780 array( 00781 'target' => $this->list->title->getPrefixedText(), 00782 'file' => $key, 00783 'token' => $this->list->getUser()->getEditToken( $key ) 00784 ) 00785 ); 00786 } 00787 if( $this->isDeleted() ) { 00788 $link = '<span class="history-deleted">' . $link . '</span>'; 00789 } 00790 return $link; 00791 } 00792 } 00793 00797 class RevDel_LogList extends RevDel_List { 00798 public function getType() { 00799 return 'logging'; 00800 } 00801 00802 public static function getRelationType() { 00803 return 'log_id'; 00804 } 00805 00810 public function doQuery( $db ) { 00811 $ids = array_map( 'intval', $this->ids ); 00812 return $db->select( 'logging', '*', 00813 array( 'log_id' => $ids ), 00814 __METHOD__, 00815 array( 'ORDER BY' => 'log_id DESC' ) 00816 ); 00817 } 00818 00819 public function newItem( $row ) { 00820 return new RevDel_LogItem( $this, $row ); 00821 } 00822 00823 public function getSuppressBit() { 00824 return Revision::DELETED_RESTRICTED; 00825 } 00826 00827 public function getLogAction() { 00828 return 'event'; 00829 } 00830 00831 public function getLogParams( $params ) { 00832 return array( 00833 implode( ',', $params['ids'] ), 00834 "ofield={$params['oldBits']}", 00835 "nfield={$params['newBits']}" 00836 ); 00837 } 00838 } 00839 00843 class RevDel_LogItem extends RevDel_Item { 00844 public function getIdField() { 00845 return 'log_id'; 00846 } 00847 00848 public function getTimestampField() { 00849 return 'log_timestamp'; 00850 } 00851 00852 public function getAuthorIdField() { 00853 return 'log_user'; 00854 } 00855 00856 public function getAuthorNameField() { 00857 return 'log_user_text'; 00858 } 00859 00860 public function canView() { 00861 return LogEventsList::userCan( $this->row, Revision::DELETED_RESTRICTED, $this->list->getUser() ); 00862 } 00863 00864 public function canViewContent() { 00865 return true; // none 00866 } 00867 00868 public function getBits() { 00869 return $this->row->log_deleted; 00870 } 00871 00872 public function setBits( $bits ) { 00873 $dbw = wfGetDB( DB_MASTER ); 00874 $dbw->update( 'recentchanges', 00875 array( 00876 'rc_deleted' => $bits, 00877 'rc_patrolled' => 1 00878 ), 00879 array( 00880 'rc_logid' => $this->row->log_id, 00881 'rc_timestamp' => $this->row->log_timestamp // index 00882 ), 00883 __METHOD__ 00884 ); 00885 $dbw->update( 'logging', 00886 array( 'log_deleted' => $bits ), 00887 array( 00888 'log_id' => $this->row->log_id, 00889 'log_deleted' => $this->getBits() 00890 ), 00891 __METHOD__ 00892 ); 00893 return (bool)$dbw->affectedRows(); 00894 } 00895 00896 public function getHTML() { 00897 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00898 $this->row->log_timestamp, $this->list->getUser() ) ); 00899 $title = Title::makeTitle( $this->row->log_namespace, $this->row->log_title ); 00900 $formatter = LogFormatter::newFromRow( $this->row ); 00901 $formatter->setContext( $this->list->getContext() ); 00902 $formatter->setAudience( LogFormatter::FOR_THIS_USER ); 00903 00904 // Log link for this page 00905 $loglink = Linker::link( 00906 SpecialPage::getTitleFor( 'Log' ), 00907 $this->list->msg( 'log' )->escaped(), 00908 array(), 00909 array( 'page' => $title->getPrefixedText() ) 00910 ); 00911 $loglink = $this->list->msg( 'parentheses' )->rawParams( $loglink )->escaped(); 00912 // User links and action text 00913 $action = $formatter->getActionText(); 00914 // Comment 00915 $comment = $this->list->getLanguage()->getDirMark() . Linker::commentBlock( $this->row->log_comment ); 00916 if( LogEventsList::isDeleted( $this->row, LogPage::DELETED_COMMENT ) ) { 00917 $comment = '<span class="history-deleted">' . $comment . '</span>'; 00918 } 00919 00920 return "<li>$loglink $date $action $comment</li>"; 00921 } 00922 }