Passed
Push — master ( 71950d...a9671b )
by John
01:51
created

UltimateMenu   A

Complexity

Total Complexity 29

Size/Duplication

Total Lines 423
Duplicated Lines 0 %

Test Coverage

Coverage 4.07%

Importance

Changes 6
Bugs 2 Features 0
Metric Value
eloc 216
c 6
b 2
f 0
dl 0
loc 423
ccs 7
cts 172
cp 0.0407
rs 10
wmc 29

13 Methods

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