QueryBuilder::setTableAndKeyNames()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
3
namespace Sfneal\Builders;
4
5
use Illuminate\Database\Eloquent\Builder as EloquentBuilder;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Database\Query\Builder;
8
use Illuminate\Support\Facades\DB;
9
use Sfneal\Builders\Traits\CountAndPaginate;
10
use Sfneal\Models\Model;
11
12
class QueryBuilder extends EloquentBuilder
13
{
14
    use CountAndPaginate;
15
16
    /**
17
     * @var string Declare a custom MySQL select string to be used by selectRawJson()
18
     */
19
    protected $selectRawJson;
20
21
    /**
22
     * @var Model
23
     */
24
    protected $targetModel;
25
26
    /**
27
     * @var string Name of the User model's table
28
     */
29
    protected $tableName;
30
31
    /**
32
     * @var string Name of the User model's primary key
33
     */
34
    protected $primaryKeyName;
35
36
    /**
37
     * UserBuilder constructor.
38
     *
39
     * @param  Builder  $query
40
     */
41
    public function __construct(Builder $query)
42
    {
43
        $this->setTableAndKeyNames();
44
        parent::__construct($query);
45
    }
46
47
    /**
48
     * Set the $tableName & $primaryKeyName properties.
49
     *
50
     * @return void
51
     */
52
    private function setTableAndKeyNames(): void
53
    {
54
        // Only declare table & pk if the target model is declared
55
        if (isset($this->targetModel)) {
56
            $this->tableName = $this->targetModel::getTableName();
57
            $this->primaryKeyName = $this->targetModel::getPrimaryKeyName();
58
        }
59
    }
60
61
    /**
62
     * Retrieve a concatenation string that combines two columns in a table into a single column.
63
     *
64
     * @param  string  $column1
65
     * @param  string  $column2
66
     * @param  string  $delimiter
67
     * @return string
68
     */
69
    protected function concatColumns(string $column1, string $column2, string $delimiter = ' '): string
70
    {
71
        // Prepend table name if it's been declared
72
        $column1 = (isset($this->tableName)) ? "{$this->tableName}.{$column1}" : $column1;
73
        $column2 = (isset($this->tableName)) ? "{$this->tableName}.{$column2}" : $column2;
74
75
        // Use Sqlite syntax
76
        if (DB::connection()->getDatabaseName() == ':memory:') {
77
            return "{$column1} || '{$delimiter}' || {$column2}";
78
        }
79
80
        // Use standard syntax
81
        else {
82
            return "concat({$column1}, '{$delimiter}', {$column2})";
83
        }
84
    }
85
86
    /**
87
     * Retrieve a MySQL if statement that can be used within a query.
88
     *
89
     * @param  string  $condition
90
     * @param  string  $expr_true
91
     * @param  string  $expr_false
92
     * @return string
93
     */
94
    protected function ifStatement(string $condition, string $expr_true, string $expr_false): string
95
    {
96
        // Use Sqlite syntax
97
        if (DB::connection()->getDatabaseName() == ':memory:') {
98
            return "CASE WHEN {$condition} THEN {$expr_true} ELSE {$expr_false} END";
99
        }
100
101
        // Use standard syntax
102
        else {
103
            return "if({$condition}, {$expr_true}, {$expr_false})";
104
        }
105
    }
106
107
    /**
108
     * Wildcard where like query to determine if any part of the value is found.
109
     *
110
     * @param  string  $column
111
     * @param  $value
112
     * @param  bool  $leadingWildcard
113
     * @param  bool  $trailingWildcard
114
     * @param  string  $boolean
115
     * @return $this
116
     */
117
    public function whereLike(string $column,
118
                                     $value,
119
                              bool $leadingWildcard = true,
120
                              bool $trailingWildcard = true,
121
                              string $boolean = 'and'): self
122
    {
123
        $this->where(
124
            $column,
125
            'LIKE',
126
            ($leadingWildcard ? '%' : '').$value.($trailingWildcard ? '%' : ''),
127
            $boolean
128
        );
129
130
        return $this;
131
    }
132
133
    /**
134
     * Wildcard or where like query to determine if any part of the value is found.
135
     *
136
     * @param  string  $column
137
     * @param  $value
138
     * @param  bool  $leadingWildcard
139
     * @param  bool  $trailingWildcard
140
     * @return $this
141
     */
142
    public function orWhereLike(string $column, $value, bool $leadingWildcard = true, bool $trailingWildcard = true): self
143
    {
144
        $this->orWhere(
145
            $column,
146
            'LIKE',
147
            ($leadingWildcard ? '%' : '').$value.($trailingWildcard ? '%' : '')
148
        );
149
150
        return $this;
151
    }
152
153
    /**
154
     * Retrieve a flat, single-dimensional array of results without keys.
155
     *
156
     * @param  string  $column
157
     * @return array
158
     */
159
    public function getFlatArray(string $column): array
160
    {
161
        return $this->distinct()->pluck($column)->toArray();
0 ignored issues
show
Bug introduced by
The method distinct() does not exist on Sfneal\Builders\QueryBuilder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

161
        return $this->/** @scrutinizer ignore-call */ distinct()->pluck($column)->toArray();
Loading history...
162
    }
163
164
    /**
165
     * Retrieve raw query results formatted for Ajax select2 form inputs.
166
     *
167
     * @param  string|null  $raw
168
     * @return $this
169
     */
170
    public function selectRawJson(string $raw = null): self
171
    {
172
        $this->withoutGlobalScopes();
173
        $this->selectRaw($raw ?? $this->selectRawJson);
0 ignored issues
show
Bug introduced by
The method selectRaw() does not exist on Sfneal\Builders\QueryBuilder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

173
        $this->/** @scrutinizer ignore-call */ 
174
               selectRaw($raw ?? $this->selectRawJson);
Loading history...
174
175
        return $this;
176
    }
177
178
    /**
179
     * Order query results by the 'created_at' column.
180
     *
181
     * @param  string  $direction
182
     * @return $this
183
     */
184
    public function orderByCreatedAt(string $direction = 'desc'): self
185
    {
186
        $this->orderBy('created_at', $direction);
0 ignored issues
show
Bug introduced by
The method orderBy() does not exist on Sfneal\Builders\QueryBuilder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

186
        $this->/** @scrutinizer ignore-call */ 
187
               orderBy('created_at', $direction);
Loading history...
187
188
        return $this;
189
    }
190
191
    /**
192
     * Retrieve the 'next' Model in the database.
193
     *
194
     * @param  int|null  $model_id
195
     * @return QueryBuilder|Collection|Model|null
196
     */
197
    public function getNextModel(int $model_id = null)
198
    {
199
        return $this->find($this->getNextModelId($model_id));
200
    }
201
202
    /**
203
     * Retrieve the 'previous' Model in the database.
204
     *
205
     * @param  int|null  $model_id
206
     * @return QueryBuilder|Collection|Model|null
207
     */
208
    public function getPreviousModel(int $model_id = null)
209
    {
210
        return $this->find($this->getPreviousModelId($model_id));
211
    }
212
213
    /**
214
     * Retrieve the 'next' Model's ID.
215
     *
216
     * @param  int|null  $model_id
217
     * @return mixed
218
     */
219
    public function getNextModelId(int $model_id = null)
220
    {
221
        return $this
222
            ->where($this->model->getKeyName(), '>', $model_id ?? $this->model->getKey())
223
            ->min($this->model->getKeyName());
0 ignored issues
show
Bug introduced by
The method min() does not exist on Sfneal\Builders\QueryBuilder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

223
            ->/** @scrutinizer ignore-call */ min($this->model->getKeyName());
Loading history...
224
    }
225
226
    /**
227
     * Retrieve the 'previous' Model's ID.
228
     *
229
     * @param  int|null  $model_id
230
     * @return mixed
231
     */
232
    public function getPreviousModelId(int $model_id = null)
233
    {
234
        return $this
235
            ->where($this->model->getKeyName(), '<', $model_id ?? $this->model->getKey())
236
            ->max($this->model->getKeyName());
0 ignored issues
show
Bug introduced by
The method max() does not exist on Sfneal\Builders\QueryBuilder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

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

236
            ->/** @scrutinizer ignore-call */ max($this->model->getKeyName());
Loading history...
237
    }
238
}
239