Completed
Pull Request — master (#161)
by Matt
01:30
created

admin_controller::query_groups()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
/**
3
*
4
* Auto Groups extension for the phpBB Forum Software package.
5
*
6
* @copyright (c) 2014 phpBB Limited <https://www.phpbb.com>
7
* @license GNU General Public License, version 2 (GPL-2.0)
8
*
9
*/
10
11
namespace phpbb\autogroups\controller;
12
13
/**
14
 * Admin controller
15
 */
16
class admin_controller implements admin_interface
17
{
18
	/** @var \phpbb\cache\driver\driver_interface */
19
	protected $cache;
20
21
	/** @var \phpbb\db\driver\driver_interface */
22
	protected $db;
23
24
	/** @var \phpbb\group\helper */
25
	protected $group_helper;
26
27
	/** @var \phpbb\language\language */
28
	protected $language;
29
30
	/** @var \phpbb\log\log */
31
	protected $log;
32
33
	/** @var \phpbb\autogroups\conditions\manager */
34
	protected $manager;
35
36
	/** @var \phpbb\request\request */
37
	protected $request;
38
39
	/** @var \phpbb\template\template */
40
	protected $template;
41
42
	/** @var \phpbb\user */
43
	protected $user;
44
45
	/** @var string The database table the auto group rules are stored in */
46
	protected $autogroups_rules_table;
47
48
	/** @var string The database table the auto group types are stored in */
49
	protected $autogroups_types_table;
50
51
	/** @var string Custom form action */
52
	protected $u_action;
53
54
	/**
55
	 * Constructor
56
	 *
57
	 * @param \phpbb\cache\driver\driver_interface $cache                    Cache driver interface
58
	 * @param \phpbb\db\driver\driver_interface    $db                       Database object
59
	 * @param \phpbb\group\helper                  $group_helper             Group helper object
60
	 * @param \phpbb\language\language             $language                 Language object
61
	 * @param \phpbb\log\log                       $log                      The phpBB log system
62
	 * @param \phpbb\autogroups\conditions\manager $manager                  Auto groups condition manager object
63
	 * @param \phpbb\request\request               $request                  Request object
64
	 * @param \phpbb\template\template             $template                 Template object
65
	 * @param \phpbb\user                          $user                     User object
66
	 * @param string                               $autogroups_rules_table   Name of the table used to store auto group rules data
67
	 * @param string                               $autogroups_types_table   Name of the table used to store auto group types data
68
	 * @access public
69
	 */
70
	public function __construct(\phpbb\cache\driver\driver_interface $cache, \phpbb\db\driver\driver_interface $db, \phpbb\group\helper $group_helper, \phpbb\language\language $language, \phpbb\log\log $log, \phpbb\autogroups\conditions\manager $manager, \phpbb\request\request $request, \phpbb\template\template $template, \phpbb\user $user, $autogroups_rules_table, $autogroups_types_table)
71
	{
72
		$this->cache = $cache;
73
		$this->db = $db;
74
		$this->group_helper = $group_helper;
75
		$this->language = $language;
76
		$this->log = $log;
77
		$this->manager = $manager;
78
		$this->request = $request;
79
		$this->template = $template;
80
		$this->user = $user;
81
		$this->autogroups_rules_table = $autogroups_rules_table;
82
		$this->autogroups_types_table = $autogroups_types_table;
83
	}
84
85
	/**
86
	 * {@inheritdoc}
87
	 */
88
	public function display_autogroups()
89
	{
90
		// Get all auto groups data from the database
91
		$autogroup_rows = $this->get_all_autogroups();
92
93
		// Process all auto groups data for display in the template
94
		foreach ($autogroup_rows as $row)
95
		{
96
			$this->template->assign_block_vars('autogroups', array(
97
				'GROUP_NAME'		=> $row['group_name'],
98
				'CONDITION_NAME'	=> $this->manager->get_condition_lang($row['autogroups_type_name']),
99
				'MIN_VALUE'			=> $row['autogroups_min_value'],
100
				'MAX_VALUE'			=> $row['autogroups_max_value'],
101
102
				'S_DEFAULT'	=> $row['autogroups_default'],
103
				'S_NOTIFY'	=> $row['autogroups_notify'],
104
105
				'EXCLUDED_GROUPS'	=> implode(', ', array_map([$this, 'display_group_name'], $this->get_excluded_groups($row['autogroups_excluded_groups']))),
106
107
				'U_EDIT'	=> "{$this->u_action}&amp;action=edit&amp;autogroups_id=" . $row['autogroups_id'],
108
				'U_DELETE'	=> "{$this->u_action}&amp;action=delete&amp;autogroups_id=" . $row['autogroups_id'],
109
				'U_SYNC'	=> "{$this->u_action}&amp;action=sync&amp;autogroups_id=" . $row['autogroups_id'] . '&amp;hash=' . generate_link_hash('sync' . $row['autogroups_id']),
110
			));
111
		}
112
113
		$this->template->assign_vars(array(
114
			'U_ACTION'				=> $this->u_action,
115
			'U_ADD_AUTOGROUP_RULE'	=> "{$this->u_action}&amp;action=add",
116
		));
117
118
		// Display the group exemption select box
119
		$exempt_groups = $this->get_exempt_groups();
120
		$this->build_groups_menu(array_keys($exempt_groups));
121
	}
122
123
	/**
124
	 * {@inheritdoc}
125
	 */
126
	public function save_autogroup_rule($autogroups_id = 0)
127
	{
128
		// Process auto group form data if form was submitted
129
		if ($this->request->is_set_post('submit'))
130
		{
131
			$this->submit_autogroup_rule($autogroups_id);
132
		}
133
134
		// Get data for the auto group so we can display it
135
		$autogroups_data = $this->get_autogroup($autogroups_id);
136
137
		// If we have no auto group data yet, zero out all default values
138
		if (empty($autogroups_data))
139
		{
140
			$autogroups_data = array_fill_keys([
141
				'autogroups_group_id',
142
				'autogroups_type_id',
143
				'autogroups_min_value',
144
				'autogroups_max_value',
145
				'autogroups_default',
146
				'autogroups_notify',
147
			], 0);
148
		}
149
150
		// Format autogroups_excluded_groups specifically to be an array type
151
		$autogroups_data['autogroups_excluded_groups'] = !empty($autogroups_data['autogroups_excluded_groups']) ? json_decode($autogroups_data['autogroups_excluded_groups'], true) : array();
152
153
		// Process the auto group data for display in the template
154
		$this->build_groups_menu($autogroups_data['autogroups_excluded_groups'], false, 'excluded_groups');
155
		$this->build_groups_menu(array($autogroups_data['autogroups_group_id']), true);
156
		$this->build_conditions_menu($autogroups_data['autogroups_type_id']);
157
		$this->template->assign_vars(array(
158
			'S_ADD'			=> (bool) !$autogroups_id,
159
			'S_EDIT'		=> (bool) $autogroups_id,
160
161
			'MIN_VALUE'		=> (int) $autogroups_data['autogroups_min_value'],
162
			'MAX_VALUE'		=> (int) $autogroups_data['autogroups_max_value'],
163
164
			'S_DEFAULT'		=> (bool) $autogroups_data['autogroups_default'],
165
			'S_NOTIFY'		=> (bool) $autogroups_data['autogroups_notify'],
166
167
			'EXEMPT_GROUPS'	=> implode(', ', array_map([$this, 'display_group_name'], $this->get_exempt_groups())),
168
169
			'U_FORM_ACTION'	=> $this->u_action . '&amp;action=' . ($autogroups_id ? 'edit' : 'add') . '&amp;autogroups_id=' . $autogroups_id,
170
			'U_ACTION'		=> $this->u_action,
171
			'U_BACK'		=> $this->u_action,
172
		));
173
	}
174
175
	/**
176
	 * {@inheritdoc}
177
	 */
178
	public function delete_autogroup_rule($autogroups_id)
179
	{
180
		// Delete and auto group rule
181
		$sql = 'DELETE FROM ' . $this->autogroups_rules_table . '
182
			WHERE autogroups_id = ' . (int) $autogroups_id;
183
		$this->db->sql_query($sql);
184
185
		// Log the action
186
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'ACP_AUTOGROUPS_DELETE_LOG', time());
187
188
		// If AJAX was used, show user a result message
189
		if ($this->request->is_ajax())
190
		{
191
			$json_response = new \phpbb\json_response;
192
			$json_response->send(array(
193
				'MESSAGE_TITLE'	=> $this->language->lang('INFORMATION'),
194
				'MESSAGE_TEXT'	=> $this->language->lang('ACP_AUTOGROUPS_DELETE_SUCCESS'),
195
				'REFRESH_DATA'	=> array(
196
					'time'	=> 3
197
				)
198
			));
199
		}
200
	}
201
202
	/**
203
	 * {@inheritdoc}
204
	 */
205
	public function resync_autogroup_rule($autogroups_id)
206
	{
207
		// If the link hash is invalid, stop and show an error message to the user
208
		if (!check_link_hash($this->request->variable('hash', ''), 'sync' . $autogroups_id))
209
		{
210
			trigger_error($this->language->lang('FORM_INVALID') . adm_back_link($this->u_action), E_USER_WARNING);
211
		}
212
213
		try
214
		{
215
			$this->manager->sync_autogroups($autogroups_id);
216
		}
217
		catch (\Exception $e)
218
		{
219
			trigger_error($e->getMessage() . adm_back_link($this->u_action), E_USER_WARNING);
220
		}
221
	}
222
223
	/**
224
	 * {@inheritdoc}
225
	 */
226
	public function submit_autogroups_options()
227
	{
228
		// Get data from the form
229
		$autogroups_default_exempt = $this->request->variable('group_ids', array(0));
230
231
		// Use a confirmation box routine before setting the data
232
		if (confirm_box(true))
233
		{
234
			// Set selected groups to 1
235
			$sql = 'UPDATE ' . GROUPS_TABLE . '
236
				SET autogroup_default_exempt = 1
237
				WHERE ' . $this->db->sql_in_set('group_id', $autogroups_default_exempt, false, true);
238
			$this->db->sql_query($sql);
239
240
			// Set all other groups to 0
241
			$sql = 'UPDATE ' . GROUPS_TABLE . '
242
				SET autogroup_default_exempt = 0
243
				WHERE ' . $this->db->sql_in_set('group_id', $autogroups_default_exempt, true, true);
244
			$this->db->sql_query($sql);
245
246
			// Clear the cached group table data
247
			$this->cache->destroy('sql', GROUPS_TABLE);
248
		}
249
		else
250
		{
251
			confirm_box(false, $this->language->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
252
				'generalsubmit' => true,
253
				'group_ids' => $autogroups_default_exempt,
254
			)));
255
		}
256
	}
257
258
	/**
259
	 * Submit auto group rule form data
260
	 *
261
	 * @param int $autogroups_id An auto group identifier
262
	 *                           A value of 0 is new, otherwise we're updating
263
	 * @return void
264
	 * @access protected
265
	 */
266
	protected function submit_autogroup_rule($autogroups_id = 0)
267
	{
268
		$data = array(
269
			'autogroups_type_id'	=> $this->request->variable('autogroups_type_id', 0),
270
			'autogroups_min_value'	=> $this->request->variable('autogroups_min_value', 0),
271
			'autogroups_max_value'	=> $this->request->variable('autogroups_max_value', 0),
272
			'autogroups_group_id'	=> $this->request->variable('autogroups_group_id', 0),
273
			'autogroups_default'	=> $this->request->variable('autogroups_default', false),
274
			'autogroups_notify'		=> $this->request->variable('autogroups_notify', false),
275
			'autogroups_excluded_groups' => $this->request->variable('autogroups_excluded_groups', array(0)),
276
		);
277
278
		// Prevent form submit when no user groups are available or selected
279 View Code Duplication
		if (!$data['autogroups_group_id'])
280
		{
281
			trigger_error($this->language->lang('ACP_AUTOGROUPS_INVALID_GROUPS') . adm_back_link($this->u_action), E_USER_WARNING);
282
		}
283
284
		// Prevent form submit when min and max values are identical
285 View Code Duplication
		if ($data['autogroups_min_value'] == $data['autogroups_max_value'])
286
		{
287
			trigger_error($this->language->lang('ACP_AUTOGROUPS_INVALID_RANGE') . adm_back_link($this->u_action), E_USER_WARNING);
288
		}
289
290
		// Prevent form submit when the target group is also in the excluded groups array
291 View Code Duplication
		if (in_array($data['autogroups_group_id'], $data['autogroups_excluded_groups']))
292
		{
293
			trigger_error($this->language->lang('ACP_AUTOGROUPS_INVALID_EXCLUDE_GROUPS') . adm_back_link($this->u_action), E_USER_WARNING);
294
		}
295
296
		// Format autogroups_excluded_groups for storage in the db
297
		$data['autogroups_excluded_groups'] = !empty($data['autogroups_excluded_groups']) ? json_encode($data['autogroups_excluded_groups']) : '';
298
299
		if ($autogroups_id != 0) // Update existing auto group data
300
		{
301
			$sql = 'UPDATE ' . $this->autogroups_rules_table . '
302
				SET ' . $this->db->sql_build_array('UPDATE', $data) . '
303
				WHERE autogroups_id = ' . (int) $autogroups_id;
304
			$this->db->sql_query($sql);
305
		}
306
		else // Insert new auto group data
307
		{
308
			$sql = 'INSERT INTO ' . $this->autogroups_rules_table . ' ' . $this->db->sql_build_array('INSERT', $data);
309
			$this->db->sql_query($sql);
310
			$autogroups_id = (int) $this->db->sql_nextid();
311
		}
312
313
		// Apply the auto group to all users
314
		$this->manager->sync_autogroups($autogroups_id);
315
316
		// Log the action
317
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'ACP_AUTOGROUPS_SAVED_LOG', time());
318
319
		// Output message to user after submitting the form
320
		trigger_error($this->language->lang('ACP_AUTOGROUPS_SUBMIT_SUCCESS') . adm_back_link($this->u_action));
321
	}
322
323
	/**
324
	 * Get one auto group rule from the database
325
	 *
326
	 * @param int $id An auto group rule identifier
327
	 * @return array An auto group rule and it's associated data
328
	 * @access public
329
	 */
330
	protected function get_autogroup($id)
331
	{
332
		$sql = 'SELECT *
333
			FROM ' . $this->autogroups_rules_table . '
334
			WHERE autogroups_id = ' . (int) $id;
335
		$result = $this->db->sql_query($sql);
336
		$autogroups_data = $this->db->sql_fetchrow($result);
337
		$this->db->sql_freeresult($result);
338
339
		return $autogroups_data ? $autogroups_data : [];
340
	}
341
342
	/**
343
	 * Get all auto group rules from the database
344
	 *
345
	 * @return array Array of auto group rules and their associated data
346
	 * @access public
347
	 */
348
	protected function get_all_autogroups()
349
	{
350
		$sql_array = array(
351
			'SELECT'	=> 'agr.*, agt.autogroups_type_name, g.group_name',
352
			'FROM'	=> array(
353
				$this->autogroups_rules_table => 'agr',
354
				$this->autogroups_types_table => 'agt',
355
				GROUPS_TABLE => 'g',
356
			),
357
			'WHERE'	=> 'agr.autogroups_type_id = agt.autogroups_type_id
358
				AND agr.autogroups_group_id = g.group_id',
359
			'ORDER_BY'	=> 'g.group_name ASC, autogroups_min_value ASC',
360
		);
361
		$sql = $this->db->sql_build_query('SELECT', $sql_array);
362
		$result = $this->db->sql_query($sql);
363
		$rows = $this->db->sql_fetchrowset($result);
364
		$this->db->sql_freeresult($result);
365
366
		return $rows;
367
	}
368
369
	/**
370
	 * Get an array of user groups marked as exempt from default switching
371
	 *
372
	 * @return array An array of exempted groups array('group_id' => 'group_name')
373
	 * @access protected
374
	 */
375
	protected function get_exempt_groups()
376
	{
377
		$groups = array();
378
379
		// Get default exempted groups
380
		$sql = 'SELECT group_id, group_name
381
			FROM ' . GROUPS_TABLE . '
382
			WHERE autogroup_default_exempt = 1';
383
		$result = $this->db->sql_query($sql, 7200);
384
385
		while ($row = $this->db->sql_fetchrow($result))
386
		{
387
			$groups[$row['group_id']] = $row['group_name'];
388
		}
389
		$this->db->sql_freeresult($result);
390
391
		return $groups;
392
	}
393
394
	/**
395
	 * Get an array of user groups marked as excluded from auto grouping
396
	 *
397
	 * @param string $excluded_groups A json encoded string
398
	 * @return array An array of exempted groups array('group_id' => 'group_name')
399
	 * @access protected
400
	 */
401
	protected function get_excluded_groups($excluded_groups)
402
	{
403
		$groups = array();
404
405
		if (!empty($excluded_groups))
406
		{
407
			$excluded_groups = json_decode($excluded_groups, true);
408
409
			foreach ($this->query_groups() as $row)
410
			{
411
				if (in_array($row['group_id'], $excluded_groups))
412
				{
413
					$groups[$row['group_id']] = $row['group_name'];
414
				}
415
			}
416
		}
417
418
		return $groups;
419
	}
420
421
	/**
422
	 * Build template vars for a select menu of user groups
423
	 *
424
	 * @param array  $selected                  An array of identifiers for selected group(s)
425
	 * @param bool   $exclude_predefined_groups Exclude GROUP_SPECIAL
426
	 * @param string $block                     Name of the template block vars array
427
	 * @return void
428
	 * @access protected
429
	 */
430
	protected function build_groups_menu($selected, $exclude_predefined_groups = false, $block = 'groups')
431
	{
432
		foreach ($this->query_groups() as $group)
433
		{
434
			if ($exclude_predefined_groups && $group['group_type'] == GROUP_SPECIAL)
435
			{
436
				continue;
437
			}
438
			$this->template->assign_block_vars($block, array(
439
				'GROUP_ID'		=> $group['group_id'],
440
				'GROUP_NAME'	=> $this->display_group_name($group['group_name']),
441
442
				'S_SELECTED'	=> in_array($group['group_id'], $selected),
443
			));
444
		}
445
	}
446
447
	/**
448
	 * Get groups excluding BOTS, Guests
449
	 *
450
	 * @return array
451
	 */
452
	protected function query_groups()
453
	{
454
		$sql = 'SELECT group_id, group_name, group_type
455
			FROM ' . GROUPS_TABLE . '
456
			WHERE ' . $this->db->sql_in_set('group_name', array('BOTS', 'GUESTS'), true, true) . '
457
			ORDER BY group_name';
458
		$result = $this->db->sql_query($sql, 3600);
459
		$groups = $this->db->sql_fetchrowset($result);
460
		$this->db->sql_freeresult($result);
461
462
		return $groups ? $groups : array();
463
	}
464
465
	/**
466
	 * Get the display name of a user group
467
	 *
468
	 * @param string $group_name
469
	 * @return string
470
	 */
471
	protected function display_group_name($group_name)
472
	{
473
		return $this->group_helper->get_name($group_name);
474
	}
475
476
	/**
477
	 * Build template vars for a select menu of auto group conditions
478
	 *
479
	 * @param int $selected An identifier for the selected group
480
	 * @return void
481
	 * @access protected
482
	 */
483
	protected function build_conditions_menu($selected)
484
	{
485
		$conditions = $this->manager->get_autogroups_type_ids();
486
487
		foreach ($conditions as $condition_name => $condition_id)
488
		{
489
			$this->template->assign_block_vars('conditions', array(
490
				'CONDITION_ID'		=> $condition_id,
491
				'CONDITION_NAME'	=> $this->manager->get_condition_lang($condition_name),
492
493
				'S_SELECTED'		=> $condition_id == $selected,
494
			));
495
		}
496
	}
497
498
	/**
499
	 * {@inheritdoc}
500
	 */
501
	public function set_page_url($u_action)
502
	{
503
		$this->u_action = $u_action;
504
	}
505
}
506