Requests for comment/Context object
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
- ...
Context object | |
---|---|
Component | General |
Creation date | |
Author(s) | IAlex |
Document status | implemented |
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
editBackward 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
- ...