View source
<?php
define('PRIVATEMSG_READ', 0);
define('PRIVATEMSG_UNREAD', 1);
define('PRIVATEMSG_UNLIMITED', 'unlimited');
function privatemsg_perm() {
return array(
'read privatemsg',
'read all private messages',
'administer privatemsg settings',
'write privatemsg',
'delete privatemsg',
);
}
function _privatemsg_generate_user_array($userstring, $slice = NULL) {
static $user_cache = array();
$users = explode(',', $userstring);
if (!is_null($slice)) {
$users = array_slice($users, $slice);
}
$participants = array();
foreach ($users as $uid) {
if (!array_key_exists($uid, $user_cache)) {
$user_cache[$uid] = user_load($uid);
}
if (is_object($user_cache[$uid])) {
$participants[$uid] = $user_cache[$uid];
}
}
return $participants;
}
function _privatemsg_format_participants($part_array, $limit = NULL, $no_text = FALSE) {
if (count($part_array) > 0) {
$to = array();
$limited = FALSE;
foreach ($part_array as $account) {
if (is_int($limit) && count($to) >= $limit) {
$limited = TRUE;
break;
}
$to[] = theme('username', $account);
}
$limit_string = '';
if ($limited) {
$limit_string = t(' and others');
}
if ($no_text) {
return implode(', ', $to) . $limit_string;
}
$last = array_pop($to);
if (count($to) == 0) {
return t("From !last", array(
'!last' => $last,
));
}
else {
$participants = implode(', ', $to);
return t('Participants: !participants and !last', array(
'!participants' => $participants,
'!last' => $last,
));
}
}
return '';
}
function privatemsg_menu() {
$items['messages'] = array(
'title' => 'Messages',
'title callback' => 'privatemsg_title_callback',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'privatemsg_list',
'list',
),
'access callback' => 'privatemsg_user_access',
'type' => MENU_NORMAL_ITEM,
);
$items['messages/list'] = array(
'title' => 'Messages',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'privatemsg_list',
'list',
),
'access callback' => 'privatemsg_user_access',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['messages/view/%privatemsg_thread'] = array(
'title' => 'Read message',
'page callback' => 'privatemsg_view',
'page arguments' => array(
2,
),
'access callback' => 'privatemsg_view_access',
'type' => MENU_LOCAL_TASK,
'weight' => -5,
);
$items['messages/delete/%privatemsg_thread/%privatemsg_message'] = array(
'title' => 'Delete message',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'privatemsg_delete',
2,
3,
),
'access callback' => 'privatemsg_user_access',
'access arguments' => array(
'delete privatemsg',
),
'type' => MENU_CALLBACK,
);
$items['messages/new'] = array(
'title' => 'Write new message',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'privatemsg_new',
2,
3,
NULL,
),
'access callback' => 'privatemsg_user_access',
'access arguments' => array(
'write privatemsg',
),
'type' => MENU_LOCAL_TASK,
'weight' => -3,
);
$items['messages/user-name-autocomplete'] = array(
'page callback' => 'privatemsg_user_name_autocomplete',
'access callback' => 'privatemsg_user_access',
'access arguments' => array(
'write privatemsg',
),
'type' => MENU_CALLBACK,
'weight' => -10,
);
$items['admin/settings/messages'] = array(
'title' => 'Private messages',
'description' => 'Configure private messaging settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'private_message_settings',
),
'access arguments' => array(
'administer privatemsg settings',
),
'type' => MENU_NORMAL_ITEM,
);
$items['admin/settings/messages/default'] = array(
'title' => 'Private messages',
'description' => 'Configure private messaging settings.',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'private_message_settings',
),
'access arguments' => array(
'administer privatemsg settings',
),
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
);
$items['messages/undo/action'] = array(
'title' => 'Private messages',
'description' => 'Undo last thread action',
'page callback' => 'privatemsg_undo_action',
'access arguments' => array(
'read privatemsg',
),
'type' => MENU_CALLBACK,
);
$items['user/%/messages'] = array(
'title' => 'Messages',
'page callback' => 'drupal_get_form',
'page arguments' => array(
'privatemsg_list',
'list',
1,
),
'access callback' => 'privatemsg_user_access',
'access arguments' => array(
'read all private messages',
),
'type' => MENU_LOCAL_TASK,
);
return $items;
}
function privatemsg_user_access($permission = 'read privatemsg', $account = NULL) {
if ($account === NULL) {
global $user;
$account = $user;
}
if (!$account->uid) {
return FALSE;
}
if (!user_access($permission, $account)) {
return FALSE;
}
return TRUE;
}
function privatemsg_view_access() {
if (privatemsg_user_access('read privatemsg') && arg(1) == 'view') {
return TRUE;
}
return FALSE;
}
function privatemsg_thread_load($thread_id, $account = NULL, $start = NULL) {
static $threads = array();
if ((int) $thread_id > 0) {
$thread = array(
'thread_id' => $thread_id,
);
if (is_null($account)) {
global $user;
$account = drupal_clone($user);
}
if (!isset($threads[$account->uid])) {
$threads[$account->uid] = array();
}
if (!array_key_exists($thread_id, $threads[$account->uid])) {
$query = _privatemsg_assemble_query('participants', $thread_id);
$participants = db_query($query['query']);
$thread['participants'] = array();
while ($participant = db_fetch_object($participants)) {
$thread['participants'][$participant->uid] = $participant;
}
$thread['read_all'] = FALSE;
if (!array_key_exists($account->uid, $thread['participants']) && privatemsg_user_access('read all private messages', $account)) {
$thread['read_all'] = TRUE;
}
$query = _privatemsg_assemble_query('messages', array(
$thread_id,
), $thread['read_all'] ? NULL : $account);
$thread['message_count'] = $thread['to'] = db_result(db_query($query['count']));
$thread['from'] = 1;
$max_amount = variable_get('privatemsg_view_max_amount', 20);
if (is_null($start)) {
if (isset($_GET['start']) && $_GET['start'] < $thread['message_count']) {
$start = $_GET['start'];
}
elseif (!variable_get('privatemsg_view_use_max_as_default', FALSE) && $max_amount == PRIVATEMSG_UNLIMITED) {
$start = PRIVATEMSG_UNLIMITED;
}
else {
$start = $thread['message_count'] - (variable_get('privatemsg_view_use_max_as_default', FALSE) ? variable_get('privatemsg_view_default_amount', 10) : $max_amount);
}
}
if ($start != PRIVATEMSG_UNLIMITED) {
if ($max_amount == PRIVATEMSG_UNLIMITED) {
$last_page = 0;
$max_amount = $thread['message_count'];
}
else {
$paging_count = variable_get('privatemsg_view_use_max_as_default', FALSE) ? $thread['message_count'] - variable_get('privatemsg_view_default_amount', 10) : $thread['message_count'];
$last_page = $paging_count % $max_amount;
}
if ($start < 0) {
$start = 0;
}
$thread['start'] = $start;
if ($start + $max_amount + 1 < $thread['message_count']) {
$thread['to'] = $start + $max_amount;
$thread['newer_start'] = $start + $max_amount;
}
if ($start - $max_amount >= 0) {
$thread['older_start'] = $start - $max_amount;
}
elseif ($start > 0) {
$thread['older_start'] = 0;
}
if ($start < $last_page && $max_amount != PRIVATEMSG_UNLIMITED && $max_amount < $thread['message_count']) {
unset($thread['older_start']);
$thread['to'] = $thread['newer_start'] = $max_amount = $last_page;
$start = 0;
}
$thread['from'] = $start + 1;
$conversation = db_query_range($query['query'], $start, $max_amount);
}
else {
$conversation = db_query($query['query']);
}
$mids = array();
while ($result = db_fetch_array($conversation)) {
$mids[] = $result['mid'];
}
$thread['messages'] = privatemsg_message_load_multiple($mids, $thread['read_all'] ? NULL : $account);
if (empty($thread['messages'])) {
$thread = FALSE;
}
else {
$thread['user'] = $account;
$message = current($thread['messages']);
$thread['subject'] = $message['subject'];
}
$threads[$account->uid][$thread_id] = $thread;
}
return $threads[$account->uid][$thread_id];
}
return FALSE;
}
function private_message_view_options() {
$options = module_invoke_all('privatemsg_view_template');
return $options;
}
function privatemsg_privatemsg_view_template() {
return array(
'privatemsg-view' => 'Default view',
);
}
function private_message_settings() {
$form = array();
$form['theming_settings'] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Theming settings'),
);
$form['theming_settings']['private_message_view_template'] = array(
'#type' => 'radios',
'#title' => t('Private message display template'),
'#default_value' => variable_get('private_message_view_template', 'privatemsg-view'),
'#options' => private_message_view_options(),
);
$form['privatemsg_display_loginmessage'] = array(
'#type' => 'checkbox',
'#title' => t('Inform the user about new messages on login'),
'#default_value' => variable_get('privatemsg_display_loginmessage', TRUE),
'#description' => t('This option can safely be disabled if the "New message indication" block is used instead.'),
);
$form['flush_deleted'] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Flush deleted messages'),
'#description' => t('By default, deleted messages are only hidden from the user but still stored in the database. These settings control if and when messages should be removed.'),
);
$form['flush_deleted']['privatemsg_flush_enabled'] = array(
'#type' => 'checkbox',
'#title' => t('Flush deleted messages'),
'#default_value' => variable_get('privatemsg_flush_enabled', FALSE),
'#description' => t('Enable the flushing of deleted messages. Requires that cron is enabled'),
);
$form['flush_deleted']['privatemsg_flush_days'] = array(
'#type' => 'select',
'#title' => t('Flush messages after they have been deleted for more days than'),
'#default_value' => variable_get('privatemsg_flush_days', 30),
'#options' => drupal_map_assoc(array(
0,
1,
2,
5,
10,
30,
100,
)),
);
$form['flush_deleted']['privatemsg_flush_max'] = array(
'#type' => 'select',
'#title' => t('Maximum number of messages to flush per cron run'),
'#default_value' => variable_get('privatemsg_flush_max', 200),
'#options' => drupal_map_assoc(array(
50,
100,
200,
500,
1000,
)),
);
$form['privatemsg_listing'] = array(
'#type' => 'fieldset',
'#title' => t('Configure listings'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['privatemsg_listing']['privatemsg_per_page'] = array(
'#type' => 'select',
'#title' => t('Threads per page'),
'#default_value' => variable_get('privatemsg_per_page', 25),
'#options' => drupal_map_assoc(array(
10,
25,
50,
75,
100,
)),
'#description' => t('Choose the number of conversations that should be listed per page.'),
);
$form['privatemsg_listing']['privatemsg_display_fields'] = array(
'#type' => 'checkboxes',
'#title' => t('Configure fields'),
'#description' => t('Select which columns/fields should be displayed in the message listings. Subject and Last updated cannot be disabled.'),
'#options' => array(
'participants' => t('Participants'),
'thread_started' => t('Started'),
'count' => t('Messages'),
),
'#default_value' => variable_get('privatemsg_display_fields', array(
'participants',
)),
);
$amounts = drupal_map_assoc(array(
5,
10,
20,
30,
50,
70,
90,
150,
200,
250,
300,
));
$form['privatemsg_listing']['privatemsg_view_max_amount'] = array(
'#type' => 'select',
'#title' => t('Number of messages on thread pages'),
'#options' => $amounts + array(
PRIVATEMSG_UNLIMITED => t('Unlimited'),
),
'#default_value' => variable_get('privatemsg_view_max_amount', 20),
'#description' => t('Threads will not show more than this number of messages on a single page.'),
'#weight' => 10,
);
$form['privatemsg_listing']['privatemsg_view_use_max_as_default'] = array(
'#type' => 'checkbox',
'#title' => t('Display different amount of messages on first thread page'),
'#default_value' => variable_get('privatemsg_view_use_max_as_default', FALSE),
'#description' => t('By default, the first thread page shows the maximally allowed amount of messages. Enable this checkbox to set a different value.'),
'#weight' => 15,
);
$form['privatemsg_listing']['privatemsg_view_default_amount'] = array(
'#prefix' => '<div id="privatemsg-view-default-button">',
'#suffix' => '</div>',
'#type' => 'select',
'#title' => t('Number of messages on first thread page'),
'#default_value' => variable_get('privatemsg_view_default_amount', 10),
'#description' => t('The number of messages to be displayed on first thread page. Displays the newest messages.'),
'#options' => $amounts,
'#weight' => 20,
);
drupal_add_js(drupal_get_path('module', 'privatemsg') . '/privatemsg-admin.js');
$form['#submit'][] = 'private_message_settings_submit';
return system_settings_form($form);
}
function private_message_settings_submit() {
drupal_rebuild_theme_registry();
}
function privatemsg_cron() {
if (variable_get('privatemsg_flush_enabled', FALSE)) {
$query = _privatemsg_assemble_query('deleted', variable_get('privatemsg_flush_days', 30));
$result = db_query($query['query']);
$flushed = 0;
while (($row = db_fetch_array($result)) && $flushed < variable_get('privatemsg_flush_max', 200)) {
$message = privatemsg_message_load($row['mid']);
module_invoke_all('privatemsg_message_flush', $message);
db_query('DELETE FROM {pm_index} WHERE mid = %d', $row['mid']);
db_query('DELETE FROM {pm_message} WHERE mid = %d', $row['mid']);
$flushed++;
}
}
}
function privatemsg_theme() {
return array(
'privatemsg_view' => array(
'arguments' => array(
'message' => NULL,
),
'template' => variable_get('private_message_view_template', 'privatemsg-view'),
),
'privatemsg_from' => array(
'arguments' => array(
'author' => NULL,
),
'template' => 'privatemsg-from',
),
'privatemsg_recipients' => array(
'arguments' => array(
'message' => NULL,
),
'template' => 'privatemsg-recipients',
),
'privatemsg_between' => array(
'arguments' => array(
'recipients' => NULL,
),
'template' => 'privatemsg-between',
),
'privatemsg_list' => array(
'file' => 'privatemsg.theme.inc',
'path' => drupal_get_path('module', 'privatemsg'),
'arguments' => array(
'form',
),
),
'privatemsg_list_header' => array(
'file' => 'privatemsg.theme.inc',
'path' => drupal_get_path('module', 'privatemsg'),
'pattern' => 'privatemsg_list_header__',
'arguments' => array(),
),
'privatemsg_list_field' => array(
'file' => 'privatemsg.theme.inc',
'path' => drupal_get_path('module', 'privatemsg'),
'pattern' => 'privatemsg_list_field__',
'arguments' => array(
'thread',
),
),
'privatemsg_new_block' => array(
'file' => 'privatemsg.theme.inc',
'path' => drupal_get_path('module', 'privatemsg'),
'arguments' => array(
'count',
),
),
);
}
function template_preprocess_privatemsg_view(&$vars) {
$message = $vars['message'];
$vars['mid'] = isset($message['mid']) ? $message['mid'] : NULL;
$vars['thread_id'] = isset($message['thread_id']) ? $message['thread_id'] : NULL;
$vars['author_picture'] = theme('user_picture', $message['author']);
$vars['author_name_link'] = theme('username', $message['author']);
$vars['message_timestamp'] = format_date($message['timestamp'], 'small');
$vars['message_body'] = check_markup($message['body'], $message['format'], FALSE);
if (isset($vars['mid']) && isset($vars['thread_id']) && privatemsg_user_access('delete privatemsg')) {
$vars['message_actions'][] = array(
'title' => t('Delete message'),
'href' => 'messages/delete/' . $vars['thread_id'] . '/' . $vars['mid'],
);
}
$vars['message_anchors'][] = 'privatemsg-mid-' . $vars['mid'];
if (!empty($message['is_new'])) {
$vars['message_anchors'][] = 'new';
$vars['new'] = drupal_ucfirst(t('new'));
}
drupal_alter('privatemsg_message_view', $vars);
$vars['message_actions'] = !empty($vars['message_actions']) ? theme('links', $vars['message_actions'], array(
'class' => 'message-actions',
)) : '';
$vars['anchors'] = '';
foreach ($vars['message_anchors'] as $anchor) {
$vars['anchors'] .= '<a name="' . $anchor . '"></a>';
}
}
function template_preprocess_privatemsg_recipients(&$vars) {
$vars['participants'] = '';
if (isset($vars['message']['participants'])) {
$vars['participants'] = _privatemsg_format_participants($vars['message']['participants']);
}
}
function privatemsg_list(&$form_state, $argument = 'list', $uid = NULL) {
global $user;
$account = $user;
if ((int) $uid > 0 && $uid != $user->uid) {
if (!privatemsg_user_access('read all private messages')) {
drupal_set_message(t("You do not have sufficient rights to view someone else's messages"), 'warning');
}
elseif ($account_check = user_load(array(
'uid' => $uid,
))) {
$account = $account_check;
}
}
$query = _privatemsg_assemble_query('list', $account, $argument);
$result = pager_query($query['query'], variable_get('privatemsg_per_page', 25), 0, $query['count']);
$threads = array();
$form['#data'] = array();
while ($row = db_fetch_array($result)) {
$form['#data'][$row['thread_id']] = $row;
$threads[$row['thread_id']] = '';
}
if (!empty($form['#data'])) {
$form['actions'] = _privatemsg_action_form();
}
$form['account'] = array(
'#type' => 'value',
'#value' => $account,
);
$form['threads'] = array(
'#type' => 'checkboxes',
'#options' => $threads,
);
$form['pager'] = array(
'#value' => theme('pager'),
'#weight' => 20,
);
$form['#theme'] = 'privatemsg_list';
$form['#account'] = $account;
return $form;
}
function privatemsg_message_change_status($pmid, $status, $account = NULL) {
if (!$account) {
global $user;
$account = $user;
}
$query = "UPDATE {pm_index} SET is_new = %d WHERE mid = %d AND uid = %d";
db_query($query, $status, $pmid, $account->uid);
}
function privatemsg_unread_count($account = NULL) {
static $counts = array();
if (!$account || $account->uid == 0) {
global $user;
$account = $user;
}
if (!isset($counts[$account->uid])) {
$query = _privatemsg_assemble_query('unread_count', $account);
$counts[$account->uid] = db_result(db_query($query['query']));
}
return $counts[$account->uid];
}
function privatemsg_view($thread) {
drupal_set_title(check_plain($thread['subject']));
$older = '';
if (isset($thread['older_start'])) {
$options = array(
'query' => array(
'start' => $thread['older_start'],
),
'title' => t('Display older messages'),
);
$older = l(t('<<'), 'messages/view/' . $thread['thread_id'], $options);
}
$newer = '';
if (isset($thread['newer_start'])) {
$options = array(
'query' => array(
'start' => $thread['newer_start'],
),
'title' => t('Display newer messages'),
);
$newer = l(t('>>'), 'messages/view/' . $thread['thread_id'], $options);
}
$substitutions = array(
'@from' => $thread['from'],
'@to' => $thread['to'],
'@total' => $thread['message_count'],
'!previous_link' => $older,
'!newer_link' => $newer,
);
$title = t('!previous_link Displaying messages @from - @to of @total !newer_link', $substitutions);
$content['pager_top'] = array(
'#value' => trim($title),
'#prefix' => '<div class="privatemsg-view-pager">',
'#suffix' => '</div>',
'#weight' => -10,
);
$content['pager_bottom'] = $content['pager_top'];
$content['pager_bottom']['#weight'] = 3;
$content['participants']['#value'] = theme('privatemsg_recipients', $thread);
$content['participants']['#weight'] = -5;
$output = '';
foreach ($thread['messages'] as $pmid => $message) {
if (!empty($message['is_new'])) {
privatemsg_message_change_status($pmid, PRIVATEMSG_READ, $thread['user']);
}
$output .= theme('privatemsg_view', $message);
}
$content['messages']['#value'] = $output;
$content['messages']['#weight'] = 0;
if (privatemsg_user_access('write privatemsg')) {
$content['reply']['#value'] = drupal_get_form('privatemsg_new', $thread['participants'], $thread['subject'], $thread['thread_id'], $thread['read_all']);
$content['reply']['#weight'] = 5;
}
if ($thread['read_all']) {
drupal_set_message(t('This conversation is being viewed with escalated priviledges and may not be the same as shown to normal users.'), 'warning');
}
drupal_alter('privatemsg_view_messages', $content, $thread);
return drupal_render($content);
}
function privatemsg_new(&$form_state, $recipients = array(), $subject = '', $thread_id = NULL, $read_all = FALSE) {
global $user;
$recipients_string = '';
$body = '';
if (!empty($recipients) && is_string($recipients) || is_int($recipients)) {
$recipients = _privatemsg_generate_user_array($recipients);
}
elseif (is_object($recipients)) {
$recipients = array(
$recipients,
);
}
elseif (empty($recipients) && is_string($recipients)) {
$recipients = array();
}
$usercount = 0;
$to = array();
$to_themed = array();
$blocked = FALSE;
foreach ($recipients as $recipient) {
if (in_array($recipient->name, $to)) {
continue;
}
$user_blocked = module_invoke_all('privatemsg_block_message', $user, array(
$recipient->uid => $recipient,
));
if (!count($user_blocked) != 0 && $recipient->uid) {
if ($recipient->uid == $user->uid) {
$usercount++;
continue;
}
$to[] = $recipient->name;
$to_themed[$recipient->uid] = theme('username', $recipient);
}
else {
$blocked = TRUE;
}
}
if (empty($to) && $usercount >= 1 && !$blocked) {
$to[] = $user->name;
$to_themed[$user->uid] = theme('username', $user);
}
if (!empty($to)) {
$recipients_string = implode(', ', $to);
}
if (isset($form_state['values'])) {
if (isset($form_state['values']['recipient'])) {
$recipients_string = $form_state['values']['recipient'];
}
$subject = $form_state['values']['subject'];
$body = $form_state['values']['body'];
}
if (!$thread_id && !empty($recipients_string)) {
drupal_set_title(t('Write new message to %recipient', array(
'%recipient' => $recipients_string,
)));
}
elseif (!$thread_id) {
drupal_set_title(t('Write new message'));
}
$form = array();
if (isset($form_state['privatemsg_preview'])) {
$form['message_header'] = array(
'#type' => 'fieldset',
'#attributes' => array(
'class' => 'preview',
),
);
$form['message_header']['message_preview'] = array(
'#value' => $form_state['privatemsg_preview'],
);
}
$form['privatemsg'] = array(
'#type' => 'fieldset',
'#access' => privatemsg_user_access('write privatemsg'),
);
$form['privatemsg']['author'] = array(
'#type' => 'value',
'#value' => $user,
);
if (is_null($thread_id)) {
$form['privatemsg']['recipient'] = array(
'#type' => 'textfield',
'#title' => t('To'),
'#description' => t('Separate multiple names with commas.'),
'#default_value' => $recipients_string,
'#required' => TRUE,
'#weight' => -10,
'#size' => 50,
'#autocomplete_path' => 'messages/user-name-autocomplete',
);
}
$form['privatemsg']['subject'] = array(
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 50,
'#maxlength' => 255,
'#default_value' => $subject,
'#weight' => -5,
);
$form['privatemsg']['body'] = array(
'#type' => 'textarea',
'#title' => t('Message'),
'#rows' => 6,
'#weight' => 0,
'#default_value' => $body,
'#resizable' => TRUE,
);
$format = FILTER_FORMAT_DEFAULT;
if (isset($form_state['values']) && array_key_exists('format', $form_state['values'])) {
$format = $form_state['values']['format'];
}
$form['privatemsg']['format'] = filter_form($format);
$form['privatemsg']['preview'] = array(
'#type' => 'submit',
'#value' => t('Preview message'),
'#submit' => array(
'pm_preview',
),
'#validate' => array(
'pm_send_validate',
),
'#weight' => 10,
);
$form['privatemsg']['submit'] = array(
'#type' => 'submit',
'#value' => t('Send message'),
'#submit' => array(
'pm_send',
),
'#validate' => array(
'pm_send_validate',
),
'#weight' => 15,
);
$url = 'messages';
$title = t('Cancel');
if (isset($_REQUEST['destination'])) {
$url = $_REQUEST['destination'];
}
elseif (!is_null($thread_id)) {
$url = $_GET['q'];
$title = t('Clear');
}
$form['privatemsg']['cancel'] = array(
'#value' => l($title, $url, array(
'attributes' => array(
'id' => 'edit-cancel',
),
)),
'#weight' => 20,
);
if (!is_null($thread_id)) {
$form['privatemsg']['thread_id'] = array(
'#type' => 'value',
'#value' => $thread_id,
);
$form['privatemsg']['subject'] = array(
'#type' => 'value',
'#default_value' => $subject,
);
$recipients_string_themed = implode(', ', $to_themed);
$form['privatemsg']['recipient_display'] = array(
'#value' => '<p>' . t('<strong>Reply to thread</strong>:<br /> Recipients: !to', array(
'!to' => $recipients_string_themed,
)) . '</p>',
'#weight' => -10,
);
if (empty($recipients_string)) {
$form['privatemsg']['#access'] = FALSE;
}
}
$form['privatemsg']['read_all'] = array(
'#type' => 'value',
'#value' => $read_all,
);
return $form;
}
function pm_send_validate($form, &$form_state) {
$message = $form_state['values'];
$message['timestamp'] = time();
$message['subject'] = trim($message['subject']);
$trimed_body = trim(truncate_utf8(strip_tags($message['body']), 50, TRUE, TRUE));
if (empty($message['subject']) && !empty($trimed_body)) {
$message['subject'] = $trimed_body;
}
if (!isset($message['thread_id'])) {
list($message['recipients'], $invalid) = _privatemsg_parse_userstring($message['recipient']);
}
else {
$message['recipients'] = _privatemsg_load_thread_participants($message['thread_id']);
if (isset($message['recipients'][$message['author']->uid]) && count($message['recipients']) > 1) {
unset($message['recipients'][$message['author']->uid]);
}
}
$validated = _privatemsg_validate_message($message, TRUE);
foreach ($validated['messages'] as $type => $text) {
drupal_set_message($text, $type);
}
$form_state['validate_built_message'] = $message;
if (!empty($invalid)) {
drupal_set_message(t('The following users will not receive this private message: @invalid', array(
'@invalid' => implode(", ", $invalid),
)), 'error');
}
}
function _privatemsg_load_thread_participants($thread_id) {
$query = _privatemsg_assemble_query('participants', $thread_id);
$result = db_query($query['query']);
$participants = array();
while ($uid = db_fetch_object($result)) {
if ($recipient = user_load($uid->uid)) {
$participants[$recipient->uid] = $recipient;
}
}
return $participants;
}
function _privatemsg_parse_userstring($input) {
if (is_string($input)) {
$input = explode(',', $input);
}
$invalid = array();
$recipients = array();
foreach ($input as $string) {
$string = trim($string);
if (!empty($string)) {
foreach (module_implements('privatemsg_name_lookup') as $module) {
$function = $module . '_privatemsg_name_lookup';
if (($recipient = $function($string)) && is_object($recipient)) {
$recipients[$recipient->uid] = $recipient;
continue 2;
}
}
if (!($error = module_invoke('user', 'validate_name', $string))) {
if ($recipient = user_load(array(
'name' => $string,
))) {
$recipients[$recipient->uid] = $recipient;
continue;
}
}
$invalid[$string] = $string;
}
}
return array(
$recipients,
$invalid,
);
}
function pm_send($form, &$form_state) {
$status = _privatemsg_send($form_state['validate_built_message']);
$recipient_names = array();
foreach ($form_state['validate_built_message']['recipients'] as $recipient) {
$recipient_names[] = theme('username', $recipient);
}
if ($status !== FALSE) {
drupal_set_message(t('A message has been sent to !recipients.', array(
'!recipients' => implode(', ', $recipient_names),
)));
}
else {
drupal_set_message(t('An attempt to send a message <em>may have failed</em> when sending to !recipients.', array(
'!recipients' => implode(', ', $recipient_names),
)), 'error');
}
}
function pm_preview($form, &$form_state) {
drupal_validate_form($form['form_id']['#value'], $form, $form_state);
if (!form_get_errors()) {
$form_state['privatemsg_preview'] = theme('privatemsg_view', $form_state['validate_built_message']);
}
$form_state['rebuild'] = TRUE;
}
function privatemsg_sql_list(&$fragments, $account, $argument = 'list') {
$fragments['primary_table'] = '{pm_message} pm';
$fields = array_filter(variable_get('privatemsg_display_fields', array(
'participants',
)));
$fragments['select'][] = 'pmi.thread_id';
$fragments['select'][] = 'MIN(pm.subject) as subject';
$fragments['select'][] = 'MAX(pm.timestamp) as last_updated';
$fragments['select'][] = 'SUM(pmi.is_new) as is_new';
if (in_array('count', $fields)) {
$fragments['select'][] = 'COUNT(distinct pmi.mid) as count';
}
if (in_array('participants', $fields)) {
if ($GLOBALS['db_type'] == 'pgsql') {
$fragments['select'][] = "array_to_string(array(SELECT DISTINCT textin(int4out(pmia.uid))\n FROM {pm_index} pmia\n WHERE pmia.thread_id = pmi.thread_id), ',') AS participants";
}
else {
$fragments['select'][] = '(SELECT GROUP_CONCAT(DISTINCT pmia.uid SEPARATOR ",")
FROM {pm_index} pmia
WHERE pmia.thread_id = pmi.thread_id) AS participants';
}
}
if (in_array('thread_started', $fields)) {
$fragments['select'][] = 'MIN(pm.timestamp) as thread_started';
}
$fragments['inner_join'][] = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
$fragments['where'][] = 'pmi.uid = %d';
$fragments['query_args']['where'][] = $account->uid;
$fragments['where'][] = 'pmi.deleted = 0';
$fragments['group_by'][] = 'pmi.thread_id';
$order_by_first = 'MAX(pmi.is_new) DESC, ';
if ($GLOBALS['db_type'] != 'pgsql' && version_compare(db_version(), '5.0.0') < 0) {
$order_by_first = 'is_new DESC, ';
}
$order_by = drupal_substr(tablesort_sql(_privatemsg_list_headers(FALSE, array_merge(array(
'subject',
'last_updated',
), $fields)), $order_by_first), 9);
$fragments['order_by'][] = $order_by;
}
function privatemsg_sql_load(&$fragments, $pmids, $account = NULL) {
$fragments['primary_table'] = '{pm_message} pm';
$fragments['select'][] = "pm.mid";
$fragments['select'][] = "pm.author";
$fragments['select'][] = "pm.subject";
$fragments['select'][] = "pm.body";
$fragments['select'][] = "pm.timestamp";
$fragments['select'][] = "pm.format";
$fragments['select'][] = "pmi.is_new";
$fragments['select'][] = "pmi.thread_id";
$fragments['inner_join'][] = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
$fragments['where'][] = 'pmi.mid IN (' . db_placeholders($pmids) . ')';
$fragments['query_args']['where'] += $pmids;
if ($account) {
$fragments['where'][] = 'pmi.uid = %d';
$fragments['query_args']['where'][] = $account->uid;
}
$fragments['order_by'][] = 'pm.timestamp ASC';
$fragments['order_by'][] = 'pm.mid ASC';
}
function privatemsg_sql_messages(&$fragments, $threads, $account = NULL, $load_all = FALSE) {
$fragments['primary_table'] = '{pm_index} pmi';
$fragments['select'][] = 'pmi.mid';
$fragments['where'][] = 'pmi.thread_id IN (' . db_placeholders($threads) . ')';
$fragments['query_args']['where'] += $threads;
$fragments['inner_join'][] = 'INNER JOIN {pm_message} pm ON (pm.mid = pmi.mid)';
if ($account) {
$fragments['where'][] = 'pmi.uid = %d';
$fragments['query_args']['where'][] = $account->uid;
}
if (!$load_all) {
$fragments['where'][] = 'pmi.deleted = 0';
}
$fragments['group_by'][] = 'pmi.mid';
$fragments['group_by'][] = 'pm.timestamp';
$fragments['order_by'][] = 'pm.timestamp ASC';
$fragments['order_by'][] = 'pmi.mid ASC';
}
function privatemsg_sql_participants(&$fragments, $thread_id) {
$fragments['primary_table'] = '{pm_index} pmi';
$fragments['select'][] = 'DISTINCT(pmi.uid) AS uid';
$fragments['select'][] = 'u.name AS name';
$fragments['inner_join'][] = 'INNER JOIN {users} u ON (u.uid = pmi.uid)';
$fragments['where'][] = 'pmi.thread_id = %d';
$fragments['query_args']['where'][] = $thread_id;
}
function privatemsg_sql_unread_count(&$fragments, $account) {
$fragments['primary_table'] = '{pm_index} pmi';
$fragments['select'][] = 'COUNT(DISTINCT thread_id) as unread_count';
$fragments['where'][] = 'pmi.deleted = 0';
$fragments['where'][] = 'pmi.is_new = 1';
$fragments['where'][] = 'pmi.uid = %d';
$fragments['query_args']['where'][] = $account->uid;
}
function privatemsg_sql_autocomplete(&$fragments, $search, $names) {
$fragments['primary_table'] = '{users} u';
$fragments['select'][] = 'u.name';
$fragments['where'][] = "u.name LIKE '%s'";
$fragments['query_args']['where'][] = $search . '%%';
if (!empty($names)) {
$fragments['where'][] = "u.name NOT IN (" . db_placeholders($names, 'text') . ")";
$fragments['query_args']['where'] += $names;
}
$fragments['where'][] = 'u.status <> 0';
$fragments['order_by'][] = 'u.name ASC';
}
function privatemsg_sql_deleted(&$fragments, $days) {
$fragments['primary_table'] = '{pm_message} pm';
$fragments['select'][] = 'pm.mid';
$fragments['select'][] = 'MIN(pmi.deleted) as is_deleted';
$fragments['select'][] = 'MAX(pmi.deleted) as last_deleted';
$fragments['inner_join'][] = 'INNER JOIN {pm_index} pmi ON (pmi.mid = pm.mid)';
$fragments['group_by'][] = 'pm.mid';
$fragments['having'][] = 'MIN(pmi.deleted) > 0';
$fragments['having'][] = 'MAX(pmi.deleted) < %d';
$fragments['query_args']['having'][] = time() - $days * 86400;
}
function privatemsg_user_name_autocomplete($string) {
$names = array();
$fragments = explode(',', $string);
foreach ($fragments as $index => $name) {
if ($name = trim($name)) {
$names[$name] = $name;
}
}
$fragment = array_pop($names);
$matches = array();
if (!empty($fragment)) {
$query = _privatemsg_assemble_query('autocomplete', $fragment, $names);
$result = db_query_range($query['query'], $fragment, 0, 10);
$prefix = count($names) ? implode(", ", $names) . ", " : '';
while ($user = db_fetch_object($result)) {
$matches[$prefix . $user->name . ", "] = $user->name;
}
}
drupal_json((object) $matches);
}
function privatemsg_user($op, &$edit, &$account, $category = NULL) {
global $user;
switch ($op) {
case 'view':
if ($url = privatemsg_get_link(array(
$account,
))) {
$account->content['privatemsg_send_new_message'] = array(
'#type' => 'markup',
'#value' => l(t('Send this user a message'), $url, array(
'query' => drupal_get_destination(),
)),
'#weight' => 10,
);
}
break;
case 'login':
if (variable_get('privatemsg_display_loginmessage', TRUE) && privatemsg_user_access()) {
$count = privatemsg_unread_count();
if ($count) {
drupal_set_message(format_plural($count, 'You have <a href="@messages">1 unread message</a>.', 'You have <a href="@messages">@count unread messages</a>', array(
'@messages' => url('messages'),
)));
}
}
break;
case 'delete':
$result = db_query("SELECT mid FROM {pm_message} WHERE author = %d", $account->uid);
$mids = array();
while ($row = db_fetch_array($result)) {
$mids[] = $row['mid'];
}
db_query('DELETE FROM {pm_message} WHERE author = %d', $account->uid);
if (!empty($mids)) {
db_query('DELETE FROM {pm_index} WHERE mid IN (' . db_placeholders($mids) . ')', $mids);
}
db_query('DELETE FROM {pm_index} WHERE uid = %d', $account->uid);
break;
}
}
function privatemsg_block($op = 'list', $delta = 0, $edit = array()) {
if ('list' == $op) {
$blocks = array();
$blocks['privatemsg-menu'] = array(
'info' => t('Privatemsg links'),
'cache' => BLOCK_NO_CACHE,
);
$blocks['privatemsg-new'] = array(
'info' => t('New message indication'),
'cache' => BLOCK_NO_CACHE,
);
return $blocks;
}
elseif ('view' == $op) {
$block = array();
switch ($delta) {
case 'privatemsg-menu':
$block = _privatemsg_block_menu();
break;
case 'privatemsg-new':
$block = _privatemsg_block_new();
break;
}
return $block;
}
}
function privatemsg_title_callback($title = NULL) {
$count = privatemsg_unread_count();
if ($count > 0) {
return format_plural($count, 'Messages (1 new)', 'Messages (@count new)');
}
return t('Messages');
}
function _privatemsg_block_new() {
$block = array();
if (!privatemsg_user_access()) {
return $block;
}
$count = privatemsg_unread_count();
if ($count) {
$block = array(
'subject' => format_plural($count, 'New message', 'New messages'),
'content' => theme('privatemsg_new_block', $count),
);
return $block;
}
return array();
}
function _privatemsg_block_menu() {
$block = array();
$links = array();
if (privatemsg_user_access('write privatemsg')) {
$links[] = l(t('Write new message'), 'messages/new');
}
if (privatemsg_user_access('read privatemsg') || privatemsg_user_access('read all private messages')) {
$links[] = l(privatemsg_title_callback(), 'messages');
}
if (count($links)) {
$block = array(
'subject' => t('Private messages'),
'content' => theme('item_list', $links),
);
}
return $block;
}
function privatemsg_delete($form_state, $thread, $message) {
$form['pmid'] = array(
'#type' => 'value',
'#value' => $message['mid'],
);
$form['delete_destination'] = array(
'#type' => 'value',
'#value' => count($thread['messages']) > 1 ? 'messages/view/' . $message['thread_id'] : 'messages',
);
if (privatemsg_user_access('read all private messages')) {
$form['delete_options'] = array(
'#type' => 'checkbox',
'#title' => t('Delete this message for all users?'),
'#description' => t('Tick the box to delete the message for all users.'),
'#default_value' => FALSE,
);
}
return confirm_form($form, t('Are you sure you want to delete this message?'), isset($_GET['destination']) ? $_GET['destination'] : 'messages/view/' . $message['thread_id'], t('This action cannot be undone.'), t('Delete'), t('Cancel'));
}
function privatemsg_delete_submit($form, &$form_state) {
global $user;
$account = drupal_clone($user);
if ($form_state['values']['confirm']) {
if (isset($form_state['values']['delete_options']) && $form_state['values']['delete_options']) {
privatemsg_message_change_delete($form_state['values']['pmid'], 1);
drupal_set_message(t('Message has been deleted for all users.'));
}
else {
privatemsg_message_change_delete($form_state['values']['pmid'], 1, $account);
drupal_set_message(t('Message has been deleted.'));
}
}
$form_state['redirect'] = $form_state['values']['delete_destination'];
}
function privatemsg_message_change_delete($pmid, $delete, $account = NULL) {
$delete_value = 0;
if ($delete == TRUE) {
$delete_value = time();
}
if ($account) {
db_query('UPDATE {pm_index} SET deleted = %d WHERE mid = %d AND uid = %d', $delete_value, $pmid, $account->uid);
}
else {
db_query('UPDATE {pm_index} SET deleted = %d WHERE mid = %d', $delete_value, $pmid);
}
}
function privatemsg_new_thread($recipients, $subject, $body = NULL, $options = array()) {
global $user;
$author = drupal_clone($user);
$message = array();
$message['subject'] = $subject;
$message['body'] = $body;
foreach ($recipients as $recipient) {
$message['recipients'][$recipient->uid] = $recipient;
}
if (!empty($options)) {
$message += $options;
}
$message += array(
'author' => $author,
'timestamp' => time(),
'format' => filter_resolve_format(FILTER_FORMAT_DEFAULT),
);
$validated = _privatemsg_validate_message($message);
if ($validated['success']) {
$validated['message'] = _privatemsg_send($message);
}
return $validated;
}
function privatemsg_reply($thread_id, $body, $options = array()) {
global $user;
$author = drupal_clone($user);
$message = array();
$message['body'] = $body;
if (!empty($options)) {
$message += $options;
}
$message += array(
'author' => $author,
'timestamp' => time(),
'format' => filter_resolve_format(FILTER_FORMAT_DEFAULT),
);
$first_message = privatemsg_message_load($thread_id, $message['author']);
if (!$first_message) {
return array(
t('Thread %thread_id not found, unable to answer', array(
'%thread_id' => $thread_id,
)),
);
}
$message['thread_id'] = $thread_id;
$message['recipients'] = _privatemsg_load_thread_participants($thread_id);
if (isset($message['recipients'][$message['author']->uid]) && count($message['recipients']) > 1) {
unset($message['recipients'][$message['author']->uid]);
}
$message['subject'] = $first_message['subject'];
$validated = _privatemsg_validate_message($message);
if ($validated['success']) {
$validated['message'] = _privatemsg_send($message);
}
return $validated;
}
function _privatemsg_validate_message(&$message, $form = FALSE) {
$messages = array(
'error' => array(),
'warning' => array(),
);
if (!privatemsg_user_access('write privatemsg', $message['author'])) {
if ($form) {
form_set_error('author', t('User @user is not allowed to write messages', array(
'@user' => $message['author']->name,
)));
return array(
'success' => FALSE,
'messages' => $messages,
);
}
else {
$messages['error'][] = t('User @user is not allowed to write messages', array(
'@user' => $message['author']->name,
));
return array(
'success' => FALSE,
'messages' => $messages,
);
}
}
$message['subject'] = trim($message['subject']);
if (empty($message['subject'])) {
if ($form) {
form_set_error('subject', t('Disallowed to send a message without subject'));
}
else {
$messages['error'][] = t('Disallowed to send a message without subject');
}
}
if (!empty($message['thread_id']) && ($message['body'] === NULL || $message['body'] === '')) {
if ($form) {
form_set_error('body', t('Disallowed to send reply without a message.'));
}
else {
$messages['error'][] = t('Disallowed to send reply without a message.');
}
}
global $user;
$original_user = drupal_clone($user);
session_save_session(FALSE);
$user = $message['author'];
if (!filter_access($message['format'])) {
if ($form) {
form_set_error('format', t('You are not allowed to use the specified input format.'));
}
else {
$messages['error'][] = t('User @user is not allowed to use the specified input format.', array(
'@user' => $message['author']->name,
));
}
}
$user = $original_user;
session_save_session(TRUE);
if (empty($message['recipients']) || !is_array($message['recipients'])) {
if ($form) {
form_set_error('to', t('Disallowed to send a message without at least one valid recipient'));
}
else {
$messages['error'][] = t('Disallowed to send a message without at least one valid recipient');
}
}
if (!empty($message['recipients']) && is_array($message['recipients'])) {
foreach (module_invoke_all('privatemsg_block_message', $message['author'], $message['recipients']) as $blocked) {
unset($message['recipients'][$blocked['uid']]);
if ($form) {
drupal_set_message($blocked['message'], 'warning');
}
else {
$messages['warning'][] = $blocked['message'];
}
}
}
if (empty($message['recipients'])) {
if ($form) {
form_set_error('to', t('Disallowed to send message because all recipients are blocked'));
}
else {
$messages['error'][] = t('Disallowed to send message because all recipients are blocked');
}
}
$messages = array_merge_recursive(module_invoke_all('privatemsg_message_validate', $message, $form), $messages);
$success = empty($messages['error']) || $form && count((array) form_get_errors()) > 0;
return array(
'success' => $success,
'messages' => $messages,
);
}
function _privatemsg_send($message) {
drupal_alter('privatemsg_message_presave', $message);
$index_sql = "INSERT INTO {pm_index} (mid, thread_id, uid, is_new, deleted) VALUES (%d, %d, %d, %d, 0)";
if (isset($message['read_all']) && $message['read_all']) {
$query_messages = _privatemsg_assemble_query('messages', array(
$message['thread_id'],
), NULL);
$conversation = db_query($query_messages['query']);
while ($result = db_fetch_array($conversation)) {
if (!db_query($index_sql, $result['mid'], $message['thread_id'], $message['author']->uid, 0)) {
return FALSE;
}
}
}
$args = array();
$args[] = $message['subject'];
$args[] = $message['author']->uid;
$args[] = $message['body'];
$args[] = $message['format'];
$args[] = $message['timestamp'];
$message_sql = "INSERT INTO {pm_message} (subject, author, body, format, timestamp) VALUES ('%s', %d, '%s', %d, %d)";
db_query($message_sql, $args);
$mid = db_last_insert_id('pm_message', 'mid');
$message['mid'] = $mid;
if (!isset($message['thread_id'])) {
$message['thread_id'] = $mid;
}
foreach ($message['recipients'] as $recipient) {
if (!db_query($index_sql, $mid, $message['thread_id'], $recipient->uid, 1)) {
return FALSE;
}
}
$is_new = isset($message['recipients'][$message['author']->uid]) ? 1 : 0;
if (!db_query($index_sql, $mid, $message['thread_id'], $message['author']->uid, $is_new)) {
return FALSE;
}
module_invoke_all('privatemsg_message_insert', $message);
return $message;
}
function privatemsg_get_link($recipients, $account = array(), $subject = NULL) {
if ($account == NULL) {
global $user;
$account = $user;
}
if (!is_array($recipients)) {
$recipients = array(
$recipients,
);
}
if (!privatemsg_user_access('write privatemsg', $account) || $account->uid == 0) {
return FALSE;
}
$validated = array();
foreach ($recipients as $recipient) {
if (!privatemsg_user_access('read privatemsg', $recipient)) {
continue;
}
if (count(module_invoke_all('privatemsg_block_message', $account, array(
$recipient->uid => $recipient,
))) > 0) {
continue;
}
$validated[] = $recipient->uid;
}
if (empty($validated)) {
return FALSE;
}
$url = 'messages/new/' . implode(',', $validated);
if (!is_null($subject)) {
$url .= '/' . $subject;
}
return $url;
}
function privatemsg_message_load($pmid, $account = NULL) {
$messages = privatemsg_message_load_multiple(array(
$pmid,
), $account);
return current($messages);
}
function privatemsg_message_load_multiple($pmids, $account = NULL) {
if (empty($pmids)) {
return array();
}
$query = _privatemsg_assemble_query('load', $pmids, $account);
$result = db_query($query['query']);
$messages = array();
while ($message = db_fetch_array($result)) {
if (!($message['author'] = user_load($message['author']))) {
$message['author'] = user_load(array(
'uid' => 0,
));
}
$returned = module_invoke_all('privatemsg_message_load', $message);
if (!empty($returned)) {
$message = array_merge_recursive($returned, $message);
}
$messages[$message['mid']] = $message;
}
return $messages;
}
function _privatemsg_assemble_query($query) {
if (is_array($query)) {
$query_id = $query[0];
$query_group = $query[1];
}
else {
$query_id = $query;
$query_group = 'privatemsg';
}
$SELECT = array();
$INNER_JOIN = array();
$WHERE = array();
$GROUP_BY = array();
$HAVING = array();
$ORDER_BY = array();
$QUERY_ARGS = array(
'select' => array(),
'where' => array(),
'join' => array(),
'having' => array(),
);
$primary_table = '';
$fragments = array(
'select' => $SELECT,
'inner_join' => $INNER_JOIN,
'where' => $WHERE,
'group_by' => $GROUP_BY,
'having' => $HAVING,
'order_by' => $ORDER_BY,
'query_args' => $QUERY_ARGS,
'primary_table' => $primary_table,
);
$args = func_get_args();
unset($args[0]);
$alterargs = array(
&$fragments,
);
$query_function = $query_group . '_sql_' . $query_id;
if (!empty($args)) {
$alterargs = array_merge($alterargs, $args);
}
if (!function_exists($query_function)) {
drupal_set_message(t('Query function %function does not exist', array(
'%function' => $query_function,
)), 'error');
return FALSE;
}
call_user_func_array($query_function, $alterargs);
array_unshift($alterargs, $query_function);
call_user_func_array('drupal_alter', $alterargs);
$SELECT = $fragments['select'];
$INNER_JOIN = $fragments['inner_join'];
$WHERE = $fragments['where'];
$GROUP_BY = $fragments['group_by'];
$HAVING = $fragments['having'];
$ORDER_BY = $fragments['order_by'];
$QUERY_ARGS = $fragments['query_args'];
$primary_table = $fragments['primary_table'];
if ($GLOBALS['db_type'] == 'pgsql') {
$WHERE = str_replace('LIKE', 'ILIKE', $WHERE);
}
if (empty($primary_table)) {
$primary_table = '{privatemsg} pm';
}
if (!empty($SELECT)) {
$str_select = implode(", ", $SELECT);
$query = "SELECT {$str_select} FROM " . $primary_table;
if (!empty($GROUP_BY)) {
$str_group_by_count = current($GROUP_BY);
$count = "SELECT COUNT(DISTINCT {$str_group_by_count}) FROM " . $primary_table;
}
else {
$count = "SELECT COUNT(*) FROM " . $primary_table;
}
if (!empty($INNER_JOIN)) {
$str_inner_join = implode(' ', $INNER_JOIN);
$query .= " {$str_inner_join}";
$count .= " {$str_inner_join}";
}
if (!empty($WHERE)) {
$str_where = '(' . implode(') AND (', $WHERE) . ')';
$query .= " WHERE {$str_where}";
$count .= " WHERE {$str_where}";
}
if (!empty($GROUP_BY)) {
$str_group_by = ' GROUP BY ' . implode(", ", $GROUP_BY);
$query .= " {$str_group_by}";
}
if (!empty($HAVING)) {
$str_having = '(' . implode(') AND (', $HAVING) . ')';
$query .= " HAVING {$str_having}";
$count = 'SELECT COUNT(*) FROM (' . $query . ') as count';
}
if (!empty($ORDER_BY)) {
$str_order_by = ' ORDER BY ' . implode(", ", $ORDER_BY);
$query .= " {$str_order_by}";
}
$QUERY_ARGS = array_merge($QUERY_ARGS['select'], $QUERY_ARGS['join'], $QUERY_ARGS['where'], $QUERY_ARGS['having']);
if (!empty($QUERY_ARGS)) {
_db_query_callback($QUERY_ARGS, TRUE);
$query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query);
_db_query_callback($QUERY_ARGS, TRUE);
$count = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $count);
}
return array(
'query' => $query,
'count' => $count,
);
}
return FALSE;
}
function _privatemsg_action_form() {
$form = array(
'#type' => 'fieldset',
'#title' => t('Actions'),
'#prefix' => '<div class="container-inline">',
'#suffix' => '</div>',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#weight' => 15,
);
if (privatemsg_user_access('delete privatemsg')) {
$form['delete'] = array(
'#type' => 'submit',
'#value' => t('Delete'),
);
}
$options = array(
0 => t('More actions...'),
);
foreach (module_invoke_all('privatemsg_thread_operations') as $operation => $array) {
if (isset($array['label'])) {
$options[$operation] = $array['label'];
}
}
$form['operation'] = array(
'#type' => 'select',
'#options' => $options,
'#default_value' => 0,
);
$form['submit'] = array(
'#prefix' => '<div class="privatemsg-op-button">',
'#suffix' => '</div>',
'#type' => 'submit',
'#value' => t('Execute'),
'#submit' => array(
'privatemsg_list_submit',
),
'#attributes' => array(
'class' => 'privatemsg-action-button',
),
);
drupal_add_js(drupal_get_path('module', 'privatemsg') . '/privatemsg-list.js');
return $form;
}
function privatemsg_thread_change_status($threads, $status, $account = NULL) {
if (!is_array($threads)) {
$threads = array(
$threads,
);
}
if (empty($account)) {
global $user;
$account = drupal_clone($user);
}
$params = array_merge(array(
$status,
$account->uid,
), $threads);
db_query('UPDATE {pm_index} SET is_new = %d WHERE uid = %d AND thread_id IN (' . db_placeholders($threads) . ')', $params);
if ($status == PRIVATEMSG_UNREAD) {
drupal_set_message(format_plural(count($threads), 'Marked 1 thread as unread.', 'Marked @count threads as unread.'));
}
else {
drupal_set_message(format_plural(count($threads), 'Marked 1 thread as read.', 'Marked @count threads as read.'));
}
}
function _privatemsg_list_headers($has_posts, $keys) {
$select_header = $has_posts ? theme('table_select_header_cell') : '';
$select_header['#weight'] = -50;
include_once drupal_get_path('module', 'privatemsg') . '/privatemsg.theme.inc';
$header = array(
$select_header,
);
foreach ($keys as $key) {
if ($return = theme(array(
'privatemsg_list_header__' . $key,
'privatemsg_list_header',
))) {
$header[$key] = $return;
}
}
if (count($header) == 1) {
$header += _privatemsg_list_headers_fallback($keys);
}
return $header;
}
function _privatemsg_list_headers_fallback($keys) {
$header = array();
foreach ($keys as $key) {
$theme_function = 'phptemplate_privatemsg_list_header__' . $key;
if (function_exists($theme_function)) {
$header[$key] = $theme_function();
}
}
return $header;
}
function _privatemsg_list_thread($thread) {
$row = array(
'data' => array(),
);
if (!empty($thread['is_new'])) {
$row['class'] = 'privatemsg-unread';
}
foreach ($thread as $key => $data) {
if ($return = theme(array(
'privatemsg_list_field__' . $key,
'privatemsg_list_field',
), $thread)) {
$row['data'][$key] = $return;
}
}
if (empty($row['data'])) {
$row['data'] = _privatemsg_list_thread_fallback($thread);
}
return $row;
}
function _privatemsg_list_thread_fallback($thread) {
$row_data = array();
foreach ($thread as $key => $data) {
$theme_function = 'phptemplate_privatemsg_list_field__' . $key;
if (function_exists($theme_function)) {
$row_data[$key] = $theme_function($thread);
}
}
return $row_data;
}
function privatemsg_undo_action() {
if (isset($_SESSION['privatemsg']['undo callback']) && is_array($_SESSION['privatemsg']['undo callback'])) {
$undo = $_SESSION['privatemsg']['undo callback'];
if (isset($undo['function']) && isset($undo['args'])) {
if (isset($undo['args']['account']) && $undo['args']['account'] > 0) {
$undo['args']['account'] = user_load((int) $undo['args']['account']);
}
call_user_func_array($undo['function'], $undo['args']);
}
drupal_goto();
}
}
function privatemsg_list_submit($form, &$form_state) {
$operations = module_invoke_all('privatemsg_thread_operations');
$operation = array(
'callback' => 0,
);
if (isset($form_state['values']['operation']) && isset($operations[$form_state['values']['operation']])) {
$operation = $operations[$form_state['values']['operation']];
}
$keys = array_keys($form_state['values'], $form_state['values']['op']);
if (isset($keys[1]) && isset($operations[$keys[1]])) {
$operation = $operations[$keys[1]];
}
if (!empty($operation['callback'])) {
privatemsg_operation_execute($operation, $form_state['values']['threads'], $form_state['values']['account']);
}
}
function privatemsg_operation_execute($operation, $threads, $account = null) {
$threads = array_filter($threads);
if (empty($threads)) {
return;
}
if (isset($operation['callback arguments'])) {
$args = array_merge(array(
$threads,
), $operation['callback arguments']);
}
else {
$args = array(
$threads,
);
}
if ($account) {
$args[] = $account;
}
call_user_func_array($operation['callback'], $args);
if (isset($operation['undo callback']) && ($undo_function = $operation['undo callback'])) {
if (isset($operation['undo callback arguments'])) {
$undo_args = array_merge(array(
$threads,
), $operation['undo callback arguments']);
}
else {
$undo_args = array(
$threads,
);
}
if ($account) {
$undo_args['account'] = $account->uid;
}
$_SESSION['privatemsg']['undo callback'] = array(
'function' => $undo_function,
'args' => $undo_args,
);
$undo = url('messages/undo/action', array(
'query' => drupal_get_destination(),
));
drupal_set_message(t('The previous action can be <a href="!undo">undone</a>.', array(
'!undo' => $undo,
)));
}
}
function privatemsg_thread_change_delete($threads, $delete, $account = NULL) {
if (!is_array($threads)) {
$threads = array(
$threads,
);
}
if (empty($account)) {
global $user;
$account = drupal_clone($user);
}
$params = array_merge(array(
$delete,
$account->uid,
), $threads);
$query = _privatemsg_assemble_query('messages', $threads, $account, TRUE);
$result = db_query($query['query']);
while ($row = db_fetch_array($result)) {
privatemsg_message_change_delete($row['mid'], $delete, $account);
}
if ($delete) {
drupal_set_message(format_plural(count($threads), 'Deleted 1 thread.', 'Deleted @count threads.'));
}
else {
drupal_set_message(format_plural(count($threads), 'Restored 1 thread.', 'Restored @count threads.'));
}
}
function privatemsg_privatemsg_thread_operations() {
$operations = array(
'mark as read' => array(
'label' => t('Mark as read'),
'callback' => 'privatemsg_thread_change_status',
'callback arguments' => array(
'status' => PRIVATEMSG_READ,
),
'undo callback' => 'privatemsg_thread_change_status',
'undo callback arguments' => array(
'status' => PRIVATEMSG_UNREAD,
),
),
'mark as unread' => array(
'label' => t('Mark as unread'),
'callback' => 'privatemsg_thread_change_status',
'callback arguments' => array(
'status' => PRIVATEMSG_UNREAD,
),
'undo callback' => 'privatemsg_thread_change_status',
'undo callback arguments' => array(
'status' => PRIVATEMSG_READ,
),
),
);
if (privatemsg_user_access('delete privatemsg')) {
$operations['delete'] = array(
'callback' => 'privatemsg_thread_change_delete',
'callback arguments' => array(
'delete' => 1,
),
'undo callback' => 'privatemsg_thread_change_delete',
'undo callback arguments' => array(
'delete' => 0,
),
);
}
return $operations;
}
function privatemsg_views_api() {
return array(
'api' => 2,
'path' => drupal_get_path('module', 'privatemsg') . '/views',
);
}