ProfileForm::changeEmail()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 6
nc 2
nop 0
1
<?php
2
3
class ProfileForm extends CFormModel
0 ignored issues
show
Coding Style Compatibility introduced by
PSR1 recommends that each class must be in a namespace of at least one level to avoid collisions.

You can fix this by adding a namespace to your class:

namespace YourVendor;

class YourClass { }

When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.

Loading history...
4
{
5
	/**
6
	 * The user's email address
7
	 * @var string $email
8
	 */
9
	public $email;
10
11
	/**
12
	 * The user's NEW password
13
	 * @var string $password
14
	 */
15
	public $password;
16
17
	/**
18
	 * The repeated password if a NEW password is applied
19
	 * @var string $password_repeat
20
	 */
21
	public $password_repeat;
22
23
	/**
24
	 * The user's current password
25
	 * This field is required to make any changes to the account
26
	 * @var string $currentPassword
27
	 */
28
	public $currentPassword;
29
30
	/**
31
	 * The user's display name
32
	 * @var string $username
33
	 */
34
	public $username;
35
36
	/**
37
	 * The user role
38
	 * @var int $role
39
	 */
40
	public $user_role;
41
42
	/**
43
	 * The user model
44
	 * @var Users $_user
45
	 */
46
	private $_user = NULL;
47
48
	/**
49
	 * This form will likely be reused in admin portals, for re-use purposes authentication is not required to change privileged information
50
	 * @var boolean $overridePasswordCheck
51
	 */
52
	private $overridePasswordCheck = false;
53
54
55
	private function canOverridePasswordCheck()
56
	{
57
		if ($this->overridePasswordCheck)
58
			return true;
59
60
		if (isset(Yii::app()->user) && $this->getId() == Yii::app()->user->id)
61
			return true;
62
63
		return false;
64
	}
65
66
	/**
67
	 * Overload of the __getter method to retrieve the user's ID
68
	 * @var int $id
69
	 */
70
	public function getId()
71
	{
72
		return $this->_user->id;
73
	}
74
75
	/**
76
	 * Retrieves the new email address if it is set
77
	 * @return mixed
78
	 */
79
	public function getNewEmail()
80
	{
81
		$metadata = UserMetadata::model()->findByAttributes(array(
82
			'user_id' => $this->_user->id,
83
			'key'     => 'newEmailAddress'
84
		));
85
86
		if ($metadata == NULL)
87
			return NULL;
88
89
		return $metadata->value;
90
	}
91
92
	/**
93
	 * Sets the new email address
94
	 * @return boolean
95
	 */
96
	public function setNewEmail()
97
	{
98
		$metadata = UserMetadata::model()->findByAttributes(array(
99
			'user_id' => $this->_user->id,
100
			'key'     => 'newEmailAddress'
101
		));
102
103
		if ($metadata == NULL)
104
		{
105
			$metadata = new UserMetadata;
106
			$metadata->attributes = array(
107
				'user_id' => $this->_user->id,
108
				'key'     => 'newEmailAddress'
109
			);
110
		}
111
112
		$metadata->value = $this->email;
113
114
		// Save the record
115
		return $metadata->save();
116
	}
117
118
	/**
119
	 * Retrieves the new email address if it is set
120
	 * @return mixed
121
	 */
122
	public function getNewEmailChangeKey()
123
	{
124
		$metadata = UserMetadata::model()->findByAttributes(array(
125
			'user_id' => $this->_user->id,
126
			'key'     => 'newEmailAddressChangeKey'
127
		));
128
129
		if ($metadata == NULL)
130
			return NULL;
131
132
		return $metadata->value;
133
	}
134
135
	/**
136
	 * Generates a new change key
137
	 * @return boolean
138
	 */
139
	public function setNewEmailChangeKey()
140
	{
141
		$metadata = UserMetadata::model()->findByAttributes(array(
142
			'user_id' => $this->_user->id,
143
			'key'     => 'newEmailAddressChangeKey'
144
		));
145
146
		if ($metadata == NULL)
147
		{
148
			$metadata = new UserMetadata;
149
			$metadata->attributes = array(
150
				'user_id' => $this->_user->id,
151
				'key'     => 'newEmailAddressChangeKey'
152
			);
153
		}
154
155
		// Generate a new key
156
		$metadata->value = Cii::generateSafeHash();
157
158
		// Save the record
159
		if ($metadata->save())
160
			return $metadata->value;
161
	
162
		throw new CHttpException(500, Yii::t('ciims.ProfileForm', 'Unable to save change key'));
163
	}
164
165
	/**
166
	 * Validation rules
167
	 * @return array
168
	 */
169
	public function rules()
170
	{
171
		return array(
172
			array('email, username', 'required'),
173
			array('username', 'length', 'max' => 255),
174
			array('currentPassword', 'validateUserPassword'),
175
			array('password', 'compare'),
176
			array('password', 'length', 'min' => 8),
177
			array('user_role', 'numerical'),
178
			array('user_role', 'validateUserRole')
179
		);
180
	}
181
182
	/**
183
	 * Retrieves the attributes labels from the Users model and returns them to reduce code redundancy
184
	 * @return array
185
	 */
186
	public function attributeLabels()
187
	{
188
		return CMap::mergeArray(Users::model()->attributeLabels(), array(
189
			'currentPassword' => Yii::t('ciims.models.ProfileForm', 'Your current password'),
190
			'password_repeat' => Yii::t('ciims.models.ProfileForm', 'Your New Password (again)')
191
		));
192
	}
193
194
	/**
195
	 * Validates the role
196
	 * @param array $attributes
197
	 * @param array $params
198
	 * return array
199
	 */
200
	public function validateUserRole($attributes, $params)
201
	{
202
		if ($this->canOverridePasswordCheck())
203
			return true;
204
205
		$this->addError('user_role', Yii::t('ciims.models.ProfileForm', 'You do not have permission to modify this attribute'));
206
		return false;
207
	}
208
209
	/**
210
	 * Ensures that the password entered matches the one provided during registration
211
	 * @param array $attributes
212
	 * @param array $params
213
	 * return array
214
	 */
215
	public function validateUserPassword($attributes, $params)
216
	{
217
		// Apply the override if it was set
218
		if ($this->canOverridePasswordCheck())
219
		{
220
			$this->password_repeat = $this->password;
221
			return true;
222
		}
223
224
		$result = password_verify($this->password, $this->_user->password);
225
		
226
		if ($result == false)
227
		{
228
			$this->addError('currentPassword', Yii::t('ciims.models.ProfileForm', 'The password you entered is invalid.'));
229
			return false;
230
		}
231
232
		return true;
233
	}
234
235
	/**
236
	 * Internally loads the user's information before attempting to validate it
237
	 * @param int  $id         The user's ID
238
	 * @param bool $override   This form may be reused
239
	 * @return ProfileForm
240
	 */
241
	public function load($id, $override = false)
242
	{
243
		$this->overridePasswordCheck = $override;
244
245
		// Load the user
246
		$this->_user = Users::model()->findByPk($id);
247
248
		if ($this->_user == NULL)
249
			throw new CHttpException(400, Yii::t('ciims.models.ProfileForm', 'The request user\'s profile could not be loaded'));
250
251
		// Reload the attribute labels
252
		$this->attributes = array(
253
			'email'         => $this->_user->email,
254
			'username'      => $this->_user->username,
255
			'user_role'     => $this->_user->role->id
256
		);
257
258
		return $this;
259
	}
260
261
	/**
262
	 * Updates the user's profile information
263
	 * @return boolean
264
	 */
265
	public function save()
266
	{
267
		if (!$this->validate(NULL, false))
268
			return false;
269
270
		// Change the email address, if necessary
271
		$this->changeEmail();
272
273
		$this->_user->attributes = array(
274
			'password'      => $this->password,
275
			'username'      => $this->username,
276
			'user_role'     => $this->user_role
277
		);
278
279
		if ($this->_user->save())
280
			return true;
281
282
		return false;
283
	}
284
285
	/**
286
	 * Changes the user's email address if necessary
287
	 * @return boolean
288
	 */
289
	private function changeEmail()
290
	{
291
		if ($this->email != $this->_user->email)
292
		{
293
			$this->setNewemail();
294
			$this->setNewEmailChangeKey();
295
			$this->sendVerificationEmail();
296
		}
297
298
		return true;
299
	}
300
301
	/**
302
	 * Sends the verification email to the user. This is broken to it's own method to allow for the resending email to be resent
303
	 * @return boolean
304
	 */
305
	public function sendVerificationEmail()
306
	{
307
		$emailSettings = new EmailSettings;
308
        return $emailSettings->send(
309
			$this->_user,
310
			Yii::t('ciims.models.Users', 'CiiMS Email Change Notification'),
311
			'base.themes.' . Cii::getConfig('theme', 'default') .'.views.email.email-change',
312
			array(
313
				'key' => $this->setNewEmailChangeKey(),
314
				'user' => $this->_user
315
			)
316
		);
317
	}
318
}
319