MediaWiki master
EntryPoint.php
Go to the documentation of this file.
1<?php
2
3namespace MediaWiki\Rest;
4
21
26
27 private RequestInterface $request;
28 private ?Router $router = null;
29 private ?CorsUtils $cors = null;
30
42 public static function createRouter(
43 MediaWikiServices $services,
44 IContextSource $context,
45 RequestInterface $request,
46 ResponseFactory $responseFactory,
47 CorsUtils $cors
48 ): Router {
49 $conf = $services->getMainConfig();
50
51 $authority = $context->getAuthority();
52 $authorizer = new CompoundAuthorizer();
53 $authorizer
54 ->addAuthorizer( new MWBasicAuthorizer( $authority ) )
55 ->addAuthorizer( $cors );
56
57 $objectFactory = $services->getObjectFactory();
58 $restValidator = new Validator( $objectFactory,
59 $request,
60 $authority
61 );
62
63 $stats = $services->getStatsdDataFactory();
64
65 return ( new Router(
66 self::getRouteFiles( $conf ),
67 ExtensionRegistry::getInstance()->getAttribute( 'RestRoutes' ),
68 new ServiceOptions( Router::CONSTRUCTOR_OPTIONS, $conf ),
69 $services->getLocalServerObjectCache(),
70 $responseFactory,
71 $authorizer,
72 $authority,
73 $objectFactory,
74 $restValidator,
75 new MWErrorReporter(),
76 $services->getHookContainer(),
77 $context->getRequest()->getSession()
78 ) )
79 ->setCors( $cors )
80 ->setStats( $stats );
81 }
82
87 public static function getMainRequest(): RequestInterface {
88 static $mainRequest = null;
89
90 if ( $mainRequest === null ) {
91 $conf = MediaWikiServices::getInstance()->getMainConfig();
92 $mainRequest = new RequestFromGlobals( [
93 'cookiePrefix' => $conf->get( MainConfigNames::CookiePrefix )
94 ] );
95 }
96
97 return $mainRequest;
98 }
99
100 protected function doSetup() {
101 parent::doSetup();
102
103 $context = RequestContext::getMain();
104
105 // Set $wgTitle and the title in RequestContext, as in api.php
106 global $wgTitle;
107 $wgTitle = Title::makeTitle(
109 'Badtitle/rest.php'
110 );
111 $context->setTitle( $wgTitle );
112
113 $responseFactory = new ResponseFactory( $this->getTextFormatters() );
114 $responseFactory->setShowExceptionDetails(
115 MWExceptionRenderer::shouldShowExceptionDetails()
116 );
117
118 $this->cors = new CorsUtils(
119 new ServiceOptions(
120 CorsUtils::CONSTRUCTOR_OPTIONS,
121 $this->getServiceContainer()->getMainConfig()
122 ),
123 $responseFactory,
124 $context->getUser()
125 );
126
127 if ( !$this->router ) {
128 $this->router = $this->createRouter(
129 $this->getServiceContainer(),
130 $context,
131 $this->request,
132 $responseFactory,
133 $this->cors
134 );
135 }
136 }
137
143 private function getTextFormatters() {
144 $services = $this->getServiceContainer();
145
146 $code = $services->getContentLanguage()->getCode();
147 $langs = array_unique( [ $code, 'en' ] );
148 $textFormatters = [];
149 $factory = $services->getMessageFormatterFactory();
150
151 foreach ( $langs as $lang ) {
152 $textFormatters[] = $factory->getTextFormatter( $lang );
153 }
154
155 return $textFormatters;
156 }
157
163 private static function getRouteFiles( $conf ) {
164 global $IP;
165 $extensionsDir = $conf->get( MainConfigNames::ExtensionDirectory );
166 // Always include the "official" routes. Include additional routes if specified.
167 $routeFiles = array_merge(
168 [ 'includes/Rest/coreRoutes.json' ],
169 $conf->get( MainConfigNames::RestAPIAdditionalRouteFiles )
170 );
171 foreach ( $routeFiles as &$file ) {
172 if (
173 str_starts_with( $file, '/' )
174 ) {
175 // Allow absolute paths on non-Windows
176 } elseif (
177 str_starts_with( $file, 'extensions/' )
178 ) {
179 // Support hacks like Wikibase.ci.php
180 $file = substr_replace( $file, $extensionsDir,
181 0, strlen( 'extensions' ) );
182 } else {
183 $file = "$IP/$file";
184 }
185 }
186
187 return $routeFiles;
188 }
189
190 public function __construct(
191 RequestInterface $request,
192 RequestContext $context,
193 EntryPointEnvironment $environment,
194 MediaWikiServices $mediaWikiServices
195 ) {
196 parent::__construct( $context, $environment, $mediaWikiServices );
197
198 $this->request = $request;
199 }
200
207 public function setRouter( Router $router ): void {
208 $this->router = $router;
209 }
210
211 public function execute() {
212 $this->startOutputBuffer();
213
214 // IDEA: Move the call to cors->modifyResponse() into Module,
215 // so it's in the same class as cors->createPreflightResponse().
216 $response = $this->cors->modifyResponse(
217 $this->request,
218 $this->router->execute( $this->request )
219 );
220
221 $webResponse = $this->getResponse();
222
223 $webResponse->header(
224 'HTTP/' . $response->getProtocolVersion() . ' ' . $response->getStatusCode() . ' ' .
225 $response->getReasonPhrase()
226 );
227
228 foreach ( $response->getRawHeaderLines() as $line ) {
229 $webResponse->header( $line );
230 }
231
232 foreach ( $response->getCookies() as $cookie ) {
233 $webResponse->setCookie(
234 $cookie['name'],
235 $cookie['value'],
236 $cookie['expiry'],
237 $cookie['options']
238 );
239 }
240
241 // Clear all errors that might have been displayed if display_errors=On
242 $this->discardOutputBuffer();
243
244 $stream = $response->getBody();
245 $stream->rewind();
246
247 $this->prepareForOutput();
248
249 if ( $stream instanceof CopyableStreamInterface ) {
250 $stream->copyToStream( fopen( 'php://output', 'w' ) );
251 } else {
252 while ( true ) {
253 $buffer = $stream->read( 65536 );
254 if ( $buffer === '' ) {
255 break;
256 }
257 $this->print( $buffer );
258 }
259 }
260 }
261
262}
const NS_SPECIAL
Definition Defines.php:53
if(!defined( 'MEDIAWIKI')) if(ini_get('mbstring.func_overload')) if(!defined( 'MW_ENTRY_POINT')) global $IP
Environment checks.
Definition Setup.php:99
if(!defined( 'MW_NO_SESSION') &&MW_ENTRY_POINT !=='cli' $wgTitle
Definition Setup.php:537
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:28
Wrapper for ParamValidator.
Definition Validator.php:36
Represents a title within MediaWiki.
Definition Title.php:78
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.