1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
declare(strict_types=1); |
4
|
|
|
|
5
|
|
|
namespace WebServCo\Api\JsonApi; |
6
|
|
|
|
7
|
|
|
use WebServCo\Api\JsonApi\Interfaces\ResourceObjectInterface; |
8
|
|
|
|
9
|
|
|
class Document implements \WebServCo\Framework\Interfaces\JsonInterface |
10
|
|
|
{ |
11
|
|
|
public const CONTENT_TYPE = 'application/vnd.api+json'; |
12
|
|
|
public const VERSION = '1.0'; |
13
|
|
|
|
14
|
|
|
/** |
15
|
|
|
* Meta. |
16
|
|
|
* |
17
|
|
|
* @var array<string,mixed> |
18
|
|
|
*/ |
19
|
|
|
protected array $meta; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* JSON API |
23
|
|
|
* |
24
|
|
|
* @var array<string,string> |
25
|
|
|
*/ |
26
|
|
|
protected array $jsonapi; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Data. |
30
|
|
|
* |
31
|
|
|
* @var array<int,\WebServCo\Api\JsonApi\Interfaces\ResourceObjectInterface> |
32
|
|
|
*/ |
33
|
|
|
protected array $data; |
34
|
|
|
|
35
|
|
|
/** |
36
|
|
|
* Errors. |
37
|
|
|
* |
38
|
|
|
* @var array<int,\WebServCo\Api\JsonApi\Error> |
39
|
|
|
*/ |
40
|
|
|
protected array $errors; |
41
|
|
|
|
42
|
|
|
protected int $statusCode; |
43
|
|
|
|
44
|
|
|
protected bool $useDataItemCollection; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* https://jsonapi.org/format/#document-top-level |
48
|
|
|
* |
49
|
|
|
* Primary data MUST be either: |
50
|
|
|
* - a single resource object, a single resource identifier object, or null, |
51
|
|
|
* for requests that target single resources |
52
|
|
|
* - an array of resource objects, an array of resource identifier objects, or an empty array ([]), |
53
|
|
|
* for requests that target resource collections |
54
|
|
|
*/ |
55
|
|
|
public function __construct(bool $useDataItemCollection = false) |
56
|
|
|
{ |
57
|
|
|
$this->meta = []; |
58
|
|
|
$this->jsonapi = ['version' => self::VERSION]; |
59
|
|
|
$this->data = []; |
60
|
|
|
$this->errors = []; |
61
|
|
|
$this->statusCode = 200; |
62
|
|
|
$this->useDataItemCollection = $useDataItemCollection; |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
public function getStatusCode(): int |
66
|
|
|
{ |
67
|
|
|
return $this->statusCode; |
68
|
|
|
} |
69
|
|
|
|
70
|
|
|
public function setData(ResourceObjectInterface $resourceObject): bool |
71
|
|
|
{ |
72
|
|
|
$this->data[] = $resourceObject; |
73
|
|
|
return true; |
74
|
|
|
} |
75
|
|
|
|
76
|
|
|
public function setError(Error $error): bool |
77
|
|
|
{ |
78
|
|
|
$this->errors[] = $error; |
79
|
|
|
$this->statusCode = $error->getStatus(); // set status code of last error. |
80
|
|
|
return true; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* @param mixed $value |
85
|
|
|
*/ |
86
|
|
|
public function setMeta(string $key, $value): bool |
87
|
|
|
{ |
88
|
|
|
$this->meta[$key] = $value; |
89
|
|
|
return true; |
90
|
|
|
} |
91
|
|
|
|
92
|
|
|
public function setStatusCode(int $statusCode): bool |
93
|
|
|
{ |
94
|
|
|
$this->statusCode = $statusCode; |
95
|
|
|
return true; |
96
|
|
|
} |
97
|
|
|
|
98
|
|
|
/** |
99
|
|
|
* @return array<string,mixed> |
100
|
|
|
*/ |
101
|
|
|
public function toArray(): array |
102
|
|
|
{ |
103
|
|
|
$array = [ |
104
|
|
|
'jsonapi' => $this->jsonapi, |
105
|
|
|
]; |
106
|
|
|
if (!empty($this->errors)) { |
107
|
|
|
foreach ($this->errors as $error) { |
108
|
|
|
$array['errors'][] = $error->toArray(); |
109
|
|
|
} |
110
|
|
|
} else { |
111
|
|
|
if ($this->useDataItemCollection) { |
112
|
|
|
$array['data'] = []; |
113
|
|
|
foreach ($this->data as $item) { |
114
|
|
|
$array['data'][] = $item->toArray(); |
115
|
|
|
} |
116
|
|
|
} else { |
117
|
|
|
$array['data'] = \array_key_exists(0, $this->data) |
118
|
|
|
? $this->data[0]->toArray() // one item |
119
|
|
|
: null; // no data |
120
|
|
|
} |
121
|
|
|
} |
122
|
|
|
if ($this->meta) { |
|
|
|
|
123
|
|
|
$array['meta'] = $this->meta; |
124
|
|
|
} |
125
|
|
|
return $array; |
126
|
|
|
} |
127
|
|
|
|
128
|
|
|
public function toJson(int $flags = 0): string |
129
|
|
|
{ |
130
|
|
|
$array = $this->toArray(); |
131
|
|
|
return (string) \json_encode($array, $flags); |
132
|
|
|
} |
133
|
|
|
} |
134
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.