• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

wol-soft / php-json-schema-model-generator / 14407937636

11 Apr 2025 04:41PM UTC coverage: 98.813%. Remained the same
14407937636

Pull #88

github

web-flow
Merge 7dcf4b3f6 into 8823c7c14
Pull Request #88: Fix code typo in README

2914 of 2949 relevant lines covered (98.81%)

517.53 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

90.0
/src/Model/SchemaDefinition/SchemaDefinitionDictionary.php
1
<?php
2

3
declare(strict_types = 1);
4

5
namespace PHPModelGenerator\Model\SchemaDefinition;
6

7
use ArrayObject;
8
use PHPModelGenerator\Exception\SchemaException;
9
use PHPModelGenerator\Model\Schema;
10
use PHPModelGenerator\SchemaProcessor\SchemaProcessor;
11

12
/**
13
 * Class SchemaDefinitionDictionary
14
 *
15
 * @package PHPModelGenerator\Model\SchemaDefinition
16
 */
17
class SchemaDefinitionDictionary extends ArrayObject
18
{
19
    /** @var Schema[] */
20
    private array $parsedExternalFileSchemas = [];
21

22
    /**
23
     * SchemaDefinitionDictionary constructor.
24
     */
25
    public function __construct(private string $sourceDirectory)
26
    {
27
        parent::__construct();
1,974✔
28
    }
29

30
    /**
31
     * Set up the definition directory for the schema
32
     */
33
    public function setUpDefinitionDictionary(SchemaProcessor $schemaProcessor, Schema $schema): void {
34
        // attach the root node to the definition dictionary
35
        $this->addDefinition('#', new SchemaDefinition($schema->getJsonSchema(), $schemaProcessor, $schema));
1,966✔
36

37
        foreach ($schema->getJsonSchema()->getJson() as $key => $propertyEntry) {
1,966✔
38
            if (!is_array($propertyEntry)) {
1,966✔
39
                continue;
1,966✔
40
            }
41

42
            // add the root nodes of the schema to resolve path references
43
            $this->addDefinition(
1,951✔
44
                $key,
1,951✔
45
                new SchemaDefinition($schema->getJsonSchema()->withJson($propertyEntry), $schemaProcessor, $schema),
1,951✔
46
            );
1,951✔
47
        }
48

49
        $this->fetchDefinitionsById($schema->getJsonSchema(), $schemaProcessor, $schema);
1,966✔
50
    }
51

52
    /**
53
     * Fetch all schema definitions with an ID for direct references
54
     */
55
    protected function fetchDefinitionsById(
56
        JsonSchema $jsonSchema,
57
        SchemaProcessor $schemaProcessor,
58
        Schema $schema,
59
    ): void {
60
        $json = $jsonSchema->getJson();
1,966✔
61

62
        if (isset($json['$id'])) {
1,966✔
63
            $this->addDefinition(
1,960✔
64
                str_starts_with($json['$id'], '#') ? $json['$id'] : "#{$json['$id']}",
1,960✔
65
                new SchemaDefinition($jsonSchema, $schemaProcessor, $schema),
1,960✔
66
            );
1,960✔
67
        }
68

69
        foreach ($json as $item) {
1,966✔
70
            if (!is_array($item)) {
1,966✔
71
                continue;
1,966✔
72
            }
73

74
            $this->fetchDefinitionsById($jsonSchema->withJson($item), $schemaProcessor, $schema);
1,951✔
75
        }
76
    }
77

78
    /**
79
     * Add a partial schema definition to the schema
80
     *
81
     * @return $this
82
     */
83
    public function addDefinition(string $key, SchemaDefinition $definition): self
84
    {
85
        if (isset($this[$key])) {
1,966✔
86
            return $this;
805✔
87
        }
88

89
        $this[$key] = $definition;
1,966✔
90

91
        return $this;
1,966✔
92
    }
93

94
    /**
95
     * @throws SchemaException
96
     */
97
    public function getDefinition(string $key, SchemaProcessor $schemaProcessor, array &$path = []): ?SchemaDefinition
98
    {
99
        if (str_starts_with($key, '#') && strpos($key, '/')) {
524✔
100
            $path = explode('/', $key);
402✔
101
            array_shift($path);
402✔
102
            $key  = array_shift($path);
402✔
103
        }
104

105
        if (!isset($this[$key])) {
524✔
106
            if (strstr($key, '#', true)) {
187✔
107
                [$jsonSchemaFile, $externalKey] = explode('#', $key);
161✔
108
            } else {
109
                $jsonSchemaFile = $key;
27✔
110
                $externalKey = '';
27✔
111
            }
112

113
            if (array_key_exists($jsonSchemaFile, $this->parsedExternalFileSchemas)) {
187✔
114
                return $this->parsedExternalFileSchemas[$jsonSchemaFile]->getSchemaDictionary()->getDefinition(
×
115
                    "#$externalKey",
×
116
                    $schemaProcessor,
×
117
                    $path,
×
118
                );
×
119
            }
120

121
            return $jsonSchemaFile
187✔
122
                ? $this->parseExternalFile($jsonSchemaFile, "#$externalKey", $schemaProcessor, $path)
187✔
123
                : null;
182✔
124
        }
125

126
        return $this[$key] ?? null;
519✔
127
    }
128

129
    /**
130
     * @throws SchemaException
131
     */
132
    protected function parseExternalFile(
133
        string $jsonSchemaFile,
134
        string $externalKey,
135
        SchemaProcessor $schemaProcessor,
136
        array &$path,
137
    ): ?SchemaDefinition {
138
        $jsonSchemaFilePath = filter_var($jsonSchemaFile, FILTER_VALIDATE_URL)
187✔
139
            ? $jsonSchemaFile
1✔
140
            : $this->sourceDirectory . '/' . $jsonSchemaFile;
187✔
141

142
        if (!filter_var($jsonSchemaFilePath, FILTER_VALIDATE_URL) && !is_file($jsonSchemaFilePath)) {
187✔
143
            throw new SchemaException("Reference to non existing JSON-Schema file $jsonSchemaFilePath");
5✔
144
        }
145

146
        $jsonSchema = file_get_contents($jsonSchemaFilePath);
183✔
147

148
        if (!$jsonSchema || !($decodedJsonSchema = json_decode($jsonSchema, true))) {
183✔
149
            throw new SchemaException("Invalid JSON-Schema file $jsonSchemaFilePath");
×
150
        }
151

152
        // set up a dummy schema to fetch the definitions from the external file
153
        $schema = new Schema(
183✔
154
            $schemaProcessor->getCurrentClassPath(),
183✔
155
            'ExternalSchema',
183✔
156
            new JsonSchema($jsonSchemaFilePath, $decodedJsonSchema),
183✔
157
            new self(dirname($jsonSchemaFilePath)),
183✔
158
        );
183✔
159

160
        $schema->getSchemaDictionary()->setUpDefinitionDictionary($schemaProcessor, $schema);
183✔
161
        $this->parsedExternalFileSchemas[$jsonSchemaFile] = $schema;
183✔
162

163
        return $schema->getSchemaDictionary()->getDefinition($externalKey, $schemaProcessor, $path);
183✔
164
    }
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc