Skip to content

Commit 4b81071

Browse files
committed
Handle JSON Schema title
and derive TypeSet from shorthand
1 parent 384c0c0 commit 4b81071

File tree

9 files changed

+183
-78
lines changed

9 files changed

+183
-78
lines changed

src/Shorthand/Shorthand.php

Lines changed: 59 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,23 @@
11
<?php
2-
declare(strict_types=1);
32

43
/**
54
* @see https://github.com/open-code-modeling/json-schema-to-php for the canonical source repository
65
* @copyright https://github.com/open-code-modeling/json-schema-to-php/blob/master/COPYRIGHT.md
76
* @license https://github.com/open-code-modeling/json-schema-to-php/blob/master/LICENSE.md MIT License
87
*/
98

9+
declare(strict_types=1);
10+
1011
namespace OpenCodeModeling\JsonSchemaToPhp\Shorthand;
1112

1213
use LogicException;
13-
use function array_push;
14-
use function array_slice;
15-
use function array_splice;
16-
use function count;
17-
use function explode;
18-
use function floatval;
19-
use function implode;
20-
use function intval;
21-
use function is_array;
22-
use function is_string;
23-
use function json_encode;
24-
use function mb_strlen;
25-
use function mb_substr;
26-
use function sprintf;
27-
use function str_replace;
28-
use function strlen;
2914

3015
final class Shorthand
3116
{
17+
/**
18+
* @param array<string, mixed> $shorthand
19+
* @return array<string, mixed>
20+
*/
3221
public static function convertToJsonSchema(array $shorthand): array
3322
{
3423
$schema = [
@@ -41,70 +30,70 @@ public static function convertToJsonSchema(array $shorthand): array
4130
];
4231

4332
foreach ($shorthand as $property => $shorthandDefinition) {
44-
if(!is_string($property) || empty($property)) {
45-
throw new LogicException(sprintf(
33+
if (! \is_string($property) || empty($property)) {
34+
throw new LogicException(\sprintf(
4635
'Shorthand %s contains an empty or non string property. Cannot deal with that!',
47-
json_encode($shorthand)
36+
\json_encode($shorthand)
4837
));
4938
}
5039

5140
$schemaProperty = $property;
5241

53-
if(mb_substr($property, -1) === '?') {
54-
$schemaProperty = mb_substr($property, 0, strlen($property) - 1);
55-
} else if ($schemaProperty === '$ref') {
56-
if(count($shorthand) > 1) {
57-
throw new LogicException(sprintf(
42+
if (\mb_substr($property, -1) === '?') {
43+
$schemaProperty = \mb_substr($property, 0, \strlen($property) - 1);
44+
} elseif ($schemaProperty === '$ref') {
45+
if (\count($shorthand) > 1) {
46+
throw new LogicException(\sprintf(
5847
'Shorthand %s contains a top level ref property "$ref", but it is not the only property!
5948
\nA top level reference cannot have other properties then "$ref".',
60-
json_encode($shorthand)
49+
\json_encode($shorthand)
6150
));
6251
}
6352

64-
if(!is_string($shorthandDefinition)) {
65-
throw new LogicException(sprintf(
53+
if (! \is_string($shorthandDefinition)) {
54+
throw new LogicException(\sprintf(
6655
'Detected a top level shorthand reference using a "$ref" property, but the value of the property is not a string.',
6756
));
6857
}
6958

70-
$shorthandDefinition = str_replace('#/definitions/', '', $shorthandDefinition);
59+
$shorthandDefinition = \str_replace('#/definitions/', '', $shorthandDefinition);
7160

7261
return [
73-
'$ref' => "#/definitions/$shorthandDefinition"
62+
'$ref' => "#/definitions/$shorthandDefinition",
7463
];
75-
} else if ($schemaProperty === '$items') {
76-
if(count($shorthand) > 1) {
77-
throw new LogicException(sprintf(
64+
} elseif ($schemaProperty === '$items') {
65+
if (\count($shorthand) > 1) {
66+
throw new LogicException(\sprintf(
7867
'Shorthand %s contains a top level array property "$items", but it is not the only property!
7968
\nA top level array cannot have other properties then "$items".',
80-
json_encode($shorthand)
69+
\json_encode($shorthand)
8170
));
8271
}
8372

84-
if(!is_string($shorthandDefinition)) {
85-
throw new LogicException(sprintf(
73+
if (! \is_string($shorthandDefinition)) {
74+
throw new LogicException(\sprintf(
8675
'Detected a top level shorthand array using an "$items" property, but the value of the property is not a string.',
8776
));
8877
}
8978

90-
if(mb_substr($shorthandDefinition, -2) !== '[]') {
79+
if (\mb_substr($shorthandDefinition, -2) !== '[]') {
9180
$shorthandDefinition .= '[]';
9281
}
9382

9483
return self::convertShorthandStringToJsonSchema($shorthandDefinition);
95-
} else if ($schemaProperty === '$title') {
84+
} elseif ($schemaProperty === '$title') {
9685
$schema['title'] = $shorthandDefinition;
9786
continue;
9887
} else {
9988
$schema['required'][] = $schemaProperty;
10089
}
10190

102-
if(is_array($shorthandDefinition)) {
91+
if (\is_array($shorthandDefinition)) {
10392
$schema['properties'][$schemaProperty] = self::convertToJsonSchema($shorthandDefinition);
104-
} else if (is_string($shorthandDefinition)) {
93+
} elseif (\is_string($shorthandDefinition)) {
10594
$schema['properties'][$schemaProperty] = self::convertShorthandStringToJsonSchema($shorthandDefinition);
10695
} else {
107-
throw new LogicException(sprintf(
96+
throw new LogicException(\sprintf(
10897
'I tried to parse JSONSchema for property: "%s", but it is neither a string nor an object.',
10998
$schemaProperty
11099
));
@@ -114,25 +103,29 @@ public static function convertToJsonSchema(array $shorthand): array
114103
return $schema;
115104
}
116105

106+
/**
107+
* @param string $shorthandStr
108+
* @return array<string, mixed>
109+
*/
117110
private static function convertShorthandStringToJsonSchema(string $shorthandStr): array
118111
{
119-
if($shorthandStr === '') {
112+
if ($shorthandStr === '') {
120113
return ['type' => 'string'];
121114
}
122115

123-
$parts = explode('|', $shorthandStr);
116+
$parts = \explode('|', $shorthandStr);
124117

125-
if($parts[0] === 'enum') {
126-
return ['enum' => array_slice($parts, 1)];
118+
if ($parts[0] === 'enum') {
119+
return ['enum' => \array_slice($parts, 1)];
127120
}
128121

129-
if(mb_substr($parts[0], -2) === '[]') {
130-
$itemsParts = [mb_substr($parts[0], 0, mb_strlen($parts[0]) - 2)];
131-
array_push($itemsParts, ...array_slice($parts, 1));
122+
if (\mb_substr($parts[0], -2) === '[]') {
123+
$itemsParts = [\mb_substr($parts[0], 0, \mb_strlen($parts[0]) - 2)];
124+
\array_push($itemsParts, ...\array_slice($parts, 1));
132125

133126
return [
134127
'type' => 'array',
135-
'items' => self::convertShorthandStringToJsonSchema(implode('|', $itemsParts)),
128+
'items' => self::convertShorthandStringToJsonSchema(\implode('|', $itemsParts)),
136129
];
137130
}
138131

@@ -143,16 +136,16 @@ private static function convertShorthandStringToJsonSchema(string $shorthandStr)
143136
case 'boolean':
144137
$type = $parts[0];
145138

146-
if(isset($parts[1]) && $parts[1] === 'null') {
139+
if (isset($parts[1]) && $parts[1] === 'null') {
147140
$type = [$type, 'null'];
148141

149-
array_splice($parts, 1, 1);
142+
\array_splice($parts, 1, 1);
150143
}
151144

152145
$schema = ['type' => $type];
153146

154-
if(count($parts) > 1) {
155-
$parts = array_slice($parts, 1);
147+
if (\count($parts) > 1) {
148+
$parts = \array_slice($parts, 1);
156149

157150
foreach ($parts as $part) {
158151
[$validationKey, $validationValue] = self::parseShorthandValidation($part);
@@ -169,33 +162,37 @@ private static function convertShorthandStringToJsonSchema(string $shorthandStr)
169162
}
170163
}
171164

165+
/**
166+
* @param string $shorthandValidation
167+
* @return array<mixed>
168+
*/
172169
private static function parseShorthandValidation(string $shorthandValidation): array
173170
{
174-
$parts = explode(':', $shorthandValidation);
171+
$parts = \explode(':', $shorthandValidation);
175172

176-
if(count($parts) !== 2) {
177-
throw new LogicException(sprintf(
173+
if (\count($parts) !== 2) {
174+
throw new LogicException(\sprintf(
178175
'Cannot parse shorthand validation: "%s". Expected format "validationKey:value". Please check again!',
179176
$shorthandValidation
180177
));
181178
}
182179

183180
[$validationKey, $value] = $parts;
184181

185-
if($value === 'true') {
182+
if ($value === 'true') {
186183
return [$validationKey, true];
187184
}
188185

189-
if($value === 'false') {
186+
if ($value === 'false') {
190187
return [$validationKey, false];
191188
}
192189

193-
if((string)intval($value) === $value) {
194-
return [$validationKey, (int)$value];
190+
if ((string) (int) $value === $value) {
191+
return [$validationKey, (int) $value];
195192
}
196193

197-
if((string)floatval($value) === $value) {
198-
return [$validationKey, (float)$value];
194+
if ((string) (float) $value === $value) {
195+
return [$validationKey, (float) $value];
199196
}
200197

201198
return [$validationKey, $value];

src/Type/ArrayType.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010

1111
namespace OpenCodeModeling\JsonSchemaToPhp\Type;
1212

13-
final class ArrayType implements TypeDefinition
13+
final class ArrayType implements TypeDefinition, TitleAware
1414
{
1515
use PopulateRequired;
1616

@@ -36,6 +36,7 @@ final class ArrayType implements TypeDefinition
3636
protected ?string $name = null;
3737
protected bool $isRequired = false;
3838
protected bool $nullable = false;
39+
protected ?string $title = null;
3940

4041
private function __construct()
4142
{
@@ -231,6 +232,16 @@ public function additionalItems(): ?TypeSet
231232
return $this->additionalItems;
232233
}
233234

235+
public function title(): ?string
236+
{
237+
return $this->title;
238+
}
239+
240+
public function setTitle(string $title): void
241+
{
242+
$this->title = $title;
243+
}
244+
234245
public static function type(): string
235246
{
236247
return self::TYPE_ARRAY;

src/Type/ObjectType.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010

1111
namespace OpenCodeModeling\JsonSchemaToPhp\Type;
1212

13-
final class ObjectType implements TypeDefinition, NullableAware, RequiredAware
13+
final class ObjectType implements TypeDefinition, NullableAware, RequiredAware, TitleAware
1414
{
1515
use PopulateRequired;
1616

1717
protected ?string $name = null;
1818
protected bool $isRequired = false;
1919
protected bool $nullable = false;
20+
protected ?string $title = null;
2021

2122
/**
2223
* @var null|bool|TypeSet
@@ -182,6 +183,16 @@ public function required(): array
182183
return $this->required;
183184
}
184185

186+
public function title(): ?string
187+
{
188+
return $this->title;
189+
}
190+
191+
public function setTitle(string $title): void
192+
{
193+
$this->title = $title;
194+
}
195+
185196
/**
186197
* @return array<string, TypeSet>
187198
*/

src/Type/ReferenceType.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010

1111
namespace OpenCodeModeling\JsonSchemaToPhp\Type;
1212

13-
final class ReferenceType implements TypeDefinition, RequiredAware, NullableAware
13+
final class ReferenceType implements TypeDefinition, RequiredAware, NullableAware, TitleAware
1414
{
1515
protected ?TypeSet $resolvedType = null;
1616
protected ?string $name = null;
1717
protected ?string $ref = null;
1818
protected bool $isRequired = false;
1919
protected bool $nullable = false;
20+
protected ?string $title = null;
2021

2122
private function __construct()
2223
{
@@ -109,4 +110,14 @@ public function setNullable(bool $nullable): void
109110
}
110111
$this->nullable = $nullable;
111112
}
113+
114+
public function title(): ?string
115+
{
116+
return $this->title;
117+
}
118+
119+
public function setTitle(string $title): void
120+
{
121+
$this->title = $title;
122+
}
112123
}

src/Type/ScalarType.php

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010

1111
namespace OpenCodeModeling\JsonSchemaToPhp\Type;
1212

13-
abstract class ScalarType implements TypeDefinition, RequiredAware, NullableAware
13+
abstract class ScalarType implements TypeDefinition, RequiredAware, NullableAware, TitleAware
1414
{
1515
protected ?string $format = null;
1616
protected ?string $name = null;
1717
protected bool $isRequired = false;
1818
protected bool $nullable = false;
19+
protected ?string $title = null;
1920

2021
/**
2122
* @var mixed
@@ -146,4 +147,14 @@ public function setIsRequired(bool $required): void
146147
{
147148
$this->isRequired = $required;
148149
}
150+
151+
public function title(): ?string
152+
{
153+
return $this->title;
154+
}
155+
156+
public function setTitle(string $title): void
157+
{
158+
$this->title = $title;
159+
}
149160
}

src/Type/TitleAware.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php
2+
3+
/**
4+
* @see https://github.com/open-code-modeling/json-schema-to-php for the canonical source repository
5+
* @copyright https://github.com/open-code-modeling/json-schema-to-php/blob/master/COPYRIGHT.md
6+
* @license https://github.com/open-code-modeling/json-schema-to-php/blob/master/LICENSE.md MIT License
7+
*/
8+
9+
declare(strict_types=1);
10+
11+
namespace OpenCodeModeling\JsonSchemaToPhp\Type;
12+
13+
interface TitleAware
14+
{
15+
public function setTitle(string $title): void;
16+
}

0 commit comments

Comments
 (0)