Passed
Push — master ( af341e...2b2ec9 )
by Jonas
07:18 queued 05:16
created

IsJsonRelation::getJsonGrammar()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 14
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
cc 4
eloc 9
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 14
ccs 8
cts 8
cp 1
crap 4
rs 9.9666
1
<?php
2
3
namespace Staudenmeir\EloquentJsonRelations\Relations\Traits;
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 245
    public function __construct()
36
    {
37 245
        $args = func_get_args();
38
39 245
        $foreignKey = explode('[]->', $args[2]);
40
41 245
        $this->path = $foreignKey[0];
42 245
        $this->key = $foreignKey[1] ?? null;
43
44 245
        parent::__construct(...$args);
45
    }
46
47
    /**
48
     * Hydrate the pivot relationship on the models.
49
     *
50
     * @param \Illuminate\Database\Eloquent\Collection $models
51
     * @param \Illuminate\Database\Eloquent\Model $parent
52
     * @param callable $callback
53
     * @return void
54
     */
55 39
    public function hydratePivotRelation(Collection $models, Model $parent, callable $callback)
56
    {
57 39
        foreach ($models as $i => $model) {
58 39
            $clone = clone $model;
59
60 39
            $models[$i] = $clone->setRelation(
61 39
                $this->getPivotAccessor(),
62 39
                $this->pivotRelation($clone, $parent, $callback)
63
            );
64
        }
65
    }
66
67
    /**
68
     * Get the pivot relationship from the query.
69
     *
70
     * @param \Illuminate\Database\Eloquent\Model $model
71
     * @param \Illuminate\Database\Eloquent\Model $parent
72
     * @param callable $callback
73
     * @return \Illuminate\Database\Eloquent\Model
74
     */
75 39
    protected function pivotRelation(Model $model, Model $parent, callable $callback)
76
    {
77 39
        $records = $callback($model, $parent);
78
79 39
        $attributes = $this->pivotAttributes($model, $parent, $records);
80
81 39
        return Pivot::fromAttributes($model, $attributes, null, true);
82
    }
83
84
    /**
85
     * Get the pivot attributes from a model.
86
     *
87
     * @param \Illuminate\Database\Eloquent\Model $model
88
     * @param \Illuminate\Database\Eloquent\Model $parent
89
     * @param array $records
90
     * @return array
91
     */
92
    abstract public function pivotAttributes(Model $model, Model $parent, array $records);
93
94
    /**
95
     * Execute the query and get the first related model.
96
     *
97
     * @param array $columns
98
     * @return mixed
99
     */
100 5
    public function first($columns = ['*'])
101
    {
102 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

102
        return $this->/** @scrutinizer ignore-call */ take(1)->get($columns)->first();
Loading history...
103
    }
104
105
    /**
106
     * Get the fully qualified path of the relationship.
107
     *
108
     * @return string
109
     */
110 108
    public function getQualifiedPath()
111
    {
112 108
        return $this->parent->qualifyColumn($this->path);
113
    }
114
115
    /**
116
     * Get the JSON grammar.
117
     *
118
     * @param \Illuminate\Database\Eloquent\Builder $query
119
     * @return \Staudenmeir\EloquentJsonRelations\Grammars\JsonGrammar
120
     */
121 141
    protected function getJsonGrammar(Builder $query)
122
    {
123 141
        $driver = $query->getConnection()->getDriverName();
124
125
        switch ($driver) {
126 141
            case 'mysql':
127 56
                return $query->getConnection()->withTablePrefix(new MySqlGrammar());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $query->getConnec...rammars\MySqlGrammar()) also could return the type Illuminate\Database\Conn...tabase\Eloquent\Builder which is incompatible with the documented return type Staudenmeir\EloquentJson...ns\Grammars\JsonGrammar.
Loading history...
128 85
            case 'pgsql':
129 56
                return $query->getConnection()->withTablePrefix(new PostgresGrammar());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $query->getConnec...mars\PostgresGrammar()) also could return the type Illuminate\Database\Conn...tabase\Eloquent\Builder which is incompatible with the documented return type Staudenmeir\EloquentJson...ns\Grammars\JsonGrammar.
Loading history...
130 29
            case 'sqlsrv':
131 29
                return $query->getConnection()->withTablePrefix(new SqlServerGrammar());
0 ignored issues
show
Bug Best Practice introduced by
The expression return $query->getConnec...ars\SqlServerGrammar()) also could return the type Illuminate\Database\Conn...tabase\Eloquent\Builder which is incompatible with the documented return type Staudenmeir\EloquentJson...ns\Grammars\JsonGrammar.
Loading history...
132
        }
133
134
        throw new RuntimeException('This database is not supported.'); // @codeCoverageIgnore
135
    }
136
137
    /**
138
     * Get the name of the pivot accessor for this relationship.
139
     *
140
     * @return string
141
     */
142 39
    public function getPivotAccessor(): string
143
    {
144 39
        return 'pivot';
145
    }
146
147
    /**
148
     * Get the base path of the foreign key.
149
     *
150
     * @return string
151
     */
152 6
    public function getForeignKeyPath(): string
153
    {
154 6
        return $this->path;
155
    }
156
}
157