Switch some HTMLForms in special pages to OOUI
[lhc/web/wiklou.git] / includes / specials / SpecialRedirect.php
1 <?php
2 /**
3 * Implements Special:Redirect
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup SpecialPage
22 */
23
24 /**
25 * A special page that redirects to: the user for a numeric user id,
26 * the file for a given filename, or the page for a given revision id.
27 *
28 * @ingroup SpecialPage
29 * @since 1.22
30 */
31 class SpecialRedirect extends FormSpecialPage {
32
33 /**
34 * The type of the redirect (user/file/revision)
35 *
36 * @var string $mType
37 * @example 'user'
38 */
39 protected $mType;
40
41 /**
42 * The identifier/value for the redirect (which id, which file)
43 *
44 * @var string $mValue
45 * @example '42'
46 */
47 protected $mValue;
48
49 function __construct() {
50 parent::__construct( 'Redirect' );
51 $this->mType = null;
52 $this->mValue = null;
53 }
54
55 /**
56 * Set $mType and $mValue based on parsed value of $subpage.
57 * @param string $subpage
58 */
59 function setParameter( $subpage ) {
60 // parse $subpage to pull out the parts
61 $parts = explode( '/', $subpage, 2 );
62 $this->mType = count( $parts ) > 0 ? $parts[0] : null;
63 $this->mValue = count( $parts ) > 1 ? $parts[1] : null;
64 }
65
66 /**
67 * Handle Special:Redirect/user/xxxx (by redirecting to User:YYYY)
68 *
69 * @return string|null Url to redirect to, or null if $mValue is invalid.
70 */
71 function dispatchUser() {
72 if ( !ctype_digit( $this->mValue ) ) {
73 return null;
74 }
75 $user = User::newFromId( (int)$this->mValue );
76 $username = $user->getName(); // load User as side-effect
77 if ( $user->isAnon() ) {
78 return null;
79 }
80 $userpage = Title::makeTitle( NS_USER, $username );
81
82 return $userpage->getFullURL( '', false, PROTO_CURRENT );
83 }
84
85 /**
86 * Handle Special:Redirect/file/xxxx
87 *
88 * @return string|null Url to redirect to, or null if $mValue is not found.
89 */
90 function dispatchFile() {
91 $title = Title::makeTitleSafe( NS_FILE, $this->mValue );
92
93 if ( !$title instanceof Title ) {
94 return null;
95 }
96 $file = wfFindFile( $title );
97
98 if ( !$file || !$file->exists() ) {
99 return null;
100 }
101 // Default behavior: Use the direct link to the file.
102 $url = $file->getURL();
103 $request = $this->getRequest();
104 $width = $request->getInt( 'width', -1 );
105 $height = $request->getInt( 'height', -1 );
106
107 // If a width is requested...
108 if ( $width != -1 ) {
109 $mto = $file->transform( array( 'width' => $width, 'height' => $height ) );
110 // ... and we can
111 if ( $mto && !$mto->isError() ) {
112 // ... change the URL to point to a thumbnail.
113 $url = $mto->getURL();
114 }
115 }
116
117 return $url;
118 }
119
120 /**
121 * Handle Special:Redirect/revision/xxx
122 * (by redirecting to index.php?oldid=xxx)
123 *
124 * @return string|null Url to redirect to, or null if $mValue is invalid.
125 */
126 function dispatchRevision() {
127 $oldid = $this->mValue;
128 if ( !ctype_digit( $oldid ) ) {
129 return null;
130 }
131 $oldid = (int)$oldid;
132 if ( $oldid === 0 ) {
133 return null;
134 }
135
136 return wfAppendQuery( wfScript( 'index' ), array(
137 'oldid' => $oldid
138 ) );
139 }
140
141 /**
142 * Handle Special:Redirect/page/xxx (by redirecting to index.php?curid=xxx)
143 *
144 * @return string|null Url to redirect to, or null if $mValue is invalid.
145 */
146 function dispatchPage() {
147 $curid = $this->mValue;
148 if ( !ctype_digit( $curid ) ) {
149 return null;
150 }
151 $curid = (int)$curid;
152 if ( $curid === 0 ) {
153 return null;
154 }
155
156 return wfAppendQuery( wfScript( 'index' ), array(
157 'curid' => $curid
158 ) );
159 }
160
161 /**
162 * Use appropriate dispatch* method to obtain a redirection URL,
163 * and either: redirect, set a 404 error code and error message,
164 * or do nothing (if $mValue wasn't set) allowing the form to be
165 * displayed.
166 *
167 * @return bool True if a redirect was successfully handled.
168 */
169 function dispatch() {
170 // the various namespaces supported by Special:Redirect
171 switch ( $this->mType ) {
172 case 'user':
173 $url = $this->dispatchUser();
174 break;
175 case 'file':
176 $url = $this->dispatchFile();
177 break;
178 case 'revision':
179 $url = $this->dispatchRevision();
180 break;
181 case 'page':
182 $url = $this->dispatchPage();
183 break;
184 default:
185 $this->getOutput()->setStatusCode( 404 );
186 $url = null;
187 break;
188 }
189 if ( $url ) {
190 $this->getOutput()->redirect( $url );
191
192 return true;
193 }
194 if ( !is_null( $this->mValue ) ) {
195 $this->getOutput()->setStatusCode( 404 );
196 // Message: redirect-not-exists
197 $msg = $this->getMessagePrefix() . '-not-exists';
198
199 return Status::newFatal( $msg );
200 }
201
202 return false;
203 }
204
205 protected function getFormFields() {
206 $mp = $this->getMessagePrefix();
207 $ns = array(
208 // subpage => message
209 // Messages: redirect-user, redirect-page, redirect-revision,
210 // redirect-file
211 'user' => $mp . '-user',
212 'page' => $mp . '-page',
213 'revision' => $mp . '-revision',
214 'file' => $mp . '-file',
215 );
216 $a = array();
217 $a['type'] = array(
218 'type' => 'select',
219 'label-message' => $mp . '-lookup', // Message: redirect-lookup
220 'options' => array(),
221 'default' => current( array_keys( $ns ) ),
222 );
223 foreach ( $ns as $n => $m ) {
224 $m = $this->msg( $m )->text();
225 $a['type']['options'][$m] = $n;
226 }
227 $a['value'] = array(
228 'type' => 'text',
229 'label-message' => $mp . '-value' // Message: redirect-value
230 );
231 // set the defaults according to the parsed subpage path
232 if ( !empty( $this->mType ) ) {
233 $a['type']['default'] = $this->mType;
234 }
235 if ( !empty( $this->mValue ) ) {
236 $a['value']['default'] = $this->mValue;
237 }
238
239 return $a;
240 }
241
242 public function onSubmit( array $data ) {
243 if ( !empty( $data['type'] ) && !empty( $data['value'] ) ) {
244 $this->setParameter( $data['type'] . '/' . $data['value'] );
245 }
246
247 /* if this returns false, will show the form */
248 return $this->dispatch();
249 }
250
251 public function onSuccess() {
252 /* do nothing, we redirect in $this->dispatch if successful. */
253 }
254
255 protected function alterForm( HTMLForm $form ) {
256 /* display summary at top of page */
257 $this->outputHeader();
258 // tweak label on submit button
259 // Message: redirect-submit
260 $form->setSubmitTextMsg( $this->getMessagePrefix() . '-submit' );
261 /* submit form every time */
262 $form->setMethod( 'get' );
263 }
264
265 /**
266 * Return an array of subpages that this special page will accept.
267 *
268 * @return string[] subpages
269 */
270 protected function getSubpagesForPrefixSearch() {
271 return array(
272 "file",
273 "page",
274 "revision",
275 "user",
276 );
277 }
278
279 protected function getGroupName() {
280 return 'redirects';
281 }
282 }