Mercurial > hg > vamp-website
diff forum/Sources/ManageScheduledTasks.php @ 76:e3e11437ecea website
Add forum code
author | Chris Cannam |
---|---|
date | Sun, 07 Jul 2013 11:25:48 +0200 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/forum/Sources/ManageScheduledTasks.php Sun Jul 07 11:25:48 2013 +0200 @@ -0,0 +1,558 @@ +<?php + +/** + * Simple Machines Forum (SMF) + * + * @package SMF + * @author Simple Machines http://www.simplemachines.org + * @copyright 2011 Simple Machines + * @license http://www.simplemachines.org/about/smf/license.php BSD + * + * @version 2.0 + */ + +if (!defined('SMF')) + die('Hacking attempt...'); + +/* /!!! + + void ManageScheduledTasks() + // !!! + + void ScheduledTasks() + // !!! + + array list_getScheduledTasks() + // !!! + + void EditTask() + // !!! + + void TaskLog() + // !!! + + array list_getTaskLogEntries() + // !!! + + array list_getNumTaskLog() + // !!! +*/ + +// !!! +function ManageScheduledTasks() +{ + global $context, $txt, $modSettings; + + isAllowedTo('admin_forum'); + + loadLanguage('ManageScheduledTasks'); + loadTemplate('ManageScheduledTasks'); + + $subActions = array( + 'taskedit' => 'EditTask', + 'tasklog' => 'TaskLog', + 'tasks' => 'ScheduledTasks', + ); + + // We need to find what's the action. + if (isset($_REQUEST['sa']) && isset($subActions[$_REQUEST['sa']])) + $context['sub_action'] = $_REQUEST['sa']; + else + $context['sub_action'] = 'tasks'; + + // Now for the lovely tabs. That we all love. + $context[$context['admin_menu_name']]['tab_data'] = array( + 'title' => $txt['scheduled_tasks_title'], + 'help' => '', + 'description' => $txt['maintain_info'], + 'tabs' => array( + 'tasks' => array( + 'description' => $txt['maintain_tasks_desc'], + ), + 'tasklog' => array( + 'description' => $txt['scheduled_log_desc'], + ), + ), + ); + + // Call it. + $subActions[$context['sub_action']](); +} + +// List all the scheduled task in place on the forum. +function ScheduledTasks() +{ + global $context, $txt, $sourcedir, $smcFunc, $user_info, $modSettings, $scripturl; + + // Mama, setup the template first - cause it's like the most important bit, like pickle in a sandwich. + // ... ironically I don't like pickle. </grudge> + $context['sub_template'] = 'view_scheduled_tasks'; + $context['page_title'] = $txt['maintain_tasks']; + + // Saving changes? + if (isset($_REQUEST['save']) && isset($_POST['enable_task'])) + { + checkSession(); + + // We'll recalculate the dates at the end! + require_once($sourcedir . '/ScheduledTasks.php'); + + // Enable and disable as required. + $enablers = array(0); + foreach ($_POST['enable_task'] as $id => $enabled) + if ($enabled) + $enablers[] = (int) $id; + + // Do the update! + $smcFunc['db_query']('', ' + UPDATE {db_prefix}scheduled_tasks + SET disabled = CASE WHEN id_task IN ({array_int:id_task_enable}) THEN 0 ELSE 1 END', + array( + 'id_task_enable' => $enablers, + ) + ); + + // Pop along... + CalculateNextTrigger(); + } + + // Want to run any of the tasks? + if (isset($_REQUEST['run']) && isset($_POST['run_task'])) + { + // Lets figure out which ones they want to run. + $tasks = array(); + foreach ($_POST['run_task'] as $task => $dummy) + $tasks[] = (int) $task; + + // Load up the tasks. + $request = $smcFunc['db_query']('', ' + SELECT id_task, task + FROM {db_prefix}scheduled_tasks + WHERE id_task IN ({array_int:tasks}) + LIMIT ' . count($tasks), + array( + 'tasks' => $tasks, + ) + ); + + // Lets get it on! + require_once($sourcedir . '/ScheduledTasks.php'); + ignore_user_abort(true); + while ($row = $smcFunc['db_fetch_assoc']($request)) + { + $start_time = microtime(); + // The functions got to exist for us to use it. + if (!function_exists('scheduled_' . $row['task'])) + continue; + + // Try to stop a timeout, this would be bad... + @set_time_limit(300); + if (function_exists('apache_reset_timeout')) + @apache_reset_timeout(); + + // Do the task... + $completed = call_user_func('scheduled_' . $row['task']); + + // Log that we did it ;) + if ($completed) + { + $total_time = round(array_sum(explode(' ', microtime())) - array_sum(explode(' ', $start_time)), 3); + $smcFunc['db_insert']('', + '{db_prefix}log_scheduled_tasks', + array('id_task' => 'int', 'time_run' => 'int', 'time_taken' => 'float'), + array($row['id_task'], time(), $total_time), + array('id_task') + ); + } + } + $smcFunc['db_free_result']($request); + redirectexit('action=admin;area=scheduledtasks;done'); + } + + $listOptions = array( + 'id' => 'scheduled_tasks', + 'title' => $txt['maintain_tasks'], + 'base_href' => $scripturl . '?action=admin;area=scheduledtasks', + 'get_items' => array( + 'function' => 'list_getScheduledTasks', + ), + 'columns' => array( + 'name' => array( + 'header' => array( + 'value' => $txt['scheduled_tasks_name'], + 'style' => 'width: 40%;', + ), + 'data' => array( + 'sprintf' => array( + 'format' => ' + <a href="' . $scripturl . '?action=admin;area=scheduledtasks;sa=taskedit;tid=%1$d">%2$s</a><br /><span class="smalltext">%3$s</span>', + 'params' => array( + 'id' => false, + 'name' => false, + 'desc' => false, + ), + ), + ), + ), + 'next_due' => array( + 'header' => array( + 'value' => $txt['scheduled_tasks_next_time'], + ), + 'data' => array( + 'db' => 'next_time', + 'class' => 'smalltext', + ), + ), + 'regularity' => array( + 'header' => array( + 'value' => $txt['scheduled_tasks_regularity'], + ), + 'data' => array( + 'db' => 'regularity', + 'class' => 'smalltext', + ), + ), + 'enabled' => array( + 'header' => array( + 'value' => $txt['scheduled_tasks_enabled'], + 'style' => 'width: 6%;', + ), + 'data' => array( + 'sprintf' => array( + 'format' => + '<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" />', + 'params' => array( + 'id' => false, + 'checked_state' => false, + ), + ), + 'style' => 'text-align: center;', + ), + ), + 'run_now' => array( + 'header' => array( + 'value' => $txt['scheduled_tasks_run_now'], + 'style' => 'width: 12%;', + ), + 'data' => array( + 'sprintf' => array( + 'format' => + '<input type="checkbox" name="run_task[%1$d]" id="run_task_%1$d" class="input_check" />', + 'params' => array( + 'id' => false, + ), + ), + 'style' => 'text-align: center;', + ), + ), + ), + 'form' => array( + 'href' => $scripturl . '?action=admin;area=scheduledtasks', + ), + 'additional_rows' => array( + array( + 'position' => 'below_table_data', + 'value' => ' + <input type="submit" name="save" value="' . $txt['scheduled_tasks_save_changes'] . '" class="button_submit" /> + <input type="submit" name="run" value="' . $txt['scheduled_tasks_run_now'] . '" class="button_submit" />', + 'class' => 'floatright', + 'style' => 'text-align: right;', + ), + array( + 'position' => 'after_title', + 'value' => ' + <span class="smalltext">' . $txt['scheduled_tasks_time_offset'] . '</span>', + 'class' => 'windowbg2', + ), + ), + ); + + require_once($sourcedir . '/Subs-List.php'); + createList($listOptions); + + $context['sub_template'] = 'view_scheduled_tasks'; + + $context['tasks_were_run'] = isset($_GET['done']); +} + +function list_getScheduledTasks($start, $items_per_page, $sort) +{ + global $smcFunc, $txt, $scripturl; + + $request = $smcFunc['db_query']('', ' + SELECT id_task, next_time, time_offset, time_regularity, time_unit, disabled, task + FROM {db_prefix}scheduled_tasks', + array( + ) + ); + $known_tasks = array(); + while ($row = $smcFunc['db_fetch_assoc']($request)) + { + // Find the next for regularity - don't offset as it's always server time! + $offset = sprintf($txt['scheduled_task_reg_starting'], date('H:i', $row['time_offset'])); + $repeating = sprintf($txt['scheduled_task_reg_repeating'], $row['time_regularity'], $txt['scheduled_task_reg_unit_' . $row['time_unit']]); + + $known_tasks[] = array( + 'id' => $row['id_task'], + 'function' => $row['task'], + 'name' => isset($txt['scheduled_task_' . $row['task']]) ? $txt['scheduled_task_' . $row['task']] : $row['task'], + 'desc' => isset($txt['scheduled_task_desc_' . $row['task']]) ? $txt['scheduled_task_desc_' . $row['task']] : '', + 'next_time' => $row['disabled'] ? $txt['scheduled_tasks_na'] : timeformat(($row['next_time'] == 0 ? time() : $row['next_time']), true, 'server'), + 'disabled' => $row['disabled'], + 'checked_state' => $row['disabled'] ? '' : 'checked="checked"', + 'regularity' => $offset . ', ' . $repeating, + ); + } + $smcFunc['db_free_result']($request); + + return $known_tasks; +} + +// Function for editing a task. +function EditTask() +{ + global $context, $txt, $sourcedir, $smcFunc, $user_info, $modSettings; + + // Just set up some lovely context stuff. + $context[$context['admin_menu_name']]['current_subsection'] = 'tasks'; + $context['sub_template'] = 'edit_scheduled_tasks'; + $context['page_title'] = $txt['scheduled_task_edit']; + $context['server_time'] = timeformat(time(), false, 'server'); + + // Cleaning... + if (!isset($_GET['tid'])) + fatal_lang_error('no_access', false); + $_GET['tid'] = (int) $_GET['tid']; + + // Saving? + if (isset($_GET['save'])) + { + checkSession(); + + // We'll need this for calculating the next event. + require_once($sourcedir . '/ScheduledTasks.php'); + + // Do we have a valid offset? + preg_match('~(\d{1,2}):(\d{1,2})~', $_POST['offset'], $matches); + + // If a half is empty then assume zero offset! + if (!isset($matches[2]) || $matches[2] > 59) + $matches[2] = 0; + if (!isset($matches[1]) || $matches[1] > 23) + $matches[1] = 0; + + // Now the offset is easy; easy peasy - except we need to offset by a few hours... + $offset = $matches[1] * 3600 + $matches[2] * 60 - date('Z'); + + // The other time bits are simple! + $interval = max((int) $_POST['regularity'], 1); + $unit = in_array(substr($_POST['unit'], 0, 1), array('m', 'h', 'd', 'w')) ? substr($_POST['unit'], 0, 1) : 'd'; + + // Don't allow one minute intervals. + if ($interval == 1 && $unit == 'm') + $interval = 2; + + // Is it disabled? + $disabled = !isset($_POST['enabled']) ? 1 : 0; + + // Do the update! + $smcFunc['db_query']('', ' + UPDATE {db_prefix}scheduled_tasks + SET disabled = {int:disabled}, time_offset = {int:time_offset}, time_unit = {string:time_unit}, + time_regularity = {int:time_regularity} + WHERE id_task = {int:id_task}', + array( + 'disabled' => $disabled, + 'time_offset' => $offset, + 'time_regularity' => $interval, + 'id_task' => $_GET['tid'], + 'time_unit' => $unit, + ) + ); + + // Check the next event. + CalculateNextTrigger($_GET['tid'], true); + + // Return to the main list. + redirectexit('action=admin;area=scheduledtasks'); + } + + // Load the task, understand? Que? Que? + $request = $smcFunc['db_query']('', ' + SELECT id_task, next_time, time_offset, time_regularity, time_unit, disabled, task + FROM {db_prefix}scheduled_tasks + WHERE id_task = {int:id_task}', + array( + 'id_task' => $_GET['tid'], + ) + ); + + // Should never, ever, happen! + if ($smcFunc['db_num_rows']($request) == 0) + fatal_lang_error('no_access', false); + + while ($row = $smcFunc['db_fetch_assoc']($request)) + { + $context['task'] = array( + 'id' => $row['id_task'], + 'function' => $row['task'], + 'name' => isset($txt['scheduled_task_' . $row['task']]) ? $txt['scheduled_task_' . $row['task']] : $row['task'], + 'desc' => isset($txt['scheduled_task_desc_' . $row['task']]) ? $txt['scheduled_task_desc_' . $row['task']] : '', + 'next_time' => $row['disabled'] ? $txt['scheduled_tasks_na'] : timeformat($row['next_time'] == 0 ? time() : $row['next_time'], true, 'server'), + 'disabled' => $row['disabled'], + 'offset' => $row['time_offset'], + 'regularity' => $row['time_regularity'], + 'offset_formatted' => date('H:i', $row['time_offset']), + 'unit' => $row['time_unit'], + ); + } + $smcFunc['db_free_result']($request); +} + +// Show the log of all tasks that have taken place. +function TaskLog() +{ + global $scripturl, $context, $txt, $smcFunc, $sourcedir; + + // Lets load the language just incase we are outside the Scheduled area. + loadLanguage('ManageScheduledTasks'); + + // Empty the log? + if (!empty($_POST['removeAll'])) + { + checkSession(); + + $smcFunc['db_query']('truncate_table', ' + TRUNCATE {db_prefix}log_scheduled_tasks', + array( + ) + ); + } + + // Setup the list. + $listOptions = array( + 'id' => 'task_log', + 'items_per_page' => 30, + 'title' => $txt['scheduled_log'], + 'no_items_label' => $txt['scheduled_log_empty'], + 'base_href' => $context['admin_area'] == 'scheduledtasks' ? $scripturl . '?action=admin;area=scheduledtasks;sa=tasklog' : $scripturl . '?action=admin;area=logs;sa=tasklog', + 'default_sort_col' => 'date', + 'get_items' => array( + 'function' => 'list_getTaskLogEntries', + ), + 'get_count' => array( + 'function' => 'list_getNumTaskLogEntries', + ), + 'columns' => array( + 'name' => array( + 'header' => array( + 'value' => $txt['scheduled_tasks_name'], + ), + 'data' => array( + 'db' => 'name' + ), + ), + 'date' => array( + 'header' => array( + 'value' => $txt['scheduled_log_time_run'], + ), + 'data' => array( + 'function' => create_function('$rowData', ' + return timeformat($rowData[\'time_run\'], true); + '), + ), + 'sort' => array( + 'default' => 'lst.id_log DESC', + 'reverse' => 'lst.id_log', + ), + ), + 'time_taken' => array( + 'header' => array( + 'value' => $txt['scheduled_log_time_taken'], + ), + 'data' => array( + 'sprintf' => array( + 'format' => $txt['scheduled_log_time_taken_seconds'], + 'params' => array( + 'time_taken' => false, + ), + ), + ), + 'sort' => array( + 'default' => 'lst.time_taken', + 'reverse' => 'lst.time_taken DESC', + ), + ), + ), + 'form' => array( + 'href' => $context['admin_area'] == 'scheduledtasks' ? $scripturl . '?action=admin;area=scheduledtasks;sa=tasklog' : $scripturl . '?action=admin;area=logs;sa=tasklog', + ), + 'additional_rows' => array( + array( + 'position' => 'below_table_data', + 'value' => ' + <input type="submit" name="removeAll" value="' . $txt['scheduled_log_empty_log'] . '" class="button_submit" />', + 'style' => 'text-align: right;', + ), + array( + 'position' => 'after_title', + 'value' => $txt['scheduled_tasks_time_offset'], + 'class' => 'smalltext', + ), + ), + ); + + require_once($sourcedir . '/Subs-List.php'); + createList($listOptions); + + $context['sub_template'] = 'show_list'; + $context['default_list'] = 'task_log'; + + // Make it all look tify. + $context[$context['admin_menu_name']]['current_subsection'] = 'tasklog'; + $context['page_title'] = $txt['scheduled_log']; +} + +function list_getTaskLogEntries($start, $items_per_page, $sort) +{ + global $smcFunc, $txt; + + $request = $smcFunc['db_query']('', ' + SELECT lst.id_log, lst.id_task, lst.time_run, lst.time_taken, st.task + FROM {db_prefix}log_scheduled_tasks AS lst + INNER JOIN {db_prefix}scheduled_tasks AS st ON (st.id_task = lst.id_task) + ORDER BY ' . $sort . ' + LIMIT ' . $start . ', ' . $items_per_page, + array( + ) + ); + $log_entries = array(); + while ($row = $smcFunc['db_fetch_assoc']($request)) + $log_entries[] = array( + 'id' => $row['id_log'], + 'name' => isset($txt['scheduled_task_' . $row['task']]) ? $txt['scheduled_task_' . $row['task']] : $row['task'], + 'time_run' => $row['time_run'], + 'time_taken' => $row['time_taken'], + ); + $smcFunc['db_free_result']($request); + + return $log_entries; +} + +function list_getNumTaskLogEntries() +{ + global $smcFunc; + + $request = $smcFunc['db_query']('', ' + SELECT COUNT(*) + FROM {db_prefix}log_scheduled_tasks', + array( + ) + ); + list ($num_entries) = $smcFunc['db_fetch_row']($request); + $smcFunc['db_free_result']($request); + + return $num_entries; +} + +?> \ No newline at end of file