Skip to content

Commit f962e25

Browse files
committed
add serializeIdentifier method and type juggling
1 parent c6c1d6c commit f962e25

File tree

3 files changed

+40
-9
lines changed

3 files changed

+40
-9
lines changed

src/Serializer.php

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
namespace tuyakhov\jsonapi;
77

88
use yii\base\Component;
9+
use yii\base\InvalidValueException;
910
use yii\base\Model;
1011
use yii\data\DataProviderInterface;
1112
use yii\data\Pagination;
@@ -86,16 +87,14 @@ public function serialize($data)
8687
* @param ResourceInterface $model
8788
* @return array
8889
*/
89-
protected function serializeModel($model)
90+
protected function serializeModel(ResourceInterface $model)
9091
{
9192
$fields = $this->getRequestedFields();
9293

9394
$attributes = isset($fields[$model->getType()]) ? $fields[$model->getType()] : [];
94-
$data = [
95-
'id' => $model->getId(),
96-
'type' => $model->getType(),
95+
$data = array_merge($this->serializeIdentifier($model), [
9796
'attributes' => $model->getResourceAttributes($attributes),
98-
];
97+
]);
9998

10099
$relationships = $model->getResourceRelationships();
101100
if (!empty($relationships)) {
@@ -104,11 +103,11 @@ protected function serializeModel($model)
104103
if (is_array($items)) {
105104
foreach ($items as $item) {
106105
if ($item instanceof ResourceIdentifierInterface) {
107-
$relationship[] = ['id' => $item->getId(), 'type' => $item->getType()];
106+
$relationship[] = $this->serializeIdentifier($item);
108107
}
109108
}
110109
} elseif ($items instanceof ResourceIdentifierInterface) {
111-
$relationship = ['id' => $items->getId(), 'type' => $items->getType()];
110+
$relationship = $this->serializeIdentifier($items);
112111
}
113112

114113
if (!empty($relationship)) {
@@ -134,7 +133,7 @@ protected function serializeModel($model)
134133
* @param ResourceInterface $resource
135134
* @return array
136135
*/
137-
protected function serializeResource($resource)
136+
protected function serializeResource(ResourceInterface $resource)
138137
{
139138
if ($this->request->getIsHead()) {
140139
return null;
@@ -150,6 +149,26 @@ protected function serializeResource($resource)
150149
}
151150
}
152151

152+
/**
153+
* Serialize resource identifier object and make type juggling
154+
* @link http://jsonapi.org/format/#document-resource-object-identification
155+
* @param ResourceIdentifierInterface $identifier
156+
* @return array
157+
*/
158+
protected function serializeIdentifier(ResourceIdentifierInterface $identifier)
159+
{
160+
$result = [];
161+
foreach (['id', 'type'] as $key) {
162+
$getter = 'get' . ucfirst($key);
163+
$value = $identifier->$getter();
164+
if ($value === null || is_array($value) || (is_object($value) && !method_exists($value, '__toString'))) {
165+
throw new InvalidValueException("The value {$key} of resource object " . get_class($identifier) . ' MUST be a string.');
166+
}
167+
$result[$key] = (string) $value;
168+
}
169+
return $result;
170+
}
171+
153172
/**
154173
* @param ResourceInterface $resource
155174
* @return array

tests/SerializerTest.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
use tuyakhov\jsonapi\tests\data\ResourceModel;
88
use tuyakhov\jsonapi\Serializer;
9+
use yii\base\InvalidValueException;
910
use yii\data\ArrayDataProvider;
1011

1112
class SerializerTest extends TestCase
@@ -17,6 +18,16 @@ protected function setUp()
1718
ResourceModel::$extraFields = [];
1819
}
1920

21+
// https://github.com/tuyakhov/yii2-json-api/pull/9
22+
public function testSerializeIdentifier()
23+
{
24+
ResourceModel::$id = [];
25+
$model = new ResourceModel();
26+
$serializer = new Serializer();
27+
$this->expectException(InvalidValueException::class);
28+
$serializer->serialize($model);
29+
}
30+
2031
public function testSerializeModelErrors()
2132
{
2233
$serializer = new Serializer();
@@ -39,6 +50,7 @@ public function testSerializeModelErrors()
3950
public function testSerializeModelData()
4051
{
4152
$serializer = new Serializer();
53+
ResourceModel::$id = 123;
4254
$model = new ResourceModel();
4355
$this->assertSame([
4456
'data' => [

tests/data/ResourceModel.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class ResourceModel extends Model implements ResourceInterface, LinksInterface
2929

3030
public function getId()
3131
{
32-
return (string) static::$id;
32+
return static::$id;
3333
}
3434

3535
public function fields()

0 commit comments

Comments
 (0)