Passed
Pull Request — develop (#3)
by Alex
02:50
created

JsonApiTransforms::transformRecord()   B

Complexity

Conditions 4
Paths 6

Size

Total Lines 33
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 33
rs 8.5806
cc 4
eloc 20
nc 6
nop 3
1
<?php
2
3
namespace Huntie\JsonApi\Support;
4
5
/**
6
 * Transform Eloquent models and collections into JSON API objects.
7
 */
8
trait JsonApiTransforms
9
{
10
    /**
11
     * Transform a model instance into a JSON API object.
12
     *
13
     * @param \Illuminate\Database\Eloquent\Model $record
14
     * @param array|null                          $fields  Field subset to return
15
     * @param array|null                          $include Relations to include
16
     *
17
     * @return array
18
     */
19
    protected function transformRecord($record, array $fields = [], array $include = [])
20
    {
21
        $relations = array_unique(array_merge($record->getRelations(), $include));
22
        $record = $record->load($relations);
23
24
        $attributes = $record->toArray();
25
        $relationships = [];
26
        $included = [];
27
28
        foreach ($relations as $relation) {
29
            $relatedRecords = $record->{$relation};
30
            $relationships[$relation] = $this->transformCollectionIds($relatedRecords);
31
32
            if (in_array($relation, $include)) {
33
                $included[] = $this->transformCollectionSimple($relatedRecords);
34
            }
35
        }
36
37
        array_forget($attributes, $relations);
38
39
        if (!empty($fields)) {
40
            $attributes = array_only($attributes, $fields);
41
        }
42
43
        $data = array_filter([
44
            'type' => $record->getTable(),
45
            'id' => $record->id,
46
            'attributes' => array_except($attributes, ['id']),
47
            'relationships' => $relationships,
48
        ]);
49
50
        return array_filter(compact('data', 'included'));
51
    }
52
53
    /**
54
     * Transform a model instance into a JSON API object without additonal data.
55
     *
56
     * @param \Illuminate\Database\Eloquent\Model $record
57
     *
58
     * @return array
59
     */
60
    protected function transformRecordSimple($record)
61
    {
62
        $attributes = array_diff_key($record->toArray(), $record->getRelations());
63
        $attributes = array_except($attributes, ['id']);
64
65
        return [
66
            'data' => [
67
                'type' => $record->getTable(),
68
                'id' => $record->id,
69
                'attributes' => $attributes,
70
            ]
71
        ];
72
    }
73
74
    /**
75
     * Transform a set of models into a JSON API collection.
76
     *
77
     * @param \Illuminate\Support\Collection $records
78
     * @param array                          $fields
79
     *
80
     * @return array
81
     */
82
    protected function transformCollection($records, array $fields = [])
83
    {
84
        $data = $records->map(function ($record) use ($fields) {
85
            return $this->transformRecord($record, $fields)['data'];
86
        });
87
88
        return compact('data');
89
    }
90
91
    /**
92
     * Transform a set of models into a JSON API colleciton without additional data.
93
     *
94
     * @param \Illuminate\Support\Collection $records
95
     *
96
     * @return array
97
     */
98
    protected function transformCollectionSimple($records)
99
    {
100
        $data = $records->map(function ($record) {
101
            return $this->transformRecordSimple($record)['data'];
102
        });
103
104
        return compact('data');
105
    }
106
107
    /**
108
     * Transform a set of models into a collection of JSON API resource
109
     * identifier objects.
110
     *
111
     * @param \Illuminate\Support\Collection $records
112
     *
113
     * @return array
114
     */
115
    protected function transformCollectionIds($records)
116
    {
117
        $data = $records->map(function ($record) {
118
            return [
119
                'type' => $record->getTable(),
120
                'id' => $record->id,
121
            ];
122
        });
123
124
        return compact('data');
125
    }
126
}
127