Completed
Push — master ( 2c2533...1543ff )
by Jonas
03:11
created

IsJsonRelation::get()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 2
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Staudenmeir\EloquentJsonRelations\Relations;
4
5
use Illuminate\Database\Eloquent\Builder;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Eloquent\Relations\Pivot;
9
use RuntimeException;
10
use Staudenmeir\EloquentJsonRelations\Grammars\MySqlGrammar;
11
use Staudenmeir\EloquentJsonRelations\Grammars\PostgresGrammar;
12
use Staudenmeir\EloquentJsonRelations\Grammars\SqlServerGrammar;
13
14
trait IsJsonRelation
15
{
16
    /**
17
     * The base path of the foreign key.
18
     *
19
     * @var string
20
     */
21
    protected $path;
22
23
    /**
24
     * The optional object key of the foreign key.
25
     *
26
     * @var string
27
     */
28
    protected $key;
29
30
    /**
31
     * Create a new JSON relationship instance.
32
     *
33
     * @return void
34
     */
35 70
    public function __construct()
36
    {
37 70
        $args = func_get_args();
38
39 70
        $foreignKey = explode('[]->', $args[2]);
40
41 70
        $this->path = $foreignKey[0];
42 70
        $this->key = $foreignKey[1] ?? null;
43
44 70
        parent::__construct(...$args);
45 70
    }
46
47
    /**
48
     * Execute the query as a "select" statement.
49
     *
50
     * @param array $columns
51
     * @return \Illuminate\Database\Eloquent\Collection
52
     */
53 38
    public function get($columns = ['*'])
54
    {
55 38
        $models = parent::get($columns);
56
57 38
        if ($this->key && !empty($this->parent->getAttributes())) {
58 18
            $this->hydratePivotRelation($models, $this->parent);
59
        }
60
61 38
        return $models;
62
    }
63
64
    /**
65
     * Hydrate the pivot relationship on the models.
66
     *
67
     * @param \Illuminate\Database\Eloquent\Collection $models
68
     * @param \Illuminate\Database\Eloquent\Model $parent
69
     * @return void
70
     */
71 26
    protected function hydratePivotRelation(Collection $models, Model $parent)
72
    {
73 26
        foreach ($models as $i => $model) {
74 26
            $clone = clone $model;
75
76 26
            $models[$i] = $clone->setRelation('pivot', $this->pivotRelation($clone, $parent));
77
        }
78 26
    }
79
80
    /**
81
     * Get the pivot relationship from the query.
82
     *
83
     * @param \Illuminate\Database\Eloquent\Model $model
84
     * @param \Illuminate\Database\Eloquent\Model $parent
85
     * @return \Illuminate\Database\Eloquent\Model
86
     */
87 26
    protected function pivotRelation(Model $model, Model $parent)
88
    {
89 26
        $attributes = $this->pivotAttributes($model, $parent);
90
91 26
        return Pivot::fromAttributes($model, $attributes, null, true);
92
    }
93
94
    /**
95
     * Get the pivot attributes from a model.
96
     *
97
     * @param \Illuminate\Database\Eloquent\Model $model
98
     * @param \Illuminate\Database\Eloquent\Model $parent
99
     * @return array
100
     */
101
    abstract protected function pivotAttributes(Model $model, Model $parent);
102
103
    /**
104
     * Execute the query and get the first related model.
105
     *
106
     * @param array $columns
107
     * @return mixed
108
     */
109 4
    public function first($columns = ['*'])
110
    {
111 4
        return $this->take(1)->get($columns)->first();
0 ignored issues
show
Bug introduced by
It seems like take() 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

111
        return $this->/** @scrutinizer ignore-call */ take(1)->get($columns)->first();
Loading history...
112
    }
113
114
    /**
115
     * Get the fully qualified path of the relationship.
116
     *
117
     * @return string
118
     */
119 12
    public function getQualifiedPath()
120
    {
121 12
        return $this->parent->qualifyColumn($this->path);
122
    }
123
124
    /**
125
     * Get the JSON grammar.
126
     *
127
     * @param \Illuminate\Database\Eloquent\Builder $query
128
     * @return \Staudenmeir\EloquentJsonRelations\Grammars\JsonGrammar
129
     */
130 16
    protected function getJsonGrammar(Builder $query)
131
    {
132 16
        $driver = $query->getConnection()->getDriverName();
133
134 16
        switch ($driver) {
135 16
            case 'mysql':
136 8
                return new MySqlGrammar;
137 8
            case 'pgsql':
138 8
                return new PostgresGrammar;
139
            case 'sqlsrv':
140
                return new SqlServerGrammar;
141
        }
142
143
        throw new RuntimeException('This database is not supported.'); // @codeCoverageIgnore
144
    }
145
}
146