Passed
Push — experiment/id-key-conversion ( cbc737...bb5ee1 )
by Bas
03:11
created

IsAranguentModel::__get()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 7
ccs 4
cts 4
cp 1
rs 10
cc 2
nc 2
nop 1
crap 2
1
<?php
2
3
namespace LaravelFreelancerNL\Aranguent\Eloquent\Concerns;
4
5
use Closure;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Support\Facades\DB;
8
use Illuminate\Support\Str;
9
use LaravelFreelancerNL\Aranguent\Eloquent\Builder;
10
use LaravelFreelancerNL\Aranguent\Query\Builder as QueryBuilder;
11
use LaravelFreelancerNL\FluentAQL\QueryBuilder as ArangoQueryBuilder;
12
13
trait IsAranguentModel
14
{
15
    use HasAranguentRelationships;
16
17
    /**
18
     * Insert the given attributes and set the ID on the model.
19
     *
20
     * @param  \Illuminate\Database\Eloquent\Builder  $query
21
     * @param  array  $attributes
22
     * @return void
23
     */
24 9
    protected function insertAndSetId(\Illuminate\Database\Eloquent\Builder $query, $attributes)
25
    {
26 9
        $id = $query->insertGetId($attributes, $keyName = $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

26
        $id = $query->insertGetId($attributes, $keyName = $this->/** @scrutinizer ignore-call */ getKeyName());
Loading history...
27
28 9
        $this->setAttribute($keyName, $id);
0 ignored issues
show
Bug introduced by
The method setAttribute() does not exist on LaravelFreelancerNL\Aran...ncerns\IsAranguentModel. Did you maybe mean setKeyAttribute()? ( Ignorable by Annotation )

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

28
        $this->/** @scrutinizer ignore-call */ 
29
               setAttribute($keyName, $id);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
29 9
        if ($keyName === '_id') {
30
            $matches = [];
31
            preg_match('/\/(.*)$/', $id, $matches);
0 ignored issues
show
Bug introduced by
It seems like $id can also be of type Illuminate\Database\Eloquent\Builder; however, parameter $subject of preg_match() does only seem to accept string, 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

31
            preg_match('/\/(.*)$/', /** @scrutinizer ignore-type */ $id, $matches);
Loading history...
32
33
            $this->setAttribute('_key', $matches[1]);
34
        }
35 9
    }
36
37
    /**
38
     * @override
39
     * Create a new Eloquent query builder for the model.
40
     *
41
     * @param QueryBuilder $query
42
     *
43
     * @return Builder
44
     */
45 137
    public function newEloquentBuilder($query)
46
    {
47 137
        return new Builder($query);
48
    }
49
50
    /**
51
     * Get a new query builder instance for the connection.
52
     *
53
     * @return \Illuminate\Database\Query\Builder
54
     */
55 137
    protected function newBaseQueryBuilder()
56
    {
57 137
        return $this->getConnection()->query();
0 ignored issues
show
Bug introduced by
It seems like getConnection() 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

57
        return $this->/** @scrutinizer ignore-call */ getConnection()->query();
Loading history...
58
    }
59
60
    /**
61
     * Dynamically set attributes on the model.
62
     *
63
     * @param  string  $key
64
     * @param  mixed  $value
65
     * @return void
66
     */
67 21
    public function __set($key, $value)
68
    {
69
        // Laravel's mutators don't differentiate between id and _id, so we catch ArangoDB's _id here.
70 21
        if ($key === 'id') {
71 1
            $this->attributes['_id'] = $this->getTable() . '/' . $value;
0 ignored issues
show
Bug introduced by
It seems like getTable() 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

71
            $this->attributes['_id'] = $this->/** @scrutinizer ignore-call */ getTable() . '/' . $value;
Loading history...
Bug Best Practice introduced by
The property attributes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
72
        }
73
74 21
        if ($key === '_id') {
75 1
            $this->attributes['id'] = explode('/', $value)[1];
76
        }
77
78 21
        $this->setAttribute($key, $value);
79 21
    }
80
81
    /**
82
     * Map the id attribute commonly used in Laravel to the primary key for third-party compatibility.
83
     * In ArangoDB '_key' is the equivalent of 'id' in sql databases.
84
     *
85
     * @param  string  $value
86
     * @return void
87
     */
88
    public function setKeyAttribute($value)
89
    {
90
        $this->attributes['_key'] = $value;
0 ignored issues
show
Bug Best Practice introduced by
The property attributes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
91
92
        $this->updateIdWithKey($value);
93
    }
94
95
    /**
96
     * @param  string  $key
97
     */
98
    protected function updateIdWithKey(string $key)
99
    {
100
        if (! isset($this->attributes['_id'])) {
101
            return;
102
        }
103
104
        $id = preg_replace("/[a-zA-Z0-9_-]+\/\K.+/i", $key, $this->attributes['_id']);
105
        $this->attributes['_id'] = $id;
0 ignored issues
show
Bug Best Practice introduced by
The property attributes does not exist. Although not strictly required by PHP, it is generally a best practice to declare properties explicitly.
Loading history...
106
    }
107
108
    /**
109
     * Qualify the given column name by the model's table.
110
     *
111
     * @param string $column
112
     *
113
     * @return string
114
     */
115 65
    public function qualifyColumn($column)
116
    {
117 65
        $tableReferer = Str::singular($this->getTable()) . 'Doc';
118
119 65
        if (Str::startsWith($column, $tableReferer . '.')) {
120
            return $column;
121
        }
122
123 65
        return $tableReferer . '.' . $column;
124
    }
125
126
    /**
127
     * Get the default foreign key name for the model.
128
     *
129
     * @return string
130
     */
131 8
    public function getForeignKey()
132
    {
133 8
        $keyName = $this->getKeyName();
134
135 8
        if ($keyName[0] != '_') {
136 8
            $keyName = '_' . $keyName;
137
        }
138
139 8
        return Str::snake(class_basename($this)) . $keyName;
140
    }
141
142 2
    protected function fromAqb(ArangoQueryBuilder|Closure $aqb): Collection
143
    {
144 2
        if ($aqb instanceof Closure) {
145
            /** @phpstan-ignore-next-line */
146 1
            $aqb = $aqb(DB::aqb());
147
        }
148 2
        $connection = $this->getConnection();
149 2
        $results = $connection->execute($aqb->get());
150 2
        return $this->hydrate($results);
0 ignored issues
show
Bug introduced by
It seems like hydrate() 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

150
        return $this->/** @scrutinizer ignore-call */ hydrate($results);
Loading history...
151
    }
152
}
153