MediaWiki  1.23.1
RequestContext.php
Go to the documentation of this file.
1 <?php
30 class RequestContext implements IContextSource {
34  private $request;
35 
39  private $title;
40 
44  private $wikipage;
45 
49  private $output;
50 
54  private $user;
55 
59  private $lang;
60 
64  private $skin;
65 
69  private $config;
70 
76  public function setConfig( Config $c ) {
77  $this->config = $c;
78  }
79 
85  public function getConfig() {
86  if ( $this->config === null ) {
87  // @todo In the future, we could move this to WebStart.php so
88  // the Config object is ready for when initialization happens
89  $this->config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' );
90  }
91 
92  return $this->config;
93  }
94 
100  public function setRequest( WebRequest $r ) {
101  $this->request = $r;
102  }
103 
109  public function getRequest() {
110  if ( $this->request === null ) {
111  global $wgRequest; # fallback to $wg till we can improve this
112  $this->request = $wgRequest;
113  }
114 
115  return $this->request;
116  }
117 
124  public function setTitle( $t ) {
125  if ( $t !== null && !$t instanceof Title ) {
126  throw new MWException( __METHOD__ . " expects an instance of Title" );
127  }
128  $this->title = $t;
129  // Erase the WikiPage so a new one with the new title gets created.
130  $this->wikipage = null;
131  }
132 
138  public function getTitle() {
139  if ( $this->title === null ) {
140  global $wgTitle; # fallback to $wg till we can improve this
141  $this->title = $wgTitle;
142  }
143 
144  return $this->title;
145  }
146 
155  public function canUseWikiPage() {
156  if ( $this->wikipage !== null ) {
157  # If there's a WikiPage object set, we can for sure get it
158  return true;
159  }
160  $title = $this->getTitle();
161  if ( $title === null ) {
162  # No Title, no WikiPage
163  return false;
164  } else {
165  # Only namespaces whose pages are stored in the database can have WikiPage
166  return $title->canExist();
167  }
168  }
169 
176  public function setWikiPage( WikiPage $p ) {
177  $contextTitle = $this->getTitle();
178  $pageTitle = $p->getTitle();
179  if ( !$contextTitle || !$pageTitle->equals( $contextTitle ) ) {
180  $this->setTitle( $pageTitle );
181  }
182  // Defer this to the end since setTitle sets it to null.
183  $this->wikipage = $p;
184  }
185 
196  public function getWikiPage() {
197  if ( $this->wikipage === null ) {
198  $title = $this->getTitle();
199  if ( $title === null ) {
200  throw new MWException( __METHOD__ . ' called without Title object set' );
201  }
202  $this->wikipage = WikiPage::factory( $title );
203  }
204 
205  return $this->wikipage;
206  }
207 
211  public function setOutput( OutputPage $o ) {
212  $this->output = $o;
213  }
214 
220  public function getOutput() {
221  if ( $this->output === null ) {
222  $this->output = new OutputPage( $this );
223  }
224 
226  }
227 
233  public function setUser( User $u ) {
234  $this->user = $u;
235  }
236 
242  public function getUser() {
243  if ( $this->user === null ) {
244  $this->user = User::newFromSession( $this->getRequest() );
245  }
246 
247  return $this->user;
248  }
249 
256  public static function sanitizeLangCode( $code ) {
257  global $wgLanguageCode;
258 
259  // BCP 47 - letter case MUST NOT carry meaning
260  $code = strtolower( $code );
261 
262  # Validate $code
263  if ( empty( $code ) || !Language::isValidCode( $code ) || ( $code === 'qqq' ) ) {
264  wfDebug( "Invalid user language code\n" );
265  $code = $wgLanguageCode;
266  }
267 
268  return $code;
269  }
270 
277  public function setLang( $l ) {
278  wfDeprecated( __METHOD__, '1.19' );
279  $this->setLanguage( $l );
280  }
281 
289  public function setLanguage( $l ) {
290  if ( $l instanceof Language ) {
291  $this->lang = $l;
292  } elseif ( is_string( $l ) ) {
293  $l = self::sanitizeLangCode( $l );
294  $obj = Language::factory( $l );
295  $this->lang = $obj;
296  } else {
297  throw new MWException( __METHOD__ . " was passed an invalid type of data." );
298  }
299  }
300 
305  public function getLang() {
306  wfDeprecated( __METHOD__, '1.19' );
307 
308  return $this->getLanguage();
309  }
310 
318  public function getLanguage() {
319  if ( isset( $this->recursion ) ) {
320  trigger_error( "Recursion detected in " . __METHOD__, E_USER_WARNING );
321  $e = new Exception;
322  wfDebugLog( 'recursion-guard', "Recursion detected:\n" . $e->getTraceAsString() );
323 
324  global $wgLanguageCode;
325  $code = ( $wgLanguageCode ) ? $wgLanguageCode : 'en';
326  $this->lang = Language::factory( $code );
327  } elseif ( $this->lang === null ) {
328  $this->recursion = true;
329 
330  global $wgLanguageCode, $wgContLang;
331 
332  $request = $this->getRequest();
333  $user = $this->getUser();
334 
335  $code = $request->getVal( 'uselang', $user->getOption( 'language' ) );
336  $code = self::sanitizeLangCode( $code );
337 
338  wfRunHooks( 'UserGetLanguageObject', array( $user, &$code, $this ) );
339 
340  if ( $code === $wgLanguageCode ) {
341  $this->lang = $wgContLang;
342  } else {
343  $obj = Language::factory( $code );
344  $this->lang = $obj;
345  }
346 
347  unset( $this->recursion );
348  }
349 
350  return $this->lang;
351  }
352 
358  public function setSkin( Skin $s ) {
359  $this->skin = clone $s;
360  $this->skin->setContext( $this );
361  }
362 
368  public function getSkin() {
369  if ( $this->skin === null ) {
370  wfProfileIn( __METHOD__ . '-createskin' );
371 
372  $skin = null;
373  wfRunHooks( 'RequestContextCreateSkin', array( $this, &$skin ) );
374 
375  // If the hook worked try to set a skin from it
376  if ( $skin instanceof Skin ) {
377  $this->skin = $skin;
378  } elseif ( is_string( $skin ) ) {
379  $this->skin = Skin::newFromKey( $skin );
380  }
381 
382  // If this is still null (the hook didn't run or didn't work)
383  // then go through the normal processing to load a skin
384  if ( $this->skin === null ) {
385  global $wgHiddenPrefs;
386  if ( !in_array( 'skin', $wgHiddenPrefs ) ) {
387  # get the user skin
388  $userSkin = $this->getUser()->getOption( 'skin' );
389  $userSkin = $this->getRequest()->getVal( 'useskin', $userSkin );
390  } else {
391  # if we're not allowing users to override, then use the default
392  global $wgDefaultSkin;
393  $userSkin = $wgDefaultSkin;
394  }
395 
396  $this->skin = Skin::newFromKey( $userSkin );
397  }
398 
399  // After all that set a context on whatever skin got created
400  $this->skin->setContext( $this );
401  wfProfileOut( __METHOD__ . '-createskin' );
402  }
403 
404  return $this->skin;
405  }
406 
415  public function msg() {
416  $args = func_get_args();
417 
418  return call_user_func_array( 'wfMessage', $args )->setContext( $this );
419  }
420 
428  public static function getMain() {
429  static $instance = null;
430  if ( $instance === null ) {
431  $instance = new self;
432  }
433 
434  return $instance;
435  }
436 
444  public function exportSession() {
445  return array(
446  'ip' => $this->getRequest()->getIP(),
447  'headers' => $this->getRequest()->getAllHeaders(),
448  'sessionId' => session_id(),
449  'userId' => $this->getUser()->getId()
450  );
451  }
452 
469  public static function importScopedSession( array $params ) {
470  if ( PHP_SAPI !== 'cli' ) {
471  // Don't send random private cookies or turn $wgRequest into FauxRequest
472  throw new MWException( "Sessions can only be imported in cli mode." );
473  } elseif ( !strlen( $params['sessionId'] ) ) {
474  throw new MWException( "No session ID was specified." );
475  }
476 
477  if ( $params['userId'] ) { // logged-in user
478  $user = User::newFromId( $params['userId'] );
479  if ( !$user ) {
480  throw new MWException( "No user with ID '{$params['userId']}'." );
481  }
482  } elseif ( !IP::isValid( $params['ip'] ) ) {
483  throw new MWException( "Could not load user '{$params['ip']}'." );
484  } else { // anon user
485  $user = User::newFromName( $params['ip'], false );
486  }
487 
488  $importSessionFunction = function ( User $user, array $params ) {
489  global $wgRequest, $wgUser;
490 
491  $context = RequestContext::getMain();
492  // Commit and close any current session
493  session_write_close(); // persist
494  session_id( '' ); // detach
495  $_SESSION = array(); // clear in-memory array
496  // Remove any user IP or agent information
497  $context->setRequest( new FauxRequest() );
498  $wgRequest = $context->getRequest(); // b/c
499  // Now that all private information is detached from the user, it should
500  // be safe to load the new user. If errors occur or an exception is thrown
501  // and caught (leaving the main context in a mixed state), there is no risk
502  // of the User object being attached to the wrong IP, headers, or session.
503  $context->setUser( $user );
504  $wgUser = $context->getUser(); // b/c
505  if ( strlen( $params['sessionId'] ) ) { // don't make a new random ID
506  wfSetupSession( $params['sessionId'] ); // sets $_SESSION
507  }
508  $request = new FauxRequest( array(), false, $_SESSION );
509  $request->setIP( $params['ip'] );
510  foreach ( $params['headers'] as $name => $value ) {
511  $request->setHeader( $name, $value );
512  }
513  // Set the current context to use the new WebRequest
514  $context->setRequest( $request );
515  $wgRequest = $context->getRequest(); // b/c
516  };
517 
518  // Stash the old session and load in the new one
519  $oUser = self::getMain()->getUser();
520  $oParams = self::getMain()->exportSession();
521  $importSessionFunction( $user, $params );
522 
523  // Set callback to save and close the new session and reload the old one
524  return new ScopedCallback( function () use ( $importSessionFunction, $oUser, $oParams ) {
525  $importSessionFunction( $oUser, $oParams );
526  } );
527  }
528 
543  public static function newExtraneousContext( Title $title, $request = array() ) {
544  $context = new self;
545  $context->setTitle( $title );
546  if ( $request instanceof WebRequest ) {
547  $context->setRequest( $request );
548  } else {
549  $context->setRequest( new FauxRequest( $request ) );
550  }
551  $context->user = User::newFromName( '127.0.0.1', false );
552 
553  return $context;
554  }
555 }
$wgUser
$wgUser
Definition: Setup.php:552
FauxRequest
WebRequest clone which takes values from a provided array.
Definition: WebRequest.php:1275
User\newFromId
static newFromId( $id)
Static factory method for creation from a given user ID.
Definition: User.php:411
RequestContext\sanitizeLangCode
static sanitizeLangCode( $code)
Accepts a language code and ensures it's sane.
Definition: RequestContext.php:248
RequestContext\setLang
setLang( $l)
Set the Language object.
Definition: RequestContext.php:269
php
skin txt MediaWiki includes four core it has been set as the default in MediaWiki since the replacing Monobook it had been been the default skin since before being replaced by Vector largely rewritten in while keeping its appearance Several legacy skins were removed in the as the burden of supporting them became too heavy to bear Those in etc for skin dependent CSS etc for skin dependent JavaScript These can also be customised on a per user by etc This feature has led to a wide variety of user styles becoming that gallery is a good place to ending in php
Definition: skin.txt:62
RequestContext\setUser
setUser(User $u)
Set the User object.
Definition: RequestContext.php:225
wfSetupSession
wfSetupSession( $sessionId=false)
Initialise php session.
Definition: GlobalFunctions.php:3523
RequestContext\setConfig
setConfig(Config $c)
Set the Config object.
Definition: RequestContext.php:68
RequestContext\$title
Title $title
Definition: RequestContext.php:37
RequestContext\$user
User $user
Definition: RequestContext.php:49
User\newFromSession
static newFromSession(WebRequest $request=null)
Create a new user object using data from session or cookies.
Definition: User.php:449
wfDebugLog
wfDebugLog( $logGroup, $text, $dest='all')
Send a line to a supplementary debug log file, if configured, or main debug log if not.
Definition: GlobalFunctions.php:1040
wfProfileIn
wfProfileIn( $functionname)
Begin profiling of a function.
Definition: Profiler.php:33
RequestContext\getRequest
getRequest()
Get the WebRequest object.
Definition: RequestContext.php:101
WikiPage
Class representing a MediaWiki article and history.
Definition: WikiPage.php:37
$params
$params
Definition: styleTest.css.php:40
RequestContext\getLang
getLang()
Definition: RequestContext.php:297
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:388
$s
$s
Definition: mergeMessageFileList.php:156
RequestContext\$config
Config $config
Definition: RequestContext.php:61
RequestContext\$skin
Skin $skin
Definition: RequestContext.php:57
$wgContLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as and the content language as $wgContLang
Definition: design.txt:56
RequestContext\getUser
getUser()
Get the User object.
Definition: RequestContext.php:234
RequestContext\msg
msg()
Helpful methods.
Definition: RequestContext.php:407
title
to move a page</td >< td > &*You are moving the page across *A non empty talk page already exists under the new or *You uncheck the box below In those you will have to move or merge the page manually if desired</td >< td > be sure to &You are responsible for making sure that links continue to point where they are supposed to go Note that the page will &a page at the new title
Definition: All_system_messages.txt:2703
Config
Interface for configuration instances.
Definition: Config.php:28
RequestContext\setTitle
setTitle( $t)
Set the Title object.
Definition: RequestContext.php:116
MWException
MediaWiki exception.
Definition: MWException.php:26
WikiPage\factory
static factory(Title $title)
Create a WikiPage object of the appropriate class for the given title.
Definition: WikiPage.php:103
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1127
RequestContext\getWikiPage
getWikiPage()
Get the WikiPage object.
Definition: RequestContext.php:188
RequestContext\getConfig
getConfig()
Get the Config object.
Definition: RequestContext.php:77
WikiPage\getTitle
getTitle()
Get the title object of the article.
Definition: WikiPage.php:221
wfProfileOut
wfProfileOut( $functionname='missing')
Stop profiling of a function.
Definition: Profiler.php:46
RequestContext\setSkin
setSkin(Skin $s)
Set the Skin object.
Definition: RequestContext.php:350
RequestContext\newExtraneousContext
static newExtraneousContext(Title $title, $request=array())
Create a new extraneous context.
Definition: RequestContext.php:535
ConfigFactory\getDefaultInstance
static getDefaultInstance()
Definition: ConfigFactory.php:42
wfRunHooks
wfRunHooks( $event, array $args=array(), $deprecatedVersion=null)
Call hook functions defined in $wgHooks.
Definition: GlobalFunctions.php:4001
RequestContext\$lang
Language $lang
Definition: RequestContext.php:53
array
the array() calling protocol came about after MediaWiki 1.4rc1.
List of Api Query prop modules.
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
RequestContext
Group all the pieces relevant to the context of a request into one instance.
Definition: RequestContext.php:30
Title\canExist
canExist()
Is this in a namespace that allows actual pages?
Definition: Title.php:979
RequestContext\$wikipage
WikiPage $wikipage
Definition: RequestContext.php:41
RequestContext\getLanguage
getLanguage()
Get the Language object.
Definition: RequestContext.php:310
ContextSource\setContext
setContext(IContextSource $context)
Set the IContextSource object.
Definition: ContextSource.php:57
OutputPage
This class should be covered by a general architecture document which does not exist as of January 20...
Definition: OutputPage.php:38
ScopedCallback
Class for asserting that a callback happens when an dummy object leaves scope.
Definition: ScopedCallback.php:28
RequestContext\getSkin
getSkin()
Get the Skin object.
Definition: RequestContext.php:360
wfDebug
wfDebug( $text, $dest='all')
Sends a line to the debug log if enabled or, optionally, to a comment in output.
Definition: GlobalFunctions.php:933
RequestContext\$output
OutputPage $output
Definition: RequestContext.php:45
WebRequest\setIP
setIP( $ip)
Definition: WebRequest.php:1168
user
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 and we might be restricted by PHP settings such as safe mode or open_basedir We cannot assume that the software even has read access anywhere useful Many shared hosts run all users web applications under the same user
Definition: distributors.txt:9
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:336
skin
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a skin(according to that user 's preference)
$value
$value
Definition: styleTest.css.php:45
RequestContext\setWikiPage
setWikiPage(WikiPage $p)
Set the WikiPage object.
Definition: RequestContext.php:168
User\getOption
getOption( $oname, $defaultOverride=null, $ignoreHidden=false)
Get the user's current setting for a given option.
Definition: User.php:2425
RequestContext\$request
WebRequest $request
Definition: RequestContext.php:33
RequestContext\getTitle
getTitle()
Get the Title object.
Definition: RequestContext.php:130
RequestContext\getMain
static getMain()
Static methods.
Definition: RequestContext.php:420
IP\isValid
static isValid( $ip)
Validate an IP address.
Definition: IP.php:108
Language\isValidCode
static isValidCode( $code)
Returns true if a language code string is of a valid form, whether or not it exists.
Definition: Language.php:337
RequestContext\importScopedSession
static importScopedSession(array $params)
Import the resolved user IP, HTTP headers, user ID, and session ID.
Definition: RequestContext.php:461
IContextSource
Interface for objects which can provide a context on request.
Definition: IContextSource.php:29
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form,...
Definition: WebRequest.php:38
$args
if( $line===false) $args
Definition: cdb.php:62
Title
Represents a title within MediaWiki.
Definition: Title.php:35
output
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add in any and then calling output() to send it all. It could be easily changed to send incrementally if that becomes useful
WebRequest\getVal
getVal( $name, $default=null)
Fetch a scalar from the input or return $default if it's not set.
Definition: WebRequest.php:374
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
RequestContext\setOutput
setOutput(OutputPage $o)
Definition: RequestContext.php:203
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:184
$t
$t
Definition: testCompression.php:65
RequestContext\canUseWikiPage
canUseWikiPage()
Check whether a WikiPage object can be get with getWikiPage().
Definition: RequestContext.php:147
RequestContext\getOutput
getOutput()
Get the OutputPage object.
Definition: RequestContext.php:212
Skin
The main skin class which provides methods and properties for all other skins.
Definition: Skin.php:35
$e
if( $useReadline) $e
Definition: eval.php:66
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:59
request
div flags Integer display flags(NO_ACTION_LINK, NO_EXTRA_USER_LINKS) 'LoginAuthenticateAudit' this hook is for auditing only etc create2 Corresponds to logging log_action database field and which is displayed in the UI similar to $comment this hook should only be used to add variables that depend on the current page request
Definition: hooks.txt:1632
RequestContext\setLanguage
setLanguage( $l)
Set the Language object.
Definition: RequestContext.php:281
Language
Internationalisation code.
Definition: Language.php:74
RequestContext\exportSession
exportSession()
Export the resolved user IP, HTTP headers, user ID, and session ID.
Definition: RequestContext.php:436
Skin\newFromKey
static & newFromKey( $key)
Factory method for loading a skin of a given type.
Definition: Skin.php:176
$wgTitle
if(! $wgRequest->checkUrlExtension()) if(! $wgEnableAPI) $wgTitle
Definition: api.php:63
RequestContext\setRequest
setRequest(WebRequest $r)
Set the WebRequest object.
Definition: RequestContext.php:92