MediaWiki  REL1_21
RevisionDeleteAbstracts.php
Go to the documentation of this file.
00001 <?php
00030 abstract class RevDel_List extends RevisionListBase {
00031         function __construct( IContextSource $context, Title $title, array $ids ) {
00032                 parent::__construct( $context, $title );
00033                 $this->ids = $ids;
00034         }
00035 
00042         public static function getRelationType() {
00043                 return null;
00044         }
00045 
00055         public function setVisibility( $params ) {
00056                 $bitPars = $params['value'];
00057                 $comment = $params['comment'];
00058 
00059                 $this->res = false;
00060                 $dbw = wfGetDB( DB_MASTER );
00061                 $this->doQuery( $dbw );
00062                 $dbw->begin( __METHOD__ );
00063                 $status = Status::newGood();
00064                 $missing = array_flip( $this->ids );
00065                 $this->clearFileOps();
00066                 $idsForLog = array();
00067                 $authorIds = $authorIPs = array();
00068 
00069                 for ( $this->reset(); $this->current(); $this->next() ) {
00070                         $item = $this->current();
00071                         unset( $missing[ $item->getId() ] );
00072 
00073                         $oldBits = $item->getBits();
00074                         // Build the actual new rev_deleted bitfield
00075                         $newBits = SpecialRevisionDelete::extractBitfield( $bitPars, $oldBits );
00076 
00077                         if ( $oldBits == $newBits ) {
00078                                 $status->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
00079                                 $status->failCount++;
00080                                 continue;
00081                         } elseif ( $oldBits == 0 && $newBits != 0 ) {
00082                                 $opType = 'hide';
00083                         } elseif ( $oldBits != 0 && $newBits == 0 ) {
00084                                 $opType = 'show';
00085                         } else {
00086                                 $opType = 'modify';
00087                         }
00088 
00089                         if ( $item->isHideCurrentOp( $newBits ) ) {
00090                                 // Cannot hide current version text
00091                                 $status->error( 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
00092                                 $status->failCount++;
00093                                 continue;
00094                         }
00095                         if ( !$item->canView() ) {
00096                                 // Cannot access this revision
00097                                 $msg = ($opType == 'show') ?
00098                                         'revdelete-show-no-access' : 'revdelete-modify-no-access';
00099                                 $status->error( $msg, $item->formatDate(), $item->formatTime() );
00100                                 $status->failCount++;
00101                                 continue;
00102                         }
00103                         // Cannot just "hide from Sysops" without hiding any fields
00104                         if( $newBits == Revision::DELETED_RESTRICTED ) {
00105                                 $status->warning( 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
00106                                 $status->failCount++;
00107                                 continue;
00108                         }
00109 
00110                         // Update the revision
00111                         $ok = $item->setBits( $newBits );
00112 
00113                         if ( $ok ) {
00114                                 $idsForLog[] = $item->getId();
00115                                 $status->successCount++;
00116                                 if( $item->getAuthorId() > 0 ) {
00117                                         $authorIds[] = $item->getAuthorId();
00118                                 } elseif( IP::isIPAddress( $item->getAuthorName() ) ) {
00119                                         $authorIPs[] = $item->getAuthorName();
00120                                 }
00121                         } else {
00122                                 $status->error( 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
00123                                 $status->failCount++;
00124                         }
00125                 }
00126 
00127                 // Handle missing revisions
00128                 foreach ( $missing as $id => $unused ) {
00129                         $status->error( 'revdelete-modify-missing', $id );
00130                         $status->failCount++;
00131                 }
00132 
00133                 if ( $status->successCount == 0 ) {
00134                         $status->ok = false;
00135                         $dbw->rollback( __METHOD__ );
00136                         return $status;
00137                 }
00138 
00139                 // Save success count
00140                 $successCount = $status->successCount;
00141 
00142                 // Move files, if there are any
00143                 $status->merge( $this->doPreCommitUpdates() );
00144                 if ( !$status->isOK() ) {
00145                         // Fatal error, such as no configured archive directory
00146                         $dbw->rollback( __METHOD__ );
00147                         return $status;
00148                 }
00149 
00150                 // Log it
00151                 $this->updateLog( array(
00152                         'title' => $this->title,
00153                         'count' => $successCount,
00154                         'newBits' => $newBits,
00155                         'oldBits' => $oldBits,
00156                         'comment' => $comment,
00157                         'ids' => $idsForLog,
00158                         'authorIds' => $authorIds,
00159                         'authorIPs' => $authorIPs
00160                 ) );
00161                 $dbw->commit( __METHOD__ );
00162 
00163                 // Clear caches
00164                 $status->merge( $this->doPostCommitUpdates() );
00165                 return $status;
00166         }
00167 
00172         function reloadFromMaster() {
00173                 $dbw = wfGetDB( DB_MASTER );
00174                 $this->res = $this->doQuery( $dbw );
00175         }
00176 
00189         protected function updateLog( $params ) {
00190                 // Get the URL param's corresponding DB field
00191                 $field = RevisionDeleter::getRelationType( $this->getType() );
00192                 if( !$field ) {
00193                         throw new MWException( "Bad log URL param type!" );
00194                 }
00195                 // Put things hidden from sysops in the oversight log
00196                 if ( ( $params['newBits'] | $params['oldBits'] ) & $this->getSuppressBit() ) {
00197                         $logType = 'suppress';
00198                 } else {
00199                         $logType = 'delete';
00200                 }
00201                 // Add params for effected page and ids
00202                 $logParams = $this->getLogParams( $params );
00203                 // Actually add the deletion log entry
00204                 $log = new LogPage( $logType );
00205                 $logid = $log->addEntry( $this->getLogAction(), $params['title'],
00206                         $params['comment'], $logParams );
00207                 // Allow for easy searching of deletion log items for revision/log items
00208                 $log->addRelations( $field, $params['ids'], $logid );
00209                 $log->addRelations( 'target_author_id', $params['authorIds'], $logid );
00210                 $log->addRelations( 'target_author_ip', $params['authorIPs'], $logid );
00211         }
00212 
00217         public function getLogAction() {
00218                 return 'revision';
00219         }
00220 
00226         public function getLogParams( $params ) {
00227                 return array(
00228                         $this->getType(),
00229                         implode( ',', $params['ids'] ),
00230                         "ofield={$params['oldBits']}",
00231                         "nfield={$params['newBits']}"
00232                 );
00233         }
00234 
00239         public function clearFileOps() {
00240         }
00241 
00247         public function doPreCommitUpdates() {
00248                 return Status::newGood();
00249         }
00250 
00256         public function doPostCommitUpdates() {
00257                 return Status::newGood();
00258         }
00259 
00263         abstract public function getSuppressBit();
00264 }
00265 
00269 abstract class RevDel_Item extends RevisionItemBase {
00276         public function isHideCurrentOp( $newBits ) {
00277                 return false;
00278         }
00279 
00283         abstract public function getBits();
00284 
00295         abstract public function setBits( $newBits );
00296 }