[ Index ]

PHP Cross Reference of MediaWiki-1.24.0

title

Body

[close]

/includes/revisiondelete/ -> RevDelList.php (source)

   1  <?php
   2  /**
   3   * This program is free software; you can redistribute it and/or modify
   4   * it under the terms of the GNU General Public License as published by
   5   * the Free Software Foundation; either version 2 of the License, or
   6   * (at your option) any later version.
   7   *
   8   * This program is distributed in the hope that it will be useful,
   9   * but WITHOUT ANY WARRANTY; without even the implied warranty of
  10   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11   * GNU General Public License for more details.
  12   *
  13   * You should have received a copy of the GNU General Public License along
  14   * with this program; if not, write to the Free Software Foundation, Inc.,
  15   * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  16   * http://www.gnu.org/copyleft/gpl.html
  17   *
  18   * @file
  19   * @ingroup RevisionDelete
  20   */
  21  
  22  /**
  23   * Abstract base class for a list of deletable items. The list class
  24   * needs to be able to make a query from a set of identifiers to pull
  25   * relevant rows, to return RevDelItem subclasses wrapping them, and
  26   * to wrap bulk update operations.
  27   */
  28  abstract class RevDelList extends RevisionListBase {
  29  	function __construct( IContextSource $context, Title $title, array $ids ) {
  30          parent::__construct( $context, $title );
  31          $this->ids = $ids;
  32      }
  33  
  34      /**
  35       * Get the DB field name associated with the ID list.
  36       * This used to populate the log_search table for finding log entries.
  37       * Override this function.
  38       * @return string|null
  39       */
  40  	public static function getRelationType() {
  41          return null;
  42      }
  43  
  44      /**
  45       * Get the user right required for this list type
  46       * Override this function.
  47       * @since 1.22
  48       * @return string|null
  49       */
  50  	public static function getRestriction() {
  51          return null;
  52      }
  53  
  54      /**
  55       * Get the revision deletion constant for this list type
  56       * Override this function.
  57       * @since 1.22
  58       * @return int|null
  59       */
  60  	public static function getRevdelConstant() {
  61          return null;
  62      }
  63  
  64      /**
  65       * Suggest a target for the revision deletion
  66       * Optionally override this function.
  67       * @since 1.22
  68       * @param Title|null $target User-supplied target
  69       * @param array $ids
  70       * @return Title|null
  71       */
  72  	public static function suggestTarget( $target, array $ids ) {
  73          return $target;
  74      }
  75  
  76      /**
  77       * Set the visibility for the revisions in this list. Logging and
  78       * transactions are done here.
  79       *
  80       * @param array $params Associative array of parameters. Members are:
  81       *     value:         The integer value to set the visibility to
  82       *     comment:       The log comment.
  83       *     perItemStatus: Set if you want per-item status reports
  84       * @return Status
  85       * @since 1.23 Added 'perItemStatus' param
  86       */
  87  	public function setVisibility( $params ) {
  88          $bitPars = $params['value'];
  89          $comment = $params['comment'];
  90          $perItemStatus = isset( $params['perItemStatus'] ) ? $params['perItemStatus'] : false;
  91  
  92          $this->res = false;
  93          $dbw = wfGetDB( DB_MASTER );
  94          $this->doQuery( $dbw );
  95          $dbw->begin( __METHOD__ );
  96          $status = Status::newGood();
  97          $missing = array_flip( $this->ids );
  98          $this->clearFileOps();
  99          $idsForLog = array();
 100          $authorIds = $authorIPs = array();
 101  
 102          if ( $perItemStatus ) {
 103              $status->itemStatuses = array();
 104          }
 105  
 106          // @codingStandardsIgnoreStart Generic.CodeAnalysis.ForLoopWithTestFunctionCall.NotAllowed
 107          for ( $this->reset(); $this->current(); $this->next() ) {
 108              // @codingStandardsIgnoreEnd
 109              $item = $this->current();
 110              unset( $missing[$item->getId()] );
 111  
 112              if ( $perItemStatus ) {
 113                  $itemStatus = Status::newGood();
 114                  $status->itemStatuses[$item->getId()] = $itemStatus;
 115              } else {
 116                  $itemStatus = $status;
 117              }
 118  
 119              $oldBits = $item->getBits();
 120              // Build the actual new rev_deleted bitfield
 121              $newBits = RevisionDeleter::extractBitfield( $bitPars, $oldBits );
 122  
 123              if ( $oldBits == $newBits ) {
 124                  $itemStatus->warning( 'revdelete-no-change', $item->formatDate(), $item->formatTime() );
 125                  $status->failCount++;
 126                  continue;
 127              } elseif ( $oldBits == 0 && $newBits != 0 ) {
 128                  $opType = 'hide';
 129              } elseif ( $oldBits != 0 && $newBits == 0 ) {
 130                  $opType = 'show';
 131              } else {
 132                  $opType = 'modify';
 133              }
 134  
 135              if ( $item->isHideCurrentOp( $newBits ) ) {
 136                  // Cannot hide current version text
 137                  $itemStatus->error( 'revdelete-hide-current', $item->formatDate(), $item->formatTime() );
 138                  $status->failCount++;
 139                  continue;
 140              }
 141              if ( !$item->canView() ) {
 142                  // Cannot access this revision
 143                  $msg = ( $opType == 'show' ) ?
 144                      'revdelete-show-no-access' : 'revdelete-modify-no-access';
 145                  $itemStatus->error( $msg, $item->formatDate(), $item->formatTime() );
 146                  $status->failCount++;
 147                  continue;
 148              }
 149              // Cannot just "hide from Sysops" without hiding any fields
 150              if ( $newBits == Revision::DELETED_RESTRICTED ) {
 151                  $itemStatus->warning( 'revdelete-only-restricted', $item->formatDate(), $item->formatTime() );
 152                  $status->failCount++;
 153                  continue;
 154              }
 155  
 156              // Update the revision
 157              $ok = $item->setBits( $newBits );
 158  
 159              if ( $ok ) {
 160                  $idsForLog[] = $item->getId();
 161                  $status->successCount++;
 162                  if ( $item->getAuthorId() > 0 ) {
 163                      $authorIds[] = $item->getAuthorId();
 164                  } elseif ( IP::isIPAddress( $item->getAuthorName() ) ) {
 165                      $authorIPs[] = $item->getAuthorName();
 166                  }
 167              } else {
 168                  $itemStatus->error( 'revdelete-concurrent-change', $item->formatDate(), $item->formatTime() );
 169                  $status->failCount++;
 170              }
 171          }
 172  
 173          // Handle missing revisions
 174          foreach ( $missing as $id => $unused ) {
 175              if ( $perItemStatus ) {
 176                  $status->itemStatuses[$id] = Status::newFatal( 'revdelete-modify-missing', $id );
 177              } else {
 178                  $status->error( 'revdelete-modify-missing', $id );
 179              }
 180              $status->failCount++;
 181          }
 182  
 183          if ( $status->successCount == 0 ) {
 184              $dbw->rollback( __METHOD__ );
 185              return $status;
 186          }
 187  
 188          // Save success count
 189          $successCount = $status->successCount;
 190  
 191          // Move files, if there are any
 192          $status->merge( $this->doPreCommitUpdates() );
 193          if ( !$status->isOK() ) {
 194              // Fatal error, such as no configured archive directory
 195              $dbw->rollback( __METHOD__ );
 196              return $status;
 197          }
 198  
 199          // Log it
 200          $this->updateLog( array(
 201              'title' => $this->title,
 202              'count' => $successCount,
 203              'newBits' => $newBits,
 204              'oldBits' => $oldBits,
 205              'comment' => $comment,
 206              'ids' => $idsForLog,
 207              'authorIds' => $authorIds,
 208              'authorIPs' => $authorIPs
 209          ) );
 210          $dbw->commit( __METHOD__ );
 211  
 212          // Clear caches
 213          $status->merge( $this->doPostCommitUpdates() );
 214          return $status;
 215      }
 216  
 217      /**
 218       * Reload the list data from the master DB. This can be done after setVisibility()
 219       * to allow $item->getHTML() to show the new data.
 220       */
 221  	function reloadFromMaster() {
 222          $dbw = wfGetDB( DB_MASTER );
 223          $this->res = $this->doQuery( $dbw );
 224      }
 225  
 226      /**
 227       * Record a log entry on the action
 228       * @param array $params Associative array of parameters:
 229       *     newBits:         The new value of the *_deleted bitfield
 230       *     oldBits:         The old value of the *_deleted bitfield.
 231       *     title:           The target title
 232       *     ids:             The ID list
 233       *     comment:         The log comment
 234       *     authorsIds:      The array of the user IDs of the offenders
 235       *     authorsIPs:      The array of the IP/anon user offenders
 236       * @throws MWException
 237       */
 238  	protected function updateLog( $params ) {
 239          // Get the URL param's corresponding DB field
 240          $field = RevisionDeleter::getRelationType( $this->getType() );
 241          if ( !$field ) {
 242              throw new MWException( "Bad log URL param type!" );
 243          }
 244          // Put things hidden from sysops in the oversight log
 245          if ( ( $params['newBits'] | $params['oldBits'] ) & $this->getSuppressBit() ) {
 246              $logType = 'suppress';
 247          } else {
 248              $logType = 'delete';
 249          }
 250          // Add params for effected page and ids
 251          $logParams = $this->getLogParams( $params );
 252          // Actually add the deletion log entry
 253          $log = new LogPage( $logType );
 254          $logid = $log->addEntry( $this->getLogAction(), $params['title'],
 255              $params['comment'], $logParams, $this->getUser() );
 256          // Allow for easy searching of deletion log items for revision/log items
 257          $log->addRelations( $field, $params['ids'], $logid );
 258          $log->addRelations( 'target_author_id', $params['authorIds'], $logid );
 259          $log->addRelations( 'target_author_ip', $params['authorIPs'], $logid );
 260      }
 261  
 262      /**
 263       * Get the log action for this list type
 264       * @return string
 265       */
 266  	public function getLogAction() {
 267          return 'revision';
 268      }
 269  
 270      /**
 271       * Get log parameter array.
 272       * @param array $params Associative array of log parameters, same as updateLog()
 273       * @return array
 274       */
 275  	public function getLogParams( $params ) {
 276          return array(
 277              $this->getType(),
 278              implode( ',', $params['ids'] ),
 279              "ofield={$params['oldBits']}",
 280              "nfield={$params['newBits']}"
 281          );
 282      }
 283  
 284      /**
 285       * Clear any data structures needed for doPreCommitUpdates() and doPostCommitUpdates()
 286       * STUB
 287       */
 288  	public function clearFileOps() {
 289      }
 290  
 291      /**
 292       * A hook for setVisibility(): do batch updates pre-commit.
 293       * STUB
 294       * @return Status
 295       */
 296  	public function doPreCommitUpdates() {
 297          return Status::newGood();
 298      }
 299  
 300      /**
 301       * A hook for setVisibility(): do any necessary updates post-commit.
 302       * STUB
 303       * @return Status
 304       */
 305  	public function doPostCommitUpdates() {
 306          return Status::newGood();
 307      }
 308  
 309      /**
 310       * Get the integer value of the flag used for suppression
 311       */
 312      abstract public function getSuppressBit();
 313  }


Generated: Fri Nov 28 14:03:12 2014 Cross-referenced by PHPXref 0.7.1