You are here

messaging_message.class.inc in Messaging 6.3

Drupal Messaging Framework - Default class file

File

classes/messaging_message.class.inc
View source
<?php

/**
 * @file
 * Drupal Messaging Framework - Default class file
 */

/**
 * Message class
 * 
 * This is a message with all the information, ready for sending
 */
class Messaging_Message {

  // Unique id
  public $mqid;

  // Message type: outgoing, incoming
  public $type;

  // Sending method
  public $method;

  // Message source, mixed data
  public $source;

  // Language code
  public $language;

  // Sending method specific params
  public $params;

  // Message destination
  public $uid;
  public $destination;
  public $user = NULL;

  // Used when sending to multiple destinations
  public $destinations;

  // Rendered message parts
  public $subject;
  public $body;
  public $files;

  // Sender information
  public $sender;
  public $sender_name;
  public $sender_address;
  public $sender_account = NULL;

  // Timestamps
  public $created = 0;
  public $sent = 0;

  // Processing parameters
  public $queue = 0;
  public $cron = 0;
  public $log;

  // Error code, error text
  public $error = 0;
  public $error_msg;

  // Temporary variables, not stored
  public $discard;

  // Message status
  public $prepared = FALSE;
  public $rendered = FALSE;
  public $queued = FALSE;
  public $redirect = FALSE;
  public $retry = FALSE;

  // Result after each operation
  public $process;
  public $result;

  // Test message, not really for sending
  public $test = FALSE;
  public $success = TRUE;

  // Template used to build this message
  // @see Messaging_Message_Template
  protected $template;

  /**
   * Constructor, with predefined array of data
   */
  function __construct($data = array()) {
    foreach ($data as $key => $value) {
      $this->{$key} = $value;
    }

    // Set logging option
    if (!isset($this->log)) {
      $this->log = variable_get('messaging_log', 0);
    }

    // If retrieved from store, populate some data
    if (!empty($this->mqid)) {
      $this->prepared = $this->method;
      $this->rendered = $this->method;
      if ($this->uid && empty($this->account)) {
        $this->account = messaging_load_user($this->uid);
      }
      if ($this->sender && empty($this->sender_account)) {
        $this->sender_account = messaging_load_user($this->sender);
      }
    }
  }

  /**
   * Build this message for method, destination
   */
  function build($method, $destination) {
    $this->method = $method;
    $this->destination = $destination;
    return $this;
  }

  /**
   * Prepare message for sending method, before rendering
   */
  function prepare() {

    // If the sending method has changed, prepare again
    if (!$this->prepared || $this->prepared != $this->method) {
      $this
        ->method_invoke('prepare');

      // Provides a hook for other modules to modify the message
      drupal_alter('message', $this);
      $this->prepared = $this->method;
      $this->rendered = FALSE;
    }
  }

  /**
   * Render the message for sending method
   */
  function render() {
    if (!$this->rendered) {
      if (isset($this->template)) {
        $this->subject = $this->template
          ->get_subject($this->method, $this
          ->get_language());
        $this->body = $this->template
          ->get_body($this->method, $this
          ->get_language());
      }
      $this
        ->method_invoke('render');
      $this->rendered = TRUE;
    }
  }

  /**
   * Send message using method, destination
   */
  function send() {
    if (!empty($this->test)) {

      // We are doing a test run so we don't send the message
      $this
        ->test();
      $this->result = TRUE;
    }
    else {

      // Run full processing, will end up on send, queue or error
      $this
        ->process();
      $this
        ->done();
    }
    return $this->result;
  }

  /**
   * Testing message, just log data
   */
  function test() {
    $this
      ->prepare();
    $this
      ->render();
    messaging_log('Emulating message sending (test run)', array(
      'message' => $this,
    ));
  }

  /**
   * Process message to the end (queue, send, log
   */
  function process() {
    $this->result = FALSE;

    // We try more than once if message is redirected
    do {
      $this->process = TRUE;
      $this->redirect = FALSE;
      $this->retry = FALSE;
      $this
        ->prepare();
      if ($this->queue) {
        $this
          ->queue();
      }
      elseif ($this->process && !$this->redirect) {
        $this
          ->post();
      }
    } while ($this->redirect || $this->retry);
    return $this->result;
  }

  /**
   * Actual message sending through sending method
   */
  function post() {

    // Disable queueing, but it can be restored by next operations
    $this
      ->render();
    $this->queue = 0;

    // Prepare operations to invoke on send method
    $this->result = $this
      ->method_process('presend', 'send', 'aftersend');
    return $this->result;
  }

  /*
   * Queue the message
   */
  function queue() {
    $this->result = TRUE;
    if (!$this->queued) {
      $this->queue = 1;
      $this
        ->render();
      $this->result = $this
        ->method_process('queue', 'afterqueue');
    }
    return $this->result;
  }

  /**
   * Wrapping up, store if we need logging
   */
  function done() {
    if ($this->queue && !$this->queued) {
      $this
        ->queue();
    }
    elseif ($this->log || $this->error) {
      $this
        ->store();
    }
  }

  /**
   * Save to store if not saved yet
   */
  function store() {
    if (empty($this->mqid)) {
      $this
        ->save();
    }
  }

  /**
   * Save to store / update
   */
  function save() {

    // Make sure this is rendered before saving
    $this
      ->prepare();
    $this
      ->render();
    if (empty($this->created)) {
      $this->created = time();
    }
    messaging_store('save', $this);
  }

  /**
   * Set destination user and find method's destination for this user if not set
   *
   * @param $account
   *   User account object
   * @param $destination
   *   Optional destination
   */
  function set_user($account, $destination = NULL) {
    $this->uid = $account->uid;
    $this->account = $account;

    // Set destination if needed
    if (isset($destination)) {
      $this->destination = $destination;
    }
    elseif (!isset($this->destination)) {
      $this->destination = messaging_user_destination($account, $this->method);
    }

    // Set user language if not set
    if (!isset($this->language) && ($preferred = user_preferred_language($account))) {
      $this->language = $preferred->language;
    }
  }

  /**
   * Set sender account and related properties
   *
   * @param $account
   *   Sender user account
   * @param $address
   *   Opational method's address for this account
   */
  function set_sender($account, $address = NULL) {
    $this->sender = $account->uid;
    $this->sender_name = $account->name;
    $this->sender_account = $account;
    if (isset($address)) {
      $this->sender_address = $address;
    }
    elseif (!isset($this->sender_address)) {
      $this->sender_address = messaging_user_destination($account, $this->method);
    }
  }

  /**
   * Get sending method parameters
   */
  function get_params($method = NULL) {
    $method = $method ? $method : $this->method;

    // First get specific parameters for this sending method
    $params = isset($this->params[$method]) ? $this->params[$method] : array();

    // Check for specific parameters for this method group
    $group = messaging_method_info($method, 'group');
    if ($group && !empty($this->params[$group])) {
      $params += $this->params[$group];
    }
    return $params;
  }

  /**
   * Get language as object
   */
  function get_language() {
    if (isset($this->language) && ($languages = language_list()) && isset($languages[$this->language])) {
      return $languages[$this->language];
    }
    else {
      return language_default();
    }
  }

  /**
   * Delete if already on store
   */
  function delete() {
    if (!empty($this->mqid)) {
      $result = messaging_store('delete', $this->mqid);
      unset($this->mqid);
      return $result;
    }
  }

  /**
   * Set error condition and stop processing
   *
   * @param $text
   *   Error message to be stored
   */
  function set_error($text, $code = 1) {

    // This will stop processing if we are in the middle of anything
    $this->process = FALSE;
    $this->result = FALSE;
    $this->error = $code;
    $this->error_msg = $text;
  }

  /**
   * Invoke multiple method callbacks
   */
  function method_process() {
    $callbacks = func_get_args();
    $this->process = TRUE;
    $this->result = TRUE;
    while ($this->process && ($key = array_shift($callbacks))) {
      $result = $this
        ->method_invoke($key);
    }

    // Success if all callbacks processed and result is not FALSE
    if ($result === FALSE || !empty($callbacks)) {
      $this->result = FALSE;
    }
    return $this->result;
  }

  /**
   * Invoke method callback with this message
   */
  function method_invoke($op) {
    $function = 'message_' . $op;
    if ($method = messaging_send_method($this->method)) {
      return $method
        ->{$function}($this);
    }
    else {
      $this
        ->set_error('Sending method not available');
    }
  }

  /**
   * Get list of fields to serialize for storage
   */
  function data_fields() {
    return array(
      'params',
      'files',
      'parts',
      'params',
      'sender_name',
      'error_msg',
    );
  }

  // Magic function, format as string
  public function __toString() {
    $subject = $this->subject ? check_plain($this->subject) : '<none>';
    return "Message: method={$this->method}, destination={$this->destination}, subject={$subject}";
  }

}

Classes

Namesort descending Description
Messaging_Message Message class