MediaWiki
REL1_20
|
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 00401 00406 class RevDel_ArchivedRevisionItem extends RevDel_ArchiveItem { 00407 public function __construct( $list, $row ) { 00408 RevDel_Item::__construct( $list, $row ); 00409 00410 $this->revision = Revision::newFromArchiveRow( $row, 00411 array( 'page' => $this->list->title->getArticleID() ) ); 00412 } 00413 00414 public function getIdField() { 00415 return 'ar_rev_id'; 00416 } 00417 00418 public function getId() { 00419 return $this->revision->getId(); 00420 } 00421 00422 public function setBits( $bits ) { 00423 $dbw = wfGetDB( DB_MASTER ); 00424 $dbw->update( 'archive', 00425 array( 'ar_deleted' => $bits ), 00426 array( 'ar_rev_id' => $this->row->ar_rev_id, 00427 'ar_deleted' => $this->getBits() 00428 ), 00429 __METHOD__ ); 00430 return (bool)$dbw->affectedRows(); 00431 } 00432 } 00433 00437 class RevDel_FileList extends RevDel_List { 00438 public function getType() { 00439 return 'oldimage'; 00440 } 00441 00442 public static function getRelationType() { 00443 return 'oi_archive_name'; 00444 } 00445 00446 var $storeBatch, $deleteBatch, $cleanupBatch; 00447 00452 public function doQuery( $db ) { 00453 $archiveNames = array(); 00454 foreach( $this->ids as $timestamp ) { 00455 $archiveNames[] = $timestamp . '!' . $this->title->getDBkey(); 00456 } 00457 return $db->select( 'oldimage', '*', 00458 array( 00459 'oi_name' => $this->title->getDBkey(), 00460 'oi_archive_name' => $archiveNames 00461 ), 00462 __METHOD__, 00463 array( 'ORDER BY' => 'oi_timestamp DESC' ) 00464 ); 00465 } 00466 00467 public function newItem( $row ) { 00468 return new RevDel_FileItem( $this, $row ); 00469 } 00470 00471 public function clearFileOps() { 00472 $this->deleteBatch = array(); 00473 $this->storeBatch = array(); 00474 $this->cleanupBatch = array(); 00475 } 00476 00477 public function doPreCommitUpdates() { 00478 $status = Status::newGood(); 00479 $repo = RepoGroup::singleton()->getLocalRepo(); 00480 if ( $this->storeBatch ) { 00481 $status->merge( $repo->storeBatch( $this->storeBatch, FileRepo::OVERWRITE_SAME ) ); 00482 } 00483 if ( !$status->isOK() ) { 00484 return $status; 00485 } 00486 if ( $this->deleteBatch ) { 00487 $status->merge( $repo->deleteBatch( $this->deleteBatch ) ); 00488 } 00489 if ( !$status->isOK() ) { 00490 // Running cleanupDeletedBatch() after a failed storeBatch() with the DB already 00491 // modified (but destined for rollback) causes data loss 00492 return $status; 00493 } 00494 if ( $this->cleanupBatch ) { 00495 $status->merge( $repo->cleanupDeletedBatch( $this->cleanupBatch ) ); 00496 } 00497 return $status; 00498 } 00499 00500 public function doPostCommitUpdates() { 00501 global $wgUseSquid; 00502 $file = wfLocalFile( $this->title ); 00503 $file->purgeCache(); 00504 $file->purgeDescription(); 00505 $purgeUrls = array(); 00506 foreach ( $this->ids as $timestamp ) { 00507 $archiveName = $timestamp . '!' . $this->title->getDBkey(); 00508 $file->purgeOldThumbnails( $archiveName ); 00509 $purgeUrls[] = $file->getArchiveUrl( $archiveName ); 00510 } 00511 if ( $wgUseSquid ) { 00512 // purge full images from cache 00513 SquidUpdate::purge( $purgeUrls ); 00514 } 00515 return Status::newGood(); 00516 } 00517 00518 public function getSuppressBit() { 00519 return File::DELETED_RESTRICTED; 00520 } 00521 } 00522 00526 class RevDel_FileItem extends RevDel_Item { 00527 00531 var $file; 00532 00533 public function __construct( $list, $row ) { 00534 parent::__construct( $list, $row ); 00535 $this->file = RepoGroup::singleton()->getLocalRepo()->newFileFromRow( $row ); 00536 } 00537 00538 public function getIdField() { 00539 return 'oi_archive_name'; 00540 } 00541 00542 public function getTimestampField() { 00543 return 'oi_timestamp'; 00544 } 00545 00546 public function getAuthorIdField() { 00547 return 'oi_user'; 00548 } 00549 00550 public function getAuthorNameField() { 00551 return 'oi_user_text'; 00552 } 00553 00554 public function getId() { 00555 $parts = explode( '!', $this->row->oi_archive_name ); 00556 return $parts[0]; 00557 } 00558 00559 public function canView() { 00560 return $this->file->userCan( File::DELETED_RESTRICTED, $this->list->getUser() ); 00561 } 00562 00563 public function canViewContent() { 00564 return $this->file->userCan( File::DELETED_FILE, $this->list->getUser() ); 00565 } 00566 00567 public function getBits() { 00568 return $this->file->getVisibility(); 00569 } 00570 00571 public function setBits( $bits ) { 00572 # Queue the file op 00573 # @todo FIXME: Move to LocalFile.php 00574 if ( $this->isDeleted() ) { 00575 if ( $bits & File::DELETED_FILE ) { 00576 # Still deleted 00577 } else { 00578 # Newly undeleted 00579 $key = $this->file->getStorageKey(); 00580 $srcRel = $this->file->repo->getDeletedHashPath( $key ) . $key; 00581 $this->list->storeBatch[] = array( 00582 $this->file->repo->getVirtualUrl( 'deleted' ) . '/' . $srcRel, 00583 'public', 00584 $this->file->getRel() 00585 ); 00586 $this->list->cleanupBatch[] = $key; 00587 } 00588 } elseif ( $bits & File::DELETED_FILE ) { 00589 # Newly deleted 00590 $key = $this->file->getStorageKey(); 00591 $dstRel = $this->file->repo->getDeletedHashPath( $key ) . $key; 00592 $this->list->deleteBatch[] = array( $this->file->getRel(), $dstRel ); 00593 } 00594 00595 # Do the database operations 00596 $dbw = wfGetDB( DB_MASTER ); 00597 $dbw->update( 'oldimage', 00598 array( 'oi_deleted' => $bits ), 00599 array( 00600 'oi_name' => $this->row->oi_name, 00601 'oi_timestamp' => $this->row->oi_timestamp, 00602 'oi_deleted' => $this->getBits() 00603 ), 00604 __METHOD__ 00605 ); 00606 return (bool)$dbw->affectedRows(); 00607 } 00608 00609 public function isDeleted() { 00610 return $this->file->isDeleted( File::DELETED_FILE ); 00611 } 00612 00618 protected function getLink() { 00619 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00620 $this->file->getTimestamp(), $this->list->getUser() ) ); 00621 00622 if ( !$this->isDeleted() ) { 00623 # Regular files... 00624 return Html::rawElement( 'a', array( 'href' => $this->file->getUrl() ), $date ); 00625 } 00626 00627 # Hidden files... 00628 if ( !$this->canViewContent() ) { 00629 $link = $date; 00630 } else { 00631 $link = Linker::link( 00632 SpecialPage::getTitleFor( 'Revisiondelete' ), 00633 $date, 00634 array(), 00635 array( 00636 'target' => $this->list->title->getPrefixedText(), 00637 'file' => $this->file->getArchiveName(), 00638 'token' => $this->list->getUser()->getEditToken( 00639 $this->file->getArchiveName() ) 00640 ) 00641 ); 00642 } 00643 return '<span class="history-deleted">' . $link . '</span>'; 00644 } 00649 protected function getUserTools() { 00650 if( $this->file->userCan( Revision::DELETED_USER, $this->list->getUser() ) ) { 00651 $link = Linker::userLink( $this->file->user, $this->file->user_text ) . 00652 Linker::userToolLinks( $this->file->user, $this->file->user_text ); 00653 } else { 00654 $link = $this->list->msg( 'rev-deleted-user' )->escaped(); 00655 } 00656 if( $this->file->isDeleted( Revision::DELETED_USER ) ) { 00657 return '<span class="history-deleted">' . $link . '</span>'; 00658 } 00659 return $link; 00660 } 00661 00668 protected function getComment() { 00669 if( $this->file->userCan( File::DELETED_COMMENT, $this->list->getUser() ) ) { 00670 $block = Linker::commentBlock( $this->file->description ); 00671 } else { 00672 $block = ' ' . $this->list->msg( 'rev-deleted-comment' )->escaped(); 00673 } 00674 if( $this->file->isDeleted( File::DELETED_COMMENT ) ) { 00675 return "<span class=\"history-deleted\">$block</span>"; 00676 } 00677 return $block; 00678 } 00679 00680 public function getHTML() { 00681 $data = 00682 $this->list->msg( 'widthheight' )->numParams( 00683 $this->file->getWidth(), $this->file->getHeight() )->text() . 00684 ' (' . $this->list->msg( 'nbytes' )->numParams( $this->file->getSize() )->text() . ')'; 00685 00686 return '<li>' . $this->getLink() . ' ' . $this->getUserTools() . ' ' . 00687 $data . ' ' . $this->getComment(). '</li>'; 00688 } 00689 } 00690 00694 class RevDel_ArchivedFileList extends RevDel_FileList { 00695 public function getType() { 00696 return 'filearchive'; 00697 } 00698 00699 public static function getRelationType() { 00700 return 'fa_id'; 00701 } 00702 00707 public function doQuery( $db ) { 00708 $ids = array_map( 'intval', $this->ids ); 00709 return $db->select( 'filearchive', '*', 00710 array( 00711 'fa_name' => $this->title->getDBkey(), 00712 'fa_id' => $ids 00713 ), 00714 __METHOD__, 00715 array( 'ORDER BY' => 'fa_id DESC' ) 00716 ); 00717 } 00718 00719 public function newItem( $row ) { 00720 return new RevDel_ArchivedFileItem( $this, $row ); 00721 } 00722 } 00723 00727 class RevDel_ArchivedFileItem extends RevDel_FileItem { 00728 public function __construct( $list, $row ) { 00729 RevDel_Item::__construct( $list, $row ); 00730 $this->file = ArchivedFile::newFromRow( $row ); 00731 } 00732 00733 public function getIdField() { 00734 return 'fa_id'; 00735 } 00736 00737 public function getTimestampField() { 00738 return 'fa_timestamp'; 00739 } 00740 00741 public function getAuthorIdField() { 00742 return 'fa_user'; 00743 } 00744 00745 public function getAuthorNameField() { 00746 return 'fa_user_text'; 00747 } 00748 00749 public function getId() { 00750 return $this->row->fa_id; 00751 } 00752 00753 public function setBits( $bits ) { 00754 $dbw = wfGetDB( DB_MASTER ); 00755 $dbw->update( 'filearchive', 00756 array( 'fa_deleted' => $bits ), 00757 array( 00758 'fa_id' => $this->row->fa_id, 00759 'fa_deleted' => $this->getBits(), 00760 ), 00761 __METHOD__ 00762 ); 00763 return (bool)$dbw->affectedRows(); 00764 } 00765 00766 protected function getLink() { 00767 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00768 $this->file->getTimestamp(), $this->list->getUser() ) ); 00769 00770 # Hidden files... 00771 if( !$this->canViewContent() ) { 00772 $link = $date; 00773 } else { 00774 $undelete = SpecialPage::getTitleFor( 'Undelete' ); 00775 $key = $this->file->getKey(); 00776 $link = Linker::link( $undelete, $date, array(), 00777 array( 00778 'target' => $this->list->title->getPrefixedText(), 00779 'file' => $key, 00780 'token' => $this->list->getUser()->getEditToken( $key ) 00781 ) 00782 ); 00783 } 00784 if( $this->isDeleted() ) { 00785 $link = '<span class="history-deleted">' . $link . '</span>'; 00786 } 00787 return $link; 00788 } 00789 } 00790 00794 class RevDel_LogList extends RevDel_List { 00795 public function getType() { 00796 return 'logging'; 00797 } 00798 00799 public static function getRelationType() { 00800 return 'log_id'; 00801 } 00802 00807 public function doQuery( $db ) { 00808 $ids = array_map( 'intval', $this->ids ); 00809 return $db->select( 'logging', '*', 00810 array( 'log_id' => $ids ), 00811 __METHOD__, 00812 array( 'ORDER BY' => 'log_id DESC' ) 00813 ); 00814 } 00815 00816 public function newItem( $row ) { 00817 return new RevDel_LogItem( $this, $row ); 00818 } 00819 00820 public function getSuppressBit() { 00821 return Revision::DELETED_RESTRICTED; 00822 } 00823 00824 public function getLogAction() { 00825 return 'event'; 00826 } 00827 00828 public function getLogParams( $params ) { 00829 return array( 00830 implode( ',', $params['ids'] ), 00831 "ofield={$params['oldBits']}", 00832 "nfield={$params['newBits']}" 00833 ); 00834 } 00835 } 00836 00840 class RevDel_LogItem extends RevDel_Item { 00841 public function getIdField() { 00842 return 'log_id'; 00843 } 00844 00845 public function getTimestampField() { 00846 return 'log_timestamp'; 00847 } 00848 00849 public function getAuthorIdField() { 00850 return 'log_user'; 00851 } 00852 00853 public function getAuthorNameField() { 00854 return 'log_user_text'; 00855 } 00856 00857 public function canView() { 00858 return LogEventsList::userCan( $this->row, Revision::DELETED_RESTRICTED, $this->list->getUser() ); 00859 } 00860 00861 public function canViewContent() { 00862 return true; // none 00863 } 00864 00865 public function getBits() { 00866 return $this->row->log_deleted; 00867 } 00868 00869 public function setBits( $bits ) { 00870 $dbw = wfGetDB( DB_MASTER ); 00871 $dbw->update( 'recentchanges', 00872 array( 00873 'rc_deleted' => $bits, 00874 'rc_patrolled' => 1 00875 ), 00876 array( 00877 'rc_logid' => $this->row->log_id, 00878 'rc_timestamp' => $this->row->log_timestamp // index 00879 ), 00880 __METHOD__ 00881 ); 00882 $dbw->update( 'logging', 00883 array( 'log_deleted' => $bits ), 00884 array( 00885 'log_id' => $this->row->log_id, 00886 'log_deleted' => $this->getBits() 00887 ), 00888 __METHOD__ 00889 ); 00890 return (bool)$dbw->affectedRows(); 00891 } 00892 00893 public function getHTML() { 00894 $date = htmlspecialchars( $this->list->getLanguage()->userTimeAndDate( 00895 $this->row->log_timestamp, $this->list->getUser() ) ); 00896 $title = Title::makeTitle( $this->row->log_namespace, $this->row->log_title ); 00897 $formatter = LogFormatter::newFromRow( $this->row ); 00898 $formatter->setContext( $this->list->getContext() ); 00899 $formatter->setAudience( LogFormatter::FOR_THIS_USER ); 00900 00901 // Log link for this page 00902 $loglink = Linker::link( 00903 SpecialPage::getTitleFor( 'Log' ), 00904 $this->list->msg( 'log' )->escaped(), 00905 array(), 00906 array( 'page' => $title->getPrefixedText() ) 00907 ); 00908 $loglink = $this->list->msg( 'parentheses' )->rawParams( $loglink )->escaped(); 00909 // User links and action text 00910 $action = $formatter->getActionText(); 00911 // Comment 00912 $comment = $this->list->getLanguage()->getDirMark() . Linker::commentBlock( $this->row->log_comment ); 00913 if( LogEventsList::isDeleted($this->row,LogPage::DELETED_COMMENT) ) { 00914 $comment = '<span class="history-deleted">' . $comment . '</span>'; 00915 } 00916 00917 return "<li>$loglink $date $action $comment</li>"; 00918 } 00919 }