MediaWiki  master
ApiDelete.php
Go to the documentation of this file.
1 <?php
26 
33 class 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',
246  ApiBase::PARAM_ISMULTI => true,
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 }
ApiBase\checkTitleUserPermissions
checkTitleUserPermissions( $pageIdentity, $actions, array $options=[])
Helper function for permission-denied errors.
Definition: ApiBase.php:1514
ApiMain
This is the main API class, used for both external and internal processing.
Definition: ApiMain.php:49
ContextSource\getConfig
getConfig()
Definition: ContextSource.php:72
WikiPage\getAutoDeleteReason
getAutoDeleteReason(&$hasHistory)
Auto-generates a deletion reason.
Definition: WikiPage.php:3014
getExpiryFromParams
getExpiryFromParams(array $params)
Get formatted expiry from the given parameters, or null if no expiry was provided.
Definition: ApiWatchlistTrait.php:164
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
ApiBase\dieWithError
dieWithError( $msg, $code=null, $data=null, $httpCode=null)
Abort execution with an error.
Definition: ApiBase.php:1379
ApiBase\getTitleOrPageId
getTitleOrPageId( $params, $load=false)
Get a WikiPage object from a title or pageid param, if possible.
Definition: ApiBase.php:976
ApiBase\PARAM_TYPE
const PARAM_TYPE
Definition: ApiBase.php:72
ApiBase\getResult
getResult()
Get the result object.
Definition: ApiBase.php:571
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:60
$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:1357
ApiDelete\canDeleteFile
static canDeleteFile(File $file)
Definition: ApiDelete.php:188
ContextSource\getUser
getUser()
Definition: ContextSource.php:136
MediaWiki\User\UserIdentity
Interface for objects representing user identity.
Definition: UserIdentity.php:39
ApiBase
This abstract class implements many basic API functions, and is the base of all API classes.
Definition: ApiBase.php:55
ApiBase\PARAM_DEPRECATED
const PARAM_DEPRECATED
Definition: ApiBase.php:77
ApiDelete\delete
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.
Definition: ApiDelete.php:155
ApiDelete\needsToken
needsToken()
Returns the token type this module requires in order to execute.
Definition: ApiDelete.php:267
File
Implements some public methods and some protected utility functions which are required by multiple ch...
Definition: File.php:66
ApiDelete\getAllowedParams
getAllowedParams()
Returns an array of allowed parameters (parameter name) => (default value) or (parameter name) => (ar...
Definition: ApiDelete.php:237
MediaWiki\Watchlist\WatchlistManager
WatchlistManager service.
Definition: WatchlistManager.php:52
ApiDelete
API module that facilitates deleting pages.
Definition: ApiDelete.php:33
ApiDelete\mustBePosted
mustBePosted()
Indicates whether this module must be called with a POST request.
Definition: ApiDelete.php:229
ApiDelete\__construct
__construct(ApiMain $mainModule, $moduleName, RepoGroup $repoGroup, WatchlistManager $watchlistManager, UserOptionsLookup $userOptionsLookup)
Definition: ApiDelete.php:47
ApiDelete\execute
execute()
Extracts the title and reason from the request parameters and invokes the local delete() function wit...
Definition: ApiDelete.php:71
setWatch
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.
Definition: ApiWatchlistTrait.php:96
WikiPage\getTitle
getTitle()
Get the title object of the article.
Definition: WikiPage.php:311
ApiBase\extractRequestParams
extractRequestParams( $options=[])
Using getAllowedParams(), this function makes an array of the values provided by the user,...
Definition: ApiBase.php:707
$title
$title
Definition: testCompression.php:38
ApiDelete\deleteFile
deleteFile(WikiPage $page, UserIdentity $deleter, $oldimage, &$reason=null, $suppress=false, $tags=[])
Definition: ApiDelete.php:201
WikiPage\doDeleteArticleReal
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,...
Definition: WikiPage.php:2654
ChangeTags\canAddTagsAccompanyingChange
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...
Definition: ChangeTags.php:625
ApiDelete\getExamplesMessages
getExamplesMessages()
Returns usage examples for this module.
Definition: ApiDelete.php:271
ApiDelete\getHelpUrls
getHelpUrls()
Return links to more detailed help pages about the module.
Definition: ApiDelete.php:280
ContextSource\getAuthority
getAuthority()
Definition: ContextSource.php:144
ApiBase\useTransactionalTimeLimit
useTransactionalTimeLimit()
Call wfTransactionalTimeLimit() if this request was POSTed.
Definition: ApiBase.php:1236
MediaWiki\User\UserOptionsLookup
Provides access to user options.
Definition: UserOptionsLookup.php:29
ApiWatchlistTrait
trait ApiWatchlistTrait
An ApiWatchlistTrait adds class properties and convenience methods for APIs that allow you to watch a...
Definition: ApiWatchlistTrait.php:21
$watchlistManager
WatchlistManager $watchlistManager
Definition: ApiWatchlistTrait.php:30
$userOptionsLookup
UserOptionsLookup $userOptionsLookup
Definition: ApiWatchlistTrait.php:33
getWatchlistParams
getWatchlistParams(array $watchOptions=[])
Get additional allow params specific to watchlisting.
Definition: ApiWatchlistTrait.php:59
ApiBase\PARAM_DFLT
const PARAM_DFLT
Definition: ApiBase.php:70
ApiBase\dieStatus
dieStatus(StatusValue $status)
Throw an ApiUsageException based on the Status object.
Definition: ApiBase.php:1442
ApiBase\getModuleName
getModuleName()
Get the name of the module being executed by this instance.
Definition: ApiBase.php:440
ApiBase\PARAM_ISMULTI
const PARAM_ISMULTI
Definition: ApiBase.php:71
RepoGroup
Prioritized list of file repositories.
Definition: RepoGroup.php:32
ApiDelete\$repoGroup
RepoGroup $repoGroup
Definition: ApiDelete.php:38
FileDeleteForm\doDelete
static doDelete(&$title, &$file, &$oldimage, $reason, $suppress, UserIdentity $user, $tags=[])
Really delete the file.
Definition: FileDeleteForm.php:207
ApiDelete\isWriteMode
isWriteMode()
Indicates whether this module requires write mode.
Definition: ApiDelete.php:233
NS_FILE
const NS_FILE
Definition: Defines.php:70
ApiBase\getErrorFormatter
getErrorFormatter()
Definition: ApiBase.php:582
FileDeleteForm\isValidOldSpec
static isValidOldSpec( $oldimage)
Is the provided oldimage value valid?
Definition: FileDeleteForm.php:525