Test Failed
Branch develop (9ed588)
by Alex
06:56
created

ResourceSerializer::getPrimaryKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 3
nc 2
nop 0
1
<?php
2
3
namespace Huntie\JsonApi\Serializers;
4
5
use Illuminate\Support\Collection;
6
7
class ResourceSerializer extends JsonApiSerializer
8
{
9
    /**
10
     * The model instance to transform.
11
     *
12
     * @var \Illuminate\Database\Eloquent\Model
13
     */
14
    protected $record;
15
16
    /**
17
     * The record relationships to return.
18
     *
19
     * @var array
20
     */
21
    protected $relationships;
22
23
    /**
24
     * The subset of attributes to return on each record type.
25
     *
26
     * @var array
27
     */
28
    protected $fields;
29
30
    /**
31
     * The relationships to load and include.
32
     *
33
     * @var array
34
     */
35
    protected $include;
36
37
    /**
38
     * Create a new JSON API resource serializer.
39
     *
40
     * @param \Illuminate\Database\Eloquent\Model $record  The model instance to serialise
41
     * @param array|null                          $fields  Subset of fields to return by record type
42
     * @param array|null                          $include Relations to include
43
     */
44
    public function __construct($record, array $fields = [], array $include = [])
45
    {
46
        parent::__construct();
47
48
        $this->record = $record;
49
        $this->relationships = array_merge(array_keys($record->getRelations()), $include);
50
        $this->fields = array_unique($fields);
51
        $this->include = array_unique($include);
52
    }
53
54
    /**
55
     * Limit which relations can be included.
56
     *
57
     * @param array $include
58
     */
59
    public function scopeIncludes($include)
60
    {
61
        $this->include = array_intersect($this->include, $include);
62
    }
63
64
    /**
65
     * Return a JSON API resource identifier object for the primary record.
66
     *
67
     * @return array
68
     */
69
    public function toResourceIdentifier()
70
    {
71
        return [
72
            'type' => $this->getResourceType(),
73
            'id' => $this->getPrimaryKey(),
74
        ];
75
    }
76
77
    /**
78
     * Return a base JSON API resource object for the primary record containing
79
     * only immediate attributes.
80
     *
81
     * @return array
82
     */
83
    public function toBaseResourceObject()
84
    {
85
        return array_merge($this->toResourceIdentifier(), [
86
            'attributes' => $this->transformRecordAttributes(),
87
        ]);
88
    }
89
90
    /**
91
     * Return a full JSON API resource object for the primary record.
92
     *
93
     * @return array
94
     */
95
    public function toResourceObject()
96
    {
97
        return array_filter(array_merge($this->toBaseResourceObject(), [
98
            'relationships' => $this->transformRecordRelations()->toArray(),
99
        ]));
100
    }
101
102
    /**
103
     * Return a collection of JSON API resource objects for each included
104
     * relationship.
105
     *
106
     * @throws \Huntie\JsonApi\Exceptions\InvalidRelationPathException
107
     *
108
     * @return \Illuminate\Support\Collection
109
     */
110
    public function getIncludedRecords()
111
    {
112
        return collect($this->include)->map(function ($relation) {
113
            $records = (new RelationshipSerializer($this->record, $relation, $this->fields))->toResourceCollection();
114
115
            return $records instanceof Collection ? $records : [$records];
116
        })->flatten(1)->unique()->values();
117
    }
118
119
    /**
120
     * Return primary data for the JSON API document.
121
     *
122
     * @return mixed
123
     */
124
    protected function getPrimaryData()
125
    {
126
        return $this->toResourceObject();
127
    }
128
129
    /**
130
     * Return any secondary included resource data.
131
     *
132
     * @return array
133
     */
134
    protected function getIncludedData()
135
    {
136
        return $this->getIncludedRecords()->toArray();
137
    }
138
139
    /**
140
     * Return the primary resource type name.
141
     *
142
     * @return string
143
     */
144
    protected function getResourceType()
145
    {
146
        $modelName = collect(explode('\\', get_class($this->record)))->last();
147
148
        return snake_case(str_plural($modelName), '-');
149
    }
150
151
    /**
152
     * Return the primary key value for the resource.
153
     *
154
     * @return int|string
155
     */
156
    protected function getPrimaryKey()
157
    {
158
        $value = $this->record->getKey();
159
160
        return is_int($value) ? $value : (string) $value;
161
    }
162
163
    /**
164
     * Return the attribute object data for the primary record.
165
     *
166
     * @return array
167
     */
168
    protected function transformRecordAttributes()
169
    {
170
        $attributes = array_diff_key($this->record->toArray(), $this->record->getRelations());
171
        $attributes = array_except($attributes, ['id']);
172
        $fields = array_get($this->fields, $this->getResourceType());
173
174
        if (!empty($fields)) {
175
            $attributes = array_only($attributes, $fields);
176
        }
177
178
        return $attributes;
179
    }
180
181
    /**
182
     * Return a collection of JSON API resource identifier objects by each
183
     * relation on the primary record.
184
     *
185
     * @throws \Huntie\JsonApi\Exceptions\InvalidRelationPathException
186
     *
187
     * @return \Illuminate\Support\Collection
188
     */
189
    protected function transformRecordRelations()
190
    {
191
        return collect($this->relationships)->combine(array_map(function ($relation) {
192
            return [
193
                'data' => (new RelationshipSerializer($this->record, $relation))->toResourceLinkage(),
194
            ];
195
        }, $this->relationships));
196
    }
197
}
198