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

User::setupValidation()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

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