MediaWiki master
EntryPoint.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Rest;
4
20
25
26 private RequestInterface $request;
27 private ?Router $router = null;
28 private ?CorsUtils $cors = null;
29
41 public static function createRouter(
42 MediaWikiServices $services,
43 IContextSource $context,
44 RequestInterface $request,
45 ResponseFactory $responseFactory,
46 CorsUtils $cors
47 ): Router {
48 $conf = $services->getMainConfig();
49
50 $authority = $context->getAuthority();
51 $authorizer = new CompoundAuthorizer();
52 $authorizer
53 ->addAuthorizer( new MWBasicAuthorizer( $authority ) )
54 ->addAuthorizer( $cors );
55
56 $objectFactory = $services->getObjectFactory();
57 $restValidator = new Validator( $objectFactory,
58 $request,
59 $authority
60 );
61
62 $stats = $services->getStatsFactory();
63
64 return ( new Router(
65 self::getRouteFiles( $conf ),
66 ExtensionRegistry::getInstance()->getAttribute( 'RestRoutes' ),
67 new ServiceOptions( Router::CONSTRUCTOR_OPTIONS, $conf ),
68 $services->getLocalServerObjectCache(),
69 $responseFactory,
70 $authorizer,
71 $authority,
72 $objectFactory,
73 $restValidator,
74 new MWErrorReporter(),
75 $services->getHookContainer(),
76 $context->getRequest()->getSession()
77 ) )
78 ->setCors( $cors )
79 ->setStats( $stats );
80 }
81
86 public static function getMainRequest(): RequestInterface {
87 static $mainRequest = null;
88
89 if ( $mainRequest === null ) {
90 $conf = MediaWikiServices::getInstance()->getMainConfig();
91 $mainRequest = new RequestFromGlobals( [
92 'cookiePrefix' => $conf->get( MainConfigNames::CookiePrefix )
93 ] );
94 }
95
96 return $mainRequest;
97 }
98
99 protected function doSetup() {
100 parent::doSetup();
101
102 $context = RequestContext::getMain();
103
104 $responseFactory = new ResponseFactory( $this->getTextFormatters() );
105 $responseFactory->setShowExceptionDetails(
106 MWExceptionRenderer::shouldShowExceptionDetails()
107 );
108
109 $this->cors = new CorsUtils(
110 new ServiceOptions(
111 CorsUtils::CONSTRUCTOR_OPTIONS,
112 $this->getServiceContainer()->getMainConfig()
113 ),
114 $responseFactory,
115 $context->getUser()
116 );
117
118 if ( !$this->router ) {
119 $this->router = $this->createRouter(
120 $this->getServiceContainer(),
121 $context,
122 $this->request,
123 $responseFactory,
124 $this->cors
125 );
126 }
127 }
128
134 private function getTextFormatters() {
135 $services = $this->getServiceContainer();
136
137 $code = $services->getContentLanguage()->getCode();
138 $langs = array_unique( [ $code, 'en' ] );
139 $textFormatters = [];
140 $factory = $services->getMessageFormatterFactory();
141
142 foreach ( $langs as $lang ) {
143 $textFormatters[] = $factory->getTextFormatter( $lang );
144 }
145
146 return $textFormatters;
147 }
148
154 private static function getRouteFiles( $conf ) {
155 global $IP;
156 $extensionsDir = $conf->get( MainConfigNames::ExtensionDirectory );
157 // Always include the "official" routes. Include additional routes if specified.
158 $routeFiles = array_merge(
159 [ 'includes/Rest/coreRoutes.json' ],
160 $conf->get( MainConfigNames::RestAPIAdditionalRouteFiles )
161 );
162 foreach ( $routeFiles as &$file ) {
163 if (
164 str_starts_with( $file, '/' )
165 ) {
166 // Allow absolute paths on non-Windows
167 } elseif (
168 str_starts_with( $file, 'extensions/' )
169 ) {
170 // Support hacks like Wikibase.ci.php
171 $file = substr_replace( $file, $extensionsDir,
172 0, strlen( 'extensions' ) );
173 } else {
174 $file = "$IP/$file";
175 }
176 }
177
178 return $routeFiles;
179 }
180
181 public function __construct(
182 RequestInterface $request,
183 RequestContext $context,
184 EntryPointEnvironment $environment,
185 MediaWikiServices $mediaWikiServices
186 ) {
187 parent::__construct( $context, $environment, $mediaWikiServices );
188
189 $this->request = $request;
190 }
191
198 public function setRouter( Router $router ): void {
199 $this->router = $router;
200 }
201
202 public function execute() {
203 $this->startOutputBuffer();
204
205 // IDEA: Move the call to cors->modifyResponse() into Module,
206 // so it's in the same class as cors->createPreflightResponse().
207 $response = $this->cors->modifyResponse(
208 $this->request,
209 $this->router->execute( $this->request )
210 );
211
212 $webResponse = $this->getResponse();
213
214 $webResponse->header(
215 'HTTP/' . $response->getProtocolVersion() . ' ' . $response->getStatusCode() . ' ' .
216 $response->getReasonPhrase()
217 );
218
219 foreach ( $response->getRawHeaderLines() as $line ) {
220 $webResponse->header( $line );
221 }
222
223 foreach ( $response->getCookies() as $cookie ) {
224 $webResponse->setCookie(
225 $cookie['name'],
226 $cookie['value'],
227 $cookie['expiry'],
228 $cookie['options']
229 );
230 }
231
232 // Clear all errors that might have been displayed if display_errors=On
233 $this->discardOutputBuffer();
234
235 $stream = $response->getBody();
236 $stream->rewind();
237
238 $this->prepareForOutput();
239
240 if ( $stream instanceof CopyableStreamInterface ) {
241 $stream->copyToStream( fopen( 'php://output', 'w' ) );
242 } else {
243 while ( true ) {
244 $buffer = $stream->read( 65536 );
245 if ( $buffer === '' ) {
246 break;
247 }
248 $this->print( $buffer );
249 }
250 }
251 }
252
253}
if(!defined( 'MEDIAWIKI')) if(ini_get('mbstring.func_overload')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.
Definition Setup.php:100
Load JSON files, and uses a Processor to extract information.
Class to expose exceptions to the client (API bots, users, admins using CLI scripts)
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.
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.
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.
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(RequestInterface $request, RequestContext $context, EntryPointEnvironment $environment, MediaWikiServices $mediaWikiServices)
execute()
Subclasses implement the entry point's functionality by overriding this method.
static createRouter(MediaWikiServices $services, IContextSource $context, RequestInterface $request, ResponseFactory $responseFactory, CorsUtils $cors)
Error reporter based on MWExceptionHandler.
This is a request class that gets data directly from the superglobals and other global PHP state,...
Generates standardized response objects.
setShowExceptionDetails(bool $showExceptionDetails)
Control whether web responses may include a exception messager and backtrace.
The REST router is responsible for gathering module configuration, matching an input path against the...
Definition Router.php:29
Wrapper for ParamValidator.
Definition Validator.php:37
Interface for configuration instances.
Definition Config.php:32
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.