Add a 5th ticket block option, cleaning up how we handle that option Add On hold as a ticket status (Fixes #77)
jdarwood007

jdarwood007 commited on 2019-02-23 11:56:47
Showing 11 changed files, with 192 additions and 9 deletions.

... ...
@@ -69,6 +69,7 @@ $txt['shd_status_3'] = 'Resolved/Closed';
69 69
 $txt['shd_status_4'] = 'Referred to Supervisor';
70 70
 $txt['shd_status_5'] = 'Escalated - Urgent';
71 71
 $txt['shd_status_6'] = 'Deleted';
72
+$txt['shd_status_7'] = 'On Hold';
72 73
 //@}
73 74
 
74 75
 //! @name Headings, for the helpdesk listing pages
... ...
@@ -80,6 +81,7 @@ $txt['shd_status_3_heading'] = 'Closed Tickets';
80 81
 $txt['shd_status_4_heading'] = 'Tickets Referred to Supervisor';
81 82
 $txt['shd_status_5_heading'] = 'Urgent Tickets';
82 83
 $txt['shd_status_6_heading'] = 'Recycled Tickets';
84
+$txt['shd_status_7_heading'] = 'On Hold Tickets';
83 85
 $txt['shd_status_assigned_heading'] = 'Assigned to Me';
84 86
 $txt['shd_status_withdeleted_heading'] = 'Tickets with Deleted Replies';
85 87
 //@}
... ...
@@ -229,6 +231,7 @@ $txt['shd_ticket_replies'] = 'Replies';
229 231
 $txt['shd_ticket_staff'] = 'Staff member';
230 232
 $txt['shd_ticket_attachments'] = 'Attachments';
231 233
 $txt['shd_ticket_reply_number'] = 'Reply <strong>#%s</strong>'; // 'Reply #34'
234
+$txt['shd_ticket_hold'] = 'Ticket On-Hold';
232 235
 $txt['shd_ticket'] = 'Ticket';
233 236
 $txt['shd_reply_written'] = 'Reply written %s'; // 'Reply written Today at 04:12:29 pm',  'Reply written January 5 2009 04:12:29 pm'
234 237
 $txt['shd_never'] = 'Never';
... ...
@@ -161,6 +161,7 @@ $txt['shd_block_order_1'] = 'Tickets Block: 1st position';
161 161
 $txt['shd_block_order_2'] = 'Tickets Block: 2nd position';
162 162
 $txt['shd_block_order_3'] = 'Tickets Block: 3rd position';
163 163
 $txt['shd_block_order_4'] = 'Tickets Block: 4th position';
164
+$txt['shd_block_order_5'] = 'Tickets Block: 5th position';
164 165
 $txt['shd_block_order_note'] = 'Specify the default order of blocks';
165 166
 //@}
166 167
 
... ...
@@ -95,6 +95,11 @@ $txt['permissionname_shd_assign_ticket_own'] = 'To themselves';
95 95
 $txt['permissionname_shd_assign_ticket_any'] = 'Any staff member';
96 96
 //@}
97 97
 
98
+//! @name Ticket modification: Ticket Hold
99
+//@{
100
+$txt['permissionname_shd_alter_hold'] = 'Alter Ticket Hold';
101
+//@}
102
+
98 103
 //! @name Ticket emails: monitoring/ignoring
99 104
 //@{
100 105
 $txt['permissionname_shd_monitor_ticket'] = 'Monitor a ticket';
... ...
@@ -400,10 +400,11 @@ function shd_modify_display_options($return_config)
400 400
 		array('check', 'shd_disable_unread', 'subtext' => $txt['shd_disable_unread_note']),
401 401
 		array('check', 'shd_disable_boardint', 'subtext' => $txt['shd_disable_boardint_note']),
402 402
 		'',
403
-		array('select', 'shd_block_order_1', array('assigned' => $txt['shd_status_assigned_heading'], 'new' => $txt['shd_status_' . TICKET_STATUS_NEW . '_heading'], 'staff' => $txt['shd_status_' . TICKET_STATUS_PENDING_STAFF . '_heading'], 'user' => $txt['shd_status_' . TICKET_STATUS_PENDING_USER . '_heading']), 'subtext' => $txt['shd_block_order_note']),
404
-		array('select', 'shd_block_order_2', array('new' => $txt['shd_status_' . TICKET_STATUS_NEW . '_heading'], 'staff' => $txt['shd_status_' . TICKET_STATUS_PENDING_STAFF . '_heading'], 'user' => $txt['shd_status_' . TICKET_STATUS_PENDING_USER . '_heading'], 'assigned' => $txt['shd_status_assigned_heading']), 'subtext' => $txt['shd_block_order_note']),
405
-		array('select', 'shd_block_order_3', array('staff' => $txt['shd_status_' . TICKET_STATUS_PENDING_STAFF . '_heading'], 'user' => $txt['shd_status_' . TICKET_STATUS_PENDING_USER . '_heading'], 'assigned' => $txt['shd_status_assigned_heading'], 'new' => $txt['shd_status_' . TICKET_STATUS_NEW . '_heading']), 'subtext' => $txt['shd_block_order_note']),
406
-		array('select', 'shd_block_order_4', array('user' => $txt['shd_status_' . TICKET_STATUS_PENDING_USER . '_heading'], 'assigned' => $txt['shd_status_assigned_heading'], 'new' => $txt['shd_status_' . TICKET_STATUS_NEW . '_heading'], 'staff' => $txt['shd_status_' . TICKET_STATUS_PENDING_STAFF . '_heading']), 'subtext' => $txt['shd_block_order_note']),
403
+		array('select', 'shd_block_order_1', shd_block_order_options('assigned'), 'subtext' => $txt['shd_block_order_note']),
404
+		array('select', 'shd_block_order_2', shd_block_order_options('new'), 'subtext' => $txt['shd_block_order_note']),
405
+		array('select', 'shd_block_order_3', shd_block_order_options('staff'), 'subtext' => $txt['shd_block_order_note']),
406
+		array('select', 'shd_block_order_4', shd_block_order_options('user'), 'subtext' => $txt['shd_block_order_note']),
407
+		array('select', 'shd_block_order_5', shd_block_order_options('hold'), 'subtext' => $txt['shd_block_order_note']),
407 408
 
408 409
 	);
409 410
 	$context['settings_title'] = $txt['shd_admin_options_display'];
... ...
@@ -413,6 +414,37 @@ function shd_modify_display_options($return_config)
413 414
 	return $config_vars;
414 415
 }
415 416
 
417
+/**
418
+ * Show the block order options, allowing us to specify a option in the first order
419
+ *
420
+ *	@param string $first First option
421
+*/
422
+function shd_block_order_options($first_option = 'assigned')
423
+{
424
+	global $txt;
425
+
426
+	// All the possible block options.
427
+	$all_options = array(
428
+		'assigned' => $txt['shd_status_assigned_heading'],
429
+		'new' => $txt['shd_status_' . TICKET_STATUS_NEW . '_heading'],
430
+		'staff' => $txt['shd_status_' . TICKET_STATUS_PENDING_STAFF . '_heading'],
431
+		'user' => $txt['shd_status_' . TICKET_STATUS_PENDING_USER . '_heading'],
432
+		'hold' => $txt['shd_status_' . TICKET_STATUS_HOLD . '_heading']
433
+	);
434
+
435
+	call_integration_hook('shd_hook_block_order_options', array(&$all_options));
436
+
437
+	// Assign the first one.
438
+	$options = array();
439
+	$options[$first_option] = $all_options[$first_option];
440
+	unset($all_options[$first_option]);
441
+
442
+	foreach ($all_options as $id_opt => $opt_txt)
443
+		$options[$id_opt] = $opt_txt;
444
+
445
+	return $options;
446
+}
447
+
416 448
 /**
417 449
  *	General posting options for SimpleDesk.
418 450
  *
... ...
@@ -48,11 +48,14 @@ function shd_post_ticket()
48 48
 		shd_is_allowed_to('shd_new_ticket', $dept); // If we don't have a department, we will verify the ability in any department, and figure it out later.
49 49
 
50 50
 		$context['ticket_form'] = array( // yes, everything goes in here.
51
+			'is_new' => true,
52
+			'is_reply' => false,
51 53
 			'dept' => $dept,
52 54
 			'selecting_dept' => $context['shd_multi_dept'] && empty($dept),
53 55
 			'form_title' => $txt['shd_create_ticket'],
54 56
 			'form_action' => $scripturl . '?action=helpdesk;sa=saveticket',
55 57
 			'first_msg' => 0,
58
+			'last_msg' => 0,
56 59
 			'message' =>  '',
57 60
 			'subject' => '',
58 61
 			'ticket' => 0,
... ...
@@ -77,6 +80,7 @@ function shd_post_ticket()
77 80
 			'num_allowed_attachments' => empty($modSettings['attachmentNumPerPostLimit']) || $modSettings['shd_attachments_mode'] == 'ticket' ? -1 : $modSettings['attachmentNumPerPostLimit'],
78 81
 			'return_to_ticket' => isset($_REQUEST['goback']),
79 82
 			'disable_smileys' => !empty($_REQUEST['no_smileys']),
83
+			'on_hold' => false,
80 84
 		);
81 85
 
82 86
 		$context['can_solve'] = false;
... ...
@@ -90,11 +94,14 @@ function shd_post_ticket()
90 94
 			shd_fatal_lang_error('cannot_shd_edit_ticket');
91 95
 
92 96
 		$context['ticket_form'] = array( // yes, everything goes in here.
97
+			'is_new' => false,
98
+			'is_reply' => false,
93 99
 			'dept' => $dept,
94 100
 			'selecting_dept' => $context['shd_multi_dept'] && empty($dept),
95 101
 			'form_title' => $txt['shd_edit_ticket'],
96 102
 			'form_action' => $scripturl . '?action=helpdesk;sa=saveticket',
97 103
 			'first_msg' => $ticketinfo['id_first_msg'],
104
+			'last_msg' => $ticketinfo['id_last_msg'],
98 105
 			'message' => $ticketinfo['body'],
99 106
 			'subject' => $ticketinfo['subject'],
100 107
 			'ticket' => $context['ticket_id'],
... ...
@@ -119,6 +126,7 @@ function shd_post_ticket()
119 126
 			'num_allowed_attachments' => empty($modSettings['attachmentNumPerPostLimit']) || $modSettings['shd_attachments_mode'] == 'ticket' ? -1 : $modSettings['attachmentNumPerPostLimit'],
120 127
 			'return_to_ticket' => isset($_REQUEST['goback']),
121 128
 			'disable_smileys' => $ticketinfo['smileys_enabled'] == 0,
129
+			'on_hold' => $ticketinfo['status'] == TICKET_STATUS_HOLD,
122 130
 		);
123 131
 
124 132
 		$context['can_solve'] = shd_allowed_to('shd_resolve_ticket_any', $dept) || (shd_allowed_to('shd_resolve_ticket_own', $dept) && $ticketinfo['starter_id'] == $user_info['id']);
... ...
@@ -164,6 +172,9 @@ function shd_post_ticket()
164 172
 	else
165 173
 		$context['display_private'] = true;
166 174
 
175
+	// Can they alter the hold?
176
+	$context['can_alter_hold'] = !$context['ticket_form']['is_new'] && empty($ticketinfo['is_own']) && shd_allowed_to('shd_alter_hold', $dept);
177
+
167 178
 	if (!$new_ticket && !empty($ticketinfo))
168 179
 	{
169 180
 		$context['ticket_form'] += array(
... ...
@@ -381,10 +392,13 @@ function shd_save_ticket()
381 392
 	}
382 393
 
383 394
 	$context['ticket_form'] = array(
395
+		'is_new' => $new_ticket,
396
+		'is_reply' => false,
384 397
 		'dept' => isset($newdept) ? $newdept : $dept,
385 398
 		'form_title' => !$new_ticket ? $txt['shd_edit_ticket'] : $txt['shd_create_ticket'],
386 399
 		'form_action' => $scripturl . '?action=helpdesk;sa=saveticket',
387 400
 		'first_msg' => !$new_ticket ? $ticketinfo['id_first_msg'] : 0,
401
+		'last_msg' => !$new_ticket ? $ticketinfo['id_last_msg'] : 0,
388 402
 		'message' => $_POST['shd_message'],
389 403
 		'subject' => $_POST['subject'],
390 404
 		'ticket' => $context['ticket_id'],
... ...
@@ -445,6 +459,9 @@ function shd_save_ticket()
445 459
 	else
446 460
 		$context['display_private'] = true;
447 461
 
462
+	// Can they alter the hold?
463
+	$context['can_alter_hold'] = !$context['ticket_form']['is_new'] && empty($ticketinfo['is_own']) && shd_allowed_to('shd_alter_hold', $dept);
464
+
448 465
 	// Custom fields?
449 466
 	shd_load_custom_fields(true, $context['ticket_form']['ticket'], $context['ticket_form']['dept']);
450 467
 	list($missing_fields, $invalid_fields) = shd_validate_custom_fields('ticket', $context['ticket_form']['dept']);
... ...
@@ -603,6 +620,9 @@ function shd_save_ticket()
603 620
 				$context['log_params']['user_name'] = $context['ticket_form']['proxy'];
604 621
 			}
605 622
 
623
+			// Is the ticket on hold?
624
+			shd_ticket_on_hold(isset($_POST['ticket_hold']), $ticketOptions);
625
+
606 626
 			shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions);
607 627
 
608 628
 			// Update our nice ticket store with the ticket id
... ...
@@ -679,6 +699,9 @@ function shd_save_ticket()
679 699
 				));
680 700
 			}
681 701
 
702
+			// Is the ticket on hold?
703
+			shd_ticket_on_hold(isset($_POST['ticket_hold']), $ticketOptions);
704
+
682 705
 			// DOOOOOOOO EEEEEEEEEEET NAO!
683 706
 			shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions);
684 707
 
... ...
@@ -781,6 +804,8 @@ function shd_post_reply()
781 804
 	// So it's either our ticket and we can reply to our own, or we can reply to any because we're awesome
782 805
 	// or we're editing and we can haz such powarz
783 806
 	$context['ticket_form'] = array( // yes, everything goes in here.
807
+		'is_new' => $new_rely,
808
+		'is_reply' => true,
784 809
 		'dept' => $ticketinfo['dept'],
785 810
 		'form_title' => !empty($reply['id_msg']) ? $txt['shd_ticket_edit_reply'] : $txt['shd_reply_ticket'],
786 811
 		'form_action' => $scripturl . '?action=helpdesk;sa=savereply',
... ...
@@ -834,6 +859,9 @@ function shd_post_reply()
834 859
 	else
835 860
 		$context['display_private'] = true;
836 861
 
862
+	// Can they alter the hold?
863
+	$context['can_alter_hold'] = !$context['ticket_form']['is_new'] && empty($ticketinfo['is_own']) && shd_allowed_to('shd_alter_hold', $dept);
864
+
837 865
 	loadMemberData($ticketinfo['starter_id']);
838 866
 	if (loadMemberContext($ticketinfo['starter_id']))
839 867
 		$context['ticket_form']['member']['avatar'] = $memberContext[$ticketinfo['starter_id']]['avatar'];
... ...
@@ -1012,6 +1040,8 @@ function shd_save_reply()
1012 1040
 	}
1013 1041
 
1014 1042
 	$context['ticket_form'] = array(
1043
+		'is_new' => $new_reply,
1044
+		'is_reply' => true,
1015 1045
 		'dept' => $ticketinfo['dept'],
1016 1046
 		'form_title' => $new_reply ? $txt['shd_reply_ticket'] : $txt['shd_ticket_edit_reply'],
1017 1047
 		'form_action' => $scripturl . '?action=helpdesk;sa=savereply',
... ...
@@ -1048,6 +1078,7 @@ function shd_save_reply()
1048 1078
 		'reply' => $_POST['shd_message'],
1049 1079
 		'return_to_ticket' => isset($_REQUEST['goback']),
1050 1080
 		'disable_smileys' => !empty($_REQUEST['no_smileys']),
1081
+		'on_hold' => $ticketinfo['status'] == TICKET_STATUS_HOLD,
1051 1082
 	);
1052 1083
 	$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']));
1053 1084
 	$context['can_silent_update'] = $new_reply && shd_allowed_to('shd_silent_update', $ticketinfo['dept']);
... ...
@@ -1064,6 +1095,9 @@ function shd_save_reply()
1064 1095
 	else
1065 1096
 		$context['display_private'] = true;
1066 1097
 
1098
+	// Can they alter the hold?
1099
+	$context['can_alter_hold'] = !$context['ticket_form']['is_new'] && empty($ticketinfo['is_own']) && shd_allowed_to('shd_alter_hold', $dept);
1100
+
1067 1101
 	loadMemberData($ticketinfo['starter_id']);
1068 1102
 	if (loadMemberContext($ticketinfo['starter_id']))
1069 1103
 		$context['ticket_form']['member']['avatar'] = $memberContext[$ticketinfo['starter_id']]['avatar'];
... ...
@@ -424,6 +424,16 @@ function shd_main_helpdesk()
424 424
 				'required' => true,
425 425
 				'collapsed' => false,
426 426
 			),
427
+			'hold' => array(
428
+				'block_icon' => 'ticket_hold.png',
429
+				'title' => $txt['shd_status_' . TICKET_STATUS_HOLD . '_heading'],
430
+				'where' => 'hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_HOLD,
431
+				'display' => $is_staff,
432
+				'count' => shd_count_helpdesk_tickets('hold', $is_staff),
433
+				'columns' => shd_get_block_columns('hold'),
434
+				'required' => true,
435
+				'collapsed' => false,
436
+			),
427 437
 		),
428 438
 		'shd_home_view' => $is_staff ? 'staff' : 'user',
429 439
 	);
... ...
@@ -432,10 +442,13 @@ function shd_main_helpdesk()
432 442
 	if (isset($modSettings['shd_block_order_1'], $modSettings['shd_block_order_2'], $modSettings['shd_block_order_3'], $modSettings['shd_block_order_4']))
433 443
 	{
434 444
 		$context['ticket_block_order'] = array();
435
-		$unused = array('assigned' => 0, 'new' => 0, 'staff' => 0, 'user' => 0);
445
+		$unused = array('assigned' => 0, 'new' => 0, 'staff' => 0, 'user' => 0, 'hold' => 0);
436 446
 
437
-		for ($i = 1; $i <= 4; $i++)
447
+		for ($i = 1; $i <= 5; $i++)
438 448
 		{
449
+			// Is anything even set for this block?
450
+			if (!isset($modSettings['shd_block_order_' . $i]))
451
+				continue;
439 452
 			// Did we already use this?
440 453
 			if (in_array($modSettings['shd_block_order_' . $i], $context['ticket_block_order']))
441 454
 				continue;
... ...
@@ -451,7 +464,7 @@ function shd_main_helpdesk()
451 464
 			$context['ticket_block_order'][] = $u;
452 465
 	}
453 466
 	else
454
-		$context['ticket_block_order'] = array(1 => 'assigned', 2 => 'new', 3 => 'staff', 4 => 'user');
467
+		$context['ticket_block_order'] = array(1 => 'assigned', 2 => 'new', 3 => 'staff', 4 => 'user', 5 => 'hold');
455 468
 
456 469
 	if (!empty($context['shd_dept_name']) && $context['shd_multi_dept'])
457 470
 		$context['linktree'][] = array(
... ...
@@ -584,6 +597,16 @@ function shd_view_block()
584 597
 				'required' => true,
585 598
 				'collapsed' => false,
586 599
 			),
600
+			'hold' => array(
601
+				'block_icon' => 'ticket_hold.png',
602
+				'title' => $txt['shd_status_' . TICKET_STATUS_HOLD . '_heading'],
603
+				'where' => 'hdt.id_member_assigned != ' . $user_info['id'] . ' AND hdt.status = ' . TICKET_STATUS_HOLD,
604
+				'display' => $is_staff,
605
+				'count' => shd_count_helpdesk_tickets('hold', $is_staff),
606
+				'columns' => shd_get_block_columns('hold'),
607
+				'required' => true,
608
+				'collapsed' => false,
609
+			),
587 610
 		),
588 611
 		'shd_home_view' => $is_staff ? 'staff' : 'user',
589 612
 	);
... ...
@@ -1329,6 +1352,7 @@ function shd_get_block_columns($block)
1329 1352
 				'updated' => 22,
1330 1353
 				'actions' => 5,
1331 1354
 			);
1355
+		case 'hold':
1332 1356
 		case 'staff':
1333 1357
 			return array(
1334 1358
 				'ticket_id' => 8,
... ...
@@ -60,6 +60,7 @@ function shd_init()
60 60
 	define('TICKET_STATUS_WITH_SUPERVISOR', 4);
61 61
 	define('TICKET_STATUS_ESCALATED', 5);
62 62
 	define('TICKET_STATUS_DELETED', 6);
63
+	define('TICKET_STATUS_HOLD', 7);
63 64
 
64 65
 	define('TICKET_URGENCY_LOW', 0);
65 66
 	define('TICKET_URGENCY_MEDIUM', 1);
... ...
@@ -695,7 +696,8 @@ function shd_count_helpdesk_tickets($status = '', $is_staff = false)
695 696
 				$context['ticket_count'][TICKET_STATUS_PENDING_USER] +
696 697
 				$context['ticket_count'][TICKET_STATUS_WITH_SUPERVISOR] +
697 698
 				$context['ticket_count'][TICKET_STATUS_ESCALATED] +
698
-				$context['ticket_count']['assigned']
699
+				$context['ticket_count']['assigned'] +
700
+				($is_staff ? 0 : $context['ticket_count'][TICKET_STATUS_HOLD])
699 701
 			);
700 702
 		case 'assigned':
701 703
 			return $context['ticket_count']['assigned'];
... ...
@@ -711,6 +713,8 @@ function shd_count_helpdesk_tickets($status = '', $is_staff = false)
711 713
 			return $context['ticket_count'][TICKET_STATUS_DELETED];
712 714
 		case 'withdeleted':
713 715
 			return $context['ticket_count']['withdeleted'];
716
+		case 'hold':
717
+			return $context['ticket_count'][TICKET_STATUS_HOLD];
714 718
 		default:
715 719
 			return array_sum($context['ticket_count']) - $context['ticket_count']['withdeleted']; // since withdeleted is the only duplicate information, all the rest is naturally self-exclusive
716 720
 	}
... ...
@@ -77,6 +77,7 @@ function shd_load_all_permission_sets()
77 77
 		'shd_alter_urgency_higher' => array(true, 'ticketactions', 'log_urgency_increase.png'),
78 78
 		'shd_alter_privacy' => array(true, 'ticketactions', 'log_markprivate.png'),
79 79
 		'shd_assign_ticket' => array(true, 'ticketactions', 'log_assign.png'),
80
+		'shd_alter_hold' => array(false, 'ticketactions', 'ticket_hold.png'),
80 81
 
81 82
 		'shd_access_recyclebin' => array(false, 'deletion', 'access_recyclebin.png'),
82 83
 		'shd_delete_ticket' => array(true, 'deletion', 'log_delete.png'),
... ...
@@ -182,6 +183,7 @@ function shd_load_role_templates()
182 183
 				'shd_alter_urgency_any' => ROLEPERM_ALLOW,
183 184
 				'shd_alter_privacy_any' => ROLEPERM_ALLOW,
184 185
 				'shd_assign_ticket_own' => ROLEPERM_ALLOW,
186
+				'shd_alter_hold' => ROLEPERM_ALLOW,
185 187
 				'shd_view_profile_any' => ROLEPERM_ALLOW,
186 188
 				'shd_view_profile_log_any' => ROLEPERM_ALLOW,
187 189
 				'shd_view_preferences_own' => ROLEPERM_ALLOW,
... ...
@@ -977,3 +977,73 @@ function shd_get_postable_depts()
977 977
 		}
978 978
 	}
979 979
 }
980
+
981
+/**
982
+ *	Set a ticket to on hold or restore to the proper status.
983
+ *
984
+ *	@param bool $on_hold (default true) Whether this ticket should be on hold or not.
985
+ *	@param array &$ticketOptions - a hash array by reference, stating one or more details necessary to change on a ticket:
986
+ *	<ul>
987
+ *	<li>id: Required in all cases, numeric ticket id that the edit relates to</li>
988
+ *	<li>subject: Optional string with the new subject in; if omitted no change will occur. If set, assumed to have been cleaned already (with $smcFunc['htmlspecialchars'] and strtr)</li>
989
+ *	<li>urgency: Optional integer with the new urgency in; if omitted no change will occur</li>
990
+ *	<li>status: Optional integer with the new status in; if omitted no change will occur</li>
991
+ *	<li>ssigned: Optional integer with the user id of assigned user; if omitted no change will occur (note, you would declare this as 0 to unassign a ticket - set to 0 is not omitted)</li>
992
+ *	<li>private: Optional boolean as to privacy of ticket: true = private, false = not private (note, you still declare this to change it)</li>
993
+ *	</ul>
994
+ *
995
+ *	@return bool True on success, false on failure.
996
+ *	@since 2.1
997
+*/
998
+function shd_ticket_on_hold($on_hold = false, &$ticketOptions)
999
+{
1000
+	global $context, $smcFunc;
1001
+
1002
+	$current_status = !isset($context['ticket_form']['status']) ? 0 : $context['ticket_form']['status'];
1003
+	$new_status = $current_status;
1004
+
1005
+	// If this is deleted or closed, you can't change the hold.  You also need to be staff.
1006
+	if ($current_status == TICKET_STATUS_DELETED || $current_status == TICKET_STATUS_CLOSED)
1007
+		return false;
1008
+
1009
+	// This is a issue.
1010
+	if (!isset($context['ticket_form']['last_msg']))
1011
+		shd_fatal_lang_error('Unable to find last_msg');
1012
+
1013
+	// Find the id_member of the last reply.
1014
+	$query = shd_db_query('', '
1015
+		SELECT id_msg, id_member
1016
+		FROM {db_prefix}helpdesk_ticket_replies
1017
+		WHERE id_ticket = {int:ticket}
1018
+			AND message_status = {int:msg_normal}
1019
+			AND id_msg = {int:last_msg}
1020
+		LIMIT 10',
1021
+		array(
1022
+			'ticket' => $context['ticket_id'],
1023
+			'msg_normal' => MSG_STATUS_NORMAL,
1024
+			'last_msg' => $context['ticket_form']['last_msg'],
1025
+		)
1026
+	);
1027
+
1028
+	$row = $smcFunc['db_fetch_assoc']($query);
1029
+	$smcFunc['db_free_result']($query);
1030
+
1031
+	// We want to make this on hold, this is simple.
1032
+	if ($on_hold)
1033
+		$new_status = TICKET_STATUS_HOLD;
1034
+	// No replies? It has to be NEW.
1035
+	elseif (empty($context['ticket_form']['num_replies']))
1036
+		$new_status = TICKET_STATUS_NEW;
1037
+	elseif (!empty($row['id_member']) && $context['ticket_form']['member']['id'] != $row['id_member'])
1038
+		$new_status = TICKET_STATUS_PENDING_USER;
1039
+	elseif (!empty($row['id_member']) && $context['ticket_form']['member']['id'] == $row['id_member'])
1040
+		$new_status = TICKET_STATUS_PENDING_STAFF;
1041
+	else
1042
+		return false;
1043
+
1044
+	// Hook may want to do something different here.
1045
+	call_integration_hook('shd_ticket_on_hold', array($current_status, &$new_status));
1046
+
1047
+	$ticketOptions['status'] = $new_status;
1048
+	return true;
1049
+}
980 1050
\ No newline at end of file
... ...
@@ -127,7 +127,15 @@ function template_ticket_info()
127 127
 							<li>
128 128
 								<img src="', $settings['default_images_url'], '/simpledesk/private.png" alt="" class="shd_smallicon">
129 129
 								', $txt['shd_ticket_privacy'], ': ', template_ticket_option('private'), '
130
-							</li>
130
+							</li>';
131
+
132
+	if (!empty($context['can_alter_hold']) && empty($context['ticket_form']['is_reply']))
133
+	echo '
134
+							<li>
135
+								<input name="ticket_hold" type="checkbox"', !empty($context['ticket_form']['on_hold']) ? ' checked="checked"' : '', '>', $txt['shd_ticket_hold'], '
136
+							</li>';
137
+
138
+	echo '
131 139
 						</ul>';
132 140
 
133 141
 	// Display ticket poster avatar?
134 142