You are here

function privatemsg_thread_load in Privatemsg 6

Same name and namespace in other branches
  1. 6.2 privatemsg.module \privatemsg_thread_load()
  2. 7.2 privatemsg.module \privatemsg_thread_load()
  3. 7 privatemsg.module \privatemsg_thread_load()

Load a thread with all the messages and participants.

This function is called by the menu system through the %privatemsg_thread wildcard.

Parameters

$thread_id: Thread id, pmi.thread_id or pm.mid of the first message in that thread.

$account: User object for which the thread should be loaded, defaults to the current user.

$start: Message offset from the start of the thread.

Return value

$thread object, with keys messages, participants, title and user. messages contains an array of messages, participants an array of user, subject the subject of the thread and user the user viewing the thread.

If no messages are found, or the thread_id is invalid, the function returns FALSE.

Related topics

File

./privatemsg.module, line 272
Allows users to send private messages to other users.

Code

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])) {

      // Load the list of participants.
      $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;
      }

      // Load messages returned by the messages query with privatemsg_message_load_multiple().
      $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;

      // Check if we need to limit the messages.
      $max_amount = variable_get('privatemsg_view_max_amount', 20);

      // If there is no start value, select based on get params.
      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 {

          // Calculate the number of messages on the "last" page to avoid
          // message overlap.
          // Note - the last page lists the earliest messages, not the latest.
          $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;
        }

        // Sanity check - we cannot start from a negative number.
        if ($start < 0) {
          $start = 0;
        }
        $thread['start'] = $start;

        //If there are newer messages on the page, show pager link allowing to go to the newer messages.
        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;
        }

        // Do not show messages on the last page that would show on the page
        // before. This will only work when using the visual pager.
        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 from the first message - this is a specific hack to make sure
          // the message display has sane paging on the last page.
          $start = 0;
        }

        // Visual counts start from 1 instead of zero, so plus one.
        $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'];
      }

      // Load messages returned by the messages query.
      $thread['messages'] = privatemsg_message_load_multiple($mids, $thread['read_all'] ? NULL : $account);

      // If there are no messages, don't allow access to the thread.
      if (empty($thread['messages'])) {
        $thread = FALSE;
      }
      else {

        // General data, assume subject is the same for all messages of that thread.
        $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;
}