Completed
Push — master ( fba85e...f9ec74 )
by Nazar
03:59
created

user_   B

Complexity

Total Complexity 44

Size/Duplication

Total Lines 223
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 9

Importance

Changes 5
Bugs 0 Features 0
Metric Value
wmc 44
c 5
b 0
f 0
lcom 1
cbo 9
dl 0
loc 223
rs 8.3396

5 Methods

Rating   Name   Duplication   Size   Complexity  
B user_change_password() 0 23 6
D user_registration() 0 77 17
B user_restore_password() 0 32 6
C user_sign_in() 0 45 12
A user_sign_out() 0 16 3

How to fix   Complexity   

Complex Class

Complex classes like user_ often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use user_, and based on these observations, apply Extract Interface, too.

1
<?php
2
/**
3
 * @package    CleverStyle CMS
4
 * @subpackage System module
5
 * @category   modules
6
 * @author     Nazar Mokrynskyi <[email protected]>
7
 * @copyright  Copyright (c) 2015-2016, Nazar Mokrynskyi
8
 * @license    MIT License, see license.txt
9
 */
10
namespace cs\modules\System\api\Controller;
11
use
12
	cs\Config,
13
	cs\ExitException,
14
	cs\Language,
15
	cs\Language\Prefix,
16
	cs\Mail,
17
	cs\Page,
18
	cs\Session,
19
	cs\User;
20
21
trait user_ {
22
	/**
23
	 * @param \cs\Request $Request
24
	 *
25
	 * @throws ExitException
26
	 */
27
	static function user_change_password ($Request) {
28
		$L    = new Prefix('system_profile_');
29
		$User = User::instance();
30
		$data = $Request->data('current_password', 'new_password');
31
		if (!$data) {
32
			throw new ExitException(400);
33
		}
34
		if (!$User->user()) {
35
			throw new ExitException(403);
36
		}
37
		if (!$data['new_password']) {
38
			throw new ExitException($L->please_type_new_password, 400);
39
		}
40
		if (!$User->validate_password($data['current_password'], $User->id, true)) {
41
			throw new ExitException($L->wrong_current_password, 400);
42
		}
43
		$id = $User->id;
44
		if ($User->set_password($data['new_password'], $id, true)) {
45
			Session::instance()->add($id);
46
		} else {
47
			throw new ExitException($L->change_password_server_error, 400);
48
		}
49
	}
50
	/**
51
	 * @param \cs\Request $Request
52
	 *
53
	 * @throws ExitException
54
	 * @throws \phpmailerException
55
	 */
56
	static function user_registration ($Request) {
57
		$Config = Config::instance();
58
		$L      = new Prefix('system_profile_registration_');
59
		$User   = User::instance();
60
		if (!$User->guest()) {
61
			throw new ExitException(403);
62
		}
63
		if (!$Config->core['allow_user_registration']) {
64
			throw new ExitException($L->prohibited, 403);
65
		}
66
		$email = $Request->data('email');
67
		if (!$email) {
68
			throw new ExitException($L->please_type_your_email, 400);
69
		}
70
		$email  = mb_strtolower($email);
71
		$result = $User->registration($email);
72
		if ($result === false) {
73
			throw new ExitException($L->please_type_correct_email, 400);
74
		}
75
		if ($result == 'error') {
76
			throw new ExitException($L->server_error, 500);
77
		}
78
		if ($result == 'exists') {
79
			throw new ExitException($L->error_exists, 400);
80
		}
81
		$confirm = $result['reg_key'] !== true;
82
		if ($Request->data('username')) {
83
			$User->set('username', $Request->data['username'], $result['id']);
84
		}
85
		// Actually `sha512(sha512(password) + public_key)` instead of plain password
86
		if ($Request->data('password')) {
87
			$User->set_password($Request->data['password'], $result['id'], true);
88
		}
89
		if ($Request->data('language')) {
90
			$User->set('language', $Request->data['language'], $result['id']);
91
		}
92
		if ($Request->data('timezone')) {
93
			$User->set('timezone', $Request->data['timezone'], $result['id']);
94
		}
95
		if ($Request->data('avatar')) {
96
			$User->set('avatar', $Request->data['avatar'], $result['id']);
97
		}
98
		if ($confirm) {
99
			$body = $L->need_confirmation_mail_body(
100
				$User->username($result['id']),
101
				get_core_ml_text('name'),
102
				$Config->core_url()."/profile/registration_confirmation/$result[reg_key]",
103
				$L->time($Config->core['registration_confirmation_time'], 'd')
104
			);
105
		} elseif ($result['password']) {
106
			$body = $L->success_mail_with_password_body(
107
				$User->username($result['id']),
108
				get_core_ml_text('name'),
109
				$Config->core_url().'/profile/settings',
110
				$User->get('login', $result['id']),
111
				$result['password']
112
			);
113
		} else {
114
			$body = $L->success_mail(
115
				$User->username($result['id']),
116
				get_core_ml_text('name'),
117
				$Config->core_url().'/profile/settings',
118
				$User->get('login', $result['id'])
119
			);
120
		}
121
		if (!Mail::instance()->send_to(
122
			$email,
123
			$L->{$confirm ? 'need_confirmation_mail' : 'success_mail'}(get_core_ml_text('name')),
124
			$body
125
		)
126
		) {
127
			$User->registration_cancel();
128
			throw new ExitException($L->mail_sending_error, 500);
129
		}
130
		// TODO: better implement using 2 status codes: 202 if confirmation needed and 201 otherwise
131
		Page::instance()->json($confirm ? 'registration_confirmation' : 'registration_success');
132
	}
133
	/**
134
	 * @param \cs\Request $Request
135
	 *
136
	 * @throws ExitException
137
	 * @throws \phpmailerException
138
	 */
139
	static function user_restore_password ($Request) {
140
		$Config = Config::instance();
141
		$L      = new Prefix('system_profile_restore_password_');
142
		$User   = User::instance();
143
		$email  = $Request->data('email');
144
		if (!$User->guest()) {
145
			throw new ExitException(403);
146
		}
147
		if (!$email) {
148
			throw new ExitException($L->please_type_your_email, 400);
149
		}
150
		$id = $User->get_id(mb_strtolower($email));
151
		if (!$id) {
152
			throw new ExitException($L->user_with_such_login_email_not_found, 400);
153
		}
154
		$key = $User->restore_password($id);
155
		if (
156
			!$key ||
157
			!Mail::instance()->send_to(
158
				$User->get('email', $id),
159
				$L->confirmation_mail(get_core_ml_text('name')),
160
				$L->confirmation_mail_body(
161
					$User->username($id),
162
					get_core_ml_text('name'),
163
					$Config->core_url()."/profile/restore_password_confirmation/$key",
164
					$L->time($Config->core['registration_confirmation_time'], 'd')
165
				)
166
			)
167
		) {
168
			throw new ExitException($L->server_error, 500);
169
		}
170
	}
171
	/**
172
	 * @param \cs\Request $Request
173
	 *
174
	 * @throws ExitException
175
	 */
176
	static function user_sign_in ($Request) {
177
		$Config = Config::instance();
178
		$L      = new Prefix('system_profile_sign_in_');
179
		$User   = User::instance();
180
		$data   = $Request->data('login', 'password');
181
		if (!$data) {
182
			throw new ExitException(400);
183
		}
184
		if (!$User->guest()) {
185
			return;
186
		}
187
		if (
188
			$Config->core['sign_in_attempts_block_count'] &&
189
			$User->get_sign_in_attempts_count($data['login']) >= $Config->core['sign_in_attempts_block_count']
190
		) {
191
			$User->sign_in_result(false, $data['login']);
192
			throw new ExitException($L->attempts_are_over_try_again_in(format_time($Config->core['sign_in_attempts_block_time'])), 403);
193
		}
194
		$id = $User->get_id($data['login']);
195
		if ($id && $User->validate_password($data['password'], $id, true)) {
196
			$status      = $User->get('status', $id);
197
			$block_until = $User->get('block_until', $id);
198
			if ($status == User::STATUS_NOT_ACTIVATED) {
199
				throw new ExitException($L->your_account_is_not_active, 403);
200
			}
201
			if ($status == User::STATUS_INACTIVE) {
202
				throw new ExitException($L->your_account_disabled, 403);
203
			}
204
			if ($block_until > time()) {
205
				throw new ExitException($L->your_account_blocked_until(date($L->_datetime, $block_until)), 403);
206
			}
207
			Session::instance()->add($id);
208
			$User->sign_in_result(true, $data['login']);
209
		} else {
210
			$User->sign_in_result(false, $data['login']);
211
			$content = $L->authentication_error;
212
			if (
213
				$Config->core['sign_in_attempts_block_count'] &&
214
				$User->get_sign_in_attempts_count($data['login']) >= $Config->core['sign_in_attempts_block_count'] * 2 / 3
215
			) {
216
				$content .= ' '.$L->attempts_left($Config->core['sign_in_attempts_block_count'] - $User->get_sign_in_attempts_count($data['login']));
217
			}
218
			throw new ExitException($content, 400);
219
		}
220
	}
221
	/**
222
	 * @param \cs\Request  $Request
223
	 * @param \cs\Response $Response
224
	 *
225
	 * @throws ExitException
226
	 */
227
	static function user_sign_out (
228
		/** @noinspection PhpUnusedParameterInspection */
229
		$Request,
1 ignored issue
show
Unused Code introduced by
The parameter $Request is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
230
		$Response
231
	) {
232
		if (User::instance()->guest()) {
233
			return;
234
		}
235
		if (!Session::instance()->del()) {
236
			throw new ExitException(500);
237
		}
238
		/**
239
		 * Hack for 403 after sign out in administration
240
		 */
241
		$Response->cookie('sign_out', 1, TIME + 5, true);
242
	}
243
}
244