15use Wikimedia\ObjectFactory\ObjectFactory;
43 private string $definitionFile;
45 private ?array $moduleDef =
null;
47 private ?
int $routeFileTimestamp =
null;
49 private ?
string $configHash =
null;
55 string $definitionFile,
60 ObjectFactory $objectFactory,
75 $this->definitionFile = $definitionFile;
82 if ( $this->configHash === null ) {
83 $this->configHash = md5( json_encode( [
86 'fileTimestamps' => $this->getRouteFileTimestamp()
89 return $this->configHash;
95 private function getModuleDefinition(): array {
96 if ( $this->moduleDef !== null ) {
97 return $this->moduleDef;
100 $this->routeFileTimestamp = filemtime( $this->definitionFile );
101 $this->moduleDef = static::loadModuleDefinition( $this->definitionFile, $this->responseFactory );
103 return $this->moduleDef;
115 $moduleDef = static::loadJsonFile( $file );
119 'Malformed module definition file: ' . $file
123 if ( !isset( $moduleDef[
'mwapi'] ) ) {
125 'Missing mwapi version field in ' . $file
130 if ( version_compare( $moduleDef[
'mwapi'],
'1.0.0',
'<' ) ||
131 version_compare( $moduleDef[
'mwapi'],
'1.1.999',
'>' )
134 "Unsupported mwapi version {$moduleDef['mwapi']} in "
139 $localizer =
new JsonLocalizer( $responseFactory );
140 return $localizer->localizeJson( $moduleDef );
146 private function getRouteFileTimestamp(): int {
147 if ( $this->routeFileTimestamp === null ) {
148 $this->routeFileTimestamp = filemtime( $this->definitionFile );
150 return $this->routeFileTimestamp;
160 $moduleDef = $this->getModuleDefinition();
162 foreach ( $moduleDef[
'paths'] as
$path => $pSpec ) {
164 foreach ( $pSpec as $method => $opSpec ) {
165 $paths[
$path][] = strtoupper( $method );
173 $moduleDef = $this->getModuleDefinition();
176 foreach ( $moduleDef[
'paths'] as
$path => $pathSpec ) {
177 foreach ( $pathSpec as $method => $opSpec ) {
178 $info = $this->makeRouteInfo(
$path, $opSpec );
179 $this->addRoute( $method,
$path, $info );
189 private function makeRouteInfo(
string $path, array $opSpec ): array {
190 static $objectSpecKeys = [
205 'deprecationSettings'
208 if ( isset( $opSpec[
'redirect'] ) ) {
210 $opSpec[
'handler'] = [
211 'class' => RedirectHandler::class,
212 'redirect' => $opSpec[
'redirect'],
214 unset( $opSpec[
'redirect'] );
217 $handlerSpec = $opSpec[
'handler'] ??
null;
218 if ( !$handlerSpec ) {
219 throw new RouteDefinitionException(
'Missing handler spec' );
223 'spec' => array_intersect_key( $handlerSpec, array_flip( $objectSpecKeys ) ),
224 'config' => array_diff_key( $handlerSpec, array_flip( $objectSpecKeys ) ),
225 'openApiSpec' => array_intersect_key( $opSpec, array_flip( $oasKeys ) ),
234 $def = $this->getModuleDefinition();
235 return $def[
'info'] ?? [];
if(!defined('MW_SETUP_CALLBACK'))