Skip to content

Commit 7072885

Browse files
committed
wip oi
1 parent 553bf86 commit 7072885

File tree

9 files changed

+213
-26
lines changed

9 files changed

+213
-26
lines changed

src/Constraint/Properties.php

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,18 @@
22

33
namespace Swaggest\JsonSchema\Constraint;
44

5+
use Swaggest\JsonSchema\Exception;
56
use Swaggest\JsonSchema\MagicMap;
67
use Swaggest\JsonSchema\Schema;
8+
use Swaggest\JsonSchema\Structure\Egg;
79

810
/**
911
* @method Schema __get($key)
1012
*/
1113
class Properties extends MagicMap implements Constraint
1214
{
1315
/** @var Schema[] */
14-
protected $_arrayOfData = array();
16+
protected $__arrayOfData = array();
1517

1618
public function __set($name, $column)
1719
{
@@ -35,4 +37,33 @@ public function setAdditionalProperties(Schema $additionalProperties = null)
3537
$this->additionalProperties = $additionalProperties;
3638
return $this;
3739
}
40+
41+
42+
/** @var Egg[] */
43+
private $nestedProperties = array();
44+
45+
public function addNested(Schema $nested, $name = null)
46+
{
47+
if (null === $nested->properties) {
48+
throw new Exception('Schema with properties required', Exception::PROPERTIES_REQUIRED);
49+
}
50+
if (null === $name) {
51+
$name = $nested->objectItemClass;
52+
}
53+
if (null === $name) {
54+
throw new Exception('Undefined nested name', Exception::UNDEFINED_NESTED_NAME);
55+
}
56+
foreach ($nested->properties->toArray() as $propertyName => $property) {
57+
$this->nestedProperties[$propertyName] = new Egg($nested, $name, $property);
58+
}
59+
return $this;
60+
}
61+
62+
/**
63+
* @return Egg[]
64+
*/
65+
public function getNestedProperties()
66+
{
67+
return $this->nestedProperties;
68+
}
3869
}

src/Exception.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?php
2+
3+
namespace Swaggest\JsonSchema;
4+
5+
6+
class Exception extends \Exception
7+
{
8+
const PROPERTIES_REQUIRED = 1;
9+
const UNDEFINED_NESTED_NAME = 2;
10+
11+
}

src/InvalidValue.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
namespace Swaggest\JsonSchema;
44

5-
class InvalidValue extends \Exception
5+
class InvalidValue extends Exception
66
{
77
public function addPath($path)
88
{

src/MagicMap.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -4,18 +4,18 @@
44

55
class MagicMap implements \ArrayAccess, \JsonSerializable
66
{
7-
protected $_arrayOfData = array();
7+
protected $__arrayOfData = array();
88

99
public function __set($name, $column)
1010
{
11-
$this->_arrayOfData[$name] = $column;
11+
$this->__arrayOfData[$name] = $column;
1212
return $this;
1313
}
1414

1515
public function &__get($name)
1616
{
17-
if (isset($this->_arrayOfData[$name])) {
18-
return $this->_arrayOfData[$name];
17+
if (isset($this->__arrayOfData[$name])) {
18+
return $this->__arrayOfData[$name];
1919
} else {
2020
$tmp = null;
2121
return $tmp;
@@ -24,13 +24,13 @@ public function &__get($name)
2424

2525
public function offsetExists($offset)
2626
{
27-
return array_key_exists($offset, $this->_arrayOfData);
27+
return array_key_exists($offset, $this->__arrayOfData);
2828
}
2929

3030
public function &offsetGet($offset)
3131
{
32-
if (isset($this->_arrayOfData[$offset])) {
33-
return $this->_arrayOfData[$offset];
32+
if (isset($this->__arrayOfData[$offset])) {
33+
return $this->__arrayOfData[$offset];
3434
} else {
3535
$tmp = null;
3636
return $tmp;
@@ -44,17 +44,17 @@ public function offsetSet($offset, $value)
4444

4545
public function offsetUnset($offset)
4646
{
47-
unset($this->_arrayOfData[$offset]);
47+
unset($this->__arrayOfData[$offset]);
4848
}
4949

5050
public function &toArray()
5151
{
52-
return $this->_arrayOfData;
52+
return $this->__arrayOfData;
5353
}
5454

5555
public function jsonSerialize()
5656
{
57-
return (object)$this->_arrayOfData;
57+
return (object)$this->__arrayOfData;
5858
}
5959

6060

src/Schema.php

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
use Swaggest\JsonSchema\Exception\StringException;
1717
use Swaggest\JsonSchema\Exception\TypeException;
1818
use Swaggest\JsonSchema\Structure\ClassStructure;
19+
use Swaggest\JsonSchema\Structure\Egg;
1920
use Swaggest\JsonSchema\Structure\ObjectItem;
2021

2122
class Schema extends MagicMap
@@ -126,7 +127,7 @@ private function process($data, $import = true, $path = '#')
126127
if ($this->enum !== null) {
127128
$enumOk = false;
128129
foreach ($this->enum as $item) {
129-
if ($item === $data) {
130+
if ($item === $data) { // todo support complex structures here
130131
$enumOk = true;
131132
break;
132133
}
@@ -263,11 +264,7 @@ private function process($data, $import = true, $path = '#')
263264
}
264265

265266
if ($import && !$result instanceof ObjectItem) {
266-
if (null === $this->objectItemClass) {
267-
$result = new ObjectItem();
268-
} else {
269-
$result = new $this->objectItemClass;
270-
}
267+
$result = $this->makeObjectItem();
271268

272269
if ($result instanceof ClassStructure) {
273270
if ($result->__validateOnSet) {
@@ -282,7 +279,8 @@ private function process($data, $import = true, $path = '#')
282279

283280
if ($this->properties !== null) {
284281
/** @var Schema[] $properties */
285-
$properties = &$this->properties->toArray();
282+
$properties = &$this->properties->toArray(); // TODO check performance of pointer
283+
$nestedProperties = $this->properties->getNestedProperties();
286284
}
287285

288286
$array = (array)$data;
@@ -301,7 +299,8 @@ private function process($data, $import = true, $path = '#')
301299
} else {
302300
foreach ($dependencies as $item) {
303301
if (!property_exists($data, $item)) {
304-
$this->fail(new ObjectException('Dependency property missing: ' . $item, ObjectException::DEPENDENCY_MISSING), $path);
302+
$this->fail(new ObjectException('Dependency property missing: ' . $item,
303+
ObjectException::DEPENDENCY_MISSING), $path);
305304
}
306305
}
307306
}
@@ -312,11 +311,22 @@ private function process($data, $import = true, $path = '#')
312311
$value = $properties[$key]->process($value, $import, $path . '->properties:' . $key);
313312
}
314313

314+
/** @var Egg $nestedEgg */
315+
$nestedEgg = null;
316+
if (!$found && isset($nestedProperties[$key])) {
317+
$found = true;
318+
$nestedEgg = $nestedProperties[$key];
319+
$value = $nestedEgg->propertySchema->process($value, $import, $path . '->nestedProperties:' . $key);
320+
}
321+
315322
if ($this->patternProperties !== null) {
316323
foreach ($this->patternProperties as $pattern => $propertySchema) {
317324
if (preg_match($pattern, $key)) {
318325
$found = true;
319326
$value = $propertySchema->process($value, $import, $path . '->patternProperties:' . $pattern);
327+
if ($import) {
328+
$result->addPatternPropertyName($pattern, $key);
329+
}
320330
//break; // todo manage multiple import data properly (pattern accessor)
321331
}
322332
}
@@ -327,8 +337,18 @@ private function process($data, $import = true, $path = '#')
327337
}
328338

329339
$value = $this->additionalProperties->process($value, $import, $path . '->additionalProperties');
340+
if ($import) {
341+
$result->addAdditionalPropertyName($key);
342+
}
330343
}
331-
$result->$key = $value;
344+
345+
if ($nestedEgg) {
346+
$result->setNestedProperty($key, $value, $nestedEgg);
347+
348+
} else {
349+
$result->$key = $value;
350+
}
351+
332352
}
333353

334354
}
@@ -471,4 +491,15 @@ public function getMeta($className)
471491
return null;
472492
}
473493

494+
/**
495+
* @return ObjectItem
496+
*/
497+
public function makeObjectItem()
498+
{
499+
if (null === $this->objectItemClass) {
500+
return new ObjectItem();
501+
} else {
502+
return new $this->objectItemClass;
503+
}
504+
}
474505
}

src/Structure/ClassStructure.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -61,16 +61,18 @@ public static function create()
6161
protected $__hasNativeProperties = true;
6262
protected $__validateOnSet = true; // todo skip validation during import
6363

64-
public function jsonSerialize()
64+
public function jsonSerialize() // todo process nested structures here
6565
{
6666
if ($this->__hasNativeProperties) {
6767
$result = new \stdClass();
68-
foreach (static::schema()->properties->toArray() as $name => $schema) {
68+
$properties = static::schema()->properties;
69+
foreach ($properties->toArray() as $name => $schema) {
6970
$value = $this->$name;
70-
if ((null !== $value) || array_key_exists($name, $this->_arrayOfData)) {
71+
if ((null !== $value) || array_key_exists($name, $this->__arrayOfData)) {
7172
$result->$name = $value;
7273
}
7374
}
75+
// foreach ($properties->addNested())
7476
} else {
7577
$result = parent::jsonSerialize();
7678
}
@@ -90,14 +92,14 @@ public static function names()
9092
return $nameflector;
9193
}
9294

93-
public function __set($name, $column)
95+
public function __set($name, $column) // todo nested schemas
9496
{
9597
if ($this->__validateOnSet) {
9698
if ($property = static::schema()->properties[$name]) {
9799
$property->export($column);
98100
}
99101
}
100-
$this->_arrayOfData[$name] = $column;
102+
$this->__arrayOfData[$name] = $column;
101103
return $this;
102104
}
103105
}

src/Structure/Egg.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace Swaggest\JsonSchema\Structure;
4+
5+
6+
use Swaggest\JsonSchema\Schema;
7+
8+
class Egg
9+
{
10+
11+
12+
/** @var Schema */
13+
public $classSchema;
14+
public $name;
15+
/** @var Schema */
16+
public $propertySchema;
17+
18+
/**
19+
* Egg constructor.
20+
* @param Schema $classSchema
21+
* @param $name
22+
* @param Schema $propertySchema
23+
*/
24+
public function __construct(Schema $classSchema, $name, Schema $propertySchema)
25+
{
26+
$this->classSchema = $classSchema;
27+
$this->name = $name;
28+
$this->propertySchema = $propertySchema;
29+
}
30+
}

src/Structure/ObjectItem.php

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,58 @@
77

88
class ObjectItem extends MagicMap
99
{
10+
protected $__nestedObjects;
11+
12+
public function setNestedProperty($propertyName, $value, Egg $nestedEgg)
13+
{
14+
$nested = &$this->__nestedObjects[$nestedEgg->name];
15+
if (null === $nested) {
16+
$nested = $nestedEgg->classSchema->makeObjectItem();
17+
}
18+
$nested->$propertyName = $value;
19+
}
20+
21+
protected $__additionalPropertyNames;
22+
public function addAdditionalPropertyName($name)
23+
{
24+
$this->__additionalPropertyNames[] = $name;
25+
}
26+
27+
/**
28+
* @return null|string[]
29+
*/
30+
public function getAdditionalPropertyNames()
31+
{
32+
return $this->__additionalPropertyNames;
33+
}
34+
35+
protected $__patternPropertyNames;
36+
37+
public function addPatternPropertyName($pattern, $name)
38+
{
39+
$this->__additionalPropertyNames[$pattern][] = $name;
40+
}
41+
42+
/**
43+
* @param $pattern
44+
* @return null|string[]
45+
*/
46+
public function getPatternPropertyNames($pattern)
47+
{
48+
if (isset($this->__patternPropertyNames[$pattern])) {
49+
return $this->__patternPropertyNames[$pattern];
50+
} else {
51+
return null;
52+
}
53+
}
54+
55+
public function jsonSerialize()
56+
{
57+
if ($this->__nestedObjects) {
58+
} else {
59+
return (object)$this->__arrayOfData;
60+
}
61+
}
62+
63+
1064
}

0 commit comments

Comments
 (0)