Update Codex from v1.20.0 to v1.20.1
[mediawiki.git] / includes / context / DerivativeContext.php
blob369260711ffbb0ea032a6ef8971721703129692c
1 <?php
2 /**
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
18 * @author Daniel Friesen
19 * @file
22 namespace MediaWiki\Context;
24 use MediaWiki\Config\Config;
25 use MediaWiki\Language\Language;
26 use MediaWiki\MediaWikiServices;
27 use MediaWiki\Message\Message;
28 use MediaWiki\Output\OutputPage;
29 use MediaWiki\Permissions\Authority;
30 use MediaWiki\Request\WebRequest;
31 use MediaWiki\Title\Title;
32 use MediaWiki\User\User;
33 use Skin;
34 use Timing;
35 use Wikimedia\Assert\Assert;
36 use Wikimedia\Message\MessageParam;
37 use Wikimedia\Message\MessageSpecifier;
38 use WikiPage;
40 /**
41 * An IContextSource implementation which will inherit context from another source
42 * but allow individual pieces of context to be changed locally
43 * eg: A ContextSource that can inherit from the main RequestContext but have
44 * a different Title instance set on it.
45 * @newable
46 * @since 1.19
48 class DerivativeContext extends ContextSource implements MutableContext {
49 /**
50 * @var WebRequest
52 private $request;
54 /**
55 * @var Title
57 private $title;
59 /**
60 * @var WikiPage
62 private $wikipage;
64 /**
65 * @var string|null|false
67 private $action = false;
69 /**
70 * @var OutputPage
72 private $output;
74 /**
75 * @var User|null
77 private $user;
79 /**
80 * @var Authority
82 private $authority;
84 /**
85 * @var Language
87 private $lang;
89 /**
90 * @var Skin
92 private $skin;
94 /**
95 * @var Config
97 private $config;
99 /**
100 * @var Timing
102 private $timing;
105 * @stable to call
106 * @param IContextSource $context Context to inherit from
108 public function __construct( IContextSource $context ) {
109 $this->setContext( $context );
112 public function setConfig( Config $config ) {
113 $this->config = $config;
117 * @return Config
119 public function getConfig() {
120 return $this->config ?: $this->getContext()->getConfig();
124 * @return Timing
126 public function getTiming() {
127 return $this->timing ?: $this->getContext()->getTiming();
130 public function setRequest( WebRequest $request ) {
131 $this->request = $request;
135 * @return WebRequest
137 public function getRequest() {
138 return $this->request ?: $this->getContext()->getRequest();
141 public function setTitle( Title $title ) {
142 $this->title = $title;
143 $this->action = null;
147 * @return Title|null
149 public function getTitle() {
150 return $this->title ?: $this->getContext()->getTitle();
154 * Check whether a WikiPage object can be get with getWikiPage().
155 * Callers should expect that an exception is thrown from getWikiPage()
156 * if this method returns false.
158 * @since 1.19
159 * @return bool
161 public function canUseWikiPage() {
162 if ( $this->wikipage !== null ) {
163 return true;
166 if ( $this->title !== null ) {
167 return $this->title->canExist();
170 return $this->getContext()->canUseWikiPage();
174 * @since 1.19
175 * @param WikiPage $wikiPage
177 public function setWikiPage( WikiPage $wikiPage ) {
178 $pageTitle = $wikiPage->getTitle();
179 if ( !$this->title || !$pageTitle->equals( $this->title ) ) {
180 $this->setTitle( $pageTitle );
182 $this->wikipage = $wikiPage;
183 $this->action = null;
187 * Get the WikiPage object.
188 * May throw an exception if there's no Title object set or the Title object
189 * belongs to a special namespace that doesn't have WikiPage, so use first
190 * canUseWikiPage() to check whether this method can be called safely.
192 * @since 1.19
193 * @return WikiPage
195 public function getWikiPage() {
196 if ( !$this->wikipage && $this->title ) {
197 $this->wikipage = MediaWikiServices::getInstance()->getWikiPageFactory()->newFromTitle( $this->title );
200 return $this->wikipage ?: $this->getContext()->getWikiPage();
204 * @since 1.38
205 * @param string $action
207 public function setActionName( string $action ): void {
208 $this->action = $action;
212 * Get the action name for the current web request.
214 * @since 1.38
215 * @return string Action
217 public function getActionName(): string {
218 if ( $this->action === false ) {
219 return $this->getContext()->getActionName();
222 $this->action ??= MediaWikiServices::getInstance()
223 ->getActionFactory()
224 ->getActionName( $this );
226 return $this->action;
229 public function setOutput( OutputPage $output ) {
230 $this->output = $output;
234 * @return OutputPage
236 public function getOutput() {
237 return $this->output ?: $this->getContext()->getOutput();
240 public function setUser( User $user ) {
241 $this->authority = $user;
242 $this->user = $user;
246 * @return User
248 public function getUser() {
249 if ( !$this->user && $this->authority ) {
250 // Keep user consistent by using a possible set authority
251 $this->user = MediaWikiServices::getInstance()
252 ->getUserFactory()
253 ->newFromAuthority( $this->authority );
255 return $this->user ?: $this->getContext()->getUser();
258 public function setAuthority( Authority $authority ) {
259 $this->authority = $authority;
260 // If needed, a User object is constructed from this authority
261 $this->user = null;
265 * @since 1.36
266 * @return Authority
268 public function getAuthority(): Authority {
269 return $this->authority ?: $this->getContext()->getAuthority();
273 * @param Language|string $language Language instance or language code
274 * @since 1.19
276 public function setLanguage( $language ) {
277 Assert::parameterType( [ Language::class, 'string' ], $language, '$language' );
278 if ( $language instanceof Language ) {
279 $this->lang = $language;
280 } else {
281 $language = RequestContext::sanitizeLangCode( $language );
282 $obj = MediaWikiServices::getInstance()->getLanguageFactory()->getLanguage( $language );
283 $this->lang = $obj;
288 * @return Language
289 * @since 1.19
291 public function getLanguage() {
292 return $this->lang ?: $this->getContext()->getLanguage();
295 public function setSkin( Skin $skin ) {
296 $this->skin = clone $skin;
297 $this->skin->setContext( $this );
301 * @return Skin
303 public function getSkin() {
304 return $this->skin ?: $this->getContext()->getSkin();
308 * Get a message using the current context.
310 * This can't just inherit from ContextSource, since then
311 * it would set only the original context, and not take
312 * into account any changes.
314 * @param string|string[]|MessageSpecifier $key Message key, or array of keys,
315 * or a MessageSpecifier.
316 * @phpcs:ignore Generic.Files.LineLength
317 * @param MessageParam|MessageSpecifier|string|int|float|list<MessageParam|MessageSpecifier|string|int|float> ...$params
318 * See Message::params()
319 * @return Message
321 public function msg( $key, ...$params ) {
322 // phpcs:ignore MediaWiki.Usage.ExtendClassUsage.FunctionVarUsage
323 return wfMessage( $key, ...$params )->setContext( $this );
327 /** @deprecated class alias since 1.42 */
328 class_alias( DerivativeContext::class, 'DerivativeContext' );