Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
83.72% |
36 / 43 |
|
44.44% |
4 / 9 |
CRAP | |
0.00% |
0 / 1 |
JsonSchemaBuilder | |
83.72% |
36 / 43 |
|
44.44% |
4 / 9 |
15.97 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getJsonSchemaReader | |
40.00% |
2 / 5 |
|
0.00% |
0 / 1 |
2.86 | |||
getSchemaName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getVersionManager | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getSchemaReader | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRootSchema | |
100.00% |
13 / 13 |
|
100.00% |
1 / 1 |
1 | |||
getRootProperties | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDefaultFromSchema | |
88.89% |
8 / 9 |
|
0.00% |
0 / 1 |
5.03 | |||
getDefaultsMap | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\CommunityConfiguration\Schema; |
4 | |
5 | use IBufferingStatsdDataFactory; |
6 | use stdClass; |
7 | |
8 | class JsonSchemaBuilder implements SchemaBuilder { |
9 | |
10 | private IBufferingStatsdDataFactory $statsdDataFactory; |
11 | private JsonSchemaReader $jsonSchema; |
12 | private JsonSchemaVersionManager $versionManager; |
13 | |
14 | public function __construct( |
15 | IBufferingStatsdDataFactory $statsdDataFactory, |
16 | JsonSchemaReader $jsonSchema |
17 | ) { |
18 | $this->statsdDataFactory = $statsdDataFactory; |
19 | $this->jsonSchema = $jsonSchema; |
20 | $this->versionManager = new JsonSchemaVersionManager( $this->jsonSchema ); |
21 | } |
22 | |
23 | /** |
24 | * Get schema reader for given version |
25 | * |
26 | * @param string|null $version |
27 | * @return JsonSchemaReader |
28 | */ |
29 | private function getJsonSchemaReader( ?string $version = null ): JsonSchemaReader { |
30 | if ( $version === null ) { |
31 | return $this->jsonSchema; |
32 | } |
33 | |
34 | return $this->versionManager->getVersionForSchema( |
35 | $version |
36 | ); |
37 | } |
38 | |
39 | /** |
40 | * @inheritDoc |
41 | */ |
42 | public function getSchemaName(): string { |
43 | return $this->getJsonSchemaReader()->getSchemaId(); |
44 | } |
45 | |
46 | /** |
47 | * @inheritDoc |
48 | */ |
49 | public function getVersionManager(): SchemaVersionManager { |
50 | return $this->versionManager; |
51 | } |
52 | |
53 | /** |
54 | * @inheritDoc |
55 | */ |
56 | public function getSchemaReader(): SchemaReader { |
57 | return $this->jsonSchema; |
58 | } |
59 | |
60 | /** |
61 | * @inheritDoc |
62 | */ |
63 | public function getRootSchema( ?string $version = null ): array { |
64 | $start = microtime( true ); |
65 | $reader = $this->getJsonSchemaReader( $version ); |
66 | $reader->assertIsSchema(); |
67 | |
68 | $result = array_merge( [ |
69 | '$schema' => $this->jsonSchema->getJsonSchemaVersion(), |
70 | '$id' => $this->jsonSchema->getSchemaId(), |
71 | JsonSchema::ADDITIONAL_PROPERTIES => false, |
72 | ], $reader->getReflectionSchemaSource()->loadAsSchema( true ) ); |
73 | $this->statsdDataFactory->timing( |
74 | 'timing.communityConfiguration.JsonSchemaBuilder.getRootSchema', |
75 | microtime( true ) - $start |
76 | ); |
77 | return $result; |
78 | } |
79 | |
80 | /** |
81 | * @inheritDoc |
82 | */ |
83 | public function getRootProperties( ?string $version = null ): array { |
84 | return $this->getRootSchema( $version )[JsonSchema::PROPERTIES]; |
85 | } |
86 | |
87 | /** |
88 | * Get a default from a JSON schema specification |
89 | * |
90 | * Takes into account dynamic defaults. |
91 | * |
92 | * @param array $schema |
93 | * @return mixed |
94 | */ |
95 | private function getDefaultFromSchema( array $schema ) { |
96 | if ( isset( $schema[JsonSchema::DYNAMIC_DEFAULT] ) ) { |
97 | $result = call_user_func( $schema[JsonSchema::DYNAMIC_DEFAULT]['callback'] ); |
98 | } else { |
99 | $result = $schema['default'] ?? null; |
100 | } |
101 | |
102 | if ( $schema[JsonSchema::TYPE] === JsonSchema::TYPE_OBJECT ) { |
103 | // Convert the value to an object when TYPE_OBJECT is expected |
104 | $result = (object)$result; |
105 | } |
106 | |
107 | // process defaults for objects recursively |
108 | if ( is_object( $result ) ) { |
109 | foreach ( $schema['properties'] ?? [] as $name => $subSchema ) { |
110 | $result->{$name} = $this->getDefaultFromSchema( $subSchema ); |
111 | } |
112 | } |
113 | |
114 | return $result; |
115 | } |
116 | |
117 | /** |
118 | * @inheritDoc |
119 | */ |
120 | public function getDefaultsMap( ?string $version = null ): stdClass { |
121 | $start = microtime( true ); |
122 | $res = new stdClass(); |
123 | foreach ( $this->getRootProperties( $version ) as $key => $specification ) { |
124 | $res->{$key} = $this->getDefaultFromSchema( $specification ); |
125 | } |
126 | $this->statsdDataFactory->timing( |
127 | 'timing.communityConfiguration.JsonSchemaBuilder.getDefaultsMap', |
128 | microtime( true ) - $start |
129 | ); |
130 | return $res; |
131 | } |
132 | } |