Completed
Push — master ( c7c099...bc3d45 )
by Nazar
04:15
created

User::bot()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %
Metric Value
dl 0
loc 3
rs 10
cc 1
eloc 2
nc 1
nop 0
1
<?php
2
/**
3
 * @package   CleverStyle CMS
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\Cache\Prefix,
11
	cs\DB\Accessor,
12
	cs\User\Data as User_data,
13
	cs\User\Group as User_group,
14
	cs\User\Management as User_management,
15
	cs\User\Permission as User_permission;
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
	/**
76
	 * Id of system guest user
77
	 */
78
	const GUEST_ID = 1;
79
	/**
80
	 * Id of first, primary system administrator
81
	 */
82
	const ROOT_ID = 2;
83
	/**
84
	 * Id of system group for administrators
85
	 */
86
	const ADMIN_GROUP_ID = 1;
87
	/**
88
	 * Id of system group for users
89
	 */
90
	const USER_GROUP_ID = 2;
91
	/**
92
	 * Status of active user
93
	 */
94
	const STATUS_ACTIVE = 1;
95
	/**
96
	 * Status of inactive user
97
	 */
98
	const STATUS_INACTIVE = 0;
99
	/**
100
	 * Status of not activated user
101
	 */
102
	const STATUS_NOT_ACTIVATED = -1;
103
	/**
104
	 * @var Prefix
105
	 */
106
	protected $cache;
107
	/**
108
	 * Returns database index
109
	 *
110
	 * @return int
111
	 */
112
	protected function cdb () {
113
		return Config::instance()->module('System')->db('users');
114
	}
115
	protected function construct () {
116
		$this->cache = new Prefix('users');
117
		Event::instance()->fire('System/User/construct/before');
118
		$this->initialize_data();
119
		/**
120
		 * Initialize session
121
		 */
122
		Session::instance();
123
		Event::instance()->fire('System/User/construct/after');
124
	}
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
			[
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
	/**
153
	 * Process sign in result (is used by system)
154
	 *
155
	 * @param bool   $success
156
	 * @param string $login_hash Hash (sha224) from login (hash from lowercase string)
157
	 */
158
	function sign_in_result ($success, $login_hash) {
159
		if (!preg_match('/^[0-9a-z]{56}$/', $login_hash)) {
160
			return;
161
		}
162
		$ip   = ip2hex(Request::instance()->ip);
163
		$time = time();
164
		if ($success) {
165
			$this->db_prime()->q(
166
				"DELETE FROM `[prefix]sign_ins`
167
				WHERE
168
					`expire` > $time AND
169
					(
170
						`login_hash` = '%s' OR `ip` = '%s'
171
					)",
172
				$login_hash,
173
				$ip
174
			);
175
		} else {
176
			$Config = Config::instance();
177
			$this->db_prime()->q(
178
				"INSERT INTO `[prefix]sign_ins`
179
					(
180
						`expire`,
181
						`login_hash`,
182
						`ip`
183
					) VALUES (
184
						'%s',
185
						'%s',
186
						'%s'
187
					)",
188
				$time + $Config->core['sign_in_attempts_block_time'],
189
				$login_hash,
190
				$ip
191
			);
192
			if ($this->db_prime()->id() % $Config->core['inserts_limit'] == 0) {
193
				$this->db_prime()->aq("DELETE FROM `[prefix]sign_ins` WHERE `expire` < $time");
194
			}
195
		}
196
	}
197
	/**
198
	 * Get data item of current user
199
	 *
200
	 * @param string|string[] $item
201
	 *
202
	 * @return false|int|mixed[]|string|User\Properties If <i>$item</i> is integer - cs\User\Properties object will be returned
203
	 */
204
	function __get ($item) {
205
		if ($item == 'id') {
206
			return Session::instance()->get_user();
207
		}
208
		return $this->get($item);
209
	}
210
	/**
211
	 * Set data item of current user
212
	 *
213
	 * @param array|int|string $item Item-value array may be specified for setting several items at once
214
	 * @param mixed|null       $value
215
	 *
216
	 * @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...
217
	 */
218
	function __set ($item, $value = null) {
219
		$this->set($item, $value);
220
	}
221
	/**
222
	 * Is admin
223
	 *
224
	 * Proxy to \cs\Session::instance()->admin() for convenience
225
	 *
226
	 * @return bool
227
	 */
228
	function admin () {
229
		return Session::instance()->admin();
230
	}
231
	/**
232
	 * Is user
233
	 *
234
	 * Proxy to \cs\Session::instance()->user() for convenience
235
	 *
236
	 * @return bool
237
	 */
238
	function user () {
239
		return Session::instance()->user();
240
	}
241
	/**
242
	 * Is guest
243
	 *
244
	 * Proxy to \cs\Session::instance()->guest() for convenience
245
	 *
246
	 * @return bool
247
	 */
248
	function guest () {
249
		return Session::instance()->guest();
250
	}
251
}
252