|
7 | 7 |
|
8 | 8 | namespace cebe\openapi; |
9 | 9 |
|
10 | | -use cebe\openapi\exceptions\ReadonlyPropertyException; |
11 | 10 | use cebe\openapi\exceptions\TypeErrorException; |
12 | 11 | use cebe\openapi\exceptions\UnknownPropertyException; |
| 12 | +use cebe\openapi\json\JsonPointer; |
13 | 13 | use cebe\openapi\spec\Reference; |
14 | 14 | use cebe\openapi\spec\Type; |
15 | 15 |
|
|
19 | 19 | * Implements property management and validation basics. |
20 | 20 | * |
21 | 21 | */ |
22 | | -abstract class SpecBaseObject implements SpecObjectInterface |
| 22 | +abstract class SpecBaseObject implements SpecObjectInterface, DocumentContextInterface |
23 | 23 | { |
24 | 24 | private $_properties = []; |
25 | 25 | private $_errors = []; |
26 | 26 |
|
| 27 | + private $_baseDocument; |
| 28 | + private $_jsonPointer; |
| 29 | + |
| 30 | + |
27 | 31 | /** |
28 | 32 | * @return array array of attributes available in this object. |
29 | 33 | */ |
@@ -192,7 +196,15 @@ public function validate(): bool |
192 | 196 | */ |
193 | 197 | public function getErrors(): array |
194 | 198 | { |
195 | | - $errors = [$this->_errors]; |
| 199 | + if (($pos = $this->getDocumentPosition()) !== null) { |
| 200 | + $errors = [ |
| 201 | + array_map(function($e) use ($pos) { |
| 202 | + return "[{$pos->getPointer()}] $e"; |
| 203 | + }, $this->_errors) |
| 204 | + ]; |
| 205 | + } else { |
| 206 | + $errors = [$this->_errors]; |
| 207 | + } |
196 | 208 | foreach ($this->_properties as $v) { |
197 | 209 | if ($v instanceof SpecObjectInterface) { |
198 | 210 | $errors[] = $v->getErrors(); |
@@ -326,4 +338,48 @@ public function setReferenceContext(ReferenceContext $context) |
326 | 338 | } |
327 | 339 | } |
328 | 340 | } |
| 341 | + |
| 342 | + /** |
| 343 | + * Provide context information to the object. |
| 344 | + * |
| 345 | + * Context information contains a reference to the base object where it is contained in |
| 346 | + * as well as a JSON pointer to its position. |
| 347 | + * @param SpecObjectInterface $baseDocument |
| 348 | + * @param JsonPointer $jsonPointer |
| 349 | + */ |
| 350 | + public function setDocumentContext(SpecObjectInterface $baseDocument, JsonPointer $jsonPointer) |
| 351 | + { |
| 352 | + $this->_baseDocument = $baseDocument; |
| 353 | + $this->_jsonPointer = $jsonPointer; |
| 354 | + |
| 355 | + foreach ($this->_properties as $property => $value) { |
| 356 | + if ($value instanceof DocumentContextInterface) { |
| 357 | + $value->setDocumentContext($baseDocument, $jsonPointer->append($property)); |
| 358 | + } elseif (is_array($value)) { |
| 359 | + foreach ($value as $k => $item) { |
| 360 | + if ($item instanceof DocumentContextInterface) { |
| 361 | + $item->setDocumentContext($baseDocument, $jsonPointer->append($property)->append($k)); |
| 362 | + } |
| 363 | + } |
| 364 | + } |
| 365 | + } |
| 366 | + } |
| 367 | + |
| 368 | + /** |
| 369 | + * @return SpecObjectInterface|null returns the base document where this object is located in. |
| 370 | + * Returns `null` if no context information was provided by [[setDocumentContext]]. |
| 371 | + */ |
| 372 | + public function getBaseDocument(): ?SpecObjectInterface |
| 373 | + { |
| 374 | + return $this->_baseDocument; |
| 375 | + } |
| 376 | + |
| 377 | + /** |
| 378 | + * @return JsonPointer|null returns a JSON pointer describing the position of this object in the base document. |
| 379 | + * Returns `null` if no context information was provided by [[setDocumentContext]]. |
| 380 | + */ |
| 381 | + public function getDocumentPosition(): ?JsonPointer |
| 382 | + { |
| 383 | + return $this->_jsonPointer; |
| 384 | + } |
329 | 385 | } |
0 commit comments