Passed
Pull Request — master (#52)
by
unknown
12:04
created

HasJsonRelationships::getAttributeFromArray()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 3
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 7
ccs 5
cts 5
cp 1
crap 2
rs 10
1
<?php
2
3
namespace Staudenmeir\EloquentJsonRelations;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Model;
7
use Illuminate\Database\Eloquent\Relations\BelongsTo;
8
use Illuminate\Database\Eloquent\Relations\HasMany;
9
use Illuminate\Database\Eloquent\Relations\HasManyThrough;
10
use Illuminate\Database\Eloquent\Relations\HasOne;
11
use Illuminate\Database\Eloquent\Relations\HasOneThrough;
12
use Illuminate\Database\Eloquent\Relations\MorphMany;
13
use Illuminate\Database\Eloquent\Relations\MorphOne;
14
use Illuminate\Support\Str;
15
use Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson;
16
use Staudenmeir\EloquentJsonRelations\Relations\HasManyJson;
17
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\BelongsTo as BelongsToPostgres;
18
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasMany as HasManyPostgres;
19
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasManyThrough as HasManyThroughPostgres;
20
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasOne as HasOnePostgres;
21
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\HasOneThrough as HasOneThroughPostgres;
22
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\MorphMany as MorphManyPostgres;
23
use Staudenmeir\EloquentJsonRelations\Relations\Postgres\MorphOne as MorphOnePostgres;
24
25
trait HasJsonRelationships
26
{
27
    /**
28
     * Get an attribute from the model.
29
     *
30
     * @param string $key
31
     * @return mixed
32
     */
33 284
    public function getAttribute($key)
34
    {
35 284
        $attribute = preg_split('/(->|\[\])/', $key)[0];
36
37 284
        if (array_key_exists($attribute, $this->attributes)) {
38 278
            return $this->getAttributeValue($key);
39
        }
40
41 214
        return parent::getAttribute($key);
42
    }
43
44
    /**
45
     * Get an attribute from the $attributes array.
46
     *
47
     * @param  string  $key
48
     * @return mixed
49
     */
50 278
    public function getAttributeFromArray($key)
51
    {
52 278
        if (Str::contains($key, '->')) {
53 155
            return $this->getAttributeValue($key);
54
        }
55 155
56 3
        return parent::getAttributeFromArray($key);
57
    }
58 3
59
    /**
60
     * Get a plain attribute (not a relationship).
61 155
     *
62
     * @param string $key
63 155
     * @return mixed
64
     */
65
    public function getAttributeValue($key)
66 278
    {
67
        if (Str::contains($key, '->')) {
68
            [$key, $path] = explode('->', $key, 2);
69
70
            if (substr($key, -2) === '[]') {
71
                $key = substr($key, 0, -2);
72
73
                $path = '*.'.$path;
74
            }
75
76
            $path = str_replace(['->', '[]'], ['.', '.*'], $path);
77
78 24
            return data_get($this->getAttributeValue($key), $path);
79
        }
80 24
81 6
        return parent::getAttributeValue($key);
82
    }
83
84 18
    /**
85
     * Instantiate a new HasOne relationship.
86
     *
87
     * @param \Illuminate\Database\Eloquent\Builder $query
88
     * @param \Illuminate\Database\Eloquent\Model $parent
89
     * @param string $foreignKey
90
     * @param string $localKey
91
     * @return \Illuminate\Database\Eloquent\Relations\HasOne
92
     */
93
    protected function newHasOne(Builder $query, Model $parent, $foreignKey, $localKey)
94
    {
95
        if ($query->getConnection()->getDriverName() === 'pgsql') {
96
            return new HasOnePostgres($query, $parent, $foreignKey, $localKey);
97
        }
98
99 24
        return new HasOne($query, $parent, $foreignKey, $localKey);
100
    }
101 24
102 6
    /**
103
     * Instantiate a new HasOneThrough relationship.
104
     *
105 18
     * @param \Illuminate\Database\Eloquent\Builder $query
106
     * @param \Illuminate\Database\Eloquent\Model $farParent
107
     * @param \Illuminate\Database\Eloquent\Model $throughParent
108
     * @param string $firstKey
109
     * @param string $secondKey
110
     * @param string $localKey
111
     * @param string $secondLocalKey
112
     * @return \Illuminate\Database\Eloquent\Relations\HasOneThrough
113
     */
114
    protected function newHasOneThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
115
    {
116
        if ($query->getConnection()->getDriverName() === 'pgsql') {
117
            return new HasOneThroughPostgres($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
118 20
        }
119
120 20
        return new HasOneThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
121 5
    }
122
123
    /**
124 15
     * Instantiate a new MorphOne relationship.
125
     *
126
     * @param \Illuminate\Database\Eloquent\Builder $query
127
     * @param \Illuminate\Database\Eloquent\Model $parent
128
     * @param string $type
129
     * @param string $id
130
     * @param string $localKey
131
     * @return \Illuminate\Database\Eloquent\Relations\MorphOne
132
     */
133
    protected function newMorphOne(Builder $query, Model $parent, $type, $id, $localKey)
134
    {
135
        if ($query->getConnection()->getDriverName() === 'pgsql') {
136
            return new MorphOnePostgres($query, $parent, $type, $id, $localKey);
137 36
        }
138
139 36
        return new MorphOne($query, $parent, $type, $id, $localKey);
140 9
    }
141
142
    /**
143 27
     * Instantiate a new BelongsTo relationship.
144
     *
145
     * @param \Illuminate\Database\Eloquent\Builder $query
146
     * @param \Illuminate\Database\Eloquent\Model $child
147
     * @param string $foreignKey
148
     * @param string $ownerKey
149
     * @param string $relation
150
     * @return \Illuminate\Database\Eloquent\Relations\BelongsTo
151
     */
152
    protected function newBelongsTo(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
153
    {
154
        if ($query->getConnection()->getDriverName() === 'pgsql') {
155 24
            return new BelongsToPostgres($query, $child, $foreignKey, $ownerKey, $relation);
156
        }
157 24
158 6
        return new BelongsTo($query, $child, $foreignKey, $ownerKey, $relation);
159
    }
160
161 18
    /**
162
     * Instantiate a new HasMany relationship.
163
     *
164
     * @param \Illuminate\Database\Eloquent\Builder $query
165
     * @param \Illuminate\Database\Eloquent\Model $parent
166
     * @param string $foreignKey
167
     * @param string $localKey
168
     * @return \Illuminate\Database\Eloquent\Relations\HasMany
169
     */
170
    protected function newHasMany(Builder $query, Model $parent, $foreignKey, $localKey)
171
    {
172
        if ($query->getConnection()->getDriverName() === 'pgsql') {
173
            return new HasManyPostgres($query, $parent, $foreignKey, $localKey);
174
        }
175
176 24
        return new HasMany($query, $parent, $foreignKey, $localKey);
177
    }
178 24
179 6
    /**
180
     * Instantiate a new HasManyThrough relationship.
181
     *
182 18
     * @param \Illuminate\Database\Eloquent\Builder $query
183
     * @param \Illuminate\Database\Eloquent\Model $farParent
184
     * @param \Illuminate\Database\Eloquent\Model $throughParent
185
     * @param string $firstKey
186
     * @param string $secondKey
187
     * @param string $localKey
188
     * @param string $secondLocalKey
189
     * @return \Illuminate\Database\Eloquent\Relations\HasManyThrough
190
     */
191
    protected function newHasManyThrough(Builder $query, Model $farParent, Model $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey)
192
    {
193
        if ($query->getConnection()->getDriverName() === 'pgsql') {
194
            return new HasManyThroughPostgres($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
195 20
        }
196
197 20
        return new HasManyThrough($query, $farParent, $throughParent, $firstKey, $secondKey, $localKey, $secondLocalKey);
198 5
    }
199
200
    /**
201 15
     * Instantiate a new MorphMany relationship.
202
     *
203
     * @param \Illuminate\Database\Eloquent\Builder $query
204
     * @param \Illuminate\Database\Eloquent\Model $parent
205
     * @param string $type
206
     * @param string $id
207
     * @param string $localKey
208
     * @return \Illuminate\Database\Eloquent\Relations\MorphMany
209
     */
210
    protected function newMorphMany(Builder $query, Model $parent, $type, $id, $localKey)
211
    {
212
        if ($query->getConnection()->getDriverName() === 'pgsql') {
213 70
            return new MorphManyPostgres($query, $parent, $type, $id, $localKey);
214
        }
215 70
216 70
        return new MorphMany($query, $parent, $type, $id, $localKey);
217
    }
218
219
    /**
220 70
     * Define an inverse one-to-one or many JSON relationship.
221
     *
222 70
     * @param string $related
223
     * @param string $foreignKey
224 70
     * @param string $ownerKey
225 70
     * @param string $relation
226
     * @return \Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson
227
     */
228
    public function belongsToJson($related, $foreignKey, $ownerKey = null, $relation = null)
229
    {
230
        if (is_null($relation)) {
231
            $relation = $this->guessBelongsToRelation();
0 ignored issues
show
Bug introduced by
It seems like guessBelongsToRelation() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

231
            /** @scrutinizer ignore-call */ 
232
            $relation = $this->guessBelongsToRelation();
Loading history...
232
        }
233
234
        /** @var \Illuminate\Database\Eloquent\Model $instance */
235
        $instance = $this->newRelatedInstance($related);
0 ignored issues
show
Bug introduced by
It seems like newRelatedInstance() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

235
        /** @scrutinizer ignore-call */ 
236
        $instance = $this->newRelatedInstance($related);
Loading history...
236
237
        $ownerKey = $ownerKey ?: $instance->getKeyName();
238
239
        return $this->newBelongsToJson(
240
            $instance->newQuery(),
241
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\EloquentJson...ns\HasJsonRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $child of Staudenmeir\EloquentJson...ips::newBelongsToJson(). ( Ignorable by Annotation )

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

241
            /** @scrutinizer ignore-type */ $this,
Loading history...
242
            $foreignKey,
243 70
            $ownerKey,
244
            $relation
245 70
        );
246
    }
247
248
    /**
249
     * Instantiate a new BelongsToJson relationship.
250
     *
251
     * @param \Illuminate\Database\Eloquent\Builder $query
252
     * @param \Illuminate\Database\Eloquent\Model $child
253
     * @param string $foreignKey
254
     * @param string $ownerKey
255
     * @param string $relation
256 36
     * @return \Staudenmeir\EloquentJsonRelations\Relations\BelongsToJson
257
     */
258
    protected function newBelongsToJson(Builder $query, Model $child, $foreignKey, $ownerKey, $relation)
259 36
    {
260
        return new BelongsToJson($query, $child, $foreignKey, $ownerKey, $relation);
261 36
    }
262
263 36
    /**
264 36
     * Define a one-to-many JSON relationship.
265
     *
266 36
     * @param string $related
267
     * @param string $foreignKey
268
     * @param string $localKey
269
     * @return \Staudenmeir\EloquentJsonRelations\Relations\HasManyJson
270
     */
271
    public function hasManyJson($related, $foreignKey, $localKey = null)
272
    {
273
        /** @var \Illuminate\Database\Eloquent\Model $instance */
274
        $instance = $this->newRelatedInstance($related);
275
276
        $localKey = $localKey ?: $this->getKeyName();
0 ignored issues
show
Bug introduced by
It seems like getKeyName() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

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

276
        $localKey = $localKey ?: $this->/** @scrutinizer ignore-call */ getKeyName();
Loading history...
277
278
        return $this->newHasManyJson(
279
            $instance->newQuery(),
280 36
            $this,
0 ignored issues
show
Bug introduced by
$this of type Staudenmeir\EloquentJson...ns\HasJsonRelationships is incompatible with the type Illuminate\Database\Eloquent\Model expected by parameter $parent of Staudenmeir\EloquentJson...ships::newHasManyJson(). ( Ignorable by Annotation )

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

280
            /** @scrutinizer ignore-type */ $this,
Loading history...
281
            $instance->getTable().'.'.$foreignKey,
282 36
            $localKey
283
        );
284
    }
285
286
    /**
287
     * Instantiate a new HasManyJson relationship.
288
     *
289
     * @param \Illuminate\Database\Eloquent\Builder $query
290
     * @param \Illuminate\Database\Eloquent\Model $parent
291
     * @param string $foreignKey
292
     * @param string $localKey
293
     * @return \Staudenmeir\EloquentJsonRelations\Relations\HasManyJson
294
     */
295
    protected function newHasManyJson(Builder $query, Model $parent, $foreignKey, $localKey)
296
    {
297
        return new HasManyJson($query, $parent, $foreignKey, $localKey);
298
    }
299
}
300