You are here

messaging_xmpp.module in Messaging 6.4

XMPP Messsaging. Messaging method plug-in

@todo properly handle queued messages

File

messaging_xmpp/messaging_xmpp.module
View source
<?php

/**
 * @file
 * XMPP Messsaging. Messaging method plug-in
 * 
 * @todo properly handle queued messages
 */

// Settings for user offline, numeric values so they don't clash with sending methods.
define('MESSAGING_XMPP_OFFLINE_SEND', 0);
define('MESSAGING_XMPP_OFFLINE_QUEUE', 1);
define('MESSAGING_XMPP_OFFLINE_DISCARD', 2);

/**
 * Options when user is off line
 */
function messaging_xmpp_user_offline_options($account = NULL) {

  // General options, for admin settings too
  $options = array(
    MESSAGING_XMPP_OFFLINE_SEND => t('Send anyway, you may get the messages when online.'),
    //MESSAGING_XMPP_OFFLINE_QUEUE => t('Queue and send when user comes back online.'),
    MESSAGING_XMPP_OFFLINE_DISCARD => t('Discard, the message will be lost.'),
  );

  // Alternate methods, will depend on user account
  if ($account) {
    $methods = messaging_method_list($account);
    unset($methods['xmpp']);
    if ($methods) {
      $options[t('Send using...')] = $methods;
    }
  }
  return $options;
}

/**
 * Implementation of hook_menu()
 */
function messaging_xmpp_menu() {
  $items['admin/messaging/settings/method/xmpp'] = array(
    'title' => 'XMPP',
    'description' => 'XMPP settings',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'messaging_xmpp_settings_form',
    ),
    'access arguments' => array(
      'administer messaging',
    ),
    'type' => MENU_LOCAL_TASK,
  );
  return $items;
}

/**
 * Site wide settings form
 */
function messaging_xmpp_settings_form($form_state) {
  $form['offline'] = array(
    '#type' => 'fieldset',
    '#title' => t('XMPP offline messages'),
    '#description' => t('What to do with XMPP messages when the destination user is offline. Depending on the XMPP API used we may not be able to determine whether the user is online or not so you may want to set the <em>Send anyway</em> option and not allow per user settings.'),
  );
  $form['offline']['messaging_default_xmpp_offline'] = array(
    '#type' => 'radios',
    '#title' => t('Default for XMPP offline messages'),
    '#default_value' => variable_get('messaging_default_xmpp_offline', MESSAGING_XMPP_OFFLINE_SEND),
    '#options' => messaging_xmpp_user_offline_options(),
    '#description' => t('Select the default option for XMPP messages when the user is offline.'),
  );
  $form['offline']['messaging_peruser_xmpp_offline'] = array(
    '#type' => 'checkbox',
    '#title' => t('Allow per user settings'),
    '#default_value' => variable_get('messaging_peruser_xmpp_offline', 1),
    '#description' => t('If checked, users will be able to override this option in their user account settings. They will be offered additional options to get the messages through a different method depending on which ones they have available.'),
  );
  return system_settings_form($form);
}

/**
 * Implementation of hook_messaging
 */
function messaging_xmpp_messaging($op) {
  switch ($op) {
    case 'send methods':
      $info['xmpp'] = array(
        'title' => t('XMPP'),
        'name' => t('XMPP'),
        'type' => MESSAGING_TYPE_PUSH,
        'glue' => "\n",
        'description' => t('Send XMPP using XMPP Framework.'),
        'address_type' => 'xmpp',
        'send callback' => 'messaging_xmpp_send_msg',
        'render callback' => 'messaging_xmpp_render',
        'user callback' => 'messaging_xmpp_user_check',
        'anonymous' => TRUE,
      );
      return $info;
    case 'address types':
      $info['xmpp'] = array(
        'name' => t('XMPP account'),
        // Name of the address for this method
        'user2address callback' => 'messaging_xmpp_user_destination',
        // Mapping user account to address
        'validate callback' => 'valid_email_address',
      );
      return $info;
  }
}

/**
 * Implementation of hook_user()
 *
 * Changed name of account to user so we know what is being performed on
 */
function messaging_xmpp_user($type, $edit, &$account, $category = NULL) {
  switch ($type) {
    case 'form':
      if ($category == 'account' && variable_get('messaging_peruser_xmpp_offline', 1)) {
        $form['messaging']['messaging_xmpp_offline'] = array(
          '#type' => 'select',
          '#title' => t('XMPP offline messages'),
          '#default_value' => messaging_user_setting('xmpp_offline', $account, 0),
          '#options' => messaging_xmpp_user_offline_options($account),
          '#description' => t('Select what to do when you are offline and an XMPP message is sent to you.'),
        );
        return $form;
      }
      break;
  }
}

/**
 * Message user callback. Check user destination and availability
 * 
 * @see messaging_message_send_user()
 * 
 * @param $message
 *   Message object. It can be redirected to other sending method.
 */
function messaging_xmpp_user_check($message) {
  $account = $message
    ->get_user();
  $message->process = FALSE;

  // If the option is 0 = Send anyway, we do nothing else
  if (!empty($account->uid) && ($what = messaging_user_setting('xmpp_offline', $account, 0))) {

    // Now we need to know whether the user is online, otherwise just return normal values
    if (!xmppframework_get_user_resources($account)) {

      // Now we need to decide
      if ($what == MESSAGING_XMPP_OFFLINE_QUEUE) {

        // Queue for when the user is online
        messaging_log('Queueing XMPP message for offline user', array(
          'uid' => $account->uid,
        ));
        $message->queue = 1;
      }
      elseif ($what == MESSAGING_XMPP_OFFLINE_DISCARD) {
        messaging_log('Discarding XMPP message for offline user', array(
          'uid' => $account->uid,
        ));

        // These two should cause the message to be discarded without logging
        $message->discard = TRUE;
        $message->log = FALSE;
      }
      elseif (messaging_method_info($what)) {
        messaging_log('Redirecting XMPP message for offline user', array(
          'uid' => $account->uid,
          'method' => $what,
        ));
        $message->method = $what;
        $message->destination = FALSE;

        // Keep on processing, the other method may have sth to say about this
        $message->process = TRUE;
      }
    }
  }
}

/**
 * Message Render callback
 */
function messaging_xmpp_render($message, $info) {

  // rendering the message to get any additional pieces being put on
  $message = Messaging_Send_Method::default_render($message, $info);

  // We apply a final filtering, stripping out all html tags
  $message->body = messaging_text_clean($message->body);
  $message->subject = messaging_text_clean($message->subject);
  return $message;
}

/**
 * Get XMPP destination (jid) for user account
 * 
 */
function messaging_xmpp_user_destination($account) {
  if ($account && !empty($account->xmpp_user['jid'])) {
    return $account->xmpp_user['jid'];
  }
}

/**
 * Send message via the xmppframework
 *
 * @param $destination
 *      Destination JID
 * @param $message
 *      Message Object
 * @param $params
 *      Extra parameters
 */
function messaging_xmpp_send_msg($destination, $message, $params = array()) {
  if ($conn = messaging_xmpp_connect()) {

    // We can send 'headline' or 'chat'. I get each headline in a different Pidgin chat window,
    // not very practical, so we use 'chat' and a single text with new lines
    $text = messaging_text_build($message, "\n");
    return xmppframework_send_message($destination, 'chat', $text, NULL, $conn);
  }
  else {
    return FALSE;
  }
}

/**
 * Get a XMPP connection using XMPPFramework and messaging jid
 */
function messaging_xmpp_connect() {
  static $conn, $tried = FALSE;
  if ($conn) {

    // If we already have a connection for this page request, use it
    return $conn;
  }
  elseif ($tried) {

    // Or if the connection failed, do not try again
    return FALSE;
  }
  else {
    $tried = TRUE;

    // We need to set presence, the messages may not be delivered if not.
    if ($conn = xmppframework_get_server_connection()) {
      xmppframework_set_presence(NULL, $type = 'available', $show = 'available', $status = 'Available', $conn);
    }
    return $conn;
  }
}

Functions

Namesort descending Description
messaging_xmpp_connect Get a XMPP connection using XMPPFramework and messaging jid
messaging_xmpp_menu Implementation of hook_menu()
messaging_xmpp_messaging Implementation of hook_messaging
messaging_xmpp_render Message Render callback
messaging_xmpp_send_msg Send message via the xmppframework
messaging_xmpp_settings_form Site wide settings form
messaging_xmpp_user Implementation of hook_user()
messaging_xmpp_user_check Message user callback. Check user destination and availability
messaging_xmpp_user_destination Get XMPP destination (jid) for user account
messaging_xmpp_user_offline_options Options when user is off line

Constants