Passed
Push — master ( cf0676...2847ea )
by Stephen
14:49 queued 11:55
created

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

98
        $this->/** @scrutinizer ignore-call */ 
99
               whereIn('id', $user_ids);
Loading history...
99
100
        return $this;
101
    }
102
103
    /**
104
     * Scope results to User's with a certain username.
105
     *
106
     * @param $value
107
     *
108
     * @return $this
109
     */
110
    public function whereUsername($value)
111
    {
112
        $this->where('username', '=', $value);
113
114
        return $this;
115
    }
116
117
    /**
118
     * Scope a query to User's with names starting with a particular string.
119
     *
120
     * @param string $name
121
     *
122
     * @return $this
123
     */
124
    public function whereNameLike(string $name)
125
    {
126
        // Full name like $name
127
        $this->whereNameLikeRaw($name);
128
129
        // Has nickname & nickname like $name
130
        $this->orWhere(function (self $builder) use ($name) {
131
            $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

131
            $builder->/** @scrutinizer ignore-call */ 
132
                      whereNotNull('nickname');
Loading history...
132
            $builder->whereNameLikeRaw($name, $this->concatNickname());
133
        });
134
135
        return $this;
136
    }
137
138
    /**
139
     * Add a whereNameLike scope with custom columns (like concatenated).
140
     *
141
     * @param string      $name
142
     * @param string|null $column
143
     *
144
     * @return $this
145
     */
146
    private function whereNameLikeRaw(string $name, string $column = null)
147
    {
148
        // Use concatName method if no $column was provided
149
        $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

149
        $this->/** @scrutinizer ignore-call */ 
150
               whereRaw(($column ?? $this->concatName())." LIKE '%{$name}%'");
Loading history...
150
151
        return $this;
152
    }
153
154
    /**
155
     * Active Users.
156
     *
157
     * @param int $value
158
     *
159
     * @return $this
160
     */
161
    public function whereActive($value = 1)
162
    {
163
        $this->where('status', '=', $value);
164
165
        return $this;
166
    }
167
168
    /**
169
     * Scope query results to User's with a particular 'role_id'.
170
     *
171
     * @param int $role_id
172
     * @param string $operator
173
     * @param string $boolean
174
     * @return $this
175
     */
176
    public function whereRole(int $role_id, string $operator = '=', string $boolean = 'and'): self
177
    {
178
        $this->where('role_id', $operator, $role_id, $boolean);
179
180
        return $this;
181
    }
182
183
    /**
184
     * Scope query results to User's without a particular 'role_id'.
185
     *
186
     * @param int $role_id
187
     * @param string $boolean
188
     * @return $this
189
     */
190
    public function whereNotRole(int $role_id, string $boolean = 'and'): self
191
    {
192
        $this->where('role_id', '!=', $role_id, $boolean);
193
194
        return $this;
195
    }
196
197
    /**
198
     * Scope query results to User's with a 'role_id' found in the array of $role_ids.
199
     *
200
     * @param array $role_ids
201
     * @param string $boolean
202
     * @param bool $not
203
     * @return $this
204
     */
205
    public function whereRoleIn(array $role_ids, string $boolean = 'and', bool $not = false): self
206
    {
207
        $this->whereIn('role_id', $role_ids, $boolean, $not);
208
209
        return $this;
210
    }
211
212
    /**
213
     * Scope query results to User's with a 'role_id' that is NOT found in the array of $role_ids.
214
     *
215
     * @param array $role_ids
216
     * @param string $boolean
217
     * @return $this
218
     */
219
    public function whereRoleNotIn(array $role_ids, string $boolean = 'and'): self
220
    {
221
        $this->whereIn('role_id', $role_ids, $boolean, true);
222
223
        return $this;
224
    }
225
226
    /**
227
     * Add a `whereRole()` clause to query using the 'or' boolean.
228
     *
229
     * @param int $role_id
230
     * @param string $operator
231
     * @return $this
232
     */
233
    public function orWhereRole(int $role_id, string $operator = '='): self
234
    {
235
        $this->whereRole($role_id, $operator, 'or');
236
237
        return $this;
238
    }
239
240
    /**
241
     * Scope query results to User's with a particular role 'name'.
242
     *
243
     * @param string $role_name
244
     * @param string $operator
245
     * @param int $count
246
     * @return $this
247
     */
248
    public function whereRoleName(string $role_name, string $operator = '>=', int $count = 1): self
249
    {
250
        $this->whereHas('role', function (RoleBuilder $builder) use ($role_name) {
251
            $builder->whereName($role_name);
252
        }, $operator, $count);
253
254
        return $this;
255
    }
256
257
    /**
258
     * Scope query results to Role's that do NOT have 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 whereNotRoleName(string $role_name, string $operator = '>=', int $count = 1): self
266
    {
267
        $this->whereHas('role', function (RoleBuilder $builder) use ($role_name) {
268
            $builder->whereNotName($role_name);
269
        }, $operator, $count);
270
271
        return $this;
272
    }
273
274
    /**
275
     * Inactive Users.
276
     *
277
     * @return $this
278
     */
279
    public function whereInactive()
280
    {
281
        $this->withInactive();
282
        $this->whereActive(0);
283
284
        return $this;
285
    }
286
287
    /**
288
     * Include 'inactive' users in collection.
289
     *
290
     * @return $this
291
     */
292
    public function withInactive()
293
    {
294
        $this->withoutGlobalScope(UserActiveScope::class);
295
296
        return $this;
297
    }
298
299
    /**
300
     * Retrieve all Users regardless of 'active status'.
301
     *
302
     * @param array $columns
303
     *
304
     * @return Collection
305
     */
306
    public function allWithInactive($columns = ['*'])
307
    {
308
        return $this->withInactive()->get($columns);
309
    }
310
}
311