+ Canned replies @ Known issues: (do not report these as bugs) - Move between categories does not work yet, it will give you a WSOD. - WYSIWYG editor is doing weird things in the canned replies area.
gruffen

gruffen commited on 2011-05-29 12:51:31
Showing 19 changed files, with 1418 additions and 21 deletions.

... ...
@@ -177,7 +177,22 @@ dl.permsettings dd
177 177
 	padding: 0;
178 178
 }
179 179
 
180
-dl.permsettings img
180
+dl.cannedsettings dt
181
+{
182
+	width: 30%;
183
+}
184
+
185
+dl.cannedsettings dd
186
+{
187
+	width: 68%;
188
+}
189
+
190
+dl.cannedsettings dd img
191
+{
192
+	margin: 0;
193
+}
194
+
195
+dl.permsettings img, dl.cannedsettings dd img.icon
181 196
 {
182 197
 	margin: 0 10px 0 0;
183 198
 }
... ...
@@ -170,7 +170,7 @@ $tables[] = array(
170 170
 			'columns' => array('status', 'withdeleted', 'deleted_replies'),
171 171
 		),
172 172
 	),
173
-	'if_exists' => 'update',
173
+	'if_exists' => 'ignore',
174 174
 	'error' => 'fatal',
175 175
 	'parameters' => array(),
176 176
 );
... ...
@@ -201,7 +201,7 @@ $tables[] = array(
201 201
 			'type' => 'index',
202 202
 		),
203 203
 	),
204
-	'if_exists' => 'update',
204
+	'if_exists' => 'ignore',
205 205
 	'error' => 'fatal',
206 206
 	'parameters' => array(),
207 207
 );
... ...
@@ -227,7 +227,7 @@ $tables[] = array(
227 227
 			'type' => 'index',
228 228
 		),
229 229
 	),
230
-	'if_exists' => 'update',
230
+	'if_exists' => 'ignore',
231 231
 	'error' => 'fatal',
232 232
 	'parameters' => array(),
233 233
 );
... ...
@@ -244,7 +244,7 @@ $tables[] = array(
244 244
 			'type' => 'primary',
245 245
 		),
246 246
 	),
247
-	'if_exists' => 'update',
247
+	'if_exists' => 'ignore',
248 248
 	'error' => 'fatal',
249 249
 	'parameters' => array(),
250 250
 );
... ...
@@ -261,7 +261,7 @@ $tables[] = array(
261 261
 			'type' => 'primary',
262 262
 		),
263 263
 	),
264
-	'if_exists' => 'update',
264
+	'if_exists' => 'ignore',
265 265
 	'error' => 'fatal',
266 266
 	'parameters' => array(),
267 267
 );
... ...
@@ -281,7 +281,7 @@ $tables[] = array(
281 281
 			'columns' => array('primary_ticket', 'rel_type'),
282 282
 		),
283 283
 	),
284
-	'if_exists' => 'update',
284
+	'if_exists' => 'ignore',
285 285
 	'error' => 'fatal',
286 286
 	'parameters' => array(),
287 287
 );
... ...
@@ -311,7 +311,7 @@ $tables[] = array(
311 311
 			'type' => 'primary',
312 312
 		),
313 313
 	),
314
-	'if_exists' => 'update',
314
+	'if_exists' => 'ignore',
315 315
 	'error' => 'fatal',
316 316
 	'parameters' => array(),
317 317
 );
... ...
@@ -329,7 +329,7 @@ $tables[] = array(
329 329
 			'type' => 'primary',
330 330
 		),
331 331
 	),
332
-	'if_exists' => 'update',
332
+	'if_exists' => 'ignore',
333 333
 	'error' => 'fatal',
334 334
 	'parameters' => array(),
335 335
 );
... ...
@@ -346,7 +346,7 @@ $tables[] = array(
346 346
 			'type' => 'primary',
347 347
 		),
348 348
 	),
349
-	'if_exists' => 'update',
349
+	'if_exists' => 'ignore',
350 350
 	'error' => 'fatal',
351 351
 	'parameters' => array(),
352 352
 );
... ...
@@ -363,7 +363,7 @@ $tables[] = array(
363 363
 			'type' => 'primary',
364 364
 		),
365 365
 	),
366
-	'if_exists' => 'update',
366
+	'if_exists' => 'ignore',
367 367
 	'error' => 'fatal',
368 368
 	'parameters' => array(),
369 369
 );
... ...
@@ -379,7 +379,7 @@ $tables[] = array(
379 379
 			'type' => 'primary',
380 380
 		),
381 381
 	),
382
-	'if_exists' => 'update',
382
+	'if_exists' => 'ignore',
383 383
 	'error' => 'fatal',
384 384
 	'parameters' => array(),
385 385
 );
... ...
@@ -396,7 +396,7 @@ $tables[] = array(
396 396
 			'type' => 'primary',
397 397
 		),
398 398
 	),
399
-	'if_exists' => 'update',
399
+	'if_exists' => 'ignore',
400 400
 	'error' => 'fatal',
401 401
 	'parameters' => array(),
402 402
 );
... ...
@@ -413,7 +413,7 @@ $tables[] = array(
413 413
 			'type' => 'primary',
414 414
 		),
415 415
 	),
416
-	'if_exists' => 'update',
416
+	'if_exists' => 'ignore',
417 417
 	'error' => 'fatal',
418 418
 	'parameters' => array(),
419 419
 );
... ...
@@ -435,7 +435,7 @@ $tables[] = array(
435 435
 			'type' => 'primary',
436 436
 		),
437 437
 	),
438
-	'if_exists' => 'update',
438
+	'if_exists' => 'ignore',
439 439
 	'error' => 'fatal',
440 440
 	'parameters' => array(),
441 441
 );
... ...
@@ -451,7 +451,62 @@ $tables[] = array(
451 451
 			'type' => 'primary',
452 452
 		),
453 453
 	),
454
-	'if_exists' => 'update',
454
+	'if_exists' => 'ignore',
455
+	'error' => 'fatal',
456
+	'parameters' => array(),
457
+);
458
+$tables[] = array(
459
+	'table_name' => '{db_prefix}helpdesk_cannedreplies',
460
+	'columns' => array(
461
+		db_field('id_reply', 'smallint', 0, true, true),
462
+		db_field('id_cat', 'smallint'),
463
+		db_field('title', 'varchar', 80),
464
+		db_field('body', 'text'),
465
+		db_field('vis_user', 'tinyint'),
466
+		db_field('vis_staff', 'tinyint'),
467
+		db_field('reply_order', 'smallint'),
468
+		db_field('active', 'tinyint'),
469
+	),
470
+	'indexes' => array(
471
+		array(
472
+			'columns' => array('id_reply'),
473
+			'type' => 'primary',
474
+		),
475
+	),
476
+	'if_exists' => 'ignore',
477
+	'error' => 'fatal',
478
+	'parameters' => array(),
479
+);
480
+$tables[] = array(
481
+	'table_name' => '{db_prefix}helpdesk_cannedreplies_cats',
482
+	'columns' => array(
483
+		db_field('id_cat', 'smallint', 0, true, true),
484
+		db_field('cat_name', 'varchar', 80),
485
+		db_field('cat_order', 'smallint'),
486
+	),
487
+	'indexes' => array(
488
+		array(
489
+			'columns' => array('id_cat'),
490
+			'type' => 'primary',
491
+		),
492
+	),
493
+	'if_exists' => 'ignore',
494
+	'error' => 'fatal',
495
+	'parameters' => array(),
496
+);
497
+$tables[] = array(
498
+	'table_name' => '{db_prefix}helpdesk_cannedreplies_depts',
499
+	'columns' => array(
500
+		db_field('id_dept', 'smallint'),
501
+		db_field('id_reply', 'smallint'),
502
+	),
503
+	'indexes' => array(
504
+		array(
505
+			'columns' => array('id_dept', 'id_reply'),
506
+			'type' => 'primary',
507
+		),
508
+	),
509
+	'if_exists' => 'ignore',
455 510
 	'error' => 'fatal',
456 511
 	'parameters' => array(),
457 512
 );
... ...
@@ -333,6 +332,47 @@ QuickReply.prototype.swap = function ()
333 332
 	this.bCollapsed = !this.bCollapsed;
334 333
 }
335 334
 
335
+function CannedReply(oOptions)
336
+{
337
+	this.opt = oOptions;
338
+	document.getElementById("canned_replies").style.display = "";
339
+}
340
+
341
+CannedReply.prototype.getReply = function ()
342
+{
343
+	var iReplyId = document.getElementById('canned_replies_select').value;
344
+	if (!iReplyId || parseInt(iReplyId, 10) < 1)
345
+		return false;
346
+
347
+	// Doing it the XMLhttp way?
348
+	if (window.XMLHttpRequest)
349
+	{
350
+		ajax_indicator(true);
351
+		getXMLDocument(smf_prepareScriptUrl(this.opt.sScriptUrl) + 'action=helpdesk;sa=ajax;op=canned;ticket=' + this.opt.iTicketId + ';reply=' + iReplyId + ';' + this.opt.sSessionVar + '=' + this.opt.sSessionId + ';xml' + ';mode=' + (oEditorHandle_shd_message.bRichTextEnabled ? 1 : 0), this.onReplyReceived);
352
+	}
353
+
354
+	// Move the view to the quick reply box.
355
+	if (navigator.appName == 'Microsoft Internet Explorer')
356
+		window.location.hash = this.opt.sJumpAnchor;
357
+	else
358
+		window.location.hash = '#' + this.opt.sJumpAnchor;
359
+
360
+	return false;
361
+}
362
+
363
+// This is the callback function used after the XMLhttp request.
364
+CannedReply.prototype.onReplyReceived = function (oXMLDoc)
365
+{
366
+	var sQuoteText = '';
367
+
368
+	for (var i = 0; i < oXMLDoc.getElementsByTagName('quote')[0].childNodes.length; i++)
369
+		sQuoteText += oXMLDoc.getElementsByTagName('quote')[0].childNodes[i].nodeValue;
370
+
371
+	oEditorHandle_shd_message.insertText(sQuoteText, false, true);
372
+
373
+	ajax_indicator(false);
374
+}
375
+
336 376
 // The quick jump function
337 377
 function shd_quickTicketJump(id_ticket)
338 378
 {
... ...
@@ -32,6 +32,7 @@ $txt['shd_helpdesk'] = 'Helpdesk';
32 32
 $txt['shd_helpdesk_maintenance'] = 'The helpdesk is currently in <strong>maintenance mode</strong>. Only forum and helpdesk administrators can see this.';
33 33
 $txt['shd_open_ticket'] = 'open ticket';
34 34
 $txt['shd_open_tickets'] = 'open tickets';
35
+$txt['shd_none'] = 'None';
35 36
 
36 37
 //! @name Admininstration panel strings
37 38
 //@{
... ...
@@ -170,6 +171,7 @@ $txt['shd_admin_custom_fields'] = 'Custom Fields';
170 171
 $txt['shd_admin_departments'] = 'Departments';
171 172
 $txt['shd_admin_permissions'] = 'Permissions';
172 173
 $txt['shd_admin_plugins'] = 'Plugins';
174
+$txt['shd_admin_cannedreplies'] = 'Canned Replies';
173 175
 $txt['shd_admin_maint'] = 'Maintenance';
174 176
 
175 177
 $txt['shd_user_greeting'] = 'Here you can file new tickets for the site staff to action, and check on current tickets already underway.';
... ...
@@ -333,6 +335,8 @@ $txt['shd_choose_one'] = '[Choose one]';
333 335
 $txt['shd_no_value'] = '[no value]';
334 336
 $txt['shd_ticket_dept'] = 'Ticket department';
335 337
 $txt['shd_select_dept'] = '-- Select a department --';
338
+$txt['canned_replies'] = 'Insert a pre-defined reply:';
339
+$txt['canned_replies_select'] = '-- Select a reply --';
336 340
 
337 341
 // Profile / trackip
338 342
 $txt['shd_replies_from_ip'] = 'Helpdesk replies posted from IP (range)';
... ...
@@ -366,12 +366,36 @@ $txt['shd_admin_cannedreplies_home'] = 'Helpdesk - Canned Replies';
366 366
 $txt['shd_admin_cannedreplies_homedesc'] = 'This section allows you to create template answers, or snippets, or the answers to frequently asked questions, so that they are available from the posting interface.';
367 367
 $txt['shd_admin_cannedreplies_nocats'] = 'There are no categories for canned replies, you will need to create one first.';
368 368
 $txt['shd_admin_cannedreplies_createcat'] = 'Create New Category';
369
+$txt['shd_admin_cannedreplies_editcat'] = 'Edit This Category';
370
+$txt['shd_admin_cannedreplies_deletecat'] = 'Delete This Category';
371
+$txt['shd_admin_cannedreplies_categoryname'] = 'Category Name';
369 372
 $txt['shd_admin_cannedreplies_replyname'] = 'Reply Name';
370 373
 $txt['shd_admin_cannedreplies_isactive'] = 'Active?';
371 374
 $txt['shd_admin_cannedreplies_visibleto'] = 'Visible To';
372 375
 $txt['shd_admin_cannedreplies_emptycat'] = 'There are no canned replies in this category.';
373 376
 $txt['shd_admin_cannedreplies_addreply'] = 'Create New Reply';
377
+$txt['shd_admin_cannedreplies_editreply'] = 'Edit This Reply';
378
+$txt['shd_admin_cannedreplies_deletereply'] = 'Delete This Reply';
374 379
 $txt['shd_admin_cannedreplies_delete_confirm'] = 'Are you sure you want to delete this category and all the replies in it?';
380
+$txt['shd_admin_cannedreplies_deletereply_confirm'] = 'Are you sure you want to delete this reply?';
381
+$txt['shd_admin_cannedreplies_move_between_cat'] = 'Move this canned reply to another category';
382
+$txt['shd_admin_cannedreplies_cannot_move_reply'] = 'This reply cannot be moved.';
383
+$txt['shd_admin_cannedreplies_cannot_move_reply_up'] = 'This reply cannot be moved up.';
384
+$txt['shd_admin_cannedreplies_cannot_move_reply_down'] = 'This reply cannot be moved down.';
385
+$txt['shd_admin_cannedreplies_cannot_move_cat'] = 'This category cannot be moved.';
386
+$txt['shd_admin_cannedreplies_cannot_move_cat_up'] = 'This category cannot be moved up.';
387
+$txt['shd_admin_cannedreplies_cannot_move_cat_down'] = 'This category cannot be moved down.';
388
+$txt['shd_admin_cannedreplies_thecatisalie'] = 'This category does not exist, it cannot be edited.';
389
+$txt['shd_admin_cannedreplies_thereplyisalie'] = 'This reply does not exist, it cannot be edited.';
390
+$txt['shd_admin_cannedreplies_nocatname'] = 'No name was given for the category, one must be provided.';
391
+$txt['shd_admin_cannedreplies_replytitle'] = 'Title of this canned reply';
392
+$txt['shd_admin_cannedreplies_content'] = 'Content of the canned reply';
393
+$txt['shd_admin_cannedreplies_active'] = 'Is this canned reply active?';
394
+$txt['shd_admin_cannedreplies_selectvisible'] = 'Who is this canned reply available to?';
395
+$txt['shd_admin_cannedreplies_departments'] = 'Departments this canned reply is accessible from';
396
+$txt['shd_admin_cannedreplies_notitle'] = 'No title was given for this canned reply, one must be provided.';
397
+$txt['shd_admin_cannedreplies_nobody'] = 'No body content was given for this canned reply, one must be provided.';
398
+$txt['shd_admin_cannedreplies_notcreated'] = 'The new reply could not be created.';
375 399
 
376 400
 //! Departments
377 401
 //@{
... ...
@@ -325,7 +325,6 @@ $txt['shd_permrole_admin'] = 'Helpdesk Administrators';
325 325
 $txt['shd_create_role'] = 'Create new role based on this';
326 326
 $txt['shd_no_defined_roles'] = 'You have not created any roles yet for your users!';
327 327
 $txt['shd_based_on'] = 'Based on \'%1$s\' template';
328
-$txt['shd_none'] = 'None';
329 328
 $txt['shd_edit_role'] = 'Edit this role';
330 329
 $txt['shd_create_role'] = 'Create New Role';
331 330
 $txt['shd_edit_role'] = 'Edit Role';
... ...
@@ -66,6 +66,7 @@ function shd_admin_main()
66 66
 	$subActions = array(
67 67
 		'helpdesk_info' => array(null, 'shd_admin_info'),
68 68
 		'helpdesk_options' => array(null, 'shd_admin_options'),
69
+		'helpdesk_cannedreplies' => array('SimpleDesk-AdminCannedReplies.php', 'shd_admin_canned'),
69 70
 		'helpdesk_customfield' => array('SimpleDesk-AdminCustomField.php', 'shd_admin_custom'),
70 71
 		'helpdesk_depts' => array('SimpleDesk-AdminDepartments.php', 'shd_admin_departments'),
71 72
 		'helpdesk_permissions' => array('SimpleDesk-AdminPermissions.php', 'shd_admin_permissions'),
... ...
@@ -0,0 +1,811 @@
1
+<?php
2
+###############################################################
3
+#         Simple Desk Project - www.simpledesk.net            #
4
+###############################################################
5
+#       An advanced help desk modifcation built on SMF        #
6
+###############################################################
7
+#                                                             #
8
+#         * Copyright 2010 - SimpleDesk.net                   #
9
+#                                                             #
10
+#   This file and its contents are subject to the license     #
11
+#   included with this distribution, license.txt, which       #
12
+#   states that this software is New BSD Licensed.            #
13
+#   Any questions, please contact SimpleDesk.net              #
14
+#                                                             #
15
+###############################################################
16
+# SimpleDesk Version: 2.0 Anatidae                            #
17
+# File Info: SimpleDesk-AdminDepartments.php / 2.0 Anatidae   #
18
+###############################################################
19
+
20
+/**
21
+ *	This file handles the core of SimpleDesk's departmental administration.
22
+ *
23
+ *	@package source
24
+ *	@since 2.0
25
+*/
26
+if (!defined('SMF'))
27
+	die('Hacking attempt...');
28
+
29
+/**
30
+ *	The start point for all interaction with the SimpleDesk departments
31
+ *
32
+ *	@since 2.0
33
+*/
34
+function shd_admin_canned()
35
+{
36
+	global $context, $scripturl, $sourcedir, $settings, $txt, $modSettings;
37
+
38
+	loadTemplate('sd_template/SimpleDesk-AdminCannedReplies');
39
+
40
+	$subactions = array(
41
+		'main' => 'shd_admin_canned_list',
42
+		'createcat' => 'shd_admin_canned_createcat',
43
+		'movecat' => 'shd_admin_canned_movecat',
44
+		'editcat' => 'shd_admin_canned_editcat',
45
+		'savecat' => 'shd_admin_canned_savecat',
46
+		'createreply' => 'shd_admin_canned_createreply',
47
+		'movereply' => 'shd_admin_canned_movereply',
48
+		'movereplycat' => 'shd_admin_canned_movereplycat',
49
+		'editreply' => 'shd_admin_canned_editreply',
50
+		'savereply' => 'shd_admin_canned_savereply',
51
+	);
52
+
53
+	$_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subactions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'main';
54
+
55
+	$subactions[$_REQUEST['sa']]();
56
+}
57
+
58
+/**
59
+ *	Set up displaying all of the canned replies in the main listing.
60
+ *
61
+ *	@since 2.0
62
+*/
63
+function shd_admin_canned_list()
64
+{
65
+	global $context, $smcFunc, $txt;
66
+
67
+	$context['page_title'] = $txt['shd_admin_cannedreplies_home'];
68
+	$context['sub_template'] = 'shd_cannedreplies_home';
69
+
70
+	$context['canned_replies'] = array();
71
+
72
+	// 1. Get all the item/department joins. This could be complicated, so do it this way.
73
+	$reply_depts = array();
74
+	$query = $smcFunc['db_query']('', '
75
+		SELECT hdcrd.id_reply, hdd.dept_name
76
+		FROM {db_prefix}helpdesk_cannedreplies_depts AS hdcrd
77
+			INNER JOIN {db_prefix}helpdesk_depts AS hdd ON (hdcrd.id_dept = hdd.id_dept)
78
+		ORDER BY hdcrd.id_reply, hdd.dept_order'
79
+	);
80
+	while ($row = $smcFunc['db_fetch_assoc']($query))
81
+		$reply_depts[$row['id_reply']][] = $row['dept_name'];
82
+
83
+	// 2. Get all the actual categories and all their items.
84
+	$query = $smcFunc['db_query']('', '
85
+		SELECT hdcr.id_reply, hdcr.title, hdcrc.id_cat, hdcrc.cat_name, hdcr.active, hdcr.vis_user, hdcr.vis_staff
86
+		FROM {db_prefix}helpdesk_cannedreplies_cats AS hdcrc
87
+			LEFT JOIN {db_prefix}helpdesk_cannedreplies AS hdcr ON (hdcr.id_cat = hdcrc.id_cat)
88
+		ORDER BY hdcrc.cat_order, hdcr.reply_order'
89
+	);
90
+
91
+	while ($row = $smcFunc['db_fetch_assoc']($query))
92
+	{
93
+		if (!isset($context['canned_replies'][$row['id_cat']]))
94
+			$context['canned_replies'][$row['id_cat']] = array(
95
+				'name' => $row['cat_name'],
96
+				'replies' => array(),
97
+				'move_up' => true,
98
+				'move_down' => true,
99
+			);
100
+
101
+		$row['active_string'] = empty($row['active']) ? 'inactive' : 'active';
102
+		$row['move_up'] = true;
103
+		$row['move_down'] = true;
104
+		$row['depts'] = !empty($reply_depts[$row['id_reply']]) ? implode(', ', $reply_depts[$row['id_reply']]) : $txt['shd_none'];
105
+
106
+		if (!empty($row['title']))
107
+			$context['canned_replies'][$row['id_cat']]['replies'][] = $row;
108
+	}
109
+
110
+	$context['move_between_cats'] = count($context['canned_replies']) > 1;
111
+	foreach ($context['canned_replies'] as $cat_id => $cat)
112
+	{
113
+		if (!empty($cat['replies']))
114
+		{
115
+			$context['canned_replies'][$cat_id]['replies'][0]['move_up'] = false;
116
+			$context['canned_replies'][$cat_id]['replies'][count($cat['replies'])-1]['move_down'] = false;
117
+		}
118
+		$context['canned_replies'][$cat_id]['move_up'] &= $context['move_between_cats'];
119
+		$context['canned_replies'][$cat_id]['move_down'] &= $context['move_between_cats'];
120
+
121
+		if (!isset($first))
122
+			$first = $cat_id;
123
+		$last = $cat_id;
124
+	}
125
+	$context['canned_replies'][$first]['move_up'] = false;
126
+	$context['canned_replies'][$last]['move_down'] = false;
127
+}
128
+
129
+/**
130
+ *	Handle moving a category of canned replied up and down.
131
+ *
132
+ *	@since 2.0
133
+*/
134
+function shd_admin_canned_movecat()
135
+{
136
+	global $context, $smcFunc, $modSettings;
137
+
138
+	checkSession('get');
139
+
140
+	$_REQUEST['cat'] = isset($_REQUEST['cat']) ? (int) $_REQUEST['cat'] : 0;
141
+	$_REQUEST['direction'] = isset($_REQUEST['direction']) && in_array($_REQUEST['direction'], array('up', 'down')) ? $_REQUEST['direction'] : '';
142
+
143
+	$query = shd_db_query('', '
144
+		SELECT id_cat, cat_order
145
+		FROM {db_prefix}helpdesk_cannedreplies_cats',
146
+		array()
147
+	);
148
+
149
+	if ($smcFunc['db_num_rows']($query) == 0 || empty($_REQUEST['direction']))
150
+	{
151
+		$smcFunc['db_free_result']($query);
152
+		fatal_lang_error('shd_admin_cannedreplies_cannot_move_cat', false);
153
+	}
154
+
155
+	$cats = array();
156
+	while ($row = $smcFunc['db_fetch_assoc']($query))
157
+		$cats[$row['cat_order']] = $row['id_cat'];
158
+
159
+	ksort($cats);
160
+
161
+	$cats_map = array_flip($cats);
162
+	if (empty($cats_map[$_REQUEST['cat']]))
163
+		fatal_lang_error('shd_admin_cannedreplies_cannot_move_cat', false);
164
+
165
+	$current_pos = $cats_map[$_REQUEST['cat']];
166
+	$destination = $current_pos + ($_REQUEST['direction'] == 'up' ? -1 : 1);
167
+
168
+	if (empty($cats[$destination]))
169
+		fatal_lang_error('shd_admin_cannedreplies_cannot_move_cat_' . $_REQUEST['direction'], false);
170
+
171
+	$other_cat = $cats[$destination];
172
+
173
+	shd_db_query('', '
174
+		UPDATE {db_prefix}helpdesk_cannedreplies_cats
175
+		SET cat_order = {int:new_pos}
176
+		WHERE id_cat = {int:cat}',
177
+		array(
178
+			'new_pos' => $destination,
179
+			'cat' => $_REQUEST['cat'],
180
+		)
181
+	);
182
+
183
+	shd_db_query('', '
184
+		UPDATE {db_prefix}helpdesk_cannedreplies_cats
185
+		SET cat_order = {int:old_pos}
186
+		WHERE id_cat = {int:other_cat}',
187
+		array(
188
+			'old_pos' => $current_pos,
189
+			'other_cat' => $other_cat,
190
+		)
191
+	);
192
+
193
+	redirectexit('action=admin;area=helpdesk_cannedreplies');
194
+}
195
+
196
+/**
197
+ *	Handle moving a reply up and down within its category.
198
+ *
199
+ *	@since 2.0
200
+*/
201
+function shd_admin_canned_movereply()
202
+{
203
+	global $context, $smcFunc, $modSettings;
204
+
205
+	checkSession('get');
206
+
207
+	$_REQUEST['reply'] = isset($_REQUEST['reply']) ? (int) $_REQUEST['reply'] : 0;
208
+	$_REQUEST['direction'] = isset($_REQUEST['direction']) && in_array($_REQUEST['direction'], array('up', 'down')) ? $_REQUEST['direction'] : '';
209
+
210
+	$query = shd_db_query('', '
211
+		SELECT id_reply, reply_order
212
+		FROM {db_prefix}helpdesk_cannedreplies',
213
+		array()
214
+	);
215
+
216
+	if ($smcFunc['db_num_rows']($query) == 0 || empty($_REQUEST['direction']))
217
+	{
218
+		$smcFunc['db_free_result']($query);
219
+		fatal_lang_error('shd_admin_cannedreplies_cannot_move_reply', false);
220
+	}
221
+
222
+	$replies = array();
223
+	while ($row = $smcFunc['db_fetch_assoc']($query))
224
+		$replies[$row['reply_order']] = $row['id_reply'];
225
+
226
+	ksort($replies);
227
+
228
+	$replies_map = array_flip($replies);
229
+	if (empty($replies_map[$_REQUEST['reply']]))
230
+		fatal_lang_error('shd_admin_cannedreplies_cannot_move_reply', false);
231
+
232
+	$current_pos = $replies_map[$_REQUEST['reply']];
233
+	$destination = $current_pos + ($_REQUEST['direction'] == 'up' ? -1 : 1);
234
+
235
+	if (empty($replies[$destination]))
236
+		fatal_lang_error('shd_admin_cannedreplies_cannot_move_reply_' . $_REQUEST['direction'], false);
237
+
238
+	$other_reply = $replies[$destination];
239
+
240
+	shd_db_query('', '
241
+		UPDATE {db_prefix}helpdesk_cannedreplies
242
+		SET reply_order = {int:new_pos}
243
+		WHERE id_reply = {int:reply}',
244
+		array(
245
+			'new_pos' => $destination,
246
+			'reply' => $_REQUEST['reply'],
247
+		)
248
+	);
249
+
250
+	shd_db_query('', '
251
+		UPDATE {db_prefix}helpdesk_cannedreplies
252
+		SET reply_order = {int:old_pos}
253
+		WHERE id_reply = {int:other_reply}',
254
+		array(
255
+			'old_pos' => $current_pos,
256
+			'other_reply' => $other_reply,
257
+		)
258
+	);
259
+
260
+	redirectexit('action=admin;area=helpdesk_cannedreplies');
261
+}
262
+
263
+/**
264
+ *	Display the UI for creating a category of canned replies.
265
+ *
266
+ *	@since 2.0
267
+*/
268
+function shd_admin_canned_createcat()
269
+{
270
+	global $context, $smcFunc, $txt;
271
+
272
+	$context['page_title'] = $txt['shd_admin_cannedreplies_createcat'];
273
+	$context['sub_template'] = 'shd_edit_canned_category';
274
+
275
+	// Setting up for the form. One form, two uses, sneaky, huh.
276
+	$_REQUEST['cat'] = 'new';
277
+	$context['category_name'] = '';
278
+	checkSubmitOnce('register');
279
+}
280
+
281
+function shd_admin_canned_editcat()
282
+{
283
+	global $context, $smcFunc, $txt;
284
+
285
+	$context['page_title'] = $txt['shd_admin_cannedreplies_editcat'];
286
+	$context['sub_template'] = 'shd_edit_canned_category';
287
+
288
+	$_REQUEST['cat'] = isset($_REQUEST['cat']) ? (int) $_REQUEST['cat'] : 0;
289
+	$query = $smcFunc['db_query']('', '
290
+		SELECT cat_name
291
+		FROM {db_prefix}helpdesk_cannedreplies_cats
292
+		WHERE id_cat = {int:cat}',
293
+		array(
294
+			'cat' => $_REQUEST['cat'],
295
+		)
296
+	);
297
+	if ($smcFunc['db_num_rows']($query) == 0)
298
+	{
299
+		$smcFunc['db_free_result']($query);
300
+		fatal_lang_error('shd_admin_cannedreplies_thecatisalie', false);
301
+	}
302
+
303
+	list($context['category_name']) = $smcFunc['db_fetch_row']($query);
304
+	$smcFunc['db_free_result']($query);
305
+	checkSubmitOnce('register');
306
+}
307
+
308
+function shd_admin_canned_savecat()
309
+{
310
+	global $context, $smcFunc, $txt;
311
+
312
+	checkSession('request');
313
+
314
+	// If we're deleting a category, do it first, get it out the way.
315
+	if (!empty($_POST['delete']))
316
+	{
317
+		$_REQUEST['cat'] = isset($_REQUEST['cat']) ? (int) $_REQUEST['cat'] : 0;
318
+		if ($_REQUEST['cat'] > 0)
319
+		{
320
+			// 1. Get the category's position.
321
+			$query = $smcFunc['db_query']('', '
322
+				SELECT cat_order
323
+				FROM {db_prefix}helpdesk_cannedreplies_cats
324
+				WHERE id_cat = {int:cat}',
325
+				array(
326
+					'cat' => $_REQUEST['cat'],
327
+				)
328
+			);
329
+			if ($smcFunc['db_num_rows']($query) == 0)
330
+				redirectexit('action=admin;area=helpdesk_cannedreplies');
331
+			
332
+			list($old_pos) = $smcFunc['db_fetch_row']($query);
333
+			
334
+			// 2. Delete the old category.
335
+			$smcFunc['db_query']('', '
336
+				DELETE FROM {db_prefix}helpdesk_cannedreplies_cats
337
+				WHERE id_cat = {int:cat}',
338
+				array(
339
+					'cat' => $_REQUEST['cat'],
340
+				)
341
+			);
342
+			// 3. Bump everything else up one.
343
+			$smcFunc['db_query']('', '
344
+				UPDATE {db_prefix}helpdesk_cannedreplies_cats
345
+				SET cat_order = cat_order - 1
346
+				WHERE cat_order > {int:old_pos}',
347
+				array(
348
+					'old_pos' => $old_pos,
349
+				)
350
+			);
351
+			// 4. Get all the replies in this category, so we can purge related records.
352
+			$query = $smcFunc['db_query']('', '
353
+				SELECT id_reply
354
+				FROM {db_prefix}helpdesk_cannedreplies
355
+				WHERE id_cat = {int:cat}',
356
+				array(
357
+					'cat' => (int) $_REQUEST['cat'],
358
+				)
359
+			);
360
+			$replies = array();
361
+			while ($row = $smcFunc['db_fetch_row']($query))
362
+				$replies[] = $row[0];
363
+			$smcFunc['db_free_result']($query);
364
+			
365
+			if (!empty($replies))
366
+			{
367
+				// 5. Remove the dept/reply relationships. (If we have any.)
368
+				$smcFunc['db_query']('', '
369
+					DELETE FROM {db_prefix}helpdesk_cannedreplies_depts
370
+					WHERE id_reply IN ({array_int:replies})',
371
+					array(
372
+						'replies' => $replies,
373
+					)
374
+				);
375
+				// 6. Remove the replies themselves.
376
+				$smcFunc['db_query']('', '
377
+					DELETE FROM {db_prefix}helpdesk_cannedreplies
378
+					WHERE id_reply IN ({array_int:replies})',
379
+					array(
380
+						'replies' => $replies,
381
+					)
382
+				);
383
+			}
384
+		}
385
+
386
+		redirectexit('action=admin;area=helpdesk_cannedreplies');
387
+	}
388
+
389
+	$_POST['catname'] = isset($_POST['catname']) ? strtr($smcFunc['htmlspecialchars']($_POST['catname']), array("\r" => '', "\n" => '', "\t" => '')) : '';
390
+
391
+	// There are two things we could be doing here. $_POST['cat'] should be set, and it should be set to 'new' for new categories, or a number of an existing category otherwise.
392
+	if (empty($_POST['cat']))
393
+		fatal_lang_error('shd_admin_cannedreplies_thecatisalie', false);
394
+	elseif (empty($_POST['catname']))
395
+		fatal_lang_error('shd_admin_cannedreplies_nocatname', false);
396
+
397
+	checkSubmitOnce('check');
398
+
399
+	// Otherwise we're doing something with a category.
400
+	if ($_POST['cat'] == 'new')
401
+	{
402
+		$query = $smcFunc['db_query']('', '
403
+			SELECT MAX(cat_order)
404
+			FROM {db_prefix}helpdesk_cannedreplies_cats');
405
+		list($current_max) = $smcFunc['db_fetch_row']($query);
406
+		$smcFunc['db_free_result']($query);
407
+
408
+		// Insert the category.
409
+		$smcFunc['db_insert']('insert',
410
+			'{db_prefix}helpdesk_cannedreplies_cats',
411
+			array(
412
+				'cat_name' => 'string', 'cat_order' => 'int',
413
+			),
414
+			array(
415
+				$_POST['catname'], (int) $current_max + 1,
416
+			),
417
+			array(
418
+				'id_cat',
419
+			)
420
+		);
421
+	}
422
+	else
423
+	{
424
+		// We're updating, apparently.
425
+		$smcFunc['db_query']('', '
426
+			UPDATE {db_prefix}helpdesk_cannedreplies_cats
427
+			SET cat_name = {string:name}
428
+			WHERE id_cat = {int:cat}',
429
+			array(
430
+				'name' => $_POST['catname'],
431
+				'cat' => (int) $_POST['cat'],
432
+			)
433
+		);
434
+		if ($smcFunc['db_affected_rows']() == 0)
435
+			fatal_lang_error('shd_admin_cannedreplies_thecatisalie', false);
436
+	}
437
+
438
+	redirectexit('action=admin;area=helpdesk_cannedreplies');
439
+}
440
+
441
+/**
442
+ *	Display the UI for creating a new reply.
443
+ *
444
+ *	@since 2.0
445
+*/
446
+function shd_admin_canned_createreply()
447
+{
448
+	global $context, $smcFunc, $txt, $sourcedir, $scripturl;
449
+
450
+	$context['page_title'] = $txt['shd_admin_cannedreplies_addreply'];
451
+	$context['sub_template'] = 'shd_edit_canned_reply';
452
+
453
+	$_REQUEST['cat'] = isset($_REQUEST['cat']) ? (int) $_REQUEST['cat'] : 0;
454
+	$query = $smcFunc['db_query']('', '
455
+		SELECT cat_name
456
+		FROM {db_prefix}helpdesk_cannedreplies_cats
457
+		WHERE id_cat = {int:cat}',
458
+		array(
459
+			'cat' => $_REQUEST['cat'],
460
+		)
461
+	);
462
+	
463
+	if ($smcFunc['db_num_rows']($query) == 0)
464
+	{
465
+		$smcFunc['db_free_result']($query);
466
+		fatal_lang_error('shd_admin_cannedreplies_thecatisalie', false);
467
+	}
468
+
469
+	$smcFunc['db_free_result']($query);
470
+
471
+	$context['canned_reply'] = array(
472
+		'id' => 'new',
473
+		'title' => '',
474
+		'body' => '',
475
+		'active' => 1,
476
+		'vis_user' => '',
477
+		'vis_staff' => '',
478
+		'cat' => $_REQUEST['cat'],
479
+		'depts_selected' => array(),
480
+		'depts_available' => array(),
481
+	);
482
+	// Now we need to get the possible departments.
483
+	$query = $smcFunc['db_query']('', '
484
+		SELECT id_dept, dept_name
485
+		FROM {db_prefix}helpdesk_depts
486
+		ORDER BY dept_order');
487
+	while ($row = $smcFunc['db_fetch_assoc']($query))
488
+		$context['canned_reply']['depts_available'][$row['id_dept']] = $row['dept_name'];
489
+	$smcFunc['db_free_result']($query);
490
+
491
+	checkSubmitOnce('register');
492
+
493
+	require_once($sourcedir . '/Subs-Editor.php');
494
+
495
+	$editorOptions = array(
496
+		'id' => 'shd_canned_reply',
497
+		'value' => $context['canned_reply']['body'],
498
+		'labels' => array(
499
+			'post_button' => $txt['shd_admin_cannedreplies_addreply'],
500
+		),
501
+		'preview_type' => 0,
502
+		'width' => '70%',
503
+		'disable_smiley_box' => false,
504
+	);
505
+	create_control_richedit($editorOptions);
506
+	$context['post_box_name'] = $editorOptions['id'];
507
+}
508
+
509
+function shd_admin_canned_editreply()
510
+{
511
+	global $context, $smcFunc, $txt, $sourcedir, $scripturl;
512
+
513
+	require_once($sourcedir . '/Subs-Editor.php');
514
+	require_once($sourcedir . '/Subs-Post.php');
515
+
516
+	$context['page_title'] = $txt['shd_admin_cannedreplies_editreply'];
517
+	$context['sub_template'] = 'shd_edit_canned_reply';
518
+
519
+	$_REQUEST['reply'] = isset($_REQUEST['reply']) ? (int) $_REQUEST['reply'] : 0;
520
+	$query = $smcFunc['db_query']('', '
521
+		SELECT hdcr.title, hdcr.body, hdcr.vis_user, hdcr.vis_staff, hdcr.active, hdcr.id_cat
522
+		FROM {db_prefix}helpdesk_cannedreplies AS hdcr
523
+		WHERE id_reply = {int:reply}',
524
+		array(
525
+			'reply' => $_REQUEST['reply'],
526
+		)
527
+	);
528
+	
529
+	if ($smcFunc['db_num_rows']($query) == 0)
530
+	{
531
+		$smcFunc['db_free_result']($query);
532
+		fatal_lang_error('shd_admin_cannedreplies_thereplyisalie', false);
533
+	}
534
+
535
+	$row = $smcFunc['db_fetch_assoc']($query);
536
+	$smcFunc['db_free_result']($query);
537
+
538
+	$context['canned_reply'] = array(
539
+		'id' => $_REQUEST['reply'],
540
+		'title' => $row['title'],
541
+		'body' => un_preparsecode($row['body']),
542
+		'active' => !empty($row['active']),
543
+		'vis_user' => !empty($row['vis_user']),
544
+		'vis_staff' => !empty($row['vis_staff']),
545
+		'cat' => $row['id_cat'],
546
+		'depts_selected' => array(),
547
+		'depts_available' => array(),
548
+	);
549
+
550
+	// Now we need to get the possible departments.
551
+	$query = $smcFunc['db_query']('', '
552
+		SELECT id_dept, dept_name
553
+		FROM {db_prefix}helpdesk_depts
554
+		ORDER BY dept_order');
555
+	while ($row = $smcFunc['db_fetch_assoc']($query))
556
+		$context['canned_reply']['depts_available'][$row['id_dept']] = $row['dept_name'];
557
+	$smcFunc['db_free_result']($query);
558
+
559
+	// Now any departments this reply is attached to.
560
+	$query = $smcFunc['db_query']('', '
561
+		SELECT hdcrd.id_dept
562
+		FROM {db_prefix}helpdesk_cannedreplies_depts AS hdcrd
563
+		WHERE hdcrd.id_reply = {int:reply}',
564
+		array(
565
+			'reply' => $_REQUEST['reply'],
566
+		)
567
+	);
568
+	while ($row = $smcFunc['db_fetch_assoc']($query))
569
+		$context['canned_reply']['depts_selected'][] = $row['id_dept'];
570
+	$smcFunc['db_free_result']($query);
571
+
572
+	checkSubmitOnce('register');
573
+
574
+	$editorOptions = array(
575
+		'id' => 'shd_canned_reply',
576
+		'value' => $context['canned_reply']['body'],
577
+		'labels' => array(
578
+			'post_button' => $txt['shd_admin_cannedreplies_editreply'],
579
+		),
580
+		'preview_type' => 0,
581
+		'width' => '70%',
582
+		'disable_smiley_box' => false,
583
+	);
584
+	create_control_richedit($editorOptions);
585
+	$context['post_box_name'] = $editorOptions['id'];
586
+}
587
+
588
+function shd_admin_canned_savereply()
589
+{
590
+	global $context, $smcFunc, $sourcedir, $txt;
591
+
592
+	checkSession('request');
593
+
594
+	require_once($sourcedir . '/Subs-Editor.php');
595
+	require_once($sourcedir . '/Subs-Post.php');
596
+
597
+	// If we're deleting this reply, do it first and get it out the way.
598
+	if (!empty($_POST['delete']))
599
+	{
600
+		$_REQUEST['reply'] = isset($_REQUEST['reply']) ? (int) $_REQUEST['reply'] : 0;
601
+		if ($_REQUEST['reply'] > 0)
602
+		{
603
+			// 1. Get the current position.
604
+			$query = $smcFunc['db_query']('', '
605
+				SELECT reply_order
606
+				FROM {db_prefix}helpdesk_cannedreplies
607
+				WHERE id_reply = {int:reply}',
608
+				array(
609
+					'reply' => $_REQUEST['reply'],
610
+				)
611
+			);
612
+			if ($smcFunc['db_num_rows']() == 0)
613
+				redirectexit('action=admin;area=helpdesk_cannedreplies');
614
+			list($old_pos) = $smcFunc['db_fetch_row']($query);
615
+			$smcFunc['db_free_result']($query);
616
+			// 2. Delete the reply itself.
617
+			$smcFunc['db_query']('', '
618
+				DELETE FROM {db_prefix}helpdesk_cannedreplies
619
+				WHERE id_reply = {int:reply}',
620
+				array(
621
+					'reply' => $_REQUEST['reply'],
622
+				)
623
+			);
624
+			// 3. Shunt the rest up one.
625
+			$smcFunc['db_query']('', '
626
+				UPDATE {db_prefix}helpdesk_cannedreplies
627
+				SET reply_order = reply_order - 1
628
+				WHERE reply_order > {int:old_pos}',
629
+				array(
630
+					'old_pos' => $old_pos,
631
+				)
632
+			);
633
+			// 4. Delete any attached departments.
634
+			$smcFunc['db_query']('', '
635
+				DELETE FROM {db_prefix}helpdesk_cannedreplies_depts
636
+				WHERE id_reply = {int:reply}',
637
+				array(
638
+					'reply' => $_REQUEST['reply'],
639
+				)
640
+			);
641
+		}
642
+		redirectexit('action=admin;area=helpdesk_cannedreplies');
643
+	}
644
+
645
+	if (empty($_REQUEST['reply']))
646
+		fatal_lang_error('shd_admin_cannedreplies_thereplyisalie', false);
647
+
648
+	$_POST['title'] = isset($_POST['title']) ? strtr($smcFunc['htmlspecialchars']($_POST['title']), array("\r" => '', "\n" => '', "\t" => '')) : '';
649
+	if (empty($_POST['title']))
650
+		fatal_lang_error('shd_admin_cannedreplies_notitle', false);
651
+
652
+	$_REQUEST['shd_canned_reply'] = isset($_POST['shd_canned_reply']) ? $_POST['shd_canned_reply'] : '';
653
+
654
+	// If we came from WYSIWYG, we need to convert from HTML to bbc, then unhtml it.
655
+	if (!empty($_REQUEST['shd_canned_reply_mode']))
656
+	{
657
+		$_REQUEST['shd_canned_reply'] = un_htmlspecialchars(html_to_bbc($_REQUEST['shd_canned_reply']));
658
+		$_POST['shd_canned_reply'] = $_REQUEST['shd_canned_reply'];
659
+	}
660
+
661
+	if ($smcFunc['htmltrim']($smcFunc['htmlspecialchars']($_POST['shd_canned_reply']), ENT_QUOTES) === '')
662
+		fatal_lang_error('shd_admin_cannedreplies_nobody', false);
663
+
664
+	$_POST['shd_canned_reply'] = $smcFunc['htmlspecialchars']($_POST['shd_canned_reply'], ENT_QUOTES);
665
+	preparsecode($_POST['shd_canned_reply']);
666
+
667
+	// Now clean up the rest of the stuff.
668
+	$_POST['vis_user'] = !empty($_POST['vis_user']) ? 1 : 0;
669
+	$_POST['vis_staff'] = !empty($_POST['vis_staff']) ? 1 : 0;
670
+	$_POST['active'] = !empty($_POST['active']) ? 1 : 0;
671
+
672
+	// Verify the destination category exists.
673
+	if (!isset($_POST['cat']))
674
+		fatal_lang_error('shd_admin_cannedreplies_thecatisalie', false);
675
+
676
+	$query = $smcFunc['db_query']('', '
677
+		SELECT cat_name
678
+		FROM {db_prefix}helpdesk_cannedreplies_cats
679
+		WHERE id_cat = {int:cat}',
680
+		array(
681
+			'cat' => (int) $_REQUEST['cat'],
682
+		)
683
+	);
684
+	if ($smcFunc['db_num_rows']($query) == 0)
685
+	{
686
+		$smcFunc['db_free_result']($query);
687
+		fatal_lang_error('shd_admin_cannedreplies_thecatisalie', false);
688
+	}
689
+	$smcFunc['db_free_result']($query);
690
+
691
+	// Lastly, figure out what departments we're doing.
692
+	$depts_insert = array();
693
+	$query = $smcFunc['db_query']('', '
694
+		SELECT id_dept
695
+		FROM {db_prefix}helpdesk_depts
696
+		ORDER BY dept_order');
697
+	while ($row = $smcFunc['db_fetch_assoc']($query))
698
+		if (!empty($_POST['dept_' . $row['id_dept']]))
699
+			$depts_insert[] = $row['id_dept'];
700
+	$smcFunc['db_free_result']($query);
701
+
702
+	checkSubmitOnce('check');
703
+
704
+	if ($_REQUEST['reply'] == 'new')
705
+	{
706
+		// 1. Get the next reply order
707
+		$query = $smcFunc['db_query']('', '
708
+			SELECT MAX(reply_order)
709
+			FROM {db_prefix}helpdesk_cannedreplies');
710
+		list($current_max) = $smcFunc['db_fetch_row']($query);
711
+		$smcFunc['db_free_result']($query);
712
+
713
+		// 2. Insert the row.
714
+		$smcFunc['db_insert']('insert',
715
+			'{db_prefix}helpdesk_cannedreplies',
716
+			array(
717
+				'id_cat' => 'int', 'title' => 'string', 'body' => 'string',
718
+				'vis_user' => 'int', 'vis_staff' => 'int', 'reply_order' => 'int', 'active' => 'int',
719
+			),
720
+			array(
721
+				$_POST['cat'], $_POST['title'], $_POST['shd_canned_reply'],
722
+				$_POST['vis_user'], $_POST['vis_staff'], (int) $current_max + 1, $_POST['active'],
723
+			),
724
+			array(
725
+				'id_cat',
726
+			)
727
+		);
728
+
729
+		// 3. Insert the departments.
730
+		$reply_id = $smcFunc['db_insert_id']('{db_prefix}helpdesk_cannedreplies', 'id_reply');
731
+		if (empty($reply_id))
732
+			fatal_lang_error('shd_admin_cannedreplies_notcreated', false);
733
+
734
+		$insert = array();
735
+		foreach ($depts_insert as $dept)
736
+			$insert[] = array($dept, $reply_id);
737
+
738
+		$smcFunc['db_insert']('insert',
739
+			'{db_prefix}helpdesk_cannedreplies_depts',
740
+			array(
741
+				'id_dept' => 'int', 'id_reply' => 'int',
742
+			),
743
+			$insert,
744
+			array(
745
+				'id_dept', 'id_reply',
746
+			)
747
+		);
748
+	}
749
+	else
750
+	{
751
+		// Verify it exists.
752
+		$query = $smcFunc['db_query']('', '
753
+			SELECT id_reply
754
+			FROM {db_prefix}helpdesk_cannedreplies
755
+			WHERE id_reply = {int:reply}',
756
+			array(
757
+				'reply' => $_REQUEST['reply'],
758
+			)
759
+		);
760
+		if ($smcFunc['db_num_rows']($query) == 0)
761
+			fatal_lang_error('shd_admin_cannedreplies_thereplyisalie', false);
762
+		$smcFunc['db_free_result']($query);
763
+
764
+		// We're updating, apparently.
765
+		$smcFunc['db_query']('', '
766
+			UPDATE {db_prefix}helpdesk_cannedreplies
767
+			SET title = {string:title},
768
+				body = {string:body},
769
+				vis_user = {int:vis_user},
770
+				vis_staff = {int:vis_staff},
771
+				active = {int:active}
772
+			WHERE id_reply = {int:reply}',
773
+			array(
774
+				'reply' => $_REQUEST['reply'],
775
+				'title' => $_POST['title'],
776
+				'body' => $_POST['shd_canned_reply'],
777
+				'vis_user' => $_POST['vis_user'],
778
+				'vis_staff' => $_POST['vis_staff'],
779
+				'active' => $_POST['active'],
780
+			)
781
+		);
782
+
783
+		// Sort out departments. Nuke the existing ones first.
784
+		$smcFunc['db_query']('', '
785
+			DELETE FROM {db_prefix}helpdesk_cannedreplies_depts
786
+			WHERE id_reply = {int:reply}',
787
+			array(
788
+				'reply' => $_REQUEST['reply'],
789
+			)
790
+		);
791
+
792
+		$insert = array();
793
+		foreach ($depts_insert as $dept)
794
+			$insert[] = array($dept, $_REQUEST['reply']);
795
+
796
+		$smcFunc['db_insert']('insert',
797
+			'{db_prefix}helpdesk_cannedreplies_depts',
798
+			array(
799
+				'id_dept' => 'int', 'id_reply' => 'int',
800
+			),
801
+			$insert,
802
+			array(
803
+				'id_dept', 'id_reply',
804
+			)
805
+		);
806
+	}
807
+
808
+	redirectexit('action=admin;area=helpdesk_cannedreplies');
809
+}
810
+
811
+?>
0 812
\ No newline at end of file
... ...
@@ -154,7 +154,7 @@ function shd_admin_dept_move()
154 154
 		)
155 155
 	);
156 156
 
157
-	redirectexit('action=admin;area=helpdesk_depts;' . $context['session_var'] . '=' . $context['session_id']);
157
+	redirectexit('action=admin;area=helpdesk_depts');
158 158
 }
159 159
 
160 160
 function shd_admin_create_dept()
... ...
@@ -63,6 +63,7 @@ function shd_ajax()
63 63
 		'quote' => 'shd_ajax_quote',
64 64
 		'assign' => 'shd_ajax_assign',
65 65
 		'assign2' => 'shd_ajax_assign2',
66
+		'canned' => 'shd_ajax_canned',
66 67
 	);
67 68
 
68 69
 	$context['ajax_return'] = array();
... ...
@@ -361,6 +362,94 @@ function shd_ajax_quote()
361 362
 	$context['ajax_raw'] = '<quote>' . $message . '</quote>';
362 363
 }
363 364
 
365
+/**
366
+ *	Collects a canned reply from the database and serves it via XML for insertion.
367
+ *
368
+ *	Operations:
369
+ *	- Session check; failing in a regular fashion (as opposed to normal return since we're using ;xml in the URL; the SMF handler can deal with that)
370
+ *	- Checks for a department number in the URL, validates access to that department then queries for the requested template.
371
+ *	- Call un_preparsecode to remove extraneous sanity encoding.
372
+ *	- Convert to SMF style BBC-to-HTML if using WYSIWYG
373
+ *	- Do other XML sanitising
374
+ *	- Return via $context['ajax_raw'] for {@link shd_ajax()} to output
375
+*/
376
+function shd_ajax_canned()
377
+{
378
+	global $modSettings, $user_info, $txt, $settings, $context;
379
+	global $sourcedir, $smcFunc;
380
+
381
+	loadLanguage('Post');
382
+	checkSession('get');
383
+
384
+	include_once($sourcedir . '/Subs-Post.php');
385
+
386
+	$_REQUEST['reply'] = !empty($_REQUEST['reply']) ? (int) $_REQUEST['reply'] : 0;
387
+	$message = '';
388
+	if (!empty($_REQUEST['reply']) && !empty($context['ticket_id']))
389
+	{
390
+		$query = shd_db_query('', '
391
+			SELECT hdt.id_member_started, hdt.id_dept, hdcr.body, hdcr.vis_user, hdcr.vis_staff
392
+			FROM {db_prefix}helpdesk_tickets AS hdt
393
+				INNER JOIN {db_prefix}helpdesk_cannedreplies_depts AS hdcrd ON (hdt.id_dept = hdcrd.id_dept)
394
+				INNER JOIN {db_prefix}helpdesk_cannedreplies AS hdcr ON (hdcrd.id_reply = hdcr.id_reply)
395
+			WHERE hdt.id_ticket = {int:ticket}
396
+				AND hdcr.id_reply = {int:reply}
397
+				AND hdcr.active = 1
398
+				AND {query_see_ticket}',
399
+			array(
400
+				'ticket' => $context['ticket_id'],
401
+				'reply' => $_REQUEST['reply'],
402
+			)
403
+		);
404
+		if ($smcFunc['db_num_rows']($query) == 0)
405
+		{
406
+			$smcFunc['db_free_result']($query);
407
+			return $context['ajax_raw'] = '<quote>' . $message . '</quote>';
408
+		}
409
+
410
+		$row = $smcFunc['db_fetch_assoc']($query);
411
+		$smcFunc['db_free_result']($query);
412
+
413
+		// Check ability to reply to this ticket. No ability to reply at all, no canned reply.
414
+		if (!shd_allowed_to('shd_reply_ticket_own', $row['id_dept']) && !shd_allowed_to('shd_reply_ticket_any', $row['id_dept']))
415
+			return $context['ajax_raw'] = '<quote>' . $message . '</quote>';
416
+
417
+		// Now check for can-reply-to-own (reply to any will pass this check correctly anyway)
418
+		if (!shd_allowed_to('shd_reply_ticket_any', $row['id_dept']) && shd_allowed_to('shd_reply_ticket_own', $row['id_dept']) && $row['id_member_started'] != $user_info['id'])
419
+			return $context['ajax_raw'] = '<quote>' . $message . '</quote>';
420
+
421
+		// Now verify the per-reply visibility. Only applies to non admins anyway...
422
+		if (!shd_allowed_to('admin_helpdesk', $row['id_dept']) && !$user_info['is_admin'])
423
+		{
424
+			if (shd_allowed_to('shd_staff', $row['id_dept']) && empty($row['vis_staff']))
425
+				return $context['ajax_raw'] = '<quote>' . $message . '</quote>';
426
+			elseif (!shd_allowed_to('shd_staff', $row['id_dept']) && empty($row['vis_user']))
427
+				return $context['ajax_raw'] = '<quote>' . $message . '</quote>';
428
+		}
429
+
430
+		$message = un_preparsecode($row['body']);
431
+
432
+		// Censor the message!
433
+		censorText($message);
434
+		$message = preg_replace('~<br ?/?' . '>~i', "\n", $row['body']);
435
+
436
+		// Make the body HTML if need be.
437
+		if (!empty($_REQUEST['mode']))
438
+		{
439
+			require_once($sourcedir . '/Subs-Editor.php');
440
+			$message = strtr($message, array('&lt;' => '#smlt#', '&gt;' => '#smgt#', '&amp;' => '#smamp#'));
441
+			$message = bbc_to_html($message);
442
+			$lb = '<br />';
443
+		}
444
+		else
445
+			$lb = "\n";
446
+	}
447
+
448
+	$message = strtr($message, array('&nbsp;' => '&#160;', '<' => '&lt;', '>' => '&gt;'));
449
+
450
+	$context['ajax_raw'] = '<quote>' . $message . '</quote>';
451
+}
452
+
364 453
 /**
365 454
  *	Returns the list of possible assignees for a ticket for AJAX assignment purposes.
366 455
  *
... ...
@@ -662,6 +662,8 @@ function shd_view_ticket()
662 662
 	$context['ticket_form']['num_replies'] = $context['ticket']['num_replies'];
663 663
 	$context['ticket_form']['disable_smileys'] = empty($modSettings['shd_allow_ticket_smileys']);
664 664
 	shd_posting_additional_options();
665
+	if ($context['can_reply'])
666
+		shd_load_canned_replies();
665 667
 
666 668
 	// Set up the fancy editor
667 669
 	shd_postbox(
... ...
@@ -788,6 +788,7 @@ function shd_post_reply()
788 788
 	);
789 789
 	$context['can_solve'] = (shd_allowed_to('shd_resolve_ticket_any', $ticketinfo['dept']) || (shd_allowed_to('shd_resolve_ticket_own', $ticketinfo['dept']) && $ticketinfo['starter_id'] == $user_info['id']));
790 790
 	shd_posting_additional_options();
791
+	shd_load_canned_replies();
791 792
 
792 793
 	// Ticket privacy
793 794
 	if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart')
... ...
@@ -1015,6 +1016,7 @@ function shd_save_reply()
1015 1016
 	$context['log_action'] = $new_reply ? 'newreply' : 'editreply';
1016 1017
 	$context['log_params']['subject'] = $context['ticket_form']['subject'];
1017 1018
 	shd_posting_additional_options();
1019
+	shd_load_canned_replies();
1018 1020
 
1019 1021
 	// Ticket privacy
1020 1022
 	if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart')
... ...
@@ -2025,4 +2027,48 @@ function shd_check_dependencies()
2025 2027
 
2026 2028
 	return '';
2027 2029
 }
2030
+
2031
+/**
2032
+ *	Loads the possible permutations of canned replies.
2033
+ *
2034
+ *	@since 2.0
2035
+*/
2036
+function shd_load_canned_replies()
2037
+{
2038
+	global $context, $smcFunc, $user_info;
2039
+
2040
+	if ($context['user']['is_admin'] || shd_allowed_to('admin_helpdesk', $context['shd_department']))
2041
+		$visible = '';
2042
+	elseif (shd_allowed_to('shd_staff', $context['shd_department']))
2043
+		$visible = '
2044
+			AND hdcr.vis_staff = 1';
2045
+	else
2046
+		$visible = '
2047
+			AND hdcr.vis_user = 1';
2048
+
2049
+	$context['canned_replies'] = array();
2050
+
2051
+	$query = $smcFunc['db_query']('', '
2052
+		SELECT hdcr.id_reply, hdcr.title, hdcrc.id_cat, hdcrc.cat_name
2053
+		FROM {db_prefix}helpdesk_cannedreplies AS hdcr
2054
+			INNER JOIN {db_prefix}helpdesk_cannedreplies_cats AS hdcrc ON (hdcr.id_cat = hdcrc.id_cat)
2055
+			INNER JOIN {db_prefix}helpdesk_cannedreplies_depts AS hdcrd ON (hdcrd.id_reply = hdcr.id_reply)
2056
+		WHERE hdcrd.id_dept = {int:dept}
2057
+			AND hdcr.active = 1' . $visible . '
2058
+		ORDER BY hdcrc.cat_order, hdcr.reply_order',
2059
+		array(
2060
+			'dept' => $context['shd_department'],
2061
+		)
2062
+	);
2063
+	while ($row = $smcFunc['db_fetch_assoc']($query))
2064
+	{
2065
+		if (!isset($context['canned_replies'][$row['id_cat']]))
2066
+			$context['canned_replies'][$row['id_cat']] = array(
2067
+				'name' => $row['cat_name'],
2068
+				'replies' => array(),
2069
+			);
2070
+		$context['canned_replies'][$row['id_cat']]['replies'][$row['id_reply']] = $row['title'];
2071
+	}
2072
+}
2073
+
2028 2074
 ?>
2029 2075
\ No newline at end of file
... ...
@@ -924,7 +924,7 @@ function shd_profile_link($name, $id = 0)
924 924
 /**
925 925
  *	Generate an image URL given the base filename.
926 926
  *
927
- *	As of 1.1, images can live either in the main Themes/default/images/simpledesk folder, or additionally in Themes/default/images/sd_plugins,
927
+ *	As of 2.0, images can live either in the main Themes/default/images/simpledesk folder, or additionally in Themes/default/images/sd_plugins,
928 928
  *	the latter of which is intended for plugins (the former is removed on SD uninstall, the latter is not)
929 929
  *
930 930
  *	It should only be used in cases where there is ambiguity over where the image may live, e.g. preferences, permissions UIs. If there is no
... ...
@@ -1952,6 +1952,11 @@ function shd_main_menu_admin($helpdesk_admin)
1952 1952
 			'href' => $scripturl . '?action=admin;area=helpdesk_options',
1953 1953
 			'show' => true,
1954 1954
 		),
1955
+		'cannedreplies' => array(
1956
+			'title' => $txt['shd_admin_cannedreplies'],
1957
+			'href' => $scripturl . '?action=admin;area=helpdesk_cannedreplies',
1958
+			'show' => true,
1959
+		),
1955 1960
 		'custom_fields' => array(
1956 1961
 			'title' => $txt['shd_admin_custom_fields'],
1957 1962
 			'href' => $scripturl . '?action=admin;area=helpdesk_customfield',
... ...
@@ -403,6 +403,14 @@ function shd_admin_bootstrap(&$admin_areas)
403 403
 						'notifications' => array($txt['shd_admin_options_notifications']),
404 404
 					),
405 405
 				),
406
+				'helpdesk_cannedreplies' => array(
407
+					'label' => $txt['shd_admin_cannedreplies'],
408
+					'file' => 'sd_source/SimpleDesk-Admin.php',
409
+					'icon' => 'shd/cannedreplies.png',
410
+					'function' => 'shd_admin_main',
411
+					'subsections' => array(
412
+					),
413
+				),
406 414
 				'helpdesk_customfield' => array(
407 415
 					'label' => $txt['shd_admin_custom_fields'],
408 416
 					'file' => 'sd_source/SimpleDesk-Admin.php',
... ...
@@ -0,0 +1,251 @@
1
+<?php
2
+// Version: 2.0 Anatidae; SimpleDesk's administration/canned replies area
3
+
4
+/**
5
+ *	Displays SimpleDesk's administration for canned replies, front page, creation and editing.
6
+ *
7
+ *	@package template
8
+ *	@since 2.0
9
+*/
10
+
11
+/**
12
+ *	Display the front page of the SimpleDesk departments.
13
+ *
14
+ *	@since 2.0
15
+*/
16
+function template_shd_cannedreplies_home()
17
+{
18
+	global $context, $settings, $txt, $modSettings, $scripturl;
19
+
20
+	echo '
21
+				<div class="tborder">
22
+					<div class="cat_bar grid_header">
23
+						<h3 class="catbg">
24
+							<img src="', $settings['default_images_url'], '/simpledesk/cannedreplies.png" class="icon" alt="*">
25
+							', $txt['shd_admin_cannedreplies_home'], '
26
+						</h3>
27
+					</div>
28
+					<p class="description">
29
+						', $txt['shd_admin_cannedreplies_homedesc'], '
30
+					</p>
31
+				</div>';
32
+
33
+	if (empty($context['canned_replies']))
34
+	{
35
+		echo '
36
+				<br />
37
+				<div class="tborder">
38
+					<div class="title_bar">
39
+						<h3 class="titlebg">
40
+							', $txt['shd_admin_cannedreplies_nocats'], '
41
+						</h3>
42
+					</div>
43
+				</div>';
44
+	}
45
+	else
46
+	{
47
+		foreach ($context['canned_replies'] as $cat_id => $cat)
48
+		{
49
+			echo '
50
+				<div class="tborder">
51
+					<br />
52
+					<div class="cat_bar grid_header">
53
+						<h3 class="catbg">
54
+							', $cat['name'], '
55
+							', !empty($cat['move_up']) ? ('<a href="' . $scripturl . '?action=admin;area=helpdesk_cannedreplies;sa=movecat;cat=' . $cat_id . ';direction=up;' . $context['session_var'] . '=' . $context['session_id'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/move_up.png" alt="' . $txt['shd_admin_move_up'] . '" title="' . $txt['shd_admin_move_up'] . '" /></a>') : '', '
56
+							', !empty($cat['move_down']) ? ('<a href="' . $scripturl . '?action=admin;area=helpdesk_cannedreplies;sa=movecat;cat=' . $cat_id . ';direction=down;' . $context['session_var'] . '=' . $context['session_id'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/move_down.png" alt="' . $txt['shd_admin_move_down'] . '" title="' . $txt['shd_admin_move_down'] . '" /></a>') : '', '
57
+							<a href="', $scripturl, '?action=admin;area=helpdesk_cannedreplies;sa=editcat;cat=' . $cat_id . ';', $context['session_var'], '=', $context['session_id'], '"><img src="', $settings['default_images_url'], '/simpledesk/edit.png" class="icon" alt="', $txt['shd_ticket_edit'],'" title="', $txt['shd_ticket_edit'], '" /></a>
58
+						</h3>
59
+					</div>
60
+					<table class="shd_ticketlist" cellspacing="0" width="100%">
61
+						<tr class="titlebg">
62
+							<td width="30%" class="shd_nowrap">', $txt['shd_admin_cannedreplies_replyname'], '</td>
63
+							<td width="25%">', $txt['shd_departments'], '</td>
64
+							<td>', $txt['shd_admin_cannedreplies_isactive'], '</td>
65
+							<td>', $txt['shd_admin_cannedreplies_visibleto'], '</td>
66
+							<td colspan="3" width="1%" class="shd_nowrap">', $txt['shd_admin_custom_fields_move'], '</td>
67
+							<td colspan="2" width="1%" class="shd_nowrap">', $txt['shd_actions'], '</td>
68
+						</tr>';
69
+
70
+			if (empty($cat['replies']))
71
+			{
72
+				$use_bg2 = false;
73
+				echo '
74
+						<tr class="windowbg2">
75
+							<td colspan="9" class="centertext">', $txt['shd_admin_cannedreplies_emptycat'], '</td>
76
+						</tr>';
77
+			}
78
+			else
79
+			{
80
+				$use_bg2 = true;
81
+				foreach ($cat['replies'] as $reply)
82
+				{
83
+					echo '
84
+						<tr class="windowbg', $use_bg2 ? '2' : '', '">
85
+							<td>', $reply['title'], '</td>
86
+							<td>', $reply['depts'], '</td>
87
+							<td><img src="', $settings['default_images_url'], '/simpledesk/cf_', $reply['active_string'], '.png" alt="', $txt['shd_admin_custom_fields_' . $reply['active_string']], '" title="', $txt['shd_admin_custom_fields_' . $reply['active_string']], '" /></td>
88
+							<td>
89
+								', !empty($reply['vis_user']) ? '<img src="' . $settings['default_images_url'] . '/simpledesk/user.png" class="icon" alt="*" />' : '', '
90
+								', !empty($reply['vis_staff']) ? '<img src="' . $settings['default_images_url'] . '/simpledesk/staff.png" class="icon" alt="*" />' : '', '
91
+								<img src="', $settings['default_images_url'], '/simpledesk/admin.png" class="icon" alt="" />
92
+							</td>
93
+							<td>', !empty($reply['move_up']) ? ('<a href="' . $scripturl . '?action=admin;area=helpdesk_cannedreplies;sa=movereply;reply=' . $reply['id_reply'] . ';direction=up;' . $context['session_var'] . '=' . $context['session_id'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/move_up.png" alt="' . $txt['shd_admin_move_up'] . '" title="' . $txt['shd_admin_move_up'] . '" /></a>') : '', '</td>
94
+							<td>', !empty($reply['move_down']) ? ('<a href="' . $scripturl . '?action=admin;area=helpdesk_cannedreplies;sa=movereply;reply=' . $reply['id_reply'] . ';direction=down;' . $context['session_var'] . '=' . $context['session_id'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/move_down.png" alt="' . $txt['shd_admin_move_down'] . '" title="' . $txt['shd_admin_move_down'] . '" /></a>') : '', '</td>
95
+							<td>', $context['move_between_cats'] ? ('<a href="' . $scripturl . '?action=admin;area=helpdesk_cannedreplies;reply=' . $reply['id_reply'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/movedept.png" alt="' . $txt['shd_admin_cannedreplies_move_between_cat'] . '" title="' . $txt['shd_admin_cannedreplies_move_between_cat'] . '" /></a>') : '', '</td>
96
+							<td><a href="', $scripturl, '?action=admin;area=helpdesk_cannedreplies;sa=editreply;reply=' . $reply['id_reply'] . ';', $context['session_var'], '=', $context['session_id'], '"><img src="', $settings['default_images_url'], '/simpledesk/edit.png" class="icon" alt="', $txt['shd_ticket_edit'],'" title="', $txt['shd_ticket_edit'], '" /></a></td>
97
+							<td><a href="', $scripturl, '?action=admin;area=helpdesk_cannedreplies;sa=savereply;reply=' . $reply['id_reply'] . ';delete;', $context['session_var'], '=', $context['session_id'], '" onclick="return confirm(' . JavaScriptEscape($txt['shd_admin_cannedreplies_delete_confirm']). ');"><img src="', $settings['default_images_url'], '/simpledesk/delete.png" class="icon" alt="', $txt['shd_ticket_delete'],'" title="', $txt['shd_ticket_delete'], '" /></a></td>
98
+						</tr>';
99
+					$use_bg2 = !$use_bg2;
100
+				}
101
+			}
102
+
103
+			echo '
104
+						<tr class="windowbg', $use_bg2 ? '2' : '', '">
105
+							<td colspan="9" class="righttext">[<a href="', $scripturl, '?action=admin;area=helpdesk_cannedreplies;sa=createreply;cat=', $cat_id, '">', $txt['shd_admin_cannedreplies_addreply'], '</a>]</td>
106
+						</tr>
107
+					</table>
108
+				</div>';
109
+		}
110
+	}
111
+
112
+	echo '
113
+				<div class="flow_auto">
114
+					<div class="floatright">
115
+						<div class="additional_row">[<a href="', $scripturl, '?action=admin;area=helpdesk_cannedreplies;sa=createcat">', $txt['shd_admin_cannedreplies_createcat'], '</a>]</div>
116
+					</div>
117
+				</div>';
118
+}
119
+
120
+function template_shd_edit_canned_category()
121
+{
122
+	global $context, $settings, $txt, $modSettings, $scripturl;
123
+
124
+	echo '
125
+				<div class="tborder">
126
+					<div class="cat_bar">
127
+						<h3 class="catbg">
128
+							<img src="', $settings['default_images_url'], '/simpledesk/cannedreplies.png" class="icon" alt="*" />
129
+							', $txt['shd_admin_cannedreplies_home'], '
130
+						</h3>
131
+					</div>
132
+					<p class="description">
133
+						', $txt['shd_admin_cannedreplies_homedesc'], '
134
+					</p>
135
+				</div>
136
+				<div class="cat_bar grid_header">
137
+					<h3 class="catbg">
138
+						<img src="', $settings['default_images_url'], '/simpledesk/additional_information.png" alt="*" />
139
+						', $context['page_title'], '
140
+					</h3>
141
+				</div>
142
+				<div class="roundframe">
143
+					<form action="', $scripturl, '?action=admin;area=helpdesk_cannedreplies;sa=savecat" method="post">
144
+						<div class="content">
145
+							<dl class="settings">
146
+								<dt><strong>', $txt['shd_admin_cannedreplies_categoryname'], '</strong></dt>
147
+								<dd><input type="text" name="catname" id="catname" class="input_text" size="30" value="', $context['category_name'], '" /></dd>
148
+							</dl>
149
+						</div>
150
+						<input type="submit" value="', $context['page_title'], '" onclick="return submitThisOnce(this);" accesskey="s" class="button_submit" />';
151
+
152
+	if ($_REQUEST['cat'] != 'new')
153
+		echo '
154
+						<input type="submit" name="delete" value="', $txt['shd_admin_cannedreplies_deletecat'], '" onclick="return confirm(', JavaScriptEscape($txt['shd_admin_cannedreplies_delete_confirm']), ') && submitThisOnce(this);" class="button_submit" />';
155
+
156
+	echo '
157
+						<input type="hidden" name="cat" value="', $_REQUEST['cat'], '" />
158
+						<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
159
+						<input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />
160
+					</form>
161
+				</div>
162
+				<span class="lowerframe"><span></span></span>';
163
+}
164
+
165
+function template_shd_edit_canned_reply()
166
+{
167
+	global $context, $settings, $txt, $modSettings, $scripturl;
168
+
169
+	$editor_context = &$context['controls']['richedit'][$context['post_box_name']];
170
+
171
+	echo '
172
+				<div class="tborder">
173
+					<div class="cat_bar">
174
+						<h3 class="catbg">
175
+							<img src="', $settings['default_images_url'], '/simpledesk/cannedreplies.png" class="icon" alt="*" />
176
+							', $txt['shd_admin_cannedreplies_home'], '
177
+						</h3>
178
+					</div>
179
+					<p class="description">
180
+						', $txt['shd_admin_cannedreplies_homedesc'], '
181
+					</p>
182
+				</div>
183
+				<form action="', $scripturl, '?action=admin;area=helpdesk_cannedreplies;sa=savereply" method="post">
184
+					<div class="cat_bar grid_header">
185
+						<h3 class="catbg">
186
+							<img src="', $settings['default_images_url'], '/simpledesk/additional_information.png" alt="*" />
187
+							', $context['page_title'], '
188
+						</h3>
189
+					</div>
190
+					<div class="roundframe">
191
+						<div class="content">
192
+							<dl class="permsettings cannedsettings">
193
+								<dt><strong>', $txt['shd_admin_cannedreplies_replytitle'], '</strong></dt>
194
+								<dd><input type="text" class="input_text" value="', $context['canned_reply']['title'], '" name="title" /></dd>
195
+								<dt><strong>', $txt['shd_admin_cannedreplies_content'], '</strong>
196
+								<dd>
197
+									<div id="bbcbox"></div>
198
+									<div id="smileybox"></div>',
199
+									template_control_richedit($context['post_box_name'], 'smileybox', 'bbcbox'), '
200
+								</dd>
201
+								<dt><strong>', $txt['shd_admin_cannedreplies_active'], '</strong></dt>
202
+								<dd><input type="checkbox" name="active" class="input_check"', !empty($context['canned_reply']['active']) ? ' checked="checked"' : '', ' />
203
+								<dt><strong>', $txt['shd_admin_cannedreplies_selectvisible'], '</strong></dt>
204
+								<dd>
205
+									<input type="checkbox" name="vis_user" class="input_check"', !empty($context['canned_reply']['vis_user']) ? ' checked="checked"' : '', ' /> <img src="', $settings['default_images_url'], '/simpledesk/user.png" class="icon" alt="', $txt['shd_admin_custom_field_users'], '" title="', $txt['shd_admin_custom_field_users'], '">
206
+									<input type="checkbox" name="vis_staff" class="input_check"', !empty($context['canned_reply']['vis_staff']) ? ' checked="checked"' : '', ' /> <img src="', $settings['default_images_url'], '/simpledesk/staff.png" class="icon" alt="', $txt['shd_admin_custom_field_staff'], '" title="', $txt['shd_admin_custom_field_staff'], '">
207
+									<input type="checkbox" name="vis_admin" class="input_check" checked="checked" disabled="disabled"> <img src="', $settings['default_images_url'], '/simpledesk/admin.png" class="icon" alt="', $txt['shd_admin_custom_field_admins'], '" title="', $txt['shd_admin_custom_field_admins'], '">
208
+								</dd>
209
+							</dl>
210
+						</div>
211
+					</div>
212
+					<span class="lowerframe"><span></span></span>
213
+					<br />
214
+					<div class="cat_bar grid_header">
215
+						<h3 class="catbg">
216
+							<img src="', $settings['default_images_url'], '/simpledesk/departments.png" alt="*" />
217
+							', $txt['shd_admin_cannedreplies_departments'], '
218
+						</h3>
219
+					</div>
220
+					<div class="roundframe">
221
+						<div class="content">
222
+							<dl class="permsettings cannedsettings">';
223
+
224
+	foreach ($context['canned_reply']['depts_available'] as $dept_id => $dept_name)
225
+	{
226
+		echo '
227
+								<dt><strong>', $dept_name, '</strong></dt>
228
+								<dd><input type="checkbox" name="dept_', $dept_id, '"', in_array($dept_id, $context['canned_reply']['depts_selected']) ? ' checked="checked"' : '', ' class="input_check" /></dd>';
229
+	}
230
+
231
+	echo '
232
+							</dl>
233
+						</div>
234
+					</div>
235
+					<span class="lowerframe"><span></span></span>
236
+					<br />
237
+					<input type="submit" value="', isset($editor_context['labels']['post_button']) ? $editor_context['labels']['post_button'] : $txt['save'], '" tabindex="', $context['tabindex']++, '" accesskey="s" class="button_submit" />';
238
+
239
+	if ($context['canned_reply']['id'] != 'new')
240
+		echo '
241
+					<input type="submit" name="delete" value="', $txt['shd_admin_cannedreplies_deletereply'], '" onclick="return confirm(', JavaScriptEscape($txt['shd_admin_cannedreplies_deletereply_confirm']), ') && submitThisOnce(this);" class="button_submit" />';
242
+
243
+	echo '
244
+					<input type="hidden" name="', $context['session_var'], '" value="', $context['session_id'], '" />
245
+					<input type="hidden" name="seqnum" value="', $context['form_sequence_number'], '" />
246
+					<input type="hidden" name="reply" value="', $context['canned_reply']['id'], '" />
247
+					<input type="hidden" name="cat" value="', $context['canned_reply']['cat'], '" />
248
+				</form>
249
+				<br />';
250
+}
251
+?>
0 252
\ No newline at end of file
... ...
@@ -804,7 +804,7 @@ function template_viewreplies()
804 804
 							<br /><br />';
805 805
 
806 806
 		// Custom fields for replies!
807
-		if (!empty($context['custom_fields_replies']))
807
+		if (!empty($context['custom_fields_replies'][$reply['id']))
808 808
 		{
809 809
 			echo '
810 810
 							<hr />';
... ...
@@ -532,6 +532,47 @@ function template_ticket_postbox()
532 532
 
533 533
 }
534 534
 
535
+function template_ticket_cannedreplies()
536
+{
537
+	global $context, $txt;
538
+
539
+	if (empty($context['canned_replies']))
540
+		return;
541
+
542
+	echo '
543
+					<div id="canned_replies" style="display:none;">
544
+						<div style="font-weight:bold; padding: 0.5em;">', $txt['canned_replies'], '</div>
545
+						<select id="canned_replies_select">
546
+							<option value="0">', $txt['canned_replies_select'], '</option>';
547
+
548
+	foreach ($context['canned_replies'] as $cat_id => $cat_details)
549
+	{
550
+		echo '
551
+							<optgroup label="', $cat_details['name'], '">';
552
+
553
+		foreach ($cat_details['replies'] as $reply_id => $reply_title)
554
+			echo '
555
+								<option value="', $reply_id, '">', $reply_title, '</option>';
556
+
557
+		echo '
558
+							</optgroup>';
559
+	}
560
+
561
+	echo '
562
+						</select>
563
+						<input type="button" class="button_submit" value="Go!" onclick="oCannedReplies.getReply();" />
564
+						<hr />
565
+					</div>
566
+					<script type="text/javascript"><!-- // --><![CDATA[
567
+					var oCannedReplies = new CannedReply({
568
+						iTicketId: ', $context['ticket_id'], ',
569
+						sScriptUrl: smf_scripturl,
570
+						sSessionVar: "', $context['session_var'], '",
571
+						sSessionId: "', $context['session_id'], '"
572
+					});					
573
+					// ]]></script>';
574
+}
575
+
535 576
 function template_ticket_footer()
536 577
 {
537 578
 	global $settings, $context, $txt;
... ...
@@ -668,7 +709,12 @@ function template_ticket_additional_options()
668 709
 
669 710
 		echo '
670 711
 							</dd>
671
-						</dl>
712
+						</dl>';
713
+
714
+	// Canned replies
715
+	template_ticket_cannedreplies();
716
+
717
+	echo '
672 718
 					</div>
673 719
 					<script type="text/javascript"><!-- // --><![CDATA[
674 720
 	var oAttach = new shd_attach_select({
675 721