MediaWiki  1.30.0
SpecialRedirect.php
Go to the documentation of this file.
1 <?php
32 
40  protected $mType;
41 
49  protected $mValue;
50 
51  function __construct() {
52  parent::__construct( 'Redirect' );
53  $this->mType = null;
54  $this->mValue = null;
55  }
56 
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 
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 
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 
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 
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 
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  $logparams = [
181  'log_id',
182  'log_timestamp',
183  'log_type',
184  'log_user_text',
185  ];
186 
187  $dbr = wfGetDB( DB_REPLICA );
188 
189  // Gets the nested SQL statement which
190  // returns timestamp of the log with the given log ID
191  $inner = $dbr->selectSQLText(
192  'logging',
193  [ 'log_timestamp' ],
194  [ 'log_id' => $logid ]
195  );
196 
197  // Returns all fields mentioned in $logparams of the logs
198  // with the same timestamp as the one returned by the statement above
199  $logsSameTimestamps = $dbr->select(
200  'logging',
201  $logparams,
202  [ "log_timestamp = ($inner)" ]
203  );
204  if ( $logsSameTimestamps->numRows() === 0 ) {
205  return null;
206  }
207 
208  // Stores the row with the same log ID as the one given
209  $rowMain = [];
210  foreach ( $logsSameTimestamps as $row ) {
211  if ( (int)$row->log_id === $logid ) {
212  $rowMain = $row;
213  }
214  }
215 
216  array_shift( $logparams );
217 
218  // Stores all the rows with the same values in each column
219  // as $rowMain
220  foreach ( $logparams as $cond ) {
221  $matchedRows = [];
222  foreach ( $logsSameTimestamps as $row ) {
223  if ( $row->$cond === $rowMain->$cond ) {
224  $matchedRows[] = $row;
225  }
226  }
227  if ( count( $matchedRows ) === 1 ) {
228  break;
229  }
230  $logsSameTimestamps = $matchedRows;
231  }
232  $query = [ 'title' => 'Special:Log', 'limit' => count( $matchedRows ) ];
233 
234  // A map of database field names from table 'logging' to the values of $logparams
235  $keys = [
236  'log_timestamp' => 'offset',
237  'log_type' => 'type',
238  'log_user_text' => 'user'
239  ];
240 
241  foreach ( $logparams as $logKey ) {
242  $query[$keys[$logKey]] = $matchedRows[0]->$logKey;
243  }
244  $query['offset'] = $query['offset'] + 1;
245  $url = $query;
246 
247  return wfAppendQuery( wfScript( 'index' ), $url );
248  }
249 
258  function dispatch() {
259  // the various namespaces supported by Special:Redirect
260  switch ( $this->mType ) {
261  case 'user':
262  $url = $this->dispatchUser();
263  break;
264  case 'file':
265  $url = $this->dispatchFile();
266  break;
267  case 'revision':
268  $url = $this->dispatchRevision();
269  break;
270  case 'page':
271  $url = $this->dispatchPage();
272  break;
273  case 'logid':
274  $url = $this->dispatchLog();
275  break;
276  default:
277  $url = null;
278  break;
279  }
280  if ( $url ) {
281  $this->getOutput()->redirect( $url );
282 
283  return true;
284  }
285  if ( !is_null( $this->mValue ) ) {
286  $this->getOutput()->setStatusCode( 404 );
287  // Message: redirect-not-exists
288  $msg = $this->getMessagePrefix() . '-not-exists';
289 
290  return Status::newFatal( $msg );
291  }
292 
293  return false;
294  }
295 
296  protected function getFormFields() {
297  $mp = $this->getMessagePrefix();
298  $ns = [
299  // subpage => message
300  // Messages: redirect-user, redirect-page, redirect-revision,
301  // redirect-file, redirect-logid
302  'user' => $mp . '-user',
303  'page' => $mp . '-page',
304  'revision' => $mp . '-revision',
305  'file' => $mp . '-file',
306  'logid' => $mp . '-logid',
307  ];
308  $a = [];
309  $a['type'] = [
310  'type' => 'select',
311  'label-message' => $mp . '-lookup', // Message: redirect-lookup
312  'options' => [],
313  'default' => current( array_keys( $ns ) ),
314  ];
315  foreach ( $ns as $n => $m ) {
316  $m = $this->msg( $m )->text();
317  $a['type']['options'][$m] = $n;
318  }
319  $a['value'] = [
320  'type' => 'text',
321  'label-message' => $mp . '-value' // Message: redirect-value
322  ];
323  // set the defaults according to the parsed subpage path
324  if ( !empty( $this->mType ) ) {
325  $a['type']['default'] = $this->mType;
326  }
327  if ( !empty( $this->mValue ) ) {
328  $a['value']['default'] = $this->mValue;
329  }
330 
331  return $a;
332  }
333 
334  public function onSubmit( array $data ) {
335  if ( !empty( $data['type'] ) && !empty( $data['value'] ) ) {
336  $this->setParameter( $data['type'] . '/' . $data['value'] );
337  }
338 
339  /* if this returns false, will show the form */
340  return $this->dispatch();
341  }
342 
343  public function onSuccess() {
344  /* do nothing, we redirect in $this->dispatch if successful. */
345  }
346 
347  protected function alterForm( HTMLForm $form ) {
348  /* display summary at top of page */
349  $this->outputHeader();
350  // tweak label on submit button
351  // Message: redirect-submit
352  $form->setSubmitTextMsg( $this->getMessagePrefix() . '-submit' );
353  /* submit form every time */
354  $form->setMethod( 'get' );
355  }
356 
357  protected function getDisplayFormat() {
358  return 'ooui';
359  }
360 
366  protected function getSubpagesForPrefixSearch() {
367  return [
368  'file',
369  'page',
370  'revision',
371  'user',
372  'logid',
373  ];
374  }
375 
379  public function requiresWrite() {
380  return false;
381  }
382 
386  public function requiresUnblock() {
387  return false;
388  }
389 
390  protected function getGroupName() {
391  return 'redirects';
392  }
393 }
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:244
User\newFromId
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition: User.php:573
SpecialPage\msg
msg( $key)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:746
SpecialRedirect\dispatchLog
dispatchLog()
Handle Special:Redirect/logid/xxx (by redirecting to index.php?title=Special:Log)
Definition: SpecialRedirect.php:170
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:675
captcha-old.count
count
Definition: captcha-old.py:249
SpecialRedirect\$mValue
$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:334
SpecialRedirect\onSuccess
onSuccess()
Do something exciting on successful processing of the form, most likely to show a confirmation messag...
Definition: SpecialRedirect.php:343
StatusValue\newFatal
static newFatal( $message)
Factory function for fatal errors.
Definition: StatusValue.php:68
NS_FILE
const NS_FILE
Definition: Defines.php:71
FormSpecialPage
Special page which uses an HTMLForm to handle processing.
Definition: FormSpecialPage.php:31
SpecialRedirect\$mType
$mType
The type of the redirect (user/file/revision)
Definition: SpecialRedirect.php:40
HTMLForm\setMethod
setMethod( $method='post')
Set the method used to submit the form.
Definition: HTMLForm.php:1593
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
SpecialRedirect\getDisplayFormat
getDisplayFormat()
Get display format for the form.
Definition: SpecialRedirect.php:357
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:534
FormSpecialPage\getMessagePrefix
getMessagePrefix()
Get message prefix for HTMLForm.
Definition: FormSpecialPage.php:73
SpecialRedirect
A special page that redirects to: the user for a numeric user id, the file for a given filename,...
Definition: SpecialRedirect.php:31
$query
null for the wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1581
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:932
wfScript
wfScript( $script='index')
Get the path to a specified script file, respecting file extensions; this is a wrapper around $wgScri...
Definition: GlobalFunctions.php:2934
wfGetDB
wfGetDB( $db, $groups=[], $wiki=false)
Get a Database object.
Definition: GlobalFunctions.php:2856
SpecialRedirect\dispatch
dispatch()
Use appropriate dispatch* method to obtain a redirection URL, and either: redirect,...
Definition: SpecialRedirect.php:258
PROTO_CURRENT
const PROTO_CURRENT
Definition: Defines.php:223
SpecialRedirect\getFormFields
getFormFields()
Get an HTMLForm descriptor array.
Definition: SpecialRedirect.php:296
Title\makeTitle
static makeTitle( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:529
SpecialRedirect\dispatchRevision
dispatchRevision()
Handle Special:Redirect/revision/xxx (by redirecting to index.php?oldid=xxx)
Definition: SpecialRedirect.php:128
DB_REPLICA
const DB_REPLICA
Definition: defines.php:25
$request
do that in ParserLimitReportFormat instead use this to modify the parameters of the image all existing parser cache entries will be invalid To avoid you ll need to handle that somehow(e.g. with the RejectParserCacheValue hook) because MediaWiki won 't do it for you. & $defaults also a ContextSource after deleting those rows but within the same transaction you ll probably need to make sure the header is varied on $request
Definition: hooks.txt:2581
Title\makeTitleSafe
static makeTitleSafe( $ns, $title, $fragment='', $interwiki='')
Create a new Title from a namespace index and a DB key.
Definition: Title.php:557
SpecialRedirect\__construct
__construct()
Definition: SpecialRedirect.php:51
SpecialRedirect\dispatchFile
dispatchFile()
Handle Special:Redirect/file/xxxx.
Definition: SpecialRedirect.php:92
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:665
SpecialRedirect\dispatchUser
dispatchUser()
Handle Special:Redirect/user/xxxx (by redirecting to User:YYYY)
Definition: SpecialRedirect.php:73
SpecialRedirect\dispatchPage
dispatchPage()
Handle Special:Redirect/page/xxx (by redirecting to index.php?curid=xxx)
Definition: SpecialRedirect.php:148
wfFindFile
wfFindFile( $title, $options=[])
Find a file.
Definition: GlobalFunctions.php:2897
HTMLForm\setSubmitTextMsg
setSubmitTextMsg( $msg)
Set the text for the submit button to a message.
Definition: HTMLForm.php:1365
SpecialRedirect\getSubpagesForPrefixSearch
getSubpagesForPrefixSearch()
Return an array of subpages that this special page will accept.
Definition: SpecialRedirect.php:366
SpecialRedirect\alterForm
alterForm(HTMLForm $form)
Play with the HTMLForm if you need to more substantially.
Definition: SpecialRedirect.php:347
Title
Represents a title within MediaWiki.
Definition: Title.php:39
$dbr
if(! $regexes) $dbr
Definition: cleanup.php:94
SpecialRedirect\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: SpecialRedirect.php:390
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
$keys
$keys
Definition: testCompression.php:65
NS_USER
const NS_USER
Definition: Defines.php:67
SpecialRedirect\setParameter
setParameter( $subpage)
Set $mType and $mValue based on parsed value of $subpage.
Definition: SpecialRedirect.php:61
$username
this hook is for auditing only or null if authentication failed before getting that far $username
Definition: hooks.txt:781
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:583
SpecialRedirect\requiresWrite
requiresWrite()
Definition: SpecialRedirect.php:379
SpecialRedirect\requiresUnblock
requiresUnblock()
Definition: SpecialRedirect.php:386
array
the array() calling protocol came about after MediaWiki 1.4rc1.
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms.
Definition: HTMLForm.php:128