Passed
Pull Request — development (#3834)
by Spuds
08:39
created

Rules::_getCriteriaMemberNames()   A

Complexity

Conditions 6
Paths 9

Size

Total Lines 24
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 6
eloc 11
nc 9
nop 0
dl 0
loc 24
rs 9.2222
c 1
b 0
f 0
1
<?php
2
3
/**
4
 * This file deals with the rule actions related to personal messages.
5
 *
6
 * @package   ElkArte Forum
7
 * @copyright ElkArte Forum contributors
8
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
9
 *
10
 * @version 2.0 Beta 1
11
 *
12
 */
13
14
namespace ElkArte\PersonalMessage;
15
16
use ElkArte\AbstractController;
17
use ElkArte\Exceptions\Exception;
18
use ElkArte\Helper\Util;
19
20
/**
21
 * Class Rules
22
 * It allows managing personal message rules
23
 *
24
 * @package ElkArte\PersonalMessage
25
 */
26
class Rules extends AbstractController
27
{
28
	/**
29
	 * Default action for the class
30
	 */
31
	public function action_index()
32
	{
33
		$this->action_manrules();
34
	}
35
36
	/**
37
	 * List and allow adding/entering all man rules
38
	 *
39
	 * @uses sub template rules
40
	 */
41
	public function action_manrules(): void
42
	{
43
		global $txt, $context;
44
45
		require_once(SUBSDIR . '/PersonalMessage.subs.php');
46
47
		// Applying all rules?
48
		if ($this->_req->hasQuery('apply'))
49
		{
50
			$this->action_applyRules();
51
		}
52
53
		// Editing a specific rule?
54
		if ($this->_req->hasQuery('add'))
55
		{
56
			$this->action_addRule();
57
58
			return;
59
		}
60
61
		// Saving?
62
		if ($this->_req->hasQuery('save'))
63
		{
64
			$this->action_saveRule();
65
		}
66
67
		// Deleting?
68
		if ($this->_req->hasPost('delselected'))
69
		{
70
			$this->action_deleteRules();
71
		}
72
73
		// The link tree - gotta have this :o
74
		$context['breadcrumbs'][] = [
75
			'url' => getUrl('action', ['action' => 'pm', 'sa' => 'manrules']),
76
			'name' => $txt['pm_manage_rules']
77
		];
78
79
		$context['page_title'] = $txt['pm_manage_rules'];
80
		$context['sub_template'] = 'rules';
81
82
		// Load them... load them!!
83
		loadRules();
84
85
		// Likely to need all the groups!
86
		require_once(SUBSDIR . '/Membergroups.subs.php');
87
		$context['groups'] = accessibleGroups();
88
	}
89
90
	/**
91
	 * Apply all rules to the current PMs
92
	 */
93
	public function action_applyRules(): void
94
	{
95
		checkSession('get');
96
97
		applyRules(true);
98
		redirectexit('action=pm;sa=manrules');
99
	}
100
101
	/**
102
	 * Setting up the UI for adding or editing a rule
103
	 */
104
	public function action_addRule(): void
105
	{
106
		global $context;
107
108
		require_once(SUBSDIR . '/PersonalMessage.subs.php');
109
		loadRules();
110
111
		require_once(SUBSDIR . '/Membergroups.subs.php');
112
		$context['groups'] = accessibleGroups();
113
114
		$rid = $this->_req->getQuery('rid', 'intval', 0);
115
		$context['rid'] = isset($context['rules'][$rid]) ? $rid : 0;
116
		$context['sub_template'] = 'add_rule';
117
118
		$this->_setupJSVars();
119
120
		// Current rule information...
121
		if ($context['rid'])
122
		{
123
			$context['rule'] = $context['rules'][$context['rid']];
124
			$this->_getCriteriaMemberNames();
125
		}
126
		else
127
		{
128
			$context['rule'] = [
129
				'id' => '',
130
				'name' => '',
131
				'criteria' => [],
132
				'actions' => [],
133
				'logic' => 'and',
134
			];
135
		}
136
137
		// Add a dummy criteria to allow expansion for none js users.
138
		$context['rule']['criteria'][] = ['t' => '', 'v' => ''];
139
	}
140
141
	/**
142
	 * Sets up the JavaScript variables for the PM rule UI
143
	 */
144
	private function _setupJSVars(): void
145
	{
146
		global $txt, $context;
147
148
		// Any known rule
149
		$js_rules = [];
150
		foreach ($context['known_rules'] as $rule)
151
		{
152
			$js_rules[$rule] = $txt['pm_rule_' . $rule];
153
		}
154
155
		// Any known label
156
		$js_labels = [];
157
		foreach ($context['labels'] as $label)
158
		{
159
			if ($label['id'] !== -1)
160
			{
161
				$js_labels[$label['id'] + 1] = $label['name'];
162
			}
163
		}
164
165
		theme()->addJavascriptVar([
166
			'criteriaNum' => 0,
167
			'actionNum' => 0,
168
		]);
169
170
		// Oh my, we have a lot of text strings for this
171
		theme()->addJavascriptVar([
172
			'groups' => json_encode($context['groups']),
173
			'labels' => json_encode($js_labels),
174
			'rules' => json_encode($js_rules),
175
			'txt_pm_readable_and' => $txt['pm_readable_and'],
176
			'txt_pm_readable_or' => $txt['pm_readable_or'],
177
			'txt_pm_readable_member' => $txt['pm_readable_member'],
178
			'txt_pm_readable_group' => $txt['pm_readable_group'],
179
			'txt_pm_readable_subject ' => $txt['pm_readable_subject'],
180
			'txt_pm_readable_body' => $txt['pm_readable_body'],
181
			'txt_pm_readable_buddy' => $txt['pm_readable_buddy'],
182
			'txt_pm_readable_label' => $txt['pm_readable_label'],
183
			'txt_pm_readable_delete' => $txt['pm_readable_delete'],
184
			'txt_pm_readable_start' => $txt['pm_readable_start'],
185
			'txt_pm_readable_end' => $txt['pm_readable_end'],
186
			'txt_pm_readable_then' => $txt['pm_readable_then'],
187
			'txt_pm_rule_not_defined' => $txt['pm_rule_not_defined'],
188
			'txt_pm_rule_criteria_pick' => $txt['pm_rule_criteria_pick'],
189
			'txt_pm_rule_sel_group' => $txt['pm_rule_sel_group'],
190
			'txt_pm_rule_sel_action' => $txt['pm_rule_sel_action'],
191
			'txt_pm_rule_label' => $txt['pm_rule_label'],
192
			'txt_pm_rule_delete' => $txt['pm_rule_delete'],
193
			'txt_pm_rule_sel_label' => $txt['pm_rule_sel_label'],
194
		], true);
195
	}
196
197
	/**
198
	 * Gets member names for rule criteria when editing a rule
199
	 */
200
	private function _getCriteriaMemberNames(): void
201
	{
202
		global $context;
203
204
		$members = [];
205
206
		// Need to get member names!
207
		foreach ($context['rule']['criteria'] as $k => $criteria)
208
		{
209
			if ($criteria['t'] !== 'mid' || empty($criteria['v']))
210
			{
211
				continue;
212
			}
213
214
			$members[(int) $criteria['v']] = $k;
215
		}
216
217
		if (!empty($members))
218
		{
219
			require_once(SUBSDIR . '/Members.subs.php');
220
			$result = getBasicMemberData(array_keys($members));
221
			foreach ($result as $row)
222
			{
223
				$context['rule']['criteria'][$members[$row['id_member']]]['v'] = $row['member_name'];
224
			}
225
		}
226
	}
227
228
	/**
229
	 * Saving a PM rule
230
	 */
231
	public function action_saveRule(): void
232
	{
233
		global $context;
234
235
		checkSession();
236
237
		require_once(SUBSDIR . '/PersonalMessage.subs.php');
238
		loadRules();
239
240
		$rid = $this->_req->getQuery('rid', 'intval', 0);
241
		$context['rid'] = isset($context['rules'][$rid]) ? $rid : 0;
242
243
		// Name is easy!
244
		$ruleName = $this->_req->getPost('rule_name', 'trim|Util::htmlspecialchars', '');
245
		if (empty($ruleName))
246
		{
247
			throw new Exception('pm_rule_no_name', false);
248
		}
249
250
		$criteria = $this->_getCriteria();
251
		$doDelete = 0;
252
		$actions = $this->_getActions($doDelete);
253
254
		if (empty($criteria) || (empty($actions) && !$doDelete))
255
		{
256
			throw new Exception('pm_rule_no_criteria', false);
257
		}
258
259
		// What are we storing?
260
		$criteria = serialize($criteria);
261
		$actions = serialize($actions);
262
263
		// Logic?
264
		$rule_logic = $this->_req->getPost('rule_logic', 'trim|strval', '');
265
		$isOr = $rule_logic === 'or' ? 1 : 0;
266
267
		// Create the rule?
268
		if (empty($context['rid']))
269
		{
270
			addPMRule($this->user->id, $ruleName, $criteria, $actions, $doDelete, $isOr);
271
		}
272
		else
273
		{
274
			updatePMRule($this->user->id, $context['rid'], $ruleName, $criteria, $actions, $doDelete, $isOr);
275
		}
276
277
		redirectexit('action=pm;sa=manrules');
278
	}
279
280
	/**
281
	 * Processes and validates rule criteria from the request
282
	 *
283
	 * @return array
284
	 */
285
	private function _getCriteria(): array
286
	{
287
		$ruletype = $this->_req->getPost('ruletype', null, []);
288
		$ruledefgroup = $this->_req->getPost('ruledefgroup', null, []);
289
		$ruledef = $this->_req->getPost('ruledef', null, []);
290
291
		if (empty($ruletype))
292
		{
293
			return [];
294
		}
295
296
		$criteria = [];
297
		foreach ($ruletype as $ind => $type)
298
		{
299
			// Check everything is here...
300
			if ($type === 'gid' && (!isset($ruledefgroup[$ind])))
301
			{
302
				continue;
303
			}
304
305
			if ($type !== 'bud' && !isset($ruledef[$ind]))
306
			{
307
				continue;
308
			}
309
310
			// Members need to be found.
311
			if ($type === 'mid')
312
			{
313
				require_once(SUBSDIR . '/Members.subs.php');
314
				$name = trim((string) ($ruledef[$ind] ?? ''));
315
				$member = getMemberByName($name, true);
316
				if (empty($member))
317
				{
318
					continue;
319
				}
320
321
				$criteria[] = ['t' => 'mid', 'v' => $member['id_member']];
322
			}
323
			elseif ($type === 'bud')
324
			{
325
				$criteria[] = ['t' => 'bud', 'v' => 1];
326
			}
327
			elseif ($type === 'gid')
328
			{
329
				$criteria[] = ['t' => 'gid', 'v' => (int) $ruledefgroup[$ind]];
330
			}
331
			elseif (in_array($type, ['sub', 'msg']) && trim((string) ($ruledef[$ind] ?? '')) !== '')
332
			{
333
				$criteria[] = ['t' => $type, 'v' => Util::htmlspecialchars(trim((string) $ruledef[$ind]))];
334
			}
335
		}
336
337
		return $criteria;
338
	}
339
340
	/**
341
	 * Processes and validates rule actions from the request
342
	 *
343
	 * @param int $doDelete
344
	 * @return array
345
	 */
346
	private function _getActions(int &$doDelete): array
347
	{
348
		$acttype = $this->_req->getPost('acttype', null, []);
349
		$labdef = $this->_req->getPost('labdef', null, []);
350
351
		$doDelete = 0;
352
		if (empty($acttype))
353
		{
354
			return [];
355
		}
356
357
		$actions = [];
358
		foreach ($acttype as $ind => $type)
359
		{
360
			// Picking a valid label?
361
			if ($type === 'lab' && !isset($labdef[$ind]))
362
			{
363
				continue;
364
			}
365
366
			// Record what we're doing.
367
			if ($type === 'del')
368
			{
369
				$doDelete = 1;
370
			}
371
			elseif ($type === 'lab')
372
			{
373
				$actions[] = ['t' => 'lab', 'v' => (int) $labdef[$ind] - 1];
374
			}
375
		}
376
377
		return $actions;
378
	}
379
380
	/**
381
	 * Deleting selected PM rules
382
	 */
383
	public function action_deleteRules(): void
384
	{
385
		checkSession();
386
387
		$delrule = $this->_req->getPost('delrule', null, []);
388
		if (empty($delrule))
389
		{
390
			redirectexit('action=pm;sa=manrules');
391
		}
392
393
		$toDelete = array_map('intval', array_keys($delrule));
394
395
		require_once(SUBSDIR . '/PersonalMessage.subs.php');
396
		deletePMRules($this->user->id, $toDelete);
397
398
		redirectexit('action=pm;sa=manrules');
399
	}
400
}
401