예제 #1
0
function template_ticket_do_replies()
{
    global $context, $settings, $txt, $scripturl, $options, $modSettings, $reply_request;
    echo '
		<div class="tborder">
		<div class="title_bar">
			<h3 class="titlebg">
				<img src="', $settings['default_images_url'], '/simpledesk/replies.png" alt="x" /> ', $txt['shd_ticket_replies'], '
			</h3>
		</div>
		<div class="roundframe" id="replies">
			<div class="content">';
    if (!empty($reply_request)) {
        while ($reply = $context['get_replies']()) {
            echo '
					<div class="description shd_reply" id="reply', $reply['id'], '">
								<span class="floatleft shd_posterinfo">
									<strong class="shd_postername">
										', $reply['member']['link'], '
									</strong>
									<br />
									', $reply['member']['group'], '<br class="shd_groupmargin" />';
            if (!empty($modSettings['shd_display_avatar']) && empty($options['show_no_avatars']) && !empty($reply['member']['avatar']['image'])) {
                echo '
							', shd_profile_link($reply['member']['avatar']['image'], $reply['member']['id']);
            }
            if ($modSettings['shd_staff_badge'] == (!empty($reply['is_staff']) ? 'staffbadge' : 'userbadge') || $modSettings['shd_staff_badge'] == 'bothbadge') {
                echo '<br />
							', $reply['member']['group_stars'];
            } elseif (!empty($reply['is_staff']) && $modSettings['shd_staff_badge'] == 'nobadge') {
                echo '<br />
							<img src="', $settings['default_images_url'] . '/simpledesk/staff.png" class="shd_smallicon" title="', $txt['shd_ticket_staff'], '" alt="', $txt['shd_ticket_staff'], '" />';
            }
            echo '
						</span>
						<div class="shd_replyarea">
							<div class="smalltext">
								<span class="floatright shd_ticketlinks">';
            if ($context['can_quote']) {
                echo '
											<img src="', $settings['default_images_url'], '/simpledesk/quote.png" class="shd_smallicon" alt="*" /><a onclick="return oQuickReply.quote(', $reply['id'], ', \'', $context['session_id'], '\', \'', $context['session_var'], '\', true);" href="', $scripturl, '?action=helpdesk;sa=reply;ticket=', $context['ticket_id'], ';quote=', $reply['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_quote_short'], '</a>';
            }
            echo '
								</span>
								', sprintf($txt['shd_reply_written'], $reply['time']), '
							</div>
							<hr class="clearfix" />
							', $reply['body'], '
							<br /><br />';
            if (!empty($settings['show_modify']) && !empty($reply['modified'])) {
                echo '
							<div class="smalltext shd_modified" style="margin-top:20px;">
								&#171; <em>', $txt['last_edit'], ': ', $reply['modified']['time'], ' ', $txt['by'], ' ', $reply['modified']['link'], '</em> &#187;
							</div>';
            }
            if (!empty($context['ticket_attach']['reply'][$reply['id']])) {
                echo '
							<div class="smalltext">
								<strong>', $txt['shd_ticket_attachments'], '</strong><br />
								<ul class="shd_replyattachments">';
                foreach ($context['ticket_attach']['reply'][$reply['id']] as $attach) {
                    echo '
									<li>', $attach['link'], '</li>';
                }
                echo '
								</ul>
							</div>';
            }
            echo '
						</div>';
            if (!empty($context['can_see_ip']) && !empty($reply['ip_address'])) {
                echo '
						<span class="floatright"><img src="', $settings['default_images_url'], '/simpledesk/ip.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_ip'], ': ', $reply['ip_address'], '</span>';
            }
            echo '
						<br class="clear" />
					</div>';
        }
    }
    echo '
				</div>
			</div>
			<span class="lowerframe"><span></span></span>
		</div>';
}
예제 #2
0
function shd_profile_show_notify_override($memID)
{
    global $txt, $user_info, $scripturl, $modSettings, $smcFunc, $board, $user_profile, $context;
    $context['notify_type'] = $_GET['sa'];
    // We already checked it's monitor or ignore, if we didn't, we wouldn't be here!
    $context['page_title'] = $txt['shd_profile_show_' . $context['notify_type'] . '_title'] . ' - ' . $user_profile[$memID]['real_name'];
    $context['sub_template'] = 'shd_profile_show_notify_override';
    // The active button.
    $context['show_tickets_navigation'][$context['notify_type']]['active'] = true;
    // Having got the general stuff out the way, let's do the specifics.
    // Ticket, Name, Started By, Replies, Status, Urgency, Updated (+ Updated By?)
    $context['tickets'] = array();
    $query = shd_db_query('', '
		SELECT hdt.id_ticket, hdt.subject, IFNULL(mem.id_member, 0) AS starter_id, IFNULL(mem.real_name, hdtr.poster_name) AS starter_name,
			hdt.num_replies, hdt.status, hdt.urgency, hdt.last_updated
		FROM {db_prefix}helpdesk_notify_override AS hdno
			INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdno.id_ticket = hdt.id_ticket)
			INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdt.id_first_msg = hdtr.id_msg)
			LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_started = mem.id_member)
		WHERE {query_see_ticket}
			AND hdno.id_member = {int:user}
			AND hdno.notify_state = {int:notify}
		ORDER BY last_updated DESC', array('user' => $memID, 'notify' => $context['notify_type'] == 'monitor' ? NOTIFY_ALWAYS : NOTIFY_NEVER));
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $row += array('id_ticket_display' => str_pad($row['id_ticket'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT), 'updated' => timeformat($row['last_updated']), 'ticket_starter' => shd_profile_link($row['starter_name'], $row['starter_id']));
        $context['tickets'][] = $row;
    }
}
예제 #3
0
/**
 *	Handles fetching the information for the helpdesk display within the unread and unread replies pages.
 *
 *	The content is 'appended' below the unread posts information by way of a template layer.
 *
 *	@since 2.0
*/
function shd_unread_posts()
{
    global $smcFunc, $context, $user_info, $sourcedir, $txt, $scripturl, $user_profile, $modSettings;
    // Are we using Dragooon's very swish mobile theme, or other wireless? If so, disable this.
    if (WIRELESS || isset($_REQUEST['thememode']) && $_REQUEST['thememode'] == 'mobile' || isset($_COOKIE['smf4m_cookie']) && $_COOKIE['smf4m_cookie'] == 'mobile') {
        $modSettings['shd_disable_unread'] = true;
    }
    // We're only displaying this to staff. We didn't do this check on bootstrapping, no sense doing it every page load.
    if (shd_allowed_to('shd_staff', 0) && empty($modSettings['shd_disable_unread'])) {
        // Get the data
        $context['shd_preferences'] = shd_load_user_prefs();
        $context['shd_unread_info'] = array();
        if (empty($context['shd_preferences']['display_unread_type']) || $context['shd_preferences']['display_unread_type'] == 'outstanding') {
            // Get all the outstanding tickets
            $context['block_title'] = $txt['shd_tickets_open'];
            $request = shd_db_query('', '
				SELECT hdt.id_ticket, hdt.subject, hdt.id_ticket, hdt.num_replies, hdt.last_updated,
					hdtr_first.poster_name, hdt.urgency, hdt.status, hdt.id_member_started, hdt.id_member_assigned, hdt.id_last_msg AS log_read
				FROM {db_prefix}helpdesk_tickets AS hdt
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
				WHERE {query_see_ticket}
					AND hdt.status IN ({array_int:status})
				ORDER BY hdt.urgency DESC, hdt.last_updated', array('status' => array(TICKET_STATUS_NEW, TICKET_STATUS_PENDING_STAFF)));
        } elseif ($context['shd_preferences']['display_unread_type'] == 'unread') {
            // Only unread ones
            $context['block_title'] = $txt['shd_unread_tickets'];
            $request = shd_db_query('', '
				SELECT hdt.id_ticket, hdt.subject, hdt.id_ticket, hdt.num_replies, hdt.last_updated,
					hdtr_first.poster_name, hdt.urgency, hdt.status, hdt.id_member_started, hdt.id_member_assigned, IFNULL(hdlr.id_msg, 0) AS log_read
				FROM {db_prefix}helpdesk_tickets AS hdt
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
					LEFT JOIN {db_prefix}helpdesk_log_read AS hdlr ON (hdt.id_ticket = hdlr.id_ticket AND hdlr.id_member = {int:user})
				WHERE {query_see_ticket}
					AND hdt.status IN ({array_int:status})
					AND (hdlr.id_msg IS NULL OR hdlr.id_msg < hdt.id_last_msg)
				ORDER BY hdt.urgency DESC, hdt.last_updated', array('user' => $context['user']['id'], 'status' => array(TICKET_STATUS_NEW, TICKET_STATUS_PENDING_STAFF)));
        }
        if (!empty($request)) {
            $members = array();
            while ($row = $smcFunc['db_fetch_assoc']($request)) {
                $row['id_ticket_display'] = str_pad($row['id_ticket'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT);
                $row['updated'] = timeformat($row['last_updated']);
                $context['shd_unread_info'][] = $row;
                if ($row['id_member_started'] != 0) {
                    $members[] = $row['id_member_started'];
                }
                if ($row['id_member_assigned'] != 0) {
                    $members[] = $row['id_member_assigned'];
                }
            }
            loadMemberData(array_unique($members));
            foreach ($context['shd_unread_info'] as $key => $ticket) {
                if (!empty($user_profile[$ticket['id_member_started']])) {
                    $context['shd_unread_info'][$key]['ticket_starter'] = shd_profile_link($user_profile[$ticket['id_member_started']]['member_name'], $ticket['id_member_started']);
                } else {
                    $context['shd_unread_info'][$key]['ticket_starter'] = $ticket['poster_name'];
                }
                if (!empty($user_profile[$ticket['id_member_assigned']])) {
                    $context['shd_unread_info'][$key]['ticket_assigned'] = shd_profile_link($user_profile[$ticket['id_member_assigned']]['member_name'], $ticket['id_member_assigned']);
                } else {
                    $context['shd_unread_info'][$key]['ticket_assigned'] = '<span class="error">' . $txt['shd_unassigned'] . '</span>';
                }
            }
            // And set up the template too.
            loadTemplate('sd_template/SimpleDesk-Unread', 'helpdesk');
            $context['template_layers'][] = 'shd_unread';
        }
    }
    // OK, time to get out of here. If we're here, it's because we have a $_REQUEST['action'] of 'unread' or 'unreadreplies', both of which
    // are defined in $context['shd_unread_actions'] thanks to shd_init_actions back in Subs-SimpleDesk.php.
    require_once $sourcedir . '/' . $context['shd_unread_actions'][$_REQUEST['action']][0];
    $context['shd_unread_actions'][$_REQUEST['action']][1]();
}
예제 #4
0
function shd_prepare_reply_context()
{
    global $settings, $txt, $modSettings, $scripturl, $options, $user_info, $smcFunc;
    global $memberContext, $context, $reply_request;
    if (empty($reply_request)) {
        return false;
    }
    $message = $smcFunc['db_fetch_assoc']($reply_request);
    if (!$message) {
        $smcFunc['db_free_result']($reply_request);
        return false;
    }
    if (!loadMemberContext($message['id_member'], true)) {
        // Notice this information isn't used anywhere else....
        $memberContext[$message['id_member']]['name'] = $message['poster_name'];
        $memberContext[$message['id_member']]['id'] = 0;
        $memberContext[$message['id_member']]['group'] = $txt['guest_title'];
        $memberContext[$message['id_member']]['link'] = $message['poster_name'];
        $memberContext[$message['id_member']]['email'] = $message['poster_email'];
        $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0);
        $memberContext[$message['id_member']]['is_guest'] = true;
        $memberContext[$message['id_member']]['group_stars'] = '';
    }
    $memberContext[$message['id_member']]['ip'] = $message['poster_ip'];
    censorText($message['body']);
    $message['body'] = shd_format_text($message['body'], $message['smileys_enabled'], 'shd_reply_' . $message['id_msg']);
    $output = array('id' => $message['id_msg'], 'member' => &$memberContext[$message['id_member']], 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'body' => $message['body'], 'is_staff' => !empty($context['shd_is_staff'][$message['id_member']]), 'can_edit' => shd_allowed_to('shd_edit_reply_any', $context['ticket_form']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_edit_reply_own', $context['ticket_form']['dept']), 'ip_address' => $message['poster_ip']);
    if (!empty($message['modified_time'])) {
        $output['modified'] = array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'id' => !empty($user_profile[$message['modified_member']]) ? $message['modified_member'] : 0, 'name' => !empty($user_profile[$message['modified_member']]) ? $user_profile[$message['modified_member']]['real_name'] : $message['modified_name']);
        $output['modified']['link'] = shd_profile_link($output['modified']['name'], $output['modified']['id']);
    }
    return $output;
}
예제 #5
0
/**
 *	Gather the data and prepare to display the ticket blocks.
 *
 *	Actually performs the queries to get data for each block, subject to the parameters specified by the calling functions.
 *
 *	It also sets up per-block pagination links, collects a variety of data (enough to populate all the columns as listed in shd_main_helpdesk,
 *	even if not entirely applicable, and populates it all into $context['ticket_blocks']['tickets'], extending the array that was
 *	already there.
 *
 *	@see shd_main_helpdesk()
 *	@see shd_closed_tickets()
 *	@see shd_recycle_bin()
 *	@since 1.0
*/
function shd_helpdesk_listing()
{
    global $context, $txt, $smcFunc, $user_profile, $scripturl, $settings, $user_info, $modSettings, $language;
    if (!empty($context['shd_permission'])) {
        shd_is_allowed_to($context['shd_permission']);
    }
    $block_list = array_keys($context['ticket_blocks']);
    $primary_url = '?action=helpdesk;sa=' . $_REQUEST['sa'];
    // First figure out the start positions of each item and sanitise them
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        if (empty($block['viewing_as_block'])) {
            $num_per_page = !empty($context['shd_preferences']['blocks_' . $block_key . '_count']) ? $context['shd_preferences']['blocks_' . $block_key . '_count'] : $context['items_per_page'];
            $start = empty($_REQUEST['st_' . $block_key]) ? 0 : (int) $_REQUEST['st_' . $block_key];
            $max_value = $block['count'];
            // easier to read
        } else {
            $num_per_page = $context['items_per_page'];
            $max_value = $context['items_per_page'];
            $start = 0;
        }
        if ($start < 0) {
            $start = 0;
        } elseif ($start >= $max_value) {
            $start = max(0, (int) $max_value - ((int) $max_value % (int) $num_per_page == 0 ? $num_per_page : (int) $max_value % (int) $num_per_page));
        } else {
            $start = max(0, (int) $start - (int) $start % (int) $num_per_page);
        }
        $context['ticket_blocks'][$block_key]['start'] = $start;
        $context['ticket_blocks'][$block_key]['num_per_page'] = $num_per_page;
        if ($start != 0) {
            $_REQUEST['st_' . $block_key] = $start;
        } elseif (isset($_REQUEST['st_' . $block_key])) {
            unset($_REQUEST['st_' . $block_key]);
        }
    }
    // Now ordering the columns, separate loop for breaking the two processes apart
    $sort_methods = array('ticketid' => array('sql' => 'hdt.id_ticket'), 'ticketname' => array('sql' => 'hdt.subject'), 'replies' => array('sql' => 'hdt.num_replies'), 'allreplies' => array('sql' => '(hdt.num_replies + hdt.deleted_replies)'), 'urgency' => array('sql' => 'hdt.urgency'), 'updated' => array('sql' => 'hdt.last_updated'), 'assigned' => array('sql' => 'assigned_name', 'sql_select' => 'IFNULL(mem.real_name, 0) AS assigned_name', 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_assigned = mem.id_member)'), 'status' => array('sql' => 'hdt.status'), 'starter' => array('sql' => 'starter_name', 'sql_select' => 'IFNULL(mem.real_name, 0) AS starter_name', 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_started = mem.id_member)'), 'lastreply' => array('sql' => 'last_reply', 'sql_select' => 'IFNULL(mem.real_name, 0) AS last_reply', 'sql_join' => 'LEFT JOIN {db_prefix}members AS mem ON (hdtr_last.id_member = mem.id_member)'));
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        $sort = isset($_REQUEST['so_' . $block_key]) ? $_REQUEST['so_' . $block_key] : (!empty($context['shd_preferences']['block_order_' . $block_key . '_block']) ? $context['shd_preferences']['block_order_' . $block_key . '_block'] : '');
        if (strpos($sort, '_') > 0 && substr_count($sort, '_') == 1) {
            list($sort_item, $sort_dir) = explode('_', $sort);
            if (empty($sort_methods[$sort_item])) {
                $sort_item = 'updated';
                $sort = '';
            }
            if (!in_array($sort_dir, array('asc', 'desc'))) {
                $sort = '';
                $sort_dir = 'asc';
            }
        } else {
            $sort = '';
            $sort_item = 'updated';
            $sort_dir = $_REQUEST['sa'] == 'closedtickets' || $_REQUEST['sa'] == 'recyclebin' ? 'desc' : 'asc';
            // default to newest first if on recyclebin or closed tickets, otherwise oldest first
        }
        if ($sort != '') {
            $_REQUEST['so_' . $block_key] = $sort;
        } elseif (isset($_REQUEST['so_' . $block_key])) {
            unset($_REQUEST['so_' . $block_key]);
        }
        $context['ticket_blocks'][$block_key]['sort'] = array('item' => $sort_item, 'direction' => $sort_dir, 'add_link' => $sort != '', 'sql' => array('select' => !empty($sort_methods[$sort_item]['sql_select']) ? $sort_methods[$sort_item]['sql_select'] : '', 'join' => !empty($sort_methods[$sort_item]['sql_join']) ? $sort_methods[$sort_item]['sql_join'] : '', 'sort' => $sort_methods[$sort_item]['sql'] . ' ' . strtoupper($sort_dir)), 'link_bits' => array());
    }
    // Having got all that, step through the blocks again to determine the full URL fragments
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        foreach ($sort_methods as $method => $sort_details) {
            $context['ticket_blocks'][$block_key]['sort']['link_bits'][$method] = ';so_' . $block_key . '=' . $method . '_' . $block['sort']['direction'];
        }
    }
    // Figure out if the user is filtering on anything, and if so, set up containers for the extra joins, selects, pagination link fragments, etc
    $_REQUEST['field'] = isset($_REQUEST['field']) ? (int) $_REQUEST['field'] : 0;
    $_REQUEST['filter'] = isset($_REQUEST['filter']) ? (int) $_REQUEST['filter'] : 0;
    if ($_REQUEST['field'] > 0 && $_REQUEST['filter'] > 0) {
        $context['filter_fragment'] = ';field=' . $_REQUEST['field'] . ';filter=' . $_REQUEST['filter'];
        $context['filter_join'] = '
				INNER JOIN {db_prefix}helpdesk_custom_fields_values AS hdcfv ON (hdcfv.id_post = hdt.id_ticket AND hdcfv.id_field = {int:field} AND hdcfv.post_type = {int:type_ticket})
				INNER JOIN {db_prefix}helpdesk_custom_fields AS hdcf ON (hdcf.id_field = hdcfv.id_field AND hdcf.active = {int:active})';
        $context['filter_where'] = '
				AND hdcfv.value = {string:filter}';
    } else {
        $context['filter_fragment'] = '';
        $context['filter_join'] = '';
        $context['filter_where'] = '';
    }
    // Now go actually do the whole block thang, setting up space for a list of users and tickets as we go along
    $users = array();
    $tickets = array();
    foreach ($context['ticket_blocks'] as $block_key => $block) {
        if (empty($block['display']) || !empty($block['collapsed'])) {
            continue;
        }
        $context['ticket_blocks'][$block_key]['tickets'] = array();
        // If we're filtering, we have to query it first to figure out how many rows there are in this block. It's not pretty.
        if (!empty($context['filter_join'])) {
            $query = shd_db_query('', '
				SELECT COUNT(hdt.id_ticket)
				FROM {db_prefix}helpdesk_tickets AS hdt
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
					INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
					INNER JOIN {db_prefix}helpdesk_depts AS hdd ON (hdt.id_dept = hdd.id_dept)
					' . (!empty($block['sort']['sql']['join']) ? $block['sort']['sql']['join'] : '') . $context['filter_join'] . '
				WHERE {query_see_ticket}' . (!empty($block['where']) ? ' AND ' . $block['where'] : '') . (!empty($context['shd_department']) ? ' AND hdt.id_dept = {int:dept}' : '') . $context['filter_where'], array('dept' => $context['shd_department'], 'user' => $context['user']['id'], 'field' => $_REQUEST['field'], 'filter' => $_REQUEST['filter'], 'type_ticket' => CFIELD_TICKET, 'active' => 1));
            list($context['ticket_blocks'][$block_key]['count']) = $smcFunc['db_fetch_row']($query);
            $block['count'] = $context['ticket_blocks'][$block_key]['count'];
            $smcFunc['db_free_result']($query);
            if ($block['start'] >= $block['count']) {
                $context['ticket_blocks'][$block_key]['start'] = max(0, (int) $block['count'] - ((int) $block['count'] % (int) $block['num_per_page'] == 0 ? $block['num_per_page'] : (int) $block['count'] % (int) $block['num_per_page']));
                $block['start'] = $context['ticket_blocks'][$block_key]['start'];
            }
        }
        $query = shd_db_query('', '
			SELECT hdt.id_ticket, hdt.id_dept, hdd.dept_name, hdt.id_last_msg, hdt.id_member_started, hdt.id_member_updated,
				hdt.id_member_assigned, hdt.subject, hdt.status, hdt.num_replies, hdt.deleted_replies, hdt.private, hdt.urgency,
				hdt.last_updated, hdtr_first.poster_name AS ticket_opener, hdtr_last.poster_name AS respondent, hdtr_last.poster_time,
				IFNULL(hdlr.id_msg, 0) AS log_read' . (!empty($block['sort']['sql']['select']) ? ', ' . $block['sort']['sql']['select'] : '') . '
			FROM {db_prefix}helpdesk_tickets AS hdt
				INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
				INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
				INNER JOIN {db_prefix}helpdesk_depts AS hdd ON (hdt.id_dept = hdd.id_dept)
				LEFT JOIN {db_prefix}helpdesk_log_read AS hdlr ON (hdt.id_ticket = hdlr.id_ticket AND hdlr.id_member = {int:user})
				' . (!empty($block['sort']['sql']['join']) ? $block['sort']['sql']['join'] : '') . $context['filter_join'] . '
			WHERE {query_see_ticket}' . (!empty($block['where']) ? ' AND ' . $block['where'] : '') . (!empty($context['shd_department']) ? ' AND hdt.id_dept = {int:dept}' : '') . $context['filter_where'] . '
			ORDER BY ' . (!empty($block['sort']['sql']['sort']) ? $block['sort']['sql']['sort'] : 'hdt.id_last_msg ASC') . '
			LIMIT {int:start}, {int:items_per_page}', array('dept' => $context['shd_department'], 'user' => $context['user']['id'], 'start' => $block['start'], 'items_per_page' => $block['num_per_page'], 'field' => $_REQUEST['field'], 'filter' => $_REQUEST['filter'], 'type_ticket' => CFIELD_TICKET, 'active' => 1));
        while ($row = $smcFunc['db_fetch_assoc']($query)) {
            $is_own = $user_info['id'] == $row['id_member_started'];
            censorText($row['subject']);
            $new_block = array('id' => $row['id_ticket'], 'display_id' => str_pad($row['id_ticket'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT), 'dept_link' => empty($context['shd_department']) && $context['shd_multi_dept'] ? '[<a href="' . $scripturl . '?' . $context['shd_home'] . ';dept=' . $row['id_dept'] . '">' . $row['dept_name'] . '</a>] ' : '', 'link' => '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : '') . '">' . $row['subject'] . '</a>', 'subject' => $row['subject'], 'status' => array('level' => $row['status'], 'label' => $txt['shd_status_' . $row['status']]), 'starter' => array('id' => $row['id_member_started'], 'name' => $row['ticket_opener']), 'last_update' => timeformat($row['last_updated']), 'assigned' => array('id' => $row['id_member_assigned']), 'respondent' => array('id' => $row['id_member_updated'], 'name' => $row['respondent']), 'urgency' => array('level' => $row['urgency'], 'label' => $row['urgency'] > TICKET_URGENCY_HIGH ? '<span class="error">' . $txt['shd_urgency_' . $row['urgency']] . '</span>' : $txt['shd_urgency_' . $row['urgency']]), 'is_unread' => $row['id_last_msg'] > $row['log_read'], 'new_href' => $row['id_last_msg'] <= $row['log_read'] ? '' : $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . '.new' . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : '') . '#new', 'private' => $row['private'], 'actions' => array('movedept' => !empty($context['shd_multi_dept']) && (shd_allowed_to('shd_move_dept_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_move_dept_own', $context['shd_department'])) ? '<a href="' . $scripturl . '?action=helpdesk;sa=movedept;ticket=' . $row['id_ticket'] . ';home;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_move_dept'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/movedept.png" alt="' . $txt['shd_move_dept'] . '" /></a>' : ''), 'num_replies' => $row['num_replies'], 'replies_href' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . '.msg' . $row['id_last_msg'] . '#msg' . $row['id_last_msg'] . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : ''), 'all_replies' => (int) $row['num_replies'] + (int) $row['deleted_replies']);
            if ($row['status'] == TICKET_STATUS_CLOSED) {
                $new_block['actions'] += array('resolve' => shd_allowed_to('shd_unresolve_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_unresolve_ticket_own', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=resolveticket;ticket=' . $row['id_ticket'] . ';home;' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_unresolved'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/unresolved.png" alt="' . $txt['shd_ticket_unresolved'] . '" /></a>' : '');
            } elseif ($row['status'] == TICKET_STATUS_DELETED) {
                $new_block['actions'] += array('restore' => shd_allowed_to('shd_restore_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_restore_ticket_own', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=restoreticket;ticket=' . $row['id_ticket'] . ';home;' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_restore'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/restore.png" alt="' . $txt['shd_ticket_restore'] . '" /></a>' : '', 'permadelete' => shd_allowed_to('shd_delete_recycling', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=permadelete;ticket=' . $row['id_ticket'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_delete_permanently'] . '" onclick="return confirm(' . JavaScriptEscape($txt['shd_delete_permanently_confirm']) . ');"><img src="' . $settings['default_images_url'] . '/simpledesk/delete.png" alt="' . $txt['shd_delete_permanently'] . '" /></a>' : '');
            } else {
                $langstring = '';
                if (shd_allowed_to('shd_assign_ticket_any', $context['shd_department'])) {
                    $langstring = empty($row['id_member_assigned']) ? $txt['shd_ticket_assign'] : $txt['shd_ticket_reassign'];
                } elseif (shd_allowed_to('shd_assign_ticket_own', $context['shd_department']) && (empty($row['id_member_assigned']) || $row['id_member_assigned'] == $context['user']['id'])) {
                    $langstring = $row['id_member_assigned'] == $context['user']['id'] ? $txt['shd_ticket_unassign'] : $txt['shd_ticket_assign_self'];
                }
                if (!empty($langstring)) {
                    $new_block['actions']['assign'] = '<a href="' . $scripturl . '?action=helpdesk;sa=assign;ticket=' . $row['id_ticket'] . ';home;' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $langstring . '"><img src="' . $settings['default_images_url'] . '/simpledesk/assign.png" alt="' . $langstring . '" /></a>';
                }
                $new_block['actions'] += array('resolve' => shd_allowed_to('shd_resolve_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_resolve_ticket_own', $context['shd_department']) ? '<a href="' . $scripturl . '?action=helpdesk;sa=resolveticket;ticket=' . $row['id_ticket'] . ';home;' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_resolved'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/resolved.png" alt="' . $txt['shd_ticket_resolved'] . '" /></a>' : '', 'tickettotopic' => empty($modSettings['shd_helpdesk_only']) && shd_allowed_to('shd_ticket_to_topic', $context['shd_department']) && ($row['deleted_replies'] == 0 || shd_allowed_to('shd_access_recyclebin')) ? '<a href="' . $scripturl . '?action=helpdesk;sa=tickettotopic;ticket=' . $row['id_ticket'] . ';' . $context['shd_dept_link'] . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_move_to_topic'] . '"><img src="' . $settings['default_images_url'] . '/simpledesk/tickettotopic.png" alt="' . $txt['shd_ticket_move_to_topic'] . '" /></a>' : '', 'delete' => shd_allowed_to('shd_delete_ticket_any', $context['shd_department']) || $is_own && shd_allowed_to('shd_delete_ticket_own') ? '<a href="' . $scripturl . '?action=helpdesk;sa=deleteticket;ticket=' . $row['id_ticket'] . ';' . $context['shd_dept_link'] . ';' . $context['session_var'] . '=' . $context['session_id'] . '" title="' . $txt['shd_ticket_delete'] . '" onclick="return confirm(' . JavaScriptEscape($txt['shd_delete_confirm']) . ');"><img src="' . $settings['default_images_url'] . '/simpledesk/delete.png" alt="' . $txt['shd_ticket_delete'] . '" /></a>' : '');
            }
            $context['ticket_blocks'][$block_key]['tickets'][$row['id_ticket']] = $new_block;
            $users[] = $row['id_member_started'];
            $users[] = $row['id_member_updated'];
            $users[] = $row['id_member_assigned'];
            $tickets[$row['id_ticket']] = array();
        }
        $smcFunc['db_free_result']($query);
    }
    $users = array_unique($users);
    if (!empty($users)) {
        loadMemberData($users, false, 'minimal');
    }
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if (empty($block['tickets'])) {
            continue;
        }
        foreach ($block['tickets'] as $tid => $ticket) {
            // Set up names and profile links for topic starter
            if (!empty($user_profile[$ticket['starter']['id']])) {
                // We found the name, so let's use their current name and profile link
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['name'] = $user_profile[$ticket['starter']['id']]['real_name'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['link'] = shd_profile_link($user_profile[$ticket['starter']['id']]['real_name'], $ticket['starter']['id']);
            } else {
                // We didn't, so keep using the name we found previously and don't make an actual link
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['link'] = $context['ticket_blocks'][$block_id]['tickets'][$tid]['starter']['name'];
            }
            // Set up names and profile links for assigned user
            if ($ticket['assigned']['id'] == 0 || empty($user_profile[$ticket['assigned']['id']])) {
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['name'] = $txt['shd_unassigned'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['link'] = '<span class="error">' . $txt['shd_unassigned'] . '</span>';
            } else {
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['name'] = $user_profile[$ticket['assigned']['id']]['real_name'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['assigned']['link'] = shd_profile_link($user_profile[$ticket['assigned']['id']]['real_name'], $ticket['assigned']['id']);
            }
            // And last respondent
            if ($ticket['respondent']['id'] == 0 || empty($user_profile[$ticket['respondent']['id']])) {
                // Didn't find the name, so reuse what we have
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['link'] = $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['name'];
            } else {
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['name'] = $user_profile[$ticket['respondent']['id']]['real_name'];
                $context['ticket_blocks'][$block_id]['tickets'][$tid]['respondent']['link'] = shd_profile_link($user_profile[$ticket['respondent']['id']]['real_name'], $ticket['respondent']['id']);
            }
        }
    }
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if (empty($block['display']) || empty($block['count']) && !$block['required'] && empty($block['collapsed'])) {
            unset($context['ticket_blocks'][$block_id]);
        }
    }
    $base_url = '';
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if ($block['sort']['add_link']) {
            $base_url .= $block['sort']['link_bits'][$block['sort']['item']];
        }
    }
    if ($_REQUEST['sa'] != 'viewblock') {
        foreach ($context['ticket_blocks'] as $block_id => $block) {
            $num_per_page = !empty($context['shd_preferences']['blocks_' . $block_key . '_count']) ? $context['shd_preferences']['blocks_' . $block_key . '_count'] : $context['items_per_page'];
            $url_fragment = $base_url;
            foreach ($block_list as $block_item) {
                if ($block_item == $block_id) {
                    $url_fragment .= ';st_' . $block_item . '=%1$d';
                } elseif (!empty($context['ticket_blocks'][$block_item]['start'])) {
                    $url_fragment .= ';st_' . $block_item . '=' . $context['ticket_blocks'][$block_item]['start'];
                }
            }
            $context['start'] = $context['ticket_blocks'][$block_id]['start'];
            $context['ticket_blocks'][$block_id]['page_index'] = shd_no_expand_pageindex($scripturl . $primary_url . $url_fragment . $context['shd_dept_link'] . $context['filter_fragment'] . '#shd_block_' . $block_id, $context['start'], $block['count'], $block['num_per_page'], true);
        }
    }
    // Just need to deal with those pesky prefix fields, if there are any.
    if (empty($tickets)) {
        return;
    }
    // We're all done here.
    // 1. Figure out if there are any custom fields that apply to us or not.
    if ($context['shd_multi_dept'] && empty($context['shd_department'])) {
        $dept_list = shd_allowed_to('access_helpdesk', false);
    } else {
        $dept_list = array($context['shd_department']);
    }
    $fields = array();
    $query = $smcFunc['db_query']('', '
		SELECT hdcf.id_field, can_see, field_type, field_options, placement, field_name
		FROM {db_prefix}helpdesk_custom_fields AS hdcf
			INNER JOIN {db_prefix}helpdesk_custom_fields_depts AS hdcfd ON (hdcfd.id_field = hdcf.id_field)
		WHERE placement IN ({array_int:placement_prefix})
			AND field_loc IN ({array_int:locations})
			AND hdcfd.id_dept IN ({array_int:dept_list})
			AND active = {int:active}
		GROUP BY hdcf.id_field
		ORDER BY field_order', array('locations' => array(CFIELD_TICKET, CFIELD_TICKET | CFIELD_REPLY), 'placement_prefix' => array(CFIELD_PLACE_PREFIX, CFIELD_PLACE_PREFIXFILTER), 'active' => 1, 'dept_list' => $dept_list));
    $is_staff = shd_allowed_to('shd_staff', $context['shd_department']);
    $is_admin = $context['user']['is_admin'] || shd_allowed_to('admin_helpdesk', $context['shd_department']);
    $context['shd_filter_fields'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        list($user_see, $staff_see) = explode(',', $row['can_see']);
        if ($is_admin || $is_staff && $staff_see == '1' || !$is_staff && $user_see == '1') {
            if (!empty($row['field_options'])) {
                $row['field_options'] = unserialize($row['field_options']);
                if (isset($row['field_options']['inactive'])) {
                    unset($row['field_options']['inactive']);
                }
                foreach ($row['field_options'] as $k => $v) {
                    if (strpos($v, '[') !== false) {
                        $row['field_options'][$k] = parse_bbc($v);
                    }
                }
            }
            $fields[$row['id_field']] = $row;
            if ($row['placement'] == CFIELD_PLACE_PREFIXFILTER) {
                $context['shd_filter_fields'][$row['id_field']] = array('name' => $row['field_name'], 'options' => $row['field_options'], 'in_use' => array());
            }
        }
    }
    $smcFunc['db_free_result']($query);
    if (empty($fields)) {
        return;
    }
    // No fields to process, time to go.
    // 2. Get the relevant values.
    $query = $smcFunc['db_query']('', '
		SELECT id_post, id_field, value
		FROM {db_prefix}helpdesk_custom_fields_values
		WHERE id_post IN ({array_int:tickets})
			AND id_field IN ({array_int:fields})
			AND post_type = {int:ticket}', array('tickets' => array_keys($tickets), 'fields' => array_keys($fields), 'ticket' => CFIELD_TICKET));
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $tickets[$row['id_post']][$row['id_field']] = $row['value'];
    }
    // 3. Apply the values into the tickets.
    if ($_REQUEST['sa'] == 'closedtickets') {
        $context['filterbase'] = $scripturl . '?action=helpdesk;sa=closedtickets';
    } elseif ($_REQUEST['sa'] == 'recyclebin') {
        $context['filterbase'] = $scripturl . '?action=helpdesk;sa=recyclebin';
    } else {
        $context['filterbase'] = $scripturl . '?' . $context['shd_home'];
    }
    foreach ($context['ticket_blocks'] as $block_id => $block) {
        if (empty($block['tickets'])) {
            continue;
        }
        foreach ($block['tickets'] as $ticket_id => $ticket) {
            if (isset($tickets[$ticket_id])) {
                $prefix_filter = '';
                $prefix = '';
                foreach ($fields as $field_id => $field) {
                    if (empty($tickets[$ticket_id][$field_id])) {
                        continue;
                    }
                    if ($field['placement'] == CFIELD_PLACE_PREFIXFILTER) {
                        if (!isset($field['field_options'][$tickets[$ticket_id][$field_id]])) {
                            continue;
                        }
                        $prefix_filter .= '[<a href="' . $context['filterbase'] . $context['shd_dept_link'] . ';field=' . $field_id . ';filter=' . $tickets[$ticket_id][$field_id] . '">' . $field['field_options'][$tickets[$ticket_id][$field_id]] . '</a>] ';
                    } else {
                        if ($field['field_type'] == CFIELD_TYPE_CHECKBOX) {
                            $prefix .= !empty($tickets[$ticket_id][$field_id]) ? $txt['yes'] . ' ' : $txt['no'] . ' ';
                        } elseif ($field['field_type'] == CFIELD_TYPE_SELECT || $field['field_type'] == CFIELD_TYPE_RADIO) {
                            $prefix .= $field['field_options'][$tickets[$ticket_id][$field_id]] . ' ';
                        } elseif ($field['field_type'] == CFIELD_TYPE_MULTI) {
                            $values = explode(',', $tickets[$ticket_id][$field_id]);
                            foreach ($values as $value) {
                                $prefix .= $field['field_options'][$value] . ' ';
                            }
                        } else {
                            $prefix .= $tickets[$ticket_id][$field_id] . ' ';
                        }
                    }
                }
                // First, set aside the subject, and if there is a non category prefix, strip links from it.
                $subject = $ticket['subject'];
                if (!empty($prefix)) {
                    $prefix = '[' . trim(preg_replace('~<a (.*?)</a>~is', '', $prefix)) . '] ';
                }
                // Then, if we have a category prefix, prepend that to any other prefix we have.
                if (!empty($prefix_filter)) {
                    $prefix = $prefix_filter . $prefix;
                }
                // Lastly, if we have some kind of prefix to put in front of this ticket, do so.
                if (!empty($prefix)) {
                    $context['ticket_blocks'][$block_id]['tickets'][$ticket_id]['subject'] = $prefix . $subject;
                    $context['ticket_blocks'][$block_id]['tickets'][$ticket_id]['link'] = $prefix . '<a href="' . $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $ticket_id . ($_REQUEST['sa'] == 'recyclebin' ? ';recycle' : '') . '">' . $subject . '</a>';
                }
            }
        }
    }
    // 4. We've collected the list of prefix-filter fields in use, now establish which values are actually in use.
    if (!empty($context['shd_filter_fields'])) {
        $query = $smcFunc['db_query']('', '
			SELECT id_field, value
			FROM {db_prefix}helpdesk_custom_fields_values
			WHERE id_field IN ({array_int:fields})', array('fields' => array_keys($context['shd_filter_fields'])));
        while ($row = $smcFunc['db_fetch_assoc']($query)) {
            $context['shd_filter_fields'][$row['id_field']]['in_use'][$row['value']] = true;
        }
        $smcFunc['db_free_result']($query);
        foreach ($context['shd_filter_fields'] as $id_field => $field) {
            if (empty($field['in_use'])) {
                unset($context['shd_filter_fields'][$id_field]);
            } else {
                foreach ($field['options'] as $k => $v) {
                    if (!isset($field['in_use'][$k])) {
                        unset($context['shd_filter_fields'][$id_field]['options'][$k]);
                    }
                }
                if (empty($context['shd_filter_fields'][$id_field]['options'])) {
                    unset($context['shd_filter_fields'][$id_field]);
                }
            }
        }
    }
}
예제 #6
0
/**
 *	Gets tickets based on supplied criteria; this is a helper function not really intended to be called directly.
 *
 *	@todo Finish writing and documenting this function.
 *	@param string $query_where SQL clauses to be supplied to the query in addition to {query_see_ticket} - note 'AND' is not required at the start.
 *	@param array $query_where_params Key/value associative array to be injected into the query, related to $query_where.
 *	@param int $query_limit Number of items to limit the query to.
 *	@param string $query_order The clause to order tickets by, defaults to tickets by order of creation.
 *	@return array An array of arrays, each primary item containing the following:
 *	<ul>
 *	<li>id: Main ticket id</li>
 *	<li>display_id: Formatted ticket id in [0000x] format</li>
 *	<li>subject: Ticket subject</li>
 *	<li>short_subject: Shortened version of ticket subject</li>
 *	<li>href: Ticket href</li>
 *	<li>opener: array of details about the ticket starter:
 *		<ul>
 *			<li>id: user id of the person who opened the ticket</li>
 *			<li>name: username of the person who opened the ticket</li>
 *			<li>link: link to the profile of the person who opened the ticket</li>
 *		</ul>
 *	</li>
 *	<li>replier: array of details about the last person to reply to the ticket:
 *		<ul>
 *			<li>id: user id of the last person to reply to the ticket</li>
 *			<li>name: username of the last person to reply to the ticket</li>
 *			<li>link: link to the profile of the last person to reply to the ticket</li>
 *		</ul>
 *	</li>
 *	<li>assigned: array of details about the person who the ticket is assigned to:
 *		<ul>
 *			<li>id: user id of the person who the ticket is assigned to</li>
 *			<li>name: username of the person who the ticket is assigned to or 'Unassigned' otherwise</li>
 *			<li>link: link to the profile of the person  who the ticket is assigned to or 'Unassigned' otherwise</li>
 *		</ul>
 *	</li>
 *	<li>num_replies: Number of replies in the ticket</li>
 *	<li>start_time: Formatted string of time the ticket was opened</li>
 *	<li>start_timestamp: Raw timestamp (adjusted for timezones) of ticket being opened</li>
 *	<li>last_time: Formatted string of time the ticket was last replied to</li>
 *	<li>last_timestamp: Raw timestamp (adjusted for timezones) of ticket's last reply</li>
 *	<li>private: Whether the ticket is private or not</li>
 *	<li>urgency_id: Number representing ticket urgency</li>
 *	<li>urgency_string: String representing ticket urgency</li>
 *	<li>status_id: Number representing ticket status</li>
 *	<li>status_text: String representing ticket status</li>
 *  <li>department: Number representing ticket department ID</li>
 *	</ul>
 *	@since 2.0
*/
function ssi_getSDTickets($query_where, $query_where_params = array(), $query_limit = 0, $query_order = 'hdt.id_ticket ASC', $output_method = 'echo')
{
    global $smcFunc, $scripturl, $txt, $modSettings;
    $query_limit = (int) $query_limit;
    $query = shd_db_query('', '
		SELECT hdt.id_ticket, hdt.subject, hdt.num_replies, hdt.private, hdt.urgency, hdt.status, hdt.dept,
			hdtr_first.poster_time AS start_time, hdt.last_updated AS last_time,
			IFNULL(mem.real_name, hdtr_first.poster_name) AS starter_name, IFNULL(mem.id_member, 0) AS starter_id,
			IFNULL(ma.real_name, 0) AS assigned_name, IFNULL(ma.id_member, 0) AS assigned_id,
			IFNULL(mm.real_name, hdtr_last.modified_name) AS modified_name, IFNULL(mm.id_member, 0) AS modified_id
		FROM {db_prefix}helpdesk_tickets AS hdt
			INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_first ON (hdt.id_first_msg = hdtr_first.id_msg)
			INNER JOIN {db_prefix}helpdesk_ticket_replies AS hdtr_last ON (hdt.id_last_msg = hdtr_last.id_msg)
			LEFT JOIN {db_prefix}members AS mem ON (hdt.id_member_started = mem.id_member)
			LEFT JOIN {db_prefix}members AS ma ON (hdt.id_member_assigned = ma.id_member)
			LEFT JOIN {db_prefix}members AS mm ON (hdt.id_member_updated = mm.id_member)
		WHERE {query_see_ticket} AND ' . $query_where . '
		ORDER BY ' . $query_order . '
		' . ($query_limit == 0 ? '' : 'LIMIT ' . $query_limit), array_merge($query_where_params, array()));
    $tickets = array();
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        censorText($row['subject']);
        $tickets[] = array('id' => $row['id_ticket'], 'display_id' => str_pad($row['id_ticket'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT), 'subject' => $row['subject'], 'short_subject' => shorten_subject($row['subject'], 25), 'href' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'], 'opener' => array('id' => $row['starter_id'], 'name' => $row['starter_name'], 'link' => shd_profile_link($row['starter_name'], $row['starter_id'])), 'replier' => array('id' => $row['modified_id'], 'name' => $row['modified_name'], 'link' => shd_profile_link($row['modified_name'], $row['modified_id'])), 'assigned' => array('id' => $row['assigned_id'], 'name' => empty($row['assigned_name']) ? $txt['shd_unassigned'] : $row['assigned_name'], 'link' => empty($row['assigned_name']) ? '<span class="error">' . $txt['shd_unassigned'] . '</span>' : shd_profile_link($row['assigned_name'], $row['assigned_id'])), 'start_time' => timeformat($row['start_time']), 'start_timestamp' => forum_time(true, $row['start_time']), 'last_time' => timeformat($row['last_time']), 'last_timestamp' => forum_time(true, $row['last_time']), 'num_replies' => $row['num_replies'], 'private' => !empty($row['private']), 'urgency_id' => $row['urgency'], 'urgency_string' => $txt['shd_urgency_' . $row['urgency']], 'status_id' => $row['status'], 'status_text' => $txt['shd_status_' . $row['status']], 'department' => $row['dept']);
    }
    $smcFunc['db_free_result']($query);
    if (empty($tickets) || $output_method != 'echo') {
        return $tickets;
    }
    // output this stuff
    echo '
		<table border="0" class="ssi_table">';
    foreach ($tickets as $ticket) {
        echo '
			<tr>
				<td align="right" valign="top" nowrap="nowrap">
					[', $ticket['status_text'], ']
				</td>
				<td valign="top">
					<a href="', $ticket['href'], '">', $ticket['subject'], '</a>
					', $txt['by'], ' ', $ticket['replier']['link'], '
				</td>
				<td align="right" nowrap="nowrap">
					', $ticket['last_time'], '
				</td>
			</tr>';
    }
    echo '
		</table>';
}
function shd_format_notify_name(&$user_name, $user_id, $ticket_starter)
{
    global $txt;
    $user_name = shd_profile_link($user_name, $user_id) . ($user_id == $ticket_starter ? $txt['shd_is_ticket_opener'] : '');
}
function template_search_results()
{
    global $context, $txt, $scripturl, $settings, $modSettings, $smcFunc;
    // Back to the helpdesk.
    echo '
		<div class="floatleft">
			', template_button_strip(array($context['navigation']['back'], $context['navigation']['search']), 'bottom'), '
		</div><br class="clear" /><br />';
    echo '
	<div class="cat_bar">
		<h3 class="catbg">
			<img src="', $settings['default_images_url'], '/simpledesk/search.png" alt="*" />
			', $txt['shd_search_results'], '
		</h3>
	</div>';
    // Page navigation. It's not your usual page index, and with good reason: we can't use regular links here without risking server hammering.
    $num_pages = ceil($context['num_results'] / $context['search_params']['limit']);
    $pages = array();
    for ($page = $context['numpage'] - 2; $page <= $context['numpage'] + 2; $page++) {
        $pages[] = $page;
    }
    // The rest of it would go here, in a nice form that carried everything through for next time, with a button named page whose value would be the page number for each page (plus prev/next) you wanted to display
    // Search criteria
    template_search_criteria();
    // And finally, the results themselves.
    $use_bg2 = false;
    foreach ($context['search_results'] as $index => $result) {
        echo '
	<div class="search_results_posts">
		<div class="windowbg', $use_bg2 ? '2' : '', ' core_posts">
			<span class="topslice"><span></span></span>
			<div class="content flow_auto">
				<div class="topic_details floatleft" style="width: 94%">
					<div class="counter">', $result['result'], '</div>
					<h5>', $result['dept_link'], '<a href="', $scripturl, '?action=helpdesk;sa=ticket;ticket=', $result['id_ticket'], '">', sprintf($result['is_ticket'] ? $txt['shd_search_result_ticket'] : $txt['shd_search_result_reply'], $result['display_id']), '</a> - ', $result['subject'], ' (', $txt['shd_search_last_updated'], ' ', timeformat($result['last_updated']), ')</h5>
					<span class="smalltext">&#171;&nbsp;<strong>', $result['is_ticket'] ? $txt['shd_search_ticket_opened_by'] : $txt['shd_search_ticket_replied_by'], ' ', shd_profile_link($result['poster_name'], $result['id_member']), '</strong>&nbsp;', $txt['on'], '&nbsp;<em>', timeformat($result['poster_time']), '</em>&nbsp;&#187;</span>
				</div>
				<br class="clear">
				<div class="list_posts double_height">', $result['body'], '</div>
			</div>
			<span class="botslice"><span></span></span>
		</div>
	</div>';
        $use_bg2 = !$use_bg2;
    }
}
예제 #9
0
function shd_list_get_ip_messages($start, $items_per_page, $sort, $where, $where_vars = array())
{
    global $smcFunc, $txt, $scripturl;
    $query = shd_db_query('', '
		SELECT
			hdtr.id_msg, hdtr.poster_ip, IFNULL(mem.real_name, hdtr.poster_name) AS display_name, mem.id_member,
			hdt.subject, hdtr.poster_time, hdt.id_ticket, hdt.id_first_msg
		FROM {db_prefix}helpdesk_ticket_replies AS hdtr
			INNER JOIN {db_prefix}helpdesk_tickets AS hdt ON (hdtr.id_ticket = hdt.id_ticket)
			LEFT JOIN {db_prefix}members AS mem ON (mem.id_member = hdtr.id_member)
		WHERE {query_see_ticket} AND ' . $where . '
		ORDER BY ' . $sort . '
		LIMIT ' . $start . ', ' . $items_per_page, array_merge($where_vars, array()));
    $messages = array();
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $messages[] = array('ip' => $row['poster_ip'], 'member_link' => shd_profile_link($row['display_name'], $row['id_member']), 'ticket' => $row['id_ticket'], 'id' => $row['id_msg'], 'subject' => $row['subject'], 'time' => timeformat($row['poster_time']), 'timestamp' => forum_time(true, $row['poster_time']), 'additional' => $row['id_first_msg'] == $row['id_msg'] ? $txt['shd_is_ticket_opener'] : '');
    }
    $smcFunc['db_free_result']($query);
    return $messages;
}
/**
 *	Display all the replies to a ticket.
 *
 *	This function deals simply with viewing of replies in a ticket, including deleted replies, which is initialised in {@link shd_view_ticket()}
 *	and data gathered through the {@link shd_prepare_ticket_context()} call back, which simply deals with a single reply at a time.
 *
 *	@see shd_view_ticket()
 *	@see template_viewticket()
 *	@since 1.0
*/
function template_viewreplies()
{
    global $context, $settings, $txt, $scripturl, $options, $modSettings, $reply_request;
    echo '
		<div class="tborder">
		<div class="title_bar grid_header">
			<h3 class="titlebg">
				<span class="floatright smalltext">', $txt['pages'], ': ', $context['page_index'], '</span>
				<img src="', $settings['default_images_url'], '/simpledesk/replies.png" alt="x" /> ', $txt['shd_ticket_replies'], '
			</h3>
		</div>
		<div class="roundframe" id="replies">
			<div class="content">';
    if (empty($reply_request)) {
        echo $txt['shd_no_replies'];
    } else {
        while ($reply = $context['get_replies']()) {
            if (!empty($reply['is_new'])) {
                echo '
					<a id="new"></a>';
            }
            echo '
					<div class="description shd_reply', !empty($context['ticket']['display_recycle']) && $reply['message_status'] == MSG_STATUS_DELETED ? ' errorbox' : '', '" id="msg', $reply['id'], '">
						<span class="floatleft shd_posterinfo">
							<strong class="shd_postername">
								', $reply['member']['link'], '
							</strong>
							<br />
							', $reply['member']['group'], '<br class="shd_groupmargin" />';
            if (!empty($modSettings['shd_display_avatar']) && empty($options['show_no_avatars']) && !empty($reply['member']['avatar']['image'])) {
                echo '
							<span class="shd_posteravatar">
								', shd_profile_link($reply['member']['avatar']['image'], $reply['member']['id']), '
							</span>';
            }
            if ($modSettings['shd_staff_badge'] == (!empty($reply['is_staff']) ? 'staffbadge' : 'userbadge') || $modSettings['shd_staff_badge'] == 'bothbadge') {
                echo '<br />
							', $reply['member']['group_stars'];
            } elseif (!empty($reply['is_staff']) && $modSettings['shd_staff_badge'] == 'nobadge') {
                echo '<br />
							<img src="', $settings['default_images_url'] . '/simpledesk/staff.png" class="shd_smallicon" title="', $txt['shd_ticket_staff'], '" alt="', $txt['shd_ticket_staff'], '" />';
            }
            echo '
						</span>
						<div class="shd_replyarea">
							<div class="smalltext">
								<span class="floatright shd_ticketlinks">';
            if ($context['can_quote']) {
                echo '
									<img src="', $settings['default_images_url'], '/simpledesk/quote.png" class="shd_smallicon" alt="*" /><a onclick="return oQuickReply.quote(', $reply['id'], ', \'', $context['session_id'], '\', \'', $context['session_var'], '\', true);" href="', $scripturl, '?action=helpdesk;sa=reply;ticket=', $context['ticket_id'], ';quote=', $reply['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_quote_short'], '</a>';
            }
            if ($reply['can_edit']) {
                echo '
									<img src="', $settings['default_images_url'], '/simpledesk/edit.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=editreply;ticket=', $context['ticket_id'], ';msg=', $reply['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_edit'], '</a>';
            }
            if ($reply['can_delete']) {
                echo '
									<img src="', $settings['default_images_url'], '/simpledesk/delete.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=deletereply;reply=', $reply['id'], ';ticket=', $context['ticket']['id'], ';', $context['session_var'], '=', $context['session_id'], '" onclick="return confirm(', JavaScriptEscape($txt['shd_delete_reply_confirm']), ');">', $txt['shd_ticket_delete'], '</a>';
            }
            if ($reply['can_restore']) {
                echo '
									<img src="', $settings['default_images_url'], '/simpledesk/restore.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=restorereply;reply=', $reply['id'], ';ticket=', $context['ticket']['id'], ';', $context['session_var'], '=', $context['session_id'], '">', $txt['shd_ticket_restore'], '</a>';
            }
            if ($reply['can_permadelete']) {
                echo '
									<img src="', $settings['default_images_url'], '/simpledesk/delete.png" class="shd_smallicon" alt="*" /><a href="', $scripturl, '?action=helpdesk;sa=permadelete;reply=', $reply['id'], ';ticket=', $context['ticket']['id'], ';', $context['session_var'], '=', $context['session_id'], '" onclick="return confirm(', JavaScriptEscape($txt['shd_delete_permanently_confirm']), ');">', $txt['shd_delete_permanently'], '</a>';
            }
            echo '
								</span>
								<a href="', $reply['link'], '">', sprintf($txt['shd_reply_written'], $reply['time']), '</a>
							</div>
							<hr />
							', $reply['body'], '
							<br /><br />';
            // Custom fields for replies!
            if (!empty($context['custom_fields_replies'][$reply['id']])) {
                echo '
							<hr />';
                foreach ($context['custom_fields_replies'][$reply['id']] as $field) {
                    if ($field['display_empty'] || !empty($field['value']) || $field['type'] == CFIELD_TYPE_CHECKBOX) {
                        echo '
							', !empty($field['icon']) ? '<img src="' . $settings['default_images_url'] . '/simpledesk/cf/' . $field['icon'] . '" alt="" class="shd_smallicon" />' : '', '
							<strong>', $field['name'], ': </strong>';
                        if ($field['type'] == CFIELD_TYPE_CHECKBOX) {
                            echo !empty($field['value']) ? $txt['yes'] : $txt['no'], '<br /><br />';
                        } elseif (empty($field['value']) && $field['display_empty']) {
                            echo $txt['shd_ticket_empty_field'], '<br /><br />';
                        } else {
                            if ($field['type'] == CFIELD_TYPE_SELECT || $field['type'] == CFIELD_TYPE_RADIO) {
                                echo $field['options'][$field['value']], '<br /><br />';
                            } elseif ($field['type'] == CFIELD_TYPE_MULTI) {
                                $values = explode(',', $field['value']);
                                $string = '';
                                foreach ($values as $value) {
                                    $string .= $field['options'][$value] . ' ';
                                }
                                echo trim($string), '<br /><br />';
                            } else {
                                echo $field['value'], '<br /><br />';
                            }
                        }
                    }
                }
            }
            if ($settings['show_modify'] && !empty($reply['modified'])) {
                echo '
							<div class="smalltext shd_modified" style="margin-top:20px;">
								&#171; <em>', $txt['last_edit'], ': ', $reply['modified']['time'], ' ', $txt['by'], ' ', $reply['modified']['link'], '</em> &#187;
							</div>';
            }
            template_inline_attachments($reply['id']);
            echo '
						</div>';
            if (!empty($reply['ip_address'])) {
                echo '
						<span class="floatright"><img src="', $settings['default_images_url'], '/simpledesk/ip.png" alt="" class="shd_smallicon" /> ', $txt['shd_ticket_ip'], ': ', $reply['ip_address'], '</span>';
            }
            echo '
						<br class="clear" />
					</div>';
        }
    }
    echo '
				</div>
				<span class="floatleft shd_nowrap"><a href="#replies" title="', $txt['shd_go_to_replies_start'], '"><img src="', $settings['default_images_url'], '/simpledesk/move_up.png" alt="" /><img src="', $settings['default_images_url'], '/simpledesk/replies.png" alt="" /></a></span>
				<span class="floatright smalltext">', $txt['pages'], ': ', $context['page_index'], '</span>
				<br class="clear" />
			</div>
			<span class="lowerframe"><span></span></span>
		</div>';
}
/**
 *	Load the items from the helpdesk action log
 *
 *	It is subject to given parameters (start, number of items, order/sorting), parses the language strings and adds the
 *	parameter information provided.
 *
 *	@param int $start Number of items into the log to start (for pagination). If -1, return everything. If nothing is given, fall back to 0, i.e the first log item.
 *	@param int $items_per_page How many items to load. Default to 10 items.
 *	@param string $sort SQL clause to state which column(s) to order the data by. By default it orders by log_time.
 *	@param string $order SQL clause to state whether the order is ascending or descending. Defaults to descending.
 *	@param string $clause An SQL fragment that forms a WHERE clause to limit log items, e.g. to load a specific ticket or specific member's log items.
 *
 *	@return array A hash array of the log items, with the auto-incremented id being the key:
 *	<ul>
 *	<li>id: Numeric identifier of the log item</li>
 *	<li>time: Formatted time of the event (as per usual for SMF, formatted for user's timezone)</li>
 *	<li>member: hash array:
 *		<ul>
 *			<li>id: Id of the user that committed the action</li>
 *			<li>name: Name of the user</li>
 *			<li>link: Link to the profile of the user that committed the action</li>
 *			<li>ip: User IP address recorded when the action was carried out</li>
 *			<li>group: Name of the group of the user (uses primary group, failing that post count group)</li>
 *		</ul>
 *	</li>
 *	<li>action: Raw name of the action (for use with collecting the image later)</li>
 *	<li>id_ticket: Numeric id of the ticket this action refers to</li>
 *	<li>id_msg: Numeric id of the individual reply this action refers to</li>
 *	<li>extra: Array of extra parameters for the log action</li>
 *	<li>action_text: Formatted text of the log item (parsed with parameters)</li>
 *	</ul>
 *
 *	@see shd_log_action()
 *	@see shd_count_action_log_entries()
 *	@since 1.0
*/
function shd_load_action_log_entries($start = 0, $items_per_page = 10, $sort = 'la.log_time', $order = 'DESC', $clause = '')
{
    global $smcFunc, $txt, $scripturl, $context, $user_info, $user_profile;
    // Load languages incase they aren't there (Read: ticket-specific logs)
    shd_load_language('sd_language/SimpleDeskAdmin');
    shd_load_language('sd_language/SimpleDeskLogAction');
    shd_load_language('sd_language/SimpleDeskNotifications');
    $loaded_users = array();
    // We may have to exclude some items from this depending on who the user is or is not. Forum/HD admins can always see everything.
    $exclude = shd_action_log_exclusions();
    if (!empty($exclude)) {
        if (empty($clause)) {
            $clause = 'la.action NOT IN ({array_string:exclude})';
        } else {
            $clause .= ' AND la.action NOT IN ({array_string:exclude})';
        }
    }
    // Without further screaming and waving, fetch the actions.
    $request = shd_db_query('', '
		SELECT la.id_action, la.log_time, la.ip, la.action, la.id_ticket, la.id_msg, la.extra,
		IFNULL(mem.id_member, 0) AS id_member, IFNULL(mem.real_name, {string:blank}) AS real_name, IFNULL(mg.group_name, {string:na}) AS group_name
		FROM {db_prefix}helpdesk_log_action AS la
			LEFT JOIN {db_prefix}members AS mem ON(mem.id_member = la.id_member)
			LEFT JOIN {db_prefix}membergroups AS mg ON (mg.id_group = CASE WHEN mem.id_group = {int:reg_group_id} THEN mem.id_post_group ELSE mem.id_group END)' . (empty($clause) ? '' : '
		WHERE ' . $clause) . '
		ORDER BY ' . ($sort != '' ? '{raw:sort} {raw:order}' : 'la.log_time DESC') . '
		' . ($start != -1 ? 'LIMIT {int:start}, {int:items_per_page}' : ''), array('reg_group_id' => 0, 'sort' => $sort, 'start' => $start, 'items_per_page' => $items_per_page, 'order' => $order, 'na' => $txt['not_applicable'], 'blank' => '', 'exclude' => $exclude));
    $actions = array();
    $notify_members = array();
    while ($row = $smcFunc['db_fetch_assoc']($request)) {
        $row['extra'] = @unserialize($row['extra']);
        $row['extra'] = is_array($row['extra']) ? $row['extra'] : array();
        // Uhoh, we don't know who this is! Check it's not automatically by the system. If it is... mark it so.
        if (empty($row['id_member'])) {
            if (isset($row['extra']['auto']) && $row['extra']['auto'] === true) {
                $row['real_name'] = $txt['shd_helpdesk'];
            } else {
                $row['real_name'] = $txt['shd_admin_actionlog_unknown'];
            }
        }
        $actions[$row['id_action']] = array('id' => $row['id_action'], 'time' => timeformat($row['log_time']), 'member' => array('id' => $row['id_member'], 'name' => $row['real_name'], 'link' => shd_profile_link($row['real_name'], $row['id_member']), 'group' => $row['group_name']), 'action' => $row['action'], 'id_ticket' => $row['id_ticket'], 'id_msg' => $row['id_msg'], 'extra' => $row['extra'], 'action_text' => '', 'action_icon' => 'log_' . $row['action'] . '.png', 'can_remove' => empty($context['waittime']) ? false : $row['log_time'] < $context['waittime']);
        // We want to use a generic icon for custom fields changes.
        if (strpos($row['action'], 'cf_') === 0) {
            $actions[$row['id_action']]['action_icon'] = 'log_cfchange.png';
        }
        if (shd_allowed_to('shd_view_ip_any', 0) || $row['id_member'] == $user_info['id'] && shd_allowed_to('shd_view_ip_own', 0)) {
            $actions[$row['id_action']]['member']['ip'] = !empty($row['ip']) ? $row['ip'] : $txt['shd_admin_actionlog_unknown'];
        }
        // Notifications require us to collate all the user ids as we go along.
        if ($row['action'] == 'notify' && !empty($row['extra']['emails'])) {
            foreach ($row['extra']['emails'] as $email_type => $recipients) {
                if (!empty($recipients['u'])) {
                    $notify_members = array_merge($notify_members, explode(',', $recipients['u']));
                }
            }
        }
    }
    $smcFunc['db_free_result']($request);
    if (!empty($notify_members)) {
        $notify_members = loadMemberData(array_unique($notify_members));
    }
    // Do some formatting of the action string.
    foreach ($actions as $k => $action) {
        if (empty($actions[$k]['action_text'])) {
            $actions[$k]['action_text'] = isset($txt['shd_log_' . $action['action']]) ? $txt['shd_log_' . $action['action']] : $action['action'];
        }
        $actions[$k]['action_text'] = str_replace('{scripturl}', $scripturl, $actions[$k]['action_text']);
        $actions[$k]['action_text'] = str_replace('{shd_home}', $context['shd_home'], $actions[$k]['action_text']);
        if (isset($action['extra']['subject'])) {
            $actions[$k]['action_text'] = str_replace('{ticket}', $actions[$k]['id_ticket'], $actions[$k]['action_text']);
            $actions[$k]['action_text'] = str_replace('{msg}', $actions[$k]['id_msg'], $actions[$k]['action_text']);
            if (isset($actions[$k]['extra']['subject'])) {
                $actions[$k]['action_text'] = str_replace('{subject}', $actions[$k]['extra']['subject'], $actions[$k]['action_text']);
            }
            if (isset($actions[$k]['extra']['urgency'])) {
                $actions[$k]['action_text'] = str_replace('{urgency}', $txt['shd_urgency_' . $actions[$k]['extra']['urgency']], $actions[$k]['action_text']);
            }
        }
        // Notifications are pretty tricky. So let's take care of all of it at once, and skip the rest if we're doing that.
        if ($action['action'] == 'notify' && isset($action['extra']['emails'])) {
            // Because this could be a lot of people etc., we compact its storage heavily compared to a conventional serialize().
            // See shd_notify_users in SimpleDesk-Notifications.php for what this is.
            // Now we have all the usernames for this instance, let's go and build this entry.
            $content = '';
            foreach ($action['extra']['emails'] as $email_type => $recipients) {
                $this_content = '<br /><a href="' . $scripturl . '?action=helpdesk;sa=emaillog;log=' . $action['id'] . ';template=' . $email_type . '" onclick="return reqWin(this.href);">' . $txt['template_log_notify_' . $email_type] . '</a> - ';
                $new_content = '';
                if (!empty($recipients['u'])) {
                    $first = true;
                    $users = explode(',', $recipients['u']);
                    $unknown_users = 0;
                    foreach ($users as $user) {
                        if (empty($user_profile[$user])) {
                            $unknown_users++;
                            continue;
                        }
                        $new_content .= ($first ? $txt['shd_log_notify_users'] . ': ' : ', ') . shd_profile_link($user_profile[$user]['real_name'], $user);
                        $first = false;
                    }
                    if ($unknown_users > 0) {
                        $new_content .= ($first ? $txt['shd_log_notify_users'] . ': ' : ', ') . ($unknown_users == 1 ? $txt['shd_log_unknown_user_1'] : sprintf($txt['shd_log_unknown_user_n'], $unknown_users));
                    }
                }
                if (!empty($new_content)) {
                    $content .= $this_content . $new_content;
                }
            }
            if (!empty($content)) {
                $actions[$k]['action_text'] .= $txt['shd_log_notify_to'] . $content;
            }
            continue;
        }
        if (isset($action['extra']['user_name'])) {
            $actions[$k]['action_text'] = str_replace('{profile_link}', shd_profile_link($actions[$k]['extra']['user_name'], isset($actions[$k]['extra']['user_id']) ? $actions[$k]['extra']['user_id'] : 0), $actions[$k]['action_text']);
            $actions[$k]['action_text'] = str_replace('{user_name}', $actions[$k]['extra']['user_name'], $actions[$k]['action_text']);
        }
        if (isset($action['extra']['user_id'])) {
            $actions[$k]['action_text'] = str_replace('{user_id}', $actions[$k]['extra']['user_id'], $actions[$k]['action_text']);
        }
        if (isset($actions[$k]['extra']['board_name'])) {
            $actions[$k]['action_text'] = str_replace('{board_name}', $actions[$k]['extra']['board_name'], $actions[$k]['action_text']);
        }
        if (isset($actions[$k]['extra']['board_id'])) {
            $actions[$k]['action_text'] = str_replace('{board_id}', $actions[$k]['extra']['board_id'], $actions[$k]['action_text']);
        }
        if (isset($action['extra']['othersubject'])) {
            $actions[$k]['action_text'] = str_replace('{othersubject}', $actions[$k]['extra']['othersubject'], $actions[$k]['action_text']);
            $actions[$k]['action_text'] = str_replace('{otherticket}', $actions[$k]['extra']['otherticket'], $actions[$k]['action_text']);
        }
        if (isset($action['extra']['old_dept_id'])) {
            $replace = array('{old_dept_id}' => $action['extra']['old_dept_id'], '{old_dept_name}' => $action['extra']['old_dept_name'], '{new_dept_id}' => $action['extra']['new_dept_id'], '{new_dept_name}' => $action['extra']['new_dept_name']);
            $actions[$k]['action_text'] = str_replace(array_keys($replace), array_values($replace), $actions[$k]['action_text']);
        }
        // Custom fields?
        if (isset($action['extra']['fieldname'])) {
            if ($action['extra']['fieldtype'] == CFIELD_TYPE_CHECKBOX) {
                $action['extra']['oldvalue'] = !empty($action['extra']['oldvalue']) ? $txt['yes'] : $txt['no'];
                $action['extra']['newvalue'] = !empty($action['extra']['newvalue']) ? $txt['yes'] : $txt['no'];
            } elseif ($action['extra']['fieldtype'] == CFIELD_TYPE_RADIO || $action['extra']['fieldtype'] == CFIELD_TYPE_SELECT || $action['extra']['fieldtype'] == CFIELD_TYPE_MULTI) {
                if (empty($action['extra']['oldvalue'])) {
                    $action['extra']['oldvalue'] = $txt['shd_none_selected'];
                }
                if (empty($action['extra']['newvalue'])) {
                    $action['extra']['newvalue'] = $txt['shd_none_selected'];
                }
            } else {
                if (empty($action['extra']['oldvalue'])) {
                    $action['extra']['oldvalue'] = $txt['shd_empty_item'];
                }
                if (empty($action['extra']['newvalue'])) {
                    $action['extra']['newvalue'] = $txt['shd_empty_item'];
                }
            }
            $actions[$k]['action_text'] = str_replace('{fieldname}', $action['extra']['fieldname'], $actions[$k]['action_text']);
            $actions[$k]['action_text'] = str_replace('{oldvalue}', $action['extra']['oldvalue'], $actions[$k]['action_text']);
            $actions[$k]['action_text'] = str_replace('{newvalue}', $action['extra']['newvalue'], $actions[$k]['action_text']);
        }
        // This should be the last pair of ops - always.
        if (isset($action['extra']['att_added'])) {
            $actions[$k]['action_text'] .= ' ' . $txt['shd_logpart_att_added'] . ': ' . implode(', ', $action['extra']['att_added']);
        }
        if (isset($action['extra']['att_removed'])) {
            $actions[$k]['action_text'] .= ' ' . $txt['shd_logpart_att_removed'] . ': ' . implode(', ', $action['extra']['att_removed']);
        }
    }
    return $actions;
}
예제 #12
0
/**
 *	Display the notice of email.
 *
 *	@todo Finish documenting
 *	@since 2.0
*/
function shd_notify_popup()
{
    global $txt, $context, $settings, $modSettings, $smcFunc, $user_profile, $user_info, $scripturl;
    // First, verify we got a log entry, that the log entry is right, and it points to a ticket we can actually see.
    $_GET['log'] = isset($_GET['log']) ? (int) $_GET['log'] : 0;
    $email_type = isset($_GET['template']) ? preg_replace('~[^a-z_]~', '', $_GET['template']) : '';
    if (empty($modSettings['shd_display_ticket_logs']) || empty($_GET['log']) || empty($email_type)) {
        fatal_lang_error('no_access', false);
    }
    $query = $smcFunc['db_query']('', '
		SELECT hdla.id_member, hdla.id_ticket, hdla.id_msg, hdla.extra, IFNULL(hdtr.body, {string:empty}) AS body, IFNULL(mem.real_name, hdtr.poster_name) AS poster_name
		FROM {db_prefix}helpdesk_log_action AS hdla
			LEFT JOIN {db_prefix}helpdesk_ticket_replies AS hdtr ON (hdla.id_msg = hdtr.id_msg)
			LEFT JOIN {db_prefix}members AS mem ON (hdtr.id_member = mem.id_member)
		WHERE id_action = {int:log}
			AND action = {string:notify}', array('log' => $_GET['log'], 'notify' => 'notify', 'empty' => ''));
    if ($smcFunc['db_num_rows']($query) == 0) {
        $smcFunc['db_free_result']($query);
        fatal_lang_error('no_access');
    }
    $row = $smcFunc['db_fetch_assoc']($query);
    $smcFunc['db_free_result']($query);
    $row['extra'] = unserialize($row['extra']);
    // Just check we did actually log an email of that type.
    if (empty($row['extra']['emails'][$_GET['template']])) {
        fatal_lang_error('no_access', false);
    }
    $ticketinfo = shd_load_ticket($row['id_ticket']);
    // OK, if we're here, we can see the ticket. Can we actually see the email log at this point?
    if (!shd_allowed_to('shd_view_ticket_logs_any', $ticketinfo['dept']) && (!shd_allowed_to('shd_view_ticket_logs_own', $ticketinfo['dept']) || !$ticketinfo['is_own'])) {
        fatal_lang_error('no_access', false);
    }
    // We're reusing the Help template, need its language file.
    loadLanguage('Help');
    shd_load_language('sd_language/SimpleDeskAdmin');
    shd_load_language('sd_language/SimpleDeskLogAction');
    shd_load_language('sd_language/SimpleDeskNotifications');
    // Set the page up
    loadTemplate('Help');
    $context['page_title'] = $context['forum_name'] . ' - ' . $txt['shd_log_notifications'];
    $context['template_layers'] = array();
    $context['sub_template'] = 'popup';
    $users = array();
    // First, get the list of users, and load their username etc if we haven't already attempted it before.
    if (isset($row['extra']['emails'][$email_type]['u'])) {
        $users = array_merge($users, explode(',', $row['extra']['emails'][$email_type]['u']));
    }
    if (!empty($users)) {
        $users = array_unique($users);
        if (!empty($users)) {
            loadMemberData($users, false, 'minimal');
        }
    }
    // Now we have all the usernames for this instance, let's go and build this entry.
    $context['help_text'] = $txt['shd_log_notify_to'] . '<br />';
    $new_content = '';
    if (!empty($users)) {
        $first = true;
        foreach ($users as $user) {
            if (empty($user_profile[$user])) {
                continue;
            }
            $new_content .= ($first ? '<img src="' . shd_image_url('user.png') . '" alt="" /> ' : ', ') . shd_profile_link($user_profile[$user]['real_name'], $user);
            $first = false;
        }
    }
    if (!empty($row['extra']['emails'][$email_type]['e'])) {
        $emails = explode(',', $row['extra']['emails'][$email_type]['e']);
        // Admins can see the actual emails.
        if (shd_allowed_to('admin_helpdesk', 0) || $user_info['is_admin']) {
            foreach ($emails as $key => $value) {
                $emails[$key] = '<a href="mailto:' . $value . '">' . $value . '</a>';
            }
            $new_content .= '<img src="' . shd_image_url('log_notify.png') . '" alt="" /> ' . implode(', ', $emails);
        } else {
            $new_content .= '<img src="' . shd_image_url('log_notify.png') . '" alt="" /> ' . (count($emails) == 1 ? $txt['shd_log_notify_hiddenemail_1'] : sprintf($txt['shd_log_notify_hiddenemail'], count($emails)));
        }
    }
    if (!empty($new_content)) {
        $context['help_text'] .= $new_content;
    }
    $context['help_text'] .= '<hr />';
    // So the general prep is done. Now let's rebuild the email contents.
    if (empty($row['extra']['withbody']) || empty($row['body'])) {
        $body = '';
    } else {
        $body = trim(un_htmlspecialchars(strip_tags(strtr(shd_format_text($row['body'], false), array('<br />' => "\n", '</div>' => "\n", '</li>' => "\n", '&#91;' => '[', '&#93;' => ']')))));
    }
    $replacements = array("\n" => '<br />', '{ticket_id}' => str_pad($row['id_ticket'], $modSettings['shd_zerofill'], '0', STR_PAD_LEFT), '{subject}' => empty($row['extra']['subject']) ? $txt['no_subject'] : $row['extra']['subject'], '{ticketlink}' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $row['id_ticket'] . (empty($row['id_msg']) ? '.0' : '.msg' . $row['id_msg'] . '#msg' . $row['id_msg']), '{body}' => $body, '{poster_name}' => $row['poster_name']);
    $email_subject = str_replace(array_keys($replacements), array_values($replacements), $txt['template_subject_notify_' . $email_type]);
    $email_body = str_replace(array_keys($replacements), array_values($replacements), $txt['template_' . (empty($row['extra']['withbody']) || empty($row['body']) ? 'body' : 'bodyfull') . '_notify_' . $email_type]);
    $context['help_text'] .= '<strong>' . $txt['subject'] . ':</strong> ' . $email_subject . '<br /><br />' . $email_body;
}
예제 #13
0
/**
 *	Callback function for the template to load messages.
 *
 *	The process set up by shd_view_ticket() and invoked within template_view_replies() is reasonably complex.
 *	{@link shd_view_ticket()} identifies what messages should be displayed on the current page of the ticket, and performs a query
 *	to load the ticket data. Instead, however, of retrieving every row directly into memory before passing to the template,
 *	it passes the query result, and the name of a handler function into $context, so the template can call to get an
 *	individual row at a time, which saves memory amongst other things.
 *
 *	With respect to {@link shd_view_ticket()}, the relevant items are $reply_request being defined and $context['get_replies']
 *	being defined as the name of this function, and in {@link template_view_replies()}, the reference is $reply = $context['get_replies']()
 *
 *	@return mixed The function returns the "next" message reply's details, or simply false if no replies were available, or no further replies are available. Assuming a reply can be returned, it will be a hash array in the following format:
 *	<ul>
 *		<li>id: numeric message id</li>
 *		<li>member: hash array containing details of the poster; normally the return value from SMF's loadMemberContext() function. A minimal set of details is prepared if the poster holds no current SMF account. Common values:
 *			<ul>
 *				<li>name: User's name (falls back to the poster name specified in the replies table)</li>
 *				<li>id: User's id</li>
 *				<li>group: Name of the assigned group/post count group of the user</li>
 *				<li>link: HTML for a hyperlink to their profile</li>
 *				<li>email: Email address of the poster</li>
 *				<li>ip: IP address of the poster</li>
 *			</ul>
 *		</li>
 *		<li>body: censored, parsed for smileys and bbcode (in {@link shd_format_text()})</li>
 *		<li>time: string of the time the reply was posted</li>
 *		<li>timestamp: internal stored timestamp attached to the reply</li>
 *		<li>is_staff: boolean value of whether the posting member is currently helpdesk staff</li>
 *		<li>can_edit: boolean value reflecting if this reply can be edited</li>
 *		<li>can_delete: boolean value reflecting if this reply can be deleted</li>
 *		<li>can_restore: boolean value reflecting if this reply can be restored</li>
 *		<li>ip_address: IP address used to post the message (not necessarily the user's normal IP address); if the user has moderate_forum_members permission, this returns a link to the track IP area, with the IP address as the link text, alternatively simply the IP address if not (is only displayed to helpdesk staff)</li>
 *		<li>modified: may not be declared, if it is, the message was modified some time after posting, and the following data items are in the hash array within:
 *			<ul>
 *				<li>id: user id who edited the reply (not always available)</li>
 *				<li>time: formatted string of the time the post was edited</li>
 *				<li>timestamp: raw timestamp of the time the post was edited</li>
 *				<li>name: user name of the editing user; if we have a definite user id, this should contain the current name, falling back to the previously stored name</li>
 *				<li>link: if we have a known, valid user id for the post's editor, this will contain a link to their profile, with the link text using their current display name; alternatively it will contain a regular string which is the username stored with the edit.</li>
 *			</ul>
 *		</li>
 *	</ul>
 *
 *	@see shd_view_ticket()
 *	@since 1.0
*/
function shd_prepare_ticket_context()
{
    global $settings, $txt, $modSettings, $scripturl, $options, $user_info, $smcFunc;
    global $memberContext, $context, $reply_request, $user_profile;
    if (empty($reply_request)) {
        return false;
    }
    $message = $smcFunc['db_fetch_assoc']($reply_request);
    if (!$message) {
        $smcFunc['db_free_result']($reply_request);
        return false;
    }
    if (!loadMemberContext($message['id_member'], true)) {
        // Notice this information isn't used anywhere else....
        $memberContext[$message['id_member']]['name'] = $message['poster_name'];
        $memberContext[$message['id_member']]['id'] = 0;
        $memberContext[$message['id_member']]['group'] = $txt['guest_title'];
        $memberContext[$message['id_member']]['link'] = $message['poster_name'];
        $memberContext[$message['id_member']]['email'] = $message['poster_email'];
        $memberContext[$message['id_member']]['show_email'] = showEmailAddress(true, 0);
        $memberContext[$message['id_member']]['is_guest'] = true;
        $memberContext[$message['id_member']]['group_stars'] = '';
    }
    $memberContext[$message['id_member']]['ip'] = $message['poster_ip'];
    censorText($message['body']);
    $message['body'] = shd_format_text($message['body'], $message['smileys_enabled'], 'shd_reply_' . $message['id_msg']);
    $output = array('id' => $message['id_msg'], 'member' => &$memberContext[$message['id_member']], 'time' => timeformat($message['poster_time']), 'timestamp' => forum_time(true, $message['poster_time']), 'body' => $message['body'], 'is_staff' => !empty($context['shd_is_staff'][$message['id_member']]), 'can_edit' => $message['message_status'] != MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_edit_reply_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_edit_reply_own', $context['ticket']['dept'])), 'can_delete' => $message['message_status'] != MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_delete_reply_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_delete_reply_own', $context['ticket']['dept'])), 'can_restore' => $message['message_status'] == MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && (shd_allowed_to('shd_restore_reply_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_restore_reply_own', $context['ticket']['dept'])), 'can_permadelete' => $message['message_status'] == MSG_STATUS_DELETED && !$context['ticket']['closed'] && !$context['ticket']['deleted'] && shd_allowed_to('shd_delete_recycling', $context['ticket']['dept']), 'message_status' => $message['message_status'], 'link' => $scripturl . '?action=helpdesk;sa=ticket;ticket=' . $context['ticket_id'] . '.msg' . $message['id_msg'] . '#msg' . $message['id_msg']);
    if (shd_allowed_to('shd_view_ip_any', $context['ticket']['dept']) || $message['id_member'] == $user_info['id'] && shd_allowed_to('shd_view_ip_own', $context['ticket']['dept'])) {
        $output['ip_address'] = $context['link_ip_address'] ? '<a href="' . $scripturl . '?action=trackip;searchip=' . $message['poster_ip'] . '">' . $message['poster_ip'] . '</a>' : $message['poster_ip'];
    }
    if (!empty($message['modified_time'])) {
        $output['modified'] = array('time' => timeformat($message['modified_time']), 'timestamp' => forum_time(true, $message['modified_time']), 'id' => !empty($user_profile[$message['modified_member']]) ? $message['modified_member'] : 0, 'name' => !empty($user_profile[$message['modified_member']]) ? $user_profile[$message['modified_member']]['real_name'] : $message['modified_name']);
        $output['modified']['link'] = shd_profile_link($output['modified']['name'], $output['modified']['id']);
    }
    if (!empty($context['ticket_start_newfrom']) && $context['ticket_start_newfrom'] == $message['id_msg']) {
        $output['is_new'] = true;
    }
    return $output;
}
예제 #14
0
/**
 *	Loads the main SimpleDesk information page for forum administrators.
 *
 *	This function is the main focus point for information about SimpleDesk in the admin panel, primarily it collects the following for the template:
 *	<ul>
 *	<li>list of helpdesk staff</li>
 *	<li>totals of tickets in the system (open/closed/deleted)</li>
 *	<li>credits</li>
 *	<li>also, in the template, whether this is a current or outdated version of SimpleDesk</li>
 *	</ul>
 *
 *	Since 1.1, it also receives the requests for subactions for action log and support page (since these are sub menu items) but simply directs them onward.
 *
 *	@see shd_admin_action_log()
 *	@see shd_admin_support()
 *
 *	@since 1.0
*/
function shd_admin_info()
{
    global $context, $settings, $scripturl, $txt, $sourcedir, $smcFunc;
    $subactions = array('main' => array('function' => false, 'icon' => 'simpledesk.png', 'title' => $txt['shd_admin_info']), 'actionlog' => array('function' => 'shd_admin_action_log', 'icon' => 'log.png', 'title' => $txt['shd_admin_actionlog_title']), 'support' => array('function' => 'shd_admin_support', 'icon' => 'support.png', 'title' => $txt['shd_admin_support']));
    $context[$context['admin_menu_name']]['tab_data'] = array('description' => $txt['shd_admin_options_desc'], 'tabs' => array('main' => array('description' => '<strong>' . $txt['hello_guest'] . ' ' . $context['user']['name'] . '!</strong><br />' . $txt['shd_admin_info_desc']), 'actionlog' => array('description' => $txt['shd_admin_actionlog_desc'] . '<br />' . (!empty($modSettings['shd_disable_action_log']) ? '<span class="smalltext">' . $txt['shd_action_log_disabled'] . '</span>' : '')), 'support' => array('description' => $txt['shd_admin_support_desc'])));
    call_integration_hook('shd_hook_hdadmininfo', array(&$subactions));
    $_REQUEST['sa'] = isset($_REQUEST['sa']) && isset($subactions[$_REQUEST['sa']]) ? $_REQUEST['sa'] : 'main';
    // Now that we have validated the subaction.
    $context[$context['admin_menu_name']]['tab_data']['title'] = '<img src="' . $settings['images_url'] . '/admin/shd/' . $subactions[$_REQUEST['sa']]['icon'] . '" class="icon" alt="*" />' . $subactions[$_REQUEST['sa']]['title'];
    // Are we doing the main page, or leaving here?
    if (!empty($subactions[$_REQUEST['sa']]['function'])) {
        $subactions[$_REQUEST['sa']]['function']();
        return;
    }
    // Get a list of the staff members of the helpdesk.
    $members = shd_members_allowed_to('shd_staff');
    $query = shd_db_query('', '
		SELECT id_member, real_name
		FROM {db_prefix}members
		WHERE id_member IN ({array_int:members})
		ORDER BY real_name', array('members' => $members));
    // Note this just gets everyone, doesn't worry about limiting it - IMO that's something for the template to decide.
    $context['staff'] = array();
    while ($row = $smcFunc['db_fetch_assoc']($query)) {
        $context['staff'][] = shd_profile_link($row['real_name'], $row['id_member']);
    }
    $smcFunc['db_free_result']($query);
    // Make we sure give these slackers some credit. After all, they made sumfin fer ya!
    shd_credits();
    $context['total_tickets'] = shd_count_helpdesk_tickets();
    $context['open_tickets'] = shd_count_helpdesk_tickets('open');
    $context['closed_tickets'] = shd_count_helpdesk_tickets('closed');
    $context['recycled_tickets'] = shd_count_helpdesk_tickets('recycled');
    // Final stuff before we go.
    $context['page_title'] = $txt['shd_admin_title'];
    $context['sub_template'] = 'shd_admin';
}