Completed
Push — master ( a59dca...9322be )
by Nazar
05:41
created

User   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 184
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 14

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
dl 0
loc 184
ccs 26
cts 26
cp 1
rs 10
c 0
b 0
f 0
wmc 14
lcom 1
cbo 14

9 Methods

Rating   Name   Duplication   Size   Complexity  
A cdb() 0 3 1
A construct() 0 10 1
A get_sign_in_attempts_count() 0 18 2
B sign_in_result() 0 39 4
A __set() 0 3 1
A admin() 0 3 1
A user() 0 3 1
A guest() 0 3 1
A __get() 0 6 2
1
<?php
2
/**
3
 * @package   CleverStyle Framework
4
 * @author    Nazar Mokrynskyi <[email protected]>
5
 * @copyright Copyright (c) 2011-2016, Nazar Mokrynskyi
6
 * @license   MIT License, see license.txt
7
 */
8
namespace cs;
9
use
10
	cs\DB\Accessor,
11
	cs\User\Data as User_data,
12
	cs\User\Group as User_group,
13
	cs\User\Management as User_management,
14
	cs\User\Permission as User_permission,
15
	cs\User\Profile as User_profile;
16
17
/**
18
 * Class for users manipulating
19
 *
20
 * Provides next events:
21
 *  System/User/construct/before
22
 *
23
 *  System/User/construct/after
24
 *
25
 *  System/User/registration/before
26
 *  ['email' => <i>email</i>]
27
 *
28
 *  System/User/registration/after
29
 *  ['id' => <i>user_id</i>]
30
 *
31
 *  System/User/registration/confirmation/before
32
 *  ['reg_key' => <i>reg_key</i>]
33
 *
34
 *  System/User/registration/confirmation/after
35
 *  ['id' => <i>user_id</i>]
36
 *
37
 *  System/User/del/before
38
 *  ['id' => <i>user_id</i>]
39
 *
40
 *  System/User/del/after
41
 *  ['id' => <i>user_id</i>]
42
 *
43
 *  System/User/get_contacts
44
 *  [
45
 *    'id'       => <i>user_id</i>,
46
 *    'contacts' => <i>&$contacts</i> //Array of user id
47
 *  ]
48
 *
49
 * @property int    $id
50
 * @property string $login
51
 * @property string $login_hash    sha224 hash
52
 * @property string $username
53
 * @property string $password_hash sha512 hash
54
 * @property string $email
55
 * @property string $email_hash    sha224 hash
56
 * @property string $language
57
 * @property string $timezone
58
 * @property int    $reg_date      unix timestamp
59
 * @property string $reg_ip        hex value, obtained by function ip2hex()
60
 * @property string $reg_key       random md5 hash, generated during registration
61
 * @property int    $status        '-1' - not activated (for example after registration), 0 - inactive, 1 - active
62
 * @property int    $block_until   unix timestamp
63
 * @property string $avatar
64
 *
65
 * @method static $this instance($check = false)
66
 */
67
class User {
68
	use
69
		Accessor,
70
		Singleton,
71
		User_data,
72
		User_group,
73
		User_management,
74
		User_permission,
75
		User_profile;
76
	/**
77
	 * Id of system guest user
78
	 */
79
	const GUEST_ID = 1;
80
	/**
81
	 * Id of first, primary system administrator
82
	 */
83
	const ROOT_ID = 2;
84
	/**
85
	 * Id of system group for administrators
86
	 */
87
	const ADMIN_GROUP_ID = 1;
88
	/**
89
	 * Id of system group for users
90
	 */
91
	const USER_GROUP_ID = 2;
92
	/**
93
	 * Status of active user
94
	 */
95
	const STATUS_ACTIVE = 1;
96
	/**
97
	 * Status of inactive user
98
	 */
99
	const STATUS_INACTIVE = 0;
100
	/**
101
	 * Status of not activated user
102
	 */
103
	const STATUS_NOT_ACTIVATED = -1;
104
	/**
105
	 * @var Cache\Prefix
106
	 */
107
	protected $cache;
108
	/**
109
	 * Returns database index
110
	 *
111
	 * @return int
112
	 */
113 12
	protected function cdb () {
114 12
		return Config::instance()->module('System')->db('users');
115
	}
116 12
	protected function construct () {
117 12
		$this->cache = Cache::prefix('users');
118 12
		Event::instance()->fire('System/User/construct/before');
119 12
		$this->initialize_data();
120
		/**
121
		 * Initialize session
122
		 */
123 12
		Session::instance();
124 12
		Event::instance()->fire('System/User/construct/after');
125 12
	}
126
	/**
127
	 * Check number of sign in attempts (is used by system)
128
	 *
129
	 * @param string $login_hash Hash (sha224) from login (hash from lowercase string)
130
	 *
131
	 * @return int Number of attempts
1 ignored issue
show
Documentation introduced by
Should the return type not be false|array[]|integer|integer[]|string|string[]?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
132
	 */
133
	function get_sign_in_attempts_count ($login_hash) {
134
		if (!preg_match('/^[0-9a-z]{56}$/', $login_hash)) {
135
			return false;
136
		}
137
		$time = time();
138
		return $this->db()->qfs(
139
			"SELECT COUNT(`expire`)
140
			FROM `[prefix]sign_ins`
141
			WHERE
142
				`expire` > $time AND
143
				(
144
					`login_hash`	= '%s' OR
145
					`ip`			= '%s'
146
				)",
147
			$login_hash,
148
			ip2hex(Request::instance()->ip)
149
		);
150
	}
151
	/**
152
	 * Process sign in result (is used by system)
153
	 *
154
	 * @param bool   $success
155
	 * @param string $login_hash Hash (sha224) from login (hash from lowercase string)
156
	 */
157 2
	function sign_in_result ($success, $login_hash) {
158 2
		if (!preg_match('/^[0-9a-z]{56}$/', $login_hash)) {
159
			return;
160
		}
161 2
		$ip   = ip2hex(Request::instance()->ip);
162 2
		$time = time();
163 2
		if ($success) {
164 2
			$this->db_prime()->q(
165
				"DELETE FROM `[prefix]sign_ins`
166
				WHERE
167 2
					`expire` > $time AND
168
					(
169
						`login_hash` = '%s' OR `ip` = '%s'
170 2
					)",
171
				$login_hash,
172
				$ip
173
			);
174
		} else {
175
			$Config = Config::instance();
176
			$this->db_prime()->q(
177
				"INSERT INTO `[prefix]sign_ins`
178
					(
179
						`expire`,
180
						`login_hash`,
181
						`ip`
182
					) VALUES (
183
						'%s',
184
						'%s',
185
						'%s'
186
					)",
187
				$time + $Config->core['sign_in_attempts_block_time'],
188
				$login_hash,
189
				$ip
190
			);
191
			if ($this->db_prime()->id() % $Config->core['inserts_limit'] == 0) {
192
				$this->db_prime()->q("DELETE FROM `[prefix]sign_ins` WHERE `expire` < $time");
193
			}
194
		}
195 2
	}
196
	/**
197
	 * Get data item of current user
198
	 *
199
	 * @param string|string[] $item
200
	 *
201
	 * @return false|int|mixed[]|string|User\Properties If <i>$item</i> is integer - cs\User\Properties object will be returned
202
	 */
203 10
	function __get ($item) {
204 10
		if ($item == 'id') {
205 10
			return Session::instance()->get_user();
206
		}
207 2
		return $this->get($item);
208
	}
209
	/**
210
	 * Set data item of current user
211
	 *
212
	 * @param array|int|string $item Item-value array may be specified for setting several items at once
213
	 * @param mixed|null       $value
214
	 *
215
	 * @return bool
1 ignored issue
show
Documentation introduced by
Should the return type not be boolean|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
216
	 */
217
	function __set ($item, $value = null) {
218
		$this->set($item, $value);
219
	}
220
	/**
221
	 * Is admin
222
	 *
223
	 * Proxy to \cs\Session::instance()->admin() for convenience
224
	 *
225
	 * @return bool
226
	 */
227 4
	function admin () {
228 4
		return Session::instance()->admin();
229
	}
230
	/**
231
	 * Is user
232
	 *
233
	 * Proxy to \cs\Session::instance()->user() for convenience
234
	 *
235
	 * @return bool
236
	 */
237
	function user () {
238
		return Session::instance()->user();
239
	}
240
	/**
241
	 * Is guest
242
	 *
243
	 * Proxy to \cs\Session::instance()->guest() for convenience
244
	 *
245
	 * @return bool
246
	 */
247 4
	function guest () {
248 4
		return Session::instance()->guest();
249
	}
250
}
251