Newer
Older
<?php
// $Id$
/**
* @file
* Allows users to send private messages to other users.
*/
function privatemsg_perm() {
return array(
'read privatemsg',
'read all private messages',
function _privatemsg_generate_user_array($userstring) {
static $user_cache = array();
$users = array_slice(explode(',', $userstring), -4);
$participants = array();
foreach ($users as $user) {
if (isset($user_cache[$user])) {
$participants[$user] = $user_cache[$user];
}
else {
$participants[$user] = $user_cache[$user] = user_load($user);
}
}
return $participants;
}
function _privatemsg_format_participants($part_array, $limit = 20, $no_text = FALSE) {
if (count($part_array) > 0) {
$limited = FALSE;
foreach ($part_array as $account) {
if (count($to) >= $limit) {
}
$limit_string = '';
if ($limited) {
$limit_string = t(' and others');
}
return implode(', ', $to) . $limit_string;
}
$last = array_pop($to);
if (count($to) == 0) { // Only one participant
return t("From !last", array('!last' => $last));
}
else { // Multipe participants..
$participants = implode(', ', $to);
return t('Participants: !participants and !last', array('!participants' => $participants, '!last' => $last));
}
}
return '';
}
$items['messages'] = array(
'title' => 'Messages',
'title callback' => 'privatemsg_title_callback',
'page callback' => 'privatemsg_list',
'access callback' => 'privatemsg_user_access',
$items['messages/inbox'] = array(
'title' => 'All messages',
'page callback' => 'privatemsg_list',
'access callback' => 'privatemsg_user_access',
'type' => MENU_DEFAULT_LOCAL_TASK,
'weight' => -10,
$items['messages/mark-read'] = array(
'title' => 'Mark all as read',
'page callback' => 'privatemsg_set_new_status',
'page arguments' => array(NULL, NULL, 0, TRUE),
'access callback' => 'privatemsg_unread_count',
'type' => MENU_NORMAL_ITEM,
'weight' => -9,
);
$items['messages/sent'] = array(
'title' => 'Sent messages',
'page callback' => 'privatemsg_list',
'access callback' => 'privatemsg_user_access',
$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,
$items['messages/delete/%'] = array(
'title' => 'Delete message',
'page callback' => 'drupal_get_form',
'page arguments' => array('privatemsg_delete', 2),
'access callback' => 'privatemsg_user_access',
'type' => MENU_CALLBACK,
'weight' => -10,
);
$items['messages/new'] = array(
'title' => 'Write new message',
'page callback' => 'drupal_get_form',
'page arguments' => array('privatemsg_new', 2),
'access callback' => 'privatemsg_user_access',
'access arguments' => array('write privatemsg'),
'type' => MENU_LOCAL_TASK,
'weight' => -7,
);
// Auto-completes available user names & removes duplicates.
$items['messages/user-name-autocomplete'] = array(
'page callback' => 'privatemsg_user_name_autocomplete',
'access callback' => 'privatemsg_user_access',
'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,
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
/**
* Privatemsg access wrapper for user_callback
*
* Never allows anonymous user access as that doesn't makes sense
*
* @param string $permission Permission string, defaults to read privatemsg
*
* @return boolean TRUE if user has access, FALSE if not
*/
function privatemsg_user_access($permission = 'read privatemsg', $account = NULL) {
if ( $account === NULL ) {
global $user;
$account = $user;
}
if (!$account->uid) { // Disallow anonymous access, regardless of permissions
return FALSE;
}
if (!user_access($permission, $account)) {
return FALSE;
}
return TRUE;
}
/**
* Function to restrict the access of the view messages page to just the messages/view/%
* pages and not to leave tabs artifact on other lower level pages
* such as the messages/new/%
*/
function privatemsg_view_access() {
if (privatemsg_user_access('read privatemsg') && arg(1) == 'view') {
return TRUE;
}
return FALSE;
}
/**
* This function is called by the menu system through the %privatemsg_thread wildcard
*
* TODO: Really load the full thread in here
*/
function privatemsg_thread_load($thread_id) {
if ((int)$thread_id > 0) {
return $thread_id;
}
return FALSE;
}
function private_message_view_options() {
$options = module_invoke_all('privatemsg_view_template');
return $options;
* Implementation of hook_privatemsg_view_template().
*
* Allows modules to define different message view template.
*
* This hook returns information about available themes for privatemsg viewing.
*
* array(
* 'machine_template_name' => 'Human readable template name',
* 'machine_template_name_2' => 'Human readable template name 2'
* };
*/
function privatemsg_privatemsg_view_template() {
return array(
function private_message_settings() {
$form = 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_per_page'] = array(
'#type' => 'select',
'#title' => t('Messages 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_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['#submit'][] = 'private_message_settings_submit';
return system_settings_form($form);
}
function private_message_settings_submit() {
drupal_rebuild_theme_registry();
}
function privatemsg_theme() {
return array(
'privatemsg_view' => array(
'arguments' => array('message' => NULL),
'template' => variable_get('private_message_view_template', 'privatemsg-view'),//'privatemsg',
'arguments' => array('author' => NULL),
'template' => 'privatemsg-from',
'privatemsg_to' => array(
'arguments' => array('message' => NULL),
'template' => 'privatemsg-recipients',
'privatemsg_between' => array(
'arguments' => array('recipients' => NULL),
'template' => 'privatemsg-between',
),
'privatemsg_message_row' => array(
'arguments' => array('row'),
'privatemsg_new_block' => array(
'arguments' => array('count'),
),
function privatemsg_preprocess_privatemsg_view(&$vars) {
// drupal_set_message('<pre>'. print_r($vars,1 ) . '</pre>');
$vars['mid'] = isset($message['mid']) ? $message['mid']:null;
$vars['author_picture'] = theme('user_picture', $message['author']);
$vars['author_name_link'] = theme('username', $message['author']);
/**
* @todo perhaps make this timestamp configurable via admin UI?
*/
$vars['message_timestamp'] = format_date($message['timestamp'], 'small');
$vars['message_body'] = check_markup($message['body']);
litwol
committed
if (isset($vars['mid'])) {
litwol
committed
$vars['message_actions'][] = array('title' => t('Delete message'), 'href' => 'messages/delete/'. $vars['mid']);
litwol
committed
// call hook_privatemsg_message_view_alter
drupal_alter('privatemsg_message_view', $vars);
litwol
committed
$vars['message_actions'] = !empty($vars['message_actions']) ? theme('links', $vars['message_actions'], array('class' => 'message-actions')) : '';
Marco Molinari
committed
}
function privatemsg_preprocess_privatemsg_to(&$vars) {
$vars['participants'] = '';//assign a default empty value
if (isset($vars['message']['participants'])) {
$vars['participants'] = _privatemsg_format_participants($vars['message']['participants']);
Marco Molinari
committed
}
}
if (is_int($uid) && $uid != $user->uid) {
// Trying to view someone else's messages...
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))) {
// Has rights and user_load return an array so user does exist
$account = $account_check;
}
// By this point we have figured out for which user we are listing messages and now it is safe to use $account->uid in the listing query.
$content = array();
$content['list']['content'] = privatemsg_list_messages($account);
$content['list']['#weight'] = 0;
drupal_alter('privatemsg_list_messages', $content, $account);
uasort($content, 'element_sort');
$expand = '';
foreach ($content as $element) {
$expand .= $element['content'];
}
return $expand;
}
/**
* Display the list of messages for a given user, called by privatemsg_privatemsg_alter
*/
function privatemsg_list_messages($account) {
switch (arg(1)) {
case 'sent':
$query = _privatemsg_assemble_query('list_sent', $account);
$query = _privatemsg_assemble_query('list', $account);
}
$result = pager_query($query['query'], variable_get('privatemsg_per_page', 25), 0, $query['count']);
$rows = array();
while ($thread = db_fetch_array($result)) {
$rows[] = theme('privatemsg_message_row', $thread);
}
$content = '';
if (!empty($rows)) {
$head = array();
foreach (array_keys($rows[0]) as $index) {
$head[$index] = array('data' => $index);
if ($index == t('Last updated') || $index == t('Subject')) {
$head[$index] += array('field' => $index, 'sort' => 'desc');
$content = theme('table', $head, $rows);
$content .= theme('pager');
drupal_add_css(drupal_get_path('module', 'privatemsg') .'/styles/privatemsg-list.css');
}
else {
drupal_set_message(t('No messages to display.'));
function theme_privatemsg_new_block($count) {
$text = format_plural($count, 'You have a new message, click here to read it',
'You have @count new messages, click here to read them',
array('@count' => $count));
return l($text, 'messages', array('attributes' => array('id' => 'privatemsg-new-link')));
}
$unread = '';
if (isset($row['is_new']) && $row['is_new'] ) {
$unread = ' privatemsg-unread';
}
$themed_row[t('Subject')] = '<span class="privatemsg-list-subject'. $unread .'">'. l($row['subject'], 'messages/view/'. $row['thread_id']) .'</span>';
$authors = _privatemsg_generate_user_array($row['author']);
$themed_row[t('Authors')] = '<span class="privatemsg-list-from'. $unread .'">'. _privatemsg_format_participants($authors, 3, TRUE) .'</span>';
if (array_key_exists('recipient', $row)) {
if (!empty($row['recipient'])) {
$recipients = _privatemsg_generate_user_array($row['recipient']);
$themed_row[t('Recipients')] = '<span class="privatemsg-list-to'. $unread .'">'. _privatemsg_format_participants($recipients, 3, TRUE) .'</span>';
}
// drupal_set_message('<pre>'. print_r($row, 1) . '</pre>');
if ($row['last_updated']) {
$themed_row[t('Last updated')] = '<span class="privatemsg-list-date'. $unread .'">'. format_date($row['last_updated'], 'small') .'</span>';
}
/**
* API function
*
* Sets a single message as read for a user.
*/
function privatemsg_mark_as_read($pmid, $account) {
$query = "UPDATE {pm_index} SET is_new = 0 WHERE mid = %d AND recipient = %d";
db_query($query, $pmid, $account->uid);
}
/**
* API function
*
* Return number of unread messages for an account.
*/
function privatemsg_unread_count($account = NULL) {
static $counts = array();
if (!$account || $account->uid == 0) {
global $user;
$query = _privatemsg_assemble_query('unread_count', $account);
$counts[$account->uid] = db_result(db_query($query['query']));
}
return $counts[$account->uid];
}
/**
* API function
*
* Change status of one or ALL messages to read / unread.
*/
function privatemsg_set_new_status($account = NULL, $mid = NULL, $new = 0, $verbose = FALSE) {
if (!$account || 0 == $account->uid) {
global $user;
$account = $user;
}
$query = "UPDATE {pm_index} SET is_new = %d WHERE uid = %d AND is_new = %d";
$arg[] = $new;
$arg[] = $account->uid;
$arg[] = ($new == 0) ? 1 : 0;
if ($mid) {
$query .= " AND mid = %d";
$arg[] = $mid;
}
$result = db_query($query, $arg) ;
if ($verbose) {
if ($result) {
if ($new == 1) {
$status = t('unread');
}
else {
$status = t('read');
}
$total_marked = db_affected_rows();
drupal_set_message(format_plural($total_marked, "1 message marked as %status", '@count messages marked as %status', array('%status' => $status)));
else {
drupal_set_message(t('An error has occured, please contact the site administrator.'), 'error');
function privatemsg_view($thread_id) {
global $user;
$output = '';
$query = _privatemsg_assemble_query('participants', $thread_id);
$participants = db_query($query['query']);
while ($result = db_fetch_object($participants)) {
$message['participants'][] = user_load($result->uid);
}
$content['participants']['content'] = theme('privatemsg_to', $message);
$content['participants']['#weight'] = -5;
// Load the messages.
litwol
committed
$query = _privatemsg_assemble_query('messages', $thread_id, $user);
$conversation = db_query($query['query']);
$message_count = 0;
while ($result = db_fetch_array($conversation)) {
$pmid = $result['mid'];
litwol
committed
$message = _privatemsg_load($pmid, $user);
privatemsg_set_new_status($user, $pmid);
$message['author'] = user_load($message['author']);
// Some tasks only need to be done once - on the first message of a thread.
if ($message_count == 0) {
// Set the page title to the message subject.
drupal_set_title(check_plain($message['subject']));
if ($message_count == 0) {
drupal_set_message(t('There are no messages available to display.'), 'error');
}
$content['messages']['content'] = $output;
$content['messages']['#weight'] = 0;
if ($message_count > 0) {
$content['reply']['content'] = drupal_get_form('privatemsg_new');
$content['reply']['#weight'] = 5;
}
//allow other modules to hook into the $content array and alter it
drupal_alter('privatemsg_view_messages', $content, $message_count);
uasort($content, 'element_sort');
$expand = '';
foreach ($content as $element) {
$expand .= $element['content'];
}
return $expand;
Marco Molinari
committed
}
function privatemsg_new(&$form_state, $account = NULL) {
Marco Molinari
committed
global $user;
$recipient = '';
$subject = '';
$body = '';
if ((int)$account > 0 && $account = user_load($account)) {
$recipient = $form_state['values']['recipient'];
$subject = $form_state['values']['subject'];
$body = $form_state['values']['body'];
Marco Molinari
committed
$form = array();
if (isset($form_state['privatemsg_preview'])) {
$form['message_header'] = array(
'#type' => 'fieldset',
);
$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,
'#type' => 'textfield',
'#title' => t('To'),
'#description' => t('Separate multiple names with commas.'),
'#default_value' => $recipient,//populate this later
litwol
committed
'#weight' => -10,
'#autocomplete_path' => 'messages/user-name-autocomplete',
// Do not hardcode #maxlength, make it configurable by number of recipients, not their name length.
'#type' => 'textfield',
'#title' => t('Subject'),
'#size' => 50,
'#maxlength' => 255,
'#default_value' => $subject,
litwol
committed
'#weight' => -5,
'#type' => 'textarea',
'#title' => t('Message'),
'#cols' => 10,
'#rows' => 6,
litwol
committed
'#weight' => 0,
litwol
committed
'#weight' => 10,
litwol
committed
'#weight' => 15,
$url = 'messages';
if (isset($_REQUEST['destination'])) {
$url = $_REQUEST['destination'];
}
'#value' => l(t('Cancel'), $url, array('attributes' => array('id' => 'edit-cancel'))),
litwol
committed
'#weight' => 20,
litwol
committed
//modules can store data here, everything stored here will be available
//in $message, similar to #node
}
// drupal_set_message('<pre>'. print_r($form_state['values'], 1) . '</pre>');
// The actual message that is being sent, we create this during validation and pass to submit to send out.
$message = array();
litwol
committed
$message['body'] = $form_state['values']['body'];
$message['subject'] = $form_state['values']['subject'];
$message['author'] = $form_state['values']['author'];
if (isset($form_state['values']['thread_id']) && $form_state['values']['thread_id']) {
$message['thread_id'] = $form_state['values']['thread_id'];
}
$trimed_body = trim(truncate_utf8(strip_tags($message['body']), 50, TRUE, TRUE));
if (empty($message['subject']) && !empty($trimed_body)) {
$message['subject'] = $trimed_body;
}
// Verify that recipient's name syntax is correct.
$fragments = explode(',', $form_state['values']['recipient']);
$invalid = array();
$valid = array();
foreach ($fragments as $index => $name) {
$name = trim($name);
if (!empty($name)) { // We don't care about white space names.
if (empty($name) || $error = module_invoke('user', 'validate_name', $name)) {
// These names are invalid due to incorrect user name syntax.
$valid[$name] = $name; // These are valid only due to user name syntax. We still need to check if the user exists and accepts messages.
// Verify users exist and load their accounts.
foreach ($valid as $index => $name) {
if ($recipient = user_load(array('name' => $name))) {
litwol
committed
$message['recipients'][$recipient->uid] = $recipient;
// Here we add more invalid names due to the fact that they don't exist.
* 1) Make sure the name exists.
* 2) Make sure he accepts private messages.
* 3) Make sure the sender is not on block list of the recipient.
* 1) Names that were not valid from previous step will be stripped out.
* 2) Names that remain will be put into a recipients array.
litwol
committed
$errors = _privatemsg_validate_message($message, $message['author'], TRUE);
if (!empty($errors)) {
foreach ($errors as $error) {
form_set_error('body', $error);
}
}
$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');
$form_state['values']['recipient'] = implode(', ', array_diff($valid, $invalid));
litwol
committed
if (_privatemsg_send($form_state['validate_built_message'])) {
drupal_set_message(t('A message has been sent to @recipients.', array('@recipients' => $form_state['values']['recipient'])));
drupal_validate_form($form['form_id']['#value'], $form, $form_state);
if (!form_get_errors()) {
// drupal_set_message('<pre>'. print_r($form, 1) .' </pre>');;
//TODO: Generate message preview here.
$form_state['privatemsg_preview'] = theme('privatemsg_view', $form_state['validate_built_message']);
$form_state['rebuild'] = TRUE; //this forces our form to be rebuilt instead of being submitted.
function privatemsg_sql_list_sent(&$fragments, $account) {
$fragments['primary_table'] = '{pm_message} pm';
if ($GLOBALS['db_type'] == 'pgsql') {
$fragments['select'][] = "array_to_string(array(SELECT DISTINCT textin(int4out(pmia.uid))
FROM {pm_index} pmia
WHERE pmia.thread_id = pmi.thread_id AND pmia.uid <> %d), ',') AS recipient";
}
else {
$fragments['select'][] = '(SELECT GROUP_CONCAT(DISTINCT pmia.uid SEPARATOR ",")
FROM {pm_index} pmia
WHERE pmia.thread_id = pmi.thread_id AND pmia.uid <> %d) AS recipient';
}
$fragments['query_args'][] = $account->uid;
$fragments['select'][] = 'MAX(pm.timestamp) as last_updated';
$fragments['inner_join'][] = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
$fragments['where'][] = 'pmi.uid = %d';
$fragments['query_args'][] = $account->uid;
$fragments['where'][] = 'pm.author = %d';
$fragments['query_args'][] = $account->uid;
$fragments['where'][] = 'pmi.deleted = 0';
$fragments['group_by'][] = 'pmi.thread_id';
$fragments['group_by'][] = 'pm.subject';
$order = 'last_updated';
$sort = 'desc';
if (isset($_GET['order'])) {
switch ($_GET['order']) {
$order = 'subject';
break;
}
$sort = isset($_GET['sort']) && ($_GET['sort'] == 'asc' || $_GET['sort'] == 'desc') ? $_GET['sort'] : 'desc';
}
$fragments['order_by'][] = $order .' '. $sort;
function privatemsg_sql_list(&$fragments, $account) {
$fragments['select'][] = 'pmi.thread_id';
$fragments['select'][] = 'MIN(pm.subject) as subject';
$fragments['select'][] = 'COUNT(pmi.thread_id) as count';
if ($GLOBALS['db_type'] == 'pgsql') {
$fragments['select'][] = "array_to_string(array(SELECT DISTINCT textin(int4out(pma.author))
FROM {pm_message} pma
INNER JOIN pm_index pmia ON pma.mid = pmia.mid
WHERE pmia.thread_id = pmi.thread_id),',') AS author";
}
else {
$fragments['select'][] = 'GROUP_CONCAT(DISTINCT author SEPARATOR ",") as author';
}
$fragments['select'][] = 'MAX(pm.timestamp) as last_updated';
$fragments['select'][] = 'MIN(pm.timestamp) as thread_started';
$fragments['select'][] = 'MAX(pmi.is_new) as is_new';
// pm_index needs to be the first join.
$fragments['inner_join'][] = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
$fragments['where'][] = 'pmi.uid = %d';
$fragments['query_args'][] = $account->uid;
$fragments['where'][] = 'pmi.deleted = 0';
$fragments['group_by'][] = 'pmi.thread_id';
$order = 'is_new';
$sort = 'desc';
if (isset($_GET['order'])) {
switch ($_GET['order']) {
case t('Subject'): // Allows translated headers to be sorted
$order = 'subject';
break;
default:
}
$sort = isset($_GET['sort']) && ($_GET['sort'] == 'asc' || $_GET['sort'] == 'desc') ? $_GET['sort'] : 'desc';
$fragments['order_by'][] = $order .' '. $sort .', last_updated DESC';
litwol
committed
function privatemsg_sql_load(&$fragments, $pmid, $account) {
// drupal_set_message('<pre>'. print_r(func_get_args(), 1) . '</pre>');
$fragments['primary_table'] = '{pm_message} pm'; // Our primary table
$fragments['select'][] = "pm.mid";
$fragments['select'][] = "pm.author";
$fragments['select'][] = "pm.subject";
$fragments['select'][] = "pm.body";
$fragments['select'][] = "pm.timestamp";
$fragments['select'][] = "pmi.is_new";
$fragments['inner_join'][] = 'INNER JOIN {pm_index} pmi ON pm.mid = pmi.mid';
$fragments['where'][] = 'pmi.mid = %d';
litwol
committed
$fragments['query_args'][] = $account->uid;
litwol
committed
function privatemsg_sql_messages(&$fragments, $thread_id, $account) {
$fragments['primary_table'] = '{pm_index} pmi';
$fragments['select'][] = 'DISTINCT(pmi.mid) as mid';
$fragments['where'][] = 'pmi.thread_id = %d';
$fragments['query_args'][] = $thread_id;
$fragments['where'][] = 'pmi.uid = %d';
litwol
committed
$fragments['query_args'][] = $account->uid;
$fragments['where'][] = 'pmi.deleted = 0';
$fragments['order_by'][] = 'pmi.mid ASC';
function privatemsg_sql_participants(&$fragments, $thread_id) {
$fragments['select'][] = 'DISTINCT(pmi.uid) as uid';
$fragments['where'][] = 'pmi.thread_id = %d';
$fragments['query_args'][] = $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'][] = $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'][] = $search. '%%';
if (!empty($names)) {
$fragments['where'][] = "u.name NOT IN (". db_placeholders($names, 'text') .")";
$fragments['query_args'] += $names;
}
$fragments['where'][] = 'u.status <> 0';
$fragments['order_by'][] = 'u.name ASC';
}
/**
* Return autocomplete results for usernames.
* Prevents usernames from being used and/or suggested twice.
*/
function privatemsg_user_name_autocomplete($string) {
$names = array();
// 1: Parse $string and build list of valid user names.
$fragments = explode(',', $string);
foreach ($fragments as $index => $name) {
$name = trim($name);
if ($error = module_invoke('user', 'validate_name', $name)) {
}
else {
$names[$name] = $name;
}
}
// By using user_validate_user we can ensure that names included in $names are at least logisticaly possible.
// 2: Find the next user name suggestion.
$fragment = array_pop($names);
if (!empty($fragment)) {
$query = _privatemsg_assemble_query('autocomplete', $fragment, $names);
$result = db_query_range($query['query'], $fragment, 0, 10);
$prefix = count($names) ? implode(", ", $names) .", " : '';
// 3: Build proper suggestions and print.
$matches = array();
while ($user = db_fetch_object($result)) {
drupal_json($matches);
litwol
committed
else {
drupal_json(array()); //prevents auto-complete js error on empty
}
function privatemsg_user($op, &$edit, &$account, $category = NULL) {
global $user;
switch ($op) {
case 'view':
litwol
committed
if ($url = privatemsg_get_link($account)) {
$account->content['privatemsg_send_new_message'] = array(
'#type' => 'markup',
litwol
committed
'#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(t('You have <a href="@inbox">%unread</a>.', array('@inbox' => url('messages/inbox'), '%unread' => format_plural($count, '1 unread message', '@count unread messages'))));
}
}
break;
}
}
function privatemsg_block($op = 'list', $delta = 0, $edit = array()) {
if ('list' == $op) {
$blocks = array();
$blocks['privatemsg-menu'] = array(
'info' => t('Privatemsg links'),
);
$blocks['privatemsg-new'] = array(
'info' => t('New message indication'),
'cache' => BLOCK_CACHE_PER_USER,
);
return $blocks;
}
else if ('view' == $op) {
$block = array();
switch ($delta) {
case 'privatemsg-menu':
$block = _privatemsg_block_menu();
break;
case 'privatemsg-new':
$block = _privatemsg_block_new();
break;
function privatemsg_title_callback($title = NULL) {
if ($count > 0) {
return format_plural($count, 'Messages (@count 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();