Skip to content

Commit b080456

Browse files
committed
fixed tests
1 parent 9b02b08 commit b080456

27 files changed

+517
-201
lines changed

src/Constraint/Constraint.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
namespace Yaoi\Schema\Constraint;
44

5+
use Yaoi\Schema\NG\Schema;
56

67
interface Constraint
78
{
8-
public static function getConstraintName();
9+
public function setToSchema(Schema $schema);
910

1011
}

src/Constraint/Definitions.php

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,8 @@ class Definitions extends MagicMap implements Constraint
1111
/** @var Schema[] */
1212
protected $_arrayOfData = array();
1313

14-
public static function getConstraintName()
14+
public function setToSchema(Schema $schema)
1515
{
16-
return 'definitions';
16+
$schema->definitions = $this;
1717
}
18-
19-
2018
}

src/Constraint/Properties.php

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,12 @@
44

55
use Yaoi\Schema\NG\MagicMap;
66
use Yaoi\Schema\NG\Schema;
7+
use Yaoi\Schema\NG\SchemaLoader;
78
use Yaoi\Schema\Structure\ObjectItem;
89

10+
/**
11+
* @method Schema __get($key)
12+
*/
913
class Properties extends MagicMap implements Constraint
1014
{
1115
/** @var Schema[] */
@@ -15,28 +19,41 @@ public function __set($name, $column)
1519
{
1620
if ($column instanceof Constraint) {
1721
$schema = new Schema();
18-
$schema->{$column->getConstraintName()} = $column;
19-
$column = $schema;
22+
$column->setToSchema($schema);
23+
return parent::__set($name, $schema);
2024
}
2125

2226
return parent::__set($name, $column);
2327
}
2428

25-
public static function create()
29+
public function setToSchema(Schema $schema)
2630
{
27-
return new static;
31+
$schema->properties = $this;
2832
}
2933

30-
public static function getConstraintName()
34+
public static function create()
3135
{
32-
return 'properties';
36+
return new static;
3337
}
3438

35-
public function import($data, ObjectItem $result)
39+
public function import($data, ObjectItem $result, Schema $schema = null)
3640
{
41+
$traceHelper = Schema::$traceHelper;
42+
43+
$additionalProperties = $schema->additionalProperties;
44+
3745
foreach ($data as $key => $value) {
3846
if (isset($this->_arrayOfData[$key])) {
47+
$traceHelper->push()->addData(SchemaLoader::PROPERTIES . ':' . $key);
3948
$result->$key = $this->_arrayOfData[$key]->import($value);
49+
$traceHelper->pop();
50+
} else {
51+
if (null !== $additionalProperties) {
52+
$traceHelper->push()->addData(SchemaLoader::ADDITIONAL_PROPERTIES);
53+
$value = $additionalProperties->import($value);
54+
$traceHelper->pop();
55+
}
56+
$result->$key = $value;
4057
}
4158
}
4259
}
@@ -49,4 +66,17 @@ public function export(ObjectItem $data)
4966
}
5067
return $result;
5168
}
69+
70+
/** @var Schema */
71+
private $additionalProperties;
72+
73+
/**
74+
* @param Schema $additionalProperties
75+
* @return Properties
76+
*/
77+
public function setAdditionalProperties(Schema $additionalProperties = null)
78+
{
79+
$this->additionalProperties = $additionalProperties;
80+
return $this;
81+
}
5282
}

src/Constraint/Ref.php

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,23 @@
22

33
namespace Yaoi\Schema\Constraint;
44

5-
use Yaoi\Schema\NG\SchemaLoader;
65
use Yaoi\Schema\NG\Schema;
76

87
class Ref implements Constraint
98
{
10-
public static function getConstraintName()
9+
private $ref;
10+
public function __construct($ref, Schema $schema)
1111
{
12-
return '$ref';
12+
$this->ref = $ref;
13+
$this->schema = $schema;
1314
}
1415

15-
private $ref;
16-
private $rootSchema;
17-
public function __construct($ref, Schema $rootSchema)
16+
public function setToSchema(Schema $schema)
1817
{
19-
$this->ref = $ref;
20-
$this->rootSchema = $rootSchema;
18+
$schema->ref = $this;
2119
}
2220

21+
2322
/** @var Schema */
2423
private $schema;
2524

@@ -30,9 +29,6 @@ public function __construct($ref, Schema $rootSchema)
3029
*/
3130
public function getSchema()
3231
{
33-
if (null === $this->schema) {
34-
$this->schema = $this->rootSchema->getDefinition($this->ref);
35-
}
3632
return $this->schema;
3733
}
3834
}

src/Constraint/Type.php

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
namespace Yaoi\Schema\Constraint;
44

55

6+
use Yaoi\Schema\NG\Schema;
7+
68
class Type implements Constraint
79
{
810
const OBJECT = 'object';
@@ -13,16 +15,21 @@ class Type implements Constraint
1315
const BOOLEAN = 'boolean';
1416
const NULL = 'null';
1517

16-
private $types;
18+
public $types;
1719

1820
public function __construct($type)
1921
{
2022
$this->types = is_array($type) ? $type : array($type);
2123
}
2224

23-
public static function getConstraintName()
25+
public function setToSchema(Schema $schema)
26+
{
27+
$schema->type = $this;
28+
}
29+
30+
public function has($type)
2431
{
25-
return 'type';
32+
return in_array($type, $this->types);
2633
}
2734

2835
public function isValid($data)

src/NG/MagicMap.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ public function __set($name, $column)
1212
return $this;
1313
}
1414

15-
public function __get($name)
15+
public function &__get($name)
1616
{
1717
return $this->_arrayOfData[$name];
1818
}
@@ -22,7 +22,7 @@ public function offsetExists($offset)
2222
return array_key_exists($offset, $this->_arrayOfData);
2323
}
2424

25-
public function offsetGet($offset)
25+
public function &offsetGet($offset)
2626
{
2727
return $this->_arrayOfData[$offset];
2828
}
@@ -37,4 +37,8 @@ public function offsetUnset($offset)
3737
unset($this->_arrayOfData[$offset]);
3838
}
3939

40+
public function &toArray()
41+
{
42+
return $this->_arrayOfData;
43+
}
4044
}

src/NG/Schema.php

Lines changed: 104 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -10,14 +10,23 @@
1010
use Yaoi\Schema\Exception;
1111
use Yaoi\Schema\Structure\ObjectItem;
1212

13-
class Schema
13+
class Schema extends MagicMap
1414
{
15+
/** @var StackTraceStorage */
16+
public static $traceHelper;
17+
1518
/** @var Type */
1619
public $type;
1720

1821
/** @var Properties */
1922
public $properties;
2023

24+
/** @var Schema */
25+
public $additionalProperties;
26+
27+
/** @var Schema */
28+
public $items;
29+
2130
/** @var Definitions */
2231
public $definitions;
2332

@@ -34,35 +43,76 @@ public function import($data)
3443

3544
if ($this->type !== null) {
3645
if (!$this->type->isValid($data)) {
37-
throw new Exception('Invalid type');
46+
$message = ucfirst(implode(', ', $this->type->types) . ' required');
47+
if ($traceFrames = Schema::$traceHelper->getClean()) {
48+
throw new Exception($message . ' at ' . implode('->', $traceFrames), Exception::INVALID_VALUE);
49+
} else {
50+
throw new Exception($message, Exception::INVALID_VALUE);
51+
52+
}
53+
3854
}
3955
}
4056

4157
if ($this->properties !== null) {
42-
if (!$result instanceof ObjectItem) {
43-
$result = new ObjectItem();
58+
if ($data instanceof \stdClass || is_array($data)) {
59+
if (!$result instanceof ObjectItem) {
60+
$result = new ObjectItem();
61+
}
62+
$this->properties->import($data, $result, $this);
63+
}
64+
65+
} else {
66+
if ($data instanceof \stdClass || is_array($data)) {
67+
if ($this->additionalProperties
68+
|| ($this->type && $this->type->has(Type::OBJECT))
69+
) {
70+
71+
if (!$result instanceof ObjectItem) {
72+
$result = new ObjectItem();
73+
}
74+
75+
foreach ((array)$data as $key => $value) {
76+
if ($this->additionalProperties !== null) {
77+
$value = $this->additionalProperties->import($value);
78+
}
79+
$result[$key] = $value;
80+
}
81+
}
82+
}
83+
}
84+
85+
if ($this->items) {
86+
if (is_array($data)) {
87+
foreach ($data as &$value) {
88+
$value = $this->items->import($value);
89+
}
4490
}
45-
$this->properties->import($data, $result);
4691
}
4792

4893

4994
return $result;
5095
}
5196

5297

53-
public function export($data) {
98+
public function export($data)
99+
{
54100
$result = $data;
55101
if ($this->ref !== null) {
56102
$result = $this->ref->getSchema()->export($data);
57103
}
58104

105+
if ($data instanceof ObjectItem) {
106+
$result = $data->toArray();
107+
}
59108

60109
if ($this->type !== null) {
61110
if (!$this->type->isValid($data)) {
62-
throw new Exception('Invalid type');
111+
throw new Exception('Invalid type', Exception::INVALID_VALUE);
63112
}
64113
}
65114

115+
66116
if ($this->properties !== null && ($data instanceof ObjectItem)) {
67117
$result = $this->properties->export($data);
68118
}
@@ -93,4 +143,50 @@ public function getDefinition($ref)
93143
}
94144

95145

96-
}
146+
public static function integer()
147+
{
148+
$schema = new Schema();
149+
$schema->type = new Type(Type::INTEGER);
150+
return $schema;
151+
}
152+
153+
public static function string()
154+
{
155+
$schema = new Schema();
156+
$schema->type = new Type(Type::STRING);
157+
return $schema;
158+
}
159+
160+
public static function create()
161+
{
162+
$schema = new Schema();
163+
return $schema;
164+
}
165+
166+
167+
/**
168+
* @param Properties $properties
169+
* @return Schema
170+
*/
171+
public function setProperties($properties)
172+
{
173+
$this->properties = $properties;
174+
return $this;
175+
}
176+
177+
/**
178+
* @param Type $type
179+
* @return Schema
180+
*/
181+
public function setType($type)
182+
{
183+
$this->type = $type;
184+
return $this;
185+
}
186+
187+
188+
189+
190+
}
191+
192+
Schema::$traceHelper = new StackTraceStorage();

0 commit comments

Comments
 (0)