! Auto closing core code ! Scheduled task being generated for midnight server time ! Minor cleanups for integration hooks
gruffen

gruffen commited on 2011-03-23 05:38:17
Showing 16 changed files, with 168 additions and 27 deletions.

... ...
@@ -105,15 +105,7 @@
105 105
 		}
106 106
 
107 107
 		// Now engage any hooks.
108
-		if (!empty($modSettings['shd_hook_profilemenu']))
109
-		{
110
-			$functions = explode(',', $modSettings['shd_hook_profilemenu']);
111
-			foreach ($functions as $function)
112
-			{
113
-				if (is_callable($function))
114
-					$function($profile_areas); // this should be picked up by reference in the called function or it won't do anything!
115
-			}
116
-		}
108
+		call_integration_hook('shd_hook_profilemenu', array(&$profile_areas));
117 109
 	}
118 110
 
119 111
 ]]></add>
... ...
@@ -420,6 +420,26 @@ $tables[] = array(
420 420
 
421 421
 // Oh joy, we've now made it to extra rows... (testing data)
422 422
 $rows = array();
423
+$rows[] = array(
424
+	'method' => 'replace',
425
+	'table_name' => '{db_prefix}scheduled_tasks',
426
+	'columns' => array(
427
+		'next_time' => 'int',
428
+		'time_offset' => 'int',
429
+		'time_regularity' => 'int',
430
+		'time_unit' => 'string',
431
+		'disabled' => 'int',
432
+		'task' => 'string',
433
+	),
434
+	'data' => array(
435
+		strtotime('tomorrow'),
436
+		0,
437
+		1,
438
+		'd',
439
+		0,
440
+		'simpledesk',
441
+	),
442
+);
423 443
 
424 444
 // Now we can add a new column to an existing table
425 445
 $columns = array();
... ...
@@ -38,6 +38,8 @@ $txt['core_settings_item_shd_desc'] = 'The helpdesk allows you to expand your fo
38 38
 //@{
39 39
 $txt['errortype_simpledesk'] = 'SimpleDesk';
40 40
 $txt['errortype_simpledesk_desc'] = 'Errors most likely related to SimpleDesk. Please report any such errors on www.simpledesk.net.';
41
+$txt['scheduled_task_simpledesk'] = 'SimpleDesk daily maintenance';
42
+$txt['scheduled_task_desc_simpledesk'] = 'Maintenance tasks and internal processing to be run daily for SimpleDesk. It is strongly not advised to disable this task.';
41 43
 //@}
42 44
 
43 45
 //! @name Items for the administration menu structure
... ...
@@ -199,6 +201,7 @@ $txt['shd_logopt_restore'] = 'Log tickets and replies being restored';
199 201
 $txt['shd_logopt_permadelete'] = 'Log tickets and replies being permadeleted';
200 202
 $txt['shd_logopt_relationships'] = 'Log any changes in ticket relationships';
201 203
 $txt['shd_logopt_split'] = 'Log splitting of a ticket into two tickets';
204
+$txt['shd_logopt_autoclose'] = 'Log tickets closed automatically by the helpdesk';
202 205
 
203 206
 $txt['shd_notify_send_to'] = 'Will be sent to';
204 207
 $txt['shd_notify_ticket_starter'] = 'the user who started the ticket (if set in their preferences)';
... ...
@@ -104,5 +104,7 @@ $txt['shd_log_newticketproxy'] = '&quot;<a href="{scripturl}?action=helpdesk;sa=
104 104
 
105 105
 $txt['shd_logpart_att_added'] = 'Files added';
106 106
 $txt['shd_logpart_att_removed'] = 'Files removed';
107
+
108
+$txt['shd_log_autoclose'] = '&quot;<a href="{scripturl}?action=helpdesk;sa=ticket;ticket={ticket}">{subject}</a>&quot; marked as <strong>resolved</strong> due to inactivity.';
107 109
 //@}
108 110
 ?>
109 111
\ No newline at end of file
... ...
@@ -72,7 +72,7 @@ function shd_admin_main()
72 72
 	);
73 73
 
74 74
 	// Int hooks - after we basically set everything up (so it's manipulatable by the hook, but before we do the last bits of finalisation)
75
-	call_integration_hook('shd_hook_hdadmin', array($subActions));
75
+	call_integration_hook('shd_hook_hdadmin', array(&$subActions));
76 76
 
77 77
 	// Make sure we can find a subaction. If not set, default to info
78 78
 	$_REQUEST['area'] = isset($_REQUEST['area']) && isset($subActions[$_REQUEST['area']]) ? $_REQUEST['area'] : 'helpdesk_info';
... ...
@@ -522,6 +522,7 @@ function shd_modify_standalone_options($return_config)
522 522
  *	<li>'shd_logopt_newposts' (checkbox) - if checked, a ticket's being creation and subsequent replies will be logged.</li>
523 523
  *	<li>'shd_logopt_editposts' (checkbox) - if checked, a ticket or its replies being edited will be logged.</li>
524 524
  *	<li>'shd_logopt_resolve' (checkbox) - if checked, a ticket's being closed and/or reopened will be logged.</li>
525
+ *	<li>'shd_logopt_autoclose' (checkbox) - if checked, tickets being closed by the helpdesk due to age will be logged.</li>
525 526
  *	<li>'shd_logopt_assign' (checkbox) - if checked, a ticket being assigned/reassigned/unassigned will be logged.</li>
526 527
  *	<li>'shd_logopt_privacy' (checkbox) - if checked, ticket privacy changes will be logged.</li>
527 528
  *	<li>'shd_logopt_urgency' (checkbox) - if checked, ticket urgency changes will be logged.</li>
... ...
@@ -550,10 +551,13 @@ function shd_modify_actionlog_options($return_config)
550 551
 		array('check', 'shd_logopt_newposts', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
551 552
 		array('check', 'shd_logopt_editposts', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
552 553
 		array('check', 'shd_logopt_resolve', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
554
+		array('check', 'shd_logopt_autoclose', 'disabled' => !empty($modSettings['shd_disable_action_log']) || empty($modSettings['shd_autoclose_tickets']) || empty($modSettings['shd_autoclose_tickets_days'])),
555
+		'',
553 556
 		array('check', 'shd_logopt_assign', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
554 557
 		array('check', 'shd_logopt_privacy', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
555 558
 		array('check', 'shd_logopt_urgency', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
556 559
 		array('check', 'shd_logopt_tickettopicmove', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
560
+		'',
557 561
 		array('check', 'shd_logopt_delete', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
558 562
 		array('check', 'shd_logopt_restore', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
559 563
 		array('check', 'shd_logopt_permadelete', 'disabled' => !empty($modSettings['shd_disable_action_log'])),
... ...
@@ -323,7 +323,6 @@ function shd_list_hooks()
323 323
 		'shd_hook_modpost', // functions to call when a ticket or reply is edited (since all kinds of things might be altered)
324 324
 		'shd_hook_assign', // functions to call when a ticket is assigned to someone
325 325
 		'shd_hook_buffer', // functions to call prior to the final page generation
326
-		'shd_hook_postingopts', // functions to call to augment the additional options on posting screen
327 326
 		'shd_hook_after_main', // functions to call after action=helpdesk has been evaluated but before template calls are made
328 327
 
329 328
 		// Menu hooks - called after the rest of menu configuration is done (meaning menu items may or may not exist depending on permissions)
... ...
@@ -289,7 +289,7 @@ function shd_commit_assignment($ticket, $assignment, $is_ajax = false)
289 289
 	);
290 290
 
291 291
 	// Int hooks - after we've set everything up but before we actually press the button
292
-	call_integration_hook('shd_hook_assign', array($ticket, $assignment));
292
+	call_integration_hook('shd_hook_assign', array(&$ticket, &$assignment));
293 293
 
294 294
 	shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions);
295 295
 
... ...
@@ -1869,8 +1869,6 @@ function shd_posting_additional_options()
1869 1869
 			'show' => !empty($context['can_solve']),
1870 1870
 		),
1871 1871
 	);
1872
-
1873
-	call_integration_hook('shd_hook_postingopts');
1874 1872
 }
1875 1873
 
1876 1874
 /**
... ...
@@ -90,7 +90,7 @@ function shd_profile_main($memID)
90 90
 	);
91 91
 
92 92
 	// Int hooks - after we basically set everything up (so it's manipulatable by the hook, but before we do the last bits of finalisation)
93
-	call_integration_hook('shd_hook_hdprofile', array($subActions, $memID));
93
+	call_integration_hook('shd_hook_hdprofile', array(&$subActions, &$memID));
94 94
 
95 95
 	// Make sure the menu is configured appropriately
96 96
 	$context['shd_profile_menu'][count($context['shd_profile_menu'])-1]['is_last'] = true;
... ...
@@ -30,7 +30,8 @@ if (!defined('SMF'))
30 30
 /**
31 31
  *	Container task for all the scheduled maintenance that SD can be asked to do.
32 32
  *
33
- *	- purge deleted tickets
33
+ *	- close older open tickets (if not replied to within a given number of days)
34
+ *	- purge deleted tickets (delete their contents aftet a given number of days of being already deleted)
34 35
  *
35 36
  *	@since 1.1
36 37
 */
... ...
@@ -39,15 +40,109 @@ function shd_scheduled()
39 40
 {
40 41
 	global $smcFunc, $modSettings;
41 42
 
43
+	shd_scheduled_close_tickets();
42 44
 	shd_scheduled_purge_tickets();
43 45
 	return true;
44 46
 }
45 47
 
48
+function shd_scheduled_close_tickets()
49
+{
50
+	global $modSettings, $smcFunc, $txt;
51
+
52
+	if (empty($modSettings['shd_autoclose_tickets']) || empty($modSettings['shd_autoclose_tickets_days']))
53
+		return;
54
+
55
+	@set_time_limit(600); // Ten minutes. Is a big job, possibly.
56
+
57
+	// 1. Get the list of tickets.
58
+	$query = $smcFunc['db_query']('', '
59
+		SELECT hdt.id_ticket, hdt.subject, hdt.id_member_started, hdt.id_member_updated, hdtr_last.poster_time
60
+		FROM {db_prefix}helpdesk_tickets AS hdt
61
+			INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
62
+		WHERE hdt.status IN ({array_int:open})
63
+			AND poster_time <= {int:old_time}',
64
+		array(
65
+			'open' => array(TICKET_STATUS_NEW, TICKET_STATUS_PENDING_STAFF, TICKET_STATUS_PENDING_USER),
66
+			'old_time' => time() - 86400 * $modSettings['shd_autoclose_tickets_days'],
67
+		)
68
+	);
69
+	$tickets = array();
70
+	$subjects = array();
71
+	$members = array();
72
+	while ($row = $smcFunc['db_fetch_assoc']($query))
73
+	{
74
+		$tickets[$row['id_ticket']] = $row['id_ticket'];
75
+		$subjects[$row['id_ticket']] = $row['subject'];
76
+		$members[] = $row['id_member_started'];
77
+		$members[] = $row['id_member_updated'];
78
+	}
79
+	$smcFunc['db_free_result']($query);
80
+
81
+	// Any to do?
82
+	if (empty($tickets))
83
+		return;
84
+
85
+	// 2. Update the tickets.
86
+	$query = $smcFunc['db_query']('', '
87
+		UPDATE {db_prefix}helpdesk_tickets
88
+		SET status = {int:closed}
89
+		WHERE id_ticket IN ({array_int:tickets})',
90
+		array(
91
+			'closed' => TICKET_STATUS_CLOSED,
92
+			'tickets' => $tickets,
93
+		)
94
+	);
95
+
96
+	// 3. Update the log if appropriate. Normally we would call shd_log_action(), however here... we might be doing a lot, so instead, we do it manually ourselves.
97
+	if (empty($modSettings['shd_disable_action_log']) && !empty($modSettings['shd_logopt_autoclose']))
98
+	{
99
+		$rows = array();
100
+		$time = time();
101
+		foreach ($tickets as $ticket)
102
+		{
103
+			$rows[] = array(
104
+				$time, // log_time
105
+				0, // id_member
106
+				'', // ip
107
+				'autoclose', // action
108
+				$ticket, // id_ticket
109
+				0, // id_msg
110
+				serialize(array(
111
+					'subject' => $subjects[$ticket],
112
+					'auto' => true, // indicate to the action log that this is the case
113
+				)),
114
+			);
115
+		}
116
+
117
+		$smcFunc['db_insert']('',
118
+			'{db_prefix}helpdesk_log_action',
119
+			array(
120
+				'log_time' => 'int', 'id_member' => 'int', 'ip' => 'string-16', 'action' => 'string', 'id_ticket' => 'int', 'id_msg' => 'int', 'extra' => 'string-65534',
121
+			),
122
+			$rows,
123
+			array('id_action')
124
+		);
125
+	}
126
+
127
+	// 4. If caching is enabled, make sure to purge the cache for members so their number of tickets will be recalculated.
128
+	// No need to dump all SD cache items though, though we have to get all those whose tickets were affected, plus all staff.
129
+	if (!empty($modSettings['cache_enable']))
130
+	{
131
+		$members = array_merge($members, shd_members_allowed_to('shd_staff'));
132
+		$members = array_unique($members);
133
+		foreach ($members as $member)
134
+		{
135
+			cache_put_data('shd_active_tickets_' . $member, null, 0);
136
+			cache_put_data('shd_ticket_count_' . $member, null, 0);
137
+		}
138
+	}
139
+}
140
+
46 141
 function shd_scheduled_purge_tickets()
47 142
 {
48 143
 	global $smcFunc, $modSettings;
49 144
 
50
-	if (empty($modSettings['shd_purge_tickets']) || empty($modSettings['shd_purge_tickets_days']))
145
+	if (empty($modSettings['shd_autopurge_tickets']) || empty($modSettings['shd_autopurge_tickets_days']))
51 146
 		return;
52 147
 
53 148
 	@set_time_limit(600); // Ten minutes. Is a big job, possibly.
... ...
@@ -89,7 +184,7 @@ function shd_scheduled_purge_tickets()
89 184
 	$smcFunc['db_free_result']($query);
90 185
 
91 186
 	// 3. Purge that list of threads too new to be deleted
92
-	$del_time = time() - (86400 * $modSettings['shd_purge_tickets_days']);
187
+	$del_time = time() - (86400 * $modSettings['shd_autopurge_tickets_days']);
93 188
 	foreach ($tickets as $k => $v)
94 189
 	{
95 190
 		if ($v == 0 || $v > $del_time)
... ...
@@ -1257,7 +1257,10 @@ function shd_display_btn_mvtopic(&$normal_buttons)
1257 1257
 */
1258 1258
 function scheduled_simpledesk()
1259 1259
 {
1260
-	global $sourcedir;
1260
+	global $sourcedir, $modSettings;
1261
+
1262
+	if (empty($modSettings['helpdesk_active']))
1263
+		return;
1261 1264
 
1262 1265
 	require($sourcedir . '/sd_source/SimpleDesk-Scheduled.php');
1263 1266
 	return shd_scheduled();
... ...
@@ -1293,7 +1296,7 @@ function shd_init_actions(&$actionArray)
1293 1296
 		shd_load_language('SimpleDeskAdmin');
1294 1297
 
1295 1298
 	// Now engage any SD specific hooks.
1296
-	call_integration_hook('shd_hook_actions', array($actionArray));
1299
+	call_integration_hook('shd_hook_actions', array(&$actionArray));
1297 1300
 
1298 1301
 	if (!empty($modSettings['shd_helpdesk_only']))
1299 1302
 	{
... ...
@@ -1352,7 +1355,7 @@ function shd_buffer_replace(&$buffer)
1352 1355
 	}
1353 1356
 
1354 1357
 	// And any replacements a buffer might want to make...
1355
-	call_integration_hook('shd_hook_buffer', array($buffer));
1358
+	call_integration_hook('shd_hook_buffer', array(&$buffer));
1356 1359
 
1357 1360
 	return $buffer;
1358 1361
 }
... ...
@@ -74,8 +74,8 @@ function shd_load_action_log_entries($start = 0, $items_per_page = 10, $sort = '
74 74
 
75 75
 	// Without further screaming and waving, fetch the actions.
76 76
 	$request = shd_db_query('','
77
-		SELECT la.id_action, la.log_time, la.id_member, la.ip, la.action, la.id_ticket, la.id_msg, la.extra,
78
-		mem.real_name, mg.group_name
77
+		SELECT la.id_action, la.log_time, la.ip, la.action, la.id_ticket, la.id_msg, la.extra,
78
+		IFNULL(mem.id_member, 0) AS id_member, IFNULL(mem.real_name, {string:blank}) AS real_name, IFNULL(mg.group_name, {string:na}) AS group_name
79 79
 		FROM {db_prefix}helpdesk_log_action AS la
80 80
 			LEFT JOIN {db_prefix}members AS mem ON(mem.id_member = la.id_member)
81 81
 			LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END)
... ...
@@ -89,6 +89,8 @@ function shd_load_action_log_entries($start = 0, $items_per_page = 10, $sort = '
89 89
 			'items_per_page' => $items_per_page,
90 90
 			'order' => $order,
91 91
 			'clause' => empty($clause) ? '' : 'WHERE ' . $clause,
92
+			'na' => $txt['not_applicable'],
93
+			'blank' => '',
92 94
 		)
93 95
 	);
94 96
 
... ...
@@ -99,6 +100,15 @@ function shd_load_action_log_entries($start = 0, $items_per_page = 10, $sort = '
99 100
 		$row['extra'] = @unserialize($row['extra']);
100 101
 		$row['extra'] = is_array($row['extra']) ? $row['extra'] : array();
101 102
 
103
+		// Uhoh, we don't know who this is! Check it's not automatically by the system. If it is... mark it so.
104
+		if (empty($row['id_member']))
105
+		{
106
+			if (isset($row['extra']) && $row['extra']['auto'] === true)
107
+				$row['real_name'] = $txt['shd_helpdesk'];
108
+			else
109
+				$row['real_name'] = $txt['shd_admin_actionlog_unknown'];
110
+		}
111
+
102 112
 		$actions[$row['id_action']] = array(
103 113
 			'id' => $row['id_action'],
104 114
 			'time' => timeformat($row['log_time']),
... ...
@@ -310,7 +310,7 @@ function shd_create_ticket_post(&$msgOptions, &$ticketOptions, &$posterOptions)
310 310
 
311 311
 	// Int hooks
312 312
 	$hook = $new_ticket ? 'shd_hook_newticket' : 'shd_hook_newreply';
313
-	call_integration_hook($hook, array($msgOptions, $ticketOptions, $posterOptions));
313
+	call_integration_hook($hook, array(&$msgOptions, &$ticketOptions, &$posterOptions));
314 314
 
315 315
 	ignore_user_abort($previous_ignore_user_abort);
316 316
 
... ...
@@ -483,7 +483,7 @@ function shd_modify_ticket_post(&$msgOptions, &$ticketOptions, &$posterOptions)
483 483
 	}
484 484
 
485 485
 	// Int hook
486
-	call_integration_hook('shd_hook_modpost', array($msgOptions, $ticketOptions, $posterOptions));
486
+	call_integration_hook('shd_hook_modpost', array(&$msgOptions, &$ticketOptions, &$posterOptions));
487 487
 
488 488
 	ignore_user_abort($previous_ignore_user_abort);
489 489
 
... ...
@@ -68,6 +68,7 @@ $to_remove = array(
68 68
 	'shd_logopt_newposts',
69 69
 	'shd_logopt_editposts',
70 70
 	'shd_logopt_resolve',
71
+	'shd_logopt_autoclose',
71 72
 	'shd_logopt_assign',
72 73
 	'shd_logopt_privacy',
73 74
 	'shd_logopt_urgency',
... ...
@@ -91,6 +92,11 @@ $to_remove = array(
91 92
 	'shd_notify_new_reply_any',
92 93
 	'shd_notify_assign_me',
93 94
 	'shd_notify_assign_own',
95
+	// Scheduled tasks
96
+	'shd_autoclose_tickets',
97
+	'shd_autoclose_tickets_days',
98
+	'shd_autopurge_tickets',
99
+	'shd_autopurge_tickets_days',
94 100
 	// Plugin related: general
95 101
 	'shd_enabled_plugins',
96 102
 	// Plugin: source load hooks
... ...
@@ -113,7 +119,6 @@ $to_remove = array(
113 119
 	'shd_hook_modpost',
114 120
 	'shd_hook_assign',
115 121
 	'shd_hook_buffer',
116
-	'shd_hook_postingopts',
117 122
 	'shd_hook_after_main',
118 123
 	// Plugin: menu hooks
119 124
 	'shd_hook_mainmenu',
... ...
@@ -45,7 +45,7 @@ elseif (!defined('SMF'))
45 45
 	die('<b>Error:</b> Cannot uninstall - please verify you put this file in the same place as SMF\'s SSI.php.');
46 46
 }
47 47
 
48
-// Unchecking the option in Core Features, and deactivating all the hooks
48
+// Unchecking the option in Core Features.
49 49
 global $modSettings;
50 50
 $modSettings['helpdesk_active'] = false;
51 51
 $features = implode(',', array_diff(explode(',', $modSettings['admin_features']), array('shd')));
... ...
@@ -57,6 +57,7 @@ updateSettings(
57 57
 	true
58 58
 );
59 59
 
60
+// Removing all the hooks.
60 61
 $hooks = array();
61 62
 $hooks[] = array(
62 63
 	'hook' => 'integrate_display_buttons',
... ...
@@ -98,4 +99,12 @@ $hooks[] = array(
98 99
 foreach ($hooks as $hook)
99 100
 	remove_integration_function($hook['hook'], $hook['function']);
100 101
 
102
+// Removing the scheduled task.
103
+$smcFunc['db_query']('', '
104
+	DELETE FROM {db_prefix}scheduled_tasks
105
+	WHERE task = {string:simpledesk}',
106
+	array(
107
+		'simpledesk' => 'simpledesk',
108
+	)
109
+);
101 110
 ?>
102 111
\ No newline at end of file
103 112