Passed
Pull Request — master (#17)
by Stephen
12:28 queued 06:46
created

User::getInitialsAttribute()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 1
eloc 7
c 2
b 1
f 0
nc 1
nop 0
dl 0
loc 9
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\Models\AuthModel;
16
use Sfneal\Scopes\OrderScope;
17
use Sfneal\Users\Builders\UserBuilder;
18
use Sfneal\Users\Scopes\UserActiveScope;
19
use Sfneal\Users\Services\OrganizationService;
20
use Vkovic\LaravelCustomCasts\HasCustomCasts;
21
22
class User extends AuthModel
23
{
24
    // todo: refactor status to use Status model?
25
    use HasCustomCasts;
26
    use HasFactory;
27
28
    /**
29
     * The "booting" method of the model.
30
     *
31
     * @return void
32
     */
33
    public static function boot()
34
    {
35
        parent::boot();
36
37
        // Global scopes
38
        static::addGlobalScope(new UserActiveScope());
39
        static::addGlobalScope(new OrderScope('last_name', 'asc'));
40
    }
41
42
    protected $dates = ['deleted_at'];
43
    protected $table = 'user';
44
    protected $primaryKey = 'id';
45
46
    /**
47
     * The attributes that are mass assignable.
48
     *
49
     * @var array
50
     */
51
    protected $fillable = [
52
        'role_id',
53
        'first_name',
54
        'middle_name',
55
        'last_name',
56
        'nickname',
57
        'nickname_preferred',
58
        'title',
59
        'suffix',
60
        'email',
61
        'phone_work',
62
        'phone_mobile',
63
        'fax',
64
        'website',
65
        'bio',
66
        'username',
67
        'password',
68
        'status',
69
        'rate',
70
    ];
71
72
    /**
73
     * The attributes that should be hidden from arrays.
74
     *
75
     * @var array
76
     */
77
    protected $hidden = [
78
        'password',
79
        'remember_token',
80
    ];
81
82
    /**
83
     * The attributes that should type cast.
84
     *
85
     * @var array
86
     */
87
    protected $casts = [
88
        'role_id' => 'int',
89
        'nickname_preferred' => 'int',
90
        'bio' => NewlineCast::class,
91
        'status' => 'int',
92
        'rate' => 'int',
93
    ];
94
95
    /**
96
     * Create a new factory instance for the model.
97
     *
98
     * @return UserFactory
99
     */
100
    protected static function newFactory(): UserFactory
101
    {
102
        return new UserFactory();
103
    }
104
105
    /**
106
     * Query Builder.
107
     * @param $query
108
     * @return UserBuilder
109
     */
110
    public function newEloquentBuilder($query)
111
    {
112
        return new UserBuilder($query);
113
    }
114
115
    /**
116
     * Custom User query Builder.
117
     *
118
     * @return UserBuilder|Builder
119
     */
120
    public static function query(): UserBuilder
121
    {
122
        return parent::query();
123
    }
124
125
    /**
126
     * User's 'role' relationship.
127
     *
128
     * @return BelongsTo
129
     */
130
    public function role()
131
    {
132
        return $this->belongsTo(Role::class, 'role_id', 'role_id');
133
    }
134
135
    /**
136
     * User's Notification Subscriptions.
137
     *
138
     * @return HasMany
139
     */
140
    public function notificationSubscriptions()
141
    {
142
        return $this->hasMany(UserNotification::class, 'user_id', 'id');
143
    }
144
145
    /**
146
     * User's 'team' relationship - indicates user is a member of the public team.
147
     *
148
     * @return HasOne
149
     */
150
    public function team()
151
    {
152
        return $this->hasOne(Team::class, 'user_id', 'id');
153
    }
154
155
    /**
156
     * User's address.
157
     *
158
     * @return MorphOne|Address
159
     */
160
    public function address()
161
    {
162
        return $this->morphOne(Address::class, 'addressable');
163
    }
164
165
    /**
166
     * Determine if a User has a particular 'role_id'.
167
     *
168
     * @param int $role_id
169
     * @return bool
170
     */
171
    public function isRoleId(int $role_id): bool
172
    {
173
        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...
174
    }
175
176
    /**
177
     * Determine if a User has a particular 'role name'.
178
     *
179
     * @param string $role
180
     * @return bool
181
     */
182
    public function isRole(string $role): bool
183
    {
184
        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...
185
    }
186
187
    /**
188
     * Determine if a User has an 'admin' role.
189
     *
190
     * @return bool
191
     */
192
    public function isAdmin(): bool
193
    {
194
        // User is considered an 'admin' if user is a 'web developer'
195
        return $this->isRoleId(3) || $this->isRoleId(4);
196
    }
197
198
    /**
199
     * Determine if a User has a 'web developer' role.
200
     *
201
     * @return bool
202
     */
203
    public function isWebDeveloper(): bool
204
    {
205
        return $this->isRoleId(4);
206
    }
207
208
    /**
209
     * Determine if a User has an 'employee' role.
210
     *
211
     * @return bool
212
     */
213
    public function isEmployee(): bool
214
    {
215
        return $this->isRoleId(1);
216
    }
217
218
    /**
219
     * Determine if a User has an 'contractor' role.
220
     *
221
     * @return bool
222
     */
223
    public function isContractor(): bool
224
    {
225
        return $this->isRoleId(2);
226
    }
227
228
    /**
229
     * Determine if a User is 'active'.
230
     *
231
     * @return bool
232
     */
233
    public function isActive(): bool
234
    {
235
        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...
236
    }
237
238
    /**
239
     * Determine if a User's $nickname is preferred over their $first_name.
240
     *
241
     * @return bool
242
     */
243
    public function isNicknamePreferred(): bool
244
    {
245
        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...
246
    }
247
248
    /**
249
     * Retrieve a User's initials.
250
     *
251
     * @return string
252
     */
253
    public function getInitialsAttribute()
254
    {
255
        return implodeFiltered('', collect([
256
            $this->first_name,
0 ignored issues
show
Bug introduced by
The property first_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...
257
            $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...
258
            $this->last_name,
0 ignored issues
show
Bug introduced by
The property last_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...
259
        ])->map(function ($name) {
260
            return substr($name, 0, 1);
261
        })->toArray());
262
    }
263
264
    /**
265
     * Get the AWS S3 file upload directory for an Inquiry model by retrieving the table name and primary key.
266
     *
267
     * @param string $base_dir
268
     * @return string
269
     */
270
    public function getUploadDirectory($base_dir = 'images'): string
271
    {
272
        return $base_dir.'/'.str_replace('_', '-', $this->getTable()).'/'.$this->getKey();
273
    }
274
275
    /**
276
     * Get the 'city_state' attribute.
277
     *
278
     * @return string
279
     */
280
    public function getCityStateAttribute()
281
    {
282
        return $this->address->city_state ?? null;
283
    }
284
285
    /**
286
     * Set the 'password' attribute.
287
     *
288
     * @param $value
289
     */
290
    public function setPasswordAttribute($value)
291
    {
292
        if (! empty($value)) {
293
            $this->attributes['password'] = bcrypt($value);
294
        }
295
    }
296
297
    /**
298
     * Mutate the 'middle_name' attribute.
299
     *
300
     * @param string|null $value
301
     */
302
    public function setMiddleNameAttribute(string $value = null)
303
    {
304
        if (! is_null($value)) {
305
            // Remove leading & trailing whitespace
306
            $middle_name = trim($value);
307
308
            // Append '.' to the middle name if's a single letter
309
            $this->attributes['middle_name'] = strlen($middle_name) == 1 ? "{$middle_name}." : $middle_name;
310
        }
311
    }
312
313
    /**
314
     * Retrieve the User's name (first & last).
315
     *
316
     * @return string
317
     */
318
    public function getNameAttribute(): string
319
    {
320
        // Use nickname instead of first if it is set & preferred
321
        $first = (isset($this->nickname) && $this->isNicknamePreferred()) ? $this->nickname : $this->first_name;
0 ignored issues
show
Bug introduced by
The property first_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...
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...
322
323
        // Return concatenated name
324
        return "{$first} {$this->last_name}";
0 ignored issues
show
Bug introduced by
The property last_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...
325
    }
326
327
    /**
328
     * Retrieve the User's full name with middle initial.
329
     *
330
     * @return string
331
     */
332
    public function getNameFullAttribute(): string
333
    {
334
        $name = $this->first_name;
0 ignored issues
show
Bug introduced by
The property first_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...
335
        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...
336
            $name .= ' '.$this->middle_name;
337
        }
338
339
        return "{$name} {$this->last_name}";
0 ignored issues
show
Bug introduced by
The property last_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...
340
    }
341
342
    /**
343
     * Retrieve the User's name with their suffix.
344
     *
345
     * @return string
346
     */
347
    public function getNameSuffixAttribute(): string
348
    {
349
        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...
350
    }
351
352
    /**
353
     * Get the 'list_name' attribute.
354
     *
355
     * @return string
356
     */
357
    public function getListNameAttribute()
358
    {
359
        return implode(', ', array_reverse(explode(' ', $this->name)));
360
    }
361
362
    /**
363
     * Get the 'name_link' attribute that returns a url to the User's team.show page.
364
     *
365
     * @return string
366
     */
367
    public function getNameLinkAttribute()
368
    {
369
        return '<a href="'.route('user.show', ['user'=>$this->id]).'">'.$this->name.'</a>';
370
    }
371
372
    // todo: add address accessor method to a sfneal/address trait
373
374
    /**
375
     * Retrieve the User's 'address1' attribute.
376
     *
377
     * @return mixed
378
     */
379
    public function getAddress1Attribute()
380
    {
381
        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...
382
    }
383
384
    /**
385
     * Retrieve the User's 'address2' attribute.
386
     *
387
     * @return mixed
388
     */
389
    public function getAddress2Attribute()
390
    {
391
        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...
392
    }
393
394
    /**
395
     * Retrieve the User's 'city' attribute.
396
     *
397
     * @return mixed
398
     */
399
    public function getCityAttribute()
400
    {
401
        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...
402
    }
403
404
    /**
405
     * Retrieve the User's 'state' attribute.
406
     *
407
     * @return mixed
408
     */
409
    public function getStateAttribute()
410
    {
411
        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...
412
    }
413
414
    /**
415
     * Retrieve the User's 'zip' attribute.
416
     *
417
     * @return mixed
418
     */
419
    public function getZipAttribute()
420
    {
421
        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...
422
    }
423
424
    /**
425
     * Retrieve an email link.
426
     *
427
     * @return string
428
     */
429
    public function getEmailLinkAttribute(): string
430
    {
431
        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...
432
    }
433
434
    /**
435
     * Retrieve a work phone link.
436
     *
437
     * @return string
438
     */
439
    public function getPhoneWorkLinkAttribute(): string
440
    {
441
        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...
442
    }
443
444
    /**
445
     * Retrieve a mobile phone link.
446
     *
447
     * @return string
448
     */
449
    public function getPhoneMobileLinkAttribute(): string
450
    {
451
        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...
452
    }
453
454
    /**
455
     * Retrieve the User's rate formatted as dollars.
456
     *
457
     * @return string
458
     */
459
    public function getRateFormattedAttribute(): string
460
    {
461
        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...
462
    }
463
464
    /**
465
     * Retrieve the raw 'text' attribute with newline chars.
466
     *
467
     * @return mixed
468
     */
469
    public function getTextareaAttribute()
470
    {
471
        return $this->attributes['bio'];
472
    }
473
474
    /**
475
     * Retrieve a User's custom email footer.
476
     *
477
     * @return string
478
     */
479
    public function getEmailFooterAttribute(): string
480
    {
481
        $footer = "{$this->name}";
482
        $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...
483
        $footer .= "\n".OrganizationService::name() ?? '';
484
        $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...
485
        $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...
486
487
        return $footer;
488
    }
489
}
490