View source
<?php
define('SUPPORT_STATE_CLOSED', -3);
define('SUPPORT_SORT_NONE', 0);
define('SUPPORT_SORT_UPDATE', 1);
define('SUPPORT_SORT_NID', 2);
define('SUPPORT_SORT_STATE', 3);
define('SUPPORT_SORT_PRIORITY', 4);
define('SUPPORT_SORT_ASC', 0);
define('SUPPORT_SORT_DESC', 1);
define('SUPPORT_ALL_CLIENTS', '-1');
function support_node_info() {
return array(
'support_ticket' => array(
'name' => t('Support ticket'),
'module' => 'support',
'description' => t('A <em>support ticket</em>.'),
),
);
}
function support_access($op, $node, $account) {
switch ($op) {
case 'create':
return user_access('create tickets', $account);
case 'update':
return user_access('edit any ticket', $account) || user_access('edit own tickets', $account) && $node->uid == $account->uid || user_access('administer support', $account);
case 'delete':
return user_access('delete any ticket', $account) || user_access('delete own tickets', $account) && $node->uid == $account->uid || user_access('administer support', $account);
case 'view':
if (isset($node->client)) {
$client = support_client_load($node->client);
if (support_access_clients($client, $account)) {
if (user_access('view other users tickets') || user_access('administer support') || user_access('edit any ticket') || user_access('delete any ticket')) {
$access = NULL;
}
else {
if ($account->uid == $node->uid && $account->uid != 0) {
$access = NULL;
}
else {
if (db_result(db_query('SELECT 1 FROM {support_assigned} WHERE nid = %d AND uid = %d', $node->nid, $account->uid))) {
$access = NULL;
}
else {
$access = FALSE;
}
}
}
}
else {
$access = FALSE;
}
return $access;
}
}
}
function support_menu() {
$items['support'] = array(
'title' => 'Support tickets',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_page_form',
),
'access callback' => 'support_access_clients',
'access arguments' => array(),
);
$items['support/fetch'] = array(
'type' => MENU_CALLBACK,
'page callback' => 'support_fetch_client_mail',
'access arguments' => array(
'download mail via support/fetch',
),
);
$items['support/autocomplete/assigned'] = array(
'title' => 'Autocomplete support assigned user',
'page callback' => 'support_autocomplete_assigned',
'access callback' => 'support_access_clients',
'access arguments' => array(),
'type' => MENU_CALLBACK,
);
$items['support/autocomplete/autosubscribe'] = array(
'title' => 'Autocomplete support autosubscribed user',
'page callback' => 'support_autocomplete_autosubscribe',
'access callback' => '_support_autosubscribe_access',
'type' => MENU_CALLBACK,
);
$states = array(
'all' => 'all',
'all open' => 'all open',
'my open' => 'my open',
) + _support_states();
$result = db_query('SELECT clid, path, name FROM {support_client} WHERE status = 1 AND parent = 0');
$clients = array();
while ($client = db_fetch_object($result)) {
$clients[] = $client;
}
if (count($clients) > 1) {
$combined = new stdClass();
$combined->clid = SUPPORT_ALL_CLIENTS;
$combined->path = '_all_';
$combined->name = '** All Tickets **';
$clients[] = $combined;
}
foreach ($clients as $client) {
$items['support/' . $client->path] = array(
'title' => check_plain($client->name),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_page_form',
$client->clid,
),
'access callback' => 'support_access_clients',
'access arguments' => array(
$client,
),
);
foreach ($states as $sid => $state) {
$items["support/{$client->path}/{$state}"] = array(
'title' => "{$state}",
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_page_form',
$client->clid,
$state,
),
'access callback' => 'support_access_clients',
'access arguments' => array(
$client,
),
'weight' => $sid,
'type' => $sid == 'all open' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
);
}
$result2 = db_query('SELECT clid, path, name FROM {support_client} WHERE status = 1 AND parent = %d', $client->clid);
while ($subclient = db_fetch_object($result2)) {
$items["support/{$client->path}/{$subclient->path}"] = array(
'title' => check_plain($subclient->name),
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_page_form',
$subclient->clid,
),
'access callback' => 'support_access_clients',
'access arguments' => array(
$subclient,
),
);
foreach ($states as $sid => $state) {
$items["support/{$client->path}/{$subclient->path}/{$state}"] = array(
'title' => "{$state}",
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_page_form',
$subclient->clid,
$state,
),
'access callback' => 'support_access_clients',
'access arguments' => array(
$subclient,
),
'weight' => $sid,
'type' => $sid == 'all open' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
);
}
}
}
$items['support/user/%user'] = array(
'page callback' => 'support_page_user',
'page arguments' => array(
2,
),
'access callback' => 'support_access_user_tickets',
'access arguments' => array(
2,
),
'type' => MENU_CALLBACK,
'file' => 'support.user.inc',
);
$items['support/%user_uid_optional/assigned'] = array(
'title' => 'My tickets',
'page callback' => 'support_page_user',
'page arguments' => array(
1,
TRUE,
),
'access callback' => 'support_page_user_access',
'access arguments' => array(
1,
),
'file' => 'support.user.inc',
);
unset($states['my open']);
foreach ($states as $sid => $state) {
$items["support/%user_uid_optional/assigned/{$state}"] = array(
'title' => "{$state}",
'page callback' => 'support_page_user',
'page arguments' => array(
1,
TRUE,
$state,
),
'access callback' => 'support_access_clients',
'access arguments' => array(
$client,
),
'file' => 'support.user.inc',
'weight' => $sid,
'type' => $sid == 'all open' ? MENU_DEFAULT_LOCAL_TASK : MENU_LOCAL_TASK,
);
}
$items['support/%node/unsubscribe/%user/%'] = array(
'page callback' => 'support_unsubscribe_user',
'page arguments' => array(
1,
3,
4,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['support/all/unsubscribe/%user/%'] = array(
'page callback' => 'support_unsubscribe_user',
'page arguments' => array(
'all',
3,
4,
),
'access callback' => TRUE,
'type' => MENU_CALLBACK,
);
$items['admin/support'] = array(
'title' => 'Support ticketing system',
'description' => 'Manage the support ticket system.',
'position' => 'right',
'weight' => 5,
'page callback' => 'support_admin_menu_block_page',
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
$items['admin/support/clients'] = array(
'title' => 'Clients',
'description' => 'Manage clients.',
'page callback' => 'support_admin_client_overview',
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
$items['admin/support/clients/list'] = array(
'title' => 'List',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/support/clients/%support_client/edit'] = array(
'title' => 'Edit',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_admin_client',
3,
),
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
$items['admin/support/clients/%support_client/delete'] = array(
'title' => 'Delete',
'type' => MENU_CALLBACK,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_admin_client_delete',
3,
),
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
$items['admin/support/clients/%support_client/fetch'] = array(
'title' => 'Fetch mail',
'type' => MENU_CALLBACK,
'page callback' => 'support_client_fetch',
'page arguments' => array(
3,
),
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
$items['admin/support/clients/add'] = array(
'title' => 'Add client',
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_admin_client',
),
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
$items['admin/support/settings'] = array(
'title' => 'Settings',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_admin_settings',
),
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
$items['admin/support/settings/general'] = array(
'title' => 'General settings',
'type' => MENU_DEFAULT_LOCAL_TASK,
);
$items['admin/support/settings/mail'] = array(
'title' => 'Mail text settings',
'type' => MENU_LOCAL_TASK,
'weight' => 2,
'page callback' => 'drupal_get_form',
'page arguments' => array(
'support_admin_mail_settings',
),
'access arguments' => array(
'administer support',
),
'file' => 'support.admin.inc',
);
return $items;
}
function support_cron() {
if (variable_get('support_cron_download_mail', TRUE)) {
support_fetch_client_mail();
}
}
function support_theme() {
return array(
'support_page_form' => array(
'arguments' => array(
'form' => NULL,
),
),
'support_page_user' => array(
'arguments' => array(
'header' => NULL,
'rows' => NULL,
),
),
);
}
function support_theme_registry_alter(&$theme_registry) {
if (!empty($theme_registry['comment_wrapper'])) {
$theme_registry['comment_wrapper']['function'] = 'support_comment_wrapper';
}
}
function support_comment_wrapper($content, $node) {
if ($node->type == 'support_ticket' && variable_get('support_disable_post_comment', FALSE)) {
$content = str_replace(t('Post new comment'), '', $content);
}
return $content;
}
function support_link_alter(&$links, $node, $comment = NULL) {
if ($node->type == 'support_ticket' && variable_get('support_disable_comment_reply', FALSE)) {
unset($links['comment_reply']);
}
if ($node->type == 'support_ticket' && isset($node->taxonomy)) {
foreach ($node->taxonomy as $tid => $term) {
if (isset($links["taxonomy_term_{$tid}"])) {
$client = support_client_load($node->client);
$links["taxonomy_term_{$tid}"]['href'] = "support/{$client->path}";
$links["taxonomy_term_{$tid}"]['query'] = "tid={$tid}";
}
}
}
}
function support_init() {
global $conf;
if (module_exists('i18n')) {
foreach (_support_mail_text_default(NULL) as $key => $text) {
$conf['i18n_variables'][] = 'support_mail_' . $key;
}
}
}
function support_block($op = 'list', $delta = 0, $edit = array()) {
switch ($op) {
case 'list':
$blocks[0]['info'] = t('Support client access');
$blocks[0]['cache'] = BLOCK_CACHE_GLOBAL;
return $blocks;
case 'view':
$block = array();
if (arg(0) == 'support') {
$clid = _support_current_client();
$access_users = array();
$access_roles = array();
if ($clid) {
$client = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $clid));
$result = db_query("SELECT p.rid, r.name FROM {permission} p JOIN {role} r ON r.rid = p.rid WHERE perm LIKE '%%%s%%' OR perm LIKE '%%%s%%'", "access {$client} tickets", 'administer support');
$roles = array();
while ($role = db_fetch_object($result)) {
$roles[$role->rid] = $role->rid;
$access_roles[] = l($role->name, "admin/user/permissions/{$role->rid}");
}
if (!empty($roles)) {
$role_sql = "SELECT u.name, u.uid FROM {users} u LEFT JOIN {users_roles} r ON u.uid = r.uid WHERE r.rid IN (%s) AND u.status = 1";
if (variable_get('support_filter_uid1', FALSE)) {
$role_sql .= ' AND u.uid <> 1';
}
$result = db_query($role_sql, implode(', ', $roles));
while ($account = db_fetch_object($result)) {
$access_users[$account->uid] = theme('username', $account);
}
}
}
$block['subject'] = t('Client access');
$block['content'] = theme_item_list($access_roles, t('Roles')) . theme_item_list($access_users, t('Users'));
}
return $block;
}
}
function support_autocomplete_assigned($clid = 0, $string = '') {
$matches = array();
if ($string) {
if ($clid) {
$client = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $clid));
$result = db_query("SELECT rid FROM {permission} WHERE perm LIKE '%%%s%%' OR perm LIKE '%%%s%%'", "access {$client} tickets", 'administer support');
}
$roles = array();
while ($role = db_fetch_object($result)) {
$roles[$role->rid] = $role->rid;
}
$result = db_query("SELECT rid FROM {permission} WHERE perm LIKE '%%%s%%'", 'administer support');
while ($role = db_fetch_object($result)) {
$roles[$role->rid] = $role->rid;
}
if (!empty($roles)) {
$role_sql = "SELECT u.name FROM {users} u LEFT JOIN {users_roles} r ON u.uid = r.uid WHERE r.rid IN (%s) AND u.status = 1 AND LOWER(name) LIKE LOWER('%s%%')";
if (variable_get('support_filter_uid1', FALSE)) {
$role_sql .= ' AND u.uid <> 1';
}
$result = db_query_range($role_sql, implode(', ', $roles), $string, 0, 10);
while ($user = db_fetch_object($result)) {
$matches[$user->name] = check_plain($user->name);
}
}
}
drupal_json($matches);
}
function support_autocomplete_autosubscribe($clid, $string = '') {
$array = drupal_explode_tags($string);
$last_string = trim(array_pop($array));
$matches = array();
if ($last_string) {
$roles = array();
$client = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $clid));
$result = db_query("SELECT rid FROM {permission} WHERE perm LIKE '%%%s%%' OR perm LIKE '%%%s%%'", "access {$client} tickets", 'administer support');
while ($role = db_fetch_object($result)) {
$roles[$role->rid] = $role->rid;
}
if (!$clid) {
$result = db_query_range("SELECT name FROM {users} WHERE status = 1 AND LOWER(name) LIKE LOWER('%s%%')", $last_string, 0, 10);
}
else {
if (!empty($roles)) {
$result = db_query_range("SELECT u.name FROM {users} u LEFT JOIN {users_roles} r ON u.uid = r.uid WHERE r.rid IN (%s) AND u.status = 1 AND LOWER(u.name) LIKE LOWER('%s%%')", implode(', ', $roles), $last_string, 0, 10);
}
}
$prefix = count($array) ? implode(', ', $array) . ', ' : '';
while ($account = db_fetch_object($result)) {
$a = $account->name;
$matches[$prefix . $a] = check_plain($account->name);
}
}
drupal_json($matches);
}
function _support_validate_assigned_user($uid, $client) {
$account = user_load(array(
'uid' => $uid,
));
return user_access("access {$client} tickets", $account) || user_access('administer support', $account);
}
function support_fetch_client_mail() {
$clients = support_active_clients();
if (is_array($clients)) {
foreach ($clients as $clid => $client) {
if ($client->integrate_email) {
support_client_fetch($client, FALSE);
}
}
}
}
function support_help($path, $arg) {
switch ($path) {
case 'admin/support/clients':
$output = '<p>' . t('Each support ticket can only be assigned to one client. !create one or more clients, then !assign allowing users to access these tickets. Users can only create tickets for clients they have permission to access. If working with multiple clients you will need to !define for each to prevent one client from viewing the tickets of another client.', array(
'!create' => l(t('Create'), 'admin/support/clients/add'),
'!assign' => l(t('assign permissions'), 'admin/user/permissions', array(
'fragment' => 'module-support',
)),
'!define' => l(t('define roles'), 'admin/user/roles'),
)) . '</p>';
break;
case 'admin/support/clients/add':
case 'admin/support/clients/%/edit':
$output = '<p>' . t("Each support ticket must be assigned to one client. Support can be configured so one client can't view another client's tickets.") . '</p>';
$output .= '<p>' . t('If you would like users to be able to create and update tickets via email, you will require a dedicated email address for each client. This email address is used to send and receive update notifications. A cronjob automatically downloads emails sent to this address and converts them into tickets and ticket updates. The message_id of each email is tracked, allowing support to properly associate replies with existing tickets.') . '</p>';
break;
case 'admin/support/settings':
$output = '<p>' . t('Global settings for the support module.') . '</p>';
break;
default:
$output = '';
break;
}
return $output;
}
function support_active_clients() {
static $clients = NULL;
if (is_null($clients)) {
$result = db_query('SELECT * FROM {support_client} WHERE status = 1');
while ($client = db_fetch_object($result)) {
$clients[$client->clid] = $client;
}
}
return $clients;
}
function support_unsubscribe_user($node, $account, $key) {
if (is_object($node) && is_object($account)) {
$lock = md5($account->uid . $node->nid);
if ($key == $lock) {
db_query('DELETE FROM {support_assigned} WHERE uid = %d AND nid = %d', $account->uid, $node->nid);
drupal_set_message(t('%email has been unsubscribed from ticket %ticket.', array(
'%email' => check_plain($account->mail),
'%ticket' => check_plain($node->title),
)));
}
else {
drupal_set_message(t('Invalid key, failed to unsubscribe %email.', array(
'%email' => check_plain($account->mail),
)), 'error');
}
drupal_goto("node/{$node->nid}");
}
else {
if (is_object($account)) {
$lock = md5($account->uid);
if ($key == $lock) {
db_query('DELETE FROM {support_assigned} WHERE uid = %d', $account->uid);
drupal_set_message(t('%email has been unsubscribed from all tickets.', array(
'%email' => check_plain($account->mail),
)));
}
else {
drupal_set_message(t('Invalid key, failed to unsubscribe %email.', array(
'%email' => check_plain($account->mail),
)), 'error');
}
}
}
drupal_goto('');
}
function support_access_clients($client = NULL, $account = NULL) {
if (is_object($client)) {
if (is_object($account)) {
return user_access('administer support', $account) || user_access("access {$client->name} tickets", $account);
}
else {
if ($client->clid == SUPPORT_ALL_CLIENTS) {
if (_support_access_tickets() > 1) {
return TRUE;
}
else {
return FALSE;
}
}
return user_access('administer support') || user_access("access {$client->name} tickets");
}
}
else {
return _support_access_tickets();
}
}
function support_client_load($id, $integer = TRUE) {
static $clients = array();
if (!isset($clients[$id])) {
if ($integer) {
$client = db_fetch_object(db_query('SELECT clid, name, path, status, parent, integrate_email, server_name, server_username, server_password, mailfrom, mailbox, protocol, extra, port, notes, autoassign, autosubscribe, thread_subject, domains, user_creation FROM {support_client} WHERE clid = %d', $id));
}
else {
$client = db_fetch_object(db_query("SELECT clid, name, path, status, integrate_email, server_name, server_username, server_password, mailfrom, mailbox, protocol, extra, port, notes, autoassign, autosubscribe, thread_subject, domains, user_creation FROM {support_client} WHERE path = '%s'", $id));
}
drupal_alter('support_client_load', $client);
$clients[$id] = $client;
}
return $clients[$id];
}
function support_ticket_load($nid) {
static $tickets = array();
if (!isset($tickets[$nid])) {
$ticket = db_fetch_object(db_query('SELECT * FROM {support_ticket} WHERE nid = %d', $nid));
drupal_alter('support_ticket_load', $ticket);
$tickets[$nid] = $ticket;
}
return $tickets[$nid];
}
function support_access_user_tickets($account = array()) {
global $user;
if (user_access('administer support') || user_access('edit any ticket') || user_access('create tickets') && $account->uid == $user->uid) {
return TRUE;
}
return FALSE;
}
function _support_domains($client, $global) {
$domains = array();
$string = "{$client}, {$global}";
$raw = explode(',', $string);
foreach ($raw as $domain) {
if ($domain) {
$domains[] = check_plain(trim($domain));
}
}
return $domains;
}
function support_account_load($from, $ticket, $subject, $client) {
$uid = db_result(db_query("SELECT uid FROM {users} WHERE mail = '%s'", $from));
if ($uid) {
return user_load($uid);
}
else {
if ($client->user_creation == 2 || $client->user_creation == 0 && variable_get('support_autocreate_users', TRUE) == FALSE) {
watchdog('support', 'An autocreation of a user from the e-mail address: !from was denied. The client recieving the request was: !client', array(
'!from' => utf8_encode($from),
'!client' => $client->name,
));
_support_mail_deny($from);
return FALSE;
}
else {
$matches = array();
preg_match('~[\\w-]+\\.\\w+(?=/|$)~', $from, $matches);
$domain = $matches[0];
$ticket = support_ticket_load($ticket);
$domains = _support_domains($client->domains, variable_get('support_global_domains', ''));
$valid = TRUE;
if (!empty($domains)) {
$valid = FALSE;
foreach ($domains as $match) {
if ($domain == $match || $match == '*') {
$valid = TRUE;
break;
}
}
}
if ($valid) {
watchdog('support', 'User !username automatically created.', array(
'!username' => $from,
), WATCHDOG_NOTICE);
return user_save(NULL, array(
'mail' => $from,
'init' => $from,
'name' => $from,
'status' => 1,
));
}
else {
$node = node_load($ticket->nid);
watchdog('support', 'Email update from !from denied for ticket "!title", subject "!subject."', array(
'!from' => $from,
'!title' => check_plain($node->title),
'!subject' => $subject,
), WATCHDOG_NOTICE);
return FALSE;
}
}
}
}
function support_perm() {
$perm = array(
'administer support',
'create tickets',
'delete any ticket',
'delete own tickets',
'edit any ticket',
'edit own tickets',
'edit multiple tickets',
'can administer state',
'can suppress notification',
'can subscribe other users to notifications',
'download mail via support/fetch',
'view other users tickets',
'can select state',
'can select priority',
'can select client',
'can assign tickets to self',
'can assign tickets to any user',
'move ticket',
);
$result = db_query('SELECT name FROM {support_client} WHERE status = 1');
while ($client = db_fetch_object($result)) {
$perm[] = 'access ' . check_plain($client->name) . ' tickets';
}
return $perm;
}
function support_user($type, &$edit, &$account) {
global $user;
if (variable_get('support_display_user_links', TRUE)) {
if ($type == 'view' && (user_access('create tickets', $account) && $user->uid == $account->uid || user_access('administer support'))) {
$items = array();
$items[] = l(t('View recent tickets'), "support/user/{$account->uid}", array(
'attributes' => array(
'title' => t("Read @username's latest tickets.", array(
'@username' => check_plain($account->name),
)),
),
));
$items[] = l(t('Create new ticket'), 'node/add/support-ticket');
$account->content['summary']['support'] = array(
'#type' => 'user_profile_item',
'#title' => t('Tickets'),
'#value' => theme('item_list', $items),
'#attributes' => array(
'class' => 'support',
),
);
}
}
}
function support_form(&$node) {
$type = node_get_types('type', $node);
$form['title'] = array(
'#type' => 'textfield',
'#title' => check_plain($type->title_label),
'#required' => TRUE,
'#default_value' => !empty($node->title) ? $node->title : NULL,
'#weight' => -5,
);
$reference = array();
$form = array_merge($form, support_status_form($reference, $node, ''));
$form['body_field'] = node_body_field($node, $type->body_label, $type->min_word_count);
if (isset($node->nid) && $node->nid) {
$form['ticket'] = array(
'#type' => 'fieldset',
'#title' => t('Support ticket'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#access' => user_access('administer support'),
);
$form['ticket']['move'] = array(
'#type' => 'textfield',
'#title' => t('Move ticket'),
'#maxlength' => 12,
'#size' => 8,
'#description' => t('Optionally specify another ticket id to move this ticket and all of its updates. When moved, this ticket and all of its updates will become updates to the specified ticket and this ticket will be removed. This action can not be undone.'),
'#access' => user_access('administer support') || user_access('move ticket'),
);
}
$form = array_merge($form, support_subscribe_form($reference, $node, ''));
return $form;
}
function support_nodeapi(&$node, $op, $teaser, $page) {
global $user;
if ($node->type == 'support_ticket') {
$autocomplete = 'subscribed-users';
switch ($op) {
case 'view':
drupal_add_css(drupal_get_path('module', 'support') . '/support-tickets.css');
$breadcrumb = array();
$breadcrumb[] = l(t('Home'), NULL);
$breadcrumb[] = l(t('Support tickets'), 'support');
if (is_numeric($node->client)) {
$_SESSION['support_client'] = $node->client;
$client = support_client_load($node->client);
if (!empty($client->parent)) {
$parent = support_client_load($client->parent);
$breadcrumb[] = l(check_plain($parent->name), "support/{$parent->path}");
$breadcrumb[] = l(check_plain($client->name), "support/{$parent->path}/{$client->path}");
}
else {
$breadcrumb[] = l(check_plain($client->name), "support/{$client->path}");
}
}
drupal_set_breadcrumb($breadcrumb);
break;
case 'load':
return db_fetch_array(db_query('SELECT message_id, state, priority, client, assigned FROM {support_ticket} WHERE nid = %d', $node->nid));
case 'validate':
$client = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $node->client));
if (!isset($node->client) || $node->client == 0) {
form_set_error('client', t('You must select a client'));
}
if (isset($node->assigned) && !is_numeric($node->assigned)) {
$assigned = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $node->assigned));
if ($node->assigned && !$assigned) {
form_set_error('assigned', t('You must specify a valid user.'));
}
else {
if ($assigned) {
$valid = _support_validate_assigned_user($assigned, $client);
if (!$valid) {
form_set_error('assigned', t('You must specify a user that has permission to view this ticket.'));
}
}
}
}
if (isset($node->move) && is_numeric($node->move) && $node->move) {
$destination = node_load(array(
'nid' => $node->move,
));
if (!is_object($destination) || !$destination->nid) {
form_set_error('move', t('Destination node does not exist.'));
}
}
if (isset($node->notifications) && !empty($node->notifications)) {
$notifications = explode(',', $node->notifications);
foreach ($notifications as $notify) {
$valid = _support_validate_assigned_user($notify, $client);
if (!$valid) {
$account = user_load(array(
'uid' => $notify,
));
form_set_error("notify-{$notify}", t('Unable to subscribe user, %user does not have permission to view this ticket.', array(
'%user' => $account->name,
)));
}
}
}
else {
if (!empty($node->{$autocomplete})) {
$notifications = explode(',', $node->{$autocomplete});
foreach ($notifications as $notify) {
$account = user_load(array(
'name' => trim($notify),
));
if (empty($account) || !user_access("access {$client} tickets", $account) && !user_access('administer support', $account)) {
form_set_error('subscribed-users', t('Unable to subscribe user, %user does not have permission to view this ticket.', array(
'%user' => $notify,
)));
}
}
}
}
break;
case 'insert':
case 'update':
if (isset($node->move) && is_numeric($node->move) && $node->move) {
$destination = node_load($node->move);
_support_node_move($node, $destination);
}
if (isset($node->assigned) && !is_numeric($node->assigned)) {
$assigned = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $node->assigned));
if ($assigned) {
$node->assigned = $assigned;
}
else {
$node->assigned = 0;
}
}
db_query("UPDATE {support_ticket} SET message_id = '%s', state = %d, priority = %d, client = %d, assigned = %d WHERE nid = %d", isset($node->message_id) ? $node->message_id : '', $node->state, $node->priority, $node->client, $node->assigned, $node->nid);
if (!db_affected_rows()) {
@db_query("INSERT INTO {support_ticket} (nid, message_id, state, priority, client, assigned) VALUES(%d, '%s', %d, %d, %d, %d)", $node->nid, isset($node->message_id) ? $node->message_id : '', $node->state, $node->priority, $node->client, $node->assigned);
}
if (isset($node->notifications) && !empty($node->notifications)) {
$notifications = explode(',', $node->notifications);
foreach ($notifications as $notify) {
$enabled = "notify-{$notify}";
support_subscribe_user($node->nid, $notify, $node->{$enabled});
}
}
else {
if (isset($node->{$autocomplete})) {
$notifications = explode(',', $node->{$autocomplete});
foreach ($notifications as $notify) {
$account = user_load(array(
'name' => trim($notify),
));
if (!empty($account)) {
support_subscribe_user($node->nid, $account->uid);
}
}
}
}
if ($op == 'insert') {
if (variable_get('support_autosubscribe_creator', FALSE) || isset($node->created_by_email)) {
support_subscribe_user($node->nid, $node->uid);
}
else {
support_subscribe_user($node->nid, $node->uid, $node->notification);
}
if ($node->assigned || isset($node->created_by_email) || !user_access('can subscribe other users to notifications')) {
support_subscribe_user($node->nid, $node->assigned);
}
if (variable_get('support_autosubscribe_force', FALSE) || isset($node->created_by_email) || !user_access('can subscribe other users to notifications')) {
_support_autosubscribe($node->nid, $node->client);
}
support_notification(array(), $node->nid, 'ticket_new', isset($node->suppress) ? $node->suppress : FALSE);
}
cache_clear_all();
break;
case 'delete':
db_query('DELETE FROM {support_ticket} WHERE nid = %d', $node->nid);
break;
}
}
}
function support_comment(&$comment, $op) {
global $user;
if (is_array($comment)) {
$node = node_load($comment['nid']);
}
else {
$node = node_load($comment->nid);
}
if ($node->type == 'support_ticket') {
switch ($op) {
case 'view':
support_comment_view($comment);
break;
case 'validate':
if (isset($comment['assigned']) && !is_numeric($comment['assigned'])) {
$assigned = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $comment['assigned']));
if ($node->assigned && !$assigned) {
form_set_error('assigned', t('You must specify a valid user.'));
}
else {
if ($assigned) {
$client = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $node->client));
$valid = _support_validate_assigned_user($assigned, $client);
if (!$valid) {
form_set_error('assigned', t('You must specify a user that has permission to view this ticket.'));
}
}
}
}
break;
case 'insert':
case 'update':
if (isset($comment['assigned']) && !is_numeric($comment['assigned'])) {
$assigned = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $comment['assigned']));
if ($assigned) {
$comment['assigned'] = $assigned;
}
else {
$comment['assigned'] = 0;
}
}
db_query("UPDATE {support_ticket_comment} SET message_id = '%s', state = %d, priority = %d, client = %d, assigned = %d WHERE cid = %d", isset($comment['message_id']) ? $comment['message_id'] : '', $comment['state'], $comment['priority'], $comment['client'], $comment['assigned'], $comment['cid']);
if (!db_affected_rows()) {
@db_query("INSERT INTO {support_ticket_comment} (cid, message_id, state, priority, client, assigned) VALUES(%d, '%s', %d, %d, %d, %d)", $comment['cid'], isset($comment['message_id']) ? $comment['message_id'] : '', $comment['state'], $comment['priority'], $comment['client'], $comment['assigned']);
$comment['previous'] = new stdClass();
$comment['previous']->state = $node->state;
$comment['previous']->priority = $node->priority;
$comment['previous']->client = $node->client;
$comment['previous']->assigned = $node->assigned;
}
_support_comment_update_node($comment['nid']);
if ($op == 'insert') {
if (variable_get('support_autosubscribe_creator', FALSE)) {
support_subscribe_user($comment['nid'], $comment['uid']);
}
else {
support_subscribe_user($comment['nid'], $comment['uid'], $comment['notification']);
}
if (variable_get('support_autosubscribe_force', FALSE)) {
_support_autosubscribe($comment['nid'], $comment['client']);
}
if ($comment['assigned']) {
support_subscribe_user($comment['nid'], $comment['assigned']);
}
support_notification($comment, $comment['nid'], 'ticket_comment_new', isset($comment['suppress']) ? $comment['suppress'] : FALSE);
}
if (user_access('administer support') && (!isset($comment['support_email']) || !$comment['support_email'])) {
if (isset($comment['subscribed-users']) && !empty($comment['subscribed-users'])) {
$array = drupal_explode_tags($comment['subscribed-users']);
foreach ($array as $name) {
$uid = db_result(db_query("SELECT uid FROM {users} WHERE name = '%s'", $name));
$comment["notify-{$uid}"] = 1;
}
}
$available = _support_assigned(0, $node);
foreach ($available as $uid => $name) {
if (!$uid || $user->uid == $uid) {
continue;
}
support_subscribe_user($node->nid, $uid, $comment["notify-{$uid}"]);
}
}
break;
case 'delete':
db_query('DELETE FROM {support_ticket_comment} WHERE cid = %d', $comment->cid);
_support_comment_update_node($comment->nid);
}
}
}
function support_comment_view(&$comment) {
static $state = 0;
static $priority = 0;
static $client = 0;
static $assigned = 0;
$current = db_fetch_object(db_query('SELECT state, priority, client, assigned FROM {support_ticket_comment} WHERE cid = %d', $comment->cid));
if (!empty($current) && $assigned != $current->assigned) {
$previous_account = user_load(array(
'uid' => $assigned,
));
$current_account = user_load(array(
'uid' => $current->assigned,
));
$comment->comment = '<div class="support-assigned">' . t('Assigned') . ': ' . ($previous_account->name ? check_plain($previous_account->name) : '<em>' . t('unassigned') . '</em>') . ' -> ' . ($current_account->name ? check_plain($current_account->name) : '<em>' . t('unassigned') . '</em>') . "</div>\n" . $comment->comment;
$assigned = $current->assigned;
}
if (!empty($current) && $client != $current->client) {
$comment->comment = '<div class="support-client">' . t('Client') . ': ' . check_plain(_support_client($client)) . ' -> ' . check_plain(_support_client($current->client)) . "</div>\n" . $comment->comment;
$client = $current->client;
}
if (!empty($current) && $state != $current->state) {
$comment->comment = '<div class="support-state">' . t('State') . ': ' . check_plain(_support_state($state)) . ' -> ' . check_plain(_support_state($current->state)) . "</div>\n" . $comment->comment;
$state = $current->state;
}
if (!empty($current) && $priority != $current->priority) {
$comment->comment = '<div class="support-priority">' . t('Priority') . ': ' . check_plain(_support_priorities($priority)) . ' -> ' . check_plain(_support_priorities($current->priority)) . "</div>\n" . $comment->comment;
$priority = $current->priority;
}
}
function support_mail($key, &$message, $params, $html = FALSE) {
$language = $message['language'];
$variables = support_mail_tokens($params['account'], $language, $params['nid'], isset($params['comment']) ? $params['comment'] : array(), $params['suppress'], $html);
$message['subject'] .= _support_mail_text($key . '_subject', $language, $variables, $params['integrate_email']);
$message['body'] = _support_mail_text($key . '_body', $language, $variables, $params['integrate_email']);
$cid = $params['cid'];
$references = array();
while ($cid) {
$cid = db_result(db_query('SELECT pid FROM {comments} WHERE cid = %d', $cid));
$references[] = _support_generate_message_id($params['nid'], $cid);
}
if (!isset($message['headers']['Message-ID'])) {
$message['headers']['Message-ID'] = _support_generate_message_id($params['nid'], $params['cid']);
}
if (!empty($references)) {
$message['headers']['In-Reply-To'] = $references[0];
$message['headers']['References'] = implode(' ', array_reverse($references));
}
}
function _support_generate_message_id($nid, $cid = 0) {
global $base_url;
$id_left = $cid . '.' . $nid;
$id_right = preg_replace('|.+://([a-zA-Z0-9\\._-]+).*|', '\\1', $base_url);
return "<{$id_left}@{$id_right}>";
}
function _support_node_move($node, $destination) {
if (!user_access('move ticket') && user_access('administer support')) {
drupal_set_message('Permission denied, unable to move ticket.');
}
$max = db_result(db_query('SELECT MAX(thread) FROM {comments} WHERE nid = %d', $destination->nid));
$max = rtrim($max, '/');
$thread = int2vancode(vancode2int($max) + 1) . '/';
$account = user_load(array(
'uid' => $node->uid,
));
db_query("INSERT INTO {comments} (nid, pid, uid, subject, comment, format, hostname, timestamp, status, thread, name, mail, homepage) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", $destination->nid, 0, $node->uid, $node->title, $node->body, 1, ip_address(), $node->changed, 0, $thread, $account->name, $account->mail, $account->homepage);
$comment = array();
$comment['cid'] = db_last_insert_id('comments', 'cid');
$comment['subject'] = $node->title;
$comment['comment'] = $node->body;
$comment['nid'] = $destination->nid;
$comment['uid'] = $account->uid;
$comment['message_id'] = db_result(db_query('SELECT message_id FROM {support_ticket} WHERE nid = %d', $node->nid));
$comment['support_email'] = TRUE;
$comment['notification'] = db_result(db_query('SELECT 1 FROM {support_assigned} WHERE nid = %d AND uid = %d', $destination->nid, $account->uid));
$comment['state'] = $destination->state;
$comment['priority'] = $destination->priority;
$comment['client'] = $destination->client;
$comment['assigned'] = $destination->assigned;
comment_invoke_comment($comment, 'insert');
if (db_table_exists('upload')) {
if (module_exists('comment_upload')) {
$result = db_query('SELECT fid, description, list, weight FROM {upload} WHERE nid = %d', $node->nid);
while ($upload = db_fetch_object($result)) {
db_query("INSERT INTO {comment_upload} (fid, nid, cid, description, list, weight) VALUES(%d, %d, %d, '%s', %d, %d)", $upload->fid, $destination->nid, $comment['cid'], $upload->description, $upload->list, $upload->weight);
}
db_query('DELETE FROM {upload} WHERE nid = %d', $node->nid);
}
else {
db_query('UPDATE {upload} SET nid = %d WHERE nid = %d', $destination->nid, $node->nid);
}
}
watchdog('content', 'Comment: added %subject.', array(
'%subject' => $comment['subject'],
), WATCHDOG_NOTICE, l(t('view'), 'node/' . $comment['nid'], array(
'fragment' => 'comment-' . $comment['cid'],
)));
$result = db_query('SELECT cid, uid, subject, comment, format, hostname, timestamp, timestamp, status, thread, name, mail, homepage FROM {comments} WHERE nid = %d', $node->nid);
while ($update = db_fetch_array($result)) {
$oldcid = $update['cid'];
$max = rtrim($thread, '/');
$thread = int2vancode(vancode2int($max) + 1) . '/';
db_query("INSERT INTO {comments} (nid, pid, uid, subject, comment, format, hostname, timestamp, status, thread, name, mail, homepage) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", $destination->nid, 0, $update['uid'], $update['subject'], $update['comment'], $update['format'], $update['hostname'], $update['timestamp'], $update['status'], $thread, $update['name'], $update['mail'], $update['homepage']);
$update['cid'] = db_last_insert_id('comments', 'cid');
$update['nid'] = $destination->nid;
$comment['message_id'] = db_query('SELECT message_id FROM {support_ticket_comment} WHERE cid = %d', $oldcid);
$update['support_email'] = TRUE;
$update['notification'] = $comment['notification'];
$update['state'] = $destination->state;
$update['priority'] = $destination->priority;
$update['client'] = $destination->client;
$update['assigned'] = $destination->assigned;
comment_invoke_comment($update, 'insert');
if (module_exists('comment_upload')) {
db_query('UPDATE {comment_upload} SET nid = %d, cid = %d WHERE nid = %d AND cid = %d', $destination->nid, $update['cid'], $node->nid, $oldcid);
}
}
_comment_update_node_statistics($comment['nid']);
node_delete($node->nid);
drupal_set_message(t('Successfully moved support ticket.'));
watchdog('content', 'support_ticket: moved ticket %title from node/%old to node/%new.', array(
'%title' => $node->title,
'%old' => $node->nid,
'%new' => $destination->nid,
), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid, array(
'fragment' => 'comment-' . $comment['cid'],
)));
cache_clear_all();
drupal_goto("node/{$destination->nid}", NULL, 'comment-' . $comment['cid']);
}
function support_mail_tokens($account, $language, $nid, $comment, $suppress, $html = FALSE) {
global $base_url, $user;
static $reset = TRUE;
$node = node_load($nid, NULL, $reset);
$assigned = user_load(array(
'uid' => $node->assigned,
));
$reset = FALSE;
if (isset($comment['cid'])) {
$cid = $comment['cid'];
$update_account = user_load($comment['uid']);
}
else {
$cid = 0;
$update_account = user_load($node->uid);
}
$client = support_client_load($node->client);
$ticket_unsubscribe_key = md5($account->uid . $node->nid);
$all_unsubscribe_key = md5($account->uid);
$previous_comment = db_result(db_query_range('SELECT cid FROM {comments} WHERE nid = %d ORDER BY cid DESC', $nid, 1, 1));
if ($previous_comment) {
$previous = db_fetch_object(db_query('SELECT * FROM {support_ticket_comment} WHERE cid = %d', $previous_comment));
}
if ($html) {
$body = check_markup($node->body, variable_get('mimemail_format', FILTER_FORMAT_DEFAULT), FALSE) . _support_mail_list_attachments($node, $comment);
$update = check_markup(isset($comment['comment']) ? $comment['comment'] : '', variable_get('mimemail_format', FILTER_FORMAT_DEFAULT), FALSE) . _support_mail_list_attachments($node, $comment);
}
else {
$body = drupal_html_to_text(check_markup($node->body) . _support_mail_list_attachments($node, $comment));
$update = drupal_html_to_text(check_markup(isset($comment['comment']) ? $comment['comment'] : '') . _support_mail_list_attachments($node, $comment));
}
$tokens = array(
'!username' => $account->name,
'!client_name' => $client->name,
'!client_path' => $client->path,
'!key' => '[' . variable_get('support_key', 'tkt') . ":{$nid}]",
'!ticket_id' => $nid,
'!ticket_update_id' => isset($comment['cid']) ? $comment['cid'] : 0,
'!update_username' => isset($update_account->name) ? $update_account->name : '',
'!update_realname' => theme('username', $user),
'!site' => variable_get('site_name', 'Drupal'),
'!uri' => $base_url,
'!uri_brief' => preg_replace('!^https?://!', '', $base_url),
'!uri_login' => url('user/register', array(
'absolute' => TRUE,
'alias' => !variable_get('support_use_aliased_urls', TRUE),
)),
'!mailto' => $account->mail,
'!date' => format_date(time(), 'medium', '', NULL, $language->language),
'!ticket_subject' => check_plain($node->title),
'!ticket_body' => $suppress ? t('The text of this ticket was manually suppressed. You must view the ticket online to see it.') . "\n" : $body,
'!ticket_url' => url("node/{$nid}", array(
'absolute' => TRUE,
'language' => $language,
'fragment' => "comment-{$cid}",
'alias' => !variable_get('support_use_aliased_urls', TRUE),
)),
'!update_url' => url("node/{$nid}", array(
'absolute' => TRUE,
'language' => $language,
'fragment' => "comment-form",
'alias' => !variable_get('support_use_aliased_urls', TRUE),
)),
'!update' => $suppress ? t('The text of this ticket update was manually suppressed. You must view the ticket online to see the update.') . "\n" : $update,
'!state' => (isset($previous->state) && $previous->state != $node->state ? _support_state($previous->state) . ' -> ' : '') . _support_state($node->state),
'!priority' => (isset($previous->priority) && $previous->priority != $node->priority ? _support_priorities($previous->priority) . ' -> ' : '') . _support_priorities($node->priority),
'!assigned_username' => !empty($assigned) ? $assigned->name : '',
'!assigned_realname' => !empty($assigned) ? theme('username', $assigned) : '',
'!unsubscribe_ticket' => url("support/{$nid}/unsubscribe/{$account->uid}/{$ticket_unsubscribe_key}", array(
'absolute' => TRUE,
'language' => $language,
'alias' => !variable_get('support_use_aliased_urls', TRUE),
)),
'!unsubscribe_all' => url("support/all/unsubscribe/{$account->uid}/{$all_unsubscribe_key}", array(
'absolute' => TRUE,
'language' => $language,
'alias' => !variable_get('support_use_aliased_urls', TRUE),
)),
);
if (!empty($account->password)) {
$tokens['!password'] = $account->password;
}
drupal_alter('support_mail_tokens', $tokens);
return $tokens;
}
function _support_mail_list_attachments($node, $comment) {
$attachments = array();
if (empty($comment) && is_object($node) && is_array($node->files)) {
foreach ($node->files as $fid => $file) {
$attachments[] = file_create_url($file->filepath);
}
}
else {
if (isset($comment['files']) && is_array($comment['files'])) {
foreach ($comment['files'] as $fid => $file) {
$attachments[] = file_create_url($file['filepath']);
}
}
}
return !empty($attachments) ? "<br />" . t('Attachments:') . "<br />" . implode("<br />", $attachments) : '';
}
function _support_mail_text($key, $language = NULL, $variables = array(), $integrate_email) {
$langcode = isset($language) ? $language->language : NULL;
if ($integrate_email == TRUE) {
$variables['!reply'] = t('You can reply to this email or visit the following URL to update this ticket');
}
else {
$variables['!reply'] = t('You can visit the following URL to update this ticket');
}
if (module_exists('i18n')) {
$admin_setting = i18n_variable_get('support_mail_' . $key, $langcode);
}
if (empty($admin_setting)) {
$admin_setting = variable_get('support_mail_' . $key, '');
}
if (empty($admin_setting)) {
return t(_support_mail_text_default($key), $variables, $langcode);
}
return strtr($admin_setting, $variables);
}
function _support_mail_text_default($key) {
$info = array(
'ticket_deny_subject' => 'Support ticket creation denied',
'ticket_deny_body' => "System message\n\nYou have tried to create a support ticket on the !site site. The creation of the ticket has been cancelled since the e-mail address you sent the message from is not registered at our site.\n\nYou have to be a registered user to be able to create support tickets via mail.\n\nYour feedback is important to us so please register at !uri_login and try again.\n\n!site Team",
'ticket_new_subject' => '!key !ticket_subject',
'ticket_new_body' => "!update_username has created the ticket '!ticket_subject':\n!ticket_url\n\nState: !state\nPriority: !priority\n\n!reply:\n!update_url\n\nTicket text:\n------------------------------\n!ticket_body------------------------------\n\nUnsubscribe from this ticket:\n!unsubscribe_ticket\n\nUnsubscribe from all tickets:\n!unsubscribe_all",
'ticket_comment_new_subject' => '!key !ticket_subject',
'ticket_comment_new_body' => "!update_username has updated the ticket '!ticket_subject':\n!ticket_url\n\nState: !state\nPriority: !priority\n\n!reply:\n!update_url\n\nUpdate text:\n------------------------------\n!update------------------------------\n\nUnsubscribe from this ticket:\n!unsubscribe_ticket\n\nUnsubscribe from all tickets:\n!unsubscribe_all",
);
drupal_alter('support_mail_text_default', $info);
if (isset($key)) {
return isset($info[$key]) ? $info[$key] : '';
}
else {
return $info;
}
}
function support_save_message($message, $client, $manual = FALSE) {
if (isset($message['uid'])) {
$account = user_load($message['uid']);
}
else {
$account = support_account_load($message['from'], $message['nid'], $message['subject'], $client);
}
$ticket = support_ticket_load($message['nid']);
if (is_object($message['headers']) && isset($message['headers']->message_id)) {
$message_id = $message['headers']->message_id;
}
else {
$message_id = NULL;
}
if (is_object($account) && is_object($ticket) && $ticket->nid) {
$max = db_result(db_query('SELECT MAX(thread) FROM {comments} WHERE nid = %d', $ticket->nid));
$max = rtrim($max, '/');
$thread = int2vancode(vancode2int($max) + 1) . '/';
db_query("INSERT INTO {comments} (nid, pid, uid, subject, comment, format, hostname, timestamp, status, thread, name, mail, homepage) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d, '%s', '%s', '%s', '%s')", $ticket->nid, 0, $account->uid, $message['subject'], $message['body'], 1, ip_address(), time(), 0, $thread, $account->name, $account->mail, isset($account->homepage) ? $account->homepage : '');
$comment['cid'] = db_last_insert_id('comments', 'cid');
$comment['subject'] = truncate_utf8(trim($message['subject']), 64, TRUE, TRUE);
$comment['comment'] = $message['body'];
$comment['nid'] = $ticket->nid;
$comment['uid'] = $account->uid;
$comment['message_id'] = $message_id;
$comment['state'] = isset($message['state']) ? $message['state'] : $ticket->state;
$comment['priority'] = isset($message['priority']) ? $message['priority'] : $ticket->priority;
$comment['client'] = $ticket->client;
$comment['assigned'] = isset($message['assigned']) ? $message['assigned'] : $ticket->assigned;
$comment['notification'] = db_result(db_query('SELECT 1 FROM {support_assigned} WHERE nid = %d AND uid = %d', $ticket->nid, $account->uid));
$comment['support_email'] = TRUE;
$comment['files'] = _support_save_attachments($message['attachments'], $account, $manual);
if (isset($message['suppress'])) {
$comment['suppress'] = $message['suppress'];
}
foreach ($comment['files'] as $fid => $file) {
$comment['files'][$fid] = (array) $file;
}
if (isset($message['_support_extra_fields'])) {
foreach ($message['_support_extra_fields'] as $k => $v) {
$comment[$k] = $v;
}
}
comment_invoke_comment($comment, 'insert');
watchdog('content', 'Comment: added %subject.', array(
'%subject' => $comment['subject'],
), WATCHDOG_NOTICE, l(t('view'), 'node/' . $comment['nid'], array(
'fragment' => 'comment-' . $comment['cid'],
)));
_comment_update_node_statistics($comment['nid']);
cache_clear_all();
return TRUE;
}
else {
if (is_object($account)) {
$node = new stdClass();
$node->title = $message['subject'];
$node->body = $message['body'];
$node->type = 'support_ticket';
$node->log = t('Support ticket created from email.');
$node->comment = COMMENT_NODE_READ_WRITE;
$node->uid = $account->uid;
$node->message_id = $message_id;
$node->state = isset($message['state']) ? $message['state'] : _support_state_default();
$node->priority = isset($message['priority']) ? $message['priority'] : _support_priority_default();
$node->client = $client->clid;
$node->assigned = _support_autoassign($client->clid, $account->uid);
$node->notification = TRUE;
$node->support_email = TRUE;
$node->language = $account->language;
if (isset($message['attachments'])) {
$node->files = _support_save_attachments($message['attachments'], $account, $manual);
}
$node->created_by_email = TRUE;
if (isset($message['_support_extra_fields'])) {
foreach ($message['_support_extra_fields'] as $k => $v) {
$node->{$k} = $v;
}
}
node_save($node);
if ($manual) {
drupal_set_message(t('Created new ticket: !title.', array(
'!title' => l($node->title, 'node/' . $node->nid),
)));
}
watchdog('content', 'Node: created %title.', array(
'%title' => $node->title,
), WATCHDOG_NOTICE, l(t('view'), 'node/' . $node->nid));
}
}
}
function _support_save_attachments($attachments, $account, $manual = FALSE) {
$files = array();
if (count($attachments)) {
foreach ($attachments as $attachment) {
$attachment = (object) $attachment;
if (is_array($attachment->parameters)) {
foreach ($attachment->parameters as $parm) {
switch (strtoupper($parm->attribute)) {
case 'NAME':
case 'FILENAME':
$attachment->filename = mb_decode_mimeheader($parm->value);
break;
case 'NAME*1*':
case 'FILENAME*1*':
$attachment->filename = urldecode(mb_decode_mimeheader($parm->value));
break;
default:
$attachment->attributes[$parm->attribute] = mb_decode_mimeheader($parm->value);
}
}
}
if ($attachment->type != TYPETEXT && is_array($attachment->dparameters)) {
foreach ($attachment->dparameters as $parm) {
switch (strtoupper($parm->attribute)) {
case 'NAME':
case 'FILENAME':
$attachment->filename = mb_decode_mimeheader($parm->value);
break;
default:
$attachment->attributes[$parm->attribute] = mb_decode_mimeheader($parm->value);
}
}
}
if ($manual && !empty($attachment->filename)) {
drupal_set_message(t('Saved attachment: %filename', array(
'%filename' => $attachment->filename,
)));
}
if (!isset($attachment->filename) || empty($attachment->filename)) {
if ($attachment->subtype == 'HTML') {
$attachment->filename = 'noname.html';
}
else {
$attachment->filename = 'noname';
}
}
if (function_exists('transliteration_clean_filename')) {
$attachment->filename = transliteration_clean_filename($attachment->filename, language_default());
}
$attachment->filepath = file_save_data($attachment->attachment, file_directory_path() . '/' . utf8_encode($attachment->filename));
if ($attachment->filepath) {
watchdog('support', 'Saved %size byte %type attachment %file to %path.', array(
'%size' => number_format($attachment->bytes),
'%type' => $attachment->filemime,
'%file' => utf8_encode($attachment->filename),
'%path' => $attachment->filepath,
), WATCHDOG_INFO);
db_query("INSERT INTO {files} (uid, filename, filepath, filemime, filesize, status, timestamp) VALUES(%d, '%s', '%s', '%s', %d, %d, %d)", $account->uid, utf8_encode($attachment->filename), $attachment->filepath, $attachment->filemime, $attachment->bytes, 1, time());
$attachment->fid = db_last_insert_id('files', 'fid');
$attachment->new = $attachment->list = TRUE;
$attachment->weight = 0;
$attachment->description = $attachment->filename;
$files[$attachment->fid] = $attachment;
}
else {
watchdog('support', 'Failed to save attachment %file, file_save_data() returned error.', array(
'%file' => utf8_encode($attachment->filename),
));
}
}
}
return $files;
}
function _support_get_filemime(&$structure) {
static $primary_mime_type = array(
'TEXT',
'MULTIPART',
'MESSAGE',
'APPLICATION',
'AUDIO',
'IMAGE',
'VIDEO',
'OTHER',
);
$type_id = (int) $structure->type;
if (isset($primary_mime_type[$type_id]) && !empty($structure->subtype)) {
return $primary_mime_type[$type_id] . '/' . $structure->subtype;
}
return 'application/octet-stream';
}
function _support_get_attachments($stream, $message, $structure, $parts, $prefix = FALSE) {
$attachments = array();
for ($part = 2; $part <= $parts; $part++) {
if ($prefix == FALSE) {
$prefix = $part;
}
$attachment = imap_fetchbody($stream, $message, $prefix);
$details = imap_bodystruct($stream, $message, $prefix);
if (empty($details)) {
continue;
}
if ($details->type == TYPEMULTIPART) {
if ($prefix) {
$prefix = $prefix . '.';
}
$structure = imap_fetchstructure($stream, $message);
while (list($index, $substructure) = each($structure->parts)) {
$parts = count($substructure->parts);
$attachments += _support_get_attachments($stream, $message, $substructure, $parts, $prefix . ($index + 1));
}
if (!empty($structure)) {
foreach ($structure->parameters as $parameter) {
if (strtoupper($parameter->attribute) == 'CHARSET') {
$encoding = mb_decode_mimeheader($parameter->value);
break;
}
if ($data) {
return $data;
}
}
}
}
if ($details->encoding == ENCBASE64) {
$attachment = imap_base64($attachment);
}
else {
if ($details->encoding == ENCQUOTEDPRINTABLE) {
$attachment = quoted_printable_decode($attachment);
}
else {
if ($details->type == TYPETEXT) {
$attachment = imap_utf8($attachment);
}
}
}
$details->filemime = _support_get_filemime($details);
if (!empty($attachment)) {
$details->attachment = $attachment;
$attachments[] = $details;
}
if (!empty($prefix)) {
$pieces = explode('.', $prefix);
$piece = count($pieces) - 1;
$pieces[$piece]++;
$prefix = implode('.', $pieces);
}
}
return $attachments;
}
function _support_get_message_body_part($stream, $message, $mime_type, $structure = FALSE, $part = FALSE) {
if (!$structure) {
$structure = imap_fetchstructure($stream, $message);
}
if (!empty($structure)) {
foreach ($structure->parameters as $parameter) {
if (strtoupper($parameter->attribute) == 'CHARSET') {
$encoding = mb_decode_mimeheader($parameter->value);
break;
}
}
if ($structure->type == TYPEMULTIPART) {
$prefix = '';
while (list($index, $sub_structure) = each($structure->parts)) {
if ($part) {
$prefix = $part . '.';
}
$mime_type = _support_get_filemime($sub_structure);
$data[] = _support_get_message_body_part($stream, $message, $mime_type, $sub_structure, $prefix . ($index + 1));
}
if (!empty($data)) {
return array_shift($data);
}
if (!empty($data)) {
return $data;
}
}
else {
if ($mime_type == _support_get_filemime($structure)) {
if (!$part) {
$part = 1;
}
$body = imap_fetchbody($stream, $message, $part);
switch ($structure->encoding) {
case ENCBASE64:
return drupal_convert_to_utf8(imap_base64($body), $encoding);
break;
case ENCQUOTEDPRINTABLE:
return drupal_convert_to_utf8(quoted_printable_decode($body), $encoding);
break;
default:
return drupal_convert_to_utf8($body, $encoding);
break;
}
}
}
}
}
function support_subscribe_user($nid, $uid, $subscribe = 1) {
$clid = db_result(db_query('SELECT client FROM {support_ticket} WHERE nid = %d', $nid));
$client = support_client_load($clid);
$account = user_load(array(
'uid' => $uid,
));
if (support_access_clients($client, $account)) {
if ($subscribe) {
@db_query('INSERT INTO {support_assigned} (nid, uid) VALUES(%d, %d)', $nid, $uid);
}
else {
db_query('DELETE FROM {support_assigned} WHERE nid = %d AND uid = %d', $nid, $uid);
}
}
else {
db_query('DELETE FROM {support_assigned} WHERE nid = %d AND uid = %d', $nid, $uid);
}
}
function _support_autosubscribe($nid, $client, $save = TRUE) {
$accounts = array();
$autosubscribe = db_result(db_query('SELECT autosubscribe FROM {support_client} WHERE clid = %d', $client));
$autosubscribe = explode(',', $autosubscribe);
foreach ($autosubscribe as $name) {
$account = user_load(array(
'name' => trim($name),
));
if (is_object($account) && $account->uid) {
$accounts[$account->uid] = $account->uid;
if ($save) {
support_subscribe_user($nid, $account->uid);
}
}
}
return $accounts;
}
function support_notification($comment = array(), $nid, $op = 'ticket_comment_new', $suppress = FALSE) {
if (variable_get('support_notifications', TRUE)) {
$result = db_query('SELECT uid FROM {support_assigned} WHERE nid = %d', $nid);
while ($account = db_fetch_object($result)) {
$account = user_load(array(
'uid' => $account->uid,
));
if ($account->status && $account->mail && (!$suppress || user_access('administer support', $account))) {
_support_mail_notify($op, $account, $comment, $nid, $suppress);
if (variable_get('support_admin_notify', FALSE)) {
if (variable_get('support_admin_notify', FALSE) == 1 && user_access('administer support') || variable_get('support_admin_notify', FALSE) == 2) {
drupal_set_message(t('Sent notification to %email.', array(
'%email' => $account->mail,
)));
}
}
}
else {
if (!$account->mail) {
watchdog('support', 'User !name (!uid) has no email address.', array(
'!name' => $account->name,
'!uid' => $account->uid,
), WATCHDOG_NOTICE);
}
}
}
}
}
function _support_mail_deny($to) {
$language = language_default();
$key = 'ticket_deny';
drupal_mail('support', $key, $to, $language, NULL);
}
function _support_mail_notify($op, $account, $comment = array(), $nid = NULL, $suppress = FALSE, $language = NULL) {
$notify = variable_get('support_mail_' . $op . '_notify', TRUE);
if ($notify) {
$node = node_load($nid);
$params['account'] = $account;
$params['nid'] = $nid;
if (isset($comment['cid'])) {
$params['cid'] = $comment['cid'];
$params['comment'] = $comment;
}
else {
$params['cid'] = 0;
}
$params['suppress'] = $suppress;
$language = $language ? $language : user_preferred_language($account);
$params['integrate_email'] = db_result(db_query('SELECT integrate_email FROM {support_client} WHERE clid = %d', $node->client));
if ($params['integrate_email'] == TRUE) {
$mailfrom = db_result(db_query('SELECT mailfrom FROM {support_client} WHERE clid = %d', $node->client));
}
else {
$mailfrom = variable_get('support_global_mailfrom', '');
}
if (function_exists('mimemail')) {
$params['message_html_filter'] = variable_get('mimemail_format', FILTER_FORMAT_DEFAULT);
$message['params'] = $params;
support_mail($op, $message, $params, TRUE);
$message['body'] = check_markup($message['body'], $params['message_html_filter'], FALSE);
$mail = mimemail($mailfrom, $account->mail, $message['subject'], $message['body'], FALSE, $message['headers']);
}
else {
$mail = drupal_mail('support', $op, $account->mail, $language, $params, $mailfrom);
}
}
return empty($mail) ? NULL : $mail['result'];
}
function _support_comment_update_node($nid) {
$cid = db_result(db_query('SELECT MAX(cid) FROM {comments} WHERE nid = %d', $nid));
if ($cid) {
$comment = db_fetch_object(db_query('SELECT state, priority, client, assigned FROM {support_ticket_comment} WHERE cid = %d', $cid));
db_query('UPDATE {support_ticket} SET state = %d, priority = %d, client = %d, assigned = %d WHERE nid = %d', $comment->state, $comment->priority, $comment->client, $comment->assigned, $nid);
}
}
function support_form_alter(&$form, $form_state, $form_id) {
if ($form_id == 'comment_form') {
if (is_array($form) && isset($form['nid']) && is_array($form['nid'])) {
$node = node_load($form['nid']['#value']);
}
if (isset($node) && is_object($node) && isset($node->type) && $node->type == 'support_ticket') {
$reference = array();
$form = array_merge(support_status_form($form_state, $form, ''), $form);
$form = array_merge($form, support_subscribe_form($reference, $form, ''));
$form['comment_filter']['comment']['#title'] = t('Update');
unset($form['_author']);
}
}
else {
if ($form_id == 'search_form' && variable_get('support_remove_tickets', TRUE)) {
unset($form['advanced']['type']['#options']['support_ticket']);
}
else {
if ($form_id == 'search_theme_form' && variable_get('support_override_theme', FALSE)) {
$form['#submit'] = array(
'support_search_form_submit',
);
}
else {
if ($form_id == 'search_block_form' && variable_get('support_override_block', FALSE)) {
$form['#submit'] = array(
'support_search_form_submit',
);
}
}
}
}
if ($form_id == 'search_form' && $form['module']['#value'] == 'support' && user_access('use advanced search')) {
$form['advanced'] = array(
'#type' => 'fieldset',
'#title' => t('Advanced search'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#attributes' => array(
'class' => 'search-advanced',
),
);
$form['advanced']['keywords'] = array(
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
);
$form['advanced']['keywords']['or'] = array(
'#type' => 'textfield',
'#title' => t('Containing any of the words'),
'#size' => 30,
'#maxlength' => 255,
);
$form['advanced']['keywords']['phrase'] = array(
'#type' => 'textfield',
'#title' => t('Containing the phrase'),
'#size' => 30,
'#maxlength' => 255,
);
$form['advanced']['keywords']['negative'] = array(
'#type' => 'textfield',
'#title' => t('Containing none of the words'),
'#size' => 30,
'#maxlength' => 255,
);
$form['advanced']['submit'] = array(
'#type' => 'submit',
'#value' => t('Advanced search'),
'#prefix' => '<div class="action">',
'#suffix' => '</div>',
);
$clients = _support_available_clients();
if (sizeof($clients) > 1) {
$form['advanced']['client'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#title' => t('Search specific client(s)'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $clients,
);
}
$states = _support_states();
if (sizeof($states) > 1) {
$form['advanced']['state'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#title' => t('Search specific state(s)'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $states,
);
}
$priorities = _support_priorities();
if (sizeof($priorities) > 1) {
$form['advanced']['priority'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#title' => t('Search specific priorities'),
'#prefix' => '<div class="criterion">',
'#suffix' => '</div>',
'#options' => $priorities,
);
}
$form['#validate'][] = 'support_search_validate';
}
}
function support_search_validate($form, &$form_state) {
$keys = $form_state['values']['processed_keys'];
if (isset($form_state['values']['client']) && is_array($form_state['values']['client'])) {
if (count($form_state['values']['client'])) {
$keys = search_query_insert($keys, 'client', implode(',', array_keys($form_state['values']['client'])));
}
}
if (isset($form_state['values']['state']) && is_array($form_state['values']['state'])) {
if (count($form_state['values']['state'])) {
$keys = search_query_insert($keys, 'state', implode(',', array_keys($form_state['values']['state'])));
}
}
if (isset($form_state['values']['priority']) && is_array($form_state['values']['priority'])) {
if (count($form_state['values']['priority'])) {
$keys = search_query_insert($keys, 'priority', implode(',', array_keys($form_state['values']['priority'])));
}
}
if ($form_state['values']['negative'] != '') {
if (preg_match_all('/ ("[^"]+"|[^" ]+)/i', ' ' . $form_state['values']['negative'], $matches)) {
$keys .= ' -' . implode(' -', $matches[1]);
}
}
if ($form_state['values']['phrase'] != '') {
$keys .= ' "' . str_replace('"', ' ', $form_state['values']['phrase']) . '"';
}
if (!empty($keys)) {
form_set_value($form['basic']['inline']['processed_keys'], trim($keys), $form_state);
}
}
function support_search_form_submit($form, &$form_state) {
$form_id = $form['form_id']['#value'];
$form_state['redirect'] = 'search/support/' . trim($form_state['values'][$form_id]);
}
function support_db_rewrite_sql($query, $primary_table, $primary_field, $args) {
global $user;
if (variable_get('support_remove_tickets', TRUE) && $query == '' && $primary_table == 'n' && ($primary_field = 'nid' && empty($args))) {
return array(
'where' => " n.type != 'support_ticket'",
);
}
if ($primary_table == 'n' and $primary_field == 'nid' && !strpos($query, '{support_ticket}')) {
$clients = support_search_available_clients();
if (!empty($clients)) {
if (user_access('view other users tickets') || user_access('administer support') || user_access('edit any ticket') || user_access('delete any ticket')) {
return array(
'join' => ' LEFT JOIN {support_ticket} st ON n.nid = st.nid',
'where' => ' (st.client IN (' . implode(',', $clients) . ') OR st.client IS NULL)',
);
}
else {
return array(
'join' => ' LEFT JOIN {support_ticket} st ON n.nid = st.nid',
'where' => ' ((st.client IN (' . implode(',', $clients) . ') AND n.uid = ' . $user->uid . ') OR st.client IS NULL)',
);
}
}
else {
return array(
'where' => " n.type != 'support_ticket'",
);
}
}
else {
if ($primary_table == 'nc' and $primary_field == 'nid' && !strpos($query, '{support_ticket_comment}')) {
$clients = support_search_available_clients();
if (!empty($clients)) {
if (user_access('view other users tickets') || user_access('administer support') || user_access('edit any ticket') || user_access('delete any ticket')) {
return array(
'join' => ' LEFT JOIN {support_ticket} st ON nc.nid = st.nid',
'where' => ' (st.client IN (' . implode(',', $clients) . ') OR st.client IS NULL)',
);
}
else {
return array(
'join' => ' LEFT JOIN {node} n ON nc.nid = n.nid LEFT JOIN {support_ticket} st ON nc.nid = st.nid',
'where' => ' (st.client IN (' . implode(',', $clients) . ') AND (n.uid = ' . $user->uid . ' OR st.assigned = ' . $user->uid . ")) OR n.type != 'support_ticket'",
);
}
}
else {
return array(
'join' => ' LEFT JOIN {node} n ON nc.nid = n.nid',
'where' => " n.type != 'support_ticket'",
);
}
}
else {
if ($primary_table == 'n' && $primary_field == 'nid' && strpos($query, 'support_ticket_timer') && strpos($query, 't.client IN')) {
$tid = isset($_GET['tid']) ? $_GET['tid'] : '';
if ($tid) {
$alter = array(
'join' => ' LEFT JOIN {term_node} tn ON n.nid = tn.nid',
);
if ($tid == 'null') {
$alter['where'] = "ISNULL(tn.tid)";
}
else {
if ($tid && $tid == preg_replace('/[^0-9,]/', '', $tid)) {
$alter['where'] = "tn.tid IN({$tid})";
}
}
return $alter;
}
}
else {
if ($primary_table == 'c' && $primary_field == 'cid' && strpos($query, 'support_ticket_comment_timer') && strpos($query, 't.client IN')) {
$tid = isset($_GET['tid']) ? $_GET['tid'] : '';
if ($tid) {
$alter = array(
'join' => ' LEFT JOIN {term_node} tn ON c.nid = tn.nid',
);
if ($tid == 'null') {
$alter['where'] = "ISNULL(tn.tid)";
}
else {
if ($tid && $tid == preg_replace('/[^0-9,]/', '', $tid)) {
$alter['where'] = "tn.tid IN({$tid})";
}
}
return $alter;
}
}
}
}
}
}
function support_search_available_clients() {
static $clids = NULL;
if (!is_array($clids)) {
$clids = array();
$clients = _support_available_clients();
foreach ($clients as $clid => $client) {
$clids[] = $clid;
}
}
return $clids;
}
function support_search($op = 'search', $keys = NULL, $skip_access_check = FALSE) {
global $user;
switch ($op) {
case 'name':
if ($skip_access_check || support_access_clients()) {
return t('Tickets');
}
break;
case 'search':
$join = 'INNER JOIN {node} n ON n.nid = i.sid';
$conditions = "n.status = 1 AND n.type = 'support_ticket'";
$arguments = array();
if ($client = search_query_extract($keys, 'client')) {
$clients = array();
foreach (explode(',', $client) as $c) {
$clients[] = "jt.client = %d";
$arguments[] = $c;
}
$conditions .= ' AND (' . implode(' OR ', $clients) . ')';
$keys = search_query_insert($keys, 'client');
}
if ($state = search_query_extract($keys, 'state')) {
$states = array();
foreach (explode(',', $state) as $s) {
$states[] = "jt.state = %d";
$arguments[] = $s;
}
$conditions .= ' AND (' . implode(' OR ', $states) . ')';
$keys = search_query_insert($keys, 'state');
}
if ($priority = search_query_extract($keys, 'priority')) {
$priorities = array();
foreach (explode(',', $priority) as $p) {
$priorities[] = "jt.priority = %d";
$arguments[] = $p;
}
$conditions .= ' AND (' . implode(' OR ', $priorities) . ')';
$keys = search_query_insert($keys, 'priority');
}
$keys = search_query_insert($keys, 'type');
$clients = support_search_available_clients();
if (!empty($clients)) {
$join .= " LEFT JOIN {support_ticket} jt ON n.nid = jt.nid";
$conditions .= ' AND jt.client IN (' . implode(',', support_search_available_clients()) . ')';
}
else {
$conditions .= " AND n.type != 'support_ticket'";
}
if (!user_access('view other users tickets') && !user_access('administer support') && !user_access('edit any ticket') && !user_access('delete any ticket')) {
$conditions .= " AND n.uid = {$user->uid}";
}
$ranking = array();
$arguments2 = array();
$join2 = '';
$stats_join = FALSE;
$total = 0;
if ($weight = (int) variable_get('node_rank_relevance', 5)) {
$ranking[] = '%d * i.relevance';
$arguments2[] = $weight;
$total += $weight;
}
if ($weight = (int) variable_get('node_rank_recent', 5)) {
$ranking[] = '%d * POW(2, (GREATEST(MAX(n.created), MAX(n.changed), MAX(c.last_comment_timestamp)) - %d) * 6.43e-8)';
$arguments2[] = $weight;
$arguments2[] = (int) variable_get('node_cron_last', 0);
$join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
$stats_join = TRUE;
$total += $weight;
}
if (module_exists('comment') && ($weight = (int) variable_get('node_rank_comments', 5))) {
$scale = variable_get('node_cron_comments_scale', 0.0);
$ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(c.comment_count) * %f))';
$arguments2[] = $weight;
$arguments2[] = $scale;
if (!$stats_join) {
$join2 .= ' LEFT JOIN {node_comment_statistics} c ON c.nid = i.sid';
}
$total += $weight;
}
if (module_exists('statistics') && variable_get('statistics_count_content_views', 0) && ($weight = (int) variable_get('node_rank_views', 5))) {
$scale = variable_get('node_cron_views_scale', 0.0);
$ranking[] = '%d * (2.0 - 2.0 / (1.0 + MAX(nc.totalcount) * %f))';
$arguments2[] = $weight;
$arguments2[] = $scale;
$join2 .= ' LEFT JOIN {node_counter} nc ON nc.nid = i.sid';
$total += $weight;
}
if ($total == 0) {
$select2 = 'i.relevance AS score';
$total = 1;
}
else {
$select2 = implode(' + ', $ranking) . ' AS score';
}
$find = do_search($keys, 'node', $join, $conditions, $arguments, $select2, $join2, $arguments2);
$results = array();
foreach ($find as $item) {
$node = node_load($item->sid);
$node->build_mode = NODE_BUILD_SEARCH_RESULT;
$node = node_build_content($node, FALSE, FALSE);
$node->body = drupal_render($node->content);
$node->body .= module_invoke('comment', 'nodeapi', $node, 'update index');
$node->body .= module_invoke('taxonomy', 'nodeapi', $node, 'update index');
$extra = node_invoke_nodeapi($node, 'search result');
if (!is_array($extra)) {
$extra = array();
}
if (sizeof($clients) > 1) {
$title = check_plain(_support_client($node->client)) . ': ' . $node->title;
}
else {
$title = $node->title;
}
foreach ($extra as $key => $value) {
$trans = array(
' comments' => ' follow ups',
);
$extra[$key] = strtr($value, $trans);
}
$extra[] = check_plain(_support_state($node->state));
$extra[] = check_plain(_support_priorities($node->priority));
$clients = support_search_available_clients();
$results[] = array(
'link' => url('node/' . $item->sid, array(
'absolute' => TRUE,
)),
'type' => check_plain(node_get_types('name', $node)),
'title' => $title,
'user' => theme('username', $node),
'date' => $node->changed,
'node' => $node,
'extra' => $extra,
'score' => $item->score / $total,
'snippet' => search_excerpt($keys, $node->body),
);
}
return $results;
}
}
function support_status_form(&$form_state, $edit, $title) {
global $user;
$cid = 0;
if (is_array($edit)) {
if (is_array($edit['nid'])) {
$node = node_load($edit['nid']['#value']);
$cid = $edit['cid']['#value'];
}
else {
$node = node_load($edit['nid']);
}
}
else {
$node = $edit;
}
$autoassign = _support_autoassign(_support_current_client(), $user->uid);
if ($autoassign && !isset($node->assigned) && (!isset($node->nid) || !$node->nid)) {
$node->assigned = $autoassign;
}
if ($cid) {
$comment = db_fetch_object(db_query('SELECT state, priority FROM {support_ticket_comment} WHERE cid = %d', $cid));
if ($comment->state && $comment->priority) {
$node->state = $comment->state;
$node->priority = $comment->priority;
}
}
if (user_access('can select state') || user_access('can select priority') || user_access('can select client') || user_access('can assign tickets to self') || user_access('can assign tickets to any user') || user_access('administer support') || user_access('can administer state')) {
$form['support'] = array(
'#type' => 'fieldset',
'#prefix' => '<div class="container-inline">',
'#suffix' => '</div>',
'#title' => t('Ticket properties'),
);
}
$default = isset($node->state) ? $node->state : _support_state_default();
if (!user_access('can select state') && !user_access('administer support') && !user_access('can administer state')) {
$form['support']['state'] = array(
'#type' => 'hidden',
'#value' => $default,
);
}
else {
if (isset($node->nid) && $node->nid && isset($node->state)) {
$state = $node->state;
}
else {
$state = 0;
}
$form['support']['state'] = array(
'#type' => 'select',
'#title' => t('State'),
'#options' => _support_states(FALSE, $state),
'#default_value' => $default,
);
}
if (!user_access('can select priority') && !user_access('administer support')) {
$form['support']['priority'] = array(
'#type' => 'hidden',
'#value' => $node->priority ? $node->priority : _support_priority_default(),
);
}
else {
$form['support']['priority'] = array(
'#type' => 'select',
'#prefix' => ' ',
'#title' => t('Priority'),
'#options' => _support_priorities(),
'#default_value' => isset($node->priority) ? $node->priority : _support_priority_default(),
);
}
$clients = _support_available_clients();
if (!isset($node->client) || empty($node->client)) {
if (sizeof($clients) == 1) {
$node->client = key($clients);
}
else {
if (is_numeric($_SESSION['support_client'])) {
$node->client = $_SESSION['support_client'];
}
else {
if (!user_access('can select client')) {
$node->client = key($clients);
}
}
}
}
$available = count($clients);
if (!$available) {
drupal_set_message(t('A site administrator must !create a client before you can create support tickets.', array(
'!create' => l(t('create and enable'), 'admin/support/clients/add'),
)), 'error');
}
$clients = array(
'- select client -',
) + $clients;
if ($available == 1 || !user_access('can select client') && !user_access('administer support')) {
$form['support']['client'] = array(
'#type' => 'hidden',
'#value' => is_numeric($node->client) ? $node->client : 0,
);
}
else {
$form['support']['client'] = array(
'#type' => 'select',
'#required' => TRUE,
'#prefix' => ' ',
'#title' => t('Client'),
'#options' => $clients,
'#default_value' => is_numeric($node->client) ? $node->client : 0,
);
}
if (!user_access('can assign tickets to self') && !user_access('can assign tickets to any user') && !user_access('administer support')) {
$form['support']['assigned'] = array(
'#type' => 'hidden',
'#value' => $node->assigned ? $node->assigned : 0,
);
}
else {
$options = _support_assigned(isset($node->assigned) ? $node->assigned : 0, $node, variable_get('support_autocomplete_limit', 15));
if ($options === FALSE) {
if (isset($node->assigned)) {
if (is_numeric($node->assigned)) {
$account = user_load(array(
'uid' => $node->assigned,
));
$assigned = $account->name;
}
else {
$assigned = $node->assigned;
}
}
else {
$assigned = '';
}
$form['support']['assigned'] = array(
'#type' => 'textfield',
'#prefix' => ' ',
'#title' => t('Assigned'),
'#autocomplete_path' => 'support/autocomplete/assigned/' . $node->client,
'#default_value' => $assigned,
'#size' => '15',
);
}
else {
$form['support']['assigned'] = array(
'#type' => 'select',
'#prefix' => ' ',
'#title' => t('Assigned'),
'#options' => $options,
'#default_value' => isset($node->assigned) ? $node->assigned : 0,
);
}
}
return $form;
}
function _support_assigned($assigned, $node, $limit = 9999) {
global $user;
static $available = array();
$counter = 0;
if (!$limit) {
return FALSE;
}
if (!isset($node->nid)) {
$node->nid = 0;
}
if (!isset($available["{$assigned}-{$node->nid}"])) {
if ($assigned && $assigned != $user->uid) {
$account = user_load($assigned);
$available["{$assigned}-{$node->nid}"][$account->uid] = $account->name;
$counter++;
}
$available["{$assigned}-{$node->nid}"][$user->uid] = $user->name;
$counter++;
if (is_numeric($node->client) && (user_access('administer support') || user_access('can assign tickets to any user'))) {
$roles = array();
$client = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $node->client));
$result = db_query("SELECT rid FROM {permission} WHERE perm LIKE '%%%s%%' OR perm LIKE '%%%s%%'", "access {$client} tickets", 'administer support');
while ($role = db_fetch_object($result)) {
$roles[$role->rid] = $role->rid;
}
$accounts = array();
$all = FALSE;
foreach ($roles as $rid) {
if ($rid == DRUPAL_AUTHENTICATED_RID) {
$all = TRUE;
$result = db_query_range('SELECT uid FROM {users} WHERE status = 1', 0, $limit);
}
else {
$result = db_query_range('SELECT r.uid FROM {users_roles} r LEFT JOIN {users} u ON r.uid = u.uid WHERE r.rid = %d AND u.status = 1', $rid, 0, $limit);
}
while ($account = db_fetch_object($result)) {
$accounts[$account->uid] = $account->uid;
$counter++;
if (!$limit || $counter > $limit) {
return FALSE;
}
}
if ($all) {
break;
}
}
foreach ($accounts as $uid) {
$account = user_load(array(
'uid' => $uid,
));
$available["{$assigned}-{$node->nid}"][$account->uid] = $account->name;
}
if ($user->uid != 1 && $assigned != 1 && variable_get('support_filter_uid1', FALSE)) {
unset($available["{$assigned}-{$node->nid}"][1]);
}
}
asort($available["{$assigned}-{$node->nid}"]);
if (!$assigned || $assigned == $user->uid || user_access('can assign tickets to any user') || user_access('administer support')) {
$available["{$assigned}-{$node->nid}"] = array(
0 => ' - ' . t('not assigned') . ' -',
) + $available["{$assigned}-{$node->nid}"];
}
}
return $available["{$assigned}-{$node->nid}"];
}
function support_subscribe_form(&$form_state, $edit, $title) {
global $user;
$form = array();
if (is_array($edit)) {
$node = node_load($edit['nid']['#value']);
}
else {
$node = $edit;
}
if (variable_get('support_notifications', TRUE)) {
$form['subscribe'] = array(
'#type' => 'fieldset',
'#title' => t('Notifications'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
if (variable_get('support_autosubscribe_creator', FALSE)) {
$notification = TRUE;
}
else {
if (is_array($edit) && isset($edit['nid']) && $edit['nid']) {
$notification = db_result(db_query('SELECT 1 FROM {support_assigned} WHERE nid = %d AND uid = %d', $edit['nid']['#value'], $user->uid));
}
else {
if (is_object($edit) && isset($edit->notification)) {
$notification = $edit->notification;
}
else {
$notification = TRUE;
}
}
}
$form['subscribe']['notification'] = array(
'#type' => 'checkbox',
'#title' => t('Subscribe'),
'#description' => t('Receive email notifications when this ticket is updated.'),
'#default_value' => isset($notification) ? $notification : TRUE,
'#disabled' => variable_get('support_autosubscribe_creator', FALSE) || variable_get('support_autosubscribe_assigned', FALSE) && isset($node->assigned) && $node->assigned == $user->uid,
);
if (user_access('can suppress notification')) {
$form['subscribe']['suppress'] = array(
'#type' => 'checkbox',
'#title' => t('Suppress notification'),
'#description' => t('By checking this box you will prevent notification emails from being sent for this ticket update. It is recommended that you check this box if you are adding sensitive information such as passwords which should not be mailed out in plain text.%admin', array(
'%admin' => user_access('administer support') ? t(' Users with "administer support" permission will still receive email notifications telling them the ticket was updated but with the body text suppressed; no notifications will be sent to users without "administer support" permissions.') : '',
)),
'#default_value' => isset($edit->suppress) ? $edit->suppress : 0,
);
}
if (isset($edit) && (user_access('administer support') || user_access('can subscribe other users to notifications'))) {
$form['subscribe']['subscribed'] = array(
'#type' => 'fieldset',
'#title' => t('Subscribed'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
);
$available = _support_assigned(0, $node, variable_get('support_autocomplete_limit', 15));
if ($available === FALSE) {
$account = user_load(array(
'uid' => $node->assigned,
));
$accounts = array();
if (isset($node->nid)) {
$result = db_query('SELECT uid FROM {support_assigned} WHERE nid = %d', $node->nid);
while ($a = db_fetch_object($result)) {
$account = user_load(array(
'uid' => $a->uid,
));
$accounts[] = $account->name;
}
}
if (!empty($accounts)) {
$default = implode(', ', $accounts);
}
else {
$default = '';
}
$form['subscribe']['subscribed']['subscribed-users'] = array(
'#type' => 'textfield',
'#autocomplete_path' => 'support/autocomplete/autosubscribe/' . $node->client,
'#default_value' => $default,
'#description' => t('Enter a comma separated list of users that should receive notifications when this ticket is updated.'),
);
}
else {
$notifications = array();
foreach ($available as $uid => $name) {
if (!$uid) {
continue;
}
if (isset($node->nid) && $node->nid) {
$enabled = db_result(db_query('SELECT 1 FROM {support_assigned} WHERE nid = %d AND uid = %d', $node->nid, $uid));
if (!isset($enabled)) {
$enabled = _support_enabled($node->client, $uid);
}
}
else {
if ($uid == $user->uid) {
$enabled = TRUE;
}
else {
$autoassign = _support_autoassign($node->client, $node->uid);
if ($autoassign && $autoassign == $uid) {
$enabled = TRUE;
}
else {
$enabled = _support_enabled($node->client, $uid);
}
}
}
if (variable_get('support_autosubscribe_force', FALSE)) {
$autosubscribed = _support_autosubscribe($node->nid, $node->client, FALSE);
}
else {
$autosubscribed = array();
}
if (variable_get('support_autosubscribe_assigned', FALSE) && isset($node->assigned) && $node->assigned == $uid) {
$enabled = TRUE;
$disabled = TRUE;
}
else {
$disabled = FALSE;
}
$notifications[] = $uid;
$form['subscribe']['subscribed']["notify-{$uid}"] = array(
'#type' => 'checkbox',
'#title' => check_plain($name),
'#default_value' => $enabled,
'#disabled' => ($uid == $user->uid || isset($autosubscribed[$uid]) || $disabled) && $enabled ? TRUE : FALSE,
);
}
$form['subscribe']['subscribed']['notifications'] = array(
'#type' => 'hidden',
'#value' => implode(',', $notifications),
);
}
}
}
return $form;
}
function _support_clients_load($path = FALSE) {
$result = db_query('SELECT clid, path, name FROM {support_client} WHERE status = 1 ORDER BY name');
while ($client = db_fetch_object($result)) {
if ($path) {
$clients[$client->clid] = check_plain($client->path);
}
else {
$clients[$client->clid] = check_plain($client->name);
}
}
drupal_alter('support_clients_load', $clients);
return $clients;
}
function support_page_user_access($account) {
return $account->uid && user_access('access content') && (user_access('create tickets', $account) || _support_ticket_exists($account));
}
function _support_states($all = TRUE, $sid = NULL, $account = NULL) {
static $states = array();
$admin = user_access('can administer state', $account);
if (!isset($states["{$admin}-{$all}-{$sid}"])) {
if ($admin || $all) {
$result = db_query("SELECT sid, state FROM {support_states} ORDER BY weight");
}
else {
if (!$all && !$sid) {
$result = db_query("SELECT sid, state FROM {support_states} WHERE phase1 = 1 ORDER BY weight");
}
else {
if (!$all) {
$result = db_query("SELECT sid, state FROM {support_states} WHERE phase2 = 1 ORDER BY weight");
}
}
}
while ($state = db_fetch_object($result)) {
$states["{$admin}-{$all}-{$sid}"][$state->sid] = $state->state;
}
if ($sid && !in_array($sid, $states["{$admin}-{$all}-{$sid}"])) {
$states["{$admin}-{$all}-{$sid}"][$sid] = db_result(db_query("SELECT state FROM {support_states} WHERE sid = %d", $sid));
}
}
return $states["{$admin}-{$all}-{$sid}"];
}
function _support_state_default() {
static $default = NULL;
if (!$default) {
$default = db_result(db_query_range('SELECT sid FROM {support_states} WHERE isdefault = 1 ORDER BY weight ASC', 0, 1));
}
return $default;
}
function _support_state_secondary() {
static $secondary = NULL;
if (!$secondary) {
$secondary = db_result(db_query_range('SELECT sid FROM {support_states} WHERE phase2 = 1 ORDER BY weight ASC', 0, 1));
}
return $secondary;
}
function _support_priorities($pid = NULL) {
static $priorities = array();
if (empty($priorities)) {
$result = db_query('SELECT pid, priority FROM {support_priority} ORDER BY weight');
while ($priority = db_fetch_object($result)) {
$priorities[$priority->pid] = $priority->priority;
}
}
if ($pid && isset($priorities[$pid])) {
return $priorities[$pid];
}
if ($pid === 0) {
return '';
}
else {
return $priorities;
}
}
function _support_priority_default() {
static $default = NULL;
if (!$default) {
$default = db_result(db_query_range('SELECT pid FROM {support_priority} WHERE isdefault = 1', 0, 1));
}
return $default;
}
function _support_ticket_exists($account) {
return (bool) db_result(db_query_range(db_rewrite_sql("SELECT 1 FROM {node} n WHERE n.type = 'support_ticket' AND n.uid = %d AND n.status = 1"), $account->uid, 0, 1));
}
function _support_state($state) {
static $state_name = array();
if (!isset($state_name[$state])) {
$state_name[$state] = db_result(db_query('SELECT state FROM {support_states} WHERE sid = %d', $state));
}
return $state_name[$state];
}
function _support_available_clients($account = NULL) {
global $user;
static $valid = array();
if (is_null($account) || !isset($account->uid)) {
$account = $user;
}
if (!isset($valid[$account->uid])) {
$clients = _support_clients_load();
if (is_array($clients) && !empty($clients)) {
foreach ($clients as $clid => $name) {
if (user_access('administer support', $account) || user_access("access {$name} tickets", $account)) {
$valid[$account->uid][$clid] = $name;
}
}
}
else {
watchdog('support', t('There are no support clients configured/enabled.'), NULL, WATCHDOG_WARNING, l(t('add client'), 'admin/support/clients/add'));
}
}
return isset($valid[$account->uid]) ? $valid[$account->uid] : array();
}
function _support_get_state($state) {
if ($state == 'all') {
return 0;
}
else {
if ($state == 'all open') {
return -1;
}
else {
if ($state == 'my open') {
return -2;
}
else {
if ($state == SUPPORT_STATE_CLOSED) {
$result = db_query("SELECT sid FROM {support_states} WHERE isclosed = 1");
$states = array();
while ($state = db_fetch_object($result)) {
$states[$state->sid] = $state->sid;
}
return $states;
}
}
}
}
$sid = db_result(db_query("SELECT sid FROM {support_states} WHERE state = '%s'", $state));
if (!$sid) {
$sid = _support_state_default();
}
return $sid;
}
function _support_truncate($text, $maxlen = 64) {
return truncate_utf8($text, $maxlen - 1, TRUE, TRUE);
}
function support_filter_form($client, $filters, $state) {
unset($filters['join']);
unset($filters['where']);
unset($filters['or']);
$form = array();
$form['filter'] = array(
'#type' => 'fieldset',
'#title' => t('Filter by'),
'#collapsible' => TRUE,
'#collapsed' => empty($filters),
);
$options = _support_client_terms($client, $state);
if (count($options)) {
$form['filter']['tags'] = array(
'#type' => 'fieldset',
'#title' => t('Tags'),
'#collapsible' => TRUE,
'#collapsed' => empty($filters['tid']),
);
$form['filter']['tags']['tid'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#options' => $options,
'#size' => count($options) > 10 ? 10 : 5,
'#default_value' => isset($filters['tid']) ? $filters['tid'] : 0,
);
}
if ($state != -2) {
$options = array(
'-1' => '- not assigned -',
);
if ($users = _support_client_users($client)) {
$options += $users;
}
unset($options[0]);
if (count($options)) {
$form['filter']['assigned'] = array(
'#type' => 'fieldset',
'#title' => t('Assigned'),
'#collapsible' => TRUE,
'#collapsed' => empty($filters['uid']),
);
$form['filter']['assigned']['uid'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#options' => $options,
'#default_value' => isset($filters['uid']) ? $filters['uid'] : 0,
);
}
}
if ($state < 1) {
$form['filter']['state'] = array(
'#type' => 'fieldset',
'#title' => t('State'),
'#collapsible' => TRUE,
'#collapsed' => empty($filters['sid']),
);
$options = _support_states();
$form['filter']['state']['sid'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#options' => $options,
'#default_value' => isset($filters['sid']) ? $filters['sid'] : 0,
);
}
$form['filter']['priority'] = array(
'#type' => 'fieldset',
'#title' => t('Priority'),
'#collapsible' => TRUE,
'#collapsed' => empty($filters['pid']),
);
$options = _support_priorities();
$form['filter']['priority']['pid'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#options' => $options,
'#default_value' => isset($filters['pid']) ? $filters['pid'] : 0,
);
if (count($client) > 1) {
$form['filter']['client'] = array(
'#type' => 'fieldset',
'#title' => t('Client'),
'#collapsible' => TRUE,
'#collapsed' => empty($filters['clid']),
);
$options = _support_access_tickets(FALSE);
$form['filter']['client']['clid'] = array(
'#type' => 'select',
'#multiple' => TRUE,
'#options' => $options,
'#default_value' => isset($filters['clid']) ? $filters['clid'] : 0,
);
}
$form['filter']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update'),
'#validate' => array(
'support_filter_form_validate',
),
'#submit' => array(
'support_filter_form_submit',
),
);
$form['filter']['markup'] = array(
'#type' => 'markup',
'#value' => l(t('Reset'), 'support'),
);
return $form;
}
function support_filter_form_validate($form, &$form_state) {
}
function support_filter_form_submit($form, &$form_state) {
$query = array();
if (!empty($form_state['values']['tid'])) {
$query['tid'] = implode(',', $form_state['values']['tid']);
}
if (!empty($form_state['values']['uid'])) {
$query['uid'] = implode(',', $form_state['values']['uid']);
}
if (!empty($form_state['values']['sid'])) {
$query['sid'] = implode(',', $form_state['values']['sid']);
}
if (!empty($form_state['values']['pid'])) {
$query['pid'] = implode(',', $form_state['values']['pid']);
}
if (!empty($form_state['values']['clid'])) {
$query['clid'] = implode(',', $form_state['values']['clid']);
}
$form_state['support_filter_query'] = $query;
drupal_alter('support_filter_form_submit', $form_state);
$path = drupal_get_path_alias(isset($_GET['q']) ? $_GET['q'] : '');
drupal_goto($path, $form_state['support_filter_query']);
}
function support_page_form(&$form_state, $client = NULL, $state = NULL) {
global $user;
$form = array();
if (!$client) {
if (isset($_SESSION['support_client']) && ($client = support_client_load($_SESSION['support_client']))) {
unset($_SESSION['support_client']);
if ($client->parent) {
$parent = support_client_load($client->parent);
drupal_goto("support/{$parent->path}/{$client->path}");
}
else {
drupal_goto("support/{$client->path}");
}
}
$clients = _support_available_clients();
if (count($clients)) {
foreach ($clients as $key => $name) {
$client = support_client_load($key);
if ($client->parent) {
$parent = support_client_load($client->parent);
drupal_goto("support/{$parent->path}/{$client->path}");
}
else {
drupal_goto("support/{$client->path}");
}
}
}
}
else {
if (is_numeric($client)) {
$_SESSION['support_client'] = $client;
}
else {
drupal_set_message(t('Client does not exist or is not enabled.'), 'error');
if (isset($_SESSION['support_client'])) {
unset($_SESSION['support_client']);
}
drupal_goto('');
}
}
if ($client == SUPPORT_ALL_CLIENTS) {
$client = array_keys(_support_access_tickets(FALSE));
$all_clients = TRUE;
}
else {
$client = array(
$client,
);
$all_clients = FALSE;
}
if (!$state) {
$state = 'all open';
}
$state = _support_get_state($state);
$available = array(
'tid',
'uid',
'sid',
'pid',
'clid',
);
$filters = array();
foreach ($available as $filter) {
$to_filter = isset($_GET[$filter]) ? $_GET[$filter] : '';
$unsanitized = explode(',', $to_filter);
foreach ($unsanitized as $element) {
$element = (int) $element;
if ($element) {
$filters[$filter][$element] = $element;
}
}
}
$join = $where = $or = array();
if (!empty($filters)) {
if (isset($filters['tid']) && !empty($filters['tid'])) {
$join[] = 'LEFT JOIN {term_node} tn ON n.nid = tn.nid';
$where[] = strtr('tn.tid IN (!tid)', array(
'!tid' => implode(',', $filters['tid']),
));
}
if (isset($filters['uid']) && !empty($filters['uid'])) {
if (isset($filters['uid'][-1])) {
$filters['uid'][-1] = 0;
}
$where[] = strtr('t.assigned IN (!uid)', array(
'!uid' => implode(',', $filters['uid']),
));
if (isset($filters['uid'][-1])) {
$filters['uid'][-1] = -1;
}
}
if (isset($filters['sid']) && !empty($filters['sid'])) {
$where[] = strtr('t.state IN (!sid)', array(
'!sid' => implode(',', $filters['sid']),
));
}
if (isset($filters['pid']) && !empty($filters['pid'])) {
$where[] = strtr('t.priority IN (!pid)', array(
'!pid' => implode(',', $filters['pid']),
));
}
if (isset($filters['clid']) && !empty($filters['clid'])) {
$where[] = strtr('t.client IN (!clid)', array(
'!clid' => implode(',', $filters['clid']),
));
}
}
$filters['join'] = $join;
$filters['where'] = $where;
$filters['or'] = $or;
drupal_alter('support_ticket_listing_filter', $filters);
if (!empty($filters['where'])) {
array_unshift($filters['where'], ' ');
}
$form += support_filter_form($client, $filters, $state);
$form['post-ticket'] = array(
'#type' => 'markup',
'#value' => l(t('Post new support ticket'), 'node/add/support-ticket'),
);
$checkboxes = user_access('edit multiple tickets') || user_access('administer support') ? theme('table_select_header_cell') : array();
$sort = variable_get('support_default_sort_tickets', SUPPORT_SORT_UPDATE);
if (variable_get('support_default_sort_order', SUPPORT_SORT_DESC) == SUPPORT_SORT_DESC) {
$order = 'desc';
}
else {
$order = 'asc';
}
foreach (array(
SUPPORT_SORT_UPDATE => array(
'data' => t('Updated'),
'field' => 'last_updated',
),
SUPPORT_SORT_NID => array(
'data' => t('Id'),
'field' => 'n.nid',
),
SUPPORT_SORT_STATE => array(
'data' => t('State'),
'field' => 't.state',
),
SUPPORT_SORT_PRIORITY => array(
'data' => t('Priority'),
'field' => 'spri.weight',
),
) as $key => $array) {
if ($sort == $key) {
$headers[$key] = $array + array(
'sort' => $order,
);
}
else {
$headers[$key] = $array;
}
}
$form['header'] = array(
'#type' => 'value',
'#value' => array(
$checkboxes,
$headers[SUPPORT_SORT_NID],
array(
'data' => t('Ticket'),
'field' => 'n.title',
),
$headers[SUPPORT_SORT_UPDATE],
array(
'data' => t('Reported by'),
'field' => 'n.uid',
),
array(
'data' => t('Assigned to'),
'field' => 't.assigned',
),
$headers[SUPPORT_SORT_STATE],
$headers[SUPPORT_SORT_PRIORITY],
array(
'data' => t('Updates'),
'field' => 'l.comment_count',
),
),
);
if ($all_clients) {
$form['header']['#value'][] = array(
'data' => t('Client'),
'field' => 'sc.name',
);
$form['all_clients']['#value'] = TRUE;
}
if ($state == -2) {
$my_open = "AND t.assigned = {$user->uid}";
}
else {
$my_open = '';
}
if ($state < 0) {
$state = 'AND t.state NOT IN (' . implode(', ', _support_get_state(SUPPORT_STATE_CLOSED)) . ')';
}
else {
$state = $state ? "AND t.state = {$state}" : '';
}
$sql = "SELECT DISTINCT(n.nid), n.title, n.type, n.changed, n.uid, u.name, GREATEST(n.changed, l.last_comment_timestamp) AS last_updated, l.comment_count, t.state, t.priority, t.assigned, t.client, sc.name FROM {node} n LEFT JOIN {support_ticket} t ON n.nid = t.nid LEFT JOIN {support_client} sc ON t.client = sc.clid LEFT JOIN {support_priority} spri ON t.priority = spri.pid INNER JOIN {node_comment_statistics} l ON n.nid = l.nid INNER JOIN {users} u ON n.uid = u.uid " . implode(' ', $filters['join']) . " WHERE (n.status = 1 AND n.type = 'support_ticket' AND client IN(" . implode(',', $client) . ") {$state} {$my_open} " . implode(' AND ', $filters['where']);
if (!user_access('view other users tickets') && !user_access('administer support') && !user_access('edit any ticket') && !user_access('delete any ticket')) {
$sql .= " AND (n.uid = {$user->uid} OR t.assigned = {$user->uid})";
}
$sql .= ')';
if (!empty($filters['or'])) {
$sql .= ' OR (' . implode(' OR ', $filters['or']) . ')';
}
$sql = db_rewrite_sql($sql);
$sql .= tablesort_sql($form['header']['#value']);
if (variable_get('support_secondary_sort_order', SUPPORT_SORT_DESC) == SUPPORT_SORT_DESC) {
$order = 'desc';
}
else {
$order = 'asc';
}
switch (variable_get('support_secondary_sort_tickets', SUPPORT_SORT_NONE)) {
case SUPPORT_SORT_UPDATE:
$sql .= ", last_updated {$order}";
break;
case SUPPORT_SORT_NID:
$sql .= ", n.nid {$order}";
break;
case SUPPORT_SORT_STATE:
$sql .= ", t.state {$order}";
break;
case SUPPORT_SORT_PRIORITY:
$sql .= ", t.priority {$order}";
break;
}
$sql_count = 'SELECT COUNT(DISTINCT(n.nid)) FROM {node} n LEFT JOIN {comments} c ON n.nid = c.nid AND (c.status = 0 OR c.status IS NULL) LEFT JOIN {support_ticket} t ON n.nid = t.nid ' . implode(' ', $filters['join']) . ' WHERE n.status = 1 AND client IN(' . implode(',', $client) . ") {$state} {$my_open} " . implode(' AND ', $filters['where']);
$sql_count = db_rewrite_sql($sql_count);
$result = pager_query($sql, 50, 0, $sql_count);
$rows = array();
$tickets = array();
while ($ticket = db_fetch_object($result)) {
drupal_alter('support_page_list_ticket', $ticket);
$account = user_load(array(
'uid' => $ticket->uid,
));
$assigned = user_load(array(
'uid' => $ticket->assigned,
));
$comments = l($ticket->comment_count, "node/{$ticket->nid}", array(
'fragment' => 'comments',
));
if ($new = comment_num_new($ticket->nid)) {
$node = node_load($ticket->nid);
$comments .= ' (' . l(format_plural($new, '1 new', '@count new'), "node/{$ticket->nid}", array(
'query' => comment_new_page_count($node->comment_count, $new, $node),
'fragment' => 'new',
)) . ')';
}
$tickets[$ticket->nid] = '';
$form['id'][$ticket->nid] = array(
'#value' => l($ticket->nid, "node/{$ticket->nid}", array(
'attributes' => array(
'class' => 'ticket-id',
),
)),
);
$form['title'][$ticket->nid] = array(
'#value' => l(_support_truncate($ticket->title), "node/{$ticket->nid}", array(
'attributes' => array(
'class' => 'ticket-title',
),
)),
);
$form['updated'][$ticket->nid] = array(
'#value' => format_date($ticket->last_updated, 'small', array(
'attributes' => array(
'class' => 'ticket-updated',
),
)),
);
$form['reported'][$ticket->nid] = array(
'#value' => l(_support_truncate($account->name, 24), "user/{$account->uid}", array(
'attributes' => array(
'class' => 'ticket-reported',
),
)),
);
if (user_access('edit multiple tickets') && user_access('can assign tickets to any user') || user_access('administer support')) {
$node = node_load($ticket->nid);
$options = _support_assigned(isset($assigned->uid) ? $assigned->uid : 0, $node, variable_get('support_autocomplete_limit', 15));
if ($options === FALSE) {
if (isset($ticket->assigned)) {
if (is_numeric($ticket->assigned)) {
$account = user_load(array(
'uid' => $ticket->assigned,
));
$assigned = $account->name;
}
else {
$assigned = $ticket->assigned;
}
}
else {
$assigned = '';
}
$form['assigned']["assigned-{$ticket->nid}"] = array(
'#type' => 'textfield',
'#autocomplete_path' => 'support/autocomplete/assigned/' . $ticket->client,
'#default_value' => $assigned,
'#size' => '15',
'#attributes' => array(
'class' => 'ticket-assigned',
),
);
}
else {
$form['assigned']["assigned-{$ticket->nid}"] = array(
'#type' => 'select',
'#options' => $options,
'#default_value' => isset($ticket->assigned) ? $ticket->assigned : 0,
'#attributes' => array(
'class' => 'ticket-assigned',
),
);
}
}
else {
$form['assigned']["assigned-{$ticket->nid}"] = array(
'#value' => l(_support_truncate($assigned->name, 24), "user/{$assigned->uid}", array(
'attributes' => array(
'class' => 'ticket-assigned',
),
)),
);
}
$states = _support_states(FALSE);
if ((user_access('edit multiple tickets') || user_access('administer support')) && sizeof($states) > 1) {
$form['state']["state-{$ticket->nid}"] = array(
'#type' => 'select',
'#options' => $states,
'#default_value' => $ticket->state,
'#attributes' => array(
'class' => 'ticket-state',
),
);
}
else {
$form['state']["state-{$ticket->nid}"] = array(
'#value' => _support_state($ticket->state),
'#attributes' => array(
'class' => 'ticket-state',
),
);
}
if (user_access('administer support') || user_access('edit multiple tickets') && user_access('can select priority')) {
$form['priority']["priority-{$ticket->nid}"] = array(
'#type' => 'select',
'#options' => _support_priorities(),
'#default_value' => $ticket->priority,
'#attributes' => array(
'class' => 'ticket-priority',
),
);
}
else {
$form['priority']["priority-{$ticket->nid}"] = array(
'#value' => _support_priorities($ticket->priority),
'#attributes' => array(
'class' => 'ticket-priority',
),
);
}
$form['updates'][$ticket->nid] = array(
'#value' => $comments,
'#attributes' => array(
'class' => "state-{$ticket->state} priority-{$ticket->priority}",
),
);
$form['class'][$ticket->nid] = array(
'#value' => "state-{$ticket->state} priority-{$ticket->priority}",
);
if ($all_clients) {
$form['client'][$ticket->nid] = array(
'#value' => _support_client($ticket->client),
'#attributes' => array(
'class' => "state-{$ticket->state} priority-{$ticket->priority}",
),
);
}
}
$form['tickets'] = array(
'#type' => 'checkboxes',
'#options' => count($tickets) && (user_access('edit multiple tickets') || user_access('administer support')) ? $tickets : array(),
);
if (count($tickets) && (user_access('edit multiple tickets') || user_access('administer support'))) {
$form['update'] = array(
'#title' => t('Update'),
'#type' => 'textarea',
'#description' => t('This text will be added to all selected tickets.'),
);
if (user_access('can suppress notification') && variable_get('support_notifications', TRUE)) {
$form['suppress'] = array(
'#type' => 'checkbox',
'#title' => t('Suppress notification'),
'#description' => t('By checking this box you will prevent notification emails from being sent for this update.'),
'#default_value' => isset($edit->suppress) ? $edit->suppress : 0,
);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Update ticket'),
);
}
$form['pager'] = array(
'#value' => theme('pager', NULL, 50, 0),
);
return $form;
}
function support_page_form_validate($form, &$form_state) {
$form_state['values']['tickets'] = array_diff($form_state['values']['tickets'], array(
0,
));
if (count($form_state['values']['tickets']) == 0) {
form_set_error('', t('Please select one or more tickets to perform the update on.'));
}
if (variable_get('support_require_comment', TRUE)) {
if (!$form_state['values']['update']) {
form_set_error('update', t('You must enter a ticket update.'));
}
}
}
function support_page_form_submit($form, &$form_state) {
global $user;
foreach ($form_state['values']['tickets'] as $nid) {
$message = array();
$message['uid'] = $user->uid;
$message['nid'] = $nid;
$message['subject'] = '';
$message['body'] = $form_state['values']['update'];
$message['attachments'] = array();
$message['suppress'] = isset($form_state['values']['suppress']) ? $form_state['values']['suppress'] : FALSE;
$message['state'] = $form_state['values']["state-{$nid}"];
$message['priority'] = $form_state['values']["priority-{$nid}"];
$message['assigned'] = $form_state['values']["assigned-{$nid}"];
$clid = db_result(db_query('SELECT client FROM {support_ticket} WHERE nid = %d', $nid));
$client = support_client_load($clid);
support_save_message($message, $client);
}
}
function theme_support_page_form($form) {
drupal_add_css(drupal_get_path('module', 'support') . '/support-tickets.css');
$output = drupal_render($form['filter']);
$output .= drupal_render($form['post-ticket']);
if (isset($form['title']) && is_array($form['title'])) {
foreach (element_children($form['title']) as $key) {
$row = array();
$row[] = drupal_render($form['tickets'][$key]);
$row[] = drupal_render($form['id'][$key]);
$row[] = drupal_render($form['title'][$key]);
$row[] = drupal_render($form['updated'][$key]);
$row[] = drupal_render($form['reported'][$key]);
$row[] = drupal_render($form['assigned']["assigned-{$key}"]);
$row[] = drupal_render($form['state']["state-{$key}"]);
$row[] = drupal_render($form['priority']["priority-{$key}"]);
$row[] = drupal_render($form['updates'][$key]);
if ($form['all_clients']) {
$row[] = drupal_render($form['client'][$key]);
}
$rows[] = array(
'data' => $row,
'class' => $form['class'][$key]['#value'],
);
unset($form['class'][$key]);
}
unset($form['all_clients']);
}
else {
$rows[] = array(
array(
'data' => t('No tickets available.'),
'colspan' => '9',
),
);
}
if ($form['pager']['#value']) {
$output .= drupal_render($form['pager']);
}
$output .= theme('table', $form['header']['#value'], $rows, array(
'class' => 'support',
));
$output .= drupal_render($form['update']);
$output .= drupal_render($form['suppress']);
$output .= drupal_render($form['submit']);
$output .= drupal_render($form);
return $output;
}
function _support_client($clid) {
static $client_name = array();
if (!isset($client_name[$clid])) {
$client_name[$clid] = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $clid));
}
return $client_name[$clid];
}
function support_client_fetch($client, $manual = TRUE) {
if (!isset($client->integrate_email) || $client->integrate_email != TRUE) {
if ($manual) {
drupal_set_message(t('Client not integrated with email, unable to fetch mail for !client.', array(
'!client' => $client->name,
)));
drupal_goto('admin/support/clients');
}
return;
}
set_time_limit(0);
if ($manual) {
drupal_set_message(t('Fetching mail for !client...', array(
'!client' => $client->name,
)));
}
$connect = '{' . $client->server_name . ':' . $client->port;
$username = $client->server_username;
$password = $client->server_password;
$extra = $client->extra;
switch ($client->protocol) {
case 0:
$connect .= "/pop3{$extra}}" . $client->mailbox;
break;
case 1:
$connect .= "/pop3/ssl{$extra}}" . $client->mailbox;
break;
case 2:
$connect .= "{$extra}}" . $client->mailbox;
break;
case 3:
$connect .= "/imap/ssl{$extra}}" . $client->mailbox;
break;
case 4:
$connect = $client->mailbox;
$username = $password = '';
if (!file_exists($connect) && $manual) {
drupal_set_message(t('Mail file "%connect" does not exist.', array(
'%connect' => $connect,
)), 'error');
}
else {
if (!is_readable($connect) && $manual) {
drupal_set_message(t('Mail file "%connect" is not readable.', array(
'%connect' => $connect,
)), 'error');
}
else {
if (!is_writable($connect) && $manual) {
drupal_set_message(t('Mail file "%connect" is not writable.', array(
'%connect' => $connect,
)));
}
}
}
break;
}
$stream = imap_open($connect, $username, $password);
if ($stream === FALSE) {
if ($manual) {
drupal_set_message(t('Failed to download messages for %client, connection to mail server failed.', array(
'%client' => $client->name,
), 'error'));
if (user_access('administer support')) {
drupal_set_message(t('Mail server connection failure: connect(!connect), username(!username), password(!password)', array(
'!connect' => $connect,
'!username' => $username,
'!password' => $password,
)), 'error');
}
}
if ($alerts = imap_alerts()) {
foreach ($alerts as $alert) {
watchdog('support', 'Imap alert: %alert for user %username', array(
'%alert' => $alert,
'%username' => $username,
));
if ($manual) {
drupal_set_message(t('Imap alert: %alert for user %username', array(
'%alert' => $alert,
'%username' => $username,
)), 'error');
}
}
}
if ($errors = imap_errors()) {
foreach ($errors as $error) {
watchdog('support', 'Imap error: %error for user %username', array(
'%error' => $error,
'%username' => $username,
), WATCHDOG_NOTICE);
if ($manual) {
drupal_set_message(t('Imap error: %error for user %username', array(
'%error' => $error,
'%username' => $username,
)), 'error');
}
}
}
if ($manual) {
drupal_goto('admin/support/clients');
}
else {
return -1;
}
}
$messages_downloaded = 0;
$messages_to_download = imap_num_msg($stream);
$messages_limit = variable_get('support_download_limit', 1000);
if ($messages_limit && $messages_limit < $messages_to_download) {
$messages_to_download = $messages_limit;
}
for ($number = 1; $number <= $messages_to_download; $number++) {
$message = array();
$message['headers'] = imap_headerinfo($stream, $number);
$message['headers_raw'] = imap_fetchbody($stream, $number, 0);
if (is_array($message['headers']->from)) {
$message['from'] = $message['headers']->from[0]->mailbox . '@' . $message['headers']->from[0]->host;
}
$strings = imap_mime_header_decode($message['headers']->subject);
$message['subject'] = '';
foreach ($strings as $string) {
if ($string->charset == 'default') {
$message['subject'] .= $string->text;
}
else {
$message['subject'] .= drupal_convert_to_utf8($string->text, $string->charset);
}
}
_support_identify_ticket($client, $message);
$structure = imap_fetchstructure($stream, $number);
$mime = _support_get_filemime($structure);
$message['body'] = _support_get_message_body_part($stream, $number, $mime, $structure);
if (isset($structure->parts)) {
$parts = count($structure->parts);
if ($parts > 1) {
$message['attachments'] = _support_get_attachments($stream, $number, $structure, $parts);
}
}
drupal_alter('support_fetch_message', $message, $client);
$saved = support_save_message($message, $client, $manual);
$messages_downloaded++;
imap_delete($stream, $number);
}
imap_close($stream, CL_EXPUNGE);
if ($manual) {
drupal_set_message(t('Downloaded !count', array(
'!count' => format_plural($messages_downloaded, '1 message', '@count messages'),
)));
drupal_goto('admin/support/clients');
}
}
function _support_identify_ticket(&$client, &$message) {
global $base_url;
$key = variable_get('support_key', 'tkt');
$tickets = array();
preg_match("/(\\[{$key}:)([0-9]*)(\\])/", $message['subject'], $tickets);
if (isset($tickets[2])) {
$message['nid'] = $tickets[2];
return TRUE;
}
if (variable_get('support_thread_by_mail_headers', TRUE)) {
$id_right = preg_replace('|.+://([a-zA-Z0-9\\._-]+).*|', '\\1', $base_url);
$check = '';
if (isset($message['headers']->in_reply_to)) {
$check .= $message['headers']->in_reply_to;
}
if (isset($message['headers']->references)) {
$check .= implode(' ', array_reverse(explode(' ', $message['headers']->references)));
}
$message_ids = array();
preg_match_all("/<[^<^>]*/", $check, $message_ids);
foreach ($message_ids[0] as $message_id) {
$message_id .= '>';
$matches = array();
if (preg_match('/^<(\\d+)\\.(\\d+)@' . $id_right . '>$/', $message_id, $matches)) {
$cid = $matches[1];
$nid = $matches[2];
if (!$cid) {
if (db_result(db_query('SELECT 1 FROM {support_ticket} t WHERE t.nid = %d AND t.client = %d', $nid, $client->clid))) {
$message['nid'] = $nid;
return TRUE;
}
}
else {
if (db_result(db_query('SELECT 1 FROM {comments} c INNER JOIN {support_ticket_comment} t ON c.cid = t.cid WHERE c.cid = %d AND c.nid = %d AND t.client = %d', $cid, $nid, $client->clid))) {
$message['nid'] = $nid;
return TRUE;
}
}
}
$nid = db_result(db_query("SELECT nid FROM {support_ticket} WHERE message_id = '%s'", $message_id));
if (isset($nid) && is_numeric($nid)) {
$message['nid'] = $nid;
return TRUE;
}
$nid = db_result(db_query("SELECT c.nid FROM {support_ticket_comment} j INNER JOIN {comments} c ON j.cid = c.cid WHERE j.message_id = '%s'", $message_id));
if (isset($nid) && is_numeric($nid)) {
$message['nid'] = $nid;
return TRUE;
}
}
}
if (!$client->thread_subject) {
$client->thread_subject = variable_get('support_thread_by_subject', 3);
}
switch ($client->thread_subject) {
case 1:
break;
case 2:
$message['nid'] = db_result(db_query_range("SELECT t.nid FROM {support_ticket} t LEFT JOIN {node} n ON t.nid = n.nid LEFT JOIN {support_states} s ON t.state = s.sid WHERE t.client = %d AND n.title = '%s' AND s.isdefault = 1 ORDER BY t.nid DESC", $client->clid, $message['subject'], 0, 1));
break;
case 3:
$message['nid'] = db_result(db_query_range("SELECT t.nid FROM {support_ticket} t LEFT JOIN {node} n ON t.nid = n.nid LEFT JOIN {support_states} s ON t.state = s.sid WHERE t.client = %d AND n.title = '%s' AND s.isclosed = 0 ORDER BY t.nid DESC", $client->clid, $message['subject'], 0, 1));
break;
case 4:
$message['nid'] = db_result(db_query_range("SELECT t.nid FROM {support_ticket} t LEFT JOIN {node} n ON t.nid = n.nid WHERE t.client = %d AND n.title = '%s' ORDER BY t.nid DESC", $client->clid, $message['subject'], 0, 1));
break;
}
return (bool) $message['nid'];
}
function _support_access_tickets($count = TRUE) {
static $clients = NULL;
if (is_null($clients)) {
$clients = array();
$result = db_query('SELECT clid, name FROM {support_client} WHERE status = 1');
while ($client = db_fetch_object($result)) {
if (user_access('administer support') || user_access("access {$client->name} tickets")) {
$clients[$client->clid] = $client->name;
}
}
}
if ($count) {
return count($clients);
}
else {
return $clients;
}
}
function _support_autoassign($clid, $uid = 0) {
static $autoassign = array();
if ($clid && !isset($autoassign[$clid])) {
$name = db_result(db_query('SELECT autoassign FROM {support_client} WHERE clid = %d', $clid));
switch ($name) {
case '<nobody>':
$autoassign[$clid] = 0;
break;
case '<creator>':
$autoassign[$clid] = $uid;
break;
default:
$account = user_load(array(
'name' => trim($name),
));
if (empty($account) || !$account->uid) {
$assign = variable_get('support_autoassign_ticket', '<nobody>');
switch ($assign) {
case '<nobody>':
$autoassign[$clid] = 0;
break;
case '<creator>':
$autoassign[$clid] = $uid;
break;
default:
$account = user_load(array(
'name' => trim($assign),
));
if (empty($account) || !$account->uid) {
$autoassign[$clid] = 0;
}
else {
$autoassign[$clid] = $account->uid;
}
break;
}
}
else {
$autoassign[$clid] = $account->uid;
}
}
}
return !empty($clid) ? $autoassign[$clid] : 0;
}
function _support_current_client() {
$clients = _support_available_clients();
drupal_alter('support_current_client', $clients);
if (count($clients) == 1) {
$client = key($clients);
}
else {
if (count($clients)) {
if (is_numeric($_SESSION['support_client'])) {
$client = $_SESSION['support_client'];
}
else {
if (!user_access('can select client')) {
$client = key($clients);
}
}
}
else {
return NULL;
}
}
return $client;
}
function _support_enabled($clid, $uid) {
static $enabled = array();
if (!isset($enabled[$clid])) {
$autosubscribe = db_result(db_query('SELECT autosubscribe FROM {support_client} WHERE clid = %d', $clid));
$names = explode(',', $autosubscribe);
foreach ($names as $name) {
$account = user_load(array(
'name' => trim($name),
));
$enabled[$clid][$account->uid] = TRUE;
}
}
return isset($enabled[$clid][$uid]);
}
function _support_autosubscribe_access() {
return user_access('administer support') || user_access('can subscribe other users to notifications');
}
function support_client_delete($client) {
drupal_alter('support_client_delete', $client);
if (!empty($client->clid)) {
$name = db_result(db_query('SELECT name FROM {support_client} WHERE clid = %d', $client->clid));
db_query('DELETE FROM {support_client} WHERE clid = %d', $client->clid);
drupal_set_message(t('Client %client deleted.', array(
'%client' => $name,
)));
module_invoke_all('support_client_deleted', $client);
}
}
function support_client_update($client) {
drupal_alter('support_client_update', $client);
if (isset($client->name)) {
$client->name = check_plain($client->name);
}
if (empty($client->name)) {
drupal_set_message(t('Valid client name required.'), 'error');
return -1;
}
$rc = drupal_write_record('support_client', $client, 'clid');
if ($rc == SAVED_UPDATED) {
drupal_set_message(t('Client %client updated successfully.', array(
'%client' => $client->name,
)));
module_invoke_all('support_client_updated', $client);
}
else {
drupal_set_message(t('Client %client update failed.', array(
'%client' => $client->name,
)), 'error');
}
}
function support_client_create($client) {
drupal_alter('support_client_create', $client);
if (isset($client->name)) {
$client->name = check_plain($client->name);
}
if (empty($client->name)) {
drupal_set_message(t('Valid client name required.'), 'error');
return -1;
}
$rc = drupal_write_record('support_client', $client);
if ($rc == SAVED_NEW) {
drupal_set_message(t('Client %client created successfully.', array(
'%client' => $client->name,
)));
module_invoke_all('support_client_created', $client);
}
else {
drupal_set_message(t('Client %client creation failed.', array(
'%client' => $client->name,
)), 'error');
}
}
function support_support_timer_client_report_alter(&$report) {
$report->filters .= drupal_get_form('support_invoice_ui_form');
}
function _support_state_query_filter($state) {
if ($state == -2) {
global $user;
$query_filter = " AND st.assigned = {$user->uid} ";
}
else {
$query_filter = '';
}
if ($state < 0) {
$query_filter .= ' AND st.state NOT IN (' . implode(', ', _support_get_state(SUPPORT_STATE_CLOSED)) . ') ';
}
else {
$query_filter .= $state ? " AND st.state = {$state} " : '';
}
return $query_filter;
}
function _support_client_terms($clid, $state = NULL) {
static $tids = array();
if (is_array($clid)) {
$clid = implode(',', $clid);
}
else {
$clid = (int) $clid;
}
if (!isset($tids["{$clid}"][$state])) {
$query_filter = _support_state_query_filter($state);
if ($state < 0) {
$query_filter .= 'AND st.state NOT IN (' . implode(', ', _support_get_state(SUPPORT_STATE_CLOSED)) . ')';
}
else {
$query_filter .= $state ? "AND st.state = {$state}" : '';
}
$result = db_query('SELECT DISTINCT(tn.tid) AS tid, td.name FROM {support_ticket} st LEFT JOIN {term_node} tn ON st.nid = tn.nid LEFT JOIN {term_data} td ON tn.tid = td.tid WHERE st.client IN(%s) AND !ISNULL(tn.nid) ' . $query_filter . ' ORDER BY td.name ASC', $clid);
while ($term = db_fetch_object($result)) {
$tids["{$clid}"][$state][$term->tid] = $term->name;
}
}
if (isset($tids["{$clid}"][$state])) {
return $tids["{$clid}"][$state];
}
return NULL;
}
function _support_client_users($clid) {
static $uids = array();
if (is_array($clid)) {
$clid = implode(',', $clid);
}
else {
$clid = (int) $clid;
}
if (!isset($uids["{$clid}"])) {
$result = db_query('SELECT DISTINCT(u.uid) AS uid, u.name FROM {support_ticket} st LEFT JOIN {users} u ON st.assigned = u.uid WHERE st.client IN(%s) ORDER BY u.name ASC', $clid);
while ($account = db_fetch_object($result)) {
$uids["{$clid}"][$account->uid] = $account->name;
}
}
if (isset($uids["{$clid}"])) {
return $uids["{$clid}"];
}
return NULL;
}
function support_invoice_ui_form() {
$form = array();
if (count(_support_client_terms(_support_current_client()))) {
$tags = array(
-1 => t('-- no tag --'),
0 => t('-- all tags --'),
) + _support_client_terms(_support_current_client());
$term = isset($_GET['tid']) ? $_GET['tid'] : '';
if ($term && $term == preg_replace('/[^0-9,]/', '', $term)) {
$selected = explode(',', $term);
}
else {
if ($_GET['tid'] == 'null') {
$selected = -1;
}
else {
$selected = 0;
}
}
$form['tags'] = array(
'#type' => 'fieldset',
'#title' => t('Tags'),
'#collapsible' => TRUE,
'#collapsed' => $selected ? FALSE : TRUE,
);
$form['tags']['tids'] = array(
'#title' => t('Tag'),
'#type' => 'select',
'#multiple' => TRUE,
'#options' => $tags,
'#default_value' => $selected,
'#description' => t('Filter report by selected tag(s).'),
);
$form['tags']['submit'] = array(
'#type' => 'submit',
'#value' => t('Update filter'),
);
}
return $form;
}
function support_invoice_ui_form_submit($form, &$form_state) {
$tids = array();
if (!empty($form_state['values']['tids'])) {
foreach ($form_state['values']['tids'] as $tid) {
if ($tid == -1) {
$tids = array(
'null',
);
break;
}
else {
if ($tid == 0) {
$tids = '';
break;
}
else {
$tids[$tid] = $tid;
}
}
}
if ($tids) {
$tids = implode(',', $tids);
}
}
$path = drupal_get_path_alias(isset($_GET['q']) ? $_GET['q'] : '');
$query = array();
foreach ($_GET as $key => $value) {
if (!in_array($key, array(
'q',
'tid',
))) {
$query[$key] = $value;
}
}
if ($tids) {
$query['tid'] = $tids;
}
drupal_goto($path, $query);
}