Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
JsonSchemaIterator
0.00% covered (danger)
0.00%
0 / 35
0.00% covered (danger)
0.00%
0 / 8
240
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 initialize
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
6
 current
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 next
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 key
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 valid
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 rewind
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 buildDataFromSchema
0.00% covered (danger)
0.00%
0 / 19
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2
3namespace MediaWiki\Extension\CommunityConfiguration\Schema;
4
5use stdClass;
6
7class 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}