Skip to content

Commit d2a3ee5

Browse files
committed
Merge branch 'release/1.0.0-beta.1' into main
2 parents ca3a8a2 + 6adbb83 commit d2a3ee5

File tree

6 files changed

+105
-39
lines changed

6 files changed

+105
-39
lines changed

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,17 @@
33
All notable changes to this project will be documented in this file. This project adheres to
44
[Semantic Versioning](http://semver.org/) and [this changelog format](http://keepachangelog.com/).
55

6+
## [1.0.0-beta.1] - 2021-03-30
7+
8+
### Changed
9+
10+
- Updated the encoder to implement changes made to the encoder interface. This removes the `withIdentifiers()` method
11+
and replaces it with the `withToOne()` and `withToMany()` methods.
12+
13+
### Fixed
14+
15+
- When encoding relationships, do not yield a relationship value that is empty (no data, links or meta).
16+
617
## [1.0.0-alpha.4] - 2021-02-27
718

819
### Changed

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
"php": "^7.4|^8.0",
2727
"ext-json": "*",
2828
"illuminate/support": "^8.0",
29-
"laravel-json-api/core": "^1.0.0-alpha.4",
29+
"laravel-json-api/core": "^1.0.0-beta.1",
3030
"laravel-json-api/neomerx-json-api": "^4.0.2"
3131
},
3232
"require-dev": {

src/Encoder.php

Lines changed: 55 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -125,11 +125,9 @@ public function withFieldSets($fieldSets): self
125125
*/
126126
public function withResource(?object $resource): DocumentContract
127127
{
128-
if (is_object($resource) && !$resource instanceof JsonApiResource) {
129-
$resource = $this->resources->create($resource);
130-
}
131-
132-
return $this->createCompoundDocument($resource);
128+
return $this->createCompoundDocument(
129+
$resource ? $this->toResource($resource) : null
130+
);
133131
}
134132

135133
/**
@@ -145,19 +143,25 @@ public function withResources(iterable $resources): DocumentContract
145143
/**
146144
* @inheritDoc
147145
*/
148-
public function withIdentifiers(object $resource, string $fieldName, $identifiers): DocumentContract
146+
public function withToOne(object $resource, string $fieldName, ?object $related): DocumentContract
149147
{
150-
$document = new RelationshipDocument(
151-
$this->createNeomerxEncoder(),
152-
$this->mapper,
148+
return $this->createRelationshipDocument(
153149
$resource,
154150
$fieldName,
155-
$identifiers
151+
$related ? $this->toResource($related) : null,
156152
);
153+
}
157154

158-
$document->withJsonApi($this->version);
159-
160-
return $document;
155+
/**
156+
* @inheritDoc
157+
*/
158+
public function withToMany(object $resource, string $fieldName, iterable $related): DocumentContract
159+
{
160+
return $this->createRelationshipDocument(
161+
$resource,
162+
$fieldName,
163+
$this->resources->cursor($related),
164+
);
161165
}
162166

163167
/**
@@ -172,6 +176,31 @@ private function createCompoundDocument($data): DocumentContract
172176
return $document;
173177
}
174178

179+
/**
180+
* @param object $resource
181+
* @param string $fieldName
182+
* @param $identifiers
183+
* @return RelationshipDocument
184+
*/
185+
private function createRelationshipDocument(
186+
object $resource,
187+
string $fieldName,
188+
$identifiers
189+
): RelationshipDocument
190+
{
191+
$document = new RelationshipDocument(
192+
$this->createNeomerxEncoder(),
193+
$this->mapper,
194+
$this->toResource($resource),
195+
$fieldName,
196+
$identifiers
197+
);
198+
199+
$document->withJsonApi($this->version);
200+
201+
return $document;
202+
}
203+
175204
/**
176205
* Create a new encoder instance.
177206
*
@@ -198,4 +227,17 @@ private function createNeomerxEncoder(): ExtendedEncoder
198227

199228
return $encoder;
200229
}
230+
231+
/**
232+
* @param object $object
233+
* @return JsonApiResource
234+
*/
235+
private function toResource(object $object): JsonApiResource
236+
{
237+
if ($object instanceof JsonApiResource) {
238+
return $object;
239+
}
240+
241+
return $this->resources->create($object);
242+
}
201243
}

src/RelationshipDocument.php

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,16 @@
1919

2020
namespace LaravelJsonApi\Encoder\Neomerx;
2121

22+
use LaravelJsonApi\Core\Resources\JsonApiResource;
2223
use LaravelJsonApi\Encoder\Neomerx\Encoder\Encoder as ExtendedEncoder;
2324

2425
class RelationshipDocument extends Document
2526
{
2627

2728
/**
28-
* @var object
29+
* @var JsonApiResource
2930
*/
30-
private object $resource;
31+
private JsonApiResource $resource;
3132

3233
/**
3334
* @var string
@@ -44,14 +45,14 @@ class RelationshipDocument extends Document
4445
*
4546
* @param ExtendedEncoder $encoder
4647
* @param Mapper $mapper
47-
* @param object $resource
48+
* @param JsonApiResource $resource
4849
* @param string $fieldName
4950
* @param object|iterable|null $data
5051
*/
5152
public function __construct(
5253
ExtendedEncoder $encoder,
5354
Mapper $mapper,
54-
object $resource,
55+
JsonApiResource $resource,
5556
string $fieldName,
5657
$data
5758
) {

src/Schema/Relation.php

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use LaravelJsonApi\Contracts\Resources\Container;
2323
use LaravelJsonApi\Contracts\Resources\JsonApiRelation;
2424
use LaravelJsonApi\Core\Document\ResourceIdentifier;
25-
use LaravelJsonApi\Core\Json\Hash;
2625
use LaravelJsonApi\Core\Resources\JsonApiResource;
2726
use LaravelJsonApi\Encoder\Neomerx\Mapper;
2827
use Neomerx\JsonApi\Contracts\Schema\ContextInterface;
@@ -63,11 +62,6 @@ final class Relation
6362
*/
6463
private ContextInterface $context;
6564

66-
/**
67-
* @var string
68-
*/
69-
private string $fieldName;
70-
7165
/**
7266
* Relation constructor.
7367
*
@@ -76,22 +70,19 @@ final class Relation
7670
* @param JsonApiRelation $object
7771
* @param SchemaFields $fields
7872
* @param ContextInterface $context
79-
* @param string $fieldName
8073
*/
8174
public function __construct(
8275
Container $container,
8376
Mapper $mapper,
8477
JsonApiRelation $object,
8578
SchemaFields $fields,
86-
ContextInterface $context,
87-
string $fieldName
79+
ContextInterface $context
8880
) {
8981
$this->container = $container;
9082
$this->mapper = $mapper;
9183
$this->relation = $object;
9284
$this->fields = $fields;
9385
$this->context = $context;
94-
$this->fieldName = $fieldName;
9586
}
9687

9788
/**
@@ -119,7 +110,7 @@ public function toArray(): array
119110
{
120111
$relation = [];
121112
$links = $this->relation->links();
122-
$meta = new Hash($this->relation->meta() ?: []);
113+
$meta = $this->relation->meta();
123114

124115
if ($this->willShowData()) {
125116
$relation[SchemaInterface::RELATIONSHIP_DATA] = $this->data();
@@ -131,7 +122,7 @@ public function toArray(): array
131122
);
132123
}
133124

134-
if ($meta->isNotEmpty()) {
125+
if (!empty($meta)) {
135126
$relation[SchemaInterface::RELATIONSHIP_META] = $meta;
136127
}
137128

@@ -149,7 +140,7 @@ private function willShowData(): bool
149140

150141
return $this->fields->isRelationshipRequested(
151142
$this->context->getPosition()->getPath(),
152-
$this->fieldName
143+
$this->relation->fieldName(),
153144
);
154145
}
155146

src/Schema/Relationships.php

Lines changed: 29 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -107,18 +107,39 @@ public function getIterator()
107107
$fieldName = $relation->fieldName();
108108

109109
if ($this->fields->isFieldRequested($this->resource->type(), $fieldName)) {
110-
yield $fieldName => (new Relation(
111-
$this->container,
112-
$this->mapper,
113-
$relation,
114-
$this->fields,
115-
$this->context,
116-
$fieldName
117-
))->toArray();
110+
$value = $this->convert($relation)->toArray();
111+
112+
/**
113+
* The value could be empty, in which case we should not yield it otherwise
114+
* the Neomerx encoder ends up encoding the relationship as an empty array.
115+
* An example of when this might be legitimately empty is when the relationship
116+
* is meta-only, but the meta value is controlled by the client (for example our
117+
* countable implementation) and the client hasn't requested it.
118+
*/
119+
if (!empty($value)) {
120+
yield $fieldName => $value;
121+
}
118122
}
119123
}
120124
}
121125

126+
/**
127+
* Convert a JSON:API relation to an schema relation.
128+
*
129+
* @param JsonApiRelation $relation
130+
* @return Relation
131+
*/
132+
private function convert(JsonApiRelation $relation): Relation
133+
{
134+
return new Relation(
135+
$this->container,
136+
$this->mapper,
137+
$relation,
138+
$this->fields,
139+
$this->context,
140+
);
141+
}
142+
122143
/**
123144
* @return iterable
124145
*/

0 commit comments

Comments
 (0)