]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/api/ApiDelete.php
MediaWiki 1.30.2-scripts2
[autoinstallsdev/mediawiki.git] / includes / api / ApiDelete.php
1 <?php
2 /**
3  *
4  *
5  * Created on Jun 30, 2007
6  *
7  * Copyright © 2007 Roan Kattouw "<Firstname>.<Lastname>@gmail.com"
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write to the Free Software Foundation, Inc.,
21  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
22  * http://www.gnu.org/copyleft/gpl.html
23  *
24  * @file
25  */
26
27 /**
28  * API module that facilitates deleting pages. The API equivalent of action=delete.
29  * Requires API write mode to be enabled.
30  *
31  * @ingroup API
32  */
33 class ApiDelete extends ApiBase {
34         /**
35          * Extracts the title and reason from the request parameters and invokes
36          * the local delete() function with these as arguments. It does not make use of
37          * the delete function specified by Article.php. If the deletion succeeds, the
38          * details of the article deleted and the reason for deletion are added to the
39          * result object.
40          */
41         public function execute() {
42                 $this->useTransactionalTimeLimit();
43
44                 $params = $this->extractRequestParams();
45
46                 $pageObj = $this->getTitleOrPageId( $params, 'fromdbmaster' );
47                 $titleObj = $pageObj->getTitle();
48                 if ( !$pageObj->exists() &&
49                         !( $titleObj->getNamespace() == NS_FILE && self::canDeleteFile( $pageObj->getFile() ) )
50                 ) {
51                         $this->dieWithError( 'apierror-missingtitle' );
52                 }
53
54                 $reason = $params['reason'];
55                 $user = $this->getUser();
56
57                 // Check that the user is allowed to carry out the deletion
58                 $this->checkTitleUserPermissions( $titleObj, 'delete' );
59
60                 // If change tagging was requested, check that the user is allowed to tag,
61                 // and the tags are valid
62                 if ( count( $params['tags'] ) ) {
63                         $tagStatus = ChangeTags::canAddTagsAccompanyingChange( $params['tags'], $user );
64                         if ( !$tagStatus->isOK() ) {
65                                 $this->dieStatus( $tagStatus );
66                         }
67                 }
68
69                 if ( $titleObj->getNamespace() == NS_FILE ) {
70                         $status = self::deleteFile(
71                                 $pageObj,
72                                 $user,
73                                 $params['oldimage'],
74                                 $reason,
75                                 false,
76                                 $params['tags']
77                         );
78                 } else {
79                         $status = self::delete( $pageObj, $user, $reason, $params['tags'] );
80                 }
81
82                 if ( !$status->isGood() ) {
83                         $this->dieStatus( $status );
84                 }
85
86                 // Deprecated parameters
87                 if ( $params['watch'] ) {
88                         $watch = 'watch';
89                 } elseif ( $params['unwatch'] ) {
90                         $watch = 'unwatch';
91                 } else {
92                         $watch = $params['watchlist'];
93                 }
94                 $this->setWatch( $watch, $titleObj, 'watchdeletion' );
95
96                 $r = [
97                         'title' => $titleObj->getPrefixedText(),
98                         'reason' => $reason,
99                         'logid' => $status->value
100                 ];
101                 $this->getResult()->addValue( null, $this->getModuleName(), $r );
102         }
103
104         /**
105          * We have our own delete() function, since Article.php's implementation is split in two phases
106          *
107          * @param Page|WikiPage $page Page or WikiPage object to work on
108          * @param User $user User doing the action
109          * @param string|null &$reason Reason for the deletion. Autogenerated if null
110          * @param array $tags Tags to tag the deletion with
111          * @return Status
112          */
113         protected static function delete( Page $page, User $user, &$reason = null, $tags = [] ) {
114                 $title = $page->getTitle();
115
116                 // Auto-generate a summary, if necessary
117                 if ( is_null( $reason ) ) {
118                         // Need to pass a throwaway variable because generateReason expects
119                         // a reference
120                         $hasHistory = false;
121                         $reason = $page->getAutoDeleteReason( $hasHistory );
122                         if ( $reason === false ) {
123                                 return Status::newFatal( 'cannotdelete', $title->getPrefixedText() );
124                         }
125                 }
126
127                 $error = '';
128
129                 // Luckily, Article.php provides a reusable delete function that does the hard work for us
130                 return $page->doDeleteArticleReal( $reason, false, 0, true, $error, $user, $tags );
131         }
132
133         /**
134          * @param File $file
135          * @return bool
136          */
137         protected static function canDeleteFile( File $file ) {
138                 return $file->exists() && $file->isLocal() && !$file->getRedirected();
139         }
140
141         /**
142          * @param Page $page Object to work on
143          * @param User $user User doing the action
144          * @param string $oldimage Archive name
145          * @param string &$reason Reason for the deletion. Autogenerated if null.
146          * @param bool $suppress Whether to mark all deleted versions as restricted
147          * @param array $tags Tags to tag the deletion with
148          * @return Status
149          */
150         protected static function deleteFile( Page $page, User $user, $oldimage,
151                 &$reason = null, $suppress = false, $tags = []
152         ) {
153                 $title = $page->getTitle();
154
155                 $file = $page->getFile();
156                 if ( !self::canDeleteFile( $file ) ) {
157                         return self::delete( $page, $user, $reason, $tags );
158                 }
159
160                 if ( $oldimage ) {
161                         if ( !FileDeleteForm::isValidOldSpec( $oldimage ) ) {
162                                 return Status::newFatal( 'invalidoldimage' );
163                         }
164                         $oldfile = RepoGroup::singleton()->getLocalRepo()->newFromArchiveName( $title, $oldimage );
165                         if ( !$oldfile->exists() || !$oldfile->isLocal() || $oldfile->getRedirected() ) {
166                                 return Status::newFatal( 'nodeleteablefile' );
167                         }
168                 }
169
170                 if ( is_null( $reason ) ) { // Log and RC don't like null reasons
171                         $reason = '';
172                 }
173
174                 return FileDeleteForm::doDelete( $title, $file, $oldimage, $reason, $suppress, $user, $tags );
175         }
176
177         public function mustBePosted() {
178                 return true;
179         }
180
181         public function isWriteMode() {
182                 return true;
183         }
184
185         public function getAllowedParams() {
186                 return [
187                         'title' => null,
188                         'pageid' => [
189                                 ApiBase::PARAM_TYPE => 'integer'
190                         ],
191                         'reason' => null,
192                         'tags' => [
193                                 ApiBase::PARAM_TYPE => 'tags',
194                                 ApiBase::PARAM_ISMULTI => true,
195                         ],
196                         'watch' => [
197                                 ApiBase::PARAM_DFLT => false,
198                                 ApiBase::PARAM_DEPRECATED => true,
199                         ],
200                         'watchlist' => [
201                                 ApiBase::PARAM_DFLT => 'preferences',
202                                 ApiBase::PARAM_TYPE => [
203                                         'watch',
204                                         'unwatch',
205                                         'preferences',
206                                         'nochange'
207                                 ],
208                         ],
209                         'unwatch' => [
210                                 ApiBase::PARAM_DFLT => false,
211                                 ApiBase::PARAM_DEPRECATED => true,
212                         ],
213                         'oldimage' => null,
214                 ];
215         }
216
217         public function needsToken() {
218                 return 'csrf';
219         }
220
221         protected function getExamplesMessages() {
222                 return [
223                         'action=delete&title=Main%20Page&token=123ABC'
224                                 => 'apihelp-delete-example-simple',
225                         'action=delete&title=Main%20Page&token=123ABC&reason=Preparing%20for%20move'
226                                 => 'apihelp-delete-example-reason',
227                 ];
228         }
229
230         public function getHelpUrls() {
231                 return 'https://www.mediawiki.org/wiki/Special:MyLanguage/API:Delete';
232         }
233 }