diff options
Diffstat (limited to 'includes/context')
-rw-r--r-- | includes/context/ContextSource.php | 34 | ||||
-rw-r--r-- | includes/context/DerivativeContext.php | 58 | ||||
-rw-r--r-- | includes/context/IContextSource.php | 20 | ||||
-rw-r--r-- | includes/context/RequestContext.php | 187 |
4 files changed, 179 insertions, 120 deletions
diff --git a/includes/context/ContextSource.php b/includes/context/ContextSource.php index e13cfa88..076504ec 100644 --- a/includes/context/ContextSource.php +++ b/includes/context/ContextSource.php @@ -34,16 +34,18 @@ abstract class ContextSource implements IContextSource { private $context; /** - * Get the RequestContext object + * Get the base IContextSource object * @since 1.18 - * @return RequestContext + * @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" ); + wfDebug( __METHOD__ . " ($class): called and \$context is null. " . + "Using RequestContext::getMain() for sanity\n" ); $this->context = RequestContext::getMain(); } + return $this->context; } @@ -58,6 +60,16 @@ abstract class ContextSource implements IContextSource { } /** + * Get the Config object + * + * @since 1.23 + * @return Config + */ + public function getConfig() { + return $this->getContext()->getConfig(); + } + + /** * Get the WebRequest object * * @since 1.18 @@ -71,7 +83,7 @@ abstract class ContextSource implements IContextSource { * Get the Title object * * @since 1.18 - * @return Title + * @return Title|null */ public function getTitle() { return $this->getContext()->getTitle(); @@ -125,17 +137,6 @@ abstract class ContextSource implements IContextSource { /** * Get the Language object * - * @deprecated since 1.19 Use getLanguage instead - * @return Language - */ - public function getLang() { - wfDeprecated( __METHOD__, '1.19' ); - return $this->getLanguage(); - } - - /** - * Get the Language object - * * @since 1.19 * @return Language */ @@ -162,6 +163,7 @@ abstract class ContextSource implements IContextSource { */ public function msg( /* $args */ ) { $args = func_get_args(); + return call_user_func_array( array( $this->getContext(), 'msg' ), $args ); } @@ -169,7 +171,7 @@ abstract class ContextSource implements IContextSource { * Export the resolved user IP, HTTP headers, user ID, and session ID. * The result will be reasonably sized to allow for serialization. * - * @return Array + * @return array * @since 1.21 */ public function exportSession() { diff --git a/includes/context/DerivativeContext.php b/includes/context/DerivativeContext.php index fd9bf963..b8966f0c 100644 --- a/includes/context/DerivativeContext.php +++ b/includes/context/DerivativeContext.php @@ -66,6 +66,11 @@ class DerivativeContext extends ContextSource { private $skin; /** + * @var Config + */ + private $config; + + /** * Constructor * @param IContextSource $context Context to inherit from */ @@ -74,6 +79,28 @@ class DerivativeContext extends ContextSource { } /** + * Set the SiteConfiguration object + * + * @param Config $s + */ + public function setConfig( Config $s ) { + $this->config = $s; + } + + /** + * Get the Config object + * + * @return Config + */ + public function getConfig() { + if ( !is_null( $this->config ) ) { + return $this->config; + } else { + return $this->getContext()->getConfig(); + } + } + + /** * Set the WebRequest object * * @param WebRequest $r @@ -100,17 +127,14 @@ class DerivativeContext extends ContextSource { * * @param Title $t */ - public function setTitle( $t ) { - if ( $t !== null && !$t instanceof Title ) { - throw new MWException( __METHOD__ . " expects an instance of Title" ); - } + public function setTitle( Title $t ) { $this->title = $t; } /** * Get the Title object * - * @return Title + * @return Title|null */ public function getTitle() { if ( !is_null( $this->title ) ) { @@ -212,17 +236,6 @@ class DerivativeContext extends ContextSource { /** * Set the Language object * - * @deprecated since 1.19 Use setLanguage instead - * @param Language|string $l Language instance or language code - */ - public function setLang( $l ) { - wfDeprecated( __METHOD__, '1.19' ); - $this->setLanguage( $l ); - } - - /** - * Set the Language object - * * @param Language|string $l Language instance or language code * @throws MWException * @since 1.19 @@ -240,15 +253,6 @@ class DerivativeContext extends ContextSource { } /** - * @deprecated since 1.19 Use getLanguage instead - * @return Language - */ - public function getLang() { - wfDeprecated( __METHOD__, '1.19' ); - $this->getLanguage(); - } - - /** * Get the Language object * * @return Language @@ -292,12 +296,12 @@ class DerivativeContext extends ContextSource { * it would set only the original context, and not take * into account any changes. * - * @param String Message name - * @param Variable number of message arguments + * @param mixed $args,... Arguments to wfMessage * @return Message */ public function msg() { $args = func_get_args(); + return call_user_func_array( 'wfMessage', $args )->setContext( $this ); } } diff --git a/includes/context/IContextSource.php b/includes/context/IContextSource.php index 35d5aed6..f718103d 100644 --- a/includes/context/IContextSource.php +++ b/includes/context/IContextSource.php @@ -37,7 +37,7 @@ interface IContextSource { /** * Get the Title object * - * @return Title + * @return Title|null */ public function getTitle(); @@ -79,14 +79,6 @@ interface IContextSource { /** * Get the Language object * - * @deprecated since 1.19 Use getLanguage instead - * @return Language - */ - public function getLang(); - - /** - * Get the Language object - * * @return Language * @since 1.19 */ @@ -100,6 +92,14 @@ interface IContextSource { public function getSkin(); /** + * Get the site configuration + * + * @since 1.23 + * @return Config + */ + public function getConfig(); + + /** * Get a Message object with context set * * @return Message @@ -110,7 +110,7 @@ interface IContextSource { * Export the resolved user IP, HTTP headers, user ID, and session ID. * The result will be reasonably sized to allow for serialization. * - * @return Array + * @return array * @since 1.21 */ public function exportSession(); diff --git a/includes/context/RequestContext.php b/includes/context/RequestContext.php index 01ec57c0..ede10fe9 100644 --- a/includes/context/RequestContext.php +++ b/includes/context/RequestContext.php @@ -64,6 +64,40 @@ class RequestContext implements IContextSource { private $skin; /** + * @var Config + */ + private $config; + + /** + * @var RequestContext + */ + private static $instance = null; + + /** + * Set the Config object + * + * @param Config $c + */ + public function setConfig( Config $c ) { + $this->config = $c; + } + + /** + * Get the Config object + * + * @return Config + */ + public function getConfig() { + if ( $this->config === null ) { + // @todo In the future, we could move this to WebStart.php so + // the Config object is ready for when initialization happens + $this->config = ConfigFactory::getDefaultInstance()->makeConfig( 'main' ); + } + + return $this->config; + } + + /** * Set the WebRequest object * * @param WebRequest $r @@ -82,19 +116,17 @@ class RequestContext implements IContextSource { global $wgRequest; # fallback to $wg till we can improve this $this->request = $wgRequest; } + return $this->request; } /** * Set the Title object * - * @param Title $t + * @param Title $title */ - public function setTitle( $t ) { - if ( $t !== null && !$t instanceof Title ) { - throw new MWException( __METHOD__ . " expects an instance of Title" ); - } - $this->title = $t; + public function setTitle( Title $title ) { + $this->title = $title; // Erase the WikiPage so a new one with the new title gets created. $this->wikipage = null; } @@ -102,13 +134,14 @@ class RequestContext implements IContextSource { /** * Get the Title object * - * @return Title + * @return Title|null */ public function getTitle() { if ( $this->title === null ) { global $wgTitle; # fallback to $wg till we can improve this $this->title = $wgTitle; } + return $this->title; } @@ -121,18 +154,14 @@ class RequestContext implements IContextSource { * @return bool */ public function canUseWikiPage() { - if ( $this->wikipage !== null ) { - # If there's a WikiPage object set, we can for sure get it + if ( $this->wikipage ) { + // If there's a WikiPage object set, we can for sure get it return true; } + // Only pages with legitimate titles can have WikiPages. + // That usually means pages in non-virtual namespaces. $title = $this->getTitle(); - if ( $title === null ) { - # No Title, no WikiPage - return false; - } else { - # Only namespaces whose pages are stored in the database can have WikiPage - return $title->canExist(); - } + return $title ? $title->canExist() : false; } /** @@ -169,11 +198,12 @@ class RequestContext implements IContextSource { } $this->wikipage = WikiPage::factory( $title ); } + return $this->wikipage; } /** - * @param $o OutputPage + * @param OutputPage $o */ public function setOutput( OutputPage $o ) { $this->output = $o; @@ -188,6 +218,7 @@ class RequestContext implements IContextSource { if ( $this->output === null ) { $this->output = new OutputPage( $this ); } + return $this->output; } @@ -209,6 +240,7 @@ class RequestContext implements IContextSource { if ( $this->user === null ) { $this->user = User::newFromSession( $this->getRequest() ); } + return $this->user; } @@ -225,7 +257,7 @@ class RequestContext implements IContextSource { $code = strtolower( $code ); # Validate $code - if ( empty( $code ) || !Language::isValidCode( $code ) || ( $code === 'qqq' ) ) { + if ( !$code || !Language::isValidCode( $code ) || $code === 'qqq' ) { wfDebug( "Invalid user language code\n" ); $code = $wgLanguageCode; } @@ -236,17 +268,6 @@ class RequestContext implements IContextSource { /** * Set the Language object * - * @deprecated since 1.19 Use setLanguage instead - * @param Language|string $l Language instance or language code - */ - public function setLang( $l ) { - wfDeprecated( __METHOD__, '1.19' ); - $this->setLanguage( $l ); - } - - /** - * Set the Language object - * * @param Language|string $l Language instance or language code * @throws MWException * @since 1.19 @@ -264,15 +285,6 @@ class RequestContext implements IContextSource { } /** - * @deprecated since 1.19 Use getLanguage instead - * @return Language - */ - public function getLang() { - wfDeprecated( __METHOD__, '1.19' ); - return $this->getLanguage(); - } - - /** * Get the Language object. * Initialization of user or request objects can depend on this. * @@ -285,30 +297,35 @@ class RequestContext implements IContextSource { $e = new Exception; wfDebugLog( 'recursion-guard', "Recursion detected:\n" . $e->getTraceAsString() ); - global $wgLanguageCode; - $code = ( $wgLanguageCode ) ? $wgLanguageCode : 'en'; + $code = $this->getConfig()->get( 'LanguageCode' ) ?: 'en'; $this->lang = Language::factory( $code ); } elseif ( $this->lang === null ) { $this->recursion = true; - global $wgLanguageCode, $wgContLang; + global $wgContLang; - $request = $this->getRequest(); - $user = $this->getUser(); + try { + $request = $this->getRequest(); + $user = $this->getUser(); - $code = $request->getVal( 'uselang', $user->getOption( 'language' ) ); - $code = self::sanitizeLangCode( $code ); + $code = $request->getVal( 'uselang', $user->getOption( 'language' ) ); + $code = self::sanitizeLangCode( $code ); - wfRunHooks( 'UserGetLanguageObject', array( $user, &$code, $this ) ); + wfRunHooks( 'UserGetLanguageObject', array( $user, &$code, $this ) ); - if ( $code === $wgLanguageCode ) { - $this->lang = $wgContLang; - } else { - $obj = Language::factory( $code ); - $this->lang = $obj; - } + if ( $code === $this->getConfig()->get( 'LanguageCode' ) ) { + $this->lang = $wgContLang; + } else { + $obj = Language::factory( $code ); + $this->lang = $obj; + } - unset( $this->recursion ); + unset( $this->recursion ); + } + catch ( Exception $ex ) { + unset( $this->recursion ); + throw $ex; + } } return $this->lang; @@ -335,35 +352,43 @@ class RequestContext implements IContextSource { $skin = null; wfRunHooks( 'RequestContextCreateSkin', array( $this, &$skin ) ); + $factory = SkinFactory::getDefaultInstance(); // If the hook worked try to set a skin from it if ( $skin instanceof Skin ) { $this->skin = $skin; } elseif ( is_string( $skin ) ) { - $this->skin = Skin::newFromKey( $skin ); + // Normalize the key, just in case the hook did something weird. + $normalized = Skin::normalizeKey( $skin ); + $this->skin = $factory->makeSkin( $normalized ); } // If this is still null (the hook didn't run or didn't work) // then go through the normal processing to load a skin if ( $this->skin === null ) { - global $wgHiddenPrefs; - if ( !in_array( 'skin', $wgHiddenPrefs ) ) { + if ( !in_array( 'skin', $this->getConfig()->get( 'HiddenPrefs' ) ) ) { # 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; + $userSkin = $this->getConfig()->get( 'DefaultSkin' ); } - $this->skin = Skin::newFromKey( $userSkin ); + // Normalize the key in case the user is passing gibberish + // or has old preferences (bug 69566). + $normalized = Skin::normalizeKey( $userSkin ); + + // Skin::normalizeKey will also validate it, so + // this won't throw an exception + $this->skin = $factory->makeSkin( $normalized ); } // After all that set a context on whatever skin got created $this->skin->setContext( $this ); wfProfileOut( __METHOD__ . '-createskin' ); } + return $this->skin; } @@ -377,6 +402,7 @@ class RequestContext implements IContextSource { */ public function msg() { $args = func_get_args(); + return call_user_func_array( 'wfMessage', $args )->setContext( $this ); } @@ -388,18 +414,43 @@ class RequestContext implements IContextSource { * @return RequestContext */ public static function getMain() { - static $instance = null; - if ( $instance === null ) { - $instance = new self; + if ( self::$instance === null ) { + self::$instance = new self; } - return $instance; + + return self::$instance; + } + + /** + * Get the RequestContext object associated with the main request + * and gives a warning to the log, to find places, where a context maybe is missing. + * + * @param string $func + * @return RequestContext + * @since 1.24 + */ + public static function getMainAndWarn( $func = __METHOD__ ) { + wfDebug( $func . ' called without context. ' . + "Using RequestContext::getMain() for sanity\n" ); + + return self::getMain(); + } + + /** + * Resets singleton returned by getMain(). Should be called only from unit tests. + */ + public static function resetMain() { + if ( !defined( 'MW_PHPUNIT_TEST' ) ) { + throw new MWException( __METHOD__ . '() should be called only from unit tests!' ); + } + self::$instance = null; } /** * Export the resolved user IP, HTTP headers, user ID, and session ID. * The result will be reasonably sized to allow for serialization. * - * @return Array + * @return array * @since 1.21 */ public function exportSession() { @@ -437,7 +488,8 @@ class RequestContext implements IContextSource { if ( $params['userId'] ) { // logged-in user $user = User::newFromId( $params['userId'] ); - if ( !$user ) { + $user->load(); + if ( !$user->getId() ) { throw new MWException( "No user with ID '{$params['userId']}'." ); } } elseif ( !IP::isValid( $params['ip'] ) ) { @@ -446,7 +498,7 @@ class RequestContext implements IContextSource { $user = User::newFromName( $params['ip'], false ); } - $importSessionFunction = function( User $user, array $params ) { + $importSessionFunction = function ( User $user, array $params ) { global $wgRequest, $wgUser; $context = RequestContext::getMain(); @@ -482,7 +534,7 @@ class RequestContext implements IContextSource { $importSessionFunction( $user, $params ); // Set callback to save and close the new session and reload the old one - return new ScopedCallback( function() use ( $importSessionFunction, $oUser, $oParams ) { + return new ScopedCallback( function () use ( $importSessionFunction, $oUser, $oParams ) { $importSessionFunction( $oUser, $oParams ); } ); } @@ -510,6 +562,7 @@ class RequestContext implements IContextSource { $context->setRequest( new FauxRequest( $request ) ); } $context->user = User::newFromName( '127.0.0.1', false ); + return $context; } } |