Passed
Push — master ( 4b44ca...bc88db )
by Stephen
03:38
created

UserBuilder::whereRoleNameIn()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 3
dl 0
loc 7
rs 10
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 whereNotUser(int $user_id, string $boolean = 'and')
99
    {
100
        $this->whereUser($user_id, '!=', $boolean);
101
102
        return $this;
103
    }
104
105
    /**
106
     * Scope query to activity that was performed by any of the specified users.
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 results to User's with a certain username.
122
     *
123
     * @param $value
124
     *
125
     * @return $this
126
     */
127
    public function whereUsername($value)
128
    {
129
        $this->where('username', '=', $value);
130
131
        return $this;
132
    }
133
134
    /**
135
     * Scope a query to User's with names starting with a particular string.
136
     *
137
     * @param string $name
138
     *
139
     * @return $this
140
     */
141
    public function whereNameLike(string $name)
142
    {
143
        // Full name like $name
144
        $this->whereNameLikeRaw($name);
145
146
        // Has nickname & nickname like $name
147
        $this->orWhere(function (self $builder) use ($name) {
148
            $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

148
            $builder->/** @scrutinizer ignore-call */ 
149
                      whereNotNull('nickname');
Loading history...
149
            $builder->whereNameLikeRaw($name, $this->concatNickname());
150
        });
151
152
        return $this;
153
    }
154
155
    /**
156
     * Add a whereNameLike scope with custom columns (like concatenated).
157
     *
158
     * @param string      $name
159
     * @param string|null $column
160
     *
161
     * @return $this
162
     */
163
    private function whereNameLikeRaw(string $name, string $column = null)
164
    {
165
        // Use concatName method if no $column was provided
166
        $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

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