9
9
10
10
namespace JsonSchema \Constraints ;
11
11
12
+ use JsonSchema \SchemaStorage ;
12
13
use JsonSchema \Uri \UriRetriever ;
13
- use JsonSchema \Validator ;
14
+ use JsonSchema \UriRetrieverInterface ;
15
+ use JsonSchema \Entity \JsonPointer ;
14
16
15
17
/**
16
18
* The Base Constraints, all Validators should extend this class
20
22
*/
21
23
abstract class Constraint implements ConstraintInterface
22
24
{
25
+ protected $ schemaStorage ;
23
26
protected $ checkMode = self ::CHECK_MODE_NORMAL ;
24
27
protected $ uriRetriever ;
25
28
protected $ errors = array ();
@@ -34,19 +37,25 @@ abstract class Constraint implements ConstraintInterface
34
37
private $ factory ;
35
38
36
39
/**
37
- * @param int $checkMode
38
- * @param UriRetriever $uriRetriever
39
- * @param Factory $factory
40
+ * @param int $checkMode
41
+ * @param SchemaStorage $schemaStorage
42
+ * @param UriRetrieverInterface $uriRetriever
43
+ * @param Factory $factory
40
44
*/
41
- public function __construct ($ checkMode = self ::CHECK_MODE_NORMAL , UriRetriever $ uriRetriever = null , Factory $ factory = null )
42
- {
43
- $ this ->checkMode = $ checkMode ;
44
- $ this ->uriRetriever = $ uriRetriever ;
45
- $ this ->factory = $ factory ;
45
+ public function __construct (
46
+ $ checkMode = self ::CHECK_MODE_NORMAL ,
47
+ SchemaStorage $ schemaStorage = null ,
48
+ UriRetrieverInterface $ uriRetriever = null ,
49
+ Factory $ factory = null
50
+ ) {
51
+ $ this ->checkMode = $ checkMode ;
52
+ $ this ->uriRetriever = $ uriRetriever ;
53
+ $ this ->factory = $ factory ;
54
+ $ this ->schemaStorage = $ schemaStorage ;
46
55
}
47
56
48
57
/**
49
- * @return UriRetriever $uriRetriever
58
+ * @return UriRetrieverInterface $uriRetriever
50
59
*/
51
60
public function getUriRetriever ()
52
61
{
@@ -63,27 +72,40 @@ public function getUriRetriever()
63
72
public function getFactory ()
64
73
{
65
74
if (!$ this ->factory ) {
66
- $ this ->factory = new Factory ($ this ->getUriRetriever (), $ this ->checkMode );
75
+ $ this ->factory = new Factory ($ this ->getSchemaStorage (), $ this -> getUriRetriever (), $ this ->checkMode );
67
76
}
68
77
69
78
return $ this ->factory ;
70
79
}
71
80
72
81
/**
73
- * @param UriRetriever $uriRetriever
82
+ * @return SchemaStorage
74
83
*/
75
- public function setUriRetriever (UriRetriever $ uriRetriever )
84
+ public function getSchemaStorage ()
85
+ {
86
+ if (is_null ($ this ->schemaStorage )) {
87
+ $ this ->schemaStorage = new SchemaStorage ($ this ->getUriRetriever ());
88
+ }
89
+
90
+ return $ this ->schemaStorage ;
91
+ }
92
+
93
+ /**
94
+ * @param UriRetrieverInterface $uriRetriever
95
+ */
96
+ public function setUriRetriever (UriRetrieverInterface $ uriRetriever )
76
97
{
77
98
$ this ->uriRetriever = $ uriRetriever ;
78
99
}
79
100
80
101
/**
81
102
* {@inheritDoc}
82
103
*/
83
- public function addError ($ path , $ message , $ constraint ='' , array $ more =null )
104
+ public function addError (JsonPointer $ path = null , $ message , $ constraint ='' , array $ more =null )
84
105
{
85
106
$ error = array (
86
- 'property ' => $ path ,
107
+ 'property ' => $ this ->convertJsonPointerIntoPropertyPath ($ path ?: new JsonPointer ('' )),
108
+ 'pointer ' => ltrim (strval ($ path ?: new JsonPointer ('' )), '# ' ),
87
109
'message ' => $ message ,
88
110
'constraint ' => $ constraint ,
89
111
);
@@ -132,37 +154,32 @@ public function reset()
132
154
/**
133
155
* Bubble down the path
134
156
*
135
- * @param string $path Current path
136
- * @param mixed $i What to append to the path
157
+ * @param JsonPointer|null $path Current path
158
+ * @param mixed $i What to append to the path
137
159
*
138
- * @return string
160
+ * @return JsonPointer;
139
161
*/
140
- protected function incrementPath ($ path , $ i )
162
+ protected function incrementPath (JsonPointer $ path = null , $ i )
141
163
{
142
- if ($ path !== '' ) {
143
- if (is_int ($ i )) {
144
- $ path .= '[ ' . $ i . '] ' ;
145
- } elseif ($ i == '' ) {
146
- $ path .= '' ;
147
- } else {
148
- $ path .= '. ' . $ i ;
149
- }
150
- } else {
151
- $ path = $ i ;
152
- }
153
-
164
+ $ path = $ path ?: new JsonPointer ('' );
165
+ $ path = $ path ->withPropertyPaths (
166
+ array_merge (
167
+ $ path ->getPropertyPaths (),
168
+ array_filter (array ($ i ), 'strlen ' )
169
+ )
170
+ );
154
171
return $ path ;
155
172
}
156
173
157
174
/**
158
175
* Validates an array
159
176
*
160
- * @param mixed $value
161
- * @param mixed $schema
162
- * @param mixed $path
163
- * @param mixed $i
177
+ * @param mixed $value
178
+ * @param mixed $schema
179
+ * @param JsonPointer|null $path
180
+ * @param mixed $i
164
181
*/
165
- protected function checkArray ($ value , $ schema = null , $ path = null , $ i = null )
182
+ protected function checkArray ($ value , $ schema = null , JsonPointer $ path = null , $ i = null )
166
183
{
167
184
$ validator = $ this ->getFactory ()->createInstanceFor ('collection ' );
168
185
$ validator ->check ($ value , $ schema , $ path , $ i );
@@ -173,13 +190,13 @@ protected function checkArray($value, $schema = null, $path = null, $i = null)
173
190
/**
174
191
* Validates an object
175
192
*
176
- * @param mixed $value
177
- * @param mixed $schema
178
- * @param mixed $path
179
- * @param mixed $i
180
- * @param mixed $patternProperties
193
+ * @param mixed $value
194
+ * @param mixed $schema
195
+ * @param JsonPointer|null $path
196
+ * @param mixed $i
197
+ * @param mixed $patternProperties
181
198
*/
182
- protected function checkObject ($ value , $ schema = null , $ path = null , $ i = null , $ patternProperties = null )
199
+ protected function checkObject ($ value , $ schema = null , JsonPointer $ path = null , $ i = null , $ patternProperties = null )
183
200
{
184
201
$ validator = $ this ->getFactory ()->createInstanceFor ('object ' );
185
202
$ validator ->check ($ value , $ schema , $ path , $ i , $ patternProperties );
@@ -190,12 +207,12 @@ protected function checkObject($value, $schema = null, $path = null, $i = null,
190
207
/**
191
208
* Validates the type of a property
192
209
*
193
- * @param mixed $value
194
- * @param mixed $schema
195
- * @param mixed $path
196
- * @param mixed $i
210
+ * @param mixed $value
211
+ * @param mixed $schema
212
+ * @param JsonPointer|null $path
213
+ * @param mixed $i
197
214
*/
198
- protected function checkType ($ value , $ schema = null , $ path = null , $ i = null )
215
+ protected function checkType ($ value , $ schema = null , JsonPointer $ path = null , $ i = null )
199
216
{
200
217
$ validator = $ this ->getFactory ()->createInstanceFor ('type ' );
201
218
$ validator ->check ($ value , $ schema , $ path , $ i );
@@ -206,28 +223,28 @@ protected function checkType($value, $schema = null, $path = null, $i = null)
206
223
/**
207
224
* Checks a undefined element
208
225
*
209
- * @param mixed $value
210
- * @param mixed $schema
211
- * @param mixed $path
212
- * @param mixed $i
226
+ * @param mixed $value
227
+ * @param mixed $schema
228
+ * @param JsonPointer|null $path
229
+ * @param mixed $i
213
230
*/
214
- protected function checkUndefined ($ value , $ schema = null , $ path = null , $ i = null )
231
+ protected function checkUndefined ($ value , $ schema = null , JsonPointer $ path = null , $ i = null )
215
232
{
216
233
$ validator = $ this ->getFactory ()->createInstanceFor ('undefined ' );
217
- $ validator ->check ($ value , $ schema , $ path , $ i );
234
+ $ validator ->check ($ value , $ this -> schemaStorage -> resolveRefSchema ( $ schema) , $ path , $ i );
218
235
219
236
$ this ->addErrors ($ validator ->getErrors ());
220
237
}
221
238
222
239
/**
223
240
* Checks a string element
224
241
*
225
- * @param mixed $value
226
- * @param mixed $schema
227
- * @param mixed $path
228
- * @param mixed $i
242
+ * @param mixed $value
243
+ * @param mixed $schema
244
+ * @param JsonPointer|null $path
245
+ * @param mixed $i
229
246
*/
230
- protected function checkString ($ value , $ schema = null , $ path = null , $ i = null )
247
+ protected function checkString ($ value , $ schema = null , JsonPointer $ path = null , $ i = null )
231
248
{
232
249
$ validator = $ this ->getFactory ()->createInstanceFor ('string ' );
233
250
$ validator ->check ($ value , $ schema , $ path , $ i );
@@ -238,12 +255,12 @@ protected function checkString($value, $schema = null, $path = null, $i = null)
238
255
/**
239
256
* Checks a number element
240
257
*
241
- * @param mixed $value
242
- * @param mixed $schema
243
- * @param mixed $path
244
- * @param mixed $i
258
+ * @param mixed $value
259
+ * @param mixed $schema
260
+ * @param JsonPointer $path
261
+ * @param mixed $i
245
262
*/
246
- protected function checkNumber ($ value , $ schema = null , $ path = null , $ i = null )
263
+ protected function checkNumber ($ value , $ schema = null , JsonPointer $ path = null , $ i = null )
247
264
{
248
265
$ validator = $ this ->getFactory ()->createInstanceFor ('number ' );
249
266
$ validator ->check ($ value , $ schema , $ path , $ i );
@@ -254,41 +271,35 @@ protected function checkNumber($value, $schema = null, $path = null, $i = null)
254
271
/**
255
272
* Checks a enum element
256
273
*
257
- * @param mixed $value
258
- * @param mixed $schema
259
- * @param mixed $path
260
- * @param mixed $i
274
+ * @param mixed $value
275
+ * @param mixed $schema
276
+ * @param JsonPointer|null $path
277
+ * @param mixed $i
261
278
*/
262
- protected function checkEnum ($ value , $ schema = null , $ path = null , $ i = null )
279
+ protected function checkEnum ($ value , $ schema = null , JsonPointer $ path = null , $ i = null )
263
280
{
264
281
$ validator = $ this ->getFactory ()->createInstanceFor ('enum ' );
265
282
$ validator ->check ($ value , $ schema , $ path , $ i );
266
283
267
284
$ this ->addErrors ($ validator ->getErrors ());
268
285
}
269
286
270
- protected function checkFormat ($ value , $ schema = null , $ path = null , $ i = null )
287
+ /**
288
+ * Checks format of an element
289
+ *
290
+ * @param mixed $value
291
+ * @param mixed $schema
292
+ * @param JsonPointer|null $path
293
+ * @param mixed $i
294
+ */
295
+ protected function checkFormat ($ value , $ schema = null , JsonPointer $ path = null , $ i = null )
271
296
{
272
297
$ validator = $ this ->getFactory ()->createInstanceFor ('format ' );
273
298
$ validator ->check ($ value , $ schema , $ path , $ i );
274
299
275
300
$ this ->addErrors ($ validator ->getErrors ());
276
301
}
277
302
278
- /**
279
- * @param string $uri JSON Schema URI
280
- * @return string JSON Schema contents
281
- */
282
- protected function retrieveUri ($ uri )
283
- {
284
- if (null === $ this ->uriRetriever ) {
285
- $ this ->setUriRetriever (new UriRetriever );
286
- }
287
- $ jsonSchema = $ this ->uriRetriever ->retrieve ($ uri );
288
- // TODO validate using schema
289
- return $ jsonSchema ;
290
- }
291
-
292
303
/**
293
304
* Get the type check based on the set check mode.
294
305
*
@@ -298,4 +309,19 @@ protected function getTypeCheck()
298
309
{
299
310
return $ this ->getFactory ()->getTypeCheck ();
300
311
}
312
+
313
+ /**
314
+ * @param JsonPointer $pointer
315
+ * @return string property path
316
+ */
317
+ protected function convertJsonPointerIntoPropertyPath (JsonPointer $ pointer )
318
+ {
319
+ $ result = array_map (
320
+ function ($ path ) {
321
+ return sprintf (is_numeric ($ path ) ? '[%d] ' : '.%s ' , $ path );
322
+ },
323
+ $ pointer ->getPropertyPaths ()
324
+ );
325
+ return trim (implode ('' , $ result ), '. ' );
326
+ }
301
327
}
0 commit comments