Skip to content

Commit c3a51b0

Browse files
committed
adding example
1 parent 16da6b3 commit c3a51b0

40 files changed

+8365
-11
lines changed

README.md

+125-1
Original file line numberDiff line numberDiff line change
@@ -1 +1,125 @@
1-
# Swaggest JSON-schema enabled PHP code builder
1+
# Swaggest JSON-schema enabled PHP code builder
2+
3+
This library generates PHP mapping structures defined by [JSON schema](http://json-schema.org/)
4+
using [`swaggest/json-schema`](https://github.com/swaggest/php-json-schema).
5+
6+
## Example
7+
8+
[Generated code](tests/src/Tmp)
9+
10+
```php
11+
<?php
12+
13+
require_once __DIR__ . '/vendor/autoload.php';
14+
15+
$schemaData = json_decode(<<<'JSON'
16+
{
17+
"type": "object",
18+
"properties": {
19+
"id": {"type": "integer"},
20+
"name": {"type": "string"},
21+
"parent": {"$ref": "#"},
22+
"children": {"type": "array", "items": {"$ref": "#"}},
23+
"info": {"$ref": "#/definitions/info"}
24+
},
25+
"definitions": {
26+
"info": {
27+
"type": "object",
28+
"properties": {
29+
"lastName": {"type": "string"},
30+
"birthDate": {"type": "string", "format": "date-time"},
31+
"options": {"$ref": "#/definitions/options"}
32+
}
33+
},
34+
"options": {
35+
"type": "object",
36+
"properties": {
37+
"rememberSession": {"type": "boolean"},
38+
"allowNotifications": {"type": "boolean"}
39+
}
40+
}
41+
}
42+
}
43+
JSON
44+
);
45+
46+
$swaggerSchema = \Swaggest\JsonSchema\Schema::import($schemaData);
47+
48+
$appPath = realpath(__DIR__ . '/tests/src/Tmp') . '/Example';
49+
$appNs = 'Swaggest\PhpCodeBuilder\Tests\Tmp\Example';
50+
51+
$app = new \Swaggest\PhpCodeBuilder\App\PhpApp();
52+
$app->setNamespaceRoot($appNs, '.');
53+
54+
$builder = new \Swaggest\PhpCodeBuilder\JsonSchema\PhpBuilder();
55+
$builder->buildSetters = true;
56+
$builder->makeEnumConstants = true;
57+
58+
$builder->classCreatedHook = new \Swaggest\PhpCodeBuilder\JsonSchema\ClassHookCallback(
59+
function (\Swaggest\PhpCodeBuilder\PhpClass $class, $path, $schema) use ($app, $appNs) {
60+
$desc = '';
61+
if ($schema->title) {
62+
$desc = $schema->title;
63+
}
64+
if ($schema->description) {
65+
$desc .= "\n" . $schema->description;
66+
}
67+
if ($fromRefs = $schema->getFromRefs()) {
68+
$desc .= "\nBuilt from " . implode("\n" . ' <- ', $fromRefs);
69+
}
70+
71+
$class->setDescription(trim($desc));
72+
73+
$class->setNamespace($appNs);
74+
if ('#' === $path) {
75+
$class->setName('User'); // Class name for root schema
76+
} elseif ('#/definitions/' === substr($path, 0, strlen('#/definitions/'))) {
77+
$class->setName(\Swaggest\PhpCodeBuilder\PhpCode::makePhpClassName(
78+
substr($path, strlen('#/definitions/'))));
79+
}
80+
$app->addClass($class);
81+
}
82+
);
83+
84+
$builder->getType($swaggerSchema);
85+
$app->clearOldFiles($appPath);
86+
$app->store($appPath);
87+
```
88+
89+
Creating and exporting an instance
90+
91+
```php
92+
$user = new \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User();
93+
$user->name = "John";
94+
$user->info = (new \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\Info())
95+
->setLastName("Doe")
96+
->setBirthDate("1980-01-01")
97+
->setOptions(
98+
(new \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\Options())
99+
->setRememberSession(true)
100+
->setAllowNotifications(false)
101+
);
102+
103+
// No exception on exporting valid data
104+
$jsonData = \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User::export($user);
105+
106+
// {"name":"John","info":{"lastName":"Doe","birthDate":"1980-01-01","options":{"rememberSession":true,"allowNotifications":false}}}
107+
echo json_encode($jsonData);
108+
109+
// Setting invalid value (integer instead of string)
110+
$user->name = 123;
111+
112+
// Exception: String expected, 123 received at #->$ref[#]->properties:name
113+
$jsonData = \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User::export($user);
114+
```
115+
116+
Creating class instance from raw data
117+
118+
```php
119+
// Importing raw data to entity class instance will do validation and mapping
120+
$user = \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User::import(
121+
json_decode('{"name":"John","info":{"lastName":"Doe","birthDate":"1980-01-01","options":{"rememberSession":true,"allowNotifications":false}}}')
122+
);
123+
124+
var_dump($user->info->options->allowNotifications); // bool(false)
125+
```

example.php

+108
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,108 @@
1+
<?php
2+
3+
require_once __DIR__ . '/vendor/autoload.php';
4+
5+
$schemaData = json_decode(<<<'JSON'
6+
{
7+
"type": "object",
8+
"properties": {
9+
"id": {"type": "integer"},
10+
"name": {"type": "string"},
11+
"parent": {"$ref": "#"},
12+
"children": {"type": "array", "items": {"$ref": "#"}},
13+
"info": {"$ref": "#/definitions/info"}
14+
},
15+
"definitions": {
16+
"info": {
17+
"type": "object",
18+
"properties": {
19+
"lastName": {"type": "string"},
20+
"birthDate": {"type": "string", "format": "date"},
21+
"options": {"$ref": "#/definitions/options"}
22+
}
23+
},
24+
"options": {
25+
"type": "object",
26+
"properties": {
27+
"rememberSession": {"type": "boolean"},
28+
"allowNotifications": {"type": "boolean"}
29+
}
30+
}
31+
}
32+
}
33+
JSON
34+
);
35+
36+
$swaggerSchema = \Swaggest\JsonSchema\Schema::import($schemaData);
37+
38+
$appPath = realpath(__DIR__ . '/tests/src/Tmp') . '/Example';
39+
$appNs = 'Swaggest\PhpCodeBuilder\Tests\Tmp\Example';
40+
41+
$app = new \Swaggest\PhpCodeBuilder\App\PhpApp();
42+
$app->setNamespaceRoot($appNs, '.');
43+
44+
$builder = new \Swaggest\PhpCodeBuilder\JsonSchema\PhpBuilder();
45+
$builder->buildSetters = true;
46+
$builder->makeEnumConstants = true;
47+
48+
$builder->classCreatedHook = new \Swaggest\PhpCodeBuilder\JsonSchema\ClassHookCallback(
49+
function (\Swaggest\PhpCodeBuilder\PhpClass $class, $path, $schema) use ($app, $appNs) {
50+
$desc = '';
51+
if ($schema->title) {
52+
$desc = $schema->title;
53+
}
54+
if ($schema->description) {
55+
$desc .= "\n" . $schema->description;
56+
}
57+
if ($fromRefs = $schema->getFromRefs()) {
58+
$desc .= "\nBuilt from " . implode("\n" . ' <- ', $fromRefs);
59+
}
60+
61+
$class->setDescription(trim($desc));
62+
63+
$class->setNamespace($appNs);
64+
if ('#' === $path) {
65+
$class->setName('User'); // Class name for root schema
66+
} elseif ('#/definitions/' === substr($path, 0, strlen('#/definitions/'))) {
67+
$class->setName(\Swaggest\PhpCodeBuilder\PhpCode::makePhpClassName(
68+
substr($path, strlen('#/definitions/'))));
69+
}
70+
$app->addClass($class);
71+
}
72+
);
73+
74+
$builder->getType($swaggerSchema);
75+
$app->clearOldFiles($appPath);
76+
$app->store($appPath);
77+
78+
79+
// Importing raw data to entity class instance will do validation and mapping
80+
$user = \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User::import(
81+
json_decode('{"name":"John","info":{"lastName":"Doe","birthDate":"1980-01-01","options":{"rememberSession":true,"allowNotifications":false}}}')
82+
);
83+
84+
var_dump($user->info->options->allowNotifications); // bool(false)
85+
86+
$user = new \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User();
87+
$user->name = "John";
88+
$user->info = (new \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\Info())
89+
->setLastName("Doe")
90+
->setBirthDate("1980-01-01")
91+
->setOptions(
92+
(new \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\Options())
93+
->setRememberSession(true)
94+
->setAllowNotifications(false)
95+
);
96+
97+
// No exception on exporting valid data
98+
$jsonData = \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User::export($user);
99+
100+
// {"name":"John","info":{"lastName":"Doe","birthDate":"1980-01-01","options":{"rememberSession":true,"allowNotifications":false}}}
101+
echo json_encode($jsonData), "\n";
102+
103+
// Setting invalid value (integer instead of string)
104+
$user->name = 123;
105+
106+
// Exception: String expected, 123 received at #->$ref[#]->properties:name
107+
$jsonData = \Swaggest\PhpCodeBuilder\Tests\Tmp\Example\User::export($user);
108+

src/JsonSchema/PhpBuilder.php

+6
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,12 @@ public function __construct()
4545
public $makeEnumConstants = false;
4646
public $skipSchemaDescriptions = false;
4747

48+
/**
49+
* Squish multiple $ref, a PHP class for each $ref will be created if false
50+
* @var bool
51+
*/
52+
public $minimizeRefs = true;
53+
4854
/** @var PhpBuilderClassHook */
4955
public $classCreatedHook;
5056

src/JsonSchema/SchemaBuilder.php

+9
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,7 @@ private function processRef()
144144
{
145145
if (!$this->skipProperties
146146
//&& $this->schema->type === Type::OBJECT
147+
&& !$this->phpBuilder->minimizeRefs
147148
&& $this->schema->getFromRefs()
148149
) {
149150
$class = $this->phpBuilder->getClass($this->schema, $this->path);
@@ -427,6 +428,14 @@ public function build()
427428

428429
private function processFromRef()
429430
{
431+
if ($this->phpBuilder->minimizeRefs) {
432+
if ($fromRefs = $this->schema->getFromRefs()) {
433+
$fromRef = $fromRefs[count($fromRefs) - 1];
434+
$value = var_export($fromRef, 1);
435+
$this->result->addSnippet("{$this->varName}->setFromRef($value);\n");
436+
}
437+
return;
438+
}
430439
if ($fromRefs = $this->schema->getFromRefs()) {
431440
foreach ($fromRefs as $fromRef) {
432441
$value = var_export($fromRef, 1);

src/JsonSchema/TypeBuilder.php

+1-1
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ public function build()
156156
}
157157

158158
if ($fromRefs = $this->schema->getFromRefs()) {
159-
$this->path = $fromRefs[0];
159+
$this->path = $fromRefs[count($fromRefs) - 1];
160160
//$this->result->add($this->phpBuilder->getType($this->schema->ref->getData(), $this->schema->ref->ref));
161161
}
162162

0 commit comments

Comments
 (0)