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