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

admin_controller::save_autogroup_rule()   B

Complexity

Conditions 5
Paths 8

Size

Total Lines 48

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 48
rs 8.8234
c 0
b 0
f 0
cc 5
nc 8
nop 1
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
				'U_EDIT'	=> "{$this->u_action}&amp;action=edit&amp;autogroups_id=" . $row['autogroups_id'],
106
				'U_DELETE'	=> "{$this->u_action}&amp;action=delete&amp;autogroups_id=" . $row['autogroups_id'],
107
				'U_SYNC'	=> "{$this->u_action}&amp;action=sync&amp;autogroups_id=" . $row['autogroups_id'] . '&amp;hash=' . generate_link_hash('sync' . $row['autogroups_id']),
108
			));
109
		}
110
111
		$this->template->assign_vars(array(
112
			'U_ACTION'				=> $this->u_action,
113
			'U_ADD_AUTOGROUP_RULE'	=> "{$this->u_action}&amp;action=add",
114
		));
115
116
		// Display the group exemption select box
117
		$exempt_groups = $this->get_exempt_groups();
118
		$this->build_groups_menu(array_keys($exempt_groups));
119
	}
120
121
	/**
122
	 * {@inheritdoc}
123
	 */
124
	public function save_autogroup_rule($autogroups_id = 0)
125
	{
126
		// Process auto group form data if form was submitted
127
		if ($this->request->is_set_post('submit'))
128
		{
129
			$this->submit_autogroup_rule($autogroups_id);
130
		}
131
132
		// Get data for the auto group so we can display it
133
		$autogroups_data = $this->get_autogroup($autogroups_id);
134
135
		// If we have no auto group data yet, zero out all default values
136
		if (empty($autogroups_data))
137
		{
138
			$autogroups_data = array_fill_keys([
139
				'autogroups_group_id',
140
				'autogroups_type_id',
141
				'autogroups_min_value',
142
				'autogroups_max_value',
143
				'autogroups_default',
144
				'autogroups_notify',
145
			], 0);
146
		}
147
148
		// Format autogroups_excluded_groups specifically to be an array type
149
		$autogroups_data['autogroups_excluded_groups'] = !empty($autogroups_data['autogroups_excluded_groups']) ? json_decode($autogroups_data['autogroups_excluded_groups'], true) : array();
150
151
		// Process the auto group data for display in the template
152
		$this->build_groups_menu($autogroups_data['autogroups_excluded_groups'], false, 'excluded_groups');
153
		$this->build_groups_menu(array($autogroups_data['autogroups_group_id']), true);
154
		$this->build_conditions_menu($autogroups_data['autogroups_type_id']);
155
		$this->template->assign_vars(array(
156
			'S_ADD'			=> (bool) !$autogroups_id,
157
			'S_EDIT'		=> (bool) $autogroups_id,
158
159
			'MIN_VALUE'		=> (int) $autogroups_data['autogroups_min_value'],
160
			'MAX_VALUE'		=> (int) $autogroups_data['autogroups_max_value'],
161
162
			'S_DEFAULT'		=> (bool) $autogroups_data['autogroups_default'],
163
			'S_NOTIFY'		=> (bool) $autogroups_data['autogroups_notify'],
164
165
			'EXEMPT_GROUPS'	=> implode(', ', array_map([$this, 'display_group_name'], $this->get_exempt_groups())),
166
167
			'U_FORM_ACTION'	=> $this->u_action . '&amp;action=' . ($autogroups_id ? 'edit' : 'add') . '&amp;autogroups_id=' . $autogroups_id,
168
			'U_ACTION'		=> $this->u_action,
169
			'U_BACK'		=> $this->u_action,
170
		));
171
	}
172
173
	/**
174
	 * {@inheritdoc}
175
	 */
176
	public function delete_autogroup_rule($autogroups_id)
177
	{
178
		// Delete and auto group rule
179
		$sql = 'DELETE FROM ' . $this->autogroups_rules_table . '
180
			WHERE autogroups_id = ' . (int) $autogroups_id;
181
		$this->db->sql_query($sql);
182
183
		// Log the action
184
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'ACP_AUTOGROUPS_DELETE_LOG', time());
185
186
		// If AJAX was used, show user a result message
187
		if ($this->request->is_ajax())
188
		{
189
			$json_response = new \phpbb\json_response;
190
			$json_response->send(array(
191
				'MESSAGE_TITLE'	=> $this->language->lang('INFORMATION'),
192
				'MESSAGE_TEXT'	=> $this->language->lang('ACP_AUTOGROUPS_DELETE_SUCCESS'),
193
				'REFRESH_DATA'	=> array(
194
					'time'	=> 3
195
				)
196
			));
197
		}
198
	}
199
200
	/**
201
	 * {@inheritdoc}
202
	 */
203
	public function resync_autogroup_rule($autogroups_id)
204
	{
205
		// If the link hash is invalid, stop and show an error message to the user
206
		if (!check_link_hash($this->request->variable('hash', ''), 'sync' . $autogroups_id))
207
		{
208
			trigger_error($this->language->lang('FORM_INVALID') . adm_back_link($this->u_action), E_USER_WARNING);
209
		}
210
211
		try
212
		{
213
			$this->manager->sync_autogroups($autogroups_id);
214
		}
215
		catch (\Exception $e)
216
		{
217
			trigger_error($e->getMessage() . adm_back_link($this->u_action), E_USER_WARNING);
218
		}
219
	}
220
221
	/**
222
	 * {@inheritdoc}
223
	 */
224
	public function submit_autogroups_options()
225
	{
226
		// Get data from the form
227
		$autogroups_default_exempt = $this->request->variable('group_ids', array(0));
228
229
		// Use a confirmation box routine before setting the data
230
		if (confirm_box(true))
231
		{
232
			// Set selected groups to 1
233
			$sql = 'UPDATE ' . GROUPS_TABLE . '
234
				SET autogroup_default_exempt = 1
235
				WHERE ' . $this->db->sql_in_set('group_id', $autogroups_default_exempt, false, true);
236
			$this->db->sql_query($sql);
237
238
			// Set all other groups to 0
239
			$sql = 'UPDATE ' . GROUPS_TABLE . '
240
				SET autogroup_default_exempt = 0
241
				WHERE ' . $this->db->sql_in_set('group_id', $autogroups_default_exempt, true, true);
242
			$this->db->sql_query($sql);
243
244
			// Clear the cached group table data
245
			$this->cache->destroy('sql', GROUPS_TABLE);
246
		}
247
		else
248
		{
249
			confirm_box(false, $this->language->lang('CONFIRM_OPERATION'), build_hidden_fields(array(
250
				'generalsubmit' => true,
251
				'group_ids' => $autogroups_default_exempt,
252
			)));
253
		}
254
	}
255
256
	/**
257
	 * Submit auto group rule form data
258
	 *
259
	 * @param int $autogroups_id An auto group identifier
260
	 *                           A value of 0 is new, otherwise we're updating
261
	 * @return void
262
	 * @access protected
263
	 */
264
	protected function submit_autogroup_rule($autogroups_id = 0)
265
	{
266
		$data = array(
267
			'autogroups_type_id'	=> $this->request->variable('autogroups_type_id', 0),
268
			'autogroups_min_value'	=> $this->request->variable('autogroups_min_value', 0),
269
			'autogroups_max_value'	=> $this->request->variable('autogroups_max_value', 0),
270
			'autogroups_group_id'	=> $this->request->variable('autogroups_group_id', 0),
271
			'autogroups_default'	=> $this->request->variable('autogroups_default', false),
272
			'autogroups_notify'		=> $this->request->variable('autogroups_notify', false),
273
			'autogroups_excluded_groups' => $this->request->variable('autogroups_excluded_groups', array(0)),
274
		);
275
276
		// Prevent form submit when no user groups are available or selected
277 View Code Duplication
		if (!$data['autogroups_group_id'])
278
		{
279
			trigger_error($this->language->lang('ACP_AUTOGROUPS_INVALID_GROUPS') . adm_back_link($this->u_action), E_USER_WARNING);
280
		}
281
282
		// Prevent form submit when min and max values are identical
283 View Code Duplication
		if ($data['autogroups_min_value'] == $data['autogroups_max_value'])
284
		{
285
			trigger_error($this->language->lang('ACP_AUTOGROUPS_INVALID_RANGE') . adm_back_link($this->u_action), E_USER_WARNING);
286
		}
287
288
		// Prevent form submit when the target group is also in the excluded groups array
289 View Code Duplication
		if (in_array($data['autogroups_group_id'], $data['autogroups_excluded_groups']))
290
		{
291
			trigger_error($this->language->lang('ACP_AUTOGROUPS_INVALID_EXCLUDE_GROUPS') . adm_back_link($this->u_action), E_USER_WARNING);
292
		}
293
294
		// Format data
295
		$data['autogroups_excluded_groups'] = !empty($data['autogroups_excluded_groups']) ? json_encode($data['autogroups_excluded_groups']) : '';
296
297
		if ($autogroups_id != 0) // Update existing auto group data
298
		{
299
			$sql = 'UPDATE ' . $this->autogroups_rules_table . '
300
				SET ' . $this->db->sql_build_array('UPDATE', $data) . '
301
				WHERE autogroups_id = ' . (int) $autogroups_id;
302
			$this->db->sql_query($sql);
303
		}
304
		else // Insert new auto group data
305
		{
306
			$sql = 'INSERT INTO ' . $this->autogroups_rules_table . ' ' . $this->db->sql_build_array('INSERT', $data);
307
			$this->db->sql_query($sql);
308
			$autogroups_id = (int) $this->db->sql_nextid();
309
		}
310
311
		// Apply the auto group to all users
312
		$this->manager->sync_autogroups($autogroups_id);
313
314
		// Log the action
315
		$this->log->add('admin', $this->user->data['user_id'], $this->user->ip, 'ACP_AUTOGROUPS_SAVED_LOG', time());
316
317
		// Output message to user after submitting the form
318
		trigger_error($this->language->lang('ACP_AUTOGROUPS_SUBMIT_SUCCESS') . adm_back_link($this->u_action));
319
	}
320
321
	/**
322
	 * Get one auto group rule from the database
323
	 *
324
	 * @param int $id An auto group rule identifier
325
	 * @return array An auto group rule and it's associated data
326
	 * @access public
327
	 */
328
	protected function get_autogroup($id)
329
	{
330
		$sql = 'SELECT *
331
			FROM ' . $this->autogroups_rules_table . '
332
			WHERE autogroups_id = ' . (int) $id;
333
		$result = $this->db->sql_query($sql);
334
		$autogroups_data = $this->db->sql_fetchrow($result);
335
		$this->db->sql_freeresult($result);
336
337
		return $autogroups_data ? $autogroups_data : [];
338
	}
339
340
	/**
341
	 * Get all auto group rules from the database
342
	 *
343
	 * @return array Array of auto group rules and their associated data
344
	 * @access public
345
	 */
346
	protected function get_all_autogroups()
347
	{
348
		$sql_array = array(
349
			'SELECT'	=> 'agr.*, agt.autogroups_type_name, g.group_name',
350
			'FROM'	=> array(
351
				$this->autogroups_rules_table => 'agr',
352
				$this->autogroups_types_table => 'agt',
353
				GROUPS_TABLE => 'g',
354
			),
355
			'WHERE'	=> 'agr.autogroups_type_id = agt.autogroups_type_id
356
				AND agr.autogroups_group_id = g.group_id',
357
			'ORDER_BY'	=> 'g.group_name ASC, autogroups_min_value ASC',
358
		);
359
		$sql = $this->db->sql_build_query('SELECT', $sql_array);
360
		$result = $this->db->sql_query($sql);
361
		$rows = $this->db->sql_fetchrowset($result);
362
		$this->db->sql_freeresult($result);
363
364
		return $rows;
365
	}
366
367
	/**
368
	 * Get an array of user groups marked as exempt from default switching
369
	 *
370
	 * @return array An array of exempted groups array('group_id' => 'group_name')
371
	 * @access protected
372
	 */
373
	protected function get_exempt_groups()
374
	{
375
		$groups = array();
376
377
		// Get default exempted groups
378
		$sql = 'SELECT group_id, group_name
379
			FROM ' . GROUPS_TABLE . '
380
			WHERE autogroup_default_exempt = 1';
381
		$result = $this->db->sql_query($sql, 7200);
382
383
		while ($row = $this->db->sql_fetchrow($result))
384
		{
385
			$groups[$row['group_id']] = $row['group_name'];
386
		}
387
		$this->db->sql_freeresult($result);
388
389
		return $groups;
390
	}
391
392
	/**
393
	 * Build template vars for a select menu of user groups
394
	 *
395
	 * @param array  $selected                  An array of identifiers for selected group(s)
396
	 * @param bool   $exclude_predefined_groups Exclude GROUP_SPECIAL
397
	 * @param string $block                     Name of the template block vars array
398
	 * @return void
399
	 * @access protected
400
	 */
401
	protected function build_groups_menu($selected, $exclude_predefined_groups = false, $block = 'groups')
402
	{
403
		// Get groups excluding BOTS, Guests, and optionally predefined
404
		$sql = 'SELECT group_id, group_name, group_type
405
			FROM ' . GROUPS_TABLE . '
406
			WHERE ' . $this->db->sql_in_set('group_name', array('BOTS', 'GUESTS'), true, true) .
407
				($exclude_predefined_groups ? ' AND group_type <> ' . GROUP_SPECIAL : '') . '
408
			ORDER BY group_name';
409
		$result = $this->db->sql_query($sql);
410
411
		while ($group_row = $this->db->sql_fetchrow($result))
412
		{
413
			$this->template->assign_block_vars($block, array(
414
				'GROUP_ID'		=> $group_row['group_id'],
415
				'GROUP_NAME'	=> $this->display_group_name($group_row['group_name']),
416
417
				'S_SELECTED'	=> in_array($group_row['group_id'], $selected),
418
			));
419
		}
420
		$this->db->sql_freeresult($result);
421
	}
422
423
	/**
424
	 * Get the display name of a user group
425
	 *
426
	 * @param string $group_name
427
	 * @return string
428
	 */
429
	protected function display_group_name($group_name)
430
	{
431
		return $this->group_helper->get_name($group_name);
432
	}
433
434
	/**
435
	 * Build template vars for a select menu of auto group conditions
436
	 *
437
	 * @param int $selected An identifier for the selected group
438
	 * @return void
439
	 * @access protected
440
	 */
441
	protected function build_conditions_menu($selected)
442
	{
443
		$conditions = $this->manager->get_autogroups_type_ids();
444
445
		foreach ($conditions as $condition_name => $condition_id)
446
		{
447
			$this->template->assign_block_vars('conditions', array(
448
				'CONDITION_ID'		=> $condition_id,
449
				'CONDITION_NAME'	=> $this->manager->get_condition_lang($condition_name),
450
451
				'S_SELECTED'		=> $condition_id == $selected,
452
			));
453
		}
454
	}
455
456
	/**
457
	 * {@inheritdoc}
458
	 */
459
	public function set_page_url($u_action)
460
	{
461
		$this->u_action = $u_action;
462
	}
463
}
464