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

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

08 Apr 2026 12:29PM UTC coverage: 98.249% (-0.4%) from 98.654%
24135379642

Pull #125

github

wol-soft
CI
Pull Request #125: attributes

1507 of 1537 new or added lines in 73 files covered. (98.05%)

4 existing lines in 3 files now uncovered.

4376 of 4454 relevant lines covered (98.25%)

621.28 hits per line

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

97.87
/src/Model/SchemaDefinition/JsonSchema.php
1
<?php
2

3
declare(strict_types=1);
4

5
namespace PHPModelGenerator\Model\SchemaDefinition;
6

7
use PHPModelGenerator\Exception\GeneratorException;
8
use PHPModelGenerator\Exception\SchemaException;
9
use PHPModelGenerator\Utils\ArrayHash;
10

11
/**
12
 * Class JsonSchema
13
 *
14
 * @package PHPModelGenerator\Model\SchemaDefinition
15
 */
16
class JsonSchema
17
{
18
    private const array SCHEMA_SIGNATURE_RELEVANT_FIELDS = [
19
        'type',
20
        'properties',
21
        '$ref',
22
        'allOf',
23
        'anyOf',
24
        'oneOf',
25
        'not',
26
        'if',
27
        'then',
28
        'else',
29
        'additionalProperties',
30
        'required',
31
        'propertyNames',
32
        'minProperties',
33
        'maxProperties',
34
        'dependencies',
35
        'patternProperties',
36
    ];
37

38
    protected array $json;
39

40
    /**
41
     * JsonSchema constructor.
42
     *
43
     * @param string $file the source file for the schema
44
     * @param array $json Decoded json schema
45
     * @param string $pointer The JSON pointer inside the $file leading to the schema provided in $json
46
     */
47
    public function __construct(private string $file, array $json, private string $pointer = '')
2,209✔
48
    {
49
        // wrap in an allOf to pass the processing to multiple handlers - ugly hack to be removed after rework
50
        if (
51
            isset($json['$ref']) &&
2,209✔
52
            count(array_diff(
2,209✔
53
                array_intersect(array_keys($json), self::SCHEMA_SIGNATURE_RELEVANT_FIELDS),
2,209✔
54
                ['$ref', 'type'],
2,209✔
55
            ))
2,209✔
56
        ) {
57
            $json = array_merge(
6✔
58
                array_diff_key($json, array_fill_keys(self::SCHEMA_SIGNATURE_RELEVANT_FIELDS, null)),
6✔
59
                [
6✔
60
                    'allOf' => [
6✔
61
                        ['$ref' => $json['$ref']],
6✔
62
                        array_intersect_key(
6✔
63
                            $json,
6✔
64
                            array_fill_keys(array_diff(self::SCHEMA_SIGNATURE_RELEVANT_FIELDS, ['$ref']), null),
6✔
65
                        ),
6✔
66
                    ],
6✔
67
                ],
6✔
68
            );
6✔
69
        }
70

71
        $this->json = $json;
2,209✔
72
    }
73

74
    public function getJson(): array
2,205✔
75
    {
76
        return $this->json;
2,205✔
77
    }
78

79
    /**
80
     * create the signature from all fields which are directly relevant for the created object. Additional fields
81
     * can be ignored as the resulting code will be identical
82
     */
83
    public function getSignature(): string
2,186✔
84
    {
85
        return ArrayHash::hash($this->json, self::SCHEMA_SIGNATURE_RELEVANT_FIELDS);
2,186✔
86
    }
87

88
    public function withJson(array $json): JsonSchema
2,186✔
89
    {
90
        $jsonSchema = clone $this;
2,186✔
91
        $jsonSchema->json = $json;
2,186✔
92

93
        return $jsonSchema;
2,186✔
94
    }
95

96
    /**
97
     * Creates a clone of the JsonSchema object with a subschema,
98
     * navigated to the provided $pointer from the current schema.
99
     */
100
    public function navigate(string | int $pointer): JsonSchema
2,171✔
101
    {
102
        $trimmed = trim((string) $pointer, '/');
2,171✔
103

104
        if ($trimmed === '') {
2,171✔
105
            return $this;
209✔
106
        }
107

108
        $jsonSchema = clone $this;
2,171✔
109

110
        foreach (explode('/', $trimmed) as $pathSegment) {
2,171✔
111
            $jsonSchema->pointer .= "/$pathSegment";
2,171✔
112
            $decodedPathSegment = self::decodePointer($pathSegment);
2,171✔
113

114
            if (!array_key_exists($decodedPathSegment, $jsonSchema->json)) {
2,171✔
NEW
115
                throw new SchemaException("Unresolved path segment $pathSegment in file $this->file");
×
116
            }
117

118
            $jsonSchema->json = $jsonSchema->json[$decodedPathSegment];
2,171✔
119
        }
120

121
        return $jsonSchema;
2,171✔
122
    }
123

124
    public function getFile(): string
2,205✔
125
    {
126
        return $this->file;
2,205✔
127
    }
128

129
    public function getPointer(): string
2,205✔
130
    {
131
        return $this->pointer;
2,205✔
132
    }
133

134
    public static function encodePointer(string | int $pointer): string
2,171✔
135
    {
136
        return str_replace(['~', '/'], ['~0', '~1'], (string) $pointer);
2,171✔
137
    }
138

139
    public static function decodePointer(string | int $pointer): string
2,171✔
140
    {
141
        return str_replace(['~1', '~0'], ['/', '~'], (string) $pointer);
2,171✔
142
    }
143
}
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