Test Failed
Pull Request — main (#64)
by Lode
08:15
created

ResourceObject::getResource()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 7
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
1
<?php
2
3
namespace alsvanzelf\jsonapi\objects;
4
5
use alsvanzelf\jsonapi\CollectionDocument;
6
use alsvanzelf\jsonapi\exceptions\DuplicateException;
7
use alsvanzelf\jsonapi\helpers\Converter;
8
use alsvanzelf\jsonapi\helpers\LinksManager;
9
use alsvanzelf\jsonapi\helpers\Validator;
10
use alsvanzelf\jsonapi\interfaces\RecursiveResourceContainerInterface;
11
use alsvanzelf\jsonapi\interfaces\ResourceInterface;
12
use alsvanzelf\jsonapi\objects\AttributesObject;
13
use alsvanzelf\jsonapi\objects\RelationshipObject;
14
use alsvanzelf\jsonapi\objects\RelationshipsObject;
15
use alsvanzelf\jsonapi\objects\ResourceIdentifierObject;
16
17
class ResourceObject extends ResourceIdentifierObject implements RecursiveResourceContainerInterface {
0 ignored issues
show
Coding Style introduced by
Missing doc comment for class ResourceObject
Loading history...
18
	use LinksManager;
19
	
20
	/** @var AttributesObject */
21
	protected $attributes;
22
	/** @var RelationshipsObject */
23
	protected $relationships;
24
	/** @var array */
25
	protected static $defaults = [
26
		/**
27
		 * blocks 'type' as a keyword inside attributes or relationships
28
		 * the specification doesn't allow this as 'type' is already set at the root of a resource
29
		 * set to true if migrating to jsonapi and currently using 'type' as attribute or relationship
30
		 */
31
		'enforceTypeFieldNamespace' => true,
32
	];
33
	
34
	/**
35
	 * human api
36
	 */
37
	
38
	/**
39
	 * @note if an `id` is set inside $attributes, it is removed from there
40
	 *       and if $id is null, it is filled with that value
41
	 *       it is common to find it inside, and not doing so will cause an exception
42
	 * 
43
	 * @param  array      $attributes
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
44
	 * @param  string     $type       optional
45
	 * @param  string|int $id         optional
46
	 * @param  array      $options    optional {@see ResourceObject::$defaults}
47
	 * @return ResourceObject
48
	 */
49
	public static function fromArray(array $attributes, $type=null, $id=null, array $options=[]) {
50
		if (isset($attributes['id'])) {
51
			if ($id === null) {
52
				$id = $attributes['id'];
53
			}
54
			
55
			unset($attributes['id']);
56
		}
57
		
58
		$resourceObject = new self($type, $id);
59
		$resourceObject->setAttributesObject(AttributesObject::fromArray($attributes), $options);
60
		
61
		return $resourceObject;
62
	}
63
	
64
	/**
65
	 * @param  object     $attributes
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
66
	 * @param  string     $type       optional
67
	 * @param  string|int $id         optional
68
	 * @param  array      $options    optional {@see ResourceObject::$defaults}
69
	 * @return ResourceObject
70
	 */
71
	public static function fromObject($attributes, $type=null, $id=null, array $options=[]) {
72
		$array = Converter::objectToArray($attributes);
73
		
74
		return self::fromArray($array, $type, $id, $options);
75
	}
76
	
77
	/**
78
	 * add key-value pairs to attributes
79
	 * 
80
	 * @param string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
81
	 * @param mixed  $value
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
82
	 * @param array  $options optional {@see ResourceObject::$defaults}
83
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
84
	public function add($key, $value, array $options=[]) {
85
		$options = array_merge(self::$defaults, $options);
86
		
87
		if ($this->attributes === null) {
88
			$this->attributes = new AttributesObject();
89
		}
90
		
91
		$this->validator->claimUsedFields([$key], Validator::OBJECT_CONTAINER_ATTRIBUTES, $options);
92
		
93
		$this->attributes->add($key, $value);
94
	}
95
	
96
	/**
97
	 * @param  string $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
98
	 * @param  mixed  $relation ResourceInterface | ResourceInterface[] | CollectionDocument
99
	 * @param  array  $links    optional
100
	 * @param  array  $meta     optional
101
	 * @param  array  $options  optional {@see ResourceObject::$defaults}
102
	 * @return RelationshipObject
103
	 */
104
	public function addRelationship($key, $relation, array $links=[], array $meta=[], array $options=[]) {
105
		$relationshipObject = RelationshipObject::fromAnything($relation, $links, $meta);
106
		
107
		$this->addRelationshipObject($key, $relationshipObject, $options);
108
		
109
		return $relationshipObject;
110
	}
111
	
112
	/**
113
	 * @param string $href
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
114
	 * @param array  $meta optional, if given a LinkObject is added, otherwise a link string is added
115
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
116
	public function setSelfLink($href, array $meta=[]) {
117
		$this->addLink('self', $href, $meta);
118
	}
119
	
120
	/**
121
	 * spec api
122
	 */
123
	
124
	/**
125
	 * @param AttributesObject $attributesObject
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
126
	 * @param array            $options          optional {@see ResourceObject::$defaults}
127
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
128
	public function setAttributesObject(AttributesObject $attributesObject, array $options=[]) {
129
		$newKeys = $attributesObject->getKeys();
130
		$this->validator->clearUsedFields(Validator::OBJECT_CONTAINER_ATTRIBUTES);
131
		$this->validator->claimUsedFields($newKeys, Validator::OBJECT_CONTAINER_ATTRIBUTES, $options);
132
		
133
		$this->attributes = $attributesObject;
134
	}
135
	
136
	/**
137
	 * @param string             $key
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
138
	 * @param RelationshipObject $relationshipObject
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
139
	 * @param array              $options            optional {@see ResourceObject::$defaults}
140
	 * 
141
	 * @throws DuplicateException if the resource is contained as a resource in the relationship
142
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
143
	public function addRelationshipObject($key, RelationshipObject $relationshipObject, array $options=[]) {
144
		if ($relationshipObject->hasResource($this)) {
145
			throw new DuplicateException('can not add relation to self');
146
		}
147
		
148
		if ($this->relationships === null) {
149
			$this->setRelationshipsObject(new RelationshipsObject());
150
		}
151
		
152
		$this->validator->claimUsedFields([$key], Validator::OBJECT_CONTAINER_RELATIONSHIPS, $options);
153
		
154
		$this->relationships->addRelationshipObject($key, $relationshipObject);
155
	}
156
	
157
	/**
158
	 * @param RelationshipsObject $relationshipsObject
0 ignored issues
show
Coding Style introduced by
Missing parameter comment
Loading history...
159
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
160
	public function setRelationshipsObject(RelationshipsObject $relationshipsObject) {
161
		$newKeys = $relationshipsObject->getKeys();
162
		$this->validator->clearUsedFields(Validator::OBJECT_CONTAINER_RELATIONSHIPS);
163
		$this->validator->claimUsedFields($newKeys, Validator::OBJECT_CONTAINER_RELATIONSHIPS);
164
		
165
		$this->relationships = $relationshipsObject;
166
	}
167
	
168
	/**
169
	 * internal api
170
	 */
171
	
172
	/**
173
	 * whether the ResourceObject is empty except for the ResourceIdentifierObject
174
	 * 
175
	 * this can be used to determine if a Relationship's resource could be added as included resource
176
	 * 
177
	 * @internal
178
	 * 
179
	 * @return boolean
180
	 */
181
	public function hasIdentifierPropertiesOnly() {
182 View Code Duplication
		if ($this->attributes !== null && $this->attributes->isEmpty() === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
183
			return false;
184
		}
185 View Code Duplication
		if ($this->relationships !== null && $this->relationships->isEmpty() === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
186
			return false;
187
		}
188 View Code Duplication
		if ($this->links !== null && $this->links->isEmpty() === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
189
			return false;
190
		}
191
		
192
		return true;
193
	}
194
	
195
	/**
196
	 * ResourceInterface
197
	 */
198
	
199
	/**
0 ignored issues
show
Coding Style introduced by
Parameter $identifierOnly should have a doc-comment as per coding-style.
Loading history...
200
	 * @inheritDoc
201
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
202
	public function getResource($identifierOnly=false) {
203
		if ($identifierOnly) {
204
			return ResourceIdentifierObject::fromResourceObject($this);
205
		}
206
		
207
		return $this;
208
	}
209
	
210
	/**
211
	 * ObjectInterface
212
	 */
213
	
214
	/**
215
	 * @inheritDoc
216
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
217
	public function isEmpty() {
218
		if (parent::isEmpty() === false) {
219
			return false;
220
		}
221 View Code Duplication
		if ($this->attributes !== null && $this->attributes->isEmpty() === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
222
			return false;
223
		}
224 View Code Duplication
		if ($this->relationships !== null && $this->relationships->isEmpty() === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
225
			return false;
226
		}
227 View Code Duplication
		if ($this->links !== null && $this->links->isEmpty() === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
228
			return false;
229
		}
230
		
231
		return true;
232
	}
233
	
234
	/**
235
	 * @inheritDoc
236
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
237 View Code Duplication
	public function toArray() {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
238
		$array = parent::toArray();
239
		
240
		if ($this->attributes !== null && $this->attributes->isEmpty() === false) {
241
			$array['attributes'] = $this->attributes->toArray();
242
		}
243
		if ($this->relationships !== null && $this->relationships->isEmpty() === false) {
244
			$array['relationships'] = $this->relationships->toArray();
245
		}
246
		if ($this->links !== null && $this->links->isEmpty() === false) {
247
			$array['links'] = $this->links->toArray();
248
		}
249
		
250
		return $array;
251
	}
252
	
253
	/**
254
	 * RecursiveResourceContainerInterface
255
	 */
256
	
257
	/**
258
	 * @inheritDoc
259
	 */
0 ignored issues
show
Coding Style introduced by
Missing @return tag in function comment
Loading history...
260
	public function getNestedContainedResourceObjects() {
261
		if ($this->relationships === null) {
262
			return [];
263
		}
264
		
265
		return $this->relationships->getNestedContainedResourceObjects();
266
	}
267
}
268