UltimateMenu::deleteButton()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 3
c 1
b 0
f 0
dl 0
loc 9
ccs 0
cts 3
cp 0
rs 10
cc 1
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * @package   Ultimate Menu mod
7
 * @version   2.0.2
8
 * @author    John Rayes <[email protected]>
9
 * @copyright Copyright (c) 2014, John Rayes
10
 * @license   http://opensource.org/licenses/MIT MIT
11
 */
12
class UltimateMenu
13
{
14
	/**
15
	 * Gets all membergroups and filters them according to the parameters.
16
	 *
17
	 * @param int[] $checked    list of all id_groups to be checked (have a mark in the checkbox).
18
	 *                          Default is an empty array.
19
	 * @param bool  $inherited  whether or not to filter out the inherited groups. Default is false.
20
	 *
21
	 * @return array all the membergroups filtered according to the parameters; empty array if something went wrong.
22
	 */
23
	public function listGroups(array $checked = [], $inherited = false)
24
	{
25
		global $modSettings, $smcFunc, $sourcedir, $txt;
26
27
		loadLanguage('ManageBoards');
28
		$groups = [
29
			-1 => [
30
				'name' => $txt['parent_guests_only'],
31
				'checked' => in_array(-1, $checked) || in_array(-3, $checked),
32
				'is_post_group' => false,
33
			],
34
			0 => [
35
				'name' => $txt['parent_members_only'],
36
				'checked' => in_array(0, $checked) || in_array(-3, $checked),
37
				'is_post_group' => false,
38
			],
39
		];
40
		$where = ['id_group NOT IN (1, 3)'];
41
42
		if (!$inherited)
43
		{
44
			$where[] = 'id_parent = {int:not_inherited}';
45
46
			if (empty($modSettings['permission_enable_postgroups']))
47
				$where[] = 'min_posts = {int:min_posts}';
48
		}
49
		$request = $smcFunc['db_query']('', '
50
			SELECT
51
				id_group, group_name, min_posts
52
			FROM {db_prefix}membergroups
53
			WHERE ' . implode("\n\t\t\t\tAND ", $where),
54
			[
55
				'not_inherited' => -2,
56
				'min_posts' => -1,
57
			]
58
		);
59
60
		while ([$id, $name, $min_posts] = $smcFunc['db_fetch_row']($request))
61
			$groups[$id] = [
62
				'name' => trim($name),
63
				'checked' => in_array($id, $checked) || in_array(-3, $checked),
64
				'is_post_group' => $min_posts != -1,
65
			];
66
		$smcFunc['db_free_result']($request);
67
68
		return $groups;
69
	}
70
71
	/**
72
	 * Loads all buttons from the db
73
	 *
74
	 * @return string[]
75
	 */
76
	public function total_getMenu()
77
	{
78
		global $smcFunc;
79
80
		$request = $smcFunc['db_query']('', '
81
			SELECT
82
				id_button, name, target, type, position, link, status, permissions, parent
83
			FROM {db_prefix}um_menu'
84
		);
85
		$buttons = [];
86
87
		while ($row = $smcFunc['db_fetch_assoc']($request))
88
			$buttons[] = $row;
89
90
		return $buttons;
91
	}
92
93
	/**
94
	 * Createlist callback, used to display um entries
95
	 *
96
	 * @param int    $start
97
	 * @param int    $items_per_page
98
	 * @param string $sort
99
	 *
100
	 * @return string[]
101
	 */
102
	public function list_getMenu($start, $items_per_page, $sort)
103
	{
104
		global $smcFunc;
105
106
		$buttons = [];
107
		$request = $smcFunc['db_query']('', '
108
			SELECT
109
				id_button, name, target, type, position, link, status, parent
110
			FROM {db_prefix}um_menu
111
			ORDER BY {raw:sort}
112
			LIMIT {int:offset}, {int:limit}',
113
			[
114
				'sort' => $sort,
115
				'offset' => $start,
116
				'limit' => $items_per_page,
117
			]
118
		);
119
120
		while ($row = $smcFunc['db_fetch_assoc']($request))
121
			$buttons[] = $row;
122
123
		return $buttons;
124
	}
125
126
	/**
127
	 * Createlist callback to determine the number of buttons
128
	 *
129
	 * @return int
130
	 */
131
	public function list_getNumButtons()
132
	{
133
		global $smcFunc;
134
135
		$request = $smcFunc['db_query']('', '
136
			SELECT COUNT(*)
137
			FROM {db_prefix}um_menu'
138
		);
139
		[$numButtons] = $smcFunc['db_fetch_row']($request);
140
		$smcFunc['db_free_result']($request);
141
142
		return $numButtons;
143
	}
144
145
	/**
146
	 * Sets the serialized array of buttons into settings
147
	 *
148
	 * Called whenever the menu structure is updated in the ACP
149
	 */
150
	public function rebuildMenu(): void
151
	{
152
		global $smcFunc;
153
154
		$buttons = [];
155
		$request = $smcFunc['db_query']('', '
156
			SELECT
157
				id_button, name, target, type, position, link, status, permissions, parent
158
			FROM {db_prefix}um_menu'
159
		);
160
161
		while ($row = $smcFunc['db_fetch_assoc']($request))
162
			$buttons['um_button_' . $row['id_button']] = json_encode([
163
				'name' => $row['name'],
164
				'target' => $row['target'],
165
				'type' => $row['type'],
166
				'position' => $row['position'],
167
				'groups' => array_map('intval', explode(',', $row['permissions'])),
168
				'link' => $row['link'],
169
				'active' => $row['status'] == 'active',
170
				'parent' => $row['parent'],
171
			]);
172
		$smcFunc['db_free_result']($request);
173
174
		$request = $smcFunc['db_query']('', '
175
			SELECT MAX(id_button)
176
			FROM {db_prefix}um_menu'
177
		);
178
		[$max] = $smcFunc['db_fetch_row']($request);
179
		$smcFunc['db_free_result']($request);
180
181
		$smcFunc['db_query']('', '
182
			DELETE FROM {db_prefix}settings
183
			WHERE variable LIKE {string:settings_search}
184
				AND variable NOT IN ({array_string:settings})',
185
			[
186
				'settings_search' => 'um_button%',
187
				'settings' => array_keys($buttons),
188
			]
189
		);
190
		updateSettings(['um_count' => $max] + $buttons);
191
	}
192
193
	/**
194
	 * Removes menu item(s) from the um system
195
	 *
196
	 * @param int[] $ids
197
	 */
198
	public function deleteButton(array $ids): void
199
	{
200
		global $smcFunc;
201
202
		$smcFunc['db_query']('', '
203
			DELETE FROM {db_prefix}um_menu
204
			WHERE id_button IN ({array_int:button_list})',
205
			[
206
				'button_list' => $ids,
207
			]
208
		);
209
	}
210
211
	/**
212
	 * Changes the status of a button from active to inactive
213
	 *
214
	 */
215
	public function updateButton(array $updates): void
216
	{
217
		global $smcFunc;
218
219
		foreach ($this->total_getMenu() as $item)
220
		{
221
			$status = !empty($updates['status'][$item['id_button']]) ? 'active' : 'inactive';
222
223
			if ($status != $item['status'])
224
				$smcFunc['db_query'](
225
					'',
226
					'
227
					UPDATE {db_prefix}um_menu
228
					SET status = {string:status}
229
					WHERE id_button = {int:item}',
230
					[
231
						'status' => $status,
232
						'item' => $item['id_button'],
233
					]
234
				);
235
		}
236
	}
237
238
	/**
239
	 * Checks if there is an existing um id with the same name before saving
240
	 *
241
	 * @param int    $id
242
	 * @param string $name
243
	 *
244
	 * @return int
245
	 */
246
	public function checkButton($id, $name): int
247
	{
248
		global $smcFunc;
249
250
		$request = $smcFunc['db_query']('', '
251
			SELECT id_button
252
			FROM {db_prefix}um_menu
253
			WHERE name = {string:name}
254
				AND id_button != {int:id}',
255
			[
256
				'name' => $name,
257
				'id' => $id ?: 0,
258
			]
259
		);
260
		$check = $smcFunc['db_num_rows']($request);
261
		$smcFunc['db_free_result']($request);
262
263
		return $check;
264
	}
265
266
	/**
267
	 * Saves a new or updates an existing button
268
	 */
269
	public function saveButton(array $menu_entry): void
270
	{
271
		global $smcFunc;
272
273
		if (!empty($menu_entry['in']))
274
		{
275
			$smcFunc['db_query'](
276
				'',
277
				'
278
				UPDATE {db_prefix}um_menu
279
				SET
280
					name = {string:name},
281
					type = {string:type},
282
					target = {string:target},
283
					position = {string:position},
284
					link = {string:link},
285
					status = {string:status},
286
					permissions = {string:permissions},
287
					parent = {string:parent}
288
				WHERE id_button = {int:id}',
289
				[
290
					'id' => $menu_entry['in'],
291
					'name' => $menu_entry['name'],
292
					'type' => $menu_entry['type'],
293
					'target' => $menu_entry['target'],
294
					'position' => $menu_entry['position'],
295
					'link' => $menu_entry['link'],
296
					'status' => $menu_entry['status'],
297
					'permissions' => implode(',', array_filter($menu_entry['permissions'], 'strlen')),
298
					'parent' => $menu_entry['parent'],
299
				]
300
			);
301
		}
302
		else
303
		{
304
			$smcFunc['db_insert'](
305
				'insert',
306
				'{db_prefix}um_menu',
307
				[
308
					'name' => 'string',
309
					'type' => 'string',
310
					'target' => 'string',
311
					'position' => 'string',
312
					'link' => 'string',
313
					'status' => 'string',
314
					'permissions' => 'string',
315
					'parent' => 'string',
316
				],
317
				[
318
					$menu_entry['name'],
319
					$menu_entry['type'],
320
					$menu_entry['target'],
321
					$menu_entry['position'],
322
					$menu_entry['link'],
323
					$menu_entry['status'],
324
					implode(',', array_filter($menu_entry['permissions'], 'strlen')),
325
					$menu_entry['parent'],
326
				],
327
				['id_button']
328
			);
329
		}
330
	}
331
332
	/**
333
	 * Fetch a specific button
334
	 *
335
	 * @param int $id
336
	 *
337
	 * @return array
338
	 */
339
	public function fetchButton($id): array
340
	{
341
		global $smcFunc;
342
343
		$request = $smcFunc['db_query']('', '
344
			SELECT
345
				id_button, name, target, type, position, link, status, permissions, parent
346
			FROM {db_prefix}um_menu
347
			WHERE id_button = {int:button}',
348
			[
349
				'button' => $id,
350
			]
351
		);
352
		$row = $smcFunc['db_fetch_assoc']($request);
353
		$smcFunc['db_free_result']($request);
354
355
		return [
356
			'id' => $row['id_button'],
357
			'name' => $row['name'],
358
			'target' => $row['target'],
359
			'type' => $row['type'],
360
			'position' => $row['position'],
361
			'permissions' => explode(',', $row['permissions']),
362
			'link' => $row['link'],
363
			'status' => $row['status'],
364
			'parent' => $row['parent'],
365
		];
366
	}
367
368
	/**
369
	 * Removes all buttons
370
	 */
371
	public function deleteallButtons(): void
372
	{
373
		global $smcFunc;
374
375
		$smcFunc['db_query']('', '
376
			TRUNCATE {db_prefix}um_menu'
377
		);
378
	}
379
380
	/**
381
	 * Fetches the names of all SMF menu buttons.
382
	 *
383
	 * @return array
384
	 */
385 1
	public function getButtonNames(): array
386
	{
387
		global $context;
388
389
		// Start an instant replay.
390 1
		add_integration_function('integrate_menu_buttons', 'um_replay_menu', false);
391
392
		// It's expected to be present.
393 1
		$context['user']['unread_messages'] = 0;
394
395
		// Load SMF's default menu context.
396 1
		setupMenuContext();
397
398
		// We are in the endgame now.
399 1
		remove_integration_function('integrate_menu_buttons', 'um_replay_menu', false);
400
401 1
		return $this->flatten($context['replayed_menu_buttons']);
402
	}
403
404 1
	private function flatten(array $array, int $i = 0): array
405
	{
406 1
		$result = array();
407 1
		foreach ($array as $key => $value)
408
		{
409 1
			$result[$key] = [$i, $value['title']];
410 1
			if (!empty($value['sub_buttons']))
411 1
				$result += $this->flatten($value['sub_buttons'], $i + 1);
412
		}
413 1
		return $result;
414
	}
415
}