Skip to content

Commit 266d153

Browse files
authored
Improve member names validation (#70)
1 parent 62e564f commit 266d153

28 files changed

+246
-421
lines changed

.travis.yml

-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
language: php
22
php:
3-
- '7.0'
43
- '7.1'
54
- '7.2'
65

composer.json

+5-2
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
}
1212
],
1313
"require": {
14-
"php": ">=7.0"
14+
"php": ">=7.1"
1515
},
1616
"require-dev": {
1717
"phpunit/phpunit": "^6.0",
@@ -21,7 +21,10 @@
2121
"autoload": {
2222
"psr-4": {
2323
"JsonApiPhp\\JsonApi\\": "src/"
24-
}
24+
},
25+
"files": [
26+
"src/functions.php"
27+
]
2528
},
2629
"autoload-dev": {
2730
"psr-4": {

src/Document.php

+16-21
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33

44
namespace JsonApiPhp\JsonApi;
55

6+
use JsonApiPhp\JsonApi\Document\Container;
67
use JsonApiPhp\JsonApi\Document\Error;
78
use JsonApiPhp\JsonApi\Document\LinksTrait;
8-
use JsonApiPhp\JsonApi\Document\Meta;
99
use JsonApiPhp\JsonApi\Document\MetaTrait;
1010
use JsonApiPhp\JsonApi\Document\PrimaryData\MultiIdentifierData;
1111
use JsonApiPhp\JsonApi\Document\PrimaryData\MultiResourceData;
@@ -16,7 +16,7 @@
1616
use JsonApiPhp\JsonApi\Document\Resource\ResourceIdentifier;
1717
use JsonApiPhp\JsonApi\Document\Resource\ResourceObject;
1818

19-
class Document implements \JsonSerializable
19+
final class Document implements \JsonSerializable
2020
{
2121
const MEDIA_TYPE = 'application/vnd.api+json';
2222
const DEFAULT_API_VERSION = '1.0';
@@ -46,7 +46,7 @@ private function __construct()
4646
{
4747
}
4848

49-
public static function fromMeta(Meta $meta): self
49+
public static function fromMeta(iterable $meta): self
5050
{
5151
$doc = new self;
5252
$doc->setMeta($meta);
@@ -100,12 +100,12 @@ public function setApiVersion(string $version = self::DEFAULT_API_VERSION)
100100
$this->api['version'] = $version;
101101
}
102102

103-
public function setApiMeta(Meta $meta)
103+
public function setApiMeta(iterable $meta): void
104104
{
105-
$this->api['meta'] = $meta;
105+
$this->api['meta'] = new Container($meta);
106106
}
107107

108-
public function setIncluded(ResourceObject ...$resources)
108+
public function setIncluded(ResourceObject ...$resources): void
109109
{
110110
if (null === $this->data) {
111111
throw new \LogicException('Document with no data cannot contain included resources');
@@ -118,30 +118,25 @@ public function setIncluded(ResourceObject ...$resources)
118118
}
119119
}
120120

121-
public function markSparse()
121+
public function markSparse(): void
122122
{
123123
$this->sparse = true;
124124
}
125125

126126
public function jsonSerialize()
127127
{
128128
$this->enforceFullLinkage();
129-
return array_filter(
130-
[
131-
'data' => $this->data,
132-
'errors' => $this->errors,
133-
'meta' => $this->meta,
134-
'jsonapi' => $this->api,
135-
'links' => $this->links,
136-
'included' => $this->included ? array_values($this->included) : null,
137-
],
138-
function ($v) {
139-
return null !== $v;
140-
}
141-
);
129+
return filterNulls([
130+
'data' => $this->data,
131+
'errors' => $this->errors,
132+
'meta' => $this->meta,
133+
'jsonapi' => $this->api,
134+
'links' => $this->links,
135+
'included' => $this->included ? array_values($this->included) : null,
136+
]);
142137
}
143138

144-
private function enforceFullLinkage()
139+
private function enforceFullLinkage(): void
145140
{
146141
if ($this->sparse || empty($this->included)) {
147142
return;

src/Document/Container.php

+14-8
Original file line numberDiff line numberDiff line change
@@ -3,25 +3,31 @@
33

44
namespace JsonApiPhp\JsonApi\Document;
55

6-
class Container implements \JsonSerializable, \IteratorAggregate
6+
use function JsonApiPhp\JsonApi\isValidMemberName;
7+
8+
final class Container implements \JsonSerializable
79
{
810
private $data;
911

10-
public function set(MemberName $name, $value)
12+
public function __construct(iterable $data = null)
1113
{
12-
if (! $this->data) {
13-
$this->data = (object) [];
14+
if ($data) {
15+
foreach ($data as $k => $v) {
16+
$this->set((string) $k, $v);
17+
}
1418
}
15-
$this->data->$name = $value;
1619
}
1720

18-
public function getIterator(): \Traversable
21+
public function set(string $name, $value)
1922
{
20-
return $this->data;
23+
if (! isValidMemberName($name)) {
24+
throw new \OutOfBoundsException("Invalid member name '$name'");
25+
}
26+
$this->data[$name] = $value;
2127
}
2228

2329
public function jsonSerialize()
2430
{
25-
return $this->data;
31+
return (object) $this->data;
2632
}
2733
}

src/Document/Error.php

+12-15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33

44
namespace JsonApiPhp\JsonApi\Document;
55

6+
use function JsonApiPhp\JsonApi\filterNulls;
7+
68
final class Error implements \JsonSerializable
79
{
810
use MetaTrait;
@@ -65,20 +67,15 @@ public function setSourceParameter(string $parameter)
6567

6668
public function jsonSerialize()
6769
{
68-
return array_filter(
69-
[
70-
'id' => $this->id,
71-
'links' => $this->links,
72-
'status' => $this->status,
73-
'code' => $this->code,
74-
'title' => $this->title,
75-
'detail' => $this->detail,
76-
'source' => $this->source,
77-
'meta' => $this->meta,
78-
],
79-
function ($v) {
80-
return null !== $v;
81-
}
82-
) ?: (object) [];
70+
return filterNulls([
71+
'id' => $this->id,
72+
'links' => $this->links,
73+
'status' => $this->status,
74+
'code' => $this->code,
75+
'title' => $this->title,
76+
'detail' => $this->detail,
77+
'source' => $this->source,
78+
'meta' => $this->meta,
79+
]) ?: (object) [];
8380
}
8481
}

src/Document/Link/Link.php

-19
This file was deleted.

src/Document/Link/LinkInterface.php

-9
This file was deleted.

src/Document/Link/LinkObject.php

-24
This file was deleted.

src/Document/LinksTrait.php

+4-20
Original file line numberDiff line numberDiff line change
@@ -3,32 +3,16 @@
33

44
namespace JsonApiPhp\JsonApi\Document;
55

6-
use JsonApiPhp\JsonApi\Document\Link\Link;
7-
use JsonApiPhp\JsonApi\Document\Link\LinkInterface;
8-
96
trait LinksTrait
107
{
118
/**
12-
* @var Container|null
9+
* @var Container
1310
*/
1411
protected $links;
1512

16-
public function setLink(string $name, string $url)
17-
{
18-
$this->init();
19-
$this->links->set(new MemberName($name), new Link($url));
20-
}
21-
22-
public function setLinkObject(string $name, LinkInterface $link)
23-
{
24-
$this->init();
25-
$this->links->set(new MemberName($name), $link);
26-
}
27-
28-
private function init()
13+
public function setLink(string $name, string $url, iterable $meta = null)
2914
{
30-
if (! $this->links) {
31-
$this->links = new Container();
32-
}
15+
$this->links = $this->links ?: new Container();
16+
$this->links->set($name, $meta ? ['meta' => new Container($meta), 'href' => $url] : $url);
3317
}
3418
}

src/Document/MemberName.php

-12
This file was deleted.

src/Document/Meta.php

-67
This file was deleted.

src/Document/MetaTrait.php

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ trait MetaTrait
77
{
88
protected $meta;
99

10-
public function setMeta(Meta $meta)
10+
public function setMeta(iterable $meta): void
1111
{
12-
$this->meta = $meta;
12+
$this->meta = new Container($meta);
1313
}
1414
}

src/Document/ReservedName.php

-20
This file was deleted.

0 commit comments

Comments
 (0)