Skip to content

Commit 0b11318

Browse files
committed
Add decoders, exceptions and some contracts.
1 parent 92e78ec commit 0b11318

12 files changed

+325
-30
lines changed
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Contracts\Error;
4+
use Neomerx\JsonApi\Contracts\Document\ErrorInterface;
5+
6+
interface ErrorCollectionInterface extends \Traversable, \Countable
7+
{
8+
9+
/**
10+
* @param ErrorInterface $error
11+
* @return $this
12+
*/
13+
public function add(ErrorInterface $error);
14+
15+
/**
16+
* @param ErrorInterface[] $errors
17+
* @return $this
18+
*/
19+
public function addMany(array $errors);
20+
21+
/**
22+
* @return ErrorInterface[]
23+
*/
24+
public function getAll();
25+
26+
/**
27+
* @return string
28+
*/
29+
public function getStatus();
30+
31+
/**
32+
* @param string|\Closure $pointer
33+
* @return $this
34+
*/
35+
public function setSourcePointer($pointer);
36+
37+
/**
38+
* @return bool
39+
*/
40+
public function isEmpty();
41+
42+
/**
43+
* @return $this
44+
*/
45+
public function clear();
46+
47+
/**
48+
* @param ErrorCollectionInterface $errors
49+
* @return $this
50+
*/
51+
public function merge(ErrorCollectionInterface $errors);
52+
53+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Contracts\Error;
4+
5+
interface ErrorsAwareInterface
6+
{
7+
8+
/**
9+
* @return ErrorCollectionInterface
10+
*/
11+
public function getErrors();
12+
}

src/Contracts/Validator/ValidatorInterface.php

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,14 @@
22

33
namespace CloudCreativity\JsonApi\Contracts\Validator;
44

5-
use CloudCreativity\JsonApi\Error\ErrorCollection;
5+
use CloudCreativity\JsonApi\Contracts\Error\ErrorsAwareInterface;
66

7-
interface ValidatorInterface
7+
interface ValidatorInterface extends ErrorsAwareInterface
88
{
99

1010
/**
1111
* @param mixed $value
1212
* @return bool
1313
*/
1414
public function isValid($value);
15-
16-
/**
17-
* @return ErrorCollection
18-
*/
19-
public function getErrors();
2015
}

src/Decoders/AbstractDecoder.php

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Decoders;
4+
5+
use CloudCreativity\JsonApi\Error\ErrorException;
6+
use CloudCreativity\JsonApi\Error\ErrorObject;
7+
use Neomerx\JsonApi\Contracts\Decoder\DecoderInterface;
8+
9+
abstract class AbstractDecoder implements DecoderInterface
10+
{
11+
12+
const ERROR_INVALID_JSON = 'invalid-json';
13+
14+
/**
15+
* @param $content
16+
* @param bool|false $assoc
17+
* @param int $depth
18+
* @param int $options
19+
* @return mixed
20+
*/
21+
public function parseJson($content, $assoc = false, $depth = 512, $options = 0)
22+
{
23+
$parsed = json_decode($content, $assoc, $depth, $options);
24+
25+
if (JSON_ERROR_NONE !== json_last_error()) {
26+
$error = new ErrorObject([
27+
ErrorObject::TITLE => 'Invalid JSON',
28+
ErrorObject::DETAIL => 'Request body content could not be parsed as JSON: ' . json_last_error_msg(),
29+
ErrorObject::CODE => static::ERROR_INVALID_JSON,
30+
ErrorObject::STATUS => 400,
31+
]);
32+
33+
throw new ErrorException($error);
34+
}
35+
36+
return $parsed;
37+
}
38+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Decoders;
4+
5+
use CloudCreativity\JsonApi\Error\MultiErrorException;
6+
use CloudCreativity\JsonApi\Object\Relationships\Relationship;
7+
use CloudCreativity\JsonApi\Validator\ValidatorAwareTrait;
8+
9+
class RelationshipDecoder extends AbstractDecoder
10+
{
11+
12+
use ValidatorAwareTrait;
13+
14+
/**
15+
* @param string $content
16+
* @return Relationship
17+
* @throws MultiErrorException
18+
*/
19+
public function decode($content)
20+
{
21+
$content = $this->parseJson($content);
22+
$validator = $this->getValidator();
23+
24+
if (!$validator->isValid($content)) {
25+
throw new MultiErrorException($validator->getErrors(), 'Invalid request body content.');
26+
}
27+
28+
return new Relationship($content);
29+
}
30+
}

src/Decoders/ResourceDecoder.php

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Decoders;
4+
5+
use CloudCreativity\JsonApi\Error\MultiErrorException;
6+
use CloudCreativity\JsonApi\Object\Resource\Resource;
7+
use CloudCreativity\JsonApi\Validator\ValidatorAwareTrait;
8+
9+
class ResourceDecoder extends AbstractDecoder
10+
{
11+
12+
use ValidatorAwareTrait;
13+
14+
/**
15+
* @param string $content
16+
* @return Resource
17+
* @throws MultiErrorException
18+
*/
19+
public function decode($content)
20+
{
21+
$content = $this->parseJson($content);
22+
$validator = $this->getValidator();
23+
24+
if (!$validator->isValid($content)) {
25+
throw new MultiErrorException($validator->getErrors(), 'Invalid request body content.');
26+
}
27+
28+
return new Resource($content);
29+
}
30+
}

src/Error/ErrorCollection.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@
22

33
namespace CloudCreativity\JsonApi\Error;
44

5+
use CloudCreativity\JsonApi\Contracts\Error\ErrorCollectionInterface;
56
use Neomerx\JsonApi\Contracts\Document\ErrorInterface;
67

7-
class ErrorCollection implements \IteratorAggregate, \Countable
8+
class ErrorCollection implements \IteratorAggregate, ErrorCollectionInterface
89
{
910

1011
/**
@@ -84,14 +85,14 @@ public function error($error)
8485
}
8586

8687
/**
87-
* @param ErrorCollection $errors
88+
* @param ErrorCollectionInterface $errors
8889
* @return $this
8990
*/
90-
public function merge(ErrorCollection $errors)
91+
public function merge(ErrorCollectionInterface $errors)
9192
{
92-
$clone = clone $errors;
93-
94-
$this->_stack = array_merge($this->_stack, $clone->_stack);
93+
foreach ($errors as $error) {
94+
$this->add(clone $error);
95+
}
9596

9697
return $this;
9798
}

src/Error/ErrorException.php

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Error;
4+
5+
use CloudCreativity\JsonApi\Contracts\Error\ErrorsAwareInterface;
6+
use Neomerx\JsonApi\Contracts\Document\ErrorInterface;
7+
8+
class ErrorException extends \RuntimeException implements ErrorsAwareInterface
9+
{
10+
11+
/**
12+
* @var ErrorInterface
13+
*/
14+
protected $_error;
15+
16+
/**
17+
* @param ErrorInterface $error
18+
* @param \Exception|null $previous
19+
*/
20+
public function __construct(ErrorInterface $error, \Exception $previous = null)
21+
{
22+
parent::__construct($error->getTitle(), $error->getCode(), $previous);
23+
24+
$this->_error = $error;
25+
}
26+
27+
/**
28+
* @return ErrorInterface
29+
*/
30+
public function getError()
31+
{
32+
return $this->_error;
33+
}
34+
35+
/**
36+
* @return ErrorCollection
37+
*/
38+
public function getErrors()
39+
{
40+
return new ErrorCollection([$this->getError()]);
41+
}
42+
}

src/Error/ErrorsAwareTrait.php

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Error;
4+
5+
use CloudCreativity\JsonApi\Contracts\Error\ErrorCollectionInterface;
6+
7+
trait ErrorsAwareTrait
8+
{
9+
10+
/**
11+
* @var ErrorCollectionInterface|null
12+
*/
13+
protected $_errors;
14+
15+
/**
16+
* @param ErrorCollectionInterface $errors
17+
* @return $this
18+
*/
19+
public function setErrors(ErrorCollectionInterface $errors)
20+
{
21+
$this->_errors = $errors;
22+
23+
return $this;
24+
}
25+
26+
/**
27+
* @return ErrorCollectionInterface
28+
*/
29+
public function getErrors()
30+
{
31+
if (!$this->_errors instanceof ErrorCollectionInterface) {
32+
$this->_errors = new ErrorCollection();
33+
}
34+
35+
return $this->_errors;
36+
}
37+
}

src/Error/MultiErrorException.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace CloudCreativity\JsonApi\Error;
4+
5+
use CloudCreativity\JsonApi\Contracts\Error\ErrorCollectionInterface;
6+
use CloudCreativity\JsonApi\Contracts\Error\ErrorsAwareInterface;
7+
8+
class MultiErrorException extends \RuntimeException implements ErrorsAwareInterface
9+
{
10+
11+
/**
12+
* @var ErrorCollectionInterface
13+
*/
14+
protected $_errors;
15+
16+
/**
17+
* @param ErrorCollectionInterface $errors
18+
* @param $message
19+
* @param \Exception|null $previous
20+
*/
21+
public function __construct(ErrorCollectionInterface $errors, $message = null, \Exception $previous = null)
22+
{
23+
parent::__construct($message, null, $previous);
24+
25+
$this->_errors = $errors;
26+
}
27+
28+
/**
29+
* @return ErrorCollectionInterface
30+
*/
31+
public function getErrors()
32+
{
33+
return $this->_errors;
34+
}
35+
}

0 commit comments

Comments
 (0)