MediaWiki REL1_34
SpecialRedirect.php
Go to the documentation of this file.
1<?php
25
34
42 protected $mType;
43
51 protected $mValue;
52
53 function __construct() {
54 parent::__construct( 'Redirect' );
55 $this->mType = null;
56 $this->mValue = null;
57 }
58
63 function setParameter( $subpage ) {
64 // parse $subpage to pull out the parts
65 $parts = explode( '/', $subpage, 2 );
66 $this->mType = $parts[0];
67 $this->mValue = $parts[1] ?? null;
68 }
69
75 function dispatchUser() {
76 if ( !ctype_digit( $this->mValue ) ) {
77 // Message: redirect-not-numeric
78 return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
79 }
80 $user = User::newFromId( (int)$this->mValue );
81 $username = $user->getName(); // load User as side-effect
82 if ( $user->isAnon() ) {
83 // Message: redirect-not-exists
84 return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
85 }
86 if ( $user->isHidden() && !MediaWikiServices::getInstance()->getPermissionManager()
87 ->userHasRight( $this->getUser(), 'hideuser' )
88 ) {
89 throw new PermissionsError( null, [ 'badaccess-group0' ] );
90 }
91 $userpage = Title::makeTitle( NS_USER, $username );
92
93 return Status::newGood( [
94 $userpage->getFullURL( '', false, PROTO_CURRENT ), 302
95 ] );
96 }
97
103 function dispatchFile() {
104 try {
105 $title = Title::newFromTextThrow( $this->mValue, NS_FILE );
106 if ( $title && !$title->inNamespace( NS_FILE ) ) {
107 // If the given value contains a namespace enforce file namespace
108 $title = Title::newFromTextThrow( Title::makeName( NS_FILE, $this->mValue ) );
109 }
110 } catch ( MalformedTitleException $e ) {
111 return Status::newFatal( $e->getMessageObject() );
112 }
113 $file = MediaWikiServices::getInstance()->getRepoGroup()->findFile( $title );
114
115 if ( !$file || !$file->exists() ) {
116 // Message: redirect-not-exists
117 return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
118 }
119 // Default behavior: Use the direct link to the file.
120 $url = $file->getUrl();
121 $request = $this->getRequest();
122 $width = $request->getInt( 'width', -1 );
123 $height = $request->getInt( 'height', -1 );
124
125 // If a width is requested...
126 if ( $width != -1 ) {
127 $mto = $file->transform( [ 'width' => $width, 'height' => $height ] );
128 // ... and we can
129 if ( $mto && !$mto->isError() ) {
130 // ... change the URL to point to a thumbnail.
131 // Note: This url is more temporary as can change
132 // if file is reuploaded and has different aspect ratio.
133 $url = [ $mto->getUrl(), $height === -1 ? 301 : 302 ];
134 }
135 }
136
137 return Status::newGood( $url );
138 }
139
146 function dispatchRevision() {
147 $oldid = $this->mValue;
148 if ( !ctype_digit( $oldid ) ) {
149 // Message: redirect-not-numeric
150 return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
151 }
152 $oldid = (int)$oldid;
153 if ( $oldid === 0 ) {
154 // Message: redirect-not-exists
155 return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
156 }
157
158 return Status::newGood( wfAppendQuery( wfScript( 'index' ), [
159 'oldid' => $oldid
160 ] ) );
161 }
162
168 function dispatchPage() {
169 $curid = $this->mValue;
170 if ( !ctype_digit( $curid ) ) {
171 // Message: redirect-not-numeric
172 return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
173 }
174 $curid = (int)$curid;
175 if ( $curid === 0 ) {
176 // Message: redirect-not-exists
177 return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
178 }
179
180 return Status::newGood( wfAppendQuery( wfScript( 'index' ), [
181 'curid' => $curid
182 ] ) );
183 }
184
192 function dispatchLog() {
193 $logid = $this->mValue;
194 if ( !ctype_digit( $logid ) ) {
195 // Message: redirect-not-numeric
196 return Status::newFatal( $this->getMessagePrefix() . '-not-numeric' );
197 }
198 $logid = (int)$logid;
199 if ( $logid === 0 ) {
200 // Message: redirect-not-exists
201 return Status::newFatal( $this->getMessagePrefix() . '-not-exists' );
202 }
203 $query = [ 'title' => 'Special:Log', 'logid' => $logid ];
204 return Status::newGood( wfAppendQuery( wfScript( 'index' ), $query ) );
205 }
206
215 function dispatch() {
216 // the various namespaces supported by Special:Redirect
217 switch ( $this->mType ) {
218 case 'user':
219 $status = $this->dispatchUser();
220 break;
221 case 'file':
222 $status = $this->dispatchFile();
223 break;
224 case 'revision':
225 $status = $this->dispatchRevision();
226 break;
227 case 'page':
228 $status = $this->dispatchPage();
229 break;
230 case 'logid':
231 $status = $this->dispatchLog();
232 break;
233 default:
234 $status = null;
235 break;
236 }
237 if ( $status && $status->isGood() ) {
238 // These urls can sometimes be linked from prominent places,
239 // so varnish cache.
240 $value = $status->getValue();
241 if ( is_array( $value ) ) {
242 list( $url, $code ) = $value;
243 } else {
244 $url = $value;
245 $code = 301;
246 }
247 if ( $code === 301 ) {
248 $this->getOutput()->setCdnMaxage( 60 * 60 );
249 } else {
250 $this->getOutput()->setCdnMaxage( 10 );
251 }
252 $this->getOutput()->redirect( $url, $code );
253
254 return true;
255 }
256 if ( !is_null( $this->mValue ) ) {
257 $this->getOutput()->setStatusCode( 404 );
258
259 return $status;
260 }
261
262 return false;
263 }
264
265 protected function getFormFields() {
266 $mp = $this->getMessagePrefix();
267 $ns = [
268 // subpage => message
269 // Messages: redirect-user, redirect-page, redirect-revision,
270 // redirect-file, redirect-logid
271 'user' => $mp . '-user',
272 'page' => $mp . '-page',
273 'revision' => $mp . '-revision',
274 'file' => $mp . '-file',
275 'logid' => $mp . '-logid',
276 ];
277 $a = [];
278 $a['type'] = [
279 'type' => 'select',
280 'label-message' => $mp . '-lookup', // Message: redirect-lookup
281 'options' => [],
282 'default' => current( array_keys( $ns ) ),
283 ];
284 foreach ( $ns as $n => $m ) {
285 $m = $this->msg( $m )->text();
286 $a['type']['options'][$m] = $n;
287 }
288 $a['value'] = [
289 'type' => 'text',
290 'label-message' => $mp . '-value' // Message: redirect-value
291 ];
292 // set the defaults according to the parsed subpage path
293 if ( !empty( $this->mType ) ) {
294 $a['type']['default'] = $this->mType;
295 }
296 if ( !empty( $this->mValue ) ) {
297 $a['value']['default'] = $this->mValue;
298 }
299
300 return $a;
301 }
302
303 public function onSubmit( array $data ) {
304 if ( !empty( $data['type'] ) && !empty( $data['value'] ) ) {
305 $this->setParameter( $data['type'] . '/' . $data['value'] );
306 }
307
308 /* if this returns false, will show the form */
309 return $this->dispatch();
310 }
311
312 public function onSuccess() {
313 /* do nothing, we redirect in $this->dispatch if successful. */
314 }
315
316 protected function alterForm( HTMLForm $form ) {
317 /* display summary at top of page */
318 $this->outputHeader();
319 // tweak label on submit button
320 // Message: redirect-submit
321 $form->setSubmitTextMsg( $this->getMessagePrefix() . '-submit' );
322 /* submit form every time */
323 $form->setMethod( 'get' );
324 }
325
326 protected function getDisplayFormat() {
327 return 'ooui';
328 }
329
335 protected function getSubpagesForPrefixSearch() {
336 return [
337 'file',
338 'page',
339 'revision',
340 'user',
341 'logid',
342 ];
343 }
344
348 public function requiresWrite() {
349 return false;
350 }
351
355 public function requiresUnblock() {
356 return false;
357 }
358
359 protected function getGroupName() {
360 return 'redirects';
361 }
362}
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Special page which uses an HTMLForm to handle processing.
getMessagePrefix()
Get message prefix for HTMLForm.
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition HTMLForm.php:131
setMethod( $method='post')
Set the method used to submit the form.
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
MalformedTitleException is thrown when a TitleParser is unable to parse a title string.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Show an error when a user tries to do something they do not have the necessary permissions for.
outputHeader( $summaryMessageKey='')
Outputs a summary message on top of special pages Per default the message key is the canonical name o...
getOutput()
Get the OutputPage being used for this instance.
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
getRequest()
Get the WebRequest being used for this instance.
A special page that redirects to: the user for a numeric user id, the file for a given filename,...
getSubpagesForPrefixSearch()
Return an array of subpages that this special page will accept.
setParameter( $subpage)
Set $mType and $mValue based on parsed value of $subpage.
onSubmit(array $data)
Process the form on POST submission.
getDisplayFormat()
Get display format for the form.
dispatchLog()
Handle Special:Redirect/logid/xxx (by redirecting to index.php?title=Special:Log&logid=xxx)
getFormFields()
Get an HTMLForm descriptor array.
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
dispatchUser()
Handle Special:Redirect/user/xxxx (by redirecting to User:YYYY)
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
dispatch()
Use appropriate dispatch* method to obtain a redirection URL, and either: redirect,...
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
dispatchRevision()
Handle Special:Redirect/revision/xxx (by redirecting to index.php?oldid=xxx)
$mValue
The identifier/value for the redirect (which id, which file)
dispatchPage()
Handle Special:Redirect/page/xxx (by redirecting to index.php?curid=xxx)
dispatchFile()
Handle Special:Redirect/file/xxxx.
$mType
The type of the redirect (user/file/revision)
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition User.php:542
const NS_USER
Definition Defines.php:71
const NS_FILE
Definition Defines.php:75
const PROTO_CURRENT
Definition Defines.php:211
if(PHP_SAPI !='cli-server') if(!isset( $_SERVER['SCRIPT_FILENAME'])) $file
Item class for a filearchive table row.
Definition router.php:42