Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 35 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
JsonSchemaIterator | |
0.00% |
0 / 35 |
|
0.00% |
0 / 8 |
240 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
initialize | |
0.00% |
0 / 5 |
|
0.00% |
0 / 1 |
6 | |||
current | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
next | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
key | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
valid | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
rewind | |
0.00% |
0 / 2 |
|
0.00% |
0 / 1 |
2 | |||
buildDataFromSchema | |
0.00% |
0 / 19 |
|
0.00% |
0 / 1 |
56 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\CommunityConfiguration\Schema; |
4 | |
5 | use stdClass; |
6 | |
7 | class JsonSchemaIterator implements \Iterator { |
8 | |
9 | private JsonSchemaReader $schema; |
10 | private int $position = 0; |
11 | private array $data = []; |
12 | private bool $initialized = false; |
13 | |
14 | /** |
15 | * @param JsonSchemaReader $schema |
16 | */ |
17 | public function __construct( JsonSchemaReader $schema ) { |
18 | $this->schema = $schema; |
19 | } |
20 | |
21 | private function initialize() { |
22 | if ( !$this->initialized ) { |
23 | // Load schema as components to omit processing the top level object "properties" |
24 | $rootSchema = $this->schema->getReflectionSchemaSource()->loadAsSchema( true ); |
25 | $objectSchema = json_decode( json_encode( $rootSchema ) ); |
26 | $this->data = $this->buildDataFromSchema( $objectSchema ); |
27 | $this->initialized = true; |
28 | } |
29 | } |
30 | |
31 | #[\ReturnTypeWillChange] |
32 | public function current() { |
33 | $this->initialize(); |
34 | return $this->data[$this->position]; |
35 | } |
36 | |
37 | public function next(): void { |
38 | $this->initialize(); |
39 | $this->position++; |
40 | } |
41 | |
42 | public function key(): int { |
43 | $this->initialize(); |
44 | return $this->position; |
45 | } |
46 | |
47 | public function valid(): bool { |
48 | $this->initialize(); |
49 | return isset( $this->data[$this->position] ); |
50 | } |
51 | |
52 | public function rewind(): void { |
53 | $this->initialize(); |
54 | $this->position = 0; |
55 | } |
56 | |
57 | /** |
58 | * Return all sub-schemas in the given schemas as an array |
59 | * while calculating a json pointer for each of them. |
60 | * |
61 | * @param stdClass $rootSchema A stdClass representing a full JSON schema |
62 | * @return array<array> An array with the relevant "objects" (represented as associative arrays in PHP) in |
63 | * the schema. That should be a single object per schema. |
64 | */ |
65 | private function buildDataFromSchema( stdClass $rootSchema ): array { |
66 | $result = []; |
67 | |
68 | $stack = new \SplStack(); |
69 | $stack->push( [ |
70 | 'parentType' => 'root', |
71 | 'schema' => $rootSchema, |
72 | 'pointer' => '#', |
73 | ] ); |
74 | |
75 | while ( !$stack->isEmpty() ) { |
76 | $schemaNode = $stack->pop(); |
77 | // Only inspect subschemas which inform a type |
78 | if ( is_object( $schemaNode['schema'] ) && isset( $schemaNode['schema']->type ) ) { |
79 | array_push( $result, $schemaNode ); |
80 | } |
81 | |
82 | foreach ( $schemaNode['schema'] as $propertyName => $propertyValue ) { |
83 | if ( is_object( $propertyValue ) || is_array( $propertyValue ) ) { |
84 | $stack->push( [ |
85 | 'parentType' => $schemaNode['schema']->type ?? $schemaNode['parentType'], |
86 | 'schema' => $propertyValue, |
87 | 'pointer' => $schemaNode['pointer'] . '/' . $propertyName, |
88 | ] ); |
89 | } |
90 | } |
91 | } |
92 | |
93 | return $result; |
94 | } |
95 | } |