/** * Function for editing a task. * * @uses ManageScheduledTasks template, edit_scheduled_tasks sub-template */ 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(); validateToken('admin-st'); // 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); createToken('admin-st'); }
function AdminBoardRecount() { global $txt, $context, $scripturl, $modSettings, $sourcedir; global $time_start, $smcFunc; isAllowedTo('admin_forum'); checkSession('request'); $context['page_title'] = $txt['not_done_title']; $context['continue_post_data'] = ''; $context['continue_countdown'] = '3'; $context['sub_template'] = 'not_done'; // Try for as much time as possible. @set_time_limit(600); // Step the number of topics at a time so things don't time out... $request = $smcFunc['db_query']('', ' SELECT MAX(id_topic) FROM {db_prefix}topics', array()); list($max_topics) = $smcFunc['db_fetch_row']($request); $smcFunc['db_free_result']($request); $increment = min(max(50, ceil($max_topics / 4)), 2000); if (empty($_REQUEST['start'])) { $_REQUEST['start'] = 0; } $total_steps = 8; // Get each topic with a wrong reply count and fix it - let's just do some at a time, though. if (empty($_REQUEST['step'])) { $_REQUEST['step'] = 0; while ($_REQUEST['start'] < $max_topics) { // Recount approved messages $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ t.id_topic, MAX(t.num_replies) AS num_replies, CASE WHEN COUNT(ma.id_msg) >= 1 THEN COUNT(ma.id_msg) - 1 ELSE 0 END AS real_num_replies FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}messages AS ma ON (ma.id_topic = t.id_topic AND ma.approved = {int:is_approved}) WHERE t.id_topic > {int:start} AND t.id_topic <= {int:max_id} GROUP BY t.id_topic HAVING CASE WHEN COUNT(ma.id_msg) >= 1 THEN COUNT(ma.id_msg) - 1 ELSE 0 END != MAX(t.num_replies)', array('is_approved' => 1, 'start' => $_REQUEST['start'], 'max_id' => $_REQUEST['start'] + $increment)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET num_replies = {int:num_replies} WHERE id_topic = {int:id_topic}', array('num_replies' => $row['real_num_replies'], 'id_topic' => $row['id_topic'])); } $smcFunc['db_free_result']($request); // Recount unapproved messages $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ t.id_topic, MAX(t.unapproved_posts) AS unapproved_posts, COUNT(mu.id_msg) AS real_unapproved_posts FROM {db_prefix}topics AS t LEFT JOIN {db_prefix}messages AS mu ON (mu.id_topic = t.id_topic AND mu.approved = {int:not_approved}) WHERE t.id_topic > {int:start} AND t.id_topic <= {int:max_id} GROUP BY t.id_topic HAVING COUNT(mu.id_msg) != MAX(t.unapproved_posts)', array('not_approved' => 0, 'start' => $_REQUEST['start'], 'max_id' => $_REQUEST['start'] + $increment)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $smcFunc['db_query']('', ' UPDATE {db_prefix}topics SET unapproved_posts = {int:unapproved_posts} WHERE id_topic = {int:id_topic}', array('unapproved_posts' => $row['real_unapproved_posts'], 'id_topic' => $row['id_topic'])); } $smcFunc['db_free_result']($request); $_REQUEST['start'] += $increment; if (array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start)) > 3) { $context['continue_get_data'] = '?action=admin;area=maintain;sa=routine;activity=recount;step=0;start=' . $_REQUEST['start'] . ';' . $context['session_var'] . '=' . $context['session_id']; $context['continue_percent'] = round(100 * $_REQUEST['start'] / $max_topics / $total_steps); return; } } $_REQUEST['start'] = 0; } // Update the post count of each board. if ($_REQUEST['step'] <= 1) { if (empty($_REQUEST['start'])) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET num_posts = {int:num_posts} WHERE redirect = {string:redirect}', array('num_posts' => 0, 'redirect' => '')); } while ($_REQUEST['start'] < $max_topics) { $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ m.id_board, COUNT(*) AS real_num_posts FROM {db_prefix}messages AS m WHERE m.id_topic > {int:id_topic_min} AND m.id_topic <= {int:id_topic_max} AND m.approved = {int:is_approved} GROUP BY m.id_board', array('id_topic_min' => $_REQUEST['start'], 'id_topic_max' => $_REQUEST['start'] + $increment, 'is_approved' => 1)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET num_posts = num_posts + {int:real_num_posts} WHERE id_board = {int:id_board}', array('id_board' => $row['id_board'], 'real_num_posts' => $row['real_num_posts'])); } $smcFunc['db_free_result']($request); $_REQUEST['start'] += $increment; if (array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start)) > 3) { $context['continue_get_data'] = '?action=admin;area=maintain;sa=routine;activity=recount;step=1;start=' . $_REQUEST['start'] . ';' . $context['session_var'] . '=' . $context['session_id']; $context['continue_percent'] = round((200 + 100 * $_REQUEST['start'] / $max_topics) / $total_steps); return; } } $_REQUEST['start'] = 0; } // Update the topic count of each board. if ($_REQUEST['step'] <= 2) { if (empty($_REQUEST['start'])) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET num_topics = {int:num_topics}', array('num_topics' => 0)); } while ($_REQUEST['start'] < $max_topics) { $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ t.id_board, COUNT(*) AS real_num_topics FROM {db_prefix}topics AS t WHERE t.approved = {int:is_approved} AND t.id_topic > {int:id_topic_min} AND t.id_topic <= {int:id_topic_max} GROUP BY t.id_board', array('is_approved' => 1, 'id_topic_min' => $_REQUEST['start'], 'id_topic_max' => $_REQUEST['start'] + $increment)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET num_topics = num_topics + {int:real_num_topics} WHERE id_board = {int:id_board}', array('id_board' => $row['id_board'], 'real_num_topics' => $row['real_num_topics'])); } $smcFunc['db_free_result']($request); $_REQUEST['start'] += $increment; if (array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start)) > 3) { $context['continue_get_data'] = '?action=admin;area=maintain;sa=routine;activity=recount;step=2;start=' . $_REQUEST['start'] . ';' . $context['session_var'] . '=' . $context['session_id']; $context['continue_percent'] = round((300 + 100 * $_REQUEST['start'] / $max_topics) / $total_steps); return; } } $_REQUEST['start'] = 0; } // Update the unapproved post count of each board. if ($_REQUEST['step'] <= 3) { if (empty($_REQUEST['start'])) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET unapproved_posts = {int:unapproved_posts}', array('unapproved_posts' => 0)); } while ($_REQUEST['start'] < $max_topics) { $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ m.id_board, COUNT(*) AS real_unapproved_posts FROM {db_prefix}messages AS m WHERE m.id_topic > {int:id_topic_min} AND m.id_topic <= {int:id_topic_max} AND m.approved = {int:is_approved} GROUP BY m.id_board', array('id_topic_min' => $_REQUEST['start'], 'id_topic_max' => $_REQUEST['start'] + $increment, 'is_approved' => 0)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET unapproved_posts = unapproved_posts + {int:unapproved_posts} WHERE id_board = {int:id_board}', array('id_board' => $row['id_board'], 'unapproved_posts' => $row['real_unapproved_posts'])); } $smcFunc['db_free_result']($request); $_REQUEST['start'] += $increment; if (array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start)) > 3) { $context['continue_get_data'] = '?action=admin;area=maintain;sa=routine;activity=recount;step=3;start=' . $_REQUEST['start'] . ';' . $context['session_var'] . '=' . $context['session_id']; $context['continue_percent'] = round((400 + 100 * $_REQUEST['start'] / $max_topics) / $total_steps); return; } } $_REQUEST['start'] = 0; } // Update the unapproved topic count of each board. if ($_REQUEST['step'] <= 4) { if (empty($_REQUEST['start'])) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET unapproved_topics = {int:unapproved_topics}', array('unapproved_topics' => 0)); } while ($_REQUEST['start'] < $max_topics) { $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ t.id_board, COUNT(*) AS real_unapproved_topics FROM {db_prefix}topics AS t WHERE t.approved = {int:is_approved} AND t.id_topic > {int:id_topic_min} AND t.id_topic <= {int:id_topic_max} GROUP BY t.id_board', array('is_approved' => 0, 'id_topic_min' => $_REQUEST['start'], 'id_topic_max' => $_REQUEST['start'] + $increment)); while ($row = $smcFunc['db_fetch_assoc']($request)) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET unapproved_topics = unapproved_topics + {int:real_unapproved_topics} WHERE id_board = {int:id_board}', array('id_board' => $row['id_board'], 'real_unapproved_topics' => $row['real_unapproved_topics'])); } $smcFunc['db_free_result']($request); $_REQUEST['start'] += $increment; if (array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start)) > 3) { $context['continue_get_data'] = '?action=admin;area=maintain;sa=routine;activity=recount;step=4;start=' . $_REQUEST['start'] . ';' . $context['session_var'] . '=' . $context['session_id']; $context['continue_percent'] = round((500 + 100 * $_REQUEST['start'] / $max_topics) / $total_steps); return; } } $_REQUEST['start'] = 0; } // Get all members with wrong number of personal messages. if ($_REQUEST['step'] <= 5) { $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ mem.id_member, COUNT(pmr.id_pm) AS real_num, MAX(mem.instant_messages) AS instant_messages FROM {db_prefix}members AS mem LEFT JOIN {db_prefix}pm_recipients AS pmr ON (mem.id_member = pmr.id_member AND pmr.deleted = {int:is_not_deleted}) GROUP BY mem.id_member HAVING COUNT(pmr.id_pm) != MAX(mem.instant_messages)', array('is_not_deleted' => 0)); while ($row = $smcFunc['db_fetch_assoc']($request)) { updateMemberData($row['id_member'], array('instant_messages' => $row['real_num'])); } $smcFunc['db_free_result']($request); $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ mem.id_member, COUNT(pmr.id_pm) AS real_num, MAX(mem.unread_messages) AS unread_messages FROM {db_prefix}members AS mem LEFT JOIN {db_prefix}pm_recipients AS pmr ON (mem.id_member = pmr.id_member AND pmr.deleted = {int:is_not_deleted} AND pmr.is_read = {int:is_not_read}) GROUP BY mem.id_member HAVING COUNT(pmr.id_pm) != MAX(mem.unread_messages)', array('is_not_deleted' => 0, 'is_not_read' => 0)); while ($row = $smcFunc['db_fetch_assoc']($request)) { updateMemberData($row['id_member'], array('unread_messages' => $row['real_num'])); } $smcFunc['db_free_result']($request); if (array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start)) > 3) { $context['continue_get_data'] = '?action=admin;area=maintain;sa=routine;activity=recount;step=6;start=0;' . $context['session_var'] . '=' . $context['session_id']; $context['continue_percent'] = round(700 / $total_steps); return; } } // Any messages pointing to the wrong board? if ($_REQUEST['step'] <= 6) { while ($_REQUEST['start'] < $modSettings['maxMsgID']) { $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ t.id_board, m.id_msg FROM {db_prefix}messages AS m INNER JOIN {db_prefix}topics AS t ON (t.id_topic = m.id_topic AND t.id_board != m.id_board) WHERE m.id_msg > {int:id_msg_min} AND m.id_msg <= {int:id_msg_max}', array('id_msg_min' => $_REQUEST['start'], 'id_msg_max' => $_REQUEST['start'] + $increment)); $boards = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $boards[$row['id_board']][] = $row['id_msg']; } $smcFunc['db_free_result']($request); foreach ($boards as $board_id => $messages) { $smcFunc['db_query']('', ' UPDATE {db_prefix}messages SET id_board = {int:id_board} WHERE id_msg IN ({array_int:id_msg_array})', array('id_msg_array' => $messages, 'id_board' => $board_id)); } $_REQUEST['start'] += $increment; if (array_sum(explode(' ', microtime())) - array_sum(explode(' ', $time_start)) > 3) { $context['continue_get_data'] = '?action=admin;area=maintain;sa=routine;activity=recount;step=6;start=' . $_REQUEST['start'] . ';' . $context['session_var'] . '=' . $context['session_id']; $context['continue_percent'] = round((700 + 100 * $_REQUEST['start'] / $modSettings['maxMsgID']) / $total_steps); return; } } $_REQUEST['start'] = 0; } // Update the latest message of each board. $request = $smcFunc['db_query']('', ' SELECT m.id_board, MAX(m.id_msg) AS local_last_msg FROM {db_prefix}messages AS m WHERE m.approved = {int:is_approved} GROUP BY m.id_board', array('is_approved' => 1)); $realBoardCounts = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $realBoardCounts[$row['id_board']] = $row['local_last_msg']; } $smcFunc['db_free_result']($request); $request = $smcFunc['db_query']('', ' SELECT /*!40001 SQL_NO_CACHE */ id_board, id_parent, id_last_msg, child_level, id_msg_updated FROM {db_prefix}boards', array()); $resort_me = array(); while ($row = $smcFunc['db_fetch_assoc']($request)) { $row['local_last_msg'] = isset($realBoardCounts[$row['id_board']]) ? $realBoardCounts[$row['id_board']] : 0; $resort_me[$row['child_level']][] = $row; } $smcFunc['db_free_result']($request); krsort($resort_me); $lastModifiedMsg = array(); foreach ($resort_me as $rows) { foreach ($rows as $row) { // The latest message is the latest of the current board and its children. if (isset($lastModifiedMsg[$row['id_board']])) { $curLastModifiedMsg = max($row['local_last_msg'], $lastModifiedMsg[$row['id_board']]); } else { $curLastModifiedMsg = $row['local_last_msg']; } // If what is and what should be the latest message differ, an update is necessary. if ($row['local_last_msg'] != $row['id_last_msg'] || $curLastModifiedMsg != $row['id_msg_updated']) { $smcFunc['db_query']('', ' UPDATE {db_prefix}boards SET id_last_msg = {int:id_last_msg}, id_msg_updated = {int:id_msg_updated} WHERE id_board = {int:id_board}', array('id_last_msg' => $row['local_last_msg'], 'id_msg_updated' => $curLastModifiedMsg, 'id_board' => $row['id_board'])); } // Parent boards inherit the latest modified message of their children. if (isset($lastModifiedMsg[$row['id_parent']])) { $lastModifiedMsg[$row['id_parent']] = max($row['local_last_msg'], $lastModifiedMsg[$row['id_parent']]); } else { $lastModifiedMsg[$row['id_parent']] = $row['local_last_msg']; } } } // Update all the basic statistics. updateStats('member'); updateStats('message'); updateStats('topic'); // Finally, update the latest event times. require_once $sourcedir . '/ScheduledTasks.php'; CalculateNextTrigger(); redirectexit('action=admin;area=maintain;sa=routine;done=recount'); }