comparison forum/Sources/ManageScheduledTasks.php @ 76:e3e11437ecea website

Add forum code
author Chris Cannam
date Sun, 07 Jul 2013 11:25:48 +0200
parents
children
comparison
equal deleted inserted replaced
75:72f59aa7e503 76:e3e11437ecea
1 <?php
2
3 /**
4 * Simple Machines Forum (SMF)
5 *
6 * @package SMF
7 * @author Simple Machines http://www.simplemachines.org
8 * @copyright 2011 Simple Machines
9 * @license http://www.simplemachines.org/about/smf/license.php BSD
10 *
11 * @version 2.0
12 */
13
14 if (!defined('SMF'))
15 die('Hacking attempt...');
16
17 /* /!!!
18
19 void ManageScheduledTasks()
20 // !!!
21
22 void ScheduledTasks()
23 // !!!
24
25 array list_getScheduledTasks()
26 // !!!
27
28 void EditTask()
29 // !!!
30
31 void TaskLog()
32 // !!!
33
34 array list_getTaskLogEntries()
35 // !!!
36
37 array list_getNumTaskLog()
38 // !!!
39 */
40
41 // !!!
42 function ManageScheduledTasks()
43 {
44 global $context, $txt, $modSettings;
45
46 isAllowedTo('admin_forum');
47
48 loadLanguage('ManageScheduledTasks');
49 loadTemplate('ManageScheduledTasks');
50
51 $subActions = array(
52 'taskedit' => 'EditTask',
53 'tasklog' => 'TaskLog',
54 'tasks' => 'ScheduledTasks',
55 );
56
57 // We need to find what's the action.
58 if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']]))
59 $context['sub_action'] = $_REQUEST['sa'];
60 else
61 $context['sub_action'] = 'tasks';
62
63 // Now for the lovely tabs. That we all love.
64 $context[$context['admin_menu_name']]['tab_data'] = array(
65 'title' => $txt['scheduled_tasks_title'],
66 'help' => '',
67 'description' => $txt['maintain_info'],
68 'tabs' => array(
69 'tasks' => array(
70 'description' => $txt['maintain_tasks_desc'],
71 ),
72 'tasklog' => array(
73 'description' => $txt['scheduled_log_desc'],
74 ),
75 ),
76 );
77
78 // Call it.
79 $subActions[$context['sub_action']]();
80 }
81
82 // List all the scheduled task in place on the forum.
83 function ScheduledTasks()
84 {
85 global $context, $txt, $sourcedir, $smcFunc, $user_info, $modSettings, $scripturl;
86
87 // Mama, setup the template first - cause it's like the most important bit, like pickle in a sandwich.
88 // ... ironically I don't like pickle. </grudge>
89 $context['sub_template'] = 'view_scheduled_tasks';
90 $context['page_title'] = $txt['maintain_tasks'];
91
92 // Saving changes?
93 if (isset($_REQUEST['save']) && isset($_POST['enable_task']))
94 {
95 checkSession();
96
97 // We'll recalculate the dates at the end!
98 require_once($sourcedir . '/ScheduledTasks.php');
99
100 // Enable and disable as required.
101 $enablers = array(0);
102 foreach ($_POST['enable_task'] as $id => $enabled)
103 if ($enabled)
104 $enablers[] = (int) $id;
105
106 // Do the update!
107 $smcFunc['db_query']('', '
108 UPDATE {db_prefix}scheduled_tasks
109 SET disabled = CASE WHEN id_task IN ({array_int:id_task_enable}) THEN 0 ELSE 1 END',
110 array(
111 'id_task_enable' => $enablers,
112 )
113 );
114
115 // Pop along...
116 CalculateNextTrigger();
117 }
118
119 // Want to run any of the tasks?
120 if (isset($_REQUEST['run']) && isset($_POST['run_task']))
121 {
122 // Lets figure out which ones they want to run.
123 $tasks = array();
124 foreach ($_POST['run_task'] as $task => $dummy)
125 $tasks[] = (int) $task;
126
127 // Load up the tasks.
128 $request = $smcFunc['db_query']('', '
129 SELECT id_task, task
130 FROM {db_prefix}scheduled_tasks
131 WHERE id_task IN ({array_int:tasks})
132 LIMIT ' . count($tasks),
133 array(
134 'tasks' => $tasks,
135 )
136 );
137
138 // Lets get it on!
139 require_once($sourcedir . '/ScheduledTasks.php');
140 ignore_user_abort(true);
141 while ($row = $smcFunc['db_fetch_assoc']($request))
142 {
143 $start_time = microtime();
144 // The functions got to exist for us to use it.
145 if (!function_exists('scheduled_' . $row['task']))
146 continue;
147
148 // Try to stop a timeout, this would be bad...
149 @set_time_limit(300);
150 if (function_exists('apache_reset_timeout'))
151 @apache_reset_timeout();
152
153 // Do the task...
154 $completed = call_user_func('scheduled_' . $row['task']);
155
156 // Log that we did it ;)
157 if ($completed)
158 {
159 $total_time = round(array_sum(explode(' ', microtime())) - array_sum(explode(' ', $start_time)), 3);
160 $smcFunc['db_insert']('',
161 '{db_prefix}log_scheduled_tasks',
162 array('id_task' => 'int', 'time_run' => 'int', 'time_taken' => 'float'),
163 array($row['id_task'], time(), $total_time),
164 array('id_task')
165 );
166 }
167 }
168 $smcFunc['db_free_result']($request);
169 redirectexit('action=admin;area=scheduledtasks;done');
170 }
171
172 $listOptions = array(
173 'id' => 'scheduled_tasks',
174 'title' => $txt['maintain_tasks'],
175 'base_href' => $scripturl . '?action=admin;area=scheduledtasks',
176 'get_items' => array(
177 'function' => 'list_getScheduledTasks',
178 ),
179 'columns' => array(
180 'name' => array(
181 'header' => array(
182 'value' => $txt['scheduled_tasks_name'],
183 'style' => 'width: 40%;',
184 ),
185 'data' => array(
186 'sprintf' => array(
187 'format' => '
188 <a href="' . $scripturl . '?action=admin;area=scheduledtasks;sa=taskedit;tid=%1$d">%2$s</a><br /><span class="smalltext">%3$s</span>',
189 'params' => array(
190 'id' => false,
191 'name' => false,
192 'desc' => false,
193 ),
194 ),
195 ),
196 ),
197 'next_due' => array(
198 'header' => array(
199 'value' => $txt['scheduled_tasks_next_time'],
200 ),
201 'data' => array(
202 'db' => 'next_time',
203 'class' => 'smalltext',
204 ),
205 ),
206 'regularity' => array(
207 'header' => array(
208 'value' => $txt['scheduled_tasks_regularity'],
209 ),
210 'data' => array(
211 'db' => 'regularity',
212 'class' => 'smalltext',
213 ),
214 ),
215 'enabled' => array(
216 'header' => array(
217 'value' => $txt['scheduled_tasks_enabled'],
218 'style' => 'width: 6%;',
219 ),
220 'data' => array(
221 'sprintf' => array(
222 'format' =>
223 '<input type="hidden" name="enable_task[%1$d]" id="task_%1$d" value="0" /><input type="checkbox" name="enable_task[%1$d]" id="task_check_%1$d" %2$s class="input_check" />',
224 'params' => array(
225 'id' => false,
226 'checked_state' => false,
227 ),
228 ),
229 'style' => 'text-align: center;',
230 ),
231 ),
232 'run_now' => array(
233 'header' => array(
234 'value' => $txt['scheduled_tasks_run_now'],
235 'style' => 'width: 12%;',
236 ),
237 'data' => array(
238 'sprintf' => array(
239 'format' =>
240 '<input type="checkbox" name="run_task[%1$d]" id="run_task_%1$d" class="input_check" />',
241 'params' => array(
242 'id' => false,
243 ),
244 ),
245 'style' => 'text-align: center;',
246 ),
247 ),
248 ),
249 'form' => array(
250 'href' => $scripturl . '?action=admin;area=scheduledtasks',
251 ),
252 'additional_rows' => array(
253 array(
254 'position' => 'below_table_data',
255 'value' => '
256 <input type="submit" name="save" value="' . $txt['scheduled_tasks_save_changes'] . '" class="button_submit" />
257 <input type="submit" name="run" value="' . $txt['scheduled_tasks_run_now'] . '" class="button_submit" />',
258 'class' => 'floatright',
259 'style' => 'text-align: right;',
260 ),
261 array(
262 'position' => 'after_title',
263 'value' => '
264 <span class="smalltext">' . $txt['scheduled_tasks_time_offset'] . '</span>',
265 'class' => 'windowbg2',
266 ),
267 ),
268 );
269
270 require_once($sourcedir . '/Subs-List.php');
271 createList($listOptions);
272
273 $context['sub_template'] = 'view_scheduled_tasks';
274
275 $context['tasks_were_run'] = isset($_GET['done']);
276 }
277
278 function list_getScheduledTasks($start, $items_per_page, $sort)
279 {
280 global $smcFunc, $txt, $scripturl;
281
282 $request = $smcFunc['db_query']('', '
283 SELECT id_task, next_time, time_offset, time_regularity, time_unit, disabled, task
284 FROM {db_prefix}scheduled_tasks',
285 array(
286 )
287 );
288 $known_tasks = array();
289 while ($row = $smcFunc['db_fetch_assoc']($request))
290 {
291 // Find the next for regularity - don't offset as it's always server time!
292 $offset = sprintf($txt['scheduled_task_reg_starting'], date('H:i', $row['time_offset']));
293 $repeating = sprintf($txt['scheduled_task_reg_repeating'], $row['time_regularity'], $txt['scheduled_task_reg_unit_' . $row['time_unit']]);
294
295 $known_tasks[] = array(
296 'id' => $row['id_task'],
297 'function' => $row['task'],
298 'name' => isset($txt['scheduled_task_' . $row['task']]) ? $txt['scheduled_task_' . $row['task']] : $row['task'],
299 'desc' => isset($txt['scheduled_task_desc_' . $row['task']]) ? $txt['scheduled_task_desc_' . $row['task']] : '',
300 'next_time' => $row['disabled'] ? $txt['scheduled_tasks_na'] : timeformat(($row['next_time'] == 0 ? time() : $row['next_time']), true, 'server'),
301 'disabled' => $row['disabled'],
302 'checked_state' => $row['disabled'] ? '' : 'checked="checked"',
303 'regularity' => $offset . ', ' . $repeating,
304 );
305 }
306 $smcFunc['db_free_result']($request);
307
308 return $known_tasks;
309 }
310
311 // Function for editing a task.
312 function EditTask()
313 {
314 global $context, $txt, $sourcedir, $smcFunc, $user_info, $modSettings;
315
316 // Just set up some lovely context stuff.
317 $context[$context['admin_menu_name']]['current_subsection'] = 'tasks';
318 $context['sub_template'] = 'edit_scheduled_tasks';
319 $context['page_title'] = $txt['scheduled_task_edit'];
320 $context['server_time'] = timeformat(time(), false, 'server');
321
322 // Cleaning...
323 if (!isset($_GET['tid']))
324 fatal_lang_error('no_access', false);
325 $_GET['tid'] = (int) $_GET['tid'];
326
327 // Saving?
328 if (isset($_GET['save']))
329 {
330 checkSession();
331
332 // We'll need this for calculating the next event.
333 require_once($sourcedir . '/ScheduledTasks.php');
334
335 // Do we have a valid offset?
336 preg_match('~(\d{1,2}):(\d{1,2})~', $_POST['offset'], $matches);
337
338 // If a half is empty then assume zero offset!
339 if (!isset($matches[2]) || $matches[2] > 59)
340 $matches[2] = 0;
341 if (!isset($matches[1]) || $matches[1] > 23)
342 $matches[1] = 0;
343
344 // Now the offset is easy; easy peasy - except we need to offset by a few hours...
345 $offset = $matches[1] * 3600 + $matches[2] * 60 - date('Z');
346
347 // The other time bits are simple!
348 $interval = max((int) $_POST['regularity'], 1);
349 $unit = in_array(substr($_POST['unit'], 0, 1), array('m', 'h', 'd', 'w')) ? substr($_POST['unit'], 0, 1) : 'd';
350
351 // Don't allow one minute intervals.
352 if ($interval == 1 && $unit == 'm')
353 $interval = 2;
354
355 // Is it disabled?
356 $disabled = !isset($_POST['enabled']) ? 1 : 0;
357
358 // Do the update!
359 $smcFunc['db_query']('', '
360 UPDATE {db_prefix}scheduled_tasks
361 SET disabled = {int:disabled}, time_offset = {int:time_offset}, time_unit = {string:time_unit},
362 time_regularity = {int:time_regularity}
363 WHERE id_task = {int:id_task}',
364 array(
365 'disabled' => $disabled,
366 'time_offset' => $offset,
367 'time_regularity' => $interval,
368 'id_task' => $_GET['tid'],
369 'time_unit' => $unit,
370 )
371 );
372
373 // Check the next event.
374 CalculateNextTrigger($_GET['tid'], true);
375
376 // Return to the main list.
377 redirectexit('action=admin;area=scheduledtasks');
378 }
379
380 // Load the task, understand? Que? Que?
381 $request = $smcFunc['db_query']('', '
382 SELECT id_task, next_time, time_offset, time_regularity, time_unit, disabled, task
383 FROM {db_prefix}scheduled_tasks
384 WHERE id_task = {int:id_task}',
385 array(
386 'id_task' => $_GET['tid'],
387 )
388 );
389
390 // Should never, ever, happen!
391 if ($smcFunc['db_num_rows']($request) == 0)
392 fatal_lang_error('no_access', false);
393
394 while ($row = $smcFunc['db_fetch_assoc']($request))
395 {
396 $context['task'] = array(
397 'id' => $row['id_task'],
398 'function' => $row['task'],
399 'name' => isset($txt['scheduled_task_' . $row['task']]) ? $txt['scheduled_task_' . $row['task']] : $row['task'],
400 'desc' => isset($txt['scheduled_task_desc_' . $row['task']]) ? $txt['scheduled_task_desc_' . $row['task']] : '',
401 'next_time' => $row['disabled'] ? $txt['scheduled_tasks_na'] : timeformat($row['next_time'] == 0 ? time() : $row['next_time'], true, 'server'),
402 'disabled' => $row['disabled'],
403 'offset' => $row['time_offset'],
404 'regularity' => $row['time_regularity'],
405 'offset_formatted' => date('H:i', $row['time_offset']),
406 'unit' => $row['time_unit'],
407 );
408 }
409 $smcFunc['db_free_result']($request);
410 }
411
412 // Show the log of all tasks that have taken place.
413 function TaskLog()
414 {
415 global $scripturl, $context, $txt, $smcFunc, $sourcedir;
416
417 // Lets load the language just incase we are outside the Scheduled area.
418 loadLanguage('ManageScheduledTasks');
419
420 // Empty the log?
421 if (!empty($_POST['removeAll']))
422 {
423 checkSession();
424
425 $smcFunc['db_query']('truncate_table', '
426 TRUNCATE {db_prefix}log_scheduled_tasks',
427 array(
428 )
429 );
430 }
431
432 // Setup the list.
433 $listOptions = array(
434 'id' => 'task_log',
435 'items_per_page' => 30,
436 'title' => $txt['scheduled_log'],
437 'no_items_label' => $txt['scheduled_log_empty'],
438 'base_href' => $context['admin_area'] == 'scheduledtasks' ? $scripturl . '?action=admin;area=scheduledtasks;sa=tasklog' : $scripturl . '?action=admin;area=logs;sa=tasklog',
439 'default_sort_col' => 'date',
440 'get_items' => array(
441 'function' => 'list_getTaskLogEntries',
442 ),
443 'get_count' => array(
444 'function' => 'list_getNumTaskLogEntries',
445 ),
446 'columns' => array(
447 'name' => array(
448 'header' => array(
449 'value' => $txt['scheduled_tasks_name'],
450 ),
451 'data' => array(
452 'db' => 'name'
453 ),
454 ),
455 'date' => array(
456 'header' => array(
457 'value' => $txt['scheduled_log_time_run'],
458 ),
459 'data' => array(
460 'function' => create_function('$rowData', '
461 return timeformat($rowData[\'time_run\'], true);
462 '),
463 ),
464 'sort' => array(
465 'default' => 'lst.id_log DESC',
466 'reverse' => 'lst.id_log',
467 ),
468 ),
469 'time_taken' => array(
470 'header' => array(
471 'value' => $txt['scheduled_log_time_taken'],
472 ),
473 'data' => array(
474 'sprintf' => array(
475 'format' => $txt['scheduled_log_time_taken_seconds'],
476 'params' => array(
477 'time_taken' => false,
478 ),
479 ),
480 ),
481 'sort' => array(
482 'default' => 'lst.time_taken',
483 'reverse' => 'lst.time_taken DESC',
484 ),
485 ),
486 ),
487 'form' => array(
488 'href' => $context['admin_area'] == 'scheduledtasks' ? $scripturl . '?action=admin;area=scheduledtasks;sa=tasklog' : $scripturl . '?action=admin;area=logs;sa=tasklog',
489 ),
490 'additional_rows' => array(
491 array(
492 'position' => 'below_table_data',
493 'value' => '
494 <input type="submit" name="removeAll" value="' . $txt['scheduled_log_empty_log'] . '" class="button_submit" />',
495 'style' => 'text-align: right;',
496 ),
497 array(
498 'position' => 'after_title',
499 'value' => $txt['scheduled_tasks_time_offset'],
500 'class' => 'smalltext',
501 ),
502 ),
503 );
504
505 require_once($sourcedir . '/Subs-List.php');
506 createList($listOptions);
507
508 $context['sub_template'] = 'show_list';
509 $context['default_list'] = 'task_log';
510
511 // Make it all look tify.
512 $context[$context['admin_menu_name']]['current_subsection'] = 'tasklog';
513 $context['page_title'] = $txt['scheduled_log'];
514 }
515
516 function list_getTaskLogEntries($start, $items_per_page, $sort)
517 {
518 global $smcFunc, $txt;
519
520 $request = $smcFunc['db_query']('', '
521 SELECT lst.id_log, lst.id_task, lst.time_run, lst.time_taken, st.task
522 FROM {db_prefix}log_scheduled_tasks AS lst
523 INNER JOIN {db_prefix}scheduled_tasks AS st ON (st.id_task = lst.id_task)
524 ORDER BY ' . $sort . '
525 LIMIT ' . $start . ', ' . $items_per_page,
526 array(
527 )
528 );
529 $log_entries = array();
530 while ($row = $smcFunc['db_fetch_assoc']($request))
531 $log_entries[] = array(
532 'id' => $row['id_log'],
533 'name' => isset($txt['scheduled_task_' . $row['task']]) ? $txt['scheduled_task_' . $row['task']] : $row['task'],
534 'time_run' => $row['time_run'],
535 'time_taken' => $row['time_taken'],
536 );
537 $smcFunc['db_free_result']($request);
538
539 return $log_entries;
540 }
541
542 function list_getNumTaskLogEntries()
543 {
544 global $smcFunc;
545
546 $request = $smcFunc['db_query']('', '
547 SELECT COUNT(*)
548 FROM {db_prefix}log_scheduled_tasks',
549 array(
550 )
551 );
552 list ($num_entries) = $smcFunc['db_fetch_row']($request);
553 $smcFunc['db_free_result']($request);
554
555 return $num_entries;
556 }
557
558 ?>