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