MediaWiki master
EntryPoint.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Rest;
4
19use Wikimedia\Assert\Assert;
21
26
27 private ?Router $router = null;
28 private ?CorsUtils $cors = null;
29
42 public static function createRouter(
43 MediaWikiServices $services,
44 IContextSource $context,
46 array $textFormatters,
47 bool $showExceptionDetails,
48 CorsUtils $cors
49 ): Router {
50 Assert::parameter(
51 count( $textFormatters ) > 0,
52 '$textFormatters', 'must not be empty'
53 );
54
55 $conf = $services->getMainConfig();
56
57 $authority = $context->getAuthority();
58 $authorizer = new CompoundAuthorizer();
59 $authorizer
60 ->addAuthorizer( new MWBasicAuthorizer( $authority ) )
61 ->addAuthorizer( $cors );
62
63 $objectFactory = $services->getObjectFactory();
64 $restValidator = new Validator( $objectFactory,
66 $authority
67 );
68
69 $stats = $services->getStatsFactory();
70
71 // NOTE: Use preferred language, see getTextFormatters().
72 $defaultTextFormatter = array_first( $textFormatters );
73 $moduleManager = new ModuleManager(
74 new ServiceOptions( ModuleManager::CONSTRUCTOR_OPTIONS, $conf ),
75 ExtensionRegistry::getInstance()->getAttribute( 'RestModuleFiles' ),
76 $services->getLocalServerObjectCache(),
77 new JsonLocalizer( $defaultTextFormatter )
78 );
79
80 return ( new Router(
81 $moduleManager,
82 ExtensionRegistry::getInstance()->getAttribute( 'RestRoutes' ),
84 $services->getLocalServerObjectCache(),
85 $textFormatters,
86 $showExceptionDetails,
87 $authorizer,
88 $authority,
89 $objectFactory,
90 $restValidator,
91 new MWErrorReporter(),
92 $services->getHookContainer(),
93 $context->getRequest()->getSession(),
94 $services->getUrlUtils(),
95 ) )
96 ->setCors( $cors )
97 ->setStats( $stats );
98 }
99
104 public static function getMainRequest(): RequestInterface {
105 static $mainRequest = null;
106
107 if ( $mainRequest === null ) {
108 $conf = MediaWikiServices::getInstance()->getMainConfig();
109 $mainRequest = new RequestFromGlobals( [
110 'cookiePrefix' => $conf->get( MainConfigNames::CookiePrefix )
111 ] );
112 }
113
114 return $mainRequest;
115 }
116
117 protected function doSetup() {
118 parent::doSetup();
119
120 $context = $this->getContext();
121 $textFormatters = $this->getTextFormatters();
122 $showExceptionDetails = MWExceptionRenderer::shouldShowExceptionDetails();
123
124 $this->cors = new CorsUtils(
125 new ServiceOptions(
126 CorsUtils::CONSTRUCTOR_OPTIONS,
127 $this->getServiceContainer()->getMainConfig()
128 ),
129 $context->getUser()
130 );
131
132 if ( !$this->router ) {
133 $this->router = $this->createRouter(
134 $this->getServiceContainer(),
135 $context,
136 $this->request,
137 $textFormatters,
138 $showExceptionDetails,
139 $this->cors
140 );
141 }
142 }
143
149 private function getTextFormatters() {
150 $services = $this->getServiceContainer();
151
152 $code = $services->getContentLanguageCode()->toString();
153 $langs = [];
154
155 $queryParams = $this->request->getQueryParams();
156 $requestedLang = $queryParams['lang'] ?? null;
157 if ( is_string( $requestedLang ) && $requestedLang !== '' ) {
158 $internalCode = \MediaWiki\Language\LanguageCode::bcp47ToInternal( $requestedLang );
159 if ( $services->getLanguageNameUtils()->isSupportedLanguage( $internalCode ) ) {
160 $langs = [ $internalCode ];
161 }
162 }
163
164 $langs = array_unique( array_merge( $langs, [ $code, 'en' ] ) );
165 $textFormatters = [];
166 $factory = $services->getMessageFormatterFactory();
167
168 foreach ( $langs as $lang ) {
169 // XXX: we could key on language here
170 $textFormatters[] = $factory->getTextFormatter( $lang );
171 }
172
173 return $textFormatters;
174 }
175
176 public function __construct(
177 private readonly RequestInterface $request,
178 RequestContext $context,
179 EntryPointEnvironment $environment,
180 MediaWikiServices $mediaWikiServices,
181 ) {
182 parent::__construct( $context, $environment, $mediaWikiServices );
183 }
184
189 public function setRouter( Router $router ): void {
190 $this->router = $router;
191 }
192
193 public function execute() {
194 $this->startOutputBuffer();
195
196 $response = $this->router->execute( $this->request );
197
198 $webResponse = $this->getResponse();
199
200 $webResponse->header(
201 'HTTP/' . $response->getProtocolVersion() . ' ' . $response->getStatusCode() . ' ' .
202 $response->getReasonPhrase()
203 );
204
205 foreach ( $response->getRawHeaderLines() as $line ) {
206 $webResponse->header( $line );
207 }
208
209 foreach ( $response->getCookies() as $cookie ) {
210 $webResponse->setCookie(
211 $cookie['name'],
212 $cookie['value'],
213 $cookie['expire'],
214 $cookie['options']
215 );
216 }
217
218 // Clear all errors that might have been displayed if display_errors=On
219 $this->discardOutputBuffer();
220
221 $stream = $response->getBody();
222 $stream->rewind();
223
224 $this->prepareForOutput();
225
226 if ( $stream instanceof CopyableStreamInterface ) {
227 $stream->copyToStream( fopen( 'php://output', 'w' ) );
228 } else {
229 while ( true ) {
230 $buffer = $stream->read( 65536 );
231 if ( $buffer === '' ) {
232 break;
233 }
234 $this->print( $buffer );
235 }
236 }
237 }
238
239}
A class for passing options to services.
Group all the pieces relevant to the context of a request into one instance.
Utility class wrapping PHP runtime state.
Class to expose exceptions to the client (API bots, users, admins using CLI scripts)
A class containing constants representing the names of configuration variables.
const CookiePrefix
Name constant for the CookiePrefix setting, for use with Config::get()
Base class for entry point handlers.
Service locator for MediaWiki core services.
getMainConfig()
Returns the Config object that provides configuration for MediaWiki core.
getLocalServerObjectCache()
Returns the main server-local cache, yielding EmptyBagOStuff if there is none.
getObjectFactory()
ObjectFactory is intended for instantiating "handlers" from declarative definitions,...
static getInstance()
Returns the global default instance of the top level service locator.
Load JSON files, and uses a Processor to extract information.
Wraps an array of BasicAuthorizerInterface and checks them all to authorize the request.
A factory for MWBasicRequestAuthorizer which passes through a UserIdentity.
doSetup()
Perform any setup needed before execute() is called.
setRouter(Router $router)
Sets the router to use.
__construct(private readonly RequestInterface $request, RequestContext $context, EntryPointEnvironment $environment, MediaWikiServices $mediaWikiServices,)
static createRouter(MediaWikiServices $services, IContextSource $context, RequestInterface $request, array $textFormatters, bool $showExceptionDetails, CorsUtils $cors)
execute()
Subclasses implement the entry point's functionality by overriding this method.
Utility class for json localization needs in the REST API.
Manages information related to REST modules, such as routes and specs.
Error reporter based on MWExceptionHandler.
This is a request class that gets data directly from the superglobals and other global PHP state,...
The REST router is responsible for gathering module configuration, matching an input path against the...
Definition Router.php:34
const CONSTRUCTOR_OPTIONS
Definition Router.php:83
Wrapper for ParamValidator.
Definition Validator.php:39
Interface for objects which can provide a MediaWiki context on request.
An interface for a stream with a copyToStream() function.
A request interface similar to PSR-7's ServerRequestInterface.
Converts MessageSpecifier objects to localized plain text in a certain language.