Passed
Pull Request — main (#53)
by Lode
03:33
created

ResourceIdentifierObject::toArray()   A

Complexity

Conditions 5
Paths 6

Size

Total Lines 17
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 5

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 5
eloc 9
c 2
b 0
f 1
nc 6
nop 0
dl 0
loc 17
ccs 10
cts 10
cp 1
crap 5
rs 9.6111
1
<?php
2
3
namespace alsvanzelf\jsonapi\objects;
4
5
use alsvanzelf\jsonapi\exceptions\Exception;
6
use alsvanzelf\jsonapi\exceptions\DuplicateException;
7
use alsvanzelf\jsonapi\helpers\AtMemberManager;
8
use alsvanzelf\jsonapi\helpers\Validator;
9
use alsvanzelf\jsonapi\interfaces\ObjectInterface;
10
use alsvanzelf\jsonapi\interfaces\ResourceInterface;
11
use alsvanzelf\jsonapi\objects\MetaObject;
12
13
class ResourceIdentifierObject implements ObjectInterface, ResourceInterface {
14
	use AtMemberManager;
15
	
16
	/** @var string */
17
	protected $type;
18
	/** @var string */
19
	protected $id;
20
	/** @var string */
21
	protected $lid;
22
	/** @var MetaObject */
23
	protected $meta;
24
	/** @var Validator */
25
	protected $validator;
26
	
27
	/**
28
	 * @note $type and $id are optional to pass during construction
29
	 *       however they are required for a valid ResourceIdentifierObject
30
	 *       so use ->setType() and ->setId() if not passing them during construction
31
	 * 
32
	 * @param string     $type optional
33
	 * @param string|int $id   optional
34
	 */
35 89
	public function __construct($type=null, $id=null) {
36 89
		$this->validator = new Validator();
37
		
38 89
		if ($type !== null) {
39 75
			$this->setType($type);
40
		}
41 89
		if ($id !== null) {
42 70
			$this->setId($id);
43
		}
44
		
45
		// always mark as used, as these keys are reserved
46 89
		$this->validator->claimUsedFields($fieldNames=['type'], Validator::OBJECT_CONTAINER_TYPE);
47 89
		$this->validator->claimUsedFields($fieldNames=['id'], Validator::OBJECT_CONTAINER_ID);
48 89
		$this->validator->claimUsedFields($fieldNames=['lid'], Validator::OBJECT_CONTAINER_LID);
49 89
	}
50
	
51
	/**
52
	 * human api
53
	 */
54
	
55
	/**
56
	 * @param string $key
57
	 * @param mixed  $value
58
	 */
59 7
	public function addMeta($key, $value) {
60 7
		if ($this->meta === null) {
61 7
			$this->setMetaObject(new MetaObject());
62
		}
63
		
64 7
		$this->meta->add($key, $value);
65 7
	}
66
	
67
	/**
68
	 * spec api
69
	 */
70
	
71
	/**
72
	 * @param string $type
73
	 */
74 81
	public function setType($type) {
75 81
		$this->type = $type;
76 81
	}
77
	
78
	/**
79
	 * @param string|int $id will be casted to a string
80
	 * 
81
	 * @throws DuplicateException if localId is already set
82
	 */
83 74
	public function setId($id) {
84 74
		if ($this->lid !== null) {
85 1
			throw new DuplicateException('id is not allowed when localId is already set');
86
		}
87
		
88 73
		$this->id = (string) $id;
89 73
	}
90
	
91
	/**
92
	 * set a local id to connect resources to each other when created on the client
93
	 * 
94
	 * @note this should not be used to send back from the server to the client
95
	 * 
96
	 * @param string|int $localId will be casted to a string
97
	 * 
98
	 * @throws DuplicateException if normal id is already set
99
	 */
100 5
	public function setLocalId($localId) {
101 5
		if ($this->id !== null) {
102 1
			throw new DuplicateException('localId is not allowed when id is already set');
103
		}
104
		
105 4
		$this->lid = (string) $localId;
106 4
	}
107
	
108
	/**
109
	 * @param MetaObject $metaObject
110
	 */
111 8
	public function setMetaObject(MetaObject $metaObject) {
112 8
		$this->meta = $metaObject;
113 8
	}
114
	
115
	/**
116
	 * internal api
117
	 */
118
	
119
	/**
120
	 * @internal
121
	 * 
122
	 * @param  ResourceObject $resourceObject
123
	 * @return ResourceIdentifierObject
124
	 */
125 35
	public static function fromResourceObject(ResourceObject $resourceObject) {
126 35
		$resourceIdentifierObject = new self($resourceObject->type, $resourceObject->primaryId());
127
		
128 35
		if ($resourceObject->meta !== null) {
129 2
			$resourceIdentifierObject->setMetaObject($resourceObject->meta);
130
		}
131
		
132 35
		return $resourceIdentifierObject;
133
	}
134
	
135
	/**
136
	 * @internal
137
	 * 
138
	 * @param  ResourceInterface $resource
139
	 * @return boolean
140
	 * 
141
	 * @throws Exception if one or both are missing identification
142
	 */
143 23
	public function equals(ResourceInterface $resource) {
144 23
		if ($this->hasIdentification() === false || $resource->getResource()->hasIdentification() === false) {
145 1
			throw new Exception('can not compare resources if identification is missing');
146
		}
147
		
148 22
		return ($this->getIdentificationKey() === $resource->getResource()->getIdentificationKey());
149
	}
150
	
151
	/**
152
	 * @internal
153
	 * 
154
	 * @return boolean
155
	 */
156 44
	public function hasIdentification() {
157 44
		return ($this->type !== null && $this->primaryId() !== null);
158
	}
159
	
160
	/**
161
	 * get a key to uniquely define this resource
162
	 * 
163
	 * @internal
164
	 * 
165
	 * @return string
166
	 * 
167
	 * @throws Exception if type or id is not set yet
168
	 */
169 41
	public function getIdentificationKey() {
170 41
		if ($this->hasIdentification() === false) {
171 2
			throw new Exception('resource has no identification yet');
172
		}
173
		
174 39
		return $this->type.'|'.$this->primaryId();
175
	}
176
	
177
	/**
178
	 * ObjectInterface
179
	 */
180
	
181
	/**
182
	 * @inheritDoc
183
	 */
184 44
	public function isEmpty() {
185 44
		if ($this->type !== null || $this->primaryId() !== null) {
1 ignored issue
show
introduced by
The condition $this->primaryId() !== null is always true.
Loading history...
186 36
			return false;
187
		}
188 9
		if ($this->meta !== null && $this->meta->isEmpty() === false) {
189 1
			return false;
190
		}
191 8
		if ($this->hasAtMembers()) {
192 1
			return false;
193
		}
194
		
195 8
		return true;
196
	}
197
	
198
	/**
199
	 * @inheritDoc
200
	 */
201 62
	public function toArray() {
202 62
		$array = $this->getAtMembers();
203
		
204 62
		$array['type'] = $this->type;
205
		
206 62
		if ($this->id !== null) {
207 54
			$array['id'] = $this->id;
208
		}
209 10
		elseif ($this->lid !== null) {
210 2
			$array['lid'] = $this->lid;
211
		}
212
		
213 62
		if ($this->meta !== null && $this->meta->isEmpty() === false) {
214 7
			$array['meta'] = $this->meta->toArray();
215
		}
216
		
217 62
		return $array;
218
	}
219
	
220
	/**
221
	 * ResourceInterface
222
	 */
223
	
224
	/**
225
	 * @inheritDoc
226
	 */
227 9
	public function getResource($identifierOnly=false) {
228 9
		return $this;
229
	}
230
	
231
	/**
232
	 * @internal
233
	 */
234
	
235 62
	private function primaryId() {
236 62
		if ($this->lid !== null) {
237 2
			return $this->lid;
238
		}
239
		
240 60
		return $this->id;
241
	}
242
}
243