Skip to content

Commit 68d6a44

Browse files
committed
Various fixes.
1 parent fb1b46f commit 68d6a44

File tree

15 files changed

+263
-105
lines changed

15 files changed

+263
-105
lines changed
Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,22 +18,50 @@
1818

1919
namespace CloudCreativity\JsonApi\Decoders;
2020

21+
use CloudCreativity\JsonApi\Contracts\Validator\ValidatorInterface;
2122
use CloudCreativity\JsonApi\Error\MultiErrorException;
22-
use CloudCreativity\JsonApi\Object\Resource\Resource;
23+
use CloudCreativity\JsonApi\Object\Document\Document;
24+
use CloudCreativity\JsonApi\Validator\Document\DocumentValidator;
2325
use CloudCreativity\JsonApi\Validator\ValidatorAwareTrait;
2426

2527
/**
2628
* Class ResourceDecoder
2729
* @package CloudCreativity\JsonApi
2830
*/
29-
class ResourceDecoder extends AbstractDecoder
31+
class DocumentDecoder extends AbstractDecoder
3032
{
3133

3234
use ValidatorAwareTrait;
3335

36+
/**
37+
* @param ValidatorInterface|null $validator
38+
*/
39+
public function __construct(ValidatorInterface $validator = null)
40+
{
41+
if ($validator) {
42+
$this->setValidator($validator);
43+
} else {
44+
$this->setValidator(new DocumentValidator());
45+
}
46+
}
47+
48+
/**
49+
* @return DocumentValidator
50+
*/
51+
public function getDocumentValidator()
52+
{
53+
$validator = $this->getValidator();
54+
55+
if (!$validator instanceof DocumentValidator) {
56+
throw new \RuntimeException('Expecting a document validator to be set.');
57+
}
58+
59+
return $validator;
60+
}
61+
3462
/**
3563
* @param string $content
36-
* @return Resource
64+
* @return Document
3765
* @throws MultiErrorException
3866
*/
3967
public function decode($content)
@@ -45,6 +73,6 @@ public function decode($content)
4573
throw new MultiErrorException($validator->getErrors(), 'Invalid request body content.');
4674
}
4775

48-
return new Resource($content);
76+
return new Document($content);
4977
}
5078
}
Lines changed: 20 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,38 @@
1616
* limitations under the License.
1717
*/
1818

19-
namespace CloudCreativity\JsonApi\Decoders;
19+
namespace CloudCreativity\JsonApi\Object\Document;
2020

21-
use CloudCreativity\JsonApi\Error\MultiErrorException;
2221
use CloudCreativity\JsonApi\Object\Relationships\Relationship;
23-
use CloudCreativity\JsonApi\Validator\ValidatorAwareTrait;
22+
use CloudCreativity\JsonApi\Object\Resource\ResourceObject;
23+
use CloudCreativity\JsonApi\Object\StandardObject;
2424

2525
/**
26-
* Class RelationshipDecoder
26+
* Class Document
2727
* @package CloudCreativity\JsonApi
2828
*/
29-
class RelationshipDecoder extends AbstractDecoder
29+
class Document extends StandardObject
3030
{
3131

32-
use ValidatorAwareTrait;
32+
const DATA = 'data';
3333

3434
/**
35-
* @param string $content
36-
* @return Relationship
37-
* @throws MultiErrorException
35+
* Get the primary data as a resource object.
36+
*
37+
* @return ResourceObject
3838
*/
39-
public function decode($content)
39+
public function getResource()
4040
{
41-
$content = $this->parseJson($content);
42-
$validator = $this->getValidator();
43-
44-
if (!$validator->isValid($content)) {
45-
throw new MultiErrorException($validator->getErrors(), 'Invalid request body content.');
46-
}
41+
return new ResourceObject($this->get(static::DATA));
42+
}
4743

48-
return new Relationship($content);
44+
/**
45+
* Get the primary data as a relationship object.
46+
*
47+
* @return Relationship
48+
*/
49+
public function getRelationship()
50+
{
51+
return new Relationship($this->get(static::DATA));
4952
}
5053
}
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
* Class Resource
2727
* @package CloudCreativity\JsonApi
2828
*/
29-
class Resource extends StandardObject
29+
class ResourceObject extends StandardObject
3030
{
3131

3232
const TYPE = 'type';
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
<?php
2+
3+
/**
4+
* Copyright 2015 Cloud Creativity Limited
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
namespace CloudCreativity\JsonApi\Validator\Document;
20+
21+
use CloudCreativity\JsonApi\Contracts\Validator\ValidatorInterface;
22+
use CloudCreativity\JsonApi\Error\ErrorObject;
23+
use CloudCreativity\JsonApi\Object\Document\Document;
24+
use CloudCreativity\JsonApi\Object\StandardObject;
25+
use CloudCreativity\JsonApi\Validator\AbstractValidator;
26+
27+
/**
28+
* Class DocumentValidator
29+
* @package CloudCreativity\JsonApi
30+
*/
31+
class DocumentValidator extends AbstractValidator
32+
{
33+
34+
// Error constants
35+
const ERROR_INVALID_VALUE = 'invalid-value';
36+
const ERROR_MISSING_DATA = 'missing-data';
37+
38+
/**
39+
* @var array
40+
*/
41+
protected $templates = [
42+
self::ERROR_INVALID_VALUE => [
43+
ErrorObject::CODE => self::ERROR_INVALID_VALUE,
44+
ErrorObject::TITLE => 'Invalid Value',
45+
ErrorObject::DETAIL => 'Request document must be an object.',
46+
ErrorObject::STATUS => 400,
47+
],
48+
self::ERROR_MISSING_DATA => [
49+
ErrorObject::CODE => self::ERROR_MISSING_DATA,
50+
ErrorObject::TITLE => 'Missing Data',
51+
ErrorObject::DETAIL => 'Request document object must have a data member.',
52+
ErrorObject::STATUS => 400,
53+
],
54+
];
55+
56+
/**
57+
* @var ValidatorInterface|null
58+
*/
59+
protected $_dataValidator;
60+
61+
/**
62+
* @param ValidatorInterface $validator
63+
* @return $this
64+
*/
65+
public function setDataValidator(ValidatorInterface $validator)
66+
{
67+
$this->_dataValidator = $validator;
68+
69+
return $this;
70+
}
71+
72+
/**
73+
* @return ValidatorInterface
74+
*/
75+
public function getDataValidator()
76+
{
77+
if (!$this->_dataValidator instanceof ValidatorInterface) {
78+
throw new \RuntimeException('No data validator set.');
79+
}
80+
81+
return $this->_dataValidator;
82+
}
83+
84+
/**
85+
* @return bool
86+
*/
87+
public function hasDataValidator()
88+
{
89+
return $this->_dataValidator instanceof ValidatorInterface;
90+
}
91+
92+
/**
93+
* @param $value
94+
*/
95+
protected function validate($value)
96+
{
97+
if (!is_object($value)) {
98+
$this->error(static::ERROR_INVALID_VALUE);
99+
return;
100+
}
101+
102+
$object = new StandardObject($value);
103+
104+
if (!$object->has(Document::DATA)) {
105+
$this->error(static::ERROR_MISSING_DATA);
106+
return;
107+
}
108+
109+
if ($this->hasDataValidator()) {
110+
$this->validateData($object->get(Document::DATA));
111+
}
112+
}
113+
114+
/**
115+
* @param $data
116+
* @return $this
117+
*/
118+
protected function validateData($data)
119+
{
120+
$validator = $this->getDataValidator();
121+
122+
if (!$validator->isValid($data)) {
123+
$this->getErrors()
124+
->merge($validator
125+
->getErrors()
126+
->setSourcePointer(function ($current) {
127+
return '/data' . $current;
128+
}));
129+
}
130+
131+
return $this;
132+
}
133+
}

src/Validator/Resource/AbstractResourceValidator.php

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020

2121
use CloudCreativity\JsonApi\Contracts\Validator\ValidatorInterface;
2222
use CloudCreativity\JsonApi\Error\ErrorObject;
23-
use CloudCreativity\JsonApi\Object\Resource\Resource;
23+
use CloudCreativity\JsonApi\Object\Resource\ResourceObject;
2424
use CloudCreativity\JsonApi\Object\StandardObject;
2525
use CloudCreativity\JsonApi\Validator\AbstractValidator;
2626

@@ -182,18 +182,18 @@ protected function validate($value)
182182
*/
183183
protected function validateType(StandardObject $object)
184184
{
185-
if (!$object->has(Resource::TYPE)) {
185+
if (!$object->has(ResourceObject::TYPE)) {
186186
$this->error(static::ERROR_MISSING_TYPE);
187187
return $this;
188188
}
189189

190190
$type = $this->getTypeValidator();
191191

192-
if (!$type->isValid($object->get(Resource::TYPE))) {
192+
if (!$type->isValid($object->get(ResourceObject::TYPE))) {
193193
$this->getErrors()
194194
->merge($type
195195
->getErrors()
196-
->setSourcePointer('/' . Resource::TYPE));
196+
->setSourcePointer('/' . ResourceObject::TYPE));
197197
}
198198

199199
return $this;
@@ -206,25 +206,25 @@ protected function validateType(StandardObject $object)
206206
protected function validateId(StandardObject $object)
207207
{
208208
// Is valid if no id and $this does not have an id validator.
209-
if (!$object->has(Resource::ID) && !$this->hasIdValidator()) {
209+
if (!$object->has(ResourceObject::ID) && !$this->hasIdValidator()) {
210210
return $this;
211211
}
212212

213-
if (!$object->has(Resource::ID) && $this->hasIdValidator()) {
213+
if (!$object->has(ResourceObject::ID) && $this->hasIdValidator()) {
214214
$this->error(static::ERROR_MISSING_ID);
215215
return $this;
216-
} elseif ($object->has(Resource::ID) && !$this->hasIdValidator()) {
217-
$this->error(static::ERROR_UNEXPECTED_ID, '/' . Resource::ID);
216+
} elseif ($object->has(ResourceObject::ID) && !$this->hasIdValidator()) {
217+
$this->error(static::ERROR_UNEXPECTED_ID, '/' . ResourceObject::ID);
218218
return $this;
219219
}
220220

221221
$validator = $this->getIdValidator();
222222

223-
if (!$validator->isValid($object->get(Resource::ID))) {
223+
if (!$validator->isValid($object->get(ResourceObject::ID))) {
224224
$this->getErrors()
225225
->merge($validator
226226
->getErrors()
227-
->setSourcePointer('/' . Resource::ID));
227+
->setSourcePointer('/' . ResourceObject::ID));
228228
}
229229

230230
return $this;
@@ -237,26 +237,26 @@ protected function validateId(StandardObject $object)
237237
protected function validateAttributes(StandardObject $object)
238238
{
239239
// valid if the object does not have attributes, and attributes are not expected.
240-
if (!$object->has(Resource::ATTRIBUTES) && !$this->isExpectingAttributes()) {
240+
if (!$object->has(ResourceObject::ATTRIBUTES) && !$this->isExpectingAttributes()) {
241241
return $this;
242242
}
243243

244-
if (!$object->has(Resource::ATTRIBUTES) && $this->isExpectingAttributes()) {
244+
if (!$object->has(ResourceObject::ATTRIBUTES) && $this->isExpectingAttributes()) {
245245
$this->error(static::ERROR_MISSING_ATTRIBUTES);
246246
return $this;
247-
} elseif ($object->has(Resource::ATTRIBUTES) && !$this->hasAttributesValidator()) {
248-
$this->error(static::ERROR_UNEXPECTED_ATTRIBUTES, '/' . Resource::ATTRIBUTES);
247+
} elseif ($object->has(ResourceObject::ATTRIBUTES) && !$this->hasAttributesValidator()) {
248+
$this->error(static::ERROR_UNEXPECTED_ATTRIBUTES, '/' . ResourceObject::ATTRIBUTES);
249249
return $this;
250250
}
251251

252252
$validator = $this->getAttributesValidator();
253253

254-
if (!$validator->isValid($object->get(Resource::ATTRIBUTES))) {
254+
if (!$validator->isValid($object->get(ResourceObject::ATTRIBUTES))) {
255255
$this->getErrors()
256256
->merge($validator
257257
->getErrors()
258258
->setSourcePointer(function ($current) {
259-
return sprintf('/%s%s', Resource::ATTRIBUTES, $current);
259+
return sprintf('/%s%s', ResourceObject::ATTRIBUTES, $current);
260260
}));
261261
}
262262

@@ -270,26 +270,26 @@ protected function validateAttributes(StandardObject $object)
270270
protected function validateRelationships(StandardObject $object)
271271
{
272272
// valid if no relationships and not expecting relationships
273-
if (!$object->has(Resource::RELATIONSHIPS) && !$this->isExpectingRelationships()) {
273+
if (!$object->has(ResourceObject::RELATIONSHIPS) && !$this->isExpectingRelationships()) {
274274
return $this;
275275
}
276276

277-
if (!$object->has(Resource::RELATIONSHIPS) && $this->isExpectingRelationships()) {
277+
if (!$object->has(ResourceObject::RELATIONSHIPS) && $this->isExpectingRelationships()) {
278278
$this->error(static::ERROR_MISSING_RELATIONSHIPS);
279279
return $this;
280-
} elseif ($object->has(Resource::RELATIONSHIPS) && !$this->hasRelationshipsValidator()) {
281-
$this->error(static::ERROR_UNEXPECTED_RELATIONSHIPS, '/' . Resource::RELATIONSHIPS);
280+
} elseif ($object->has(ResourceObject::RELATIONSHIPS) && !$this->hasRelationshipsValidator()) {
281+
$this->error(static::ERROR_UNEXPECTED_RELATIONSHIPS, '/' . ResourceObject::RELATIONSHIPS);
282282
return $this;
283283
}
284284

285285
$validator = $this->getRelationshipsValidator();
286286

287-
if (!$validator->isValid($object->get(Resource::RELATIONSHIPS))) {
287+
if (!$validator->isValid($object->get(ResourceObject::RELATIONSHIPS))) {
288288
$this->getErrors()
289289
->merge($validator
290290
->getErrors()
291291
->setSourcePointer(function ($current) {
292-
return sprintf('/%s%s', Resource::RELATIONSHIPS, $current);
292+
return sprintf('/%s%s', ResourceObject::RELATIONSHIPS, $current);
293293
}));
294294
}
295295

0 commit comments

Comments
 (0)