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