/**
 *	Marks a ticket resolved or unresolved.
 *
 *	This function identifies whether a given ticket is resolved or not, if not resolved, mark it resolved. If it was resolved
 *	reopen the ticket back to an appropriate status based on last respondent. In both cases, the action is logged in the action log.
 *	It is also unassigned from having a user on either closure or reopen.
 *
 *	Accessed through ?action=helpdesk;sa=resolve;ticket=x;sessvar=sessid before redirecting back to the ticket, or add ;home to the
 *	URL to have it redirect back to the home page.
 *
 *	@since 1.0
*/
function shd_ticket_resolve()
{
    global $smcFunc, $user_info, $context, $sourcedir;
    checkSession('get');
    // First, figure out the state of the ticket - is it resolved or not? Can we even see it?
    if (empty($context['ticket_id'])) {
        fatal_lang_error('shd_no_ticket', false);
    }
    $context['shd_return_to'] = isset($_REQUEST['home']) ? 'home' : 'ticket';
    $query = shd_db_query('', '
		SELECT id_member_started, id_member_updated, status, num_replies, subject, id_dept
		FROM {db_prefix}helpdesk_tickets AS hdt
		WHERE {query_see_ticket}
			AND id_ticket = {int:current_ticket}', array('current_ticket' => $context['ticket_id']));
    if ($row = $smcFunc['db_fetch_assoc']($query)) {
        $smcFunc['db_free_result']($query);
        $action = $row['status'] != TICKET_STATUS_CLOSED ? 'resolve' : 'unresolve';
        call_integration_hook('shd_hook_mark' . $action);
        if (!shd_allowed_to('shd_' . $action . '_ticket_any', $row['id_dept']) && (!shd_allowed_to('shd_' . $action . '_ticket_own', $row['id_dept']) || $row['id_member_started'] != $user_info['id'])) {
            fatal_lang_error('shd_cannot_' . $action, false);
        }
        // OK, so what about any children related tickets that are still open? Eeek, could be awkward.
        if (empty($modSettings['shd_disable_relationships'])) {
            $query = shd_db_query('', '
				SELECT COUNT(hdt.id_ticket)
				FROM {db_prefix}helpdesk_relationships AS rel
					INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (rel.secondary_ticket = hdt.id_ticket)
				WHERE rel.primary_ticket = {int:ticket}
					AND rel.rel_type = {int:parent}
					AND hdt.status NOT IN ({array_int:closed_status})', array('ticket' => $context['ticket_id'], 'parent' => RELATIONSHIP_ISPARENT, 'closed_status' => array(TICKET_STATUS_CLOSED, TICKET_STATUS_DELETED)));
            list($count_children) = $smcFunc['db_fetch_row']($query);
            $smcFunc['db_free_result']($query);
            if (!empty($count_children)) {
                fatal_lang_error('error_shd_cannot_resolve_children', false);
            }
        }
        $new = shd_determine_status($action, $row['id_member_started'], $row['id_member_updated'], $row['num_replies'], $row['id_dept']);
        shd_db_query('', '
			UPDATE {db_prefix}helpdesk_tickets
			SET status = {int:status}
			WHERE id_ticket = {int:ticket}', array('status' => $new, 'ticket' => $context['ticket_id']));
        shd_log_action($action, array('ticket' => $context['ticket_id'], 'subject' => $row['subject']));
        shd_clear_active_tickets($row['id_dept']);
        if ($context['shd_return_to'] == 'home') {
            redirectexit($context['shd_home'] . $context['shd_dept_link']);
        } else {
            redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']);
        }
    } else {
        fatal_lang_error('shd_no_ticket', false);
    }
}
Esempio n. 2
0
function shd_save_reply()
{
    global $txt, $modSettings, $sourcedir, $context, $scripturl;
    global $user_info, $options, $smcFunc, $memberContext;
    $_REQUEST['msg'] = !empty($_REQUEST['msg']) ? (int) $_REQUEST['msg'] : 0;
    // We're replying so there must be an existing ticket or sumthin's WRONG.
    $ticketinfo = shd_load_ticket();
    $reply = array();
    $new_reply = $_REQUEST['msg'] == 0;
    // So, at this point, we can see it, but no guarantee we can reply to it.
    // Can we reply to any? If so, just go right along. If not, we need to do more work.
    if ($new_reply) {
        if (!shd_allowed_to('shd_reply_ticket_any', $ticketinfo['dept'])) {
            if (shd_allowed_to('shd_reply_ticket_own', $ticketinfo['dept'])) {
                if (!$ticketinfo['is_own']) {
                    fatal_lang_error('shd_cannot_reply_any_but_own', false);
                }
            } else {
                fatal_lang_error('shd_cannot_reply_any', false);
            }
            // can't do nuthin'
        }
    } else {
        $query = shd_db_query('', '
			SELECT id_msg, id_member, body, modified_time, modified_member, modified_name
			FROM {db_prefix}helpdesk_ticket_replies
			WHERE id_msg = {int:msg}
				AND id_ticket = {int:ticket}', array('msg' => $_REQUEST['msg'], 'ticket' => $context['ticket_id']));
        if ($smcFunc['db_num_rows']($query) == 0) {
            $smcFunc['db_free_result']($query);
            fatal_lang_error('shd_no_ticket', false);
        }
        $reply = $smcFunc['db_fetch_assoc']($query);
        if (!shd_allowed_to('shd_edit_reply_any', $ticketinfo['dept'])) {
            if (shd_allowed_to('shd_edit_reply_own', $ticketinfo['dept'])) {
                if ($reply['id_member'] != $user_info['id']) {
                    fatal_lang_error('shd_cannot_edit_reply_any_but_own', false);
                }
            } else {
                fatal_lang_error('shd_cannot_edit_reply_any', false);
            }
        }
    }
    $context['ticket_form'] = array('dept' => $ticketinfo['dept'], 'form_title' => $new_reply ? $txt['shd_reply_ticket'] : $txt['shd_ticket_edit_reply'], 'form_action' => $scripturl . '?action=helpdesk;sa=savereply', 'first_msg' => $new_reply ? 0 : $ticketinfo['id_first_msg'], 'message' => shd_format_text($ticketinfo['body'], $ticketinfo['smileys_enabled'], $new_reply ? '' : 'shd_reply_' . $ticketinfo['id_first_msg']), 'subject' => $ticketinfo['subject'], 'ticket' => $context['ticket_id'], 'msg' => $_REQUEST['msg'], 'display_id' => str_pad($context['ticket_id'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT), 'urgency' => array('setting' => $ticketinfo['urgency']), 'private' => array('setting' => $ticketinfo['private'], 'can_change' => false, 'options' => array(0 => 'shd_ticket_notprivate', 1 => 'shd_ticket_private')), 'status' => $ticketinfo['status'], 'member' => array('name' => $ticketinfo['starter_name'], 'id' => $ticketinfo['starter_id'], 'link' => shd_profile_link($ticketinfo['starter_name'], $ticketinfo['starter_id'])), 'assigned' => array('id' => $ticketinfo['assigned_id'], 'name' => !empty($ticketinfo['assigned_id']) ? $ticketinfo['assigned_name'] : $txt['shd_unassigned'], 'link' => !empty($ticketinfo['assigned_id']) ? shd_profile_link($ticketinfo['assigned_name'], $ticketinfo['assigned_id']) : '<span class="error">' . $txt['shd_unassigned'] . '</span>'), 'num_replies' => $ticketinfo['num_replies'], 'do_attach' => shd_allowed_to('shd_post_attachment', $ticketinfo['dept']), 'reply' => $_POST['shd_message'], 'return_to_ticket' => isset($_REQUEST['goback']), 'disable_smileys' => !empty($_REQUEST['no_smileys']));
    $context['can_solve'] = shd_allowed_to('shd_resolve_ticket_any', $ticketinfo['dept']) || shd_allowed_to('shd_resolve_ticket_own', $ticketinfo['dept']) && $ticketinfo['starter_id'] == $user_info['id'];
    $context['can_silent_update'] = $new_reply && shd_allowed_to('shd_silent_update', $ticketinfo['dept']);
    $context['log_action'] = $new_reply ? 'newreply' : 'editreply';
    $context['log_params']['subject'] = $context['ticket_form']['subject'];
    shd_posting_additional_options();
    shd_load_canned_replies();
    $context['can_ping'] = $new_reply && shd_allowed_to('shd_singleton_email', $context['ticket_form']['dept']);
    // Ticket privacy
    if (empty($modSettings['shd_privacy_display']) || $modSettings['shd_privacy_display'] == 'smart') {
        $context['display_private'] = shd_allowed_to('shd_view_ticket_private_any', $ticketinfo['dept']) || shd_allowed_to('shd_alter_privacy_own', $ticketinfo['dept']) || shd_allowed_to('shd_alter_privacy_any', $ticketinfo['dept']) || $context['ticket_form']['private']['setting'];
    } else {
        $context['display_private'] = true;
    }
    loadMemberData($ticketinfo['starter_id']);
    if (loadMemberContext($ticketinfo['starter_id'])) {
        $context['ticket_form']['member']['avatar'] = $memberContext[$ticketinfo['starter_id']]['avatar'];
    }
    if (!empty($ticketinfo['modified_time'])) {
        $context['ticket_form'] += array('modified' => array('name' => $ticketinfo['modified_name'], 'id' => $ticketinfo['modified_id'], 'time' => timeformat($ticketinfo['modified_time']), 'link' => shd_profile_link($ticketinfo['modified_name'], $ticketinfo['modified_id'])));
    }
    if (isset($_REQUEST['preview'])) {
        $context['ticket_form']['preview'] = array('title' => $txt['shd_previewing_reply'] . ': ' . (empty($context['ticket_form']['subject']) ? '<em>' . $txt['no_subject'] . '</em>' : $context['ticket_form']['subject']), 'body' => shd_format_text($_POST['shd_message']));
    }
    shd_load_attachments();
    shd_get_urgency_options($ticketinfo['is_own'], $ticketinfo['dept']);
    $context['ticket_form']['urgency']['can_change'] = false;
    if (!empty($ticketinfo['num_replies'])) {
        shd_setup_replies($ticketinfo['id_first_msg']);
    }
    // A few basic checks
    if ($context['ticket_form']['status'] == TICKET_STATUS_CLOSED) {
        fatal_lang_error('shd_cannot_edit_closed', false);
    } elseif ($context['ticket_form']['status'] == TICKET_STATUS_DELETED) {
        fatal_lang_error('shd_cannon_edit_deleted', false);
    }
    // Have there been any new replies that we missed?
    if (empty($options['no_new_reply_warning']) && isset($_REQUEST['num_replies'])) {
        $_REQUEST['num_replies'] = (int) $_REQUEST['num_replies'];
        $newReplies = $context['ticket_form']['num_replies'] > $_REQUEST['num_replies'] ? $context['ticket_form']['num_replies'] - $_REQUEST['num_replies'] : 0;
        if (!empty($newReplies)) {
            loadLanguage('Post');
            if ($newReplies > 1) {
                $txt['error_new_replies'] = sprintf($txt['error_new_replies'], $newReplies);
            }
            $context['shd_errors'][] = $newReplies == 1 ? 'new_reply' : 'new_replies';
        }
    }
    // OK, does the user want to close this ticket? Are there any problems with that?
    if (!empty($context['can_solve']) && !empty($_POST['resolve_ticket'])) {
        $string = shd_check_dependencies();
        if (!empty($string)) {
            $context['shd_errors'][] = $string;
        }
    }
    // Custom fields?
    shd_load_custom_fields(false, $context['ticket_form']['msg'], $context['ticket_form']['dept']);
    list($missing_fields, $invalid_fields) = shd_validate_custom_fields($context['ticket_form']['msg'], $context['ticket_form']['dept']);
    $context['can_override_fields'] = shd_allowed_to('shd_override_cf', $context['ticket_form']['dept']);
    $context['overriding_fields'] = $context['can_override_fields'] && isset($_POST['override_cf']);
    // Did any custom fields fail validation?
    if (!empty($invalid_fields)) {
        $context['shd_errors'][] = 'invalid_fields';
        $txt['error_invalid_fields'] = sprintf($txt['error_invalid_fields'], implode(', ', $invalid_fields));
    }
    // Any flat-out missing?
    if (!empty($missing_fields) && !$context['overriding_fields']) {
        $context['shd_errors'][] = 'missing_fields';
        $txt['error_missing_fields'] = sprintf($txt['error_missing_fields'], implode(', ', $missing_fields));
    }
    if ($context['can_override_fields'] && !empty($missing_fields)) {
        $context['ticket_form']['additional_opts']['override_cf'] = array('show' => true, 'checked' => false, 'text' => $txt['shd_override_cf']);
    }
    if (!empty($context['shd_errors']) || !empty($context['ticket_form']['preview'])) {
        checkSubmitOnce('free');
        // Anything else for redisplaying the form
        $context['page_title'] = $txt['shd_helpdesk'];
        $context['sub_template'] = 'reply_post';
        // Oh, yeah, we need to look at the existing notifications pinging stuff, if appropriate, and reset that.
        if ($context['can_ping'] && !empty($_POST['notify']) && is_array($_POST['notify'])) {
            $items = array();
            foreach ($_POST['notify'] as $item) {
                if (!empty($item) && is_numeric($item)) {
                    $items[] = $item;
                }
            }
            if (!empty($items)) {
                $context['notification_ping_list'] = implode(',', $items);
            }
        }
        shd_check_attachments();
        // Set up the fancy editor
        shd_postbox('shd_message', un_preparsecode($_POST['shd_message']), array('post_button' => $new_reply ? $txt['shd_reply_ticket'] : $txt['shd_ticket_edit_reply']));
        // Build the link tree and navigation
        $context['linktree'][] = array('name' => $txt['shd_reply_ticket']);
        checkSubmitOnce('register');
    } else {
        // It all worked, w00t, so let's get ready to rumble
        $attachIDs = shd_handle_attachments();
        if ($new_reply) {
            // So... what is the new status?
            $new_status = shd_determine_status('reply', $ticketinfo['starter_id'], $user_info['id'], -1, $context['ticket_form']['dept']);
            // We explicitly don't care about how many replies - but it must be non-zero. Default in function spec is -1.
            // Now to add the ticket details
            $posterOptions = array('id' => $user_info['id']);
            $msgOptions = array('body' => $_POST['shd_message'], 'id' => $context['ticket_form']['msg'], 'smileys_enabled' => empty($context['ticket_form']['disable_smileys']), 'attachments' => $attachIDs, 'custom_fields' => !empty($context['ticket_form']['custom_fields'][$context['ticket_form']['msg']]) ? $context['ticket_form']['custom_fields'][$context['ticket_form']['msg']] : array());
            $ticketOptions = array('id' => $context['ticket_form']['ticket'], 'mark_as_read' => true, 'status' => $new_status);
            if (!empty($context['can_solve']) && !empty($_POST['resolve_ticket'])) {
                $ticketOptions['status'] = TICKET_STATUS_CLOSED;
                shd_log_action('resolve', array('ticket' => $context['ticket_id'], 'subject' => $ticketinfo['subject']));
            }
            shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions);
            // Handle notifications
            require_once $sourcedir . '/sd_source/SimpleDesk-Notifications.php';
            shd_notifications_notify_newreply($msgOptions, $ticketOptions, $posterOptions);
        } else {
            // Only add what has actually changed
            // Now to add the ticket details
            $posterOptions = array();
            $msgOptions = array('id' => $context['ticket_form']['msg'], 'attachments' => $attachIDs, 'custom_fields' => !empty($context['ticket_form']['custom_fields'][$context['ticket_form']['msg']]) ? $context['ticket_form']['custom_fields'][$context['ticket_form']['msg']] : array());
            $ticketOptions = array('id' => $context['ticket_form']['ticket']);
            if ((bool) $ticketinfo['smileys_enabled'] == $context['ticket_form']['disable_smileys']) {
                // since one is enabled, one is 'now disable'...
                $msgOptions['smileys_enabled'] = !$context['ticket_form']['disable_smileys'];
            }
            if ($reply['body'] != $context['ticket_form']['reply']) {
                $msgOptions['body'] = $context['ticket_form']['reply'];
            }
            if (isset($msgOptions['body'])) {
                $msgOptions['modified'] = array('id' => $user_info['id'], 'name' => $user_info['name'], 'time' => time());
            }
            if (!empty($context['can_solve']) && !empty($_POST['resolve_ticket'])) {
                $ticketOptions['status'] = TICKET_STATUS_CLOSED;
                shd_log_action('resolve', array('ticket' => $context['ticket_id'], 'subject' => $ticketinfo['subject']));
            }
            // DOOOOOOOO EEEEEEEEEEET NAO!
            shd_modify_ticket_post($msgOptions, $ticketOptions, $posterOptions);
            // OK, did we get any custom fields back?
            foreach ($context['custom_fields_updated'] as $field) {
                $action = 'cf_' . ($field['scope'] == CFIELD_TICKET ? 'tkt' : 'rpl') . (empty($field['default']) ? 'change_' : 'chgdef_') . ($field['visible'][0] ? 'user' : '') . ($field['visible'][1] ? 'staff' : '') . 'admin';
                unset($field['default'], $field['scope'], $field['visible']);
                $field['subject'] = $ticketinfo['subject'];
                shd_log_action($action, $field);
            }
        }
        $context['ticket_form']['msg'] = $msgOptions['id'];
        shd_done_posting();
    }
}
Esempio n. 3
0
function shd_reply_restore()
{
    global $smcFunc, $user_info, $context, $sourcedir;
    checkSession('get');
    $_REQUEST['reply'] = empty($_REQUEST['reply']) ? 0 : (int) $_REQUEST['reply'];
    if (empty($_REQUEST['reply'])) {
        fatal_lang_error('shd_no_ticket', false);
    }
    // Check we can actually see the ticket we're restoring from, and that we can restore this reply
    $query_ticket = shd_db_query('', '
		SELECT hdt.id_ticket, hdt.id_dept, hdtr.id_member, hdt.id_member_started, hdt.id_member_updated, hdt.num_replies, hdt.subject, hdt.status, hdtr.message_status
		FROM {db_prefix}helpdesk_tickets AS hdt
			INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdt.id_ticket = hdtr.id_ticket)
		WHERE {query_see_ticket}
			AND hdtr.id_msg = {int:reply}
			AND hdt.id_first_msg != {int:reply2}', array('reply' => $_REQUEST['reply'], 'reply2' => $_REQUEST['reply']));
    if ($row = $smcFunc['db_fetch_assoc']($query_ticket)) {
        $smcFunc['db_free_result']($query_ticket);
        if ($row['status'] == TICKET_STATUS_DELETED || $row['status'] == TICKET_STATUS_CLOSED || $row['message_status'] != MSG_STATUS_DELETED || !shd_allowed_to('shd_restore_reply_any', $row['id_dept']) && (!shd_allowed_to('shd_restore_reply_own', $row['id_dept']) || $user_info['id'] != $row['id_member'])) {
            fatal_lang_error('shd_cannot_restore_reply', false);
        }
        $context['ticket_id'] = (int) $row['id_ticket'];
        $subject = $row['subject'];
        $starter = $row['id_member_started'];
        $replier = $row['id_member_updated'];
        $num_replies = $row['num_replies'];
    } else {
        $smcFunc['db_free_result']($query_ticket);
        fatal_lang_error('shd_no_ticket', false);
    }
    // The ticket's id is in $context['ticket_id'], the reply id in $_REQUEST['reply'].
    call_integration_hook('shd_hook_restorereply');
    // OK, let's clear this one, hasta la vista... ticket.
    shd_db_query('', '
		UPDATE {db_prefix}helpdesk_ticket_replies
		SET message_status = {int:msg_status_deleted}
		WHERE id_msg = {int:reply}', array('msg_status_deleted' => MSG_STATUS_NORMAL, 'reply' => $_REQUEST['reply']));
    // Captain's Log, stardate 18.3.10.1010
    shd_log_action('restore_reply', array('ticket' => $context['ticket_id'], 'subject' => $subject, 'msg' => $_REQUEST['reply']));
    // Fix the topic data
    list($starter, $replier, $num_replies) = shd_recalc_ids($context['ticket_id']);
    $query_reply = shd_db_query('', '
		UPDATE {db_prefix}helpdesk_tickets
		SET status = {int:status}
		WHERE id_ticket = {int:ticket}', array('ticket' => $context['ticket_id'], 'status' => shd_determine_status('restorereply', $starter, $replier, $num_replies, $row['id_dept'])));
    // Expire the cache of count(active tickets)
    shd_clear_active_tickets($row['id_dept']);
    redirectexit('action=helpdesk;sa=ticket;ticket=' . $context['ticket_id']);
}
/**
 *	Handles moving a topic into the helpdesk.
 *
 *	After checking permissions, and so on, begin to actually move posts.
 *
 *	Broadly this is done using {@link shd_create_ticket_post()}, which has hooks specifically to deal with post modification times (written in specifically to ease this function's workload)
 *
 *	Operations:
 *	- get the topic information (and checking topic access permission in the process)
 *	- identify the status of the topic (new/with staff/with user)
 *	- create the new ticket from these details
 *	- assuming there are replies, query for them
 *	- step through and repost
 *	- send the notification PM if we're doing that
 *	- update the attachments table
 *	- update the action log
 *	- remove the topic from the forum
 *
 *	@see shd_topictoticket()
 *	@since 1.0
*/
function shd_topictoticket2()
{
    global $smcFunc, $context, $txt, $modSettings, $scripturl, $sourcedir;
    checkSession();
    checkSubmitOnce('check');
    $_REQUEST['dept'] = isset($_REQUEST['dept']) ? (int) $_REQUEST['dept'] : 0;
    if (empty($_REQUEST['dept'])) {
        $_REQUEST['dept'] = -1;
    }
    // which is never a valid department!
    if (!shd_allowed_to('shd_topic_to_ticket', $_REQUEST['dept']) || !empty($modSettings['shd_helpdesk_only']) || !empty($modSettings['shd_disable_tickettotopic'])) {
        fatal_lang_error('shd_cannot_move_topic', false);
    }
    if (empty($_REQUEST['topic'])) {
        fatal_lang_error('shd_no_topic');
    }
    $context['topic_id'] = (int) $_REQUEST['topic'];
    // Just in case, are they cancelling?
    if (isset($_REQUEST['cancel'])) {
        redirectexit('topic=' . $context['topic_id']);
    }
    if (isset($_POST['send_pm']) && (!isset($_POST['pm_content']) || trim($_POST['pm_content']) == '')) {
        fatal_lang_error('shd_move_no_pm_topic', false);
    }
    require_once $sourcedir . '/sd_source/Subs-SimpleDeskPost.php';
    // Fetch the topic information.
    $request = shd_db_query('', '
		SELECT m.subject, t.id_board, t.id_member_started, m.body, t.id_first_msg, m.smileys_enabled, t.id_member_updated, t.num_replies,
		m.poster_email, m.poster_name, m.poster_ip, m.poster_time, m.modified_time, m.modified_name, m.id_msg
		FROM {db_prefix}topics AS t
			INNER JOIN {db_prefix}messages AS m ON (m.id_msg = t.id_first_msg)
			INNER JOIN {db_prefix}boards AS b ON (t.id_board = b.id_board)
		WHERE {query_see_board} AND t.id_topic = {int:topic}
		LIMIT 1', array('topic' => $context['topic_id']));
    if ($smcFunc['db_num_rows']($request) == 0) {
        fatal_lang_error('shd_move_ticket_not_created');
    } else {
        list($subject, $board, $owner, $body, $firstmsg, $smileys_enabled, $memberupdated, $numreplies, $postername, $posteremail, $posterip, $postertime, $modified_time, $modified_name, $smf_id_msg) = $smcFunc['db_fetch_row']($request);
    }
    $smcFunc['db_free_result']($request);
    // Figure out what the status of the ticket should be.
    $status = shd_determine_status('topictoticket', $owner, $memberupdated, $numreplies, $_REQUEST['dept']);
    // Are we changing the subject?
    $old_subject = $subject;
    $subject = !empty($_POST['change_subject']) && !empty($_POST['subject']) ? $_POST['subject'] : $subject;
    // Just before we do this, make sure we call any hooks. $context and $_POST have lots of interesting things for us.
    call_integration_hook('shd_hook_topictoticket');
    // All okay, it seems. Let's go create the ticket.
    $msg_assoc = array();
    $msgOptions = array('body' => $body, 'smileys_enabled' => !empty($smileys_enabled) ? 1 : 0, 'modified' => array('time' => $modified_time, 'name' => $modified_name), 'time' => $postertime);
    $ticketOptions = array('dept' => $_REQUEST['dept'], 'subject' => $subject, 'mark_as_read' => false, 'private' => false, 'status' => $status, 'urgency' => 0, 'assigned' => 0);
    $posterOptions = array('id' => $owner, 'name' => $postername, 'email' => $posteremail, 'ip' => $posterip);
    shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions);
    $msg_assoc[$smf_id_msg] = $msgOptions['id'];
    // Ticket created, let's dig out the replies and post them in the ticket, if there are any.
    if (isset($ticketOptions['id'])) {
        $request = shd_db_query('', '
			SELECT body, id_member, poster_time, poster_name, poster_email, poster_ip, smileys_enabled, id_msg
			FROM {db_prefix}messages
			WHERE id_topic = {int:topic}
			AND id_msg != {int:topic_msg}', array('topic' => $context['topic_id'], 'topic_msg' => $firstmsg));
        $num_replies = $smcFunc['db_num_rows']($request) + 1;
        // Plus one since we want to count the main ticket post as well.
        // The ID of the ticket we created
        $ticket = $ticketOptions['id'];
        if ($smcFunc['db_num_rows']($request) != 0) {
            // Now loop through each reply and post it.  Hopefully there aren't too many. *looks at clock*
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $msgOptions = array('body' => $row['body'], 'smileys_enabled' => !empty($row['smileys_enabled']) ? 1 : 0);
                $ticketOptions = array('id' => $ticket, 'mark_as_read' => false);
                $posterOptions = array('id' => $row['id_member'], 'name' => !empty($row['poster_name']) ? $row['poster_name'] : '', 'email' => !empty($row['poster_email']) ? $row['poster_email'] : '', 'ip' => !empty($row['poster_ip']) ? $row['poster_ip'] : '');
                shd_create_ticket_post($msgOptions, $ticketOptions, $posterOptions);
                $msg_assoc[$row['id_msg']] = $msgOptions['id'];
            }
        }
        // Ticket: check; Replies: check; Notfiy the topic starter, if desired.
        if (isset($_POST['send_pm'])) {
            require_once $sourcedir . '/Subs-Post.php';
            $request = shd_db_query('pm_find_username', '
				SELECT id_member, real_name
				FROM {db_prefix}members
				WHERE id_member = {int:user}
				LIMIT 1', array('user' => $owner));
            list($userid, $username) = $smcFunc['db_fetch_row']($request);
            $smcFunc['db_free_result']($request);
            // Fix the content
            $replacements = array('{user}' => $username, '{subject}' => $old_subject, '{link}' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $ticket);
            $message = str_replace(array_keys($replacements), array_values($replacements), $_POST['pm_content']);
            $recipients = array('to' => array($owner), 'bcc' => array());
            sendpm($recipients, $txt['shd_ticket_moved_subject_topic'], un_htmlspecialchars($message));
        }
        // And now for something completely different: attachments
        if (!empty($msg_assoc)) {
            // 1. Get all the attachments for these messages from the attachments table
            $attachIDs = array();
            $query = shd_db_query('', '
				SELECT id_attach, id_msg
				FROM {db_prefix}attachments
				WHERE id_msg IN ({array_int:smf_msgs})', array('smf_msgs' => array_keys($msg_assoc)));
            while ($row = $smcFunc['db_fetch_assoc']($query)) {
                $attachIDs[] = $row;
            }
            $smcFunc['db_free_result']($query);
            if (!empty($attachIDs)) {
                // 2. Do the switch
                // 2.1. Add them to SD's tables
                $array = array();
                foreach ($attachIDs as $attach) {
                    $array[] = array($attach['id_attach'], $ticket, $msg_assoc[$attach['id_msg']]);
                }
                $smcFunc['db_insert']('replace', '{db_prefix}helpdesk_attachments', array('id_attach' => 'int', 'id_ticket' => 'int', 'id_msg' => 'int'), $array, array('id_attach'));
                // 2.2. "Remove" them from SMF's table
                shd_db_query('', '
					UPDATE {db_prefix}attachments
					SET id_msg = 0
					WHERE id_msg IN ({array_int:smf_msgs})', array('smf_msgs' => array_keys($msg_assoc)));
            }
        }
        // Now we'll add this to the log.
        $log_params = array('subject' => $subject, 'ticket' => $ticket);
        shd_log_action('topictoticket', $log_params);
        // Update post counts.
        $request = shd_db_query('', '
			SELECT id_member
			FROM {db_prefix}messages
			WHERE id_topic = {int:topic}', array('topic' => $context['topic_id']));
        $posters = array();
        while ($row = $smcFunc['db_fetch_assoc']($request)) {
            if (!isset($posters[$row['id_member']])) {
                $posters[$row['id_member']] = 0;
            }
            $posters[$row['id_member']]++;
        }
        $smcFunc['db_free_result']($request);
        foreach ($posters as $id_member => $posts) {
            updateMemberData($id_member, array('posts' => 'posts - ' . $posts));
        }
        // Lastly, delete the topic from the database.
        shd_db_query('', '
			DELETE FROM {db_prefix}topics
			WHERE id_topic = {int:topic}
			LIMIT 1', array('topic' => $context['topic_id']));
        // And the replies, too.
        shd_db_query('', '
			DELETE FROM {db_prefix}messages
			WHERE id_topic = {int:topic}', array('topic' => $context['topic_id']));
        // Update the stats.
        require_once $sourcedir . '/Subs-Post.php';
        updateStats('message');
        updateStats('topic');
        updateLastMessages($board);
        // Update board post counts.
        shd_db_query('', '
			UPDATE {db_prefix}boards
			SET num_topics = num_topics - 1,
				num_posts = num_posts - {int:num_posts}
			WHERE id_board = {int:board}', array('board' => $board, 'num_posts' => $num_replies));
    } else {
        fatal_lang_error('shd_move_ticket_not_created', false);
    }
    // Send them to the ticket.
    redirectexit('action=helpdesk;sa=ticket;ticket=' . $ticket);
}
Esempio n. 5
0
function shd_maint_status()
{
    global $context, $smcFunc, $txt;
    $open = array(TICKET_STATUS_NEW, TICKET_STATUS_PENDING_STAFF, TICKET_STATUS_PENDING_USER);
    // First we need the number of tickets
    $query = $smcFunc['db_query']('', '
		SELECT COUNT(*)
		FROM {db_prefix}helpdesk_tickets
		WHERE status IN ({array_int:open})', array('open' => $open));
    list($ticket_count) = $smcFunc['db_fetch_row']($query);
    $smcFunc['db_free_result']($query);
    $_REQUEST['start'] = isset($_REQUEST['start']) ? (int) $_REQUEST['start'] : 0;
    $step_size = 100;
    $tickets = array();
    $tickets_modify = array();
    $query = $smcFunc['db_query']('', '
		SELECT id_ticket, num_replies, id_member_started, id_member_updated, status, id_dept
		FROM {db_prefix}helpdesk_tickets
		WHERE status IN ({array_int:open})
		ORDER BY id_ticket ASC
		LIMIT {int:start}, {int:limit}', array('open' => $open, 'start' => $_REQUEST['start'], 'limit' => $step_size));
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $tickets[$row['id_ticket']] = $row;
    }
    $smcFunc['db_free_result']($query);
    if (!empty($tickets)) {
        foreach ($tickets as $ticket) {
            $new_status = shd_determine_status('reply', $ticket['id_member_started'], $ticket['id_member_updated'], $ticket['num_replies'], $ticket['id_dept']);
            if ($ticket['status'] != $new_status) {
                $tickets_modify[$ticket['id_ticket']] = $new_status;
            }
        }
        // Any to update?
        if (!empty($tickets_modify)) {
            // Oh crap.
            foreach ($tickets_modify as $id_ticket => $status) {
                $smcFunc['db_query']('', '
					UPDATE {db_prefix}helpdesk_tickets
					SET status = {int:status}
					WHERE id_ticket = {int:id_ticket}', array('id_ticket' => $id_ticket, 'status' => $status));
            }
            $_SESSION['shd_maint']['status'] = count($tickets_modify);
        }
    }
    // Another round?
    $_REQUEST['start'] += $step_size;
    if ($_REQUEST['start'] > $ticket_count) {
        // All done
        $context['continue_post_data'] .= '<input type="hidden" name="step" value="' . ($context['step'] + 1) . '" />';
    } else {
        // More to do, call back - and provide the subtitle
        $context['continue_post_data'] .= '<input type="hidden" name="step" value="' . $context['step'] . '" />
		<input type="hidden" name="start" value="' . $_REQUEST['start'] . '" />';
        $context['substep_enabled'] = true;
        $context['substep_title'] = $txt['shd_admin_maint_findrepair_firstlast'];
        $context['substep_continue_percent'] = round(100 * $_REQUEST['start'] / $ticket_count);
    }
}