Passed
Push — serialization-refactor ( 7d0248...e27dea )
by Alex
02:50
created

ResourceSerializer::mapRelation()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 12
rs 9.4285
cc 3
eloc 7
nc 3
nop 2
1
<?php
2
3
namespace Huntie\JsonApi\Serializers;
4
5
class ResourceSerializer extends JsonApiSerializer
6
{
7
    /**
8
     * The model instance to transform.
9
     *
10
     * @var \Illuminate\Database\Eloquent\Model
11
     */
12
    protected $record;
13
14
    /**
15
     * The record relationships to return.
16
     *
17
     * @var array
18
     */
19
    protected $relationships;
20
21
    /**
22
     * The subset of record attributes to return.
23
     *
24
     * @var array
25
     */
26
    protected $fields;
27
28
    /**
29
     * The relationships to load and include.
30
     *
31
     * @var array
32
     */
33
    protected $include;
34
35
    /**
36
     * Create a new JSON API resource serializer.
37
     *
38
     * @param Model      $record  The model instance to serialise
39
     * @param array|null $fields  Subset of fields to return
40
     * @param array|null $include Relations to include
41
     */
42
    public function __construct($record, array $fields = [], array $include = [])
43
    {
44
        parent::__construct();
45
46
        $this->record = $record;
0 ignored issues
show
Documentation Bug introduced by
It seems like $record of type object<Huntie\JsonApi\Serializers\Model> is incompatible with the declared type object<Illuminate\Database\Eloquent\Model> of property $record.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
47
        $this->relationships = array_merge($record->getRelations(), $include);
48
        $this->fields = array_unique($fields);
49
        $this->include = array_unique($include);
50
    }
51
52
    /**
53
     * Limit which relations can be included.
54
     *
55
     * @param array $include
56
     */
57
    public function scopeIncludes($include)
58
    {
59
        $this->include = array_intersect($this->include, $include);
60
    }
61
62
    /**
63
     * Return a JSON API resource identifier object for the primary record.
64
     *
65
     * @return array
66
     */
67
    public function toResourceIdentifier()
68
    {
69
        return [
70
            'type' => $this->getRecordType(),
71
            'id' => $this->record->id,
72
        ];
73
    }
74
75
    /**
76
     * Return a base JSON API resource object for the primary record containing
77
     * only immediate attributes.
78
     *
79
     * @return array
80
     */
81
    public function toBaseResourceObject()
82
    {
83
        return array_merge($this->toResourceIdentifier(), [
84
            'attributes' => $this->transformRecordAttributes(),
85
        ]);
86
    }
87
88
    /**
89
     * Return a full JSON API resource object for the primary record.
90
     *
91
     * @return array
92
     */
93
    public function toResourceObject()
94
    {
95
        $this->record->load($this->relationships);
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 $this->include->map($included, function ($relation) {
0 ignored issues
show
Bug introduced by
The variable $included does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
Bug introduced by
The method map cannot be called on $this->include (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
111
            return collect((new RelationshipSerializer($this->record, $relation))->toResourceCollection());
112
        })->flatten(1);
113
    }
114
115
    /**
116
     * Return primary data for the JSON API document.
117
     *
118
     * @return array
119
     */
120
    protected function getPrimaryData()
121
    {
122
        return $this->toResourceObject();
123
    }
124
125
    /**
126
     * Return any secondary included resource data.
127
     *
128
     * @return array
129
     */
130
    protected function getIncludedData()
131
    {
132
        return $this->getIncludedRecords()->toArray();
133
    }
134
135
    /**
136
     * Return the primary record type name.
137
     *
138
     * @return string
139
     */
140
    protected function getRecordType()
141
    {
142
        $modelName = collect(explode('\\', get_class($this->record)))->last();
143
144
        return snake_case(str_plural($modelName), '-');
145
    }
146
147
    /**
148
     * Return the attribute object data for the primary record.
149
     *
150
     * @return array
151
     */
152
    protected function transformRecordAttributes()
153
    {
154
        $attributes = array_diff_key($this->record->toArray(), $this->record->getRelations());
155
        $attributes = array_except($attributes, ['id']);
156
157
        if (!empty($this->fields)) {
158
            $attributes = array_only($attributes, $this->fields);
159
        }
160
161
        return $attributes;
162
    }
163
164
    /**
165
     * Return a collection of JSON API resource identifier objects by each
166
     * relation on the primary record.
167
     *
168
     * @return \Illuminate\Support\Collection
169
     */
170
    protected function transformRecordRelations()
171
    {
172
        return $this->relationships->combine($this->relationships->map(function ($relation) {
0 ignored issues
show
Bug introduced by
The method map cannot be called on $this->relationships (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
Bug introduced by
The method combine cannot be called on $this->relationships (of type array).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
173
            return [
174
                'data' => (new RelationshipSerializer($this->record, $relation))->toResourceLinkage(),
175
            ];
176
        }));
177
    }
178
}
179