Completed
Push — master ( c6794e...0594fd )
by Nazar
03:59
created

User::disable_memory_cache()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 4
c 1
b 0
f 0
nc 1
nop 0
dl 0
loc 5
ccs 5
cts 5
cp 1
crap 1
rs 9.4285
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
	 * Whether to use memory cache (locally, inside object, may require a lot of memory if working with many users together)
110
	 * @var bool
111
	 */
112
	protected $memory_cache = true;
113
	/**
114
	 * Returns database index
115
	 *
116
	 * @return int
117
	 */
118 20
	protected function cdb () {
119 20
		return Config::instance()->module('System')->db('users');
120
	}
121 22
	protected function construct () {
122 22
		$this->cache = Cache::prefix('users');
123 22
		Event::instance()->fire('System/User/construct/before');
124 22
		$this->initialize_data();
125
		/**
126
		 * Initialize session
127
		 */
128 22
		Session::instance();
129 22
		Event::instance()->fire('System/User/construct/after');
130 22
	}
131
	/**
132
	 * Check number of sign in attempts (is used by system)
133
	 *
134
	 * @param string $login_hash Hash (sha224) from login (hash from lowercase string)
135
	 *
136
	 * @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...
137
	 */
138
	function get_sign_in_attempts_count ($login_hash) {
139
		if (!preg_match('/^[0-9a-z]{56}$/', $login_hash)) {
140
			return false;
141
		}
142
		$time = time();
143
		return $this->db()->qfs(
144
			"SELECT COUNT(`expire`)
145
			FROM `[prefix]sign_ins`
146
			WHERE
147
				`expire` > $time AND
148
				(
149
					`login_hash`	= '%s' OR
150
					`ip`			= '%s'
151
				)",
152
			$login_hash,
153
			ip2hex(Request::instance()->ip)
154
		);
155
	}
156
	/**
157
	 * Process sign in result (is used by system)
158
	 *
159
	 * @param bool   $success
160
	 * @param string $login_hash Hash (sha224) from login (hash from lowercase string)
161
	 */
162 4
	function sign_in_result ($success, $login_hash) {
163 4
		if (!preg_match('/^[0-9a-z]{56}$/', $login_hash)) {
164
			return;
165
		}
166 4
		$ip   = ip2hex(Request::instance()->ip);
167 4
		$time = time();
168 4
		if ($success) {
169 4
			$this->db_prime()->q(
170
				"DELETE FROM `[prefix]sign_ins`
171
				WHERE
172 4
					`expire` > $time AND
173
					(
174
						`login_hash` = '%s' OR `ip` = '%s'
175 4
					)",
176
				$login_hash,
177
				$ip
178
			);
179
		} else {
180
			$Config = Config::instance();
181
			$this->db_prime()->q(
182
				"INSERT INTO `[prefix]sign_ins`
183
					(
184
						`expire`,
185
						`login_hash`,
186
						`ip`
187
					) VALUES (
188
						'%s',
189
						'%s',
190
						'%s'
191
					)",
192
				$time + $Config->core['sign_in_attempts_block_time'],
193
				$login_hash,
194
				$ip
195
			);
196
			if ($this->db_prime()->id() % $Config->core['inserts_limit'] == 0) {
197
				$this->db_prime()->q("DELETE FROM `[prefix]sign_ins` WHERE `expire` < $time");
198
			}
199
		}
200 4
	}
201
	/**
202
	 * Get data item of current user
203
	 *
204
	 * @param string|string[] $item
205
	 *
206
	 * @return false|int|mixed[]|string|User\Properties If <i>$item</i> is integer - cs\User\Properties object will be returned
207
	 */
208 16
	function __get ($item) {
209 16
		if ($item == 'id') {
210 16
			return Session::instance()->get_user();
211
		}
212 2
		return $this->get($item);
213
	}
214
	/**
215
	 * Set data item of current user
216
	 *
217
	 * @param array|int|string $item Item-value array may be specified for setting several items at once
218
	 * @param mixed|null       $value
219
	 *
220
	 * @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...
221
	 */
222
	function __set ($item, $value = null) {
223
		$this->set($item, $value);
224
	}
225
	/**
226
	 * Is admin
227
	 *
228
	 * Proxy to \cs\Session::instance()->admin() for convenience
229
	 *
230
	 * @return bool
231
	 */
232 8
	function admin () {
233 8
		return Session::instance()->admin();
234
	}
235
	/**
236
	 * Is user
237
	 *
238
	 * Proxy to \cs\Session::instance()->user() for convenience
239
	 *
240
	 * @return bool
241
	 */
242
	function user () {
243
		return Session::instance()->user();
244
	}
245
	/**
246
	 * Is guest
247
	 *
248
	 * Proxy to \cs\Session::instance()->guest() for convenience
249
	 *
250
	 * @return bool
251
	 */
252 6
	function guest () {
253 6
		return Session::instance()->guest();
254
	}
255
	/**
256
	 * Disable memory cache
257
	 *
258
	 * Memory cache stores users data inside User class in order to get data faster next time.
259
	 * But in case of working with large amount of users this cache can be too large. Disabling will cause some performance drop, but save a lot of RAM.
260
	 */
261 6
	function disable_memory_cache () {
262 6
		$this->memory_cache = false;
263 6
		$this->data         = [];
264 6
		$this->permissions  = [];
265 6
	}
266
}
267