Completed
Push — 1.0.0-alpha ( c04b09...2436c2 )
by Alex
11s
created

src/Http/Concerns/UpdatesModelRelations.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
namespace Huntie\JsonApi\Http\Concerns;
4
5
use Illuminate\Database\Eloquent\Relations\BelongsTo;
6
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
7
8
/**
9
 * Specify and update relationships on the primary controller resource.
10
 *
11
 * @property $model
12
 */
13
trait UpdatesModelRelations
14
{
15
    /**
16
     * The model relationships that can be updated.
17
     *
18
     * @var array
19
     */
20
    protected $fillableRelations = [];
21
22
    /**
23
     * Determine whether the given named relation can be updated on the model.
24
     *
25
     * @param string $relation
26
     */
27
    protected function isFillableRelation(string $relation): bool
28
    {
29
        return array_key_exists($relation, $this->fillableRelations);
30
    }
31
32
    /**
33
     * Determine the JSON API relation type for a named relation on the primary
34
     * resource.
35
     *
36
     * @param string $relation
37
     *
38
     * @return string|void
39
     */
40
    protected function getRelationType(string $relation)
41
    {
42
        $relation = $this->model->{$relation}();
0 ignored issues
show
The property model does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
43
44
        if ($relation instanceof BelongsTo) {
45
            return 'To-One';
46
        } else if ($relation instanceof BelongsToMany) {
47
            return 'To-Many';
48
        }
49
    }
50
51
    /**
52
     * Update a named many-to-one relationship association on a model instance.
53
     *
54
     * http://jsonapi.org/format/#crud-updating-to-one-relationships
55
     *
56
     * @param Model  $record
57
     * @param string $relation
58
     * @param array  $data
59
     */
60
    protected function updateToOneResourceRelationship($record, string $relation, array $data)
61
    {
62
        $record->{$relation}()->associate($data['id']);
63
        $record->save();
64
    }
65
66
    /**
67
     * Update named many-to-many relationship entries on a model instance.
68
     *
69
     * http://jsonapi.org/format/#crud-updating-to-many-relationships
70
     *
71
     * @param Model  $record
72
     * @param string $relation
73
     * @param array  $data
74
     * @param string $method
75
     */
76
    protected function updateToManyResourceRelationship($record, string $relation, array $data, string $method)
77
    {
78
        $items = [];
79
80
        foreach ($data as $item) {
81
            if (isset($item['attributes'])) {
82
                $items[$item['id']] = $item['attributes'];
83
            } else {
84
                $items[] = $item['id'];
85
            }
86
        }
87
88
        switch ($method) {
89
            case 'PATCH':
90
                $record->{$relation}()->sync($items);
91
                break;
92
            case 'POST':
93
                $record->{$relation}()->sync($items, false);
94
                break;
95
            case 'DELETE':
96
                $record->{$relation}()->detach(array_keys($items));
97
        }
98
    }
99
100
    /**
101
     * Update one or more relationships on a model instance from an array of
102
     * named relationships and associated resource identifiers.
103
     *
104
     * http://jsonapi.org/format/#crud-updating-resource-relationships
105
     *
106
     * @param Model $record
107
     * @param array $relationships
108
     */
109
    protected function updateResourceRelationships($record, array $relationships)
110
    {
111
        $relationships = array_intersect_key($relationships, array_flip($this->fillableRelations));
112
113
        foreach ($relationships as $name => $relationship) {
114
            if ($this->getRelationType($name) === 'To-One') {
115
                $record->{$name}()->associate(array_get($relationship, 'data.id'));
116
                $record->save();
117
            } else if ($this->getRelationType($name) === 'To-Many') {
118
                $record->{$name}()->sync(array_pluck($relationship['data'], 'id'));
119
            }
120
        }
121
    }
122
}
123