MediaWiki  master
ApiDelete.php
Go to the documentation of this file.
1 <?php
24 
31 class 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, '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',
224  ApiBase::PARAM_ISMULTI => true,
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 }
ApiMain
This is the main API class, used for both external and internal processing.
Definition: ApiMain.php:47
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:67
WikiPage\getAutoDeleteReason
getAutoDeleteReason(&$hasHistory)
Auto-generates a deletion reason.
Definition: WikiPage.php:3785
getExpiryFromParams
getExpiryFromParams(array $params)
Get formatted expiry from the given parameters, or null if no expiry was provided.
Definition: ApiWatchlistTrait.php:132
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:154
ApiDelete\__construct
__construct(ApiMain $mainModule, $moduleName, $modulePrefix='')
Stable to call.
Definition: ApiDelete.php:35
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:1382
ApiBase\getTitleOrPageId
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition: ApiBase.php:986
ApiBase\PARAM_TYPE
const PARAM_TYPE
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:71
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:565
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:52
NS_FILE
const NS_FILE
Definition: Defines.php:75
$file
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition: router.php:42
ApiBase\addMessagesFromStatus
addMessagesFromStatus(StatusValue $status, $types=[ 'warning', 'error'], array $filter=[])
Add warnings and/or errors from a Status.
Definition: ApiBase.php:1361
ApiDelete\canDeleteFile
static canDeleteFile(File $file)
Definition: ApiDelete.php:165
ContextSource\getUser
getUser()
Stable to override.
Definition: ContextSource.php:131
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:52
ApiBase\PARAM_DEPRECATED
const PARAM_DEPRECATED
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:76
ApiDelete\needsToken
needsToken()
Returns the token type this module requires in order to execute.
Definition: ApiDelete.php:245
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:63
ApiDelete\getAllowedParams
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
Definition: ApiDelete.php:215
ApiDelete
API module that facilitates deleting pages.
Definition: ApiDelete.php:31
ApiDelete\delete
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.
Definition: ApiDelete.php:132
ApiDelete\mustBePosted
mustBePosted()
Indicates whether this module must be called with a POST request Stable to override.
Definition: ApiDelete.php:207
ApiDelete\execute
execute()
Extracts the title and reason from the request parameters and invokes the local delete() function wit...
Definition: ApiDelete.php:49
WikiPage\getTitle
getTitle()
Get the title object of the article.
Definition: WikiPage.php:281
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:717
$title
$title
Definition: testCompression.php:38
ApiDelete\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.
Definition: ApiDelete.php:249
ApiDelete\getHelpUrls
getHelpUrls()
Return links to more detailed help pages about the module.
Definition: ApiDelete.php:258
ApiBase\useTransactionalTimeLimit
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition: ApiBase.php:1239
ApiWatchlistTrait
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
Definition: ApiWatchlistTrait.php:17
ApiDelete\deleteFile
static deleteFile(WikiPage $page, User $user, $oldimage, &$reason=null, $suppress=false, $tags=[])
Definition: ApiDelete.php:178
ChangeTags\canAddTagsAccompanyingChange
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...
Definition: ChangeTags.php:544
getWatchlistParams
getWatchlistParams(array $watchOptions=[])
Get additional allow params specific to watchlisting.
Definition: ApiWatchlistTrait.php:35
setWatch
setWatch(string $watch, Title $titleObj, ?string $userOption=null, ?string $expiry=null)
Set a watch (or unwatch) based the based on a watchlist parameter.
Definition: ApiWatchlistTrait.php:71
ApiBase\PARAM_DFLT
const PARAM_DFLT
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:69
WikiPage\doDeleteArticleReal
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,...
Definition: WikiPage.php:2756
ApiBase\dieStatus
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition: ApiBase.php:1440
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:444
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
(boolean) Inverse of IntegerDef::PARAM_IGNORE_RANGE
Definition: ApiBase.php:70
ApiDelete\isWriteMode
isWriteMode()
Indicates whether this module requires write mode.
Definition: ApiDelete.php:211
FileDeleteForm\doDelete
static doDelete(&$title, &$file, &$oldimage, $reason, $suppress, User $user=null, $tags=[])
Really delete the file.
Definition: FileDeleteForm.php:193
ApiBase\checkTitleUserPermissions
checkTitleUserPermissions(LinkTarget $linkTarget, $actions, array $options=[])
Helper function for permission-denied errors.
Definition: ApiBase.php:1509
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:56
FileDeleteForm\isValidOldSpec
static isValidOldSpec( $oldimage)
Is the provided oldimage value valid?
Definition: FileDeleteForm.php:504