1414
1515namespace JsonApiPhp \JsonApi \Document ;
1616
17+ use JsonApiPhp \JsonApi \Document \Resource \IdentifiableResource ;
18+ use JsonApiPhp \JsonApi \Document \Resource \ResourceObject ;
1719use JsonApiPhp \JsonApi \HasLinksAndMeta ;
1820
1921final class Document implements \JsonSerializable
@@ -23,11 +25,13 @@ final class Document implements \JsonSerializable
2325
2426 use HasLinksAndMeta;
2527
26- protected $ data ;
27- protected $ errors ;
28- protected $ meta ;
29- protected $ jsonapi ;
30- protected $ links ;
28+ private $ data ;
29+ private $ errors ;
30+ private $ meta ;
31+ private $ jsonapi ;
32+ private $ links ;
33+ private $ included ;
34+ private $ sparse = false ;
3135
3236 /**
3337 * Use named constructors instead
@@ -50,14 +54,14 @@ public static function fromErrors(Error ...$errors): self
5054 return $ doc ;
5155 }
5256
53- public static function fromData ( PrimaryDataInterface $ data ): self
57+ public static function fromResource ( IdentifiableResource $ data ): self
5458 {
5559 $ doc = new self ;
5660 $ doc ->data = $ data ;
5761 return $ doc ;
5862 }
5963
60- public static function fromDataItems ( PrimaryDataItemInterface ...$ data ): self
64+ public static function fromResources ( IdentifiableResource ...$ data ): self
6165 {
6266 $ doc = new self ;
6367 $ doc ->data = $ data ;
@@ -74,19 +78,68 @@ public function setApiMeta(array $meta): void
7478 $ this ->jsonapi ['meta ' ] = $ meta ;
7579 }
7680
81+ public function setIncluded (IdentifiableResource ...$ included )
82+ {
83+ $ this ->included = $ included ;
84+ }
85+
86+ public function setSparse ()
87+ {
88+ $ this ->sparse = true ;
89+ }
90+
7791 public function jsonSerialize ()
7892 {
93+ if ($ this ->included && !$ this ->sparse ) {
94+ foreach ($ this ->included as $ resource ) {
95+ if ($ this ->hasLinkTo ($ resource )) {
96+ continue ;
97+ }
98+ throw new \LogicException ("Full linkage is required for $ resource " );
99+ }
100+ }
79101 return array_filter (
80102 [
81- 'data ' => $ this ->data ,
82- 'errors ' => $ this ->errors ,
83- 'meta ' => $ this ->meta ,
103+ 'data ' => $ this ->data ,
104+ 'errors ' => $ this ->errors ,
105+ 'meta ' => $ this ->meta ,
84106 'jsonapi ' => $ this ->jsonapi ,
85- 'links ' => $ this ->links ,
107+ 'links ' => $ this ->links ,
108+ 'included ' => $ this ->included ,
86109 ],
87110 function ($ v ) {
88111 return null !== $ v ;
89112 }
90113 );
91114 }
115+
116+ private function hasLinkTo (IdentifiableResource $ resource ): bool
117+ {
118+ if (!$ this ->data ) {
119+ return false ;
120+ }
121+
122+ foreach ($ this ->toDataItems () as $ my_resource ) {
123+ if ($ my_resource instanceof ResourceObject) {
124+ if ($ my_resource ->hasRelationTo ($ resource )) {
125+ return true ;
126+ }
127+ }
128+ }
129+ return false ;
130+ }
131+
132+ /**
133+ * @return IdentifiableResource[]
134+ */
135+ private function toDataItems (): array
136+ {
137+ if ($ this ->data instanceof IdentifiableResource) {
138+ return [$ this ->data ];
139+ } elseif (is_array ($ this ->data )) {
140+ return $ this ->data ;
141+ } else {
142+ return [];
143+ }
144+ }
92145}
0 commit comments