MediaWiki REL1_37
ApiDelete.php
Go to the documentation of this file.
1<?php
26
33class ApiDelete extends ApiBase {
34
36
38 private $repoGroup;
39
47 public function __construct(
48 ApiMain $mainModule,
49 $moduleName,
53 ) {
54 parent::__construct( $mainModule, $moduleName );
55 $this->repoGroup = $repoGroup;
56
57 // Variables needed in ApiWatchlistTrait trait
58 $this->watchlistExpiryEnabled = $this->getConfig()->get( 'WatchlistExpiry' );
59 $this->watchlistMaxDuration = $this->getConfig()->get( 'WatchlistExpiryMaxDuration' );
60 $this->watchlistManager = $watchlistManager;
61 $this->userOptionsLookup = $userOptionsLookup;
62 }
63
71 public function execute() {
73
74 $params = $this->extractRequestParams();
75
76 $pageObj = $this->getTitleOrPageId( $params, 'fromdbmaster' );
77 $titleObj = $pageObj->getTitle();
78 $this->getErrorFormatter()->setContextTitle( $titleObj );
79 if ( !$pageObj->exists() &&
80 // @phan-suppress-next-line PhanUndeclaredMethod
81 !( $titleObj->getNamespace() === NS_FILE && self::canDeleteFile( $pageObj->getFile() ) )
82 ) {
83 $this->dieWithError( 'apierror-missingtitle' );
84 }
85
86 $reason = $params['reason'];
87 $user = $this->getUser();
88
89 // Check that the user is allowed to carry out the deletion
90 $this->checkTitleUserPermissions( $titleObj, 'delete' );
91
92 // If change tagging was requested, check that the user is allowed to tag,
93 // and the tags are valid
94 if ( $params['tags'] ) {
95 $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $this->getAuthority() );
96 if ( !$tagStatus->isOK() ) {
97 $this->dieStatus( $tagStatus );
98 }
99 }
100
101 if ( $titleObj->getNamespace() === NS_FILE ) {
102 $status = $this->deleteFile(
103 $pageObj,
104 $user,
105 $params['oldimage'],
106 $reason,
107 false,
108 $params['tags']
109 );
110 } else {
111 $status = self::delete( $pageObj, $user, $reason, $params['tags'] );
112 }
113
114 if ( !$status->isOK() ) {
115 $this->dieStatus( $status );
116 }
117 $this->addMessagesFromStatus( $status, [ 'warning' ], [ 'delete-scheduled' ] );
118
119 // Deprecated parameters
120 if ( $params['watch'] ) {
121 $watch = 'watch';
122 } elseif ( $params['unwatch'] ) {
123 $watch = 'unwatch';
124 } else {
125 $watch = $params['watchlist'];
126 }
127
128 $watchlistExpiry = $this->getExpiryFromParams( $params );
129 $this->setWatch( $watch, $titleObj, $user, 'watchdeletion', $watchlistExpiry );
130
131 $r = [
132 'title' => $titleObj->getPrefixedText(),
133 'reason' => $reason,
134 ];
135
136 if ( $status->hasMessage( 'delete-scheduled' ) ) {
137 $r['scheduled'] = true;
138 }
139 if ( $status->value !== null ) {
140 // Scheduled deletions don't currently have a log entry available at this point
141 $r['logid'] = $status->value;
142 }
143 $this->getResult()->addValue( null, $this->getModuleName(), $r );
144 }
145
155 private static function delete( WikiPage $page, UserIdentity $deleter, &$reason = null, $tags = [] ) {
156 $title = $page->getTitle();
157
158 // Auto-generate a summary, if necessary
159 if ( $reason === null ) {
160 // Need to pass a throwaway variable because generateReason expects
161 // a reference
162 $hasHistory = false;
163 $reason = $page->getAutoDeleteReason( $hasHistory );
164 if ( $reason === false ) {
165 // Should be reachable only if the page has no revisions
166 return Status::newFatal( 'cannotdelete', $title->getPrefixedText() ); // @codeCoverageIgnore
167 }
168 }
169
170 $error = '';
171
172 // Luckily, WikiPage provides a reusable delete function that does the hard work for us
173 return $page->doDeleteArticleReal(
174 $reason,
175 $deleter,
176 false, // don't suppress
177 null, // unused
178 $error,
179 null, // unused
180 $tags
181 );
182 }
183
188 protected static function canDeleteFile( File $file ) {
189 return $file->exists() && $file->isLocal() && !$file->getRedirected();
190 }
191
201 private function deleteFile( WikiPage $page, UserIdentity $deleter, $oldimage,
202 &$reason = null, $suppress = false, $tags = []
203 ) {
204 $title = $page->getTitle();
205
206 // @phan-suppress-next-line PhanUndeclaredMethod There's no right typehint for it
207 $file = $page->getFile();
208 if ( !self::canDeleteFile( $file ) ) {
209 return self::delete( $page, $deleter, $reason, $tags );
210 }
211
212 if ( $oldimage ) {
213 if ( !FileDeleteForm::isValidOldSpec( $oldimage ) ) {
214 return Status::newFatal( 'invalidoldimage' );
215 }
216 $oldfile = $this->repoGroup->getLocalRepo()->newFromArchiveName( $title, $oldimage );
217 if ( !$oldfile->exists() || !$oldfile->isLocal() || $oldfile->getRedirected() ) {
218 return Status::newFatal( 'nodeleteablefile' );
219 }
220 }
221
222 if ( $reason === null ) { // Log and RC don't like null reasons
223 $reason = '';
224 }
225
226 return FileDeleteForm::doDelete( $title, $file, $oldimage, $reason, $suppress, $deleter, $tags );
227 }
228
229 public function mustBePosted() {
230 return true;
231 }
232
233 public function isWriteMode() {
234 return true;
235 }
236
237 public function getAllowedParams() {
238 $params = [
239 'title' => null,
240 'pageid' => [
241 ApiBase::PARAM_TYPE => 'integer'
242 ],
243 'reason' => null,
244 'tags' => [
245 ApiBase::PARAM_TYPE => 'tags',
247 ],
248 'watch' => [
249 ApiBase::PARAM_DFLT => false,
251 ],
252 ];
253
254 // Params appear in the docs in the order they are defined,
255 // which is why this is here and not at the bottom.
256 $params += $this->getWatchlistParams();
257
258 return $params + [
259 'unwatch' => [
260 ApiBase::PARAM_DFLT => false,
262 ],
263 'oldimage' => null,
264 ];
265 }
266
267 public function needsToken() {
268 return 'csrf';
269 }
270
271 protected function getExamplesMessages() {
272 return [
273 'action=delete&title=Main%20Page&token=123ABC'
274 => 'apihelp-delete-example-simple',
275 'action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
276 => 'apihelp-delete-example-reason',
277 ];
278 }
279
280 public function getHelpUrls() {
281 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Delete';
282 }
283}
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.
WatchlistManager $watchlistManager
UserOptionsLookup $userOptionsLookup
const NS_FILE
Definition Defines.php:70
This abstract class implements many basic API functions, and is the base of all API classes.
Definition ApiBase.php:55
dieWithError( $msg, $code=null, $data=null, $httpCode=0)
Abort execution with an error.
Definition ApiBase.php:1436
const PARAM_DEPRECATED
Definition ApiBase.php:101
addMessagesFromStatus(StatusValue $status, $types=[ 'warning', 'error'], array $filter=[])
Add warnings and/or errors from a Status.
Definition ApiBase.php:1414
const PARAM_TYPE
Definition ApiBase.php:81
getErrorFormatter()
Definition ApiBase.php:639
const PARAM_DFLT
Definition ApiBase.php:73
getResult()
Get the result object.
Definition ApiBase.php:628
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition ApiBase.php:764
checkTitleUserPermissions( $pageIdentity, $actions, array $options=[])
Helper function for permission-denied errors.
Definition ApiBase.php:1565
getModuleName()
Get the name of the module being executed by this instance.
Definition ApiBase.php:497
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition ApiBase.php:1033
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:1293
const PARAM_ISMULTI
Definition ApiBase.php:77
API module that facilitates deleting pages.
Definition ApiDelete.php:33
execute()
Extracts the title and reason from the request parameters and invokes the local delete() function wit...
Definition ApiDelete.php:71
needsToken()
Returns the token type this module requires in order to execute.
__construct(ApiMain $mainModule, $moduleName, RepoGroup $repoGroup, WatchlistManager $watchlistManager, UserOptionsLookup $userOptionsLookup)
Definition ApiDelete.php:47
deleteFile(WikiPage $page, UserIdentity $deleter, $oldimage, &$reason=null, $suppress=false, $tags=[])
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 delete(WikiPage $page, UserIdentity $deleter, &$reason=null, $tags=[])
We have our own delete() function, since Article.php's implementation is split in two phases.
RepoGroup $repoGroup
Definition ApiDelete.php:38
isWriteMode()
Indicates whether this module requires write mode.
mustBePosted()
Indicates whether this module must be called with a POST request.
This is the main API class, used for both external and internal processing.
Definition ApiMain.php:49
static canAddTagsAccompanyingChange(array $tags, Authority $performer=null)
Is it OK to allow the user to apply all the specified tags at the same time as they edit/make the cha...
static isValidOldSpec( $oldimage)
Is the provided oldimage value valid?
static doDelete(&$title, &$file, &$oldimage, $reason, $suppress, UserIdentity $user, $tags=[])
Really delete the file.
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition File.php:66
Provides access to user options.
Prioritized list of file repositories.
Definition RepoGroup.php:33
Class representing a MediaWiki article and history.
Definition WikiPage.php:60
doDeleteArticleReal( $reason, UserIdentity $deleter, $suppress=false, $u1=null, &$error='', $u2=null, $tags=[], $logsubtype='delete', $immediate=false)
Back-end article deletion Deletes the article with database consistency, writes logs,...
getAutoDeleteReason(&$hasHistory)
Auto-generates a deletion reason.
getTitle()
Get the title object of the article.
Definition WikiPage.php:311
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
Interface for objects representing user identity.
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42