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

users::admin_users___patch()   C

Complexity

Conditions 14
Paths 13

Size

Total Lines 42
Code Lines 30

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 42
rs 5.0864
cc 14
eloc 30
nc 13
nop 1

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\admin;
11
use
12
	cs\ExitException,
13
	cs\Language\Prefix,
14
	cs\Page,
15
	cs\Response,
16
	cs\User;
17
18
trait users {
19
	/**
20
	 * Get user's data or data of several specified groups if specified in ids query parameter or allows to search for users by login or email (users id will
21
	 * be returned)
22
	 *
23
	 * Data will be pre-processed with `reg_date_formatted` and `reg_ip_formatted` keys added
24
	 *
25
	 * @param \cs\Request $Request
26
	 *
27
	 * @throws ExitException
28
	 */
29
	static function admin_users___get ($Request) {
30
		$User    = User::instance();
31
		$Page    = Page::instance();
32
		$columns = static::admin_users___search_options_get()['columns'];
33
		if (isset($Request->route_ids[0])) {
34
			$result = static::admin_users___get_post_process(
35
				$User->get($columns, $Request->route_ids[0])
36
			);
37
		} elseif (isset($_GET['ids'])) {
38
			$ids    = _int(explode(',', $_GET['ids']));
39
			$result = [];
40
			foreach ($ids as $id) {
41
				$result[] = static::admin_users___get_post_process(
42
					$User->get($columns, $id)
43
				);
44
			}
45
		} elseif (isset($_GET['search'])) {
46
			$result = _int($User->search_users($_GET['search']));
47
		} else {
48
			throw new ExitException(400);
49
		}
50
		if (!$result) {
51
			throw new ExitException(404);
52
		}
53
		$Page->json($result);
54
	}
55
	protected static function admin_users___get_post_process ($data) {
56
		$L                          = new Prefix('system_admin_users_');
57
		$data['reg_date_formatted'] = $data['reg_date'] ? date($L->_date, $data['reg_date']) : $L->undefined;
58
		$data['reg_ip_formatted']   = hex2ip($data['reg_ip'], 10);
59
		return $data;
60
	}
61
	/**
62
	 * Update user's data
63
	 *
64
	 * @param \cs\Request $Request
65
	 *
66
	 * @throws ExitException
67
	 */
68
	static function admin_users___patch ($Request) {
69
		if (!isset($Request->route_ids[0], $_POST['user'])) {
70
			throw new ExitException(400);
71
		}
72
		$User      = User::instance();
73
		$user_id   = (int)$Request->route_ids[0];
74
		$user_data = array_filter(
75
			$_POST['user'],
76
			function ($item) {
77
				return in_array($item, ['login', 'username', 'email', 'language', 'timezone', 'status', 'block_until', 'avatar'], true);
78
			},
79
			ARRAY_FILTER_USE_KEY
80
		);
81
		foreach ($user_data as &$d) {
82
			$d = xap($d, false);
83
		}
84
		unset($d);
85
		if (!$user_data && !isset($_POST['user']['password'])) {
86
			throw new ExitException(400);
87
		}
88
		$L = new Prefix('system_admin_users_');
89
		if (
90
			isset($user_data['login']) &&
91
			$user_data['login'] !== $User->get('login', $user_id) &&
92
			$User->get_id(hash('sha224', $user_data['login']))
93
		) {
94
			throw new ExitException($L->login_occupied, 400);
95
		}
96
		if (
97
			isset($user_data['email']) &&
98
			$user_data['email'] !== $User->get('email', $user_id) &&
99
			$User->get_id(hash('sha224', $user_data['email']))
100
		) {
101
			throw new ExitException($L->email_occupied, 400);
102
		}
103
		if (!$User->set($user_data, null, $user_id)) {
104
			throw new ExitException(500);
105
		}
106
		if (isset($_POST['user']['password']) && !$User->set_password($_POST['user']['password'], $user_id)) {
107
			throw new ExitException(500);
108
		}
109
	}
110
	/**
111
	 * Add new user
112
	 *
113
	 * @throws ExitException
114
	 */
115
	static function admin_users___post () {
116
		if (!isset($_POST['type'])) {
117
			throw new ExitException(400);
118
		}
119
		$User = User::instance();
120
		if (isset($_POST['email'])) {
121
			$result = $User->registration($_POST['email'], false, false);
122
			if (!$result) {
123
				throw new ExitException(500);
124
			}
125
			if ($result === 'exists') {
126
				$L = new Prefix('system_admin_users_');
127
				throw new ExitException($L->user_already_exists, 400);
128
			}
129
			Response::instance()->code = 201;
130
			Page::instance()->json(
131
				[
132
					'login'    => $User->get('login', $result['id']),
133
					'password' => $result['password']
134
				]
135
			);
136
		} else {
137
			throw new ExitException(400);
138
		}
139
	}
140
	/**
141
	 * Advanced search for users (users data will be returned similar to GET method)
142
	 *
143
	 * @throws ExitException
144
	 */
145
	static function admin_users___search () {
146
		if (!isset($_POST['mode'], $_POST['column'], $_POST['text'], $_POST['page'], $_POST['limit'])) {
147
			throw new ExitException(400);
148
		}
149
		$mode           = $_POST['mode'];
150
		$column         = $_POST['column'];
151
		$text           = $_POST['text'];
152
		$page           = (int)$_POST['page'];
153
		$limit          = (int)$_POST['limit'];
154
		$search_options = static::admin_users___search_options_get();
155
		if (
156
			!in_array($mode, $search_options['modes']) ||
157
			(
158
				$column !== '' &&
159
				!in_array($column, $search_options['columns'])
160
			)
161
		) {
162
			throw new ExitException(400);
163
		}
164
		$cdb   = User::instance()->db();
165
		$where = static::admin_users___search_prepare_where($mode, $text, $column ?: $search_options['columns'], $cdb);
166
		$count = $cdb->qfs(
167
			[
168
				"SELECT COUNT(`id`)
169
				FROM `[prefix]users`
170
				WHERE $where"
171
			]
172
		);
173
		if (!$count) {
174
			throw new ExitException(404);
175
		}
176
		$where = str_replace('%', '%%', $where);
177
		$ids   = $cdb->qfas(
178
			[
179
				"SELECT `id`
180
				FROM `[prefix]users`
181
				WHERE $where
182
				ORDER BY `id`
183
				LIMIT %d, %d",
184
				($page - 1) * $limit,
185
				$limit
186
			]
187
		);
188
		Page::instance()->json(
189
			[
190
				'count' => $count,
191
				'users' => static::admin_users___search_get($ids, $search_options['columns'])
192
			]
193
		);
194
	}
195
	/**
196
	 * @param string           $mode
197
	 * @param string           $text
198
	 * @param string|string[]  $column
199
	 * @param \cs\DB\_Abstract $cdb
200
	 *
201
	 * @return string
202
	 */
203
	protected static function admin_users___search_prepare_where ($mode, $text, $column, $cdb) {
204
		$where = '1';
205
		if ($text && $mode) {
206
			switch ($mode) {
207
				case '=':
208
				case '!=':
209
				case '>':
210
				case '<':
211
				case '>=':
212
				case '<=':
213
				case 'LIKE':
214
				case 'NOT LIKE':
215
				case 'REGEXP':
216
				case 'NOT REGEXP':
217
					$where = static::admin_users___search_prepare_where_compose(
218
						"`%s` $mode %s",
219
						$column,
220
						$cdb->s($text)
221
					);
222
					break;
223
				case 'IN':
224
				case 'NOT IN':
225
					$where = static::admin_users___search_prepare_where_compose(
226
						"`%s` $mode (%s)",
227
						$column,
228
						implode(
229
							", ",
230
							$cdb->s(
231
								_trim(
232
									_trim(explode(',', $text), "'")
233
								)
234
							)
235
						)
236
					);
237
					break;
238
			}
239
		}
240
		return $where;
241
	}
242
	/**
243
	 * @param string          $where
244
	 * @param string|string[] $column
245
	 * @param string          $text
246
	 *
247
	 * @return string
248
	 */
249
	protected static function admin_users___search_prepare_where_compose ($where, $column, $text) {
250
		if (is_array($column)) {
251
			$return = [];
252
			foreach ($column as $c) {
253
				$return[] = sprintf($where, $c, $text);
254
			}
255
			return '('.implode(' OR ', $return).')';
256
		}
257
		return sprintf($where, $column, $text);
258
	}
259
	/**
260
	 * @param int[]    $users
261
	 * @param string[] $columns
262
	 *
263
	 * @return array[]
0 ignored issues
show
Documentation introduced by
Should the return type not be integer[]?

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...
264
	 */
265
	protected static function admin_users___search_get ($users, $columns) {
266
		$User = User::instance();
267
		foreach ($users as &$user) {
268
			$groups         = (array)$User->get_groups($user);
269
			$user           =
270
				$User->get($columns, $user) +
271
				[
272
					'is_user'  => in_array(User::USER_GROUP_ID, $groups),
273
					'is_admin' => in_array(User::ADMIN_GROUP_ID, $groups),
274
					'username' => $User->username($user)
275
				];
276
			$user['reg_ip'] = hex2ip($user['reg_ip'], 10);
277
		}
278
		return $users;
279
	}
280
	/**
281
	 * Get available search options
282
	 */
283
	static function admin_users___search_options () {
284
		Page::instance()->json(
285
			static::admin_users___search_options_get()
286
		);
287
	}
288
	/*
289
	 * @return string[][]
0 ignored issues
show
Documentation introduced by
Should the return type not be array<string,array>?

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...
290
	 */
291
	protected static function admin_users___search_options_get () {
292
		return [
293
			'modes'   => [
294
				'=',
295
				'!=',
296
				'>',
297
				'<',
298
				'>=',
299
				'<=',
300
				'LIKE',
301
				'NOT LIKE',
302
				'IN',
303
				'NOT IN',
304
				'IS NULL',
305
				'IS NOT NULL',
306
				'REGEXP',
307
				'NOT REGEXP'
308
			],
309
			'columns' => array_values(
310
				array_filter(
311
					User::instance()->get_users_columns(),
312
					function ($column) {
313
						return $column !== 'password_hash';
314
					}
315
				)
316
			)
317
		];
318
	}
319
}
320