92
92
/**
93
93
* @property int $quantity PHPDoc defined dynamic properties will be validated on every set
94
94
*/
95
- class Example extends ClassStructure
95
+ class User extends ClassStructure
96
96
{
97
97
/* Native (public) properties will be validated only on import and export of structure data */
98
98
@@ -102,30 +102,53 @@ class Example extends ClassStructure
102
102
/** @var Order[] */
103
103
public $orders;
104
104
105
+ /** @var UserInfo */
106
+ public $info;
107
+
105
108
/**
106
- * Define your properties
107
- *
108
109
* @param Properties|static $properties
109
110
* @param Schema $ownerSchema
110
111
*/
111
112
public static function setUpProperties($properties, Schema $ownerSchema)
112
113
{
114
+ // Setup property schemas
113
115
$properties->id = Schema::integer();
114
116
$properties->name = Schema::string();
115
117
118
+ // You can embed structures to main level with nested schemas
119
+ $properties->info = UserInfo::schema()->nested();
120
+
121
+ // Dynamic (phpdoc-defined) properties can be used as well
116
122
$properties->quantity = Schema::integer();
117
123
$properties->quantity->minimum = 0;
118
124
125
+ // Property can be any complex structure
119
126
$properties->orders = Schema::create();
120
127
$properties->orders->items = Order::schema();
121
128
122
129
$ownerSchema->required = array(self::names()->id);
123
130
}
124
131
}
125
132
126
- /**
127
- *
128
- */
133
+
134
+ class UserInfo extends ClassStructure {
135
+ public $firstName;
136
+ public $lastName;
137
+ public $birthDay;
138
+
139
+ /**
140
+ * @param Properties|static $properties
141
+ * @param Schema $ownerSchema
142
+ */
143
+ public static function setUpProperties($properties, Schema $ownerSchema)
144
+ {
145
+ $properties->firstName = Schema::string();
146
+ $properties->lastName = Schema::string();
147
+ $properties->birthDay = Schema::string();
148
+ }
149
+ }
150
+
151
+
129
152
class Order extends ClassStructure
130
153
{
131
154
public $id;
@@ -139,7 +162,7 @@ class Order extends ClassStructure
139
162
public static function setUpProperties($properties, Schema $ownerSchema)
140
163
{
141
164
$properties->id = Schema::integer();
142
- $properties->dateTime = Schema::string();
165
+ $properties->dateTime = Schema::string()->meta(new FieldName('date_time')) ;
143
166
$properties->dateTime->format = Schema::FORMAT_DATE_TIME;
144
167
$properties->price = Schema::number();
145
168
@@ -152,26 +175,134 @@ Validation of dynamic properties is performed on set,
152
175
this can help to find source of invalid data at cost of
153
176
some performance drop
154
177
``` php
155
- $example = new Example ();
156
- $example ->quantity = -1; // Exception: Value more than 0 expected, -1 received
178
+ $user = new User ();
179
+ $user ->quantity = -1; // Exception: Value more than 0 expected, -1 received
157
180
```
158
181
159
182
Validation of native properties is performed only on import/export
160
183
``` php
161
- $example = new Example ();
162
- $example ->quantity = 10;
163
- Example ::export($example ); // Exception: Required property missing: id
184
+ $user = new User ();
185
+ $user ->quantity = 10;
186
+ User ::export($user ); // Exception: Required property missing: id
164
187
```
165
188
166
189
Error messages provide a path to invalid data
167
190
``` php
168
- $example = new Example ();
169
- $example ->id = 1;
170
- $example ->name = 'John Doe';
191
+ $user = new User ();
192
+ $user ->id = 1;
193
+ $user ->name = 'John Doe';
171
194
172
195
$order = new Order();
173
196
$order->dateTime = (new \DateTime())->format(DATE_RFC3339);
174
- $example ->orders[] = $order;
197
+ $user ->orders[] = $order;
175
198
176
- Example::export($example); // Exception: Required property missing: id at #->properties:orders->items[0]
199
+ User::export($user); // Exception: Required property missing: id at #->properties:orders->items[0]
200
+ ```
201
+
202
+ #### Nested structures
203
+
204
+ Nested structures allow you to make composition: flatten several objects in one and separate back.
205
+
206
+ ``` php
207
+ $user = new User();
208
+ $user->id = 1;
209
+
210
+ $info = new UserInfo();
211
+ $info->firstName = 'John';
212
+ $info->lastName = 'Doe';
213
+ $info->birthDay = '1970-01-01';
214
+ $user->info = $info;
215
+
216
+ $json = <<<JSON
217
+ {
218
+ " id" : 1,
219
+ " firstName" : " John" ,
220
+ " lastName" : " Doe" ,
221
+ " birthDay" : " 1970-01-01"
222
+ }
223
+ JSON;
224
+ $exported = User::export($user);
225
+ $this- >assertSame($json, json_encode($exported, JSON_PRETTY_PRINT));
226
+
227
+ $imported = User::import(json_decode($json));
228
+ $this->assertSame('John', $imported->info->firstName);
229
+ $this->assertSame('Doe', $imported->info->lastName);
230
+ ```
231
+
232
+ You can also use ` \Swaggest\JsonSchema\Structure\Composition ` to dynamically create schema compositions.
233
+ This can be helpful to deal with results of database query on joined data.
234
+
235
+ ``` php
236
+ $schema = new Composition(UserInfo::schema(), Order::schema());
237
+ $json = <<<JSON
238
+ {
239
+ " id" : 1,
240
+ " firstName" : " John" ,
241
+ " lastName" : " Doe" ,
242
+ " price" : 2.66
243
+ }
244
+ JSON;
245
+ $object = $schema- >import(json_decode($json));
246
+
247
+ // Get particular object with `pick` accessor
248
+ $info = UserInfo::pick($object);
249
+ $order = Order::pick($object);
250
+
251
+ // Data is imported objects of according classes
252
+ $this->assertTrue($order instanceof Order);
253
+ $this->assertTrue($info instanceof UserInfo);
254
+
255
+ $this->assertSame(1, $order->id);
256
+ $this->assertSame('John', $info->firstName);
257
+ $this->assertSame('Doe', $info->lastName);
258
+ $this->assertSame(2.66, $order->price);
259
+ ```
260
+
261
+ #### Keys mapping
262
+
263
+ If property names of PHP objects should be different from raw data you
264
+ can apply ` \Swaggest\JsonSchema\PreProcessor\NameMapper ` during processing.
265
+ It takes ` Swaggest\JsonSchema\Meta\FieldName ` as source of raw name.
266
+
267
+ ``` php
268
+ $properties->dateTime = Schema::string()->meta(new FieldName('date_time'));
269
+ ```
270
+
271
+ ``` php
272
+ $mapper = new NameMapper();
273
+
274
+ $order = new Order();
275
+ $order->id = 1;
276
+ $order->dateTime = '2015-10-28T07:28:00Z';
277
+ $exported = Order::export($order, $mapper);
278
+ $json = <<<JSON
279
+ {
280
+ " id" : 1,
281
+ " date_time" : " 2015-10-28T07:28:00Z"
282
+ }
283
+ JSON;
284
+ $this- >assertSame($json, json_encode($exported, JSON_PRETTY_PRINT));
285
+
286
+ $imported = Order::import(json_decode($json), $mapper);
287
+ $this->assertSame('2015-10-28T07:28:00Z', $imported->dateTime);
288
+ ```
289
+
290
+ You can create your own pre-processor implementing ` Swaggest\JsonSchema\DataPreProcessor ` .
291
+
292
+ #### Meta
293
+
294
+ ` Meta ` is a way to complement ` Schema ` with your own data. You can keep and retrieve it.
295
+
296
+ You can store it.
297
+ ``` php
298
+ $schema = new Schema();
299
+ // Setting meta
300
+ $schema->meta(new FieldName('my-value'));
301
+ ```
302
+
303
+ And get back.
304
+ ``` php
305
+ // Retrieving meta
306
+ $myMeta = FieldName::get($schema);
307
+ $this->assertSame('my-value', $myMeta->name);
177
308
```
0 commit comments