Issues (18)

src/Builders/UserBuilder.php (3 issues)

Labels
Severity
1
<?php
2
3
namespace Sfneal\Users\Builders;
4
5
use Closure;
6
use Illuminate\Database\Eloquent\Collection;
7
use Illuminate\Database\Eloquent\Model as EloquentModel;
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
    /**
17
     * @var string MySQL select objects to be queried in a raw json return
18
     */
19
    protected $selectRawJson;
20
21
    /**
22
     * @var EloquentModel|User
23
     */
24
    protected $targetModel = User::class;
25
26
    /**
27
     * UserBuilder constructor.
28
     *
29
     * @param  Builder  $query
30
     */
31
    public function __construct(Builder $query)
32
    {
33
        parent::__construct($query);
34
        $this->setSelectRawJson();
35
    }
36
37
    /**
38
     * Find a User.
39
     *
40
     * @param  int  $user_id
41
     * @param  string  $operator
42
     * @param  string  $boolean
43
     * @return $this
44
     */
45
    public function whereUser(int $user_id, string $operator = '=', string $boolean = 'and'): self
46
    {
47
        $this->where('id', $operator, $user_id, $boolean);
48
49
        return $this;
50
    }
51
52
    /**
53
     * Exclude a User.
54
     *
55
     * @param  int  $user_id
56
     * @param  string  $boolean
57
     * @return $this
58
     */
59
    public function whereUserNot(int $user_id, string $boolean = 'and'): self
60
    {
61
        $this->whereUser($user_id, '!=', $boolean);
62
63
        return $this;
64
    }
65
66
    /**
67
     * Scope query to User's that have an 'id' found in the array of $user_ids.
68
     *
69
     * @param  array  $user_ids
70
     * @param  string  $boolean
71
     * @param  bool  $not
72
     * @return $this|WhereUserInterface
73
     */
74
    public function whereUserIn(array $user_ids, string $boolean = 'and', bool $not = false): self
75
    {
76
        $this->whereIn('id', $user_ids, $boolean, $not);
0 ignored issues
show
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

76
        $this->/** @scrutinizer ignore-call */ 
77
               whereIn('id', $user_ids, $boolean, $not);
Loading history...
77
78
        return $this;
79
    }
80
81
    /**
82
     * Scope query to User's that does NOT have 'id' found in the array of $user_ids.
83
     *
84
     * @param  array  $user_ids
85
     * @param  string  $boolean
86
     * @return $this|WhereUserInterface
87
     */
88
    public function whereUserNotIn(array $user_ids, string $boolean = 'and'): self
89
    {
90
        $this->whereUserIn($user_ids, $boolean, true);
91
92
        return $this;
93
    }
94
95
    /**
96
     * Scope results to User's with a certain username.
97
     *
98
     * @param  $value
99
     * @return $this
100
     */
101
    public function whereUsername($value): self
102
    {
103
        $this->where('username', '=', $value);
104
105
        return $this;
106
    }
107
108
    /**
109
     * Scope a query to User's with names starting with a particular string.
110
     *
111
     * @param  string  $name
112
     * @return $this
113
     */
114
    public function whereNameLike(string $name): self
115
    {
116
        // Full name like $name
117
        $this->whereNameLikeRaw($name);
118
119
        // Has nickname & nickname like $name
120
        $this->orWhere(function (self $builder) use ($name) {
121
            $builder->whereNotNull('nickname');
0 ignored issues
show
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

121
            $builder->/** @scrutinizer ignore-call */ 
122
                      whereNotNull('nickname');
Loading history...
122
            $builder->whereNameLikeRaw($name, $this->concatNickname());
123
        });
124
125
        return $this;
126
    }
127
128
    /**
129
     * Add a whereNameLike scope with custom columns (like concatenated).
130
     *
131
     * @param  string  $name
132
     * @param  string|null  $column
133
     * @return $this
134
     */
135
    private function whereNameLikeRaw(string $name, string $column = null): self
136
    {
137
        // Use concatName method if no $column was provided
138
        $this->whereRaw(($column ?? $this->concatName()).' LIKE "%'.$name.'%"');
0 ignored issues
show
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

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