CollectionDocument::addResource()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 13
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 4
eloc 7
c 1
b 0
f 0
nc 3
nop 2
dl 0
loc 13
ccs 8
cts 8
cp 1
crap 4
rs 10
1
<?php
2
3
namespace alsvanzelf\jsonapi;
4
5
use alsvanzelf\jsonapi\DataDocument;
6
use alsvanzelf\jsonapi\Document;
7
use alsvanzelf\jsonapi\exceptions\InputException;
8
use alsvanzelf\jsonapi\interfaces\PaginableInterface;
9
use alsvanzelf\jsonapi\interfaces\RecursiveResourceContainerInterface;
10
use alsvanzelf\jsonapi\interfaces\ResourceContainerInterface;
11
use alsvanzelf\jsonapi\interfaces\ResourceInterface;
12
use alsvanzelf\jsonapi\objects\ResourceObject;
13
use alsvanzelf\jsonapi\objects\ResourceIdentifierObject;
14
15
/**
16
 * this document is a set of Resources
17
 * this document should be used if there could be multiple, also if only one or even none is returned
18
 */
19
class CollectionDocument extends DataDocument implements PaginableInterface, ResourceContainerInterface {
20
	/** @var ResourceInterface[] */
21
	protected $resources = [];
22
	/** @var array */
23
	protected static $defaults = [
24
		/**
25
		 * add resources inside relationships to /included when adding resources to the collection
26
		 */
27
		'includeContainedResources' => true,
28
	];
29
	
30
	/**
31
	 * human api
32
	 */
33
	
34
	/**
35
	 * generate a CollectionDocument from one or multiple resources
36
	 * 
37
	 * adds included resources if found inside the resource's relationships, use {@see ->addResource()} to change that behavior
38
	 * 
39
	 * @param  ResourceInterface ...$resources
40
	 * @return CollectionDocument
41
	 */
42 7
	public static function fromResources(ResourceInterface ...$resources) {
43 7
		$collectionDocument = new self();
44
		
45 7
		foreach ($resources as $resource) {
46 7
			$collectionDocument->addResource($resource);
47
		}
48
		
49 7
		return $collectionDocument;
50
	}
51
	
52
	/**
53
	 * @param string     $type
54
	 * @param string|int $id
55
	 * @param array      $attributes optional, if given a ResourceObject is added, otherwise a ResourceIdentifierObject is added
56
	 */
57 4
	public function add($type, $id, array $attributes=[]) {
58 4
		if ($attributes === []) {
59 3
			$this->addResource(new ResourceIdentifierObject($type, $id));
60
		}
61
		else {
62 1
			$this->addResource(ResourceObject::fromArray($attributes, $type, $id));
63
		}
64
	}
65
	
66
	/**
67
	 * @inheritDoc
68
	 */
69 7
	public function setPaginationLinks($previousHref=null, $nextHref=null, $firstHref=null, $lastHref=null) {
70 7
		if ($previousHref !== null) {
71 2
			$this->addLink('prev', $previousHref);
72
		}
73 7
		if ($nextHref !== null) {
74 3
			$this->addLink('next', $nextHref);
75
		}
76 7
		if ($firstHref !== null) {
77 2
			$this->addLink('first', $firstHref);
78
		}
79 7
		if ($lastHref !== null) {
80 3
			$this->addLink('last', $lastHref);
81
		}
82
	}
83
	
84
	/**
85
	 * spec api
86
	 */
87
	
88
	/**
89
	 * add a resource to the collection
90
	 * 
91
	 * adds included resources if found inside the resource's relationships, unless $options['includeContainedResources'] is set to false
92
	 * 
93
	 * @param ResourceInterface $resource
94
	 * @param array             $options  optional {@see CollectionDocument::$defaults}
95
	 * 
96
	 * @throws InputException if the resource is empty
97
	 */
98 18
	public function addResource(ResourceInterface $resource, array $options=[]) {
99 18
		if ($resource->getResource()->isEmpty()) {
100 1
			throw new InputException('does not make sense to add empty resources to a collection');
101
		}
102
		
103 17
		$options = array_merge(self::$defaults, $options);
104
		
105 17
		$this->validator->claimUsedResourceIdentifier($resource);
106
		
107 16
		$this->resources[] = $resource;
108
		
109 16
		if ($options['includeContainedResources'] && $resource instanceof RecursiveResourceContainerInterface) {
110 12
			$this->addIncludedResourceObject(...$resource->getNestedContainedResourceObjects());
111
		}
112
	}
113
	
114
	/**
115
	 * DocumentInterface
116
	 */
117
	
118
	/**
119
	 * @inheritDoc
120
	 */
121 21
	public function toArray() {
122 21
		$array = parent::toArray();
123
		
124 21
		$array['data'] = [];
125 21
		foreach ($this->resources as $resource) {
126 9
			$array['data'][] = $resource->getResource()->toArray();
127
		}
128
		
129 21
		return $array;
130
	}
131
	
132
	/**
133
	 * ResourceContainerInterface
134
	 */
135
	
136
	/**
137
	 * @inheritDoc
138
	 */
139 8
	public function getContainedResources() {
140 8
		return $this->resources;
141
	}
142
}
143