/** * Standard modular run function for RSS hooks. * * @param string A list of categories we accept from * @param TIME Cutoff time, before which we do not show results from * @param string Prefix that represents the template set we use * @set RSS_ ATOM_ * @param string The standard format of date to use for the syndication type represented in the prefix * @param integer The maximum number of entries to return, ordering by date * @return ?array A pair: The main syndication section, and a title (NULL: error) */ function run($_filters, $cutoff, $prefix, $date_string, $max) { if (!addon_installed('tickets')) { return NULL; } if (!has_actual_page_access(get_member(), 'tickets')) { return NULL; } if (is_guest()) { return NULL; } require_code('tickets'); require_code('tickets2'); $ticket_types = ocfilter_to_idlist_using_callback($_filters, '', NULL, NULL, NULL, NULL, false); if (count($ticket_types) != 0) { $rows = array(); foreach ($ticket_types as $ticket_type) { if (!has_category_access(get_member(), 'tickets', get_translated_text($ticket_type))) { continue; } $rows = array_merge($rows, get_tickets(get_member(), $ticket_type, false, false, true)); } } else { $rows = get_tickets(get_member(), NULL, false, false, true); } require_code('feedback'); $content = new ocp_tempcode(); foreach ($rows as $i => $row) { if ($i == $max) { break; } if ($row['lasttime'] < $cutoff) { continue; } $ticket_id = extract_topic_identifier($row['description']); $ticket_type = $GLOBALS['SITE_DB']->query_value_null_ok('tickets', 'ticket_type', array('ticket_id' => $ticket_id)); $author = $row['firstusername']; $date = date($date_string, $row['firsttime']); $edit_date = date($date_string, $row['lasttime']); $title = xmlentities($row['firsttitle']); $summary = xmlentities($row['firstpost']->evaluate()); $category = ''; $category_raw = ''; if (!is_null($ticket_type)) { $category = get_translated_text($ticket_type); $category_raw = strval($ticket_type); } $view_url = build_url(array('page' => 'tickets', 'type' => 'ticket', 'id' => $ticket_id), get_module_zone('tickets'), NULL, false, false, true); if ($prefix == 'RSS_' && get_option('is_on_comments') == '1') { $if_comments = do_template('RSS_ENTRY_COMMENTS', array('_GUID' => 'b4f25f5cf68304f8d402bb06851489d6', 'COMMENT_URL' => $view_url, 'ID' => strval($ticket_id))); } else { $if_comments = new ocp_tempcode(); } $content->attach(do_template($prefix . 'ENTRY', array('VIEW_URL' => $view_url, 'SUMMARY' => $summary, 'EDIT_DATE' => $edit_date, 'IF_COMMENTS' => $if_comments, 'TITLE' => $title, 'CATEGORY_RAW' => $category_raw, 'CATEGORY' => $category, 'AUTHOR' => $author, 'ID' => $ticket_id, 'NEWS' => '', 'DATE' => $date))); } require_lang('tickets'); return array($content, do_lang('SUPPORT_TICKETS')); }
/** * If necessary, send out a support ticket reply * * @param AUTO_LINK Forum ID * @param AUTO_LINK Topic ID * @param SHORT_TEXT Topic title * @param LONG_TEXT Post made */ function handle_topic_ticket_reply($forum_id, $topic_id, $topic_title, $post) { // E-mail the user or staff if the post is a new one in a support ticket if (addon_installed('tickets')) { require_code('tickets'); require_code('tickets2'); require_code('feedback'); if (is_ticket_forum($forum_id)) { $topic_info = $GLOBALS['FORUM_DB']->query_select('f_topics', array('t_cache_first_title', 't_sunk', 't_forum_id', 't_is_open', 't_description'), array('id' => $topic_id), '', 1); if (!array_key_exists(0, $topic_info)) { warn_exit(do_lang_tempcode('MISSING_RESOURCE')); } $topic_description = $topic_info[0]['t_description']; $ticket_id = extract_topic_identifier($topic_description); $home_url = build_url(array('page' => 'tickets', 'type' => 'ticket', 'id' => $ticket_id), 'site', NULL, false, true); send_ticket_email($ticket_id, $topic_title, $post, $home_url->evaluate(), '', -1); } } }
/** * Actualise to toggle the closed state of a ticket. * * @return tempcode The UI */ function toggle_ticket_closed() { $id = get_param('id'); require_code('feedback'); $action = 'CLOSE_TICKET'; // Our tickets - search them for this ticket, acting as a kind of security check (as we will only iterate through tickets we have access to) $tickets = get_tickets(get_member(), NULL); foreach ($tickets as $ticket) { $ticket_id = extract_topic_identifier($ticket['description']); if ($ticket_id == $id) { if ($ticket['closed'] == 0) { $action = 'OPEN_TICKET'; } $GLOBALS['FORUM_DB']->query_update('f_topics', array('t_is_open' => $ticket['closed']), array('id' => $ticket['id']), '', 1); } } $title = get_page_title($action); $url = build_url(array('page' => '_SELF', 'type' => 'ticket', 'id' => $id), '_SELF'); if (is_guest()) { $url = build_url(array('page' => '_SELF'), '_SELF'); } return redirect_screen($title, $url, do_lang_tempcode('SUCCESS')); }
/** * Update the cache of ticket type lead times (average time taken for a response to tickets of that type) in the database. * This is a query-intensive function, so should only be run occasionally. */ function update_ticket_type_lead_times() { require_code('feedback'); $ticket_types = $GLOBALS['SITE_DB']->query_select('ticket_types', NULL); foreach ($ticket_types as $ticket_type) { $total_lead_time = 0; $tickets_counted = 0; $tickets = $GLOBALS['SITE_DB']->query_select('tickets', NULL, array('ticket_type' => $ticket_type['ticket_type'])); foreach ($tickets as $ticket) { $max_rows = 0; $topic = $GLOBALS['FORUM_DRIVER']->show_forum_topics($ticket['forum_id'], 1, 0, $max_rows, $ticket['ticket_id'], true, 'lasttime', false, do_lang('SUPPORT_TICKET') . ': #' . $ticket['ticket_id']); if (is_null($topic)) { continue; } $topic = $topic[0]; // We need to have two posts for new-style tickets, or three for old-style tickets (with spacers) if ($topic['num'] < 2 || $topic['firstusername'] == do_lang('SYSTEM') && $topic['num'] < 3) { continue; } $ticket_id = extract_topic_identifier($topic['description']); $_forum = 1; $_topic_id = 1; $_ticket_type = 1; // These will be returned by reference $posts = get_ticket_posts($ticket_id, $_forum, $_topic_id, $_ticket_type); // Differentiate between old- and new-style tickets if ($topic['firstusername'] == do_lang('SYSTEM')) { $first_key = 1; } else { $first_key = 0; } // Find the first post by someone other than the ticket owner $i = $first_key + 1; while (array_key_exists($i, $posts) && $posts[$i]['user'] != $posts[$first_key]['user']) { $i++; } if (array_key_exists($i, $posts)) { $total_lead_time += $posts[$i]['date'] - $posts[$first_key]['date']; $tickets_counted++; } } /* Calculate the new lead time and store it in the DB */ if ($tickets_counted > 0) { $GLOBALS['SITE_DB']->query_update('ticket_types', array('cache_lead_time' => $total_lead_time / $tickets_counted), array('ticket_type' => $ticket_type['ticket_type']), '', 1); } } }