Completed
Push — master ( 9af3cf...09ac23 )
by Jasper
04:37
created

HasRelations::hasRelation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Swis\JsonApi\Client\Concerns;
4
5
use Illuminate\Support\Str;
6
use Swis\JsonApi\Client\Collection;
7
use Swis\JsonApi\Client\Interfaces\DataInterface;
8
use Swis\JsonApi\Client\Interfaces\ManyRelationInterface;
9
use Swis\JsonApi\Client\Interfaces\OneRelationInterface;
10
use Swis\JsonApi\Client\Links;
11
use Swis\JsonApi\Client\Meta;
12
use Swis\JsonApi\Client\Relations\HasManyRelation;
13
use Swis\JsonApi\Client\Relations\HasOneRelation;
14
use Swis\JsonApi\Client\Relations\MorphToManyRelation;
15
use Swis\JsonApi\Client\Relations\MorphToRelation;
16
17
trait HasRelations
18
{
19
    /**
20
     * @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface[]|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface[]
21
     */
22
    protected $relations = [];
23
24
    /**
25
     * Create a singular relation to another item.
26
     *
27
     * @param string      $itemClass
28
     * @param string|null $name
29
     *
30
     * @return \Swis\JsonApi\Client\Relations\HasOneRelation
31
     */
32 180
    public function hasOne(string $itemClass, string $name = null): OneRelationInterface
33
    {
34 180
        $name = $name ?: Str::snake(debug_backtrace()[1]['function']);
35
36 180
        if (!array_key_exists($name, $this->relations)) {
37 180
            $this->relations[$name] = new HasOneRelation((new $itemClass())->getType());
38
        }
39
40 180
        return $this->relations[$name];
41
    }
42
43
    /**
44
     * Create a plural relation to another item.
45
     *
46
     * @param string      $itemClass
47
     * @param string|null $name
48
     *
49
     * @return \Swis\JsonApi\Client\Relations\HasManyRelation
50
     */
51 135
    public function hasMany(string $itemClass, string $name = null): ManyRelationInterface
52
    {
53 135
        $name = $name ?: Str::snake(debug_backtrace()[1]['function']);
54
55 135
        if (!array_key_exists($name, $this->relations)) {
56 135
            $this->relations[$name] = new HasManyRelation((new $itemClass())->getType());
57
        }
58
59 135
        return $this->relations[$name];
60
    }
61
62
    /**
63
     * Create a singular relation.
64
     *
65
     * @param string|null $name
66
     *
67
     * @return \Swis\JsonApi\Client\Relations\MorphToRelation
68
     */
69 360
    public function morphTo(string $name = null): OneRelationInterface
70
    {
71 360
        $name = $name ?: Str::snake(debug_backtrace()[1]['function']);
72
73 360
        if (!array_key_exists($name, $this->relations)) {
74 360
            $this->relations[$name] = new MorphToRelation();
75
        }
76
77 360
        return $this->relations[$name];
78
    }
79
80
    /**
81
     * Create a plural relation.
82
     *
83
     * @param string|null $name
84
     *
85
     * @return \Swis\JsonApi\Client\Relations\MorphToManyRelation
86
     */
87 207
    public function morphToMany(string $name = null): ManyRelationInterface
88
    {
89 207
        $name = $name ?: Str::snake(debug_backtrace()[1]['function']);
90
91 207
        if (!array_key_exists($name, $this->relations)) {
92 207
            $this->relations[$name] = new MorphToManyRelation();
93
        }
94
95 207
        return $this->relations[$name];
96
    }
97
98
    /**
99
     * @return \Swis\JsonApi\Client\Interfaces\OneRelationInterface[]|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface[]
100
     */
101 504
    public function getRelations(): array
102
    {
103 504
        return $this->relations;
104
    }
105
106
    /**
107
     * @param string $name
108
     *
109
     * @return \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface|null
110
     */
111 378
    public function getRelation(string $name)
112
    {
113 378
        return $this->relations[$name] ?? null;
114
    }
115
116
    /**
117
     * Get the relationship data (included).
118
     *
119
     * @param string $name
120
     *
121
     * @return \Swis\JsonApi\Client\Interfaces\DataInterface|null
122
     */
123 36
    public function getRelationValue(string $name): ?DataInterface
124
    {
125
        // If the "attribute" exists as a method on the model, we will just assume
126
        // it is a relationship and will load and return the included items in the relationship
127 36
        $method = Str::camel($name);
128 36
        if (method_exists($this, $method)) {
129 9
            return $this->$method()->getIncluded();
130
        }
131
132
        // If the "attribute" exists as a relationship on the model, we will return
133
        // the included items in the relationship
134 27
        if ($this->hasRelation($name)) {
135 9
            return $this->getRelation($name)->getIncluded();
136
        }
137
138 18
        return null;
139
    }
140
141
    /**
142
     * Set the specific relationship on the model.
143
     *
144
     * @param string                                                   $name
145
     * @param \Swis\JsonApi\Client\Interfaces\DataInterface|false|null $data
146
     * @param \Swis\JsonApi\Client\Links|null                          $links
147
     * @param \Swis\JsonApi\Client\Meta|null                           $meta
148
     *
149
     * @return static
150
     */
151 315
    public function setRelation(string $name, $data = false, Links $links = null, Meta $meta = null)
152
    {
153 315
        $method = Str::camel($name);
154 315
        if (method_exists($this, $method)) {
155
            /** @var \Swis\JsonApi\Client\Interfaces\OneRelationInterface|\Swis\JsonApi\Client\Interfaces\ManyRelationInterface $relationObject */
156 81
            $relationObject = $this->$method();
157 279
        } elseif ($data instanceof Collection) {
158 72
            $relationObject = $this->morphToMany($name);
159
        } else {
160 261
            $relationObject = $this->morphTo($name);
161
        }
162
163 315
        if ($data !== false) {
164 306
            $relationObject->dissociate();
165 306
            if ($data !== null) {
166 288
                $relationObject->associate($data);
0 ignored issues
show
Bug introduced by
It seems like $data can also be of type Swis\JsonApi\Client\Collection; however, parameter $included of Swis\JsonApi\Client\Inte...nInterface::associate() does only seem to accept Swis\JsonApi\Client\Interfaces\ItemInterface, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

166
                $relationObject->associate(/** @scrutinizer ignore-type */ $data);
Loading history...
167
            }
168
        }
169 315
        $relationObject->setLinks($links);
170 315
        $relationObject->setMeta($meta);
171
172 315
        return $this;
173
    }
174
175
    /**
176
     * @param string $name
177
     *
178
     * @return bool
179
     */
180 45
    public function hasRelation(string $name): bool
181
    {
182 45
        return array_key_exists($name, $this->relations);
183
    }
184
185
    /**
186
     * @param $name
187
     *
188
     * @return static
189
     */
190 9
    public function unsetRelation(string $name)
191
    {
192 9
        unset($this->relations[$name]);
193
194 9
        return $this;
195
    }
196
}
197