Change layout of the mustBePosted format to standardise it
[lhc/web/wiklou.git] / includes / api / ApiMove.php
1 <?php
2
3 /*
4 * Created on Oct 31, 2007
5 * API for MediaWiki 1.8+
6 *
7 * Copyright (C) 2007 Roan Kattouw <Firstname>.<Lastname>@home.nl
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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
22 * http://www.gnu.org/copyleft/gpl.html
23 */
24
25 if ( !defined( 'MEDIAWIKI' ) ) {
26 // Eclipse helper - will be ignored in production
27 require_once ( "ApiBase.php" );
28 }
29
30
31 /**
32 * @ingroup API
33 */
34 class ApiMove extends ApiBase {
35
36 public function __construct( $main, $action ) {
37 parent :: __construct( $main, $action );
38 }
39
40 public function execute() {
41 global $wgUser;
42 $params = $this->extractRequestParams();
43 if ( is_null( $params['reason'] ) )
44 $params['reason'] = '';
45
46 $this->requireOnlyOneParameter( $params, 'from', 'fromid' );
47 if ( !isset( $params['to'] ) )
48 $this->dieUsageMsg( array( 'missingparam', 'to' ) );
49 if ( !isset( $params['token'] ) )
50 $this->dieUsageMsg( array( 'missingparam', 'token' ) );
51 if ( !$wgUser->matchEditToken( $params['token'] ) )
52 $this->dieUsageMsg( array( 'sessionfailure' ) );
53
54 if ( isset( $params['from'] ) )
55 {
56 $fromTitle = Title::newFromText( $params['from'] );
57 if ( !$fromTitle )
58 $this->dieUsageMsg( array( 'invalidtitle', $params['from'] ) );
59 }
60 else if ( isset( $params['fromid'] ) )
61 {
62 $fromTitle = Title::newFromID( $params['fromid'] );
63 if ( !$fromTitle )
64 $this->dieUsageMsg( array( 'nosuchpageid', $params['fromid'] ) );
65 }
66
67 if ( !$fromTitle->exists() )
68 $this->dieUsageMsg( array( 'notanarticle' ) );
69 $fromTalk = $fromTitle->getTalkPage();
70
71 $toTitle = Title::newFromText( $params['to'] );
72 if ( !$toTitle )
73 $this->dieUsageMsg( array( 'invalidtitle', $params['to'] ) );
74 $toTalk = $toTitle->getTalkPage();
75
76 if ( $toTitle->getNamespace() == NS_FILE
77 && !RepoGroup::singleton()->getLocalRepo()->findFile( $toTitle )
78 && wfFindFile( $toTitle ) )
79 {
80 if ( !$params['ignorewarnings'] && $wgUser->isAllowed( 'reupload-shared' ) ) {
81 $this->dieUsageMsg( array( 'sharedfile-exists' ) );
82 } elseif ( !$wgUser->isAllowed( 'reupload-shared' ) ) {
83 $this->dieUsageMsg( array( 'cantoverwrite-sharedfile' ) );
84 }
85 }
86
87 // Move the page
88 $hookErr = null;
89 $retval = $fromTitle->moveTo( $toTitle, true, $params['reason'], !$params['noredirect'] );
90 if ( $retval !== true )
91 $this->dieUsageMsg( reset( $retval ) );
92
93 $r = array( 'from' => $fromTitle->getPrefixedText(), 'to' => $toTitle->getPrefixedText(), 'reason' => $params['reason'] );
94 if ( !$params['noredirect'] || !$wgUser->isAllowed( 'suppressredirect' ) )
95 $r['redirectcreated'] = '';
96
97 // Move the talk page
98 if ( $params['movetalk'] && $fromTalk->exists() && !$fromTitle->isTalkPage() )
99 {
100 $retval = $fromTalk->moveTo( $toTalk, true, $params['reason'], !$params['noredirect'] );
101 if ( $retval === true )
102 {
103 $r['talkfrom'] = $fromTalk->getPrefixedText();
104 $r['talkto'] = $toTalk->getPrefixedText();
105 }
106 // We're not gonna dieUsage() on failure, since we already changed something
107 else
108 {
109 $parsed = $this->parseMsg( reset( $retval ) );
110 $r['talkmove-error-code'] = $parsed['code'];
111 $r['talkmove-error-info'] = $parsed['info'];
112 }
113 }
114
115 // Move subpages
116 if ( $params['movesubpages'] )
117 {
118 $r['subpages'] = $this->moveSubpages( $fromTitle, $toTitle,
119 $params['reason'], $params['noredirect'] );
120 $this->getResult()->setIndexedTagName( $r['subpages'], 'subpage' );
121 if ( $params['movetalk'] )
122 {
123 $r['subpages-talk'] = $this->moveSubpages( $fromTalk, $toTalk,
124 $params['reason'], $params['noredirect'] );
125 $this->getResult()->setIndexedTagName( $r['subpages-talk'], 'subpage' );
126 }
127 }
128
129 // Watch pages
130 if ( $params['watch'] || $wgUser->getOption( 'watchmoves' ) )
131 {
132 $wgUser->addWatch( $fromTitle );
133 $wgUser->addWatch( $toTitle );
134 }
135 else if ( $params['unwatch'] )
136 {
137 $wgUser->removeWatch( $fromTitle );
138 $wgUser->removeWatch( $toTitle );
139 }
140 $this->getResult()->addValue( null, $this->getModuleName(), $r );
141 }
142
143 public function moveSubpages( $fromTitle, $toTitle, $reason, $noredirect )
144 {
145 $retval = array();
146 $success = $fromTitle->moveSubpages( $toTitle, true, $reason, !$noredirect );
147 if ( isset( $success[0] ) )
148 return array( 'error' => $this->parseMsg( $success ) );
149 else
150 {
151 // At least some pages could be moved
152 // Report each of them separately
153 foreach ( $success as $oldTitle => $newTitle )
154 {
155 $r = array( 'from' => $oldTitle );
156 if ( is_array( $newTitle ) )
157 $r['error'] = $this->parseMsg( reset( $newTitle ) );
158 else
159 // Success
160 $r['to'] = $newTitle;
161 $retval[] = $r;
162 }
163 }
164 return $retval;
165 }
166
167 public function mustBePosted() {
168 return true;
169 }
170
171 public function isWriteMode() {
172 return true;
173 }
174
175 public function getAllowedParams() {
176 return array (
177 'from' => null,
178 'fromid' => array(
179 ApiBase::PARAM_TYPE => 'integer'
180 ),
181 'to' => null,
182 'token' => null,
183 'reason' => null,
184 'movetalk' => false,
185 'movesubpages' => false,
186 'noredirect' => false,
187 'watch' => false,
188 'unwatch' => false,
189 'ignorewarnings' => false
190 );
191 }
192
193 public function getParamDescription() {
194 return array (
195 'from' => 'Title of the page you want to move. Cannot be used together with fromid.',
196 'fromid' => 'Page ID of the page you want to move. Cannot be used together with from.',
197 'to' => 'Title you want to rename the page to.',
198 'token' => 'A move token previously retrieved through prop=info',
199 'reason' => 'Reason for the move (optional).',
200 'movetalk' => 'Move the talk page, if it exists.',
201 'movesubpages' => 'Move subpages, if applicable',
202 'noredirect' => 'Don\'t create a redirect',
203 'watch' => 'Add the page and the redirect to your watchlist',
204 'unwatch' => 'Remove the page and the redirect from your watchlist',
205 'ignorewarnings' => 'Ignore any warnings'
206 );
207 }
208
209 public function getDescription() {
210 return array(
211 'Move a page.'
212 );
213 }
214
215 public function getPossibleErrors() {
216 return array_merge( parent::getPossibleErrors(), array(
217 array( 'missingparam', 'to' ),
218 array( 'missingparam', 'token' ),
219 array( 'sessionfailure' ),
220 array( 'invalidtitle', 'from' ),
221 array( 'nosuchpageid', 'fromid' ),
222 array( 'notanarticle' ),
223 array( 'invalidtitle', 'to' ),
224 array( 'sharedfile-exists' ),
225 ) );
226 }
227
228 protected function getExamples() {
229 return array (
230 'api.php?action=move&from=Exampel&to=Example&token=123ABC&reason=Misspelled%20title&movetalk&noredirect'
231 );
232 }
233
234 public function getVersion() {
235 return __CLASS__ . ': $Id$';
236 }
237 }