Skip to content
privatemsg.module 30.7 KiB
Newer Older
Marco Molinari's avatar
Marco Molinari committed
// $Id$
define('PRIVATEMSG_MAIL_NONE', 0);
define('PRIVATEMSG_MAIL_DIGEST', 1);
define('PRIVATEMSG_MAIL_INDIVIDUAL', 2);
Marco Molinari's avatar
Marco Molinari committed

/**
 * Implementation of hook_help().
 */
function privatemsg_help($section) {
  switch ($section) {
    case 'admin/help#privatemsg':
      $output = '<p>'. t('The private messaging module allows users to send messages to each other without having to share email addresses. An inbox link will appear in the navigation menu. The "write to author" links are included in posts, allowing users to write a private message instead of commenting openly.  Allowing users to communicate directly is an important  part of building the strength of the community.') .'</p>';
      $output .= '<p>'. t('Users can also select whether to receive email notices of new messages by editing their user profile.  The contacts list contains only users that you have previously messaged. To contact users not in your list, you need to know their local user name.  Administrators can set messaging options such as frequency of emails, message status display, and number of messages to display per page.   They can also configure \'Write to Author\' options.') .'</p>';
      $output .= t('<p>You can</p>
<ul>
<li>administer privatemsg at <a href="%admin-settings-privatemsg">administer &gt;&gt; settings &gt;&gt; private message</a>.</li>
<li>view your private messages at <a href="%privatemsg">view inbox</a>.</li>
', array('%admin-settings-privatemsg' => url('admin/settings/privatemsg'), '%privatemsg' => url('privatemsg'))) .'</ul>';
      $output .= '<p>'. t('For more information please read the configuration and customization handbook <a href="%privatemsg">Privatemsg page</a>.', array('%privatemsg' => 'http://drupal.org/handbook/modules/privatemsg/')) .'</p>';
      return $output;
    case 'admin/modules#description':
      return t('Allows private messages between users.');
Marco Molinari's avatar
Marco Molinari committed
}

/**
 * Implementation of hook_link().
 */
function privatemsg_link($type, $node = 0, $main = 0) {
  global $user;
  static $access = array();
  if (user_access('access private messages') && ($type == 'node' || $type == 'comment') && variable_get("privatemsg_link_$type", 0) && (isset($user->privatemsg_allow) ? $user->privatemsg_allow : 1)) {
    if (!isset($access[$node->uid])) {
      $author = user_load(array('uid' => $node->uid));
      $access[$node->uid] = user_access('access private messages', $author) && $author->uid && (isset($author->privatemsg_allow) ? $author->privatemsg_allow : 1);
      return array(l(t('write to author'), 'privatemsg/msgto/'. $node->uid));
/**
 * Implementation of hook_menu().
 */
Tom Dobes's avatar
Tom Dobes committed
function privatemsg_menu($may_cache) {
  global $user;
Tom Dobes's avatar
Tom Dobes committed

Neil Drumm's avatar
Neil Drumm committed
  if ($may_cache) {
    $items[] = array('path' => 'admin/settings/privatemsg',
                     'title' => 'privatemsg',
                     'callback' => 'privatemsg_configure');
    $items[] = array('path' => 'privatemsg/new',
                     'title' => t('Write a new message'),
                     'callback' => 'privatemsg_new',
                     'type' => MENU_CALLBACK);
    $items[] = array('path' => 'privatemsg/reply',
                     'title' => t('Write a new message'),
                     'callback' => 'privatemsg_new',
                     'type' => MENU_CALLBACK);
    $items[] = array('path' => 'privatemsg/msgto',
                     'title' => t('Write a new message'),
                     'callback' => 'privatemsg_new',
                     'type' => MENU_CALLBACK);
    $items[] = array('path' => 'privatemsg/autocomplete',
                     'title' => t('privatemsg autocomplete'),
                     'callback' => 'privatemsg_autocomplete',
                     'type' => MENU_CALLBACK);
    $items[] = array('path' => 'privatemsg/view',
                     'title' => t('Read message'),
                     'callback' => 'privatemsg_view',
                     'access' => $user->uid, // No guest access
                     'type' => MENU_CALLBACK);
    $items[] = array('path' => 'privatemsg/newfolder',
                     'title' => t('Create new folder'),
                     'callback' => 'privatemsg_new_folder',
                     'access' => $user->uid, // No guest access
                     'type' => MENU_CALLBACK);
    $items[] = array('path' => 'privatemsg/delete',
                     'callback' => 'privatemsg_delete',
                     'access' => $user->uid, // No guest access
                     'type' => MENU_CALLBACK);
Neil Drumm's avatar
Neil Drumm committed
  }
  else {
    $new = (int)_privatemsg_get_new_messages();
Tom Dobes's avatar
Tom Dobes committed
    $items[] = array('path' => 'privatemsg',
                     'title' => t('my inbox') . ($new ? ' ('. $new .')' : ''),
                     'callback' => 'privatemsg_list',
                     'access' => user_access('access private messages'),
                     'type' => $user->uid && (isset($user->privatemsg_allow) ? $user->privatemsg_allow : 1) ? MENU_DYNAMIC_ITEM : MENU_CALLBACK);

    if ($new && (isset($user->privatemsg_setmessage_notify) ? $user->privatemsg_setmessage_notify : 1)) {
      $m = drupal_set_message();
      if (empty($m)) {
        drupal_set_message(strtr(format_plural($new, 'You have one new <a href="%url">private message</a>', 'You have %count new <a href="%url">private messages</a>'), array('%url' => url('privatemsg'))));
      }
Tom Dobes's avatar
Tom Dobes committed
  }
James Walker's avatar
James Walker committed
  return $items;
}

/**
 * Implementation of hook_user().
 */
Neil Drumm's avatar
Neil Drumm committed
function privatemsg_user($type, &$edit, &$user, $category = NULL) {
  switch ($type) {
    case 'view':
Tom Dobes's avatar
Tom Dobes committed
      if (user_access('access private messages') && (isset($user->privatemsg_allow) ? $user->privatemsg_allow : 1)) {
        return array(t('Private messages') => array(array(
          'value' => l(t('send private message'), 'privatemsg/msgto/'. $user->uid),
          'class' => 'send-message')));
      }
      else if ($GLOBALS['user']->uid) {
        return;
      }
      else if (isset($user->privatemsg_allow) ? $user->privatemsg_allow : 1) {
        if (variable_get('user_register', 1)) {
          return array(t('Private messages') => array(array(
            'value' => t('<a href="%login">login</a> or <a href="%register">register</a> to send private messages to this user', array('%login' => url('user/login'), '%register' => url('user/register'))),
            'class' => 'need-login')));
          return array(t('Private messages') => array(array(
            'value' => t('<a href="%login">login</a> to send private messages to this user', array('%login' => url('user/login'))),
            'class' => 'need-login')));
Neil Drumm's avatar
Neil Drumm committed
      break;

    case 'form':
      if (user_access('access private messages') && $category == 'account') {
Neil Drumm's avatar
Neil Drumm committed
        $form = array();
        $form['privatemsg_settings'] = array(
            '#type' => 'fieldset',
            '#title' => t('Private message settings'),
            '#weight' => 4,
            '#collapsible' => TRUE
            );
        $form['privatemsg_settings']['privatemsg_allow'] = array(
            '#type' => 'checkbox',
            '#title' => t('Allow private messages'),
            '#default_value' => isset($edit['privatemsg_allow']) ? $edit['privatemsg_allow'] : 1,
            '#description' => t('Check this box to allow users to send you private messages.')
            );
        $form['privatemsg_settings']['privatemsg_setmessage_notify'] = array(
            '#type' => 'checkbox',
            '#title' => t('Aggressive notification of new messages'),
            '#default_value' => isset($edit['privatemsg_setmessage_notify']) ? $edit['privatemsg_setmessage_notify'] : 1,
            '#description' => t('Show status message on every page until new messages are read.')
            );
Neil Drumm's avatar
Neil Drumm committed
        $form['privatemsg_settings']['privatemsg_mailalert'] = array(
            '#type' => 'radios',
            '#title' => t('Receive e-mail for unread messages'),
            '#options' => array(PRIVATEMSG_MAIL_NONE => t('Never'), PRIVATEMSG_MAIL_DIGEST => t('Daily'), PRIVATEMSG_MAIL_INDIVIDUAL => t('Every message')),
            '#default_value' => isset($edit['privatemsg_mailalert']) ? $edit['privatemsg_mailalert'] : PRIVATEMSG_MAIL_NONE,
            '#description' => t('Select when to receive e-mail notification for unread messages.')
Neil Drumm's avatar
Neil Drumm committed
            );

        return $form;
Neil Drumm's avatar
Neil Drumm committed
      break;
Marco Molinari's avatar
Marco Molinari committed
  }
Kjartan Mannes's avatar
Kjartan Mannes committed
}
Neil Drumm's avatar
Neil Drumm committed
function privatemsg_configure() {
  $form = array();

  $form['privatemsg_max_rate'] = array(
      '#type' => 'select',
      '#title' => t('Private messaging max rate'),
      '#default_value' => variable_get('privatemsg_max_rate', 15),
      '#options' => drupal_map_assoc(array(5, 10, 15, 20, 30, 60), 'format_interval'),
      '#description' => t('Max submit rate for private messaging. To prevent abuse.')
      );
  $form['privatemsg_sent_status'] = array(
      '#type' => 'select',
      '#title' => t('Sent message status'),
      '#default_value' => variable_get('privatemsg_sent_status', 1),
      '#options' => array(t('Disabled'), t('Enabled')),
      '#description' => t('If enabled users can see whether a message has been read or not.')
      );
  $form['privatemsg_per_page'] = array(
      '#type' => 'select',
      '#title' => t('Messages per page'),
      '#default_value' => variable_get('privatemsg_per_page', 10),
      '#options' => drupal_map_assoc(array(5, 10, 15, 20, 25, 30, 35, 40, 50, 60, 80, 100)),
      '#description' => t('The maximum number of messages displayed per page; links to browse messages automatically appear.')
      );

  $form['links'] = array(
      '#type' => 'fieldset',
      '#title' => t('"Write to author" links')
      );
  $form['links']['privatemsg_link_node'] = array(
      '#type' => 'checkbox',
      '#title' => t('Display link with posts'),
      '#return_value' => 1,
      '#default_value' => variable_get('privatemsg_link_node', 0),
      '#description' => t('Provide a link to send private messages to users with posts they start.')
      );
  $form['links']['privatemsg_link_comment'] = array(
      '#type' => 'checkbox',
      '#title' => t('Display link with comments'),
      '#return_value' => 1,
      '#default_value' => variable_get('privatemsg_link_comment', 0),
      '#description' => t('Provide a link to send private messages to users with their comments.')
      );

  return system_settings_form('privatemsg_settings', $form);
/**
 * Implementation of hook_perm().
 */
Marco Molinari's avatar
Marco Molinari committed
function privatemsg_perm() {
Tom Dobes's avatar
Tom Dobes committed
  return array('access private messages');
Marco Molinari's avatar
Marco Molinari committed
}
/**
 * Implementation of hook_cron().
 */
Marco Molinari's avatar
Marco Molinari committed
function privatemsg_cron() {
  // perform these actions just once per day
Tom Dobes's avatar
Tom Dobes committed
  if (variable_get('privatemsg_last_cron', 0) < (time() - 3600*24)) {
Marco Molinari's avatar
Marco Molinari committed
    _privatemsg_prune();
    _privatemsg_mailalert();
Tom Dobes's avatar
Tom Dobes committed
    variable_set('privatemsg_last_cron', time());
Marco Molinari's avatar
Marco Molinari committed
function _privatemsg_prune() {
  // move deleted message older than 1 month to archive table, and optimize table
  $result = db_query('SELECT * FROM {privatemsg} WHERE author_del = 1 AND recipient_del = 1 AND timestamp < %d', time() - 3600*24*30);
Marco Molinari's avatar
Marco Molinari committed
  while ($message = db_fetch_object($result)) {
    db_query("INSERT INTO {privatemsg_archive} (id, author, recipient, subject, message, timestamp, hostname, format, folder) VALUES (%d, %d, %d, '%s', '%s', %d, '%s', %d, %d)", $message->id, $message->author, $message->recipient, $message->subject, $message->message, $message->timestamp, $message->hostname, $message->format, $message->folder);
    db_query('DELETE FROM {privatemsg} WHERE id = %d', $message->id);
Marco Molinari's avatar
Marco Molinari committed
  }
Marco Molinari's avatar
Marco Molinari committed
  // this is MySQL-specific
  if (!strncmp($GLOBALS['db_type'], 'mysql', 5)) {
    db_query('OPTIMIZE TABLE {privatemsg}');
Marco Molinari's avatar
Marco Molinari committed
}
Marco Molinari's avatar
Marco Molinari committed
function _privatemsg_mailalert() {
  $result = db_query('SELECT COUNT(*) AS c, recipient FROM {privatemsg} WHERE newmsg = 1 AND recipient_del = 0 GROUP BY recipient');
Marco Molinari's avatar
Marco Molinari committed
  while ($alert = db_fetch_object($result)) {
Tom Dobes's avatar
Tom Dobes committed
    $user = user_load(array('uid' => $alert->recipient));

    if ((isset($user->privatemsg_allow) ? $user->privatemsg_allow : 1) && isset($user->privatemsg_mailalert) && $user->privatemsg_mailalert == PRIVATEMSG_MAIL_DIGEST && $user->status != 0) {
      _privatemsg_sendmail($user, $alert->c);
    }
  }
}

function _privatemsg_sendmail($user, $new_count) {
  global $locale;
  static $from, $languages;
  if (!isset($from)) {
    $from = variable_get('site_mail', ini_get('sendmail_from'));
    $languages = array();
    if (function_exists('locale')) {
      $languages = locale_supported_languages();
      $languages = $languages['name'];
    }
  }
  $save_locale = $locale;

  // use each user's individual locale
  if (isset($languages[$user->language])) {
    $locale = $user->language;
  }
Tom Dobes's avatar
Tom Dobes committed

  $subject = t('New private messages at %site.', array('%site' => variable_get('site_name', 'drupal')));
  $message = strtr(format_plural($new_count, 'Hi %name,
This is an automatic reminder from the site %site. You have received a new private message.

To read your message, follow this link:
%link1

If you don\'t want to receive these emails again, change your preferences here:
%link2', 'Hi %name,
This is an automatic reminder from the site %site. You have %count unread private messages.

To read your messages, follow this link:
%link1

If you don\'t want to receive these emails again, change your preferences here:
%link2'), array('%name' => $user->name, '%site' => variable_get('site_name', 'drupal'), '%link1' => url('user/login', 'destination=privatemsg', NULL, 1), '%link2' => url('user/'. $user->uid .'/edit', NULL, NULL, 1)));
Tom Dobes's avatar
Tom Dobes committed

  user_mail($user->mail, $subject, $message, "From: $from\nReply-to: $from\nX-Mailer: Drupal\nReturn-path: $from\nErrors-to: $from");
Tom Dobes's avatar
Tom Dobes committed

  // revert to previous (site default) locale
  $locale = $save_locale;
}

function privatemsg_autocomplete($string) {
  $matches = array();
  $result = db_query_range("SELECT name FROM {users} u WHERE status <> 0 AND LOWER(name) LIKE LOWER('%s%%') AND data NOT LIKE '%\"privatemsg_allow\";s:0%'", $string, 0, 10);
  while ($user = db_fetch_object($result)) {
    $matches[$user->name] = check_plain($user->name);
Marco Molinari's avatar
Marco Molinari committed
  }
  print drupal_to_js($matches);
  exit();
  global $user;
  if (!$user->uid || !(isset($user->privatemsg_allow) ? $user->privatemsg_allow : 1)) {
    // If guests have privatemsg access they can only send messages
    return drupal_access_denied();
  }
  drupal_set_title(t('Private messages'));
  $current_folder = arg(2);
  if ($current_folder != 1) {
    $result = pager_query('SELECT id, subject, p.timestamp, u.uid, u.name, newmsg FROM {privatemsg} p, {users} u WHERE p.author = u.uid AND p.recipient = %d AND folder = %d AND p.recipient_del = 0 ORDER BY p.timestamp DESC', variable_get('privatemsg_per_page', 10), 0, NULL, $user->uid, $current_folder);
    if ($current_folder > 0) {
      $folder_name = db_result(db_query('SELECT name FROM {privatemsg_folder} WHERE fid = %d AND uid = %d', $current_folder, $user->uid));
    }
    else {
      $folder_name = t('Inbox');
    }
Neil Drumm's avatar
Neil Drumm committed
  }
  else {
    // sent messages
    $result = pager_query('SELECT id, subject, p.timestamp, u.uid, u.name, newmsg FROM {privatemsg} p, {users} u WHERE p.recipient = u.uid AND p.author = %d AND p.author_del = 0 ORDER BY p.timestamp DESC', variable_get('privatemsg_per_page', 10), 0, NULL, $user->uid);

    $folder_name = t('Sent messages');
Neil Drumm's avatar
Neil Drumm committed
  }
  $messages = array();
  while ($message = db_fetch_object($result)) {
    $messages[] = $message;
Marco Molinari's avatar
Marco Molinari committed
  }
  $folders[] = array(0, t('Inbox'));
  $result = db_query('SELECT fid, name FROM {privatemsg_folder} WHERE uid = %d', $user->uid);
  while ($folder = db_fetch_object($result)) {
    $folders[] = array($folder->fid, $folder->name);
  $folders[] = array(1, t('Sent messages'));
  return theme('privatemsg_list', $current_folder, $messages, $folders);
}
function privatemsg_list_form_submit($form_id, $form_values) {
  global $user;
  switch ($_POST['op']) {
    case t('Write a new message'):
      return 'privatemsg/new';
    case t('Delete messages'):
      foreach ($form_values['messages'] as $mid => $message) {
        if ($message['selected']) {
          _privatemsg_delete($mid);
Marco Molinari's avatar
Marco Molinari committed
        }
      return 'privatemsg/newfolder';
    case t('Move to folder'):
      if (!isset($form_values['folder']) || ($form_values['folder'] != 0 && !db_result(db_query('SELECT fid FROM {privatemsg_folder} WHERE fid = %d AND uid = %d', $form_values['folder'], $user->uid)))) {
        watchdog('privatemsg', t('Attempted use of unauthorized folder'), WATCHDOG_WARNING);
        return drupal_access_denied();
      foreach ($form_values['messages'] as $mid => $message) {
        if ($message['selected']) {
          db_query('UPDATE {privatemsg} SET folder = %d WHERE id = %d AND recipient = %d', $form_values['folder'], $mid, $user->uid);
        }
      return $form_values['folder'] ? 'privatemsg/list/'. $form_values['folder'] : 'privatemsg';
        db_query('UPDATE {privatemsg} SET author_del = 1 WHERE author = %d', $user->uid);
      else if ($fid > 1 && !db_result(db_query('SELECT fid FROM {privatemsg_folder} WHERE fid = %d AND uid = %d', $fid, $user->uid))) {
        watchdog('privatemsg', t('Attempted use of unauthorized folder'), WATCHDOG_WARNING);
        return drupal_access_denied();
      }
      else {
        db_query('UPDATE {privatemsg} SET recipient_del = 1 WHERE folder = %d AND recipient = %d', $fid, $user->uid);
    case t('Delete folder'):
      $fid = (int)arg(2);
      if (!db_result(db_query('SELECT fid FROM {privatemsg_folder} WHERE fid = %d AND uid = %d', $fid, $user->uid))) {
        watchdog('privatemsg', t('Attempted use of unauthorized folder'), WATCHDOG_WARNING);
        return drupal_access_denied();
      }
      db_query('DELETE FROM {privatemsg_folder} WHERE fid = %d', $fid);
      db_query('UPDATE {privatemsg} SET recipient_del = 1 WHERE folder = %d', $fid);
Marco Molinari's avatar
Marco Molinari committed
  }
}
Marco Molinari's avatar
Marco Molinari committed
function _privatemsg_format_folder($current, $fid, $name) {
  if ($current == $fid) {
Marco Molinari's avatar
Marco Molinari committed
  }
  else {
    return l($name, $fid ? 'privatemsg/list/'. $fid : 'privatemsg');
Marco Molinari's avatar
Marco Molinari committed
  }
  global $user;
  $message = 0;
  if (($op = arg(1)) == 'reply') {
    $message = arg(2);
  }
  else if ($op == 'msgto' && ($arg = arg(2)) && ($msg->recipient = db_result(db_query('SELECT name FROM {users} WHERE uid = %d', $arg)))) {
    $message = $msg;
  }
Marco Molinari's avatar
Marco Molinari committed

  if ($message && !is_object($message)) {
Neil Drumm's avatar
Neil Drumm committed
    // This is a reply to another message
    $message = db_fetch_object(db_query('SELECT subject, message, u.name AS recipient FROM {privatemsg} p, {users} u WHERE u.uid = p.author AND id = %d AND recipient = %d', $message, $user->uid));
    if (!stristr($message->subject, t('Re:'))) {
      $message->subject = t('Re:') .' '. $message->subject;
Marco Molinari's avatar
Marco Molinari committed
    }

    // quoting
    $message->message = "\n". str_replace("\n", "\n> ", "\n". $message->message);
Kjartan Mannes's avatar
Kjartan Mannes committed
  }
Neil Drumm's avatar
Neil Drumm committed
  drupal_add_js(drupal_get_path('module', 'privatemsg') .'/privatemsg.js');
Neil Drumm's avatar
Neil Drumm committed
  $form['recipient'] = array(
      '#prefix' => '<div class="container-inline">',
      '#type' => 'textfield',
      '#title' => t('To'),
Neil Drumm's avatar
Neil Drumm committed
      '#default_value' => $message->recipient,
      '#autocomplete_path' => 'privatemsg/autocomplete',
Neil Drumm's avatar
Neil Drumm committed
      '#size' => 50,
      '#maxlength' => 64,
      '#required' => TRUE
Neil Drumm's avatar
Neil Drumm committed
      );
  $result = db_query('SELECT DISTINCT(name) AS name FROM {privatemsg} p, {users} u WHERE p.author = u.uid AND recipient = %d AND p.timestamp > (UNIX_TIMESTAMP(NOW()) - (3600 * 24 * 30)) ORDER BY name', $user->uid);
Neil Drumm's avatar
Neil Drumm committed
  $contacts = array(t('Contacts'));
  while ($name = db_fetch_object($result)) {
Neil Drumm's avatar
Neil Drumm committed
    $contacts[] = check_plain($name->name);
  }
  if (module_exist('buddylist')) {
    $result = db_query('SELECT u.name FROM {buddylist} b, {users} u WHERE b.buddy = u.uid AND b.uid = %d', $user->uid);
    while ($name = db_fetch_object($result)) {
      $buddyname = check_plain($name->name);
      if (!in_array($buddyname, $contacts)) {
        $contacts[] = $buddyname;
      }
    }
    sort($contacts);
  }
Neil Drumm's avatar
Neil Drumm committed
  $form['quick'] = array(
      '#type' => 'select',
      '#options' => drupal_map_assoc($contacts),
      '#attributes' => array('style' => 'display: none;'), // hidden unless JS is working
      '#suffix' => '</div>'
      );

  $form['subject'] = array(
      '#type' => 'textfield',
      '#title' => t("Subject"),
      '#default_value' => $message->subject,
      '#size' => 50,
      '#maxlength' => 64,
      '#required' => TRUE
Neil Drumm's avatar
Neil Drumm committed
      );
  $form['privatemsgbody'] = array(
Neil Drumm's avatar
Neil Drumm committed
      '#type' => 'textarea',
      '#title' => t("Message"),
      '#default_value' => $message->message,
      '#cols' => 80,
Neil Drumm's avatar
Neil Drumm committed
      );
  $form[] = filter_form($message->format);
  $form['op'] = array(
      '#type' => 'submit',
      '#value' => t("Send private message"),
      );

  return drupal_get_form('privatemsg_message_form', $form);
function privatemsg_message_form_validate($form_id, $form_values) {
  if (!empty($form_values['recipient'])) {
    $recipient = user_load(array('name' => $form_values['recipient']));
    if (!$recipient->uid) {
      form_set_error('recipient', t('The <em>Recipient</em> does not exist.'));
    }
    else if (!(isset($recipient->privatemsg_allow) ? $recipient->privatemsg_allow : 1)) {
      form_set_error('recipient', t('%name does not accept private messages.', array('%name' => $recipient->name)));
    }
  if (!isset($form_values['format']) || !filter_access($form_values['format'])) {
    form_set_error('format', t('The supplied input format is invalid.'));
function privatemsg_message_form_submit($form_id, $form_values) {
  global $user;
  $recipient = user_load(array('name' => $form_values['recipient']));

  $result = _privatemsg_send($user, $recipient, $form_values['subject'], $form_values['privatemsgbody'], $form_values['format']);
  drupal_set_message(t('Message sent.'));
  drupal_goto($user->uid ? 'privatemsg' : '');
}

// API callable from other modules:
function privatemsg_send($recipient, $subject, $body, $format = FILTER_FORMAT_DEFAULT) {
  global $user;
  return _privatemsg_send($user, $recipient, $subject, $body, $format);
}

function _privatemsg_send($sender, $recipient, $subject, $body, $format) {
  $result = db_query("INSERT INTO {privatemsg} (author, recipient, subject, message, timestamp, newmsg, hostname, format) VALUES (%d, %d, '%s', '%s', %d, %d, '%s', %d)", $sender->uid, $recipient->uid, $subject, $body, time(), 1, getenv('REMOTE_ADDR'), $format);
  if ($result !== false && isset($recipient->privatemsg_mailalert) && $recipient->privatemsg_mailalert == PRIVATEMSG_MAIL_INDIVIDUAL) {
    _privatemsg_sendmail($recipient, 1);
  }
  return $result;
}

function privatemsg_view($message_id) {
  global $user;
  $result = db_query('SELECT p.id, u.uid, u.name, p.author, p.timestamp, p.subject, p.message, p.newmsg, p.recipient, p.format FROM {privatemsg} p, {users} u WHERE (recipient = %d OR author = %d) AND author = u.uid AND id = %d', $user->uid, $user->uid, $message_id);
  if ($message->newmsg && $user->uid == $message->recipient) {
    $result = db_query('UPDATE {privatemsg} SET newmsg = 0 WHERE id = %d', $message_id);
Marco Molinari's avatar
Marco Molinari committed
  }
  return theme('privatemsg_view', $message);
}

function privatemsg_delete() {
  if (($folder = _privatemsg_delete(arg(2))) !== false) {
    drupal_set_message(t('Message deleted.'));
  }
  drupal_goto($folder ? 'privatemsg/list/'. $folder : 'privatemsg');
Marco Molinari's avatar
Marco Molinari committed
function _privatemsg_delete($id) {
Marco Molinari's avatar
Marco Molinari committed

  $result = db_query('SELECT author, recipient, folder FROM {privatemsg} WHERE (recipient = %d OR author = %d) AND id = %d', $user->uid, $user->uid, $id);
Marco Molinari's avatar
Marco Molinari committed
  if ($message = db_fetch_object($result)) {
    if ($message->author == $user->uid) {
      db_query('UPDATE {privatemsg} SET author_del = 1 WHERE id = %d', $id);
Marco Molinari's avatar
Marco Molinari committed
    }
    if ($message->recipient == $user->uid) {
      db_query('UPDATE {privatemsg} SET recipient_del = 1 WHERE id = %d', $id);
Tom Dobes's avatar
Tom Dobes committed
function _privatemsg_get_new_messages($uid = 0) {
  global $user;
Tom Dobes's avatar
Tom Dobes committed
  if ($uid == 0) {
    $uid = $user->uid;
  }
  if (!isset($cache[$uid])) {
    $cache[$uid] = db_result(db_query('SELECT COUNT(*) FROM {privatemsg} WHERE recipient = %d AND newmsg = 1 AND recipient_del = 0', $uid));
function privatemsg_new_folder() {
Neil Drumm's avatar
Neil Drumm committed
  $form = array();
  $form['name'] = array(
      '#type' => 'textfield',
      '#title' => t('Name'),
      '#size' => 50,
      '#maxlength' => 64,
      '#required' => TRUE
Neil Drumm's avatar
Neil Drumm committed
      );
  $form['op'] = array(
      '#type' => 'submit',
Neil Drumm's avatar
Neil Drumm committed
      );

  return drupal_get_form('privatemsg_new_folder', $form);
function privatemsg_new_folder_validate($form_id, $form_values) {
  global $user;
  if (!empty($form_values['name']) && db_result(db_query("SELECT name FROM {privatemsg_folder} WHERE name = '%s' AND uid = %d", $form_values['name'], $user->uid))) {
    form_set_error('name', t('A folder with this name already exists.'));
  }
}

function privatemsg_new_folder_submit($form_id, $form_values) {
  db_query("INSERT INTO {privatemsg_folder} (uid, name) VALUES (%d, '%s')", $user->uid, $form_values['name']);
  drupal_set_message(t('Folder created successfully.'));
  drupal_goto('privatemsg');
/**
  @addtogroup theme_system

  Privatemsg module specific theme functions
  @{
**/

/**
 Returns content to view a private message

 @param message
**/
function theme_privatemsg_view($message) {
  global $user;

  if ($message) {
      <p><strong>'. t('From') .':</strong> '. theme('username', $message) .'<br />
      <strong>'. t('To') .':</strong> '. theme('username', user_load(array('uid' => $message->recipient))) .'<br />
      <strong>'. t('Subject') .':</strong> '.check_plain($message->subject) .'<br />
      <strong>'. t('Date') .':</strong> '. format_date($message->timestamp) .'</p>
       <div class="privatemsgbody">
      '. check_markup($message->message, $message->format, FALSE) .'</div>';
    if ($message->recipient == $user->uid) {
Alan Harder's avatar
Alan Harder committed
      $author = user_load(array('uid' => $message->uid));
      if ($author->uid && (isset($author->privatemsg_allow) ? $author->privatemsg_allow : 1)) {
        $links[] = l(t('Reply to this message'), 'privatemsg/reply/'. $message->id);
      }
      else {
        $links[] = t('Sender does not accept replies');
      }
    if ($message->recipient == $user->uid || variable_get('privatemsg_sent_status', 1)) {
      $links[] = l(t('Delete this message'), 'privatemsg/delete/'. $message->id, array('onclick' => "return confirm('". t('Are you sure to delete this message?') ."')"));
    $links[] = l(t('List messages'), $message->folder ? 'privatemsg/list/'. $message->folder : 'privatemsg');
    $body .= '<div class="links">'. theme('links', $links) .'</div>';
    drupal_set_message(t('Error: you can\'t read this message'), 'error');
    $body = '';
  }

  return $body;
}

/**
 Returns content to view a list of private messages

 @param current_folder
 @param messages
 @param folders
**/
function theme_privatemsg_list($current_folder, $messages, $folders) {
Neil Drumm's avatar
Neil Drumm committed
  $form = array();

  $extra_folders = array();
  foreach ($folders as $folder) {
    $folder_list[] = _privatemsg_format_folder($current_folder, $folder[0], $folder[1]);
    if ($folder[0] != 1 && $folder[0] != $current_folder) {
      $extra_folders[$folder[0]] = $folder[1];
    }
  }
Neil Drumm's avatar
Neil Drumm committed
  $form['messages'] = array(
      '#theme' => 'privatemsg_message_table',
      '#tree' => TRUE
      );
  $form['messages']['current_folder'] = array(
      '#type' => 'value',
      '#value' => $current_folder
      );
  foreach ($messages as $message) {
    if ($current_folder != 1) {
      $new = variable_get('privatemsg_sent_status', 1) ? $message->newmsg : 0;
Neil Drumm's avatar
Neil Drumm committed
    $form['messages'][$message->id] = array();
    $form['messages'][$message->id]['selected'] = array(
        '#type' => 'checkbox',
        );
    $form['messages'][$message->id]['date'] = array(
        '#type' => 'value',
        '#value' => format_date($message->timestamp, 'small')
        );
    $form['messages'][$message->id]['user'] = array(
        '#type' => 'value',
        '#value' => theme('username', $message)
        );
    $form['messages'][$message->id]['subject'] = array(
        '#type' => 'value',
        '#value' => l($message->subject, 'privatemsg/view/'. $message->id) . ($new ? (' '. theme('mark')) : '')
        );
  }
  $form[] = array('#type' => 'markup', '#value' => theme('pager', array(), variable_get('privatemsg_per_page', 10)));
  if (count($messages) > 0) {
Neil Drumm's avatar
Neil Drumm committed
    $form['delete_messages'] = array(
        '#type' => 'submit',
        '#value' => t('Delete messages'),
        '#attributes' => array('onclick' => "return confirm('". t('Are you sure you want to delete these messages?') ."')")
        );
  if (count($extra_folders) > 0 && $current_folder != 1 && count($messages) > 0) {
Neil Drumm's avatar
Neil Drumm committed
    $form['folder'] = array(
        '#prefix' => '<div class="container-inline">',
        '#type' => 'select',
        '#options' => $extra_folders
        );
    $form['move_messages'] = array(
        '#type' => 'submit',
        '#value' => t('Move to folder'),
        '#suffix' => '</div>'
        );
Neil Drumm's avatar
Neil Drumm committed
  $form[] = array('#type' => 'markup', '#value' => '<br />');

  $form['new_message'] = array(
      '#type' => 'submit',
      '#value' => t('Write a new message')
Neil Drumm's avatar
Neil Drumm committed
      );

  $form[] = array('#type' => 'markup', '#value' => '<br />');

  if ($current_folder > 1) {
    // you can't delete Inbox
Neil Drumm's avatar
Neil Drumm committed
    $form['delete_folder'] = array(
        '#type' => 'submit',
        '#value' => t('Delete folder'),
        '#attributes' => array('onclick' => "return confirm('". t('Are you sure you want to delete this folder and all its messages?') ."')")
        );
  if (count($messages) > 0) {
Neil Drumm's avatar
Neil Drumm committed
    $form['empty_folder'] = array(
        '#type' => 'submit',
        '#value' => t('Empty folder'),
        '#attributes' => array('onclick' => "return confirm('". t('Are you sure you want to delete every message in this folder?') ."')")
        );
  }
  $form['new_folder'] = array(
      '#type' => 'submit',
Neil Drumm's avatar
Neil Drumm committed
      );

  return $out . drupal_get_form('privatemsg_list_form', $form);
}

function theme_privatemsg_message_table($form) {
  $rows = array();

  foreach (element_children($form) as $key) {
    if ($key != 'current_folder') {
      $row = array();
      $row[] = form_render($form[$key]['selected']);
      $row[] = $form[$key]['date']['#value'];
      $row[] = $form[$key]['user']['#value'];
      $row[] = $form[$key]['subject']['#value'];
      $rows[] = $row;
    }
Neil Drumm's avatar
Neil Drumm committed
  if (count($rows) == 0) {
    $rows[] = array(array('data' => t('No messages.'), 'colspan' => 4));
  }

  $header = array(
      NULL,
      t('Date'),
      ($form['current_folder']['#value'] == 1 ? t('To') : t('From')),
      t('Subject'),
      );

  return theme('table', $header, $rows);
Marco Molinari's avatar
Marco Molinari committed
?>