00001 <?php
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 if (!defined('MEDIAWIKI')) {
00026
00027 require_once ("ApiBase.php");
00028 }
00029
00030
00037 class ApiDelete extends ApiBase {
00038
00039 public function __construct($main, $action) {
00040 parent :: __construct($main, $action);
00041 }
00042
00050 public function execute() {
00051 global $wgUser;
00052 $params = $this->extractRequestParams();
00053
00054 $this->requireOnlyOneParameter($params, 'title', 'pageid');
00055 if(!isset($params['token']))
00056 $this->dieUsageMsg(array('missingparam', 'token'));
00057
00058 if(isset($params['title']))
00059 {
00060 $titleObj = Title::newFromText($params['title']);
00061 if(!$titleObj)
00062 $this->dieUsageMsg(array('invalidtitle', $params['title']));
00063 }
00064 else if(isset($params['pageid']))
00065 {
00066 $titleObj = Title::newFromID($params['pageid']);
00067 if(!$titleObj)
00068 $this->dieUsageMsg(array('nosuchpageid', $params['pageid']));
00069 }
00070 if(!$titleObj->exists())
00071 $this->dieUsageMsg(array('notanarticle'));
00072
00073 $reason = (isset($params['reason']) ? $params['reason'] : NULL);
00074 if ($titleObj->getNamespace() == NS_FILE) {
00075 $retval = self::deleteFile($params['token'], $titleObj, $params['oldimage'], $reason, false);
00076 if(count($retval))
00077
00078 $this->dieUsageMsg(reset($retval));
00079 } else {
00080 $articleObj = new Article($titleObj);
00081 if($articleObj->isBigDeletion() && !$wgUser->isAllowed('bigdelete')) {
00082 global $wgDeleteRevisionsLimit;
00083 $this->dieUsageMsg(array('delete-toobig', $wgDeleteRevisionsLimit));
00084 }
00085 $retval = self::delete($articleObj, $params['token'], $reason);
00086
00087 if(count($retval))
00088
00089 $this->dieUsageMsg(reset($retval));
00090
00091 if($params['watch'] || $wgUser->getOption('watchdeletion'))
00092 $articleObj->doWatch();
00093 else if($params['unwatch'])
00094 $articleObj->doUnwatch();
00095 }
00096
00097 $r = array('title' => $titleObj->getPrefixedText(), 'reason' => $reason);
00098 $this->getResult()->addValue(null, $this->getModuleName(), $r);
00099 }
00100
00101 private static function getPermissionsError(&$title, $token) {
00102 global $wgUser;
00103
00104
00105 $errors = $title->getUserPermissionsErrors('delete', $wgUser);
00106 if (count($errors) > 0) return $errors;
00107
00108
00109 if(!$wgUser->matchEditToken($token))
00110 return array(array('sessionfailure'));
00111 return array();
00112 }
00113
00122 public static function delete(&$article, $token, &$reason = NULL)
00123 {
00124 global $wgUser;
00125 $title = $article->getTitle();
00126 $errors = self::getPermissionsError($title, $token);
00127 if (count($errors)) return $errors;
00128
00129
00130 if(is_null($reason))
00131 {
00132 # Need to pass a throwaway variable because generateReason expects
00133 # a reference
00134 $hasHistory = false;
00135 $reason = $article->generateReason($hasHistory);
00136 if($reason === false)
00137 return array(array('cannotdelete'));
00138 }
00139
00140 $error = '';
00141 if (!wfRunHooks('ArticleDelete', array(&$article, &$wgUser, &$reason, $error)))
00142 $this->dieUsageMsg(array('hookaborted', $error));
00143
00144
00145 if($article->doDeleteArticle($reason)) {
00146 wfRunHooks('ArticleDeleteComplete', array(&$article, &$wgUser, $reason, $article->getId()));
00147 return array();
00148 }
00149 return array(array('cannotdelete', $article->mTitle->getPrefixedText()));
00150 }
00151
00152 public static function deleteFile($token, &$title, $oldimage, &$reason = NULL, $suppress = false)
00153 {
00154 $errors = self::getPermissionsError($title, $token);
00155 if (count($errors)) return $errors;
00156
00157 if( $oldimage && !FileDeleteForm::isValidOldSpec($oldimage) )
00158 return array(array('invalidoldimage'));
00159
00160 $file = wfFindFile($title, false, FileRepo::FIND_IGNORE_REDIRECT);
00161 $oldfile = false;
00162
00163 if( $oldimage )
00164 $oldfile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $oldimage );
00165
00166 if( !FileDeleteForm::haveDeletableFile($file, $oldfile, $oldimage) )
00167 return array(array('nofile'));
00168 if (is_null($reason)) # Log and RC don't like null reasons
00169 $reason = '';
00170 $status = FileDeleteForm::doDelete( $title, $file, $oldimage, $reason, $suppress );
00171
00172 if( !$status->isGood() )
00173 return array(array('cannotdelete', $title->getPrefixedText()));
00174
00175 return array();
00176 }
00177
00178 public function mustBePosted() { return true; }
00179
00180 public function isWriteMode() {
00181 return true;
00182 }
00183
00184 public function getAllowedParams() {
00185 return array (
00186 'title' => null,
00187 'pageid' => array(
00188 ApiBase::PARAM_TYPE => 'integer'
00189 ),
00190 'token' => null,
00191 'reason' => null,
00192 'watch' => false,
00193 'unwatch' => false,
00194 'oldimage' => null
00195 );
00196 }
00197
00198 public function getParamDescription() {
00199 return array (
00200 'title' => 'Title of the page you want to delete. Cannot be used together with pageid',
00201 'pageid' => 'Page ID of the page you want to delete. Cannot be used together with title',
00202 'token' => 'A delete token previously retrieved through prop=info',
00203 'reason' => 'Reason for the deletion. If not set, an automatically generated reason will be used.',
00204 'watch' => 'Add the page to your watchlist',
00205 'unwatch' => 'Remove the page from your watchlist',
00206 'oldimage' => 'The name of the old image to delete as provided by iiprop=archivename'
00207 );
00208 }
00209
00210 public function getDescription() {
00211 return array(
00212 'Delete a page.'
00213 );
00214 }
00215
00216 protected function getExamples() {
00217 return array (
00218 'api.php?action=delete&title=Main%20Page&token=123ABC',
00219 'api.php?action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
00220 );
00221 }
00222
00223 public function getVersion() {
00224 return __CLASS__ . ': $Id: ApiDelete.php 48122 2009-03-07 12:58:41Z catrope $';
00225 }
00226 }