Passed
Push — master ( bc88db...f4b932 )
by Stephen
02:58
created

UserBuilder::whereUserNotIn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 2
nc 1
nop 2
dl 0
loc 5
rs 10
c 1
b 0
f 0
1
<?php
2
3
namespace Sfneal\Users\Builders;
4
5
use Closure;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Database\Eloquent\Model;
8
use Illuminate\Database\Query\Builder;
9
use Sfneal\Builders\QueryBuilder;
10
use Sfneal\Users\Builders\Interfaces\WhereUserInterface;
11
use Sfneal\Users\Models\User;
12
use Sfneal\Users\Scopes\UserActiveScope;
13
14
class UserBuilder extends QueryBuilder implements WhereUserInterface
15
{
16
    // todo: improve type hinting after tests are improved
17
18
    /**
19
     * @var string MySQL select objects to be queried in a raw json return
20
     */
21
    protected $selectRawJson;
22
23
    /**
24
     * @var Model|User
25
     */
26
    protected $targetModel = User::class;
27
28
    /**
29
     * UserBuilder constructor.
30
     *
31
     * @param Builder $query
32
     */
33
    public function __construct(Builder $query)
34
    {
35
        parent::__construct($query);
36
        $this->setSelectRawJson();
37
    }
38
39
    /**
40
     * Retrieve the User model's 'name' attribute by concatenating first and last name columns.
41
     *
42
     * @return string
43
     */
44
    private function concatName(): string
45
    {
46
        return $this->concatColumns('first_name', 'last_name');
47
    }
48
49
    /**
50
     * Retrieve the User model's 'name' attribute by concatenating nickname and last name columns.
51
     *
52
     * @return string
53
     */
54
    private function concatNickname(): string
55
    {
56
        return $this->concatColumns('nickname', 'last_name');
57
    }
58
59
    /**
60
     * Dynamically set the $selectRawJson.
61
     *
62
     * @return void
63
     */
64
    private function setSelectRawJson(): void
65
    {
66
        $raw = "{$this->tableName}.{$this->primaryKeyName} as id, ";
67
        $raw .= $this->ifStatement(
68
            "nickname is not null and {$this->tableName}.nickname_preferred=1",
69
            $this->concatNickname(),
70
            $this->concatName()
71
        );
72
        $raw .= ' as text';
73
        $this->selectRawJson = $raw;
74
    }
75
76
    /**
77
     * Find a User.
78
     *
79
     * @param int $user_id
80
     * @param string $operator
81
     * @param string $boolean
82
     * @return $this
83
     */
84
    public function whereUser(int $user_id, string $operator = '=', string $boolean = 'and')
85
    {
86
        $this->where('id', $operator, $user_id, $operator);
87
88
        return $this;
89
    }
90
91
    /**
92
     * Exclude a User.
93
     *
94
     * @param int $user_id
95
     * @param string $boolean
96
     * @return $this
97
     */
98
    public function whereUserNot(int $user_id, string $boolean = 'and')
99
    {
100
        $this->whereUser($user_id, '!=', $boolean);
101
102
        return $this;
103
    }
104
105
    /**
106
     * Scope query to User's that have an 'id' found in the array of $user_ids.
107
     *
108
     * @param array $user_ids
109
     * @param string $boolean
110
     * @param bool $not
111
     * @return $this|WhereUserInterface
112
     */
113
    public function whereUserIn(array $user_ids, string $boolean = 'and', bool $not = false)
114
    {
115
        $this->whereIn('id', $user_ids, $boolean, $not);
0 ignored issues
show
Bug introduced by
The method whereIn() does not exist on Sfneal\Users\Builders\UserBuilder. 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

115
        $this->/** @scrutinizer ignore-call */ 
116
               whereIn('id', $user_ids, $boolean, $not);
Loading history...
116
117
        return $this;
118
    }
119
120
    /**
121
     * Scope query to User's that does NOT have 'id' found in the array of $user_ids.
122
     *
123
     * @param array $user_ids
124
     * @param string $boolean
125
     * @return $this|WhereUserInterface
126
     */
127
    public function whereUserNotIn(array $user_ids, string $boolean = 'and')
128
    {
129
        $this->whereUserIn($user_ids, $boolean, true);
130
131
        return $this;
132
    }
133
134
    /**
135
     * Scope results to User's with a certain username.
136
     *
137
     * @param $value
138
     *
139
     * @return $this
140
     */
141
    public function whereUsername($value)
142
    {
143
        $this->where('username', '=', $value);
144
145
        return $this;
146
    }
147
148
    /**
149
     * Scope a query to User's with names starting with a particular string.
150
     *
151
     * @param string $name
152
     *
153
     * @return $this
154
     */
155
    public function whereNameLike(string $name)
156
    {
157
        // Full name like $name
158
        $this->whereNameLikeRaw($name);
159
160
        // Has nickname & nickname like $name
161
        $this->orWhere(function (self $builder) use ($name) {
162
            $builder->whereNotNull('nickname');
0 ignored issues
show
Bug introduced by
The method whereNotNull() does not exist on Sfneal\Users\Builders\UserBuilder. 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

162
            $builder->/** @scrutinizer ignore-call */ 
163
                      whereNotNull('nickname');
Loading history...
163
            $builder->whereNameLikeRaw($name, $this->concatNickname());
164
        });
165
166
        return $this;
167
    }
168
169
    /**
170
     * Add a whereNameLike scope with custom columns (like concatenated).
171
     *
172
     * @param string      $name
173
     * @param string|null $column
174
     *
175
     * @return $this
176
     */
177
    private function whereNameLikeRaw(string $name, string $column = null)
178
    {
179
        // Use concatName method if no $column was provided
180
        $this->whereRaw(($column ?? $this->concatName())." LIKE '%{$name}%'");
0 ignored issues
show
Bug introduced by
The method whereRaw() does not exist on Sfneal\Users\Builders\UserBuilder. 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

180
        $this->/** @scrutinizer ignore-call */ 
181
               whereRaw(($column ?? $this->concatName())." LIKE '%{$name}%'");
Loading history...
181
182
        return $this;
183
    }
184
185
    /**
186
     * Active Users.
187
     *
188
     * @param int $value
189
     *
190
     * @return $this
191
     */
192
    public function whereActive($value = 1)
193
    {
194
        $this->where('status', '=', $value);
195
196
        return $this;
197
    }
198
199
    /**
200
     * Scope query results to User's with a particular 'role_id'.
201
     *
202
     * @param int $role_id
203
     * @param string $operator
204
     * @param string $boolean
205
     * @return $this
206
     */
207
    public function whereRole(int $role_id, string $operator = '=', string $boolean = 'and'): self
208
    {
209
        $this->where('role_id', $operator, $role_id, $boolean);
210
211
        return $this;
212
    }
213
214
    /**
215
     * Scope query results to User's without a particular 'role_id'.
216
     *
217
     * @param int $role_id
218
     * @param string $boolean
219
     * @return $this
220
     */
221
    public function whereRoleNot(int $role_id, string $boolean = 'and'): self
222
    {
223
        $this->where('role_id', '!=', $role_id, $boolean);
224
225
        return $this;
226
    }
227
228
    /**
229
     * Scope query results to User's with a 'role_id' found in the array of $role_ids.
230
     *
231
     * @param array $role_ids
232
     * @param string $boolean
233
     * @param bool $not
234
     * @return $this
235
     */
236
    public function whereRoleIn(array $role_ids, string $boolean = 'and', bool $not = false): self
237
    {
238
        $this->whereIn('role_id', $role_ids, $boolean, $not);
239
240
        return $this;
241
    }
242
243
    /**
244
     * Scope query results to User's with a 'role_id' that is NOT found in the array of $role_ids.
245
     *
246
     * @param array $role_ids
247
     * @param string $boolean
248
     * @return $this
249
     */
250
    public function whereRoleNotIn(array $role_ids, string $boolean = 'and'): self
251
    {
252
        $this->whereIn('role_id', $role_ids, $boolean, true);
253
254
        return $this;
255
    }
256
257
    /**
258
     * Add a `whereRole()` clause to query using the 'or' boolean.
259
     *
260
     * @param int $role_id
261
     * @param string $operator
262
     * @return $this
263
     */
264
    public function orWhereRole(int $role_id, string $operator = '='): self
265
    {
266
        $this->whereRole($role_id, $operator, 'or');
267
268
        return $this;
269
    }
270
271
    /**
272
     * Scope query results to User's with a particular role 'name'.
273
     *
274
     * @param string $role_name
275
     * @param string $operator
276
     * @param int $count
277
     * @return $this
278
     */
279
    public function whereRoleName(string $role_name, string $operator = '>=', int $count = 1): self
280
    {
281
        $this->whereHasRole(function (RoleBuilder $builder) use ($role_name) {
282
            $builder->whereName($role_name);
283
        }, $operator, $count);
284
285
        return $this;
286
    }
287
288
    /**
289
     * Scope query results to Role's that do NOT have a particular role 'name'.
290
     *
291
     * @param string $role_name
292
     * @param string $operator
293
     * @param int $count
294
     * @return $this
295
     */
296
    public function whereRoleNameNot(string $role_name, string $operator = '>=', int $count = 1): self
297
    {
298
        $this->whereHasRole(function (RoleBuilder $builder) use ($role_name) {
299
            $builder->whereNameNot($role_name);
300
        }, $operator, $count);
301
302
        return $this;
303
    }
304
305
    /**
306
     * Scope query results to User's with role names that are in the array of $role_names.
307
     *
308
     * @param array $role_names
309
     * @param string $operator
310
     * @param int $count
311
     * @return $this
312
     */
313
    public function whereRoleNameIn(array $role_names, string $operator = '>=', int $count = 1): self
314
    {
315
        $this->whereHasRole(function (RoleBuilder $builder) use ($role_names) {
316
            $builder->whereNameIn($role_names);
317
        }, $operator, $count);
318
319
        return $this;
320
    }
321
322
    /**
323
     * Scope query results to User's with role names that are NOT in the array of $role_names.
324
     *
325
     * @param array $role_names
326
     * @param string $operator
327
     * @param int $count
328
     * @return $this
329
     */
330
    public function whereRoleNameNotIn(array $role_names, string $operator = '>=', int $count = 1): self
331
    {
332
        $this->whereHasRole(function (RoleBuilder $builder) use ($role_names) {
333
            $builder->whereNameNotIn($role_names);
334
        }, $operator, $count);
335
336
        return $this;
337
    }
338
339
    /**
340
     * Scope query results to User's that have roles.
341
     *
342
     * @param Closure|null $callback
343
     * @param string $operator
344
     * @param int $count
345
     * @return $this
346
     */
347
    public function whereHasRole(Closure $callback = null, $operator = '>=', $count = 1): self
348
    {
349
        $this->whereHas('role', $callback, $operator, $count);
350
351
        return $this;
352
    }
353
354
    /**
355
     * Inactive Users.
356
     *
357
     * @return $this
358
     */
359
    public function whereInactive()
360
    {
361
        $this->withInactive();
362
        $this->whereActive(0);
363
364
        return $this;
365
    }
366
367
    /**
368
     * Include 'inactive' users in collection.
369
     *
370
     * @return $this
371
     */
372
    public function withInactive()
373
    {
374
        $this->withoutGlobalScope(UserActiveScope::class);
375
376
        return $this;
377
    }
378
379
    /**
380
     * Retrieve all Users regardless of 'active status'.
381
     *
382
     * @param array $columns
383
     *
384
     * @return Collection
385
     */
386
    public function allWithInactive($columns = ['*'])
387
    {
388
        return $this->withInactive()->get($columns);
389
    }
390
}
391