Passed
Push — documentation ( 2be3e9...2ecb8c )
by Alex
04:22 queued 01:23
created

ResourceSerializer::getPrimaryData()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
rs 10
cc 1
eloc 2
nc 1
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($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->getRecordType(),
73
            'id' => $this->record->id,
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
     * @return \Illuminate\Support\Collection
107
     */
108
    public function getIncludedRecords()
109
    {
110
        return collect($this->include)->map(function ($relation) {
111
            $records = (new RelationshipSerializer($this->record, $relation, $this->fields))->toResourceCollection();
112
113
            return $records instanceof Collection ? $records : [$records];
114
        })->flatten(1)->unique()->values();
115
    }
116
117
    /**
118
     * Return primary data for the JSON API document.
119
     *
120
     * @return mixed
121
     */
122
    protected function getPrimaryData()
123
    {
124
        return $this->toResourceObject();
125
    }
126
127
    /**
128
     * Return any secondary included resource data.
129
     *
130
     * @return array
131
     */
132
    protected function getIncludedData()
133
    {
134
        return $this->getIncludedRecords()->toArray();
135
    }
136
137
    /**
138
     * Return the primary record type name.
139
     *
140
     * @return string
141
     */
142
    protected function getRecordType()
143
    {
144
        $modelName = collect(explode('\\', get_class($this->record)))->last();
145
146
        return snake_case(str_plural($modelName), '-');
147
    }
148
149
    /**
150
     * Return the attribute object data for the primary record.
151
     *
152
     * @return array
153
     */
154
    protected function transformRecordAttributes()
155
    {
156
        $attributes = array_diff_key($this->record->toArray(), $this->record->getRelations());
157
        $attributes = array_except($attributes, ['id']);
158
        $fields = array_get($this->fields, $this->getRecordType());
159
160
        if (!empty($fields)) {
161
            $attributes = array_only($attributes, $fields);
162
        }
163
164
        return $attributes;
165
    }
166
167
    /**
168
     * Return a collection of JSON API resource identifier objects by each
169
     * relation on the primary record.
170
     *
171
     * @return \Illuminate\Support\Collection
172
     */
173
    protected function transformRecordRelations()
174
    {
175
        $this->record->load($this->relationships);
176
177
        return collect($this->relationships)->combine(array_map(function ($relation) {
178
            return [
179
                'data' => (new RelationshipSerializer($this->record, $relation))->toResourceLinkage(),
180
            ];
181
        }, $this->relationships));
182
    }
183
}
184