MediaWiki fundraising/REL1_35
ApiDelete.php
Go to the documentation of this file.
1<?php
24
31class ApiDelete extends ApiBase {
32
34
35 public function __construct( ApiMain $mainModule, $moduleName, $modulePrefix = '' ) {
36 parent::__construct( $mainModule, $moduleName, $modulePrefix );
37
38 $this->watchlistExpiryEnabled = $this->getConfig()->get( 'WatchlistExpiry' );
39 $this->watchlistMaxDuration = $this->getConfig()->get( 'WatchlistExpiryMaxDuration' );
40 }
41
49 public function execute() {
51
52 $params = $this->extractRequestParams();
53
54 $pageObj = $this->getTitleOrPageId( $params, 'fromdbmaster' );
55 $titleObj = $pageObj->getTitle();
56 if ( !$pageObj->exists() &&
57 // @phan-suppress-next-line PhanUndeclaredMethod
58 !( $titleObj->getNamespace() == NS_FILE && self::canDeleteFile( $pageObj->getFile() ) )
59 ) {
60 $this->dieWithError( 'apierror-missingtitle' );
61 }
62
63 $reason = $params['reason'];
64 $user = $this->getUser();
65
66 // Check that the user is allowed to carry out the deletion
67 $this->checkTitleUserPermissions( $titleObj, 'delete' );
68
69 // If change tagging was requested, check that the user is allowed to tag,
70 // and the tags are valid
71 if ( $params['tags'] ) {
72 $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user );
73 if ( !$tagStatus->isOK() ) {
74 $this->dieStatus( $tagStatus );
75 }
76 }
77
78 if ( $titleObj->getNamespace() == NS_FILE ) {
79 $status = self::deleteFile(
80 $pageObj,
81 $user,
82 $params['oldimage'],
83 $reason,
84 false,
85 $params['tags']
86 );
87 } else {
88 $status = self::delete( $pageObj, $user, $reason, $params['tags'] );
89 }
90
91 if ( !$status->isOK() ) {
92 $this->dieStatus( $status );
93 }
94 $this->addMessagesFromStatus( $status, [ 'warning' ], [ 'delete-scheduled' ] );
95
96 // Deprecated parameters
97 if ( $params['watch'] ) {
98 $watch = 'watch';
99 } elseif ( $params['unwatch'] ) {
100 $watch = 'unwatch';
101 } else {
102 $watch = $params['watchlist'];
103 }
104
105 $watchlistExpiry = $this->getExpiryFromParams( $params );
106 $this->setWatch( $watch, $titleObj, $user, 'watchdeletion', $watchlistExpiry );
107
108 $r = [
109 'title' => $titleObj->getPrefixedText(),
110 'reason' => $reason,
111 ];
112
113 if ( $status->hasMessage( 'delete-scheduled' ) ) {
114 $r['scheduled'] = true;
115 }
116 if ( $status->value !== null ) {
117 // Scheduled deletions don't currently have a log entry available at this point
118 $r['logid'] = $status->value;
119 }
120 $this->getResult()->addValue( null, $this->getModuleName(), $r );
121 }
122
132 private static function delete( WikiPage $page, User $user, &$reason = null, $tags = [] ) {
133 $title = $page->getTitle();
134
135 // Auto-generate a summary, if necessary
136 if ( $reason === null ) {
137 // Need to pass a throwaway variable because generateReason expects
138 // a reference
139 $hasHistory = false;
140 $reason = $page->getAutoDeleteReason( $hasHistory );
141 if ( $reason === false ) {
142 // Should be reachable only if the page has no revisions
143 return Status::newFatal( 'cannotdelete', $title->getPrefixedText() ); // @codeCoverageIgnore
144 }
145 }
146
147 $error = '';
148
149 // Luckily, WikiPage provides a reusable delete function that does the hard work for us
150 return $page->doDeleteArticleReal(
151 $reason,
152 $user,
153 false, // don't suppress
154 null, // unused
155 $error,
156 null, // unused
157 $tags
158 );
159 }
160
165 protected static function canDeleteFile( File $file ) {
166 return $file->exists() && $file->isLocal() && !$file->getRedirected();
167 }
168
178 private static function deleteFile( WikiPage $page, User $user, $oldimage,
179 &$reason = null, $suppress = false, $tags = []
180 ) {
181 $title = $page->getTitle();
182
183 // @phan-suppress-next-line PhanUndeclaredMethod There's no right typehint for it
184 $file = $page->getFile();
185 if ( !self::canDeleteFile( $file ) ) {
186 return self::delete( $page, $user, $reason, $tags );
187 }
188
189 if ( $oldimage ) {
190 if ( !FileDeleteForm::isValidOldSpec( $oldimage ) ) {
191 return Status::newFatal( 'invalidoldimage' );
192 }
193 $oldfile = MediaWikiServices::getInstance()->getRepoGroup()
194 ->getLocalRepo()->newFromArchiveName( $title, $oldimage );
195 if ( !$oldfile->exists() || !$oldfile->isLocal() || $oldfile->getRedirected() ) {
196 return Status::newFatal( 'nodeleteablefile' );
197 }
198 }
199
200 if ( $reason === null ) { // Log and RC don't like null reasons
201 $reason = '';
202 }
203
204 return FileDeleteForm::doDelete( $title, $file, $oldimage, $reason, $suppress, $user, $tags );
205 }
206
207 public function mustBePosted() {
208 return true;
209 }
210
211 public function isWriteMode() {
212 return true;
213 }
214
215 public function getAllowedParams() {
216 $params = [
217 'title' => null,
218 'pageid' => [
219 ApiBase::PARAM_TYPE => 'integer'
220 ],
221 'reason' => null,
222 'tags' => [
223 ApiBase::PARAM_TYPE => 'tags',
225 ],
226 'watch' => [
227 ApiBase::PARAM_DFLT => false,
229 ],
230 ];
231
232 // Params appear in the docs in the order they are defined,
233 // which is why this is here and not at the bottom.
234 $params += $this->getWatchlistParams();
235
236 return $params + [
237 'unwatch' => [
238 ApiBase::PARAM_DFLT => false,
240 ],
241 'oldimage' => null,
242 ];
243 }
244
245 public function needsToken() {
246 return 'csrf';
247 }
248
249 protected function getExamplesMessages() {
250 return [
251 'action=delete&title=Main%20Page&token=123ABC'
252 => 'apihelp-delete-example-simple',
253 'action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
254 => 'apihelp-delete-example-reason',
255 ];
256 }
257
258 public function getHelpUrls() {
259 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Delete';
260 }
261}
getExpiryFromParams(array $params)
Get formatted expiry from the given parameters, or null if no expiry was provided.
setWatch(string $watch, Title $title, User $user, ?string $userOption=null, ?string $expiry=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
getWatchlistParams(array $watchOptions=[])
Get additional allow params specific to watchlisting.
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:52
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1437
const PARAM_DEPRECATED
Definition ApiBase.php:98
addMessagesFromStatus(StatusValue $status, $types=[ 'warning', 'error'], array $filter=[])
Add warnings and/or errors from a Status.
Definition ApiBase.php:1416
const PARAM_TYPE
Definition ApiBase.php:78
const PARAM_DFLT
Definition ApiBase.php:70
getResult()
Get the result object.
Definition ApiBase.php:620
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:772
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:499
checkTitleUserPermissions(LinkTarget $linkTarget, $actions, array $options=[])
Helper function for permission-denied errors.
Definition ApiBase.php:1564
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition ApiBase.php:1041
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition ApiBase.php:1495
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition ApiBase.php:1294
const PARAM_ISMULTI
Definition ApiBase.php:74
API module that facilitates deleting pages.
Definition ApiDelete.php:31
static delete(WikiPage $page, User $user, &$reason=null, $tags=[])
We have our own delete() function, since Article.php's implementation is split in two phases.
execute()
Extracts the title and reason from the request parameters and invokes the local delete() function wit...
Definition ApiDelete.php:49
needsToken()
Returns the token type this module requires in order to execute.
getExamplesMessages()
Returns usage examples for this module.
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
getHelpUrls()
Return links to more detailed help pages about the module.
static canDeleteFile(File $file)
static deleteFile(WikiPage $page, User $user, $oldimage, &$reason=null, $suppress=false, $tags=[])
__construct(ApiMain $mainModule, $moduleName, $modulePrefix='')
Stable to call.
Definition ApiDelete.php:35
isWriteMode()
Indicates whether this module requires write mode.
mustBePosted()
Indicates whether this module must be called with a POST request Stable to override.
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:47
static canAddTagsAccompanyingChange(array $tags, User $user=null)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
getUser()
Stable to override.
static doDelete(&$title, &$file, &$oldimage, $reason, $suppress, User $user=null, $tags=[])
Really delete the file.
static isValidOldSpec( $oldimage)
Is the provided oldimage value valid?
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:63
MediaWikiServices is the service locator for the application scope of MediaWiki.
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition User.php:60
Class representing a MediaWiki article and history.
Definition WikiPage.php:51
getAutoDeleteReason(&$hasHistory)
Auto-generates a deletion reason.
doDeleteArticleReal( $reason, $user=false, $suppress=false, $u2=null, &$error='', User $deleter=null, $tags=[], $logsubtype='delete', $immediate=false)
Back-end article deletion Deletes the article with database consistency, writes logs,...
getTitle()
Get the title object of the article.
Definition WikiPage.php:318
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
const NS_FILE
Definition Defines.php:76
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42