MediaWiki  REL1_19
RevisionDeleteAbstracts.php
Go to the documentation of this file.
00001 <?php
00002 
00009 abstract class RevDel_List extends RevisionListBase {
00010         function __construct( IContextSource $context, Title $title, array $ids ) {
00011                 parent::__construct( $context, $title );
00012                 $this->ids = $ids;
00013         }
00014 
00020         public static function getRelationType() {
00021                 return null;
00022         }
00023 
00033         public function setVisibility( $params ) {
00034                 $bitPars = $params['value'];
00035                 $comment = $params['comment'];
00036 
00037                 $this->res = false;
00038                 $dbw = wfGetDB( DB_MASTER );
00039                 $this->doQuery( $dbw );
00040                 $dbw->begin();
00041                 $status = Status::newGood();
00042                 $missing = array_flip( $this->ids );
00043                 $this->clearFileOps();
00044                 $idsForLog = array();
00045                 $authorIds = $authorIPs = array();
00046 
00047                 for ( $this->reset(); $this->current(); $this->next() ) {
00048                         $item = $this->current();
00049                         unset( $missing[ $item->getId() ] );
00050 
00051                         $oldBits = $item->getBits();
00052                         // Build the actual new rev_deleted bitfield
00053                         $newBits = SpecialRevisionDelete::extractBitfield( $bitPars, $oldBits );
00054 
00055                         if ( $oldBits == $newBits ) {
00056                                 $status->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
00057                                 $status->failCount++;
00058                                 continue;
00059                         } elseif ( $oldBits == 0 && $newBits != 0 ) {
00060                                 $opType = 'hide';
00061                         } elseif ( $oldBits != 0 && $newBits == 0 ) {
00062                                 $opType = 'show';
00063                         } else {
00064                                 $opType = 'modify';
00065                         }
00066 
00067                         if ( $item->isHideCurrentOp( $newBits ) ) {
00068                                 // Cannot hide current version text
00069                                 $status->error( 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
00070                                 $status->failCount++;
00071                                 continue;
00072                         }
00073                         if ( !$item->canView() ) {
00074                                 // Cannot access this revision
00075                                 $msg = ($opType == 'show') ?
00076                                         'revdelete-show-no-access' : 'revdelete-modify-no-access';
00077                                 $status->error( $msg, $item->formatDate(), $item->formatTime() );
00078                                 $status->failCount++;
00079                                 continue;
00080                         }
00081                         // Cannot just "hide from Sysops" without hiding any fields
00082                         if( $newBits == Revision::DELETED_RESTRICTED ) {
00083                                 $status->warning( 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
00084                                 $status->failCount++;
00085                                 continue;
00086                         }
00087 
00088                         // Update the revision
00089                         $ok = $item->setBits( $newBits );
00090 
00091                         if ( $ok ) {
00092                                 $idsForLog[] = $item->getId();
00093                                 $status->successCount++;
00094                                 if( $item->getAuthorId() > 0 ) {
00095                                         $authorIds[] = $item->getAuthorId();
00096                                 } elseif( IP::isIPAddress( $item->getAuthorName() ) ) {
00097                                         $authorIPs[] = $item->getAuthorName();
00098                                 }
00099                         } else {
00100                                 $status->error( 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
00101                                 $status->failCount++;
00102                         }
00103                 }
00104 
00105                 // Handle missing revisions
00106                 foreach ( $missing as $id => $unused ) {
00107                         $status->error( 'revdelete-modify-missing', $id );
00108                         $status->failCount++;
00109                 }
00110 
00111                 if ( $status->successCount == 0 ) {
00112                         $status->ok = false;
00113                         $dbw->rollback();
00114                         return $status;
00115                 }
00116 
00117                 // Save success count
00118                 $successCount = $status->successCount;
00119 
00120                 // Move files, if there are any
00121                 $status->merge( $this->doPreCommitUpdates() );
00122                 if ( !$status->isOK() ) {
00123                         // Fatal error, such as no configured archive directory
00124                         $dbw->rollback();
00125                         return $status;
00126                 }
00127 
00128                 // Log it
00129                 $this->updateLog( array(
00130                         'title' => $this->title,
00131                         'count' => $successCount,
00132                         'newBits' => $newBits,
00133                         'oldBits' => $oldBits,
00134                         'comment' => $comment,
00135                         'ids' => $idsForLog,
00136                         'authorIds' => $authorIds,
00137                         'authorIPs' => $authorIPs
00138                 ) );
00139                 $dbw->commit();
00140 
00141                 // Clear caches
00142                 $status->merge( $this->doPostCommitUpdates() );
00143                 return $status;
00144         }
00145 
00150         function reloadFromMaster() {
00151                 $dbw = wfGetDB( DB_MASTER );
00152                 $this->res = $this->doQuery( $dbw );
00153         }
00154 
00166         protected function updateLog( $params ) {
00167                 // Get the URL param's corresponding DB field
00168                 $field = RevisionDeleter::getRelationType( $this->getType() );
00169                 if( !$field ) {
00170                         throw new MWException( "Bad log URL param type!" );
00171                 }
00172                 // Put things hidden from sysops in the oversight log
00173                 if ( ( $params['newBits'] | $params['oldBits'] ) & $this->getSuppressBit() ) {
00174                         $logType = 'suppress';
00175                 } else {
00176                         $logType = 'delete';
00177                 }
00178                 // Add params for effected page and ids
00179                 $logParams = $this->getLogParams( $params );
00180                 // Actually add the deletion log entry
00181                 $log = new LogPage( $logType );
00182                 $logid = $log->addEntry( $this->getLogAction(), $params['title'],
00183                         $params['comment'], $logParams );
00184                 // Allow for easy searching of deletion log items for revision/log items
00185                 $log->addRelations( $field, $params['ids'], $logid );
00186                 $log->addRelations( 'target_author_id', $params['authorIds'], $logid );
00187                 $log->addRelations( 'target_author_ip', $params['authorIPs'], $logid );
00188         }
00189 
00193         public function getLogAction() {
00194                 return 'revision';
00195         }
00196 
00202         public function getLogParams( $params ) {
00203                 return array(
00204                         $this->getType(),
00205                         implode( ',', $params['ids'] ),
00206                         "ofield={$params['oldBits']}",
00207                         "nfield={$params['newBits']}"
00208                 );
00209         }
00210 
00215         public function clearFileOps() {
00216         }
00217 
00223         public function doPreCommitUpdates() {
00224                 return Status::newGood();
00225         }
00226 
00232         public function doPostCommitUpdates() {
00233                 return Status::newGood();
00234         }
00235 
00239         abstract public function getSuppressBit();
00240 }
00241 
00245 abstract class RevDel_Item extends RevisionItemBase {
00251         public function isHideCurrentOp( $newBits ) {
00252                 return false;
00253         }
00254 
00258         abstract public function getBits();
00259 
00270         abstract public function setBits( $newBits );
00271 }