Completed
Push — master ( 21b117...a2719e )
by ARCANEDEV
10s
created

User::scopeVerifiedEmail()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
cc 1
nc 1
nop 1
crap 1
1
<?php namespace Arcanedev\LaravelAuth\Models;
2
3
use Arcanedev\LaravelAuth\Events\Users\{
4
    ActivatedUser, ActivatingUser, AttachedRoleToUser, AttachingRoleToUser, CreatedUser, CreatingUser,
5
    DeactivatedUser, DeactivatingUser, DeletedUser, DeletingUser, DetachedRoleFromUser, DetachedRolesFromUser,
6
    DetachingRoleFromUser, DetachingRolesFromUser, RestoredUser, RestoringUser, SavedUser, SavingUser,
7
    SyncedUserWithRoles, SyncingUserWithRoles, UpdatedUser, UpdatingUser
8
};
9
use Arcanedev\LaravelAuth\Services\SocialAuthenticator;
10
use Arcanesoft\Contracts\Auth\Models\{
11
    Permission as PermissionContract,
12
    Role as RoleContract,
13
    User as UserContract
14
};
15
use Illuminate\Auth\{
16
    Authenticatable, MustVerifyEmail, Passwords\CanResetPassword
17
};
18
use Illuminate\Contracts\Auth\{
19
    Access\Authorizable as AuthorizableContract,
20
    Authenticatable as AuthenticatableContract,
21
    CanResetPassword as CanResetPasswordContract
22
};
23
use Illuminate\Database\Eloquent\SoftDeletes;
24
use Illuminate\Foundation\Auth\Access\Authorizable;
25
use Illuminate\Support\Collection;
26
use Illuminate\Support\Str;
27
28
/**
29
 * Class     User
30
 *
31
 * @package  Arcanedev\LaravelAuth\Models
32
 * @author   ARCANEDEV <[email protected]>
33
 *
34
 * @property  int                                       id
35
 * @property  string                                    username
36
 * @property  string                                    first_name
37
 * @property  string                                    last_name
38
 * @property  string                                    full_name
39
 * @property  string                                    email
40
 * @property  \Carbon\Carbon|null                       email_verified_at
41
 * @property  string                                    password
42
 * @property  string                                    remember_token
43
 * @property  bool                                      is_admin
44
 * @property  \Carbon\Carbon                            last_activity
45
 * @property  \Carbon\Carbon                            created_at
46
 * @property  \Carbon\Carbon                            updated_at
47
 * @property  \Carbon\Carbon|null                       activated_at
48
 * @property  \Carbon\Carbon                            deleted_at
49
 *
50
 * @property  \Illuminate\Database\Eloquent\Collection       roles
51
 * @property  \Illuminate\Support\Collection                 permissions
52
 * @property  \Arcanedev\LaravelAuth\Models\Pivots\RoleUser  pivot
53
 *
54
 * @method  static  \Illuminate\Database\Eloquent\Builder|static  lastActive(int $minutes = null)
55
 * @method  static  \Illuminate\Database\Eloquent\Builder|static  unverifiedEmail
56
 * @method  static  \Illuminate\Database\Eloquent\Builder|static  verifiedEmail
57
 */
58
class User
59
    extends AbstractModel
60
    implements UserContract, AuthenticatableContract, AuthorizableContract, CanResetPasswordContract
61
{
62
    /* -----------------------------------------------------------------
63
     |  Traits
64
     | -----------------------------------------------------------------
65
     */
66
67
    use Authenticatable,
68
        Authorizable,
69
        CanResetPassword,
70
        MustVerifyEmail,
71
        Traits\Roleable,
72
        Traits\Activatable,
73
        SoftDeletes;
74
75
    /* -----------------------------------------------------------------
76
     |  Properties
77
     | -----------------------------------------------------------------
78
79
     */
80
    /**
81
     * The attributes that are mass assignable.
82
     *
83
     * @var array
84
     */
85
    protected $fillable = [
86
        'username',
87
        'first_name',
88
        'last_name',
89
        'email',
90
        'password',
91
    ];
92
93
    /**
94
     * The attributes excluded from the model's JSON form.
95
     *
96
     * @var array
97
     */
98
    protected $hidden   = [
99
        'password',
100
        'remember_token',
101
    ];
102
103
    /**
104
     * The attributes that should be casted to native types.
105
     *
106
     * @var array
107
     */
108
    protected $casts = [
109
        'id'           => 'integer',
110
        'is_admin'     => 'boolean',
111
        'is_active'    => 'boolean',
112
        'is_confirmed' => 'boolean',
113
    ];
114
115
    /**
116
     * The attributes that should be mutated to dates.
117
     *
118
     * @var array
119
     */
120
    protected $dates = [
121
        'email_verified_at',
122
        'last_activity',
123
        'activated_at',
124
        'deleted_at',
125
    ];
126
127
    /**
128
     * The event map for the model.
129
     *
130
     * @var array
131
     */
132
    protected $dispatchesEvents = [
133
        'creating'  => CreatingUser::class,
134
        'created'   => CreatedUser::class,
135
        'updating'  => UpdatingUser::class,
136
        'updated'   => UpdatedUser::class,
137
        'saving'    => SavingUser::class,
138
        'saved'     => SavedUser::class,
139
        'deleting'  => DeletingUser::class,
140
        'deleted'   => DeletedUser::class,
141
        'restoring' => RestoringUser::class,
142
        'restored'  => RestoredUser::class,
143
    ];
144
145
    /* -----------------------------------------------------------------
146
     |  Constructor
147
     | -----------------------------------------------------------------
148
     */
149
150
    /**
151
     * Create a new Eloquent model instance.
152
     *
153
     * @param  array  $attributes
154
     */
155 93
    public function __construct(array $attributes = [])
156
    {
157 93
        $this->setTable(config('laravel-auth.users.table', 'users'));
158
159 93
        if (SocialAuthenticator::isEnabled()) {
160 93
            $this->hidden   = array_merge($this->hidden, ['social_provider_id']);
161 93
            $this->fillable = array_merge($this->fillable, ['social_provider', 'social_provider_id']);
162
        }
163
164 93
        parent::__construct($attributes);
165 93
    }
166
167
    /* -----------------------------------------------------------------
168
     |  Relationships
169
     | -----------------------------------------------------------------
170
     */
171
172
    /**
173
     * User belongs to many roles.
174
     *
175
     * @return \Illuminate\Database\Eloquent\Relations\BelongsToMany
176
     */
177 42
    public function roles()
178
    {
179 42
        return $this->belongsToMany(
180 42
                config('laravel-auth.roles.model', Role::class),
181 42
                $this->getPrefix().config('laravel-auth.role-user.table', 'role_user')
182
            )
183 42
            ->using(Pivots\RoleUser::class)
184 42
            ->withTimestamps();
185
    }
186
187
    /**
188
     * Get all user permissions.
189
     *
190
     * @return \Illuminate\Support\Collection
191
     */
192 9
    public function getPermissionsAttribute()
193
    {
194 9
        return $this->active_roles
195 9
            ->pluck('permissions')
196 9
            ->flatten()
197
            ->unique(function (PermissionContract $permission) {
198 9
                return $permission->getKey();
199 9
            });
200
    }
201
202
    /* -----------------------------------------------------------------
203
     |  Scopes
204
     | -----------------------------------------------------------------
205
     */
206
207
    /**
208
     * Scope last active users.
209
     *
210
     * @param  \Illuminate\Database\Eloquent\Builder  $query
211
     * @param  int|null                               $minutes
212
     *
213
     * @return \Illuminate\Database\Eloquent\Builder
214
     */
215 3
    public function scopeLastActive($query, $minutes = null)
216
    {
217 3
        $date = $this->freshTimestamp()->subMinutes(
218 3
            $minutes ?: config('laravel_auth.track-activity.minutes', 5)
219 3
        )->toDateTimeString();
220
221 3
        return $query->where('last_activity', '>=', $date);
222
    }
223
224
    /**
225
     * Scope unverified emails' users.
226
     *
227
     * @param  \Illuminate\Database\Eloquent\Builder  $query
228
     *
229
     * @return \Illuminate\Database\Eloquent\Builder
230
     */
231 3
    public function scopeUnverifiedEmail($query)
232
    {
233 3
        return $query->whereNull('email_verified_at');
234
    }
235
236
    /**
237
     * Scope unverified emails' users.
238
     *
239
     * @param  \Illuminate\Database\Eloquent\Builder  $query
240
     *
241
     * @return \Illuminate\Database\Eloquent\Builder
242
     */
243 3
    public function scopeVerifiedEmail($query)
244
    {
245 3
        return $query->whereNotNull('email_verified_at');
246
    }
247
248
    /* -----------------------------------------------------------------
249
     |  Getters & Setters
250
     | -----------------------------------------------------------------
251
     */
252
253
    /**
254
     * Set the `email` attribute.
255
     *
256
     * @param  string  $email
257
     */
258 75
    public function setEmailAttribute($email)
259
    {
260 75
        $this->attributes['email'] = Str::lower($email);
261 75
    }
262
263
    /**
264
     * Set the `username` attribute.
265
     *
266
     * @param  string  $username
267
     */
268 72
    public function setUsernameAttribute($username)
269
    {
270 72
        $this->attributes['username'] = Str::slug($username, config('laravel-auth.users.slug-separator', '.'));
271 72
    }
272
273
    /**
274
     * Set the `first_name` attribute.
275
     *
276
     * @param  string  $firstName
277
     */
278 75
    public function setFirstNameAttribute($firstName)
279
    {
280 75
        $this->attributes['first_name'] = Str::title(Str::lower($firstName));
281 75
    }
282
283
    /**
284
     * Set the `last_name` attribute.
285
     *
286
     * @param  string  $lastName
287
     */
288 75
    public function setLastNameAttribute($lastName)
289
    {
290 75
        $this->attributes['last_name'] = Str::upper($lastName);
291 75
    }
292
293
    /**
294
     * Get the `full_name` attribute.
295
     *
296
     * @return string
297
     */
298 6
    public function getFullNameAttribute()
299
    {
300 6
        return $this->first_name.' '.$this->last_name;
301
    }
302
303
    /**
304
     * Set the `password` attribute.
305
     *
306
     * @param  string  $password
307
     */
308 72
    public function setPasswordAttribute($password)
309
    {
310 72
        $this->attributes['password'] = bcrypt($password);
311 72
    }
312
313
    /* -----------------------------------------------------------------
314
     |  Main Methods
315
     | -----------------------------------------------------------------
316
     */
317
318
    /**
319
     * Activate the model.
320
     *
321
     * @param  bool  $save
322
     *
323
     * @return bool
324
     */
325 3
    public function activate($save = true)
326
    {
327 3
        event(new ActivatingUser($this));
328 3
        $result = $this->switchActive(true, $save);
329 3
        event(new ActivatedUser($this));
330
331 3
        return $result;
332
    }
333
334
    /**
335
     * Deactivate the model.
336
     *
337
     * @param  bool  $save
338
     *
339
     * @return bool
340
     */
341 3
    public function deactivate($save = true)
342
    {
343 3
        event(new DeactivatingUser($this));
344 3
        $result = $this->switchActive(false, $save);
345 3
        event(new DeactivatedUser($this));
346
347 3
        return $result;
348
    }
349
350
    /**
351
     * Attach a role to a user.
352
     *
353
     * @param  \Arcanesoft\Contracts\Auth\Models\Role|int  $role
354
     * @param  bool                                        $reload
355
     */
356 33
    public function attachRole($role, $reload = true)
357
    {
358 33
        if ($this->hasRole($role)) return;
359
360 33
        event(new AttachingRoleToUser($this, $role));
361 33
        $this->roles()->attach($role);
362 33
        event(new AttachedRoleToUser($this, $role));
363
364 33
        $this->loadRoles($reload);
365 33
    }
366
367
    /**
368
     * Sync the roles by its slugs.
369
     *
370
     * @param  array|\Illuminate\Support\Collection  $slugs
371
     * @param  bool                                  $reload
372
     *
373
     * @return array
374
     */
375 3
    public function syncRoles($slugs, $reload = true)
376
    {
377
        /** @var  \Illuminate\Database\Eloquent\Collection  $roles */
378 3
        $roles = app(RoleContract::class)->whereIn('slug', $slugs)->get();
379
380 3
        event(new SyncingUserWithRoles($this, $roles));
381 3
        $synced = $this->roles()->sync($roles->pluck('id'));
382 3
        event(new SyncedUserWithRoles($this, $roles, $synced));
383
384 3
        $this->loadRoles($reload);
385
386 3
        return $synced;
387
    }
388
389
    /**
390
     * Detach a role from a user.
391
     *
392
     * @param  \Arcanesoft\Contracts\Auth\Models\Role|int  $role
393
     * @param  bool                                        $reload
394
     *
395
     * @return int
396
     */
397 3
    public function detachRole($role, $reload = true)
398
    {
399 3
        event(new DetachingRoleFromUser($this, $role));
400 3
        $results = $this->roles()->detach($role);
401 3
        event(new DetachedRoleFromUser($this, $role, $results));
402
403 3
        $this->loadRoles($reload);
404
405 3
        return $results;
406
    }
407
408
    /**
409
     * Detach all roles from a user.
410
     *
411
     * @param  bool  $reload
412
     *
413
     * @return int
414
     */
415 3
    public function detachAllRoles($reload = true)
416
    {
417 3
        event(new DetachingRolesFromUser($this));
418 3
        $results = $this->roles()->detach();
419 3
        event(new DetachedRolesFromUser($this, $results));
420
421 3
        $this->loadRoles($reload);
422
423 3
        return $results;
424
    }
425
426
    /**
427
     * Update the user's last activity.
428
     *
429
     * @param  bool  $save
430
     */
431 3
    public function updateLastActivity($save = true)
432
    {
433 3
        $this->forceFill(['last_activity' => $this->freshTimestamp()]);
434
435 3
        if ($save) $this->save();
436 3
    }
437
438
    /* -----------------------------------------------------------------
439
     |  Permission Check Methods
440
     | -----------------------------------------------------------------
441
     */
442
    /**
443
     * Check if the user has a permission.
444
     *
445
     * @param  string  $slug
446
     *
447
     * @return bool
448
     */
449 9
    public function may($slug)
450
    {
451
        return ! $this->permissions->filter(function (PermissionContract $permission) use ($slug) {
452 9
            return $permission->hasSlug($slug);
453 9
        })->isEmpty();
454
    }
455
456
    /**
457
     * Check if the user has at least one permission.
458
     *
459
     * @param  \Illuminate\Support\Collection|array  $permissions
460
     * @param  \Illuminate\Support\Collection        &$failed
461
     *
462
     * @return bool
463
     */
464 6
    public function mayOne($permissions, &$failed = null)
465
    {
466 6
        $permissions = is_array($permissions) ? collect($permissions) : $permissions;
467
468
        $failed = $permissions->reject(function ($permission) {
469 6
            return $this->may($permission);
470 6
        })->values();
471
472 6
        return $permissions->count() !== $failed->count();
473
    }
474
475
    /**
476
     * Check if the user has all permissions.
477
     *
478
     * @param  \Illuminate\Support\Collection|array  $permissions
479
     * @param  \Illuminate\Support\Collection        &$failed
480
     *
481
     * @return bool
482
     */
483 3
    public function mayAll($permissions, &$failed = null)
484
    {
485 3
        $this->mayOne($permissions, $failed);
486
487 3
        return $failed instanceof Collection ? $failed->isEmpty() : false;
488
    }
489
490
    /* -----------------------------------------------------------------
491
     |  Check Methods
492
     | -----------------------------------------------------------------
493
     */
494
495
    /**
496
     * Check if user is an administrator.
497
     *
498
     * @return bool
499
     */
500 15
    public function isAdmin()
501
    {
502 15
        return $this->is_admin;
503
    }
504
505
    /**
506
     * Check if user is a moderator.
507
     *
508
     * @return bool
509
     */
510 6
    public function isModerator()
511
    {
512
        // Override this method to give more privileges than members.
513 6
        return false;
514
    }
515
516
    /**
517
     * Check if user is a member.
518
     *
519
     * @return bool
520
     */
521 9
    public function isMember()
522
    {
523 9
        return ! $this->isAdmin();
524
    }
525
526
    /**
527
     * Check if user can be impersonated.
528
     *
529
     * @return bool
530
     */
531 3
    public function canBeImpersonated()
532
    {
533 3
        return $this->isMember();
534
    }
535
}
536