Separate RequestContext.php into separate files inside of context/
authorDaniel Friesen <dantman@users.mediawiki.org>
Thu, 15 Sep 2011 17:42:17 +0000 (17:42 +0000)
committerDaniel Friesen <dantman@users.mediawiki.org>
Thu, 15 Sep 2011 17:42:17 +0000 (17:42 +0000)
Update the AutoLoader too. This is also a follow up to r97161 since I forgot to add the AutoLoader line.

includes/AutoLoader.php
includes/RequestContext.php [deleted file]
includes/context/ContextSource.php [new file with mode: 0644]
includes/context/DerivativeContext.php [new file with mode: 0644]
includes/context/IContextSource.php [new file with mode: 0644]
includes/context/RequestContext.php [new file with mode: 0644]

index 73ab7e0..96b68d9 100644 (file)
@@ -46,7 +46,6 @@ $wgAutoloadLocalClasses = array(
        'ConfEditor' => 'includes/ConfEditor.php',
        'ConfEditorParseError' => 'includes/ConfEditor.php',
        'ConfEditorToken' => 'includes/ConfEditor.php',
-       'ContextSource' => 'includes/RequestContext.php',
        'Cookie' => 'includes/Cookie.php',
        'CookieJar' => 'includes/Cookie.php',
        'DeferrableUpdate' => 'includes/DeferredUpdates.php',
@@ -116,7 +115,6 @@ $wgAutoloadLocalClasses = array(
        'HTMLTextField' => 'includes/HTMLForm.php',
        'Http' => 'includes/HttpFunctions.php',
        'HttpRequest' => 'includes/HttpFunctions.old.php',
-       'IContextSource' => 'includes/RequestContext.php',
        'IcuCollation' => 'includes/Collation.php',
        'IdentityCollation' => 'includes/Collation.php',
        'ImageGallery' => 'includes/ImageGallery.php',
@@ -139,6 +137,7 @@ $wgAutoloadLocalClasses = array(
        'Linker' => 'includes/Linker.php',
        'LinkFilter' => 'includes/LinkFilter.php',
        'LinksUpdate' => 'includes/LinksUpdate.php',
+       'ListMessageParser' => 'includes/ListMessageParser.php',
        'LocalisationCache' => 'includes/LocalisationCache.php',
        'LocalisationCache_BulkLoad' => 'includes/LocalisationCache.php',
        'LogEventsList' => 'includes/LogEventsList.php',
@@ -187,7 +186,6 @@ $wgAutoloadLocalClasses = array(
        'RegexlikeReplacer' => 'includes/StringUtils.php',
        'ReplacementArray' => 'includes/StringUtils.php',
        'Replacer' => 'includes/StringUtils.php',
-       'RequestContext' => 'includes/RequestContext.php',
        'ReverseChronologicalPager' => 'includes/Pager.php',
        'RevisionItemBase' => 'includes/RevisionList.php',
        'RevisionListBase' => 'includes/RevisionList.php',
@@ -200,6 +198,7 @@ $wgAutoloadLocalClasses = array(
        'SiteStatsInit' => 'includes/SiteStats.php',
        'SiteStatsUpdate' => 'includes/SiteStats.php',
        'Skin' => 'includes/Skin.php',
+       'Skin2' => 'includes/Skin2.php',
        'SkinLegacy' => 'includes/SkinLegacy.php',
        'SkinTemplate' => 'includes/SkinTemplate.php',
        'SpecialCreateAccount' => 'includes/SpecialPage.php',
@@ -384,6 +383,12 @@ $wgAutoloadLocalClasses = array(
        'DatabaseConf' => 'includes/conf/DatabaseConf.php',
        'DefaultSettings' => 'includes/conf/DefaultSettings.php',
 
+       # includes/context
+       'ContextSource' => 'includes/context/ContextSource.php',
+       'DerivativeContext' => 'includes/context/DerivativeContext.php',
+       'IContextSource' => 'includes/context/IContextSource.php',
+       'RequestContext' => 'includes/context/RequestContext.php',
+
        # includes/db
        'Blob' => 'includes/db/DatabaseUtility.php',
        'ChronologyProtector' => 'includes/db/LBFactory.php',
@@ -533,6 +538,7 @@ $wgAutoloadLocalClasses = array(
        'JavaScriptMinifier' => 'includes/libs/JavaScriptMinifier.php',
        'JSMinPlus' => 'includes/libs/jsminplus.php',
        'JSParser' => 'includes/libs/jsminplus.php',
+       'simple_html_dom' => 'includes/libs/simple_html_dom.php',
 
        # includes/logging
        'LogEntry' => 'includes/logging/LogEntry.php',
diff --git a/includes/RequestContext.php b/includes/RequestContext.php
deleted file mode 100644 (file)
index 2d2dc66..0000000
+++ /dev/null
@@ -1,634 +0,0 @@
-<?php
-/**
- * Request-dependant objects containers.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- * http://www.gnu.org/copyleft/gpl.html
- *
- * @since 1.18
- *
- * @author Alexandre Emsenhuber
- * @author Daniel Friesen
- * @file
- */
-
-/**
- * Interface for objects which can provide a context on request.
- */
-interface IContextSource {
-
-       /**
-        * Get the WebRequest object
-        *
-        * @return WebRequest
-        */
-       public function getRequest();
-
-       /**
-        * Get the Title object
-        *
-        * @return Title
-        */
-       public function getTitle();
-
-       /**
-        * Get the OutputPage object
-        *
-        * @return OutputPage object
-        */
-       public function getOutput();
-
-       /**
-        * Get the User object
-        *
-        * @return User
-        */
-       public function getUser();
-
-       /**
-        * Get the Language object
-        *
-        * @return Language
-        */
-       public function getLang();
-
-       /**
-        * Get the Skin object
-        *
-        * @return Skin
-        */
-       public function getSkin();
-}
-
-/**
- * Group all the pieces relevant to the context of a request into one instance
- */
-class RequestContext implements IContextSource {
-
-       /**
-        * @var WebRequest
-        */
-       private $request;
-
-       /**
-        * @var Title
-        */
-       private $title;
-
-       /**
-        * @var OutputPage
-        */
-       private $output;
-
-       /**
-        * @var User
-        */
-       private $user;
-
-       /**
-        * @var Language
-        */
-       private $lang;
-
-       /**
-        * @var Skin
-        */
-       private $skin;
-
-       /**
-        * Set the WebRequest object
-        *
-        * @param $r WebRequest object
-        */
-       public function setRequest( WebRequest $r ) {
-               $this->request = $r;
-       }
-
-       /**
-        * Get the WebRequest object
-        *
-        * @return WebRequest
-        */
-       public function getRequest() {
-               if ( $this->request === null ) {
-                       global $wgRequest; # fallback to $wg till we can improve this
-                       $this->request = $wgRequest;
-               }
-               return $this->request;
-       }
-
-       /**
-        * Set the Title object
-        *
-        * @param $t Title object
-        */
-       public function setTitle( Title $t ) {
-               $this->title = $t;
-       }
-
-       /**
-        * Get the Title object
-        *
-        * @return Title
-        */
-       public function getTitle() {
-               if ( $this->title === null ) {
-                       global $wgTitle; # fallback to $wg till we can improve this
-                       $this->title = $wgTitle;
-               }
-               return $this->title;
-       }
-
-       /**
-        * @param $o OutputPage
-        */
-       public function setOutput( OutputPage $o ) {
-               $this->output = $o;
-       }
-
-       /**
-        * Get the OutputPage object
-        *
-        * @return OutputPage object
-        */
-       public function getOutput() {
-               if ( $this->output === null ) {
-                       $this->output = new OutputPage( $this );
-               }
-               return $this->output;
-       }
-
-       /**
-        * Set the User object
-        *
-        * @param $u User
-        */
-       public function setUser( User $u ) {
-               $this->user = $u;
-       }
-
-       /**
-        * Get the User object
-        *
-        * @return User
-        */
-       public function getUser() {
-               if ( $this->user === null ) {
-                       $this->user = User::newFromSession( $this->getRequest() );
-               }
-               return $this->user;
-       }
-
-       /**
-        * Accepts a language code and ensures it's sane. Outputs a cleaned up language
-        * code and replaces with $wgLanguageCode if not sane.
-        */
-       private static function sanitizeLangCode( $code ) {
-               global $wgLanguageCode;
-
-               // BCP 47 - letter case MUST NOT carry meaning
-               $code = strtolower( $code );
-
-               # Validate $code
-               if( empty( $code ) || !Language::isValidCode( $code ) || ( $code === 'qqq' ) ) {
-                       wfDebug( "Invalid user language code\n" );
-                       $code = $wgLanguageCode;
-               }
-
-               return $code;
-       }
-
-       /**
-        * Set the Language object
-        *
-        * @param $l Mixed Language instance or language code
-        */
-       public function setLang( $l ) {
-               if ( $l instanceof Language ) {
-                       $this->lang = $l;
-               } elseif ( is_string( $l ) ) {
-                       $l = self::sanitizeLangCode( $l );
-                       $obj = Language::factory( $l );
-                       $this->lang = $obj;
-               } else {
-                       throw new MWException( __METHOD__ . " was passed an invalid type of data." );
-               }
-       }
-
-       /**
-        * Get the Language object
-        *
-        * @return Language
-        */
-       public function getLang() {
-               if ( $this->lang === null ) {
-                       global $wgLanguageCode, $wgContLang;
-                       $code = $this->getRequest()->getVal(
-                               'uselang',
-                               $this->getUser()->getOption( 'language' )
-                       );
-                       $code = self::sanitizeLangCode( $code );
-
-                       wfRunHooks( 'UserGetLanguageObject', array( $this->getUser(), &$code ) );
-
-                       if( $code === $wgLanguageCode ) {
-                               $this->lang = $wgContLang;
-                       } else {
-                               $obj = Language::factory( $code );
-                               $this->lang = $obj;
-                       }
-               }
-               return $this->lang;
-       }
-
-       /**
-        * Set the Skin object
-        *
-        * @param $s Skin
-        */
-       public function setSkin( Skin $s ) {
-               $this->skin = clone $s;
-               $this->skin->setContext( $this );
-       }
-
-       /**
-        * Get the Skin object
-        *
-        * @return Skin
-        */
-       public function getSkin() {
-               if ( $this->skin === null ) {
-                       wfProfileIn( __METHOD__ . '-createskin' );
-                       
-                       global $wgHiddenPrefs;
-                       if( !in_array( 'skin', $wgHiddenPrefs ) ) {
-                               # get the user skin
-                               $userSkin = $this->getUser()->getOption( 'skin' );
-                               $userSkin = $this->getRequest()->getVal( 'useskin', $userSkin );
-                       } else {
-                               # if we're not allowing users to override, then use the default
-                               global $wgDefaultSkin;
-                               $userSkin = $wgDefaultSkin;
-                       }
-
-                       $this->skin = Skin::newFromKey( $userSkin );
-                       $this->skin->setContext( $this );
-                       wfProfileOut( __METHOD__ . '-createskin' );
-               }
-               return $this->skin;
-       }
-
-       /** Helpful methods **/
-
-       /**
-        * Get a Message object with context set
-        * Parameters are the same as wfMessage()
-        *
-        * @return Message object
-        */
-       public function msg() {
-               $args = func_get_args();
-               return call_user_func_array( 'wfMessage', $args )->inLanguage( $this->getLang() )->title( $this->getTitle() );
-       }
-
-       /** Static methods **/
-
-       /**
-        * Get the RequestContext object associated with the main request
-        *
-        * @return RequestContext object
-        */
-       public static function getMain() {
-               static $instance = null;
-               if ( $instance === null ) {
-                       $instance = new self;
-               }
-               return $instance;
-       }
-
-       /**
-        * Create a new extraneous context. The context is filled with information
-        * external to the current session.
-        * - Title is specified by argument
-        * - Request is a FauxRequest, or a FauxRequest can be specified by argument
-        * - User is an anonymous user, for separation IPv4 localhost is used
-        * - Language will be based on the anonymous user and request, may be content
-        *   language or a uselang param in the fauxrequest data may change the lang
-        * - Skin will be based on the anonymous user, should be the wiki's default skin
-        *
-        * @param $title Title Title to use for the extraneous request
-        * @param $request Mixed A WebRequest or data to use for a FauxRequest
-        * @return RequestContext
-        */
-       public static function newExtraneousContext( Title $title, $request=array() ) {
-               $context = new self;
-               $context->setTitle( $title );
-               if ( $request instanceof WebRequest ) {
-                       $context->setRequest( $request );
-               } else {
-                       $context->setRequest( new FauxRequest( $request ) );
-               }
-               $context->user = User::newFromName( '127.0.0.1', false );
-               return $context;
-       }
-
-}
-
-/**
- * The simplest way of implementing IContextSource is to hold a RequestContext as a
- * member variable and provide accessors to it.
- */
-abstract class ContextSource implements IContextSource {
-
-       /**
-        * @var IContextSource
-        */
-       private $context;
-
-       /**
-        * Get the IContextSource object
-        *
-        * @return IContextSource
-        */
-       public function getContext() {
-               if ( $this->context === null ) {
-                       $class = get_class( $this );
-                       wfDebug( __METHOD__  . " ($class): called and \$context is null. Using RequestContext::getMain() for sanity\n" );
-                       $this->context = RequestContext::getMain();
-               }
-               return $this->context;
-       }
-
-       /**
-        * Set the IContextSource object
-        *
-        * @param $context IContextSource
-        */
-       public function setContext( IContextSource $context ) {
-               $this->context = $context;
-       }
-
-       /**
-        * Get the WebRequest object
-        *
-        * @return WebRequest
-        */
-       public function getRequest() {
-               return $this->getContext()->getRequest();
-       }
-
-       /**
-        * Get the Title object
-        *
-        * @return Title
-        */
-       public function getTitle() {
-               return $this->getContext()->getTitle();
-       }
-
-       /**
-        * Get the OutputPage object
-        *
-        * @return OutputPage object
-        */
-       public function getOutput() {
-               return $this->getContext()->getOutput();
-       }
-
-       /**
-        * Get the User object
-        *
-        * @return User
-        */
-       public function getUser() {
-               return $this->getContext()->getUser();
-       }
-
-       /**
-        * Get the Language object
-        *
-        * @return Language
-        */
-       public function getLang() {
-               return $this->getContext()->getLang();
-       }
-
-       /**
-        * Get the Skin object
-        *
-        * @return Skin
-        */
-       public function getSkin() {
-               return $this->getContext()->getSkin();
-       }
-
-       /**
-        * Get a Message object with context set
-        * Parameters are the same as wfMessage()
-        *
-        * @return Message object
-        */
-       public function msg( /* $args */ ) {
-               return call_user_func_array( array( $this->getContext(), 'msg' ), func_get_args() );
-       }
-}
-
-/**
- * An IContextSource implementation which will inherit context from another source
- * but allow individual pieces of context to be changed locally
- * eg: A ContextSource that can inherit from the main RequestContext but have
- *     a different Title instance set on it.
- */
-class DerivativeContext extends ContextSource {
-
-       /**
-        * @var WebRequest
-        */
-       private $request;
-
-       /**
-        * @var Title
-        */
-       private $title;
-
-       /**
-        * @var OutputPage
-        */
-       private $output;
-
-       /**
-        * @var User
-        */
-       private $user;
-
-       /**
-        * @var Language
-        */
-       private $lang;
-
-       /**
-        * @var Skin
-        */
-       private $skin;
-
-       /**
-        * Constructor
-        * @param $context IContextSource Context to inherit from
-        */
-       public function __construct( IContextSource $context ) {
-               $this->setContext( $context );
-       }
-
-       /**
-        * Set the WebRequest object
-        *
-        * @param $r WebRequest object
-        */
-       public function setRequest( WebRequest $r ) {
-               $this->request = $r;
-       }
-
-       /**
-        * Get the WebRequest object
-        *
-        * @return WebRequest
-        */
-       public function getRequest() {
-               if ( !is_null( $this->request ) ) {
-                       return $this->request;
-               } else {
-                       return $this->getContext()->getRequest();
-               }
-       }
-
-       /**
-        * Set the Title object
-        *
-        * @param $t Title object
-        */
-       public function setTitle( Title $t ) {
-               $this->title = $t;
-       }
-
-       /**
-        * Get the Title object
-        *
-        * @return Title
-        */
-       public function getTitle() {
-               if ( !is_null( $this->title ) ) {
-                       return $this->title;
-               } else {
-                       return $this->getContext()->getTitle();
-               }
-       }
-
-       /**
-        * @param $o OutputPage
-        */
-       public function setOutput( OutputPage $o ) {
-               $this->output = $o;
-       }
-
-       /**
-        * Get the OutputPage object
-        *
-        * @return OutputPage object
-        */
-       public function getOutput() {
-               if ( !is_null( $this->output ) ) {
-                       return $this->output;
-               } else {
-                       return $this->getContext()->getOutput();
-               }
-       }
-
-       /**
-        * Set the User object
-        *
-        * @param $u User
-        */
-       public function setUser( User $u ) {
-               $this->user = $u;
-       }
-
-       /**
-        * Get the User object
-        *
-        * @return User
-        */
-       public function getUser() {
-               if ( !is_null( $this->user ) ) {
-                       return $this->user;
-               } else {
-                       return $this->getContext()->getUser();
-               }
-       }
-
-       /**
-        * Set the Language object
-        *
-        * @param $l Mixed Language instance or language code
-        */
-       public function setLang( $l ) {
-               if ( $l instanceof Language ) {
-                       $this->lang = $l;
-               } elseif ( is_string( $l ) ) {
-                       $l = self::sanitizeLangCode( $l );
-                       $obj = Language::factory( $l );
-                       $this->lang = $obj;
-               } else {
-                       throw new MWException( __METHOD__ . " was passed an invalid type of data." );
-               }
-       }
-
-       /**
-        * Get the Language object
-        *
-        * @return Language
-        */
-       public function getLang() {
-               if ( !is_null( $this->lang ) ) {
-                       return $this->lang;
-               } else {
-                       return $this->getContext()->getLang();
-               }
-       }
-
-       /**
-        * Set the Skin object
-        *
-        * @param $s Skin
-        */
-       public function setSkin( Skin $s ) {
-               $this->skin = clone $s;
-               $this->skin->setContext( $this );
-       }
-
-       /**
-        * Get the Skin object
-        *
-        * @return Skin
-        */
-       public function getSkin() {
-               if ( !is_null( $this->skin ) ) {
-                       return $this->skin;
-               } else {
-                       return $this->getContext()->getSkin();
-               }
-       }
-
-}
-
diff --git a/includes/context/ContextSource.php b/includes/context/ContextSource.php
new file mode 100644 (file)
index 0000000..3ab9168
--- /dev/null
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Request-dependant objects containers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.18
+ *
+ * @author Happy-melon
+ * @file
+ */
+
+/**
+ * The simplest way of implementing IContextSource is to hold a RequestContext as a
+ * member variable and provide accessors to it.
+ */
+abstract class ContextSource implements IContextSource {
+
+       /**
+        * @var IContextSource
+        */
+       private $context;
+
+       /**
+        * Get the IContextSource object
+        *
+        * @return IContextSource
+        */
+       public function getContext() {
+               if ( $this->context === null ) {
+                       $class = get_class( $this );
+                       wfDebug( __METHOD__  . " ($class): called and \$context is null. Using RequestContext::getMain() for sanity\n" );
+                       $this->context = RequestContext::getMain();
+               }
+               return $this->context;
+       }
+
+       /**
+        * Set the IContextSource object
+        *
+        * @param $context IContextSource
+        */
+       public function setContext( IContextSource $context ) {
+               $this->context = $context;
+       }
+
+       /**
+        * Get the WebRequest object
+        *
+        * @return WebRequest
+        */
+       public function getRequest() {
+               return $this->getContext()->getRequest();
+       }
+
+       /**
+        * Get the Title object
+        *
+        * @return Title
+        */
+       public function getTitle() {
+               return $this->getContext()->getTitle();
+       }
+
+       /**
+        * Get the OutputPage object
+        *
+        * @return OutputPage object
+        */
+       public function getOutput() {
+               return $this->getContext()->getOutput();
+       }
+
+       /**
+        * Get the User object
+        *
+        * @return User
+        */
+       public function getUser() {
+               return $this->getContext()->getUser();
+       }
+
+       /**
+        * Get the Language object
+        *
+        * @return Language
+        */
+       public function getLang() {
+               return $this->getContext()->getLang();
+       }
+
+       /**
+        * Get the Skin object
+        *
+        * @return Skin
+        */
+       public function getSkin() {
+               return $this->getContext()->getSkin();
+       }
+
+       /**
+        * Get a Message object with context set
+        * Parameters are the same as wfMessage()
+        *
+        * @return Message object
+        */
+       public function msg( /* $args */ ) {
+               return call_user_func_array( array( $this->getContext(), 'msg' ), func_get_args() );
+       }
+}
+
diff --git a/includes/context/DerivativeContext.php b/includes/context/DerivativeContext.php
new file mode 100644 (file)
index 0000000..fa0d6fe
--- /dev/null
@@ -0,0 +1,212 @@
+<?php
+/**
+ * Request-dependant objects containers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.19
+ *
+ * @author Daniel Friesen
+ * @file
+ */
+
+/**
+ * An IContextSource implementation which will inherit context from another source
+ * but allow individual pieces of context to be changed locally
+ * eg: A ContextSource that can inherit from the main RequestContext but have
+ *     a different Title instance set on it.
+ */
+class DerivativeContext extends ContextSource {
+
+       /**
+        * @var WebRequest
+        */
+       private $request;
+
+       /**
+        * @var Title
+        */
+       private $title;
+
+       /**
+        * @var OutputPage
+        */
+       private $output;
+
+       /**
+        * @var User
+        */
+       private $user;
+
+       /**
+        * @var Language
+        */
+       private $lang;
+
+       /**
+        * @var Skin
+        */
+       private $skin;
+
+       /**
+        * Constructor
+        * @param $context IContextSource Context to inherit from
+        */
+       public function __construct( IContextSource $context ) {
+               $this->setContext( $context );
+       }
+
+       /**
+        * Set the WebRequest object
+        *
+        * @param $r WebRequest object
+        */
+       public function setRequest( WebRequest $r ) {
+               $this->request = $r;
+       }
+
+       /**
+        * Get the WebRequest object
+        *
+        * @return WebRequest
+        */
+       public function getRequest() {
+               if ( !is_null( $this->request ) ) {
+                       return $this->request;
+               } else {
+                       return $this->getContext()->getRequest();
+               }
+       }
+
+       /**
+        * Set the Title object
+        *
+        * @param $t Title object
+        */
+       public function setTitle( Title $t ) {
+               $this->title = $t;
+       }
+
+       /**
+        * Get the Title object
+        *
+        * @return Title
+        */
+       public function getTitle() {
+               if ( !is_null( $this->title ) ) {
+                       return $this->title;
+               } else {
+                       return $this->getContext()->getTitle();
+               }
+       }
+
+       /**
+        * @param $o OutputPage
+        */
+       public function setOutput( OutputPage $o ) {
+               $this->output = $o;
+       }
+
+       /**
+        * Get the OutputPage object
+        *
+        * @return OutputPage object
+        */
+       public function getOutput() {
+               if ( !is_null( $this->output ) ) {
+                       return $this->output;
+               } else {
+                       return $this->getContext()->getOutput();
+               }
+       }
+
+       /**
+        * Set the User object
+        *
+        * @param $u User
+        */
+       public function setUser( User $u ) {
+               $this->user = $u;
+       }
+
+       /**
+        * Get the User object
+        *
+        * @return User
+        */
+       public function getUser() {
+               if ( !is_null( $this->user ) ) {
+                       return $this->user;
+               } else {
+                       return $this->getContext()->getUser();
+               }
+       }
+
+       /**
+        * Set the Language object
+        *
+        * @param $l Mixed Language instance or language code
+        */
+       public function setLang( $l ) {
+               if ( $l instanceof Language ) {
+                       $this->lang = $l;
+               } elseif ( is_string( $l ) ) {
+                       $l = self::sanitizeLangCode( $l );
+                       $obj = Language::factory( $l );
+                       $this->lang = $obj;
+               } else {
+                       throw new MWException( __METHOD__ . " was passed an invalid type of data." );
+               }
+       }
+
+       /**
+        * Get the Language object
+        *
+        * @return Language
+        */
+       public function getLang() {
+               if ( !is_null( $this->lang ) ) {
+                       return $this->lang;
+               } else {
+                       return $this->getContext()->getLang();
+               }
+       }
+
+       /**
+        * Set the Skin object
+        *
+        * @param $s Skin
+        */
+       public function setSkin( Skin $s ) {
+               $this->skin = clone $s;
+               $this->skin->setContext( $this );
+       }
+
+       /**
+        * Get the Skin object
+        *
+        * @return Skin
+        */
+       public function getSkin() {
+               if ( !is_null( $this->skin ) ) {
+                       return $this->skin;
+               } else {
+                       return $this->getContext()->getSkin();
+               }
+       }
+
+}
+
diff --git a/includes/context/IContextSource.php b/includes/context/IContextSource.php
new file mode 100644 (file)
index 0000000..12dd1a1
--- /dev/null
@@ -0,0 +1,73 @@
+<?php
+/**
+ * Request-dependant objects containers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.18
+ *
+ * @author Happy-melon
+ * @file
+ */
+
+/**
+ * Interface for objects which can provide a context on request.
+ */
+interface IContextSource {
+
+       /**
+        * Get the WebRequest object
+        *
+        * @return WebRequest
+        */
+       public function getRequest();
+
+       /**
+        * Get the Title object
+        *
+        * @return Title
+        */
+       public function getTitle();
+
+       /**
+        * Get the OutputPage object
+        *
+        * @return OutputPage object
+        */
+       public function getOutput();
+
+       /**
+        * Get the User object
+        *
+        * @return User
+        */
+       public function getUser();
+
+       /**
+        * Get the Language object
+        *
+        * @return Language
+        */
+       public function getLang();
+
+       /**
+        * Get the Skin object
+        *
+        * @return Skin
+        */
+       public function getSkin();
+}
+
diff --git a/includes/context/RequestContext.php b/includes/context/RequestContext.php
new file mode 100644 (file)
index 0000000..fffad42
--- /dev/null
@@ -0,0 +1,300 @@
+<?php
+/**
+ * Request-dependant objects containers.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * http://www.gnu.org/copyleft/gpl.html
+ *
+ * @since 1.18
+ *
+ * @author Alexandre Emsenhuber
+ * @author Daniel Friesen
+ * @file
+ */
+
+/**
+ * Group all the pieces relevant to the context of a request into one instance
+ */
+class RequestContext implements IContextSource {
+
+       /**
+        * @var WebRequest
+        */
+       private $request;
+
+       /**
+        * @var Title
+        */
+       private $title;
+
+       /**
+        * @var OutputPage
+        */
+       private $output;
+
+       /**
+        * @var User
+        */
+       private $user;
+
+       /**
+        * @var Language
+        */
+       private $lang;
+
+       /**
+        * @var Skin
+        */
+       private $skin;
+
+       /**
+        * Set the WebRequest object
+        *
+        * @param $r WebRequest object
+        */
+       public function setRequest( WebRequest $r ) {
+               $this->request = $r;
+       }
+
+       /**
+        * Get the WebRequest object
+        *
+        * @return WebRequest
+        */
+       public function getRequest() {
+               if ( $this->request === null ) {
+                       global $wgRequest; # fallback to $wg till we can improve this
+                       $this->request = $wgRequest;
+               }
+               return $this->request;
+       }
+
+       /**
+        * Set the Title object
+        *
+        * @param $t Title object
+        */
+       public function setTitle( Title $t ) {
+               $this->title = $t;
+       }
+
+       /**
+        * Get the Title object
+        *
+        * @return Title
+        */
+       public function getTitle() {
+               if ( $this->title === null ) {
+                       global $wgTitle; # fallback to $wg till we can improve this
+                       $this->title = $wgTitle;
+               }
+               return $this->title;
+       }
+
+       /**
+        * @param $o OutputPage
+        */
+       public function setOutput( OutputPage $o ) {
+               $this->output = $o;
+       }
+
+       /**
+        * Get the OutputPage object
+        *
+        * @return OutputPage object
+        */
+       public function getOutput() {
+               if ( $this->output === null ) {
+                       $this->output = new OutputPage( $this );
+               }
+               return $this->output;
+       }
+
+       /**
+        * Set the User object
+        *
+        * @param $u User
+        */
+       public function setUser( User $u ) {
+               $this->user = $u;
+       }
+
+       /**
+        * Get the User object
+        *
+        * @return User
+        */
+       public function getUser() {
+               if ( $this->user === null ) {
+                       $this->user = User::newFromSession( $this->getRequest() );
+               }
+               return $this->user;
+       }
+
+       /**
+        * Accepts a language code and ensures it's sane. Outputs a cleaned up language
+        * code and replaces with $wgLanguageCode if not sane.
+        */
+       private static function sanitizeLangCode( $code ) {
+               global $wgLanguageCode;
+
+               // BCP 47 - letter case MUST NOT carry meaning
+               $code = strtolower( $code );
+
+               # Validate $code
+               if( empty( $code ) || !Language::isValidCode( $code ) || ( $code === 'qqq' ) ) {
+                       wfDebug( "Invalid user language code\n" );
+                       $code = $wgLanguageCode;
+               }
+
+               return $code;
+       }
+
+       /**
+        * Set the Language object
+        *
+        * @param $l Mixed Language instance or language code
+        */
+       public function setLang( $l ) {
+               if ( $l instanceof Language ) {
+                       $this->lang = $l;
+               } elseif ( is_string( $l ) ) {
+                       $l = self::sanitizeLangCode( $l );
+                       $obj = Language::factory( $l );
+                       $this->lang = $obj;
+               } else {
+                       throw new MWException( __METHOD__ . " was passed an invalid type of data." );
+               }
+       }
+
+       /**
+        * Get the Language object
+        *
+        * @return Language
+        */
+       public function getLang() {
+               if ( $this->lang === null ) {
+                       global $wgLanguageCode, $wgContLang;
+                       $code = $this->getRequest()->getVal(
+                               'uselang',
+                               $this->getUser()->getOption( 'language' )
+                       );
+                       $code = self::sanitizeLangCode( $code );
+
+                       wfRunHooks( 'UserGetLanguageObject', array( $this->getUser(), &$code ) );
+
+                       if( $code === $wgLanguageCode ) {
+                               $this->lang = $wgContLang;
+                       } else {
+                               $obj = Language::factory( $code );
+                               $this->lang = $obj;
+                       }
+               }
+               return $this->lang;
+       }
+
+       /**
+        * Set the Skin object
+        *
+        * @param $s Skin
+        */
+       public function setSkin( Skin $s ) {
+               $this->skin = clone $s;
+               $this->skin->setContext( $this );
+       }
+
+       /**
+        * Get the Skin object
+        *
+        * @return Skin
+        */
+       public function getSkin() {
+               if ( $this->skin === null ) {
+                       wfProfileIn( __METHOD__ . '-createskin' );
+                       
+                       global $wgHiddenPrefs;
+                       if( !in_array( 'skin', $wgHiddenPrefs ) ) {
+                               # get the user skin
+                               $userSkin = $this->getUser()->getOption( 'skin' );
+                               $userSkin = $this->getRequest()->getVal( 'useskin', $userSkin );
+                       } else {
+                               # if we're not allowing users to override, then use the default
+                               global $wgDefaultSkin;
+                               $userSkin = $wgDefaultSkin;
+                       }
+
+                       $this->skin = Skin::newFromKey( $userSkin );
+                       $this->skin->setContext( $this );
+                       wfProfileOut( __METHOD__ . '-createskin' );
+               }
+               return $this->skin;
+       }
+
+       /** Helpful methods **/
+
+       /**
+        * Get a Message object with context set
+        * Parameters are the same as wfMessage()
+        *
+        * @return Message object
+        */
+       public function msg() {
+               $args = func_get_args();
+               return call_user_func_array( 'wfMessage', $args )->inLanguage( $this->getLang() )->title( $this->getTitle() );
+       }
+
+       /** Static methods **/
+
+       /**
+        * Get the RequestContext object associated with the main request
+        *
+        * @return RequestContext object
+        */
+       public static function getMain() {
+               static $instance = null;
+               if ( $instance === null ) {
+                       $instance = new self;
+               }
+               return $instance;
+       }
+
+       /**
+        * Create a new extraneous context. The context is filled with information
+        * external to the current session.
+        * - Title is specified by argument
+        * - Request is a FauxRequest, or a FauxRequest can be specified by argument
+        * - User is an anonymous user, for separation IPv4 localhost is used
+        * - Language will be based on the anonymous user and request, may be content
+        *   language or a uselang param in the fauxrequest data may change the lang
+        * - Skin will be based on the anonymous user, should be the wiki's default skin
+        *
+        * @param $title Title Title to use for the extraneous request
+        * @param $request Mixed A WebRequest or data to use for a FauxRequest
+        * @return RequestContext
+        */
+       public static function newExtraneousContext( Title $title, $request=array() ) {
+               $context = new self;
+               $context->setTitle( $title );
+               if ( $request instanceof WebRequest ) {
+                       $context->setRequest( $request );
+               } else {
+                       $context->setRequest( new FauxRequest( $request ) );
+               }
+               $context->user = User::newFromName( '127.0.0.1', false );
+               return $context;
+       }
+
+}
+