MediaWiki master
ExtraRoutesModule.php
Go to the documentation of this file.
1<?php
2
4
5use AppendIterator;
6use ArrayIterator;
7use Iterator;
18use Wikimedia\ObjectFactory\ObjectFactory;
19
65
67 private array $routeFiles;
68
72 private array $extraRoutes;
73
78 private ?array $routesFromFiles = null;
79
81 private ?array $routeFileTimestamps = null;
82
83 private ?string $configHash = null;
84
93 public function __construct(
94 array $routeFiles,
95 array $extraRoutes,
96 Router $router,
98 BasicAuthorizerInterface $basicAuth,
99 ObjectFactory $objectFactory,
100 Validator $restValidator,
101 ErrorReporter $errorReporter,
102 HookContainer $hookContainer
103 ) {
104 parent::__construct(
105 $router,
106 '',
108 $basicAuth,
109 $objectFactory,
110 $restValidator,
111 $errorReporter,
112 $hookContainer
113 );
114 $this->routeFiles = $routeFiles;
115 $this->extraRoutes = $extraRoutes;
116 }
117
121 protected function getConfigHash(): string {
122 if ( $this->configHash === null ) {
123 $this->configHash = md5( json_encode( [
124 'class' => __CLASS__,
125 'version' => 1,
126 'extraRoutes' => $this->extraRoutes,
127 'fileTimestamps' => $this->getRouteFileTimestamps()
128 ] ) );
129 }
130 return $this->configHash;
131 }
132
140 private function getRoutesFromFiles(): array {
141 if ( $this->routesFromFiles !== null ) {
142 return $this->routesFromFiles;
143 }
144
145 $this->routesFromFiles = [];
146 $this->routeFileTimestamps = [];
147 foreach ( $this->routeFiles as $fileName ) {
148 $this->routeFileTimestamps[$fileName] = filemtime( $fileName );
149
150 $routes = $this->loadJsonFile( $fileName );
151
152 $this->routesFromFiles = array_merge( $this->routesFromFiles, $routes );
153 }
154
155 return $this->routesFromFiles;
156 }
157
163 private function getRouteFileTimestamps(): array {
164 if ( $this->routeFileTimestamps === null ) {
165 $this->routeFileTimestamps = [];
166 foreach ( $this->routeFiles as $fileName ) {
167 $this->routeFileTimestamps[$fileName] = filemtime( $fileName );
168 }
169 }
170 return $this->routeFileTimestamps;
171 }
172
176 public function getDefinedPaths(): array {
177 $paths = [];
178 foreach ( $this->getAllRoutes() as $spec ) {
179 $key = $spec['path'];
180
181 $methods = isset( $spec['method'] ) ? (array)$spec['method'] : [ 'GET' ];
182
183 $paths[$key] = array_merge( $paths[$key] ?? [], $methods );
184 }
185
186 return $paths;
187 }
188
192 private function getAllRoutes() {
193 $iterator = new AppendIterator;
194 $iterator->append( new ArrayIterator( $this->getRoutesFromFiles() ) );
195 $iterator->append( new ArrayIterator( $this->extraRoutes ) );
196 return $iterator;
197 }
198
199 protected function initRoutes(): void {
200 $routeDefs = $this->getAllRoutes();
201
202 foreach ( $routeDefs as $route ) {
203 if ( !isset( $route['path'] ) ) {
204 throw new RouteDefinitionException( 'Missing path' );
205 }
206
207 $path = $route['path'];
208 $method = $route['method'] ?? 'GET';
209 $info = $this->makeRouteInfo( $route );
210
211 $this->addRoute( $method, $path, $info );
212 }
213 }
214
220 private function makeRouteInfo( array $route ): array {
221 static $objectSpecKeys = [
222 'class',
223 'factory',
224 'services',
225 'optional_services',
226 'args',
227 ];
228
229 if ( isset( $route['redirect'] ) ) {
230 // Redirect shorthand
231 $info = [
232 'spec' => [ 'class' => RedirectHandler::class ],
233 'config' => $route,
234 ];
235 } else {
236 // Object spec at the top level
237 $info = [
238 'spec' => array_intersect_key( $route, array_flip( $objectSpecKeys ) ),
239 'config' => array_diff_key( $route, array_flip( $objectSpecKeys ) ),
240 ];
241 }
242
243 $info['path'] = $route['path'];
244 return $info;
245 }
246
247 public function getOpenApiInfo() {
248 // Note that mwapi-1.0 is based on OAS 3.0, so it doesn't support the
249 // "summary" property introduced in 3.1.
250 $localizer = new JsonLocalizer( $this->responseFactory );
251 return [
252 'title' => $localizer->getFormattedMessage( 'rest-extra-routes-module-title' ),
253 'description' => $localizer->getFormattedMessage( 'rest-extra-routes-module-desc' ),
254 'version' => 'undefined',
255 ];
256 }
257
258}
if(!defined('MW_SETUP_CALLBACK'))
Definition WebStart.php:81
Utility class for json localization needs in the REST API.
A Module that is based on flat route definitions in the form originally introduced in MW 1....
getOpenApiInfo()
Return an array with data to be included in an OpenAPI "info" object describing this module.
__construct(array $routeFiles, array $extraRoutes, Router $router, ResponseFactory $responseFactory, BasicAuthorizerInterface $basicAuth, ObjectFactory $objectFactory, Validator $restValidator, ErrorReporter $errorReporter, HookContainer $hookContainer)
initRoutes()
Initialize matchers by calling addRoute() for each known route.
getConfigHash()
Get a config version hash for cache invalidation.
MatcherBasedModules respond to requests by matching the requested path against a list of known routes...
ResponseFactory $responseFactory
Definition Module.php:44
Exception indicating incorrect REST module configuration.
Generates standardized response objects.
The REST router is responsible for gathering module configuration, matching an input path against the...
Definition Router.php:30
Wrapper for ParamValidator.
Definition Validator.php:37
An interface used by Router to ensure that the client has "basic" access, i.e.
An ErrorReporter internally reports an error that happened during the handling of a request.