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