Requests for comment/Context object
Appearance
Context object | |
---|---|
Component | General |
Creation date | |
Author(s) | IAlex |
Document status | implemented |
We are currently using more and more member variables to store local versions of global objects such as Title object in OutputPage, Skin, ... There are some problems with this method:
- We need to do this to this for each object we want to store in every class that need it
- When something changes, it needs to be passed to all objects
- ...
The proposal here is to replace all these members with only one "context" object that would contain the following members:
$request
to replace$wgRequest
$title
to replace$wgTitle
$out
to replace$wgOut
$user
to replace$wgUser
$lang
to replace$wgLang
$skin
to replace$wgUser->getSkin()
since there was concerns that this method should not be in the User class
As you can see, I propose to not add an $article
member to this object.
Mockup of the class
[edit]<?php
/**
* A class that hold request-dependant object
*/
class RequestContext {
private $request; /// WebRequest object
private $title; /// Title object
private $out; /// OutputPage object
private $user; /// User object
private $lang; /// Language object
private $skin; /// Skin object
/**
* Constructor
*
* @param $request WebRequest object
* @param $title Title object
* @param $user User object, optional
*/
public function __construct( $request, $title = null, $user = null ) {
$this->request = $request;
$this->title = $title;
$this->user = $user;
}
// Accessors
/**
* Get the WebRequest object
*
* @return WebRequest object
*/
public function getRequest() {
return $this->request;
}
/**
* Get the Title object
*
* @return Title object
*/
public function getTitle() {
if ( $this->out === null ) {
// Get a Title object
}
return $this->title;
}
/**
* Get the OutputPage object
*
* @return OutputPage object
*/
public function getOut() {
if ( $this->out === null ) {
$this->out = new OutputPage;
$this->out->setContext( $this );
}
return $this->out;
}
/**
* Get the User object
*
* @return User object
*/
public function getUser() {
if ( $this->user === null ) {
$this->user = User::newFromSession( $this->request );
}
return $this->user;
}
/**
* Get the Language object
*
* @return Language object
*/
public function getLang() {
if ( $this->lang === null ) {
// Insert code from StubUserLang::_newObject()
// Maybe run a hook
}
return $this->lang;
}
/**
* Get the Skin object
*
* @return Skin object
*/
public function getSkin() {
if ( $this->lang === null ) {
// Insert code from User::getSkin()
// Maybe run a hook
}
return $this->skin;
}
// Other useful functions
/**
* Get a Message object with context set
* Parameters are the same as wfMessage()
*
* @return Message object
*/
public function msg() {
$args = function_get_args();
return call_user_func_array( 'wfMessage', $args )->inLanguage( $this->getLang() )->outputPage( $this->getOut() );
}
// Static functions
/**
* Get the RequestContext object associated with the main request
*
* @return RequestContext object
*/
public static function getMain() {
static $instance = null;
if ( $instance === null ) {
global $wgRequest;
$instance = new self( $wgRequest );
}
return $instance;
}
}
Backward compatibility
[edit]Backward compatibility would not be hard to maintain by using StubObject
; e.g.
<?php
class StubUserLang extends StubObject {
// [...]
function _newObject() {
return RequestContext::getMain()->getLang();
}
}
Classes that should have a context object
[edit]- OutputPage
- Skin
- It would probably actually be better if Skin was dependent on OutputPage. Dantman 06:31, 3 April 2011 (UTC) - SpecialPage
- ...
Classes that should not have a context object
[edit]- Article
- Title
- User
- ...