Passed
Pull Request — master (#33)
by Stephen
12:46
created

User::setPasswordAttribute()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 2
eloc 2
c 2
b 1
f 0
nc 2
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
namespace Sfneal\Users\Models;
4
5
use Database\Factories\UserFactory;
6
use Illuminate\Database\Eloquent\Builder;
7
use Illuminate\Database\Eloquent\Factories\HasFactory;
8
use Illuminate\Database\Eloquent\Relations\BelongsTo;
9
use Illuminate\Database\Eloquent\Relations\HasMany;
10
use Illuminate\Database\Eloquent\Relations\HasOne;
11
use Illuminate\Database\Eloquent\Relations\MorphOne;
12
use Sfneal\Address\Models\Address;
13
use Sfneal\Casts\NewlineCast;
14
use Sfneal\Currency\Currency;
15
use Sfneal\Helpers\Strings\StringHelpers;
16
use Sfneal\Models\AuthModel;
17
use Sfneal\Scopes\OrderScope;
18
use Sfneal\Users\Builders\UserBuilder;
19
use Sfneal\Users\Scopes\UserActiveScope;
20
use Sfneal\Users\Services\OrganizationService;
21
use Vkovic\LaravelCustomCasts\HasCustomCasts;
22
23
class User extends AuthModel
24
{
25
    // todo: refactor status to use Status model?
26
    use HasCustomCasts;
27
    use HasFactory;
28
29
    /**
30
     * The "booting" method of the model.
31
     *
32
     * @return void
33
     */
34
    protected static function boot()
35
    {
36
        parent::boot();
37
38
        // Global scopes
39
        static::addGlobalScope(new UserActiveScope());
40
        static::addGlobalScope(new OrderScope('last_name', 'asc'));
41
    }
42
43
    protected $dates = ['deleted_at'];
44
    protected $table = 'user';
45
    protected $primaryKey = 'id';
46
47
    /**
48
     * The attributes that are mass assignable.
49
     *
50
     * @var array
51
     */
52
    protected $fillable = [
53
        'role_id',
54
        'first_name',
55
        'middle_name',
56
        'last_name',
57
        'nickname',
58
        'nickname_preferred',
59
        'title',
60
        'suffix',
61
        'email',
62
        'phone_work',
63
        'phone_mobile',
64
        'fax',
65
        'website',
66
        'bio',
67
        'username',
68
        'password',
69
        'status',
70
        'rate',
71
    ];
72
73
    /**
74
     * The attributes that should be hidden from arrays.
75
     *
76
     * @var array
77
     */
78
    protected $hidden = [
79
        'password',
80
        'remember_token',
81
    ];
82
83
    /**
84
     * The attributes that should type cast.
85
     *
86
     * @var array
87
     */
88
    protected $casts = [
89
        'role_id' => 'int',
90
        'nickname_preferred' => 'int',
91
        'bio' => NewlineCast::class,
92
        'status' => 'int',
93
        'rate' => 'int',
94
    ];
95
96
    /**
97
     * @var array Attributes that should be appended to collections
98
     */
99
    protected $appends = [
100
        'name',
101
    ];
102
103
    /**
104
     * Create a new factory instance for the model.
105
     *
106
     * @return UserFactory
107
     */
108
    protected static function newFactory(): UserFactory
109
    {
110
        return new UserFactory();
111
    }
112
113
    /**
114
     * Query Builder.
115
     * @param $query
116
     * @return UserBuilder
117
     */
118
    public function newEloquentBuilder($query)
119
    {
120
        return new UserBuilder($query);
121
    }
122
123
    /**
124
     * Custom User query Builder.
125
     *
126
     * @return UserBuilder|Builder
127
     */
128
    public static function query(): UserBuilder
129
    {
130
        return parent::query();
131
    }
132
133
    /**
134
     * User's 'role' relationship.
135
     *
136
     * @return BelongsTo
137
     */
138
    public function role()
139
    {
140
        return $this->belongsTo(Role::class, 'role_id', 'role_id');
141
    }
142
143
    /**
144
     * User's Notification Subscriptions.
145
     *
146
     * @return HasMany
147
     */
148
    public function notificationSubscriptions()
149
    {
150
        return $this->hasMany(UserNotification::class, 'user_id', 'id');
151
    }
152
153
    /**
154
     * User's 'team' relationship - indicates user is a member of the public team.
155
     *
156
     * @return HasOne
157
     */
158
    public function team()
159
    {
160
        return $this->hasOne(Team::class, 'user_id', 'id');
161
    }
162
163
    /**
164
     * User's address.
165
     *
166
     * @return MorphOne
167
     */
168
    public function address()
169
    {
170
        return $this->morphOne(Address::class, 'addressable');
171
    }
172
173
    /**
174
     * Determine if a User has a particular 'role_id'.
175
     *
176
     * @param int $role_id
177
     * @return bool
178
     */
179
    public function isRoleId(int $role_id): bool
180
    {
181
        return $this->role_id == $role_id;
0 ignored issues
show
Bug introduced by
The property role_id does not exist on Sfneal\Users\Models\User. Did you mean role?
Loading history...
182
    }
183
184
    /**
185
     * Determine if a User has a particular 'role name'.
186
     *
187
     * @param string $role
188
     * @return bool
189
     */
190
    public function isRole(string $role): bool
191
    {
192
        return strtolower($this->role->name) == strtolower($role);
0 ignored issues
show
Bug introduced by
The property name does not seem to exist on Sfneal\Users\Models\Role. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
193
    }
194
195
    /**
196
     * Determine if a User has an 'admin' role.
197
     *
198
     * @return bool
199
     */
200
    public function isAdmin(): bool
201
    {
202
        // User is considered an 'admin' if user is a 'web developer'
203
        return $this->isRoleId(3) || $this->isRoleId(4);
204
    }
205
206
    /**
207
     * Determine if a User has a 'web developer' role.
208
     *
209
     * @return bool
210
     */
211
    public function isWebDeveloper(): bool
212
    {
213
        return $this->isRoleId(4);
214
    }
215
216
    /**
217
     * Determine if a User has an 'employee' role.
218
     *
219
     * @return bool
220
     */
221
    public function isEmployee(): bool
222
    {
223
        return $this->isRoleId(1);
224
    }
225
226
    /**
227
     * Determine if a User has an 'contractor' role.
228
     *
229
     * @return bool
230
     */
231
    public function isContractor(): bool
232
    {
233
        return $this->isRoleId(2);
234
    }
235
236
    /**
237
     * Determine if a User is 'active'.
238
     *
239
     * @return bool
240
     */
241
    public function isActive(): bool
242
    {
243
        return $this->status == 1;
0 ignored issues
show
Bug introduced by
The property status does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
244
    }
245
246
    /**
247
     * Determine if a User's $nickname is preferred over their $first_name.
248
     *
249
     * @return bool
250
     */
251
    public function isNicknamePreferred(): bool
252
    {
253
        return $this->nickname_preferred == 1;
0 ignored issues
show
Bug introduced by
The property nickname_preferred does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
254
    }
255
256
    /**
257
     * Retrieve a User's initials.
258
     *
259
     * @return string
260
     */
261
    public function getInitialsAttribute()
262
    {
263
        return StringHelpers::implodeFiltered('', collect([
264
            $this->first_name,
265
            $this->middle_name,
0 ignored issues
show
Bug introduced by
The property middle_name does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
266
            $this->last_name,
267
        ])->map(function ($name) {
268
            return substr($name, 0, 1);
269
        })->toArray());
270
    }
271
272
    /**
273
     * Get the AWS S3 file upload directory for an Inquiry model by retrieving the table name and primary key.
274
     *
275
     * @param string $base_dir
276
     * @return string
277
     */
278
    public function getUploadDirectory($base_dir = 'images'): string
279
    {
280
        return $base_dir.'/'.str_replace('_', '-', $this->getTable()).'/'.$this->getKey();
281
    }
282
283
    /**
284
     * Get the 'city_state' attribute.
285
     *
286
     * @return string
287
     */
288
    public function getCityStateAttribute()
289
    {
290
        return $this->address->city_state ?? null;
291
    }
292
293
    /**
294
     * Mutate the 'middle_name' attribute.
295
     *
296
     * @param string|null $value
297
     */
298
    public function setMiddleNameAttribute(string $value = null)
299
    {
300
        if (! is_null($value)) {
301
            // Remove leading & trailing whitespace
302
            $middle_name = trim($value);
303
304
            // Append '.' to the middle name if's a single letter
305
            $this->attributes['middle_name'] = strlen($middle_name) == 1 ? "{$middle_name}." : $middle_name;
306
        }
307
    }
308
309
    /**
310
     * Mutate the 'first_name' attribute.
311
     *
312
     * @param string|null $value
313
     */
314
    public function setFirstNameAttribute(string $value = null)
315
    {
316
        if (! is_null($value)) {
317
            $this->attributes['first_name'] = trim($value);
318
        }
319
    }
320
321
    /**
322
     * Mutate the 'last_name' attribute.
323
     *
324
     * @param string|null $value
325
     */
326
    public function setLastNameAttribute(string $value = null)
327
    {
328
        if (! is_null($value)) {
329
            $this->attributes['last_name'] = trim($value);
330
        }
331
    }
332
333
    /**
334
     * Access the 'first_name' attribute.
335
     *
336
     * @param string|null $value
337
     * @return string
338
     */
339
    public function getFirstNameAttribute(string $value = null): string
340
    {
341
        return trim($value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type null; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

341
        return trim(/** @scrutinizer ignore-type */ $value);
Loading history...
342
    }
343
344
    /**
345
     * Access the 'last_name' attribute.
346
     *
347
     * @param string|null $value
348
     * @return string
349
     */
350
    public function getLastNameAttribute(string $value = null): string
351
    {
352
        return trim($value);
0 ignored issues
show
Bug introduced by
It seems like $value can also be of type null; however, parameter $string of trim() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

352
        return trim(/** @scrutinizer ignore-type */ $value);
Loading history...
353
    }
354
355
    /**
356
     * Retrieve the User's name (first & last).
357
     *
358
     * @return string
359
     */
360
    public function getNameAttribute(): string
361
    {
362
        // Use nickname instead of first if it is set & preferred
363
        $first = (isset($this->nickname) && $this->isNicknamePreferred()) ? $this->nickname : $this->first_name;
0 ignored issues
show
Bug introduced by
The property nickname does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
364
365
        // Return concatenated name
366
        return "{$first} {$this->last_name}";
367
    }
368
369
    /**
370
     * Retrieve the User's full name with middle initial.
371
     *
372
     * @return string
373
     */
374
    public function getNameFullAttribute(): string
375
    {
376
        $name = $this->first_name;
377
        if ($this->middle_name) {
0 ignored issues
show
Bug introduced by
The property middle_name does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
378
            $name .= ' '.$this->middle_name;
379
        }
380
381
        return "{$name} {$this->last_name}";
382
    }
383
384
    /**
385
     * Retrieve the User's name with their suffix.
386
     *
387
     * @return string
388
     */
389
    public function getNameSuffixAttribute(): string
390
    {
391
        return $this->name_full.($this->suffix ? ", {$this->suffix}" : '');
0 ignored issues
show
Bug introduced by
The property suffix does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
392
    }
393
394
    /**
395
     * Get the 'list_name' attribute.
396
     *
397
     * @return string
398
     */
399
    public function getListNameAttribute()
400
    {
401
        return implode(', ', array_reverse(explode(' ', $this->name)));
402
    }
403
404
    /**
405
     * Get the 'name_link' attribute that returns a url to the User's team.show page.
406
     *
407
     * @return string
408
     */
409
    public function getNameLinkAttribute()
410
    {
411
        return '<a href="'.route('user.show', ['user'=>$this->id]).'">'.$this->name.'</a>';
412
    }
413
414
    // todo: add address accessor method to a sfneal/address trait
415
416
    /**
417
     * Retrieve the User's 'address1' attribute.
418
     *
419
     * @return mixed
420
     */
421
    public function getAddress1Attribute()
422
    {
423
        return $this->address->address_1 ?? null;
0 ignored issues
show
Bug introduced by
The property address_1 does not exist on Sfneal\Address\Models\Address. Did you mean addressable?
Loading history...
424
    }
425
426
    /**
427
     * Retrieve the User's 'address2' attribute.
428
     *
429
     * @return mixed
430
     */
431
    public function getAddress2Attribute()
432
    {
433
        return $this->address->address_2 ?? null;
0 ignored issues
show
Bug introduced by
The property address_2 does not exist on Sfneal\Address\Models\Address. Did you mean addressable?
Loading history...
434
    }
435
436
    /**
437
     * Retrieve the User's 'city' attribute.
438
     *
439
     * @return mixed
440
     */
441
    public function getCityAttribute()
442
    {
443
        return $this->address->city ?? null;
0 ignored issues
show
Bug introduced by
The property city does not seem to exist on Sfneal\Address\Models\Address. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
444
    }
445
446
    /**
447
     * Retrieve the User's 'state' attribute.
448
     *
449
     * @return mixed
450
     */
451
    public function getStateAttribute()
452
    {
453
        return $this->address->state ?? null;
0 ignored issues
show
Bug introduced by
The property state does not seem to exist on Sfneal\Address\Models\Address. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
454
    }
455
456
    /**
457
     * Retrieve the User's 'zip' attribute.
458
     *
459
     * @return mixed
460
     */
461
    public function getZipAttribute()
462
    {
463
        return $this->address->zip ?? null;
0 ignored issues
show
Bug introduced by
The property zip does not seem to exist on Sfneal\Address\Models\Address. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
464
    }
465
466
    /**
467
     * Retrieve an email link.
468
     *
469
     * @return string
470
     */
471
    public function getEmailLinkAttribute(): string
472
    {
473
        return $this->email ? ('mailto:'.$this->email) : '#!';
0 ignored issues
show
Bug introduced by
The property email does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
474
    }
475
476
    /**
477
     * Retrieve a work phone link.
478
     *
479
     * @return string
480
     */
481
    public function getPhoneWorkLinkAttribute(): string
482
    {
483
        return $this->phone_work ? ('tel:'.$this->phone_work) : '#!';
0 ignored issues
show
Bug introduced by
The property phone_work does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
484
    }
485
486
    /**
487
     * Retrieve a mobile phone link.
488
     *
489
     * @return string
490
     */
491
    public function getPhoneMobileLinkAttribute(): string
492
    {
493
        return $this->phone_mobile ? ('tel:'.$this->phone_mobile) : '#!';
0 ignored issues
show
Bug introduced by
The property phone_mobile does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
494
    }
495
496
    /**
497
     * Retrieve the User's rate formatted as dollars.
498
     *
499
     * @return string
500
     */
501
    public function getRateFormattedAttribute(): string
502
    {
503
        return (! empty($this->rate)) ? Currency::dollars($this->rate) : '-';
0 ignored issues
show
Bug introduced by
The property rate does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
504
    }
505
506
    /**
507
     * Retrieve the raw 'text' attribute with newline chars.
508
     *
509
     * @return mixed
510
     */
511
    public function getTextareaAttribute()
512
    {
513
        return $this->attributes['bio'];
514
    }
515
516
    /**
517
     * Retrieve a User's custom email footer.
518
     *
519
     * @return string
520
     */
521
    public function getEmailFooterAttribute(): string
522
    {
523
        $footer = "{$this->name}";
524
        $footer .= $this->title ? "\n{$this->title}" : '';
0 ignored issues
show
Bug introduced by
The property title does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
525
        $footer .= "\n".OrganizationService::name() ?? '';
526
        $footer .= "\n".($this->phone_work ?? OrganizationService::phone()) ?? '';
0 ignored issues
show
Bug introduced by
The property phone_work does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
527
        $footer .= $this->email ? "\n{$this->email}" : '';
0 ignored issues
show
Bug introduced by
The property email does not seem to exist on Sfneal\Users\Models\User. Are you sure there is no database migration missing?

Checks if undeclared accessed properties appear in database migrations and if the creating migration is correct.

Loading history...
528
529
        return $footer;
530
    }
531
}
532