Completed
Push — master ( d70e6c...215c97 )
by Nazar
04:09
created

User::guest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 2
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 0
cp 0
crap 2
rs 10
c 0
b 0
f 0
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
 * @property int    $id
44
 * @property string $login
45
 * @property string $login_hash    sha224 hash
46
 * @property string $username
47
 * @property string $password_hash sha512 hash
48
 * @property string $email
49
 * @property string $email_hash    sha224 hash
50
 * @property string $language
51
 * @property string $timezone
52
 * @property int    $reg_date      unix timestamp
53
 * @property string $reg_ip        hex value, obtained by function ip2hex()
54
 * @property string $reg_key       random md5 hash, generated during registration
55
 * @property int    $status        '-1' - not activated (for example after registration), 0 - inactive, 1 - active
56
 * @property int    $block_until   unix timestamp
57
 * @property string $avatar
58
 *
59
 * @method static $this instance($check = false)
60
 */
61
class User {
62
	use
63
		Accessor,
64
		Singleton,
65
		User_data,
66
		User_group,
67
		User_management,
68
		User_permission,
69
		User_profile;
70
	/**
71
	 * Id of system guest user
72
	 */
73
	const GUEST_ID = 1;
74
	/**
75
	 * Id of first, primary system administrator
76
	 */
77
	const ROOT_ID = 2;
78
	/**
79
	 * Id of system group for administrators
80
	 */
81
	const ADMIN_GROUP_ID = 1;
82
	/**
83
	 * Id of system group for users
84
	 */
85
	const USER_GROUP_ID = 2;
86
	/**
87
	 * Status of active user
88
	 */
89
	const STATUS_ACTIVE = 1;
90
	/**
91
	 * Status of inactive user
92
	 */
93
	const STATUS_INACTIVE = 0;
94
	/**
95
	 * Status of not activated user
96
	 */
97
	const STATUS_NOT_ACTIVATED = -1;
98
	/**
99
	 * @var Cache\Prefix
100
	 */
101
	protected $cache;
102
	/**
103
	 * Whether to use memory cache (locally, inside object, may require a lot of memory if working with many users together)
104
	 * @var bool
105
	 */
106
	protected $memory_cache = true;
107
	/**
108
	 * Returns database index
109
	 *
110
	 * @return int
111
	 */
112 28
	protected function cdb () {
113 28
		return Config::instance()->module('System')->db('users');
114
	}
115 30
	protected function construct () {
116 30
		$this->cache = Cache::prefix('users');
117 30
		Event::instance()->fire('System/User/construct/before');
118 30
		$this->initialize_data();
119
		/**
120
		 * Initialize session
121
		 */
122 30
		Session::instance();
123 30
		Event::instance()->fire('System/User/construct/after');
124 30
	}
125
	/**
126
	 * Check number of sign in attempts (is used by system)
127
	 *
128
	 * @param string $login_hash Hash (sha224) from login (hash from lowercase string)
129
	 *
130
	 * @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...
131
	 */
132
	function get_sign_in_attempts_count ($login_hash) {
133
		if (!preg_match('/^[0-9a-z]{56}$/', $login_hash)) {
134
			return false;
135
		}
136
		$time = time();
137
		return $this->db()->qfs(
138
			"SELECT COUNT(`expire`)
139
			FROM `[prefix]sign_ins`
140
			WHERE
141
				`expire` > $time AND
142
				(
143
					`login_hash`	= '%s' OR
144
					`ip`			= '%s'
145
				)",
146
			$login_hash,
147
			ip2hex(Request::instance()->ip)
148
		);
149
	}
150
	/**
151
	 * Process sign in result (is used by system)
152
	 *
153
	 * @param bool   $success
154
	 * @param string $login_hash Hash (sha224) from login (hash from lowercase string)
155
	 */
156
	function sign_in_result ($success, $login_hash) {
157
		if (!preg_match('/^[0-9a-z]{56}$/', $login_hash)) {
158
			return;
159
		}
160
		$ip   = ip2hex(Request::instance()->ip);
161
		$time = time();
162
		if ($success) {
163
			$this->db_prime()->q(
164
				"DELETE FROM `[prefix]sign_ins`
165
				WHERE
166
					`expire` > $time AND
167
					(
168
						`login_hash` = '%s' OR `ip` = '%s'
169
					)",
170
				$login_hash,
171
				$ip
172
			);
173
		} else {
174
			$Config = Config::instance();
175
			$this->db_prime()->q(
176
				"INSERT INTO `[prefix]sign_ins`
177
					(
178
						`expire`,
179
						`login_hash`,
180
						`ip`
181
					) VALUES (
182
						'%s',
183
						'%s',
184
						'%s'
185
					)",
186
				$time + $Config->core['sign_in_attempts_block_time'],
187
				$login_hash,
188
				$ip
189
			);
190
			if ($this->db_prime()->id() % $Config->core['inserts_limit'] == 0) {
191
				$this->db_prime()->q("DELETE FROM `[prefix]sign_ins` WHERE `expire` < $time");
192
			}
193
		}
194
	}
195
	/**
196
	 * Get data item of current user
197
	 *
198
	 * @param string|string[] $item
199
	 *
200
	 * @return false|int|mixed[]|string|User\Properties If <i>$item</i> is integer - cs\User\Properties object will be returned
201
	 */
202 20
	function __get ($item) {
203 20
		if ($item == 'id') {
204 20
			return Session::instance()->get_user();
205
		}
206 4
		return $this->get($item);
207
	}
208
	/**
209
	 * Set data item of current user
210
	 *
211
	 * @param array|int|string $item Item-value array may be specified for setting several items at once
212
	 * @param mixed|null       $value
213
	 *
214
	 * @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...
215
	 */
216
	function __set ($item, $value = null) {
217
		$this->set($item, $value);
218
	}
219
	/**
220
	 * Is admin
221
	 *
222
	 * Proxy to \cs\Session::instance()->admin() for convenience
223
	 *
224
	 * @return bool
225
	 */
226 8
	function admin () {
227 8
		return Session::instance()->admin();
228
	}
229
	/**
230
	 * Is user
231
	 *
232
	 * Proxy to \cs\Session::instance()->user() for convenience
233
	 *
234
	 * @return bool
235
	 */
236
	function user () {
237
		return Session::instance()->user();
238
	}
239
	/**
240
	 * Is guest
241
	 *
242
	 * Proxy to \cs\Session::instance()->guest() for convenience
243
	 *
244
	 * @return bool
245
	 */
246
	function guest () {
247
		return Session::instance()->guest();
248
	}
249
	/**
250
	 * Disable memory cache
251
	 *
252
	 * Memory cache stores users data inside User class in order to get data faster next time.
253
	 * 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.
254
	 */
255
	function disable_memory_cache () {
256
		$this->memory_cache = false;
257
		$this->data         = [];
258
		$this->permissions  = [];
259
	}
260
}
261