MediaWiki  REL1_24
ApiRevisionDelete.php
Go to the documentation of this file.
00001 <?php
00032 class ApiRevisionDelete extends ApiBase {
00033 
00034     public function execute() {
00035         $params = $this->extractRequestParams();
00036         $user = $this->getUser();
00037 
00038         if ( !$user->isAllowed( RevisionDeleter::getRestriction( $params['type'] ) ) ) {
00039             $this->dieUsageMsg( 'badaccess-group0' );
00040         }
00041 
00042         if ( !$params['ids'] ) {
00043             $this->dieUsage( "At least one value is required for 'ids'", 'badparams' );
00044         }
00045 
00046         $hide = $params['hide'] ?: array();
00047         $show = $params['show'] ?: array();
00048         if ( array_intersect( $hide, $show ) ) {
00049             $this->dieUsage( "Mutually exclusive values for 'hide' and 'show'", 'badparams' );
00050         } elseif ( !$hide && !$show ) {
00051             $this->dieUsage( "At least one value is required for 'hide' or 'show'", 'badparams' );
00052         }
00053         $bits = array(
00054             'content' => RevisionDeleter::getRevdelConstant( $params['type'] ),
00055             'comment' => Revision::DELETED_COMMENT,
00056             'user' => Revision::DELETED_USER,
00057         );
00058         $bitfield = array();
00059         foreach ( $bits as $key => $bit ) {
00060             if ( in_array( $key, $hide ) ) {
00061                 $bitfield[$bit] = 1;
00062             } elseif ( in_array( $key, $show ) ) {
00063                 $bitfield[$bit] = 0;
00064             } else {
00065                 $bitfield[$bit] = -1;
00066             }
00067         }
00068 
00069         if ( $params['suppress'] === 'yes' ) {
00070             if ( !$user->isAllowed( 'suppressrevision' ) ) {
00071                 $this->dieUsageMsg( 'badaccess-group0' );
00072             }
00073             $bitfield[Revision::DELETED_RESTRICTED] = 1;
00074         } elseif ( $params['suppress'] === 'no' ) {
00075             $bitfield[Revision::DELETED_RESTRICTED] = 0;
00076         } else {
00077             $bitfield[Revision::DELETED_RESTRICTED] = -1;
00078         }
00079 
00080         $targetObj = null;
00081         if ( $params['target'] ) {
00082             $targetObj = Title::newFromText( $params['target'] );
00083         }
00084         $targetObj = RevisionDeleter::suggestTarget( $params['type'], $targetObj, $params['ids'] );
00085         if ( $targetObj === null ) {
00086             $this->dieUsage( 'A target title is required for this RevDel type', 'needtarget' );
00087         }
00088 
00089         $list = RevisionDeleter::createList(
00090             $params['type'], $this->getContext(), $targetObj, $params['ids']
00091         );
00092         $status = $list->setVisibility(
00093             array( 'value' => $bitfield, 'comment' => $params['reason'], 'perItemStatus' => true )
00094         );
00095 
00096         $result = $this->getResult();
00097         $data = $this->extractStatusInfo( $status );
00098         $data['target'] = $targetObj->getFullText();
00099         $data['items'] = array();
00100 
00101         foreach ( $status->itemStatuses as $id => $s ) {
00102             $data['items'][$id] = $this->extractStatusInfo( $s );
00103             $data['items'][$id]['id'] = $id;
00104         }
00105 
00106         $list->reloadFromMaster();
00107         // @codingStandardsIgnoreStart Avoid function calls in a FOR loop test part
00108         for ( $item = $list->reset(); $list->current(); $item = $list->next() ) {
00109             $data['items'][$item->getId()] += $item->getApiData( $this->getResult() );
00110         }
00111         // @codingStandardsIgnoreEnd
00112 
00113         $data['items'] = array_values( $data['items'] );
00114         $result->setIndexedTagName( $data['items'], 'i' );
00115         $result->addValue( null, $this->getModuleName(), $data );
00116     }
00117 
00118     private function extractStatusInfo( $status ) {
00119         $ret = array(
00120             'status' => $status->isOK() ? 'Success' : 'Fail',
00121         );
00122         $errors = $this->formatStatusMessages( $status->getErrorsByType( 'error' ) );
00123         if ( $errors ) {
00124             $this->getResult()->setIndexedTagName( $errors, 'e' );
00125             $ret['errors'] = $errors;
00126         }
00127         $warnings = $this->formatStatusMessages( $status->getErrorsByType( 'warning' ) );
00128         if ( $warnings ) {
00129             $this->getResult()->setIndexedTagName( $warnings, 'w' );
00130             $ret['warnings'] = $warnings;
00131         }
00132 
00133         return $ret;
00134     }
00135 
00136     private function formatStatusMessages( $messages ) {
00137         if ( !$messages ) {
00138             return array();
00139         }
00140         $result = $this->getResult();
00141         $ret = array();
00142         foreach ( $messages as $m ) {
00143             $message = array();
00144             if ( $m['message'] instanceof Message ) {
00145                 $msg = $m['message'];
00146                 $message = array( 'message' => $msg->getKey() );
00147                 if ( $msg->getParams() ) {
00148                     $message['params'] = $msg->getParams();
00149                     $result->setIndexedTagName( $message['params'], 'p' );
00150                 }
00151             } else {
00152                 $message = array( 'message' => $m['message'] );
00153                 $msg = wfMessage( $m['message'] );
00154                 if ( isset( $m['params'] ) ) {
00155                     $message['params'] = $m['params'];
00156                     $result->setIndexedTagName( $message['params'], 'p' );
00157                     $msg->params( $m['params'] );
00158                 }
00159             }
00160             $message['rendered'] = $msg->useDatabase( false )->inLanguage( 'en' )->plain();
00161             $ret[] = $message;
00162         }
00163 
00164         return $ret;
00165     }
00166 
00167     public function mustBePosted() {
00168         return true;
00169     }
00170 
00171     public function isWriteMode() {
00172         return true;
00173     }
00174 
00175     public function getAllowedParams() {
00176         return array(
00177             'type' => array(
00178                 ApiBase::PARAM_TYPE => RevisionDeleter::getTypes(),
00179                 ApiBase::PARAM_REQUIRED => true
00180             ),
00181             'target' => null,
00182             'ids' => array(
00183                 ApiBase::PARAM_ISMULTI => true,
00184                 ApiBase::PARAM_REQUIRED => true
00185             ),
00186             'hide' => array(
00187                 ApiBase::PARAM_TYPE => array( 'content', 'comment', 'user' ),
00188                 ApiBase::PARAM_ISMULTI => true,
00189             ),
00190             'show' => array(
00191                 ApiBase::PARAM_TYPE => array( 'content', 'comment', 'user' ),
00192                 ApiBase::PARAM_ISMULTI => true,
00193             ),
00194             'suppress' => array(
00195                 ApiBase::PARAM_TYPE => array( 'yes', 'no', 'nochange' ),
00196                 ApiBase::PARAM_DFLT => 'nochange',
00197             ),
00198             'reason' => null,
00199         );
00200     }
00201 
00202     public function getParamDescription() {
00203         return array(
00204             'type' => 'Type of revision deletion being performed',
00205             'target' => 'Page title for the revision deletion, if required for the type',
00206             'ids' => 'Identifiers for the revisions to be deleted',
00207             'hide' => 'What to hide for each revision',
00208             'show' => 'What to unhide for each revision',
00209             'suppress' => 'Whether to suppress data from administrators as well as others',
00210             'reason' => 'Reason for the deletion/undeletion',
00211         );
00212     }
00213 
00214     public function getDescription() {
00215         return 'Delete/undelete revisions.';
00216     }
00217 
00218     public function needsToken() {
00219         return 'csrf';
00220     }
00221 
00222     public function getExamples() {
00223         return array(
00224             'api.php?action=revisiondelete&target=Main%20Page&type=revision&ids=12345&' .
00225                 'hide=content&token=123ABC'
00226                 => 'Hide content for revision 12345 on the Main Page',
00227             'api.php?action=revisiondelete&type=logging&ids=67890&hide=content|comment|user&' .
00228                 'reason=BLP%20violation&token=123ABC'
00229                 => 'Hide all data on log entry 67890 with the reason "BLP violation"',
00230         );
00231     }
00232 
00233     public function getHelpUrls() {
00234         return 'https://www.mediawiki.org/wiki/API:Revisiondelete';
00235     }
00236 }