]> scripts.mit.edu Git - autoinstallsdev/mediawiki.git/blob - includes/specials/SpecialRedirect.php
MediaWiki 1.30.2 renames
[autoinstallsdev/mediawiki.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          * Example value: `'user'`
37          *
38          * @var string $mType
39          */
40         protected $mType;
41
42         /**
43          * The identifier/value for the redirect (which id, which file)
44          *
45          * Example value: `'42'`
46          *
47          * @var string $mValue
48          */
49         protected $mValue;
50
51         function __construct() {
52                 parent::__construct( 'Redirect' );
53                 $this->mType = null;
54                 $this->mValue = null;
55         }
56
57         /**
58          * Set $mType and $mValue based on parsed value of $subpage.
59          * @param string $subpage
60          */
61         function setParameter( $subpage ) {
62                 // parse $subpage to pull out the parts
63                 $parts = explode( '/', $subpage, 2 );
64                 $this->mType = count( $parts ) > 0 ? $parts[0] : null;
65                 $this->mValue = count( $parts ) > 1 ? $parts[1] : null;
66         }
67
68         /**
69          * Handle Special:Redirect/user/xxxx (by redirecting to User:YYYY)
70          *
71          * @return string|null Url to redirect to, or null if $mValue is invalid.
72          */
73         function dispatchUser() {
74                 if ( !ctype_digit( $this->mValue ) ) {
75                         return null;
76                 }
77                 $user = User::newFromId( (int)$this->mValue );
78                 $username = $user->getName(); // load User as side-effect
79                 if ( $user->isAnon() ) {
80                         return null;
81                 }
82                 $userpage = Title::makeTitle( NS_USER, $username );
83
84                 return $userpage->getFullURL( '', false, PROTO_CURRENT );
85         }
86
87         /**
88          * Handle Special:Redirect/file/xxxx
89          *
90          * @return string|null Url to redirect to, or null if $mValue is not found.
91          */
92         function dispatchFile() {
93                 $title = Title::makeTitleSafe( NS_FILE, $this->mValue );
94
95                 if ( !$title instanceof Title ) {
96                         return null;
97                 }
98                 $file = wfFindFile( $title );
99
100                 if ( !$file || !$file->exists() ) {
101                         return null;
102                 }
103                 // Default behavior: Use the direct link to the file.
104                 $url = $file->getUrl();
105                 $request = $this->getRequest();
106                 $width = $request->getInt( 'width', -1 );
107                 $height = $request->getInt( 'height', -1 );
108
109                 // If a width is requested...
110                 if ( $width != -1 ) {
111                         $mto = $file->transform( [ 'width' => $width, 'height' => $height ] );
112                         // ... and we can
113                         if ( $mto && !$mto->isError() ) {
114                                 // ... change the URL to point to a thumbnail.
115                                 $url = $mto->getUrl();
116                         }
117                 }
118
119                 return $url;
120         }
121
122         /**
123          * Handle Special:Redirect/revision/xxx
124          * (by redirecting to index.php?oldid=xxx)
125          *
126          * @return string|null Url to redirect to, or null if $mValue is invalid.
127          */
128         function dispatchRevision() {
129                 $oldid = $this->mValue;
130                 if ( !ctype_digit( $oldid ) ) {
131                         return null;
132                 }
133                 $oldid = (int)$oldid;
134                 if ( $oldid === 0 ) {
135                         return null;
136                 }
137
138                 return wfAppendQuery( wfScript( 'index' ), [
139                         'oldid' => $oldid
140                 ] );
141         }
142
143         /**
144          * Handle Special:Redirect/page/xxx (by redirecting to index.php?curid=xxx)
145          *
146          * @return string|null Url to redirect to, or null if $mValue is invalid.
147          */
148         function dispatchPage() {
149                 $curid = $this->mValue;
150                 if ( !ctype_digit( $curid ) ) {
151                         return null;
152                 }
153                 $curid = (int)$curid;
154                 if ( $curid === 0 ) {
155                         return null;
156                 }
157
158                 return wfAppendQuery( wfScript( 'index' ), [
159                         'curid' => $curid
160                 ] );
161         }
162
163         /**
164          * Handle Special:Redirect/logid/xxx
165          * (by redirecting to index.php?title=Special:Log&logid=xxx)
166          *
167          * @since 1.27
168          * @return string|null Url to redirect to, or null if $mValue is invalid.
169          */
170         function dispatchLog() {
171                 $logid = $this->mValue;
172                 if ( !ctype_digit( $logid ) ) {
173                         return null;
174                 }
175                 $logid = (int)$logid;
176                 if ( $logid === 0 ) {
177                         return null;
178                 }
179
180                 $query = [ 'title' => 'Special:Log', 'logid' => $logid ];
181                 return wfAppendQuery( wfScript( 'index' ), $query );
182         }
183
184         /**
185          * Use appropriate dispatch* method to obtain a redirection URL,
186          * and either: redirect, set a 404 error code and error message,
187          * or do nothing (if $mValue wasn't set) allowing the form to be
188          * displayed.
189          *
190          * @return bool True if a redirect was successfully handled.
191          */
192         function dispatch() {
193                 // the various namespaces supported by Special:Redirect
194                 switch ( $this->mType ) {
195                         case 'user':
196                                 $url = $this->dispatchUser();
197                                 break;
198                         case 'file':
199                                 $url = $this->dispatchFile();
200                                 break;
201                         case 'revision':
202                                 $url = $this->dispatchRevision();
203                                 break;
204                         case 'page':
205                                 $url = $this->dispatchPage();
206                                 break;
207                         case 'logid':
208                                 $url = $this->dispatchLog();
209                                 break;
210                         default:
211                                 $url = null;
212                                 break;
213                 }
214                 if ( $url ) {
215                         $this->getOutput()->redirect( $url );
216
217                         return true;
218                 }
219                 if ( !is_null( $this->mValue ) ) {
220                         $this->getOutput()->setStatusCode( 404 );
221                         // Message: redirect-not-exists
222                         $msg = $this->getMessagePrefix() . '-not-exists';
223
224                         return Status::newFatal( $msg );
225                 }
226
227                 return false;
228         }
229
230         protected function getFormFields() {
231                 $mp = $this->getMessagePrefix();
232                 $ns = [
233                         // subpage => message
234                         // Messages: redirect-user, redirect-page, redirect-revision,
235                         // redirect-file, redirect-logid
236                         'user' => $mp . '-user',
237                         'page' => $mp . '-page',
238                         'revision' => $mp . '-revision',
239                         'file' => $mp . '-file',
240                         'logid' => $mp . '-logid',
241                 ];
242                 $a = [];
243                 $a['type'] = [
244                         'type' => 'select',
245                         'label-message' => $mp . '-lookup', // Message: redirect-lookup
246                         'options' => [],
247                         'default' => current( array_keys( $ns ) ),
248                 ];
249                 foreach ( $ns as $n => $m ) {
250                         $m = $this->msg( $m )->text();
251                         $a['type']['options'][$m] = $n;
252                 }
253                 $a['value'] = [
254                         'type' => 'text',
255                         'label-message' => $mp . '-value' // Message: redirect-value
256                 ];
257                 // set the defaults according to the parsed subpage path
258                 if ( !empty( $this->mType ) ) {
259                         $a['type']['default'] = $this->mType;
260                 }
261                 if ( !empty( $this->mValue ) ) {
262                         $a['value']['default'] = $this->mValue;
263                 }
264
265                 return $a;
266         }
267
268         public function onSubmit( array $data ) {
269                 if ( !empty( $data['type'] ) && !empty( $data['value'] ) ) {
270                         $this->setParameter( $data['type'] . '/' . $data['value'] );
271                 }
272
273                 /* if this returns false, will show the form */
274                 return $this->dispatch();
275         }
276
277         public function onSuccess() {
278                 /* do nothing, we redirect in $this->dispatch if successful. */
279         }
280
281         protected function alterForm( HTMLForm $form ) {
282                 /* display summary at top of page */
283                 $this->outputHeader();
284                 // tweak label on submit button
285                 // Message: redirect-submit
286                 $form->setSubmitTextMsg( $this->getMessagePrefix() . '-submit' );
287                 /* submit form every time */
288                 $form->setMethod( 'get' );
289         }
290
291         protected function getDisplayFormat() {
292                 return 'ooui';
293         }
294
295         /**
296          * Return an array of subpages that this special page will accept.
297          *
298          * @return string[] subpages
299          */
300         protected function getSubpagesForPrefixSearch() {
301                 return [
302                         'file',
303                         'page',
304                         'revision',
305                         'user',
306                         'logid',
307                 ];
308         }
309
310         /**
311          * @return bool
312          */
313         public function requiresWrite() {
314                 return false;
315         }
316
317         /**
318          * @return bool
319          */
320         public function requiresUnblock() {
321                 return false;
322         }
323
324         protected function getGroupName() {
325                 return 'redirects';
326         }
327 }