1<?php
2/**
3 * Category management page.
4 *
5 * Allows administrators to create, reposition, and remove categories.
6 *
7 * @copyright (C) 2008-2012 PunBB, partially based on code (C) 2008-2009 FluxBB.org
8 * @license http://www.gnu.org/licenses/gpl.html GPL version 2 or higher
9 * @package PunBB
10 */
11
12
13if (!defined('FORUM_ROOT'))
14	define('FORUM_ROOT', '../');
15require FORUM_ROOT.'include/common.php';
16require FORUM_ROOT.'include/common_admin.php';
17
18($hook = get_hook('acg_start')) ? eval($hook) : null;
19
20if ($forum_user['g_id'] != FORUM_ADMIN)
21	message($lang_common['No permission']);
22
23// Load the admin.php language file
24require FORUM_ROOT.'lang/'.$forum_user['language'].'/admin_common.php';
25require FORUM_ROOT.'lang/'.$forum_user['language'].'/admin_categories.php';
26
27
28// Add a new category
29if (isset($_POST['add_cat']))
30{
31	$new_cat_name = forum_trim($_POST['new_cat_name']);
32	if ($new_cat_name == '')
33		message($lang_admin_categories['Must name category']);
34
35	$new_cat_pos = intval($_POST['position']);
36
37	($hook = get_hook('acg_add_cat_form_submitted')) ? eval($hook) : null;
38
39	$query = array(
40		'INSERT'	=> 'cat_name, disp_position',
41		'INTO'		=> 'categories',
42		'VALUES'	=> '\''.$forum_db->escape($new_cat_name).'\', '.$new_cat_pos
43	);
44
45	($hook = get_hook('acg_add_cat_qr_add_category')) ? eval($hook) : null;
46	$forum_db->query_build($query) or error(__FILE__, __LINE__);
47
48	// Add flash message
49	$forum_flash->add_info($lang_admin_categories['Category added']);
50
51	($hook = get_hook('acg_add_cat_pre_redirect')) ? eval($hook) : null;
52
53	redirect(forum_link($forum_url['admin_categories']), $lang_admin_categories['Category added']);
54}
55
56
57// Delete a category
58else if (isset($_POST['del_cat']) || isset($_POST['del_cat_comply']))
59{
60	$cat_to_delete = intval($_POST['cat_to_delete']);
61	if ($cat_to_delete < 1)
62		message($lang_common['Bad request']);
63
64	// User pressed the cancel button
65	if (isset($_POST['del_cat_cancel']))
66		redirect(forum_link($forum_url['admin_categories']), $lang_admin_common['Cancel redirect']);
67
68	($hook = get_hook('acg_del_cat_form_submitted')) ? eval($hook) : null;
69
70	if (isset($_POST['del_cat_comply']))	// Delete a category with all forums and posts
71	{
72		@set_time_limit(0);
73
74		$query = array(
75			'SELECT'	=> 'f.id',
76			'FROM'		=> 'forums AS f',
77			'WHERE'		=> 'cat_id='.$cat_to_delete
78		);
79
80		($hook = get_hook('acg_del_cat_qr_get_forums_to_delete')) ? eval($hook) : null;
81		$result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
82
83		$forum_ids = array();
84		while ($cur_forum_id = $forum_db->fetch_assoc($result)) {
85			$forum_ids[] = $cur_forum_id['id'];
86		}
87
88		if (!empty($forum_ids))
89		{
90			foreach ($forum_ids as $cur_forum)
91			{
92				// Prune all posts and topics
93				prune($cur_forum, 1, -1);
94
95				// Delete the forum
96				$query = array(
97					'DELETE'	=> 'forums',
98					'WHERE'		=> 'id='.$cur_forum
99				);
100
101				($hook = get_hook('acg_del_cat_qr_delete_forum')) ? eval($hook) : null;
102				$forum_db->query_build($query) or error(__FILE__, __LINE__);
103
104				// Delete any forum subscriptions
105				$query = array(
106					'DELETE'	=> 'forum_subscriptions',
107					'WHERE'		=> 'forum_id='.$cur_forum
108				);
109
110				($hook = get_hook('acg_del_cat_qr_delete_forum_subscriptions')) ? eval($hook) : null;
111				$forum_db->query_build($query) or error(__FILE__, __LINE__);
112			}
113		}
114
115		delete_orphans();
116
117		// Delete the category
118		$query = array(
119			'DELETE'	=> 'categories',
120			'WHERE'		=> 'id='.$cat_to_delete
121		);
122
123		($hook = get_hook('acg_del_cat_qr_delete_category')) ? eval($hook) : null;
124		$forum_db->query_build($query) or error(__FILE__, __LINE__);
125
126		// Regenerate the quickjump cache
127		if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
128			require FORUM_ROOT.'include/cache.php';
129
130		generate_quickjump_cache();
131
132		// Add flash message
133		$forum_flash->add_info($lang_admin_categories['Category deleted']);
134
135		($hook = get_hook('acg_del_cat_pre_redirect')) ? eval($hook) : null;
136
137		redirect(forum_link($forum_url['admin_categories']), $lang_admin_categories['Category deleted']);
138	}
139	else	// If the user hasn't comfirmed the delete
140	{
141		$query = array(
142			'SELECT'	=> 'c.cat_name',
143			'FROM'		=> 'categories AS c',
144			'WHERE'		=> 'c.id='.$cat_to_delete
145		);
146
147		($hook = get_hook('acg_del_cat_qr_get_category_name')) ? eval($hook) : null;
148		$result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
149		$cat_name = $forum_db->result($result);
150
151		if (is_null($cat_name) || $cat_name === false)
152			message($lang_common['Bad request']);
153
154
155		// Setup the form
156		$forum_page['form_action'] = forum_link($forum_url['admin_categories']);
157
158		$forum_page['hidden_fields'] = array(
159			'csrf_token'	=> '<input type="hidden" name="csrf_token" value="'.generate_form_token($forum_page['form_action']).'" />',
160			'cat_to_delete'	=> '<input type="hidden" name="cat_to_delete" value="'.$cat_to_delete.'" />'
161		);
162
163		// Setup breadcrumbs
164		$forum_page['crumbs'] = array(
165			array($forum_config['o_board_title'], forum_link($forum_url['index'])),
166			array($lang_admin_common['Forum administration'], forum_link($forum_url['admin_index'])),
167			array($lang_admin_common['Start'], forum_link($forum_url['admin_index'])),
168			array($lang_admin_common['Categories'], forum_link($forum_url['admin_categories'])),
169			$lang_admin_categories['Delete category']
170		);
171
172		($hook = get_hook('acg_del_cat_pre_header_load')) ? eval($hook) : null;
173
174		define('FORUM_PAGE_SECTION', 'start');
175		define('FORUM_PAGE', 'admin-categories');
176		require FORUM_ROOT.'header.php';
177
178		// START SUBST - <!-- forum_main -->
179		ob_start();
180
181		($hook = get_hook('acg_del_cat_output_start')) ? eval($hook) : null;
182
183?>
184	<div class="main-subhead">
185		<h2 class="hn"><span><?php printf($lang_admin_categories['Confirm delete cat'], forum_htmlencode($cat_name)) ?></span></h2>
186	</div>
187	<div class="main-content main-frm">
188		<div class="ct-box warn-box">
189			<p class="warn"><?php echo $lang_admin_categories['Delete category warning'] ?></p>
190		</div>
191		<form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
192			<div class="hidden">
193				<?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
194			</div>
195			<div class="frm-buttons">
196				<span class="submit primary caution"><input type="submit" name="del_cat_comply" value="<?php echo $lang_admin_categories['Delete category'] ?>" /></span>
197				<span class="cancel"><input type="submit" name="del_cat_cancel" value="<?php echo $lang_admin_common['Cancel'] ?>" /></span>
198			</div>
199		</form>
200	</div>
201<?php
202
203		($hook = get_hook('acg_del_cat_end')) ? eval($hook) : null;
204
205		$tpl_temp = forum_trim(ob_get_contents());
206		$tpl_main = str_replace('<!-- forum_main -->', $tpl_temp, $tpl_main);
207		ob_end_clean();
208		// END SUBST - <!-- forum_main -->
209
210		require FORUM_ROOT.'footer.php';
211	}
212}
213
214
215else if (isset($_POST['update']))	// Change position and name of the categories
216{
217	$cat_order = array_map('intval', $_POST['cat_order']);
218	$cat_name = array_map('trim', $_POST['cat_name']);
219
220	($hook = get_hook('acg_update_cats_form_submitted')) ? eval($hook) : null;
221
222	$query = array(
223		'SELECT'	=> 'c.id, c.cat_name, c.disp_position',
224		'FROM'		=> 'categories AS c',
225		'ORDER BY'	=> 'c.id'
226	);
227
228	($hook = get_hook('acg_update_cats_qr_get_categories')) ? eval($hook) : null;
229	$result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
230	while ($cur_cat = $forum_db->fetch_assoc($result))
231	{
232		// If these aren't set, we're looking at a category that was added after
233		// the admin started editing: we don't want to mess with it
234		if (isset($cat_name[$cur_cat['id']]) && isset($cat_order[$cur_cat['id']]))
235		{
236			if ($cat_name[$cur_cat['id']] == '')
237				message($lang_admin_categories['Must name category']);
238
239			if ($cat_order[$cur_cat['id']] < 0)
240				message($lang_admin_categories['Must be integer']);
241
242			// We only want to update if we changed anything
243			if ($cur_cat['cat_name'] != $cat_name[$cur_cat['id']] || $cur_cat['disp_position'] != $cat_order[$cur_cat['id']])
244			{
245				$query = array(
246					'UPDATE'	=> 'categories',
247					'SET'		=> 'cat_name=\''.$forum_db->escape($cat_name[$cur_cat['id']]).'\', disp_position='.$cat_order[$cur_cat['id']],
248					'WHERE'		=> 'id='.$cur_cat['id']
249				);
250
251				($hook = get_hook('acg_update_cats_qr_update_category')) ? eval($hook) : null;
252				$forum_db->query_build($query) or error(__FILE__, __LINE__);
253			}
254		}
255	}
256
257	// Regenerate the quickjump cache
258	if (!defined('FORUM_CACHE_FUNCTIONS_LOADED'))
259		require FORUM_ROOT.'include/cache.php';
260
261	generate_quickjump_cache();
262
263	// Add flash message
264	$forum_flash->add_info($lang_admin_categories['Categories updated']);
265
266	($hook = get_hook('acg_update_cats_pre_redirect')) ? eval($hook) : null;
267
268	redirect(forum_link($forum_url['admin_categories']), $lang_admin_categories['Categories updated']);
269}
270
271
272// Generate an array with all categories
273$query = array(
274	'SELECT'	=> 'c.id, c.cat_name, c.disp_position',
275	'FROM'		=> 'categories AS c',
276	'ORDER BY'	=> 'c.disp_position'
277);
278
279($hook = get_hook('acg_qr_get_categories')) ? eval($hook) : null;
280$result = $forum_db->query_build($query) or error(__FILE__, __LINE__);
281
282$cat_list = array();
283while ($cur_cat = $forum_db->fetch_assoc($result))
284{
285	$cat_list[] = $cur_cat;
286}
287
288// Setup the form
289$forum_page['group_count'] = $forum_page['item_count'] = $forum_page['fld_count'] = 0;
290$forum_page['form_action'] = forum_link($forum_url['admin_categories']).'?action=foo';
291
292$forum_page['hidden_fields'] = array(
293	'csrf_token'	=> '<input type="hidden" name="csrf_token" value="'.generate_form_token($forum_page['form_action']).'" />'
294);
295
296// Setup breadcrumbs
297$forum_page['crumbs'] = array(
298	array($forum_config['o_board_title'], forum_link($forum_url['index'])),
299	array($lang_admin_common['Forum administration'], forum_link($forum_url['admin_index'])),
300	array($lang_admin_common['Start'], forum_link($forum_url['admin_index'])),
301	array($lang_admin_common['Categories'], forum_link($forum_url['admin_categories']))
302);
303
304($hook = get_hook('acg_pre_header_load')) ? eval($hook) : null;
305
306define('FORUM_PAGE_SECTION', 'start');
307define('FORUM_PAGE', 'admin-categories');
308require FORUM_ROOT.'header.php';
309
310// START SUBST - <!-- forum_main -->
311ob_start();
312
313($hook = get_hook('acg_main_output_start')) ? eval($hook) : null;
314
315?>
316	<div class="main-subhead">
317		<h2 class="hn"><span><?php echo $lang_admin_categories['Add category head'] ?></span></h2>
318	</div>
319	<div class="main-content main-frm">
320		<form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
321			<div class="hidden">
322				<?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
323			</div>
324<?php ($hook = get_hook('acg_pre_add_cat_fieldset')) ? eval($hook) : null; ?>
325			<div class="ct-box">
326				<p><?php printf($lang_admin_categories['Add category info'], '<a href="'.forum_link($forum_url['admin_forums']).'">'.$lang_admin_categories['Add category info link text'].'</a>') ?></p>
327			</div>
328			<fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
329				<legend class="group-legend"><span><?php echo $lang_admin_categories['Add category legend'] ?></span></legend>
330<?php ($hook = get_hook('acg_pre_new_category_name')) ? eval($hook) : null; ?>
331				<div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
332					<div class="sf-box text">
333						<label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_admin_categories['New category label'] ?></span></label><br />
334						<span class="fld-input"><input type="text" id="fld<?php echo $forum_page['fld_count'] ?>" name="new_cat_name" size="35" maxlength="80" required /></span>
335					</div>
336				</div>
337<?php ($hook = get_hook('acg_pre_new_category_position')) ? eval($hook) : null; ?>
338				<div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
339					<div class="sf-box text">
340						<label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_admin_categories['Position label'] ?></span></label><br />
341						<span class="fld-input"><input type="number" id="fld<?php echo $forum_page['fld_count'] ?>" name="position" size="3" maxlength="3" /></span>
342					</div>
343				</div>
344<?php ($hook = get_hook('acg_pre_add_cat_fieldset_end')) ? eval($hook) : null; ?>
345			</fieldset>
346<?php ($hook = get_hook('acg_add_cat_fieldset_end')) ? eval($hook) : null; ?>
347			<div class="frm-buttons">
348				<span class="submit primary"><input type="submit" name="add_cat" value="<?php echo $lang_admin_categories['Add category'] ?>" /></span>
349			</div>
350		</form>
351	</div>
352<?php
353
354($hook = get_hook('acg_post_add_cat_form')) ? eval($hook) : null;
355
356// Reset counter
357$forum_page['group_count'] = $forum_page['item_count'] = 0;
358
359if (!empty($cat_list))
360{
361
362?>
363	<div class="main-subhead">
364		<h2 class="hn"><span><?php echo $lang_admin_categories['Del category head'] ?></span></h2>
365	</div>
366	<div class="main-content main-frm">
367		<form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
368			<div class="hidden">
369				<?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
370			</div>
371<?php ($hook = get_hook('acg_pre_del_cat_fieldset')) ? eval($hook) : null; ?>
372			<fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
373				<legend class="group-legend"><strong><?php echo $lang_admin_categories['Delete category'] ?></strong></legend>
374<?php ($hook = get_hook('acg_pre_del_category_select')) ? eval($hook) : null; ?>
375				<div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
376					<div class="sf-box select">
377						<label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_admin_categories['Select category label'] ?></span> <small><?php echo $lang_admin_common['Delete help'] ?></small></label><br />
378						<span class="fld-input"><select id="fld<?php echo $forum_page['fld_count'] ?>" name="cat_to_delete">
379<?php
380
381	foreach ($cat_list as $cur_category)
382	{
383		echo "\t\t\t\t\t\t\t".'<option value="'.$cur_category['id'].'">'.forum_htmlencode($cur_category['cat_name']).'</option>'."\n";
384	}
385
386?>
387						</select></span>
388					</div>
389				</div>
390<?php ($hook = get_hook('acg_pre_del_cat_fieldset_end')) ? eval($hook) : null; ?>
391			</fieldset>
392<?php ($hook = get_hook('acg_del_cat_fieldset_end')) ? eval($hook) : null; ?>
393			<div class="frm-buttons">
394				<span class="submit primary"><input type="submit" name="del_cat" value="<?php echo $lang_admin_categories['Delete category'] ?>" /></span>
395			</div>
396		</form>
397	</div>
398<?php
399
400($hook = get_hook('acg_post_del_cat_form')) ? eval($hook) : null;
401
402// Reset counter
403$forum_page['group_count'] = $forum_page['item_count'] = 0;
404
405?>
406	<div class="main-subhead">
407		<h2 class="hn"><span><?php echo $lang_admin_categories['Edit categories head'] ?></span></h2>
408	</div>
409	<div class="main-content main-frm">
410		<form class="frm-form" method="post" accept-charset="utf-8" action="<?php echo $forum_page['form_action'] ?>">
411			<div class="hidden">
412				<?php echo implode("\n\t\t\t\t", $forum_page['hidden_fields'])."\n" ?>
413			</div>
414<?php
415
416	($hook = get_hook('acg_edit_cat_fieldsets_start')) ? eval($hook) : null;
417	foreach ($cat_list as $cur_category)
418	{
419		$forum_page['item_count'] = 0;
420		($hook = get_hook('acg_pre_edit_cur_cat_fieldset')) ? eval($hook) : null;
421
422?>
423			<fieldset class="frm-group group<?php echo ++$forum_page['group_count'] ?>">
424				<legend class="group-legend"><span><?php echo $lang_admin_categories['Edit category legend'] ?></span></legend>
425				<div class="sf-set set<?php echo ++$forum_page['item_count'] ?>">
426<?php ($hook = get_hook('acg_pre_edit_cat_name')) ? eval($hook) : null; ?>
427					<div class="sf-box text">
428						<label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_admin_categories['Category name label'] ?></span></label><br />
429						<span class="fld-input"><input type="text" id="fld<?php echo $forum_page['fld_count'] ?>" name="cat_name[<?php echo $cur_category['id'] ?>]" value="<?php echo forum_htmlencode($cur_category['cat_name']) ?>" size="35" maxlength="80" required /></span>
430					</div>
431<?php ($hook = get_hook('acg_pre_edit_cat_position')) ? eval($hook) : null; ?>
432					<div class="sf-box text">
433						<label for="fld<?php echo ++$forum_page['fld_count'] ?>"><span><?php echo $lang_admin_categories['Position label'] ?></span></label><br />
434						<span class="fld-input"><input type="number" id="fld<?php echo $forum_page['fld_count'] ?>" name="cat_order[<?php echo $cur_category['id'] ?>]" value="<?php echo $cur_category['disp_position'] ?>" size="3" maxlength="3" /></span>
435					</div>
436				</div>
437<?php ($hook = get_hook('acg_pre_edit_cur_cat_fieldset_end')) ? eval($hook) : null; ?>
438			</fieldset>
439<?php
440
441		($hook = get_hook('acg_edit_cur_cat_fieldset_end')) ? eval($hook) : null;
442	}
443
444	($hook = get_hook('acg_edit_cat_fieldsets_end')) ? eval($hook) : null;
445
446?>
447			<div class="frm-buttons">
448				<span class="submit primary"><input type="submit" name="update" value="<?php echo $lang_admin_categories['Update all categories'] ?>" /></span>
449			</div>
450		</form>
451	</div>
452<?php
453
454	($hook = get_hook('acg_post_edit_cat_form')) ? eval($hook) : null;
455}
456
457($hook = get_hook('acg_end')) ? eval($hook) : null;
458
459$tpl_temp = forum_trim(ob_get_contents());
460$tpl_main = str_replace('<!-- forum_main -->', $tpl_temp, $tpl_main);
461ob_end_clean();
462// END SUBST - <!-- forum_main -->
463
464require FORUM_ROOT.'footer.php';
465