Passed
Pull Request — master (#50)
by Ronan
05:05
created

User::getLevelOptions()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 3
c 0
b 0
f 0
dl 0
loc 5
ccs 0
cts 2
cp 0
rs 10
cc 1
nc 1
nop 0
crap 2
1
<?php
2
3
namespace App\Model;
4
5
use App\Model\Finder\UserFinder;
6
use Carbon\Carbon;
7
use Respect\Validation\Validator;
8
use Ronanchilvers\Orm\Model;
9
use Ronanchilvers\Orm\Traits\HasValidationTrait;
10
use Ronanchilvers\Utility\Str;
11
12
/**
13
 * Model representing a project
14
 *
15
 * @property int id
16
 * @property string name
17
 * @property string email
18
 * @property string password
19
 * @property string status
20
 * @property null|string preferences
21
 * @property string level
22
 * @property null|\Carbon\Carbon last_login
23
 * @property null|\Carbon\Carbon created
24
 * @property null|\Carbon\Carbon updated
25
 * @author Ronan Chilvers <[email protected]>
26
 */
27
class User extends Model
28
{
29
    const STATUS_ACTIVE   = 'active';
30
    const STATUS_INACTIVE = 'inactive';
31
    const STATUS_PENDING  = 'pending';
32
33
    const LEVEL_USER      = 'user';
34
    const LEVEL_ADMIN     = 'admin';
35
36
    use HasValidationTrait;
37
38
    static protected $finder       = UserFinder::class;
39
    static protected $columnPrefix = 'user';
40
41
    protected $data = [
42
        'user_status' => 'pending',
43
        'user_level'  => 'user',
44
    ];
45
46
    /**
47
     * @author Ronan Chilvers <[email protected]>
48
     */
49
    protected function boot()
50
    {
51
        $this->addType('datetime', 'last_login');
52
        $this->addType('array', 'preferences');
53
    }
54
55
    /**
56
     * @author Ronan Chilvers <[email protected]>
57
     */
58
    protected function setupValidation()
59
    {
60
        $this->registerRules([
61
            'name'     => Validator::notEmpty(),
62
            'email'    => Validator::notEmpty()->email(),
63
            'password' => Validator::notEmpty(),
64
            'status'   => Validator::notEmpty()->in([
65
                static::STATUS_PENDING,
66
                static::STATUS_INACTIVE,
67
                static::STATUS_ACTIVE,
68
            ]),
69
            'level'   => Validator::notEmpty()->in([
70
                static::LEVEL_USER,
71
                static::LEVEL_ADMIN,
72
            ]),
73
        ]);
74
        $this->registerRules([
75
            'password' => Validator::notEmpty(),
76
        ], 'security');
77
    }
78
79
    /**
80
     * Get the user level options for this user
81
     *
82
     * @return array
83
     * @author Ronan Chilvers <[email protected]>
84
     */
85
    public function getLevelOptions(): array
86
    {
87
        return [
88
            static::LEVEL_USER => static::LEVEL_USER,
89
            static::LEVEL_ADMIN => static::LEVEL_ADMIN,
90
        ];
91
    }
92
93
    /**
94
     * Get the status options for this user
95
     *
96
     * @return array
97
     * @author Ronan Chilvers <[email protected]>
98
     */
99
    public function getStatusOptions(): array
100
    {
101
        return [
102
            static::STATUS_INACTIVE => static::STATUS_INACTIVE,
103
            static::STATUS_ACTIVE   => static::STATUS_ACTIVE,
104
        ];
105
    }
106
107
    /**
108
     * Get a preference by key
109
     *
110
     * @param string $key
111
     * @param mixed $default
112
     * @author Ronan Chilvers <[email protected]>
113
     */
114
    public function preference($key, $default = null)
115
    {
116
        $preferences = $this->preferences;
117
        if (is_null($preferences)) {
118
            return $default;
119
        }
120
        if (!isset($preferences[$key])) {
121
            return $default;
122
        }
123
124
        return $preferences[$key];
125
    }
126
127
    /**
128
     * Set a preference value for the user
129
     *
130
     * @param $key
131
     * @param mixed $value
132
     * @author Ronan Chilvers <[email protected]>
133
     */
134
    public function setPreference($key, $value)
135
    {
136
        $preferences       = $this->preferences;
137
        $preferences[$key] = $value;
138
        $this->preferences = $preferences;
139
140
        return $this->save();
141
    }
142
143
    /**
144
     * Verify a password against this user
145
     *
146
     * @param string $password
147
     * @return boolean
148
     * @author Ronan Chilvers <[email protected]>
149
     */
150
    public function verify($password)
151
    {
152
        if (!$this->isLoaded()) {
153
            return false;
154
        }
155
156
        return password_verify($password, $this->password);
157
    }
158
159
    /**
160
     * Verify and set a new password
161
     *
162
     * @param string $old
163
     * @param string $new
164
     * @param string $confirm
165
     * @return bool
166
     * @author Ronan Chilvers <[email protected]>
167
     */
168
    public function setNewPassword(string $old, string $new, string $confirm)
169
    {
170
        foreach (['old', 'new', 'confirm'] as $var) {
171
            $$var = trim($$var);
172
        }
173
        if (!$this->verify($old)) {
174
            return false;
175
        }
176
177
        if (empty($new)) {
178
            return false;
179
        }
180
181
        if ($new !== $confirm) {
182
            return false;
183
        }
184
185
        $this->password = password_hash($new, PASSWORD_DEFAULT);
186
187
        return true;
188
    }
189
190
    /**
191
     * Record a last login timestamp
192
     *
193
     * @author Ronan Chilvers <[email protected]>
194
     */
195
    public function recordLogin(): bool
196
    {
197
        $this->last_login = Carbon::now();
198
199
        return $this->save();
200
    }
201
}
202