Completed
Push — master ( 1543ff...8389b3 )
by Jonas
05:36
created

IsJsonRelation::first()   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
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 2
cts 2
cp 1
crap 1
rs 10
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 97
    public function __construct()
36
    {
37 97
        $args = func_get_args();
38
39 97
        $foreignKey = explode('[]->', $args[2]);
40
41 97
        $this->path = $foreignKey[0];
42 97
        $this->key = $foreignKey[1] ?? null;
43
44 97
        parent::__construct(...$args);
45 97
    }
46
47
    /**
48
     * Execute the query as a "select" statement.
49
     *
50
     * @param array $columns
51
     * @return \Illuminate\Database\Eloquent\Collection
52
     */
53 53
    public function get($columns = ['*'])
54
    {
55 53
        $models = parent::get($columns);
56
57 53
        if ($this->key && !empty($this->parent->getAttributes())) {
58 25
            $this->hydratePivotRelation($models, $this->parent);
59
        }
60
61 53
        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 35
    protected function hydratePivotRelation(Collection $models, Model $parent)
72
    {
73 35
        foreach ($models as $i => $model) {
74 35
            $clone = clone $model;
75
76 35
            $models[$i] = $clone->setRelation('pivot', $this->pivotRelation($clone, $parent));
77
        }
78 35
    }
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 35
    protected function pivotRelation(Model $model, Model $parent)
88
    {
89 35
        $attributes = $this->pivotAttributes($model, $parent);
90
91 35
        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 5
    public function first($columns = ['*'])
110
    {
111 5
        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 15
    public function getQualifiedPath()
120
    {
121 15
        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 20
    protected function getJsonGrammar(Builder $query)
131
    {
132 20
        $driver = $query->getConnection()->getDriverName();
133
134 20
        switch ($driver) {
135 20
            case 'mysql':
136 8
                return new MySqlGrammar;
137 12
            case 'pgsql':
138 8
                return new PostgresGrammar;
139 4
            case 'sqlsrv':
140 4
                return new SqlServerGrammar;
141
        }
142
143
        throw new RuntimeException('This database is not supported.'); // @codeCoverageIgnore
144
    }
145
}
146