messaging_method.class.inc in Messaging 6.3
Drupal Messaging Framework - Send_Method class file
File
classes/messaging_method.class.incView source
<?php
/**
* @file
* Drupal Messaging Framework - Send_Method class file
*/
/**
* Sending method, implements all specific method functionality
*
* Old callback functions are
* - send
* - destination
*/
class Messaging_Send_Method {
// Method key
public $method;
// Full info array
public $info;
function __construct($info, $method) {
$this->method = $method;
$this->info = $info;
}
function get_info($property = NULL) {
if ($property) {
return isset($this->info[$property]) ? $this->info[$property] : NULL;
}
else {
return $this->info;
}
}
/**
* Send message to destination by calling the method's send callback
*/
function send($destination, $message) {
// Translate destination object to old fashion parameters
$callback = $this
->get_callback('send');
$params = $message
->get_params($this->method);
return $this
->callback_invoke($callback, $destination, $message, $params);
}
/**
* Send a message to multiple destinations
*
* @param $source
* Message or message template
* @param $destinations
* Array of destinations for this method
*/
function send_multiple($source, $destinations) {
$result = array();
$template = $source
->build($this->method, NULL);
$template->destinations = $destinations;
$template
->prepare();
$template
->render();
foreach ($destinations as $index => $destination) {
$message = clone $template;
$message->destination = $destination;
$result[$index] = $message
->send();
}
return $result;
}
/**
* Queue multiple copies of the same message
*
* @param $source
* Message or message template
* @param $destinations
* Array of destinations for this method
*/
function queue_multiple($source, $destinations) {
$result = array();
$template = $source
->build($this->method, NULL);
$template->destinations = $destinations;
$template
->prepare();
$template->queue = 1;
$template
->render();
foreach ($destinations as $index => $destination) {
$message = clone $template;
$message->destination = $destination;
$result[$index] = $message
->queue();
}
return $result;
}
/**
* Get destination for user
*/
function user_destination($account) {
if (($property = $this->destination) && !empty($account->{$property})) {
// Get destination property from user account
return $account->{$property};
}
elseif ($callback = $this
->get_callback('destination')) {
// Backwards compatibility, call destination callback
return $this
->callback_invoke($callback, $account);
}
}
/**
* Check user availability
*/
/**
* Get default sender
*/
function get_default_sender() {
return array(
'name' => variable_get('site_name', 'Drupal'),
'from' => '',
);
}
/**
* Prepare message for processing with this method
*/
function message_prepare($message) {
// If the messaging method is of type push, cron processing will be enabled
if ($message->queue && $this->type & MESSAGING_TYPE_PUSH) {
$this->cron = 1;
}
// It will be queued always for pull methods, cron disabled though, so it will wait till it's pulled
if (!$message->queue && $this->type & MESSAGING_TYPE_PULL) {
$message->queue = 1;
$message->cron = 0;
}
}
/**
* Check destination, user availability, etc...
*
* At this stage it is still possible to redirect to other sending method with $message->redirect = TRUE
*/
function message_check($message) {
}
/**
* Run before sending prepared message
*/
function message_presend($message) {
}
/**
* Send a message to a single destination
*/
function message_send($message) {
$message
->prepare();
$message
->render();
return $this
->send($message->destination, $message);
}
/**
* Queue the message
*/
function message_queue($message) {
$message->result = TRUE;
$message->queue = 1;
$message
->save();
return $message->result;
}
/**
* Test message sending
*/
function message_test($message) {
$message
->log('Emulating message sending (test run)', array(
'message' => (string) $message,
));
}
/**
* Run after sending message
*/
function message_aftersend($message) {
// Depending on parameters and what's happened so far we make the final queue/log decision
if ($message->queue || $message->log) {
$message
->store();
}
}
/**
* Run after message has been queued
*/
function message_afterqueue($message) {
}
/**
* Render a template object
*
* It builds subject and body properties
*/
function message_render($template) {
$info = $this->info + array(
'glue' => ' ',
'filter' => NULL,
);
// Render body if anything to render
if ($body = $template->body) {
// Apply footer prefix if provided and the message has a footer element.
// Note: If $body is a string the final isset($body['footer']) will be true
if (is_array($body) && !empty($info['footer']) && isset($body['footer'])) {
$body['footer_prefix'] = $info['footer'];
$body['footer_text'] = $body['footer'];
unset($body['footer']);
}
$template->body = $this
->render_text($body, $info['glue'], $info['filter']);
}
// Render subject if anything to render
if ($subject = $template->subject) {
// Render separately subject and body info, adding default parameters
$info += array(
'subject_glue' => ' ',
);
$template->subject = $this
->check_subject($this
->render_text($subject, $info['subject_glue']));
}
return $template;
}
/**
* Composes message from different parts, recursively and applies filter
*
* Filter is applied now only once
*
* @param $text
* Simple string or array of message parts
* It may have named elements like #prefix and #text
* or it may be single strings to render straight forward
* @param $glue
* Text to glue all lines together
* @param $filter
* Input format to apply to the results
*/
function render_text($text, $glue, $filter = NULL) {
if (!$text) {
return '';
}
elseif (is_array($text)) {
$elements = array();
// First render children recursively, without filtering
foreach (element_children($text) as $key) {
$elements[$key] = $this
->render_text($text[$key], $glue);
}
// Apply theme if set, just implode if not
if (!empty($text['#theme'])) {
$output = theme($text['#theme'], $text, $glue);
}
else {
$output = implode($glue, $elements);
}
}
else {
$output = $text;
}
// The filter is applied now only once
if ($filter) {
$output = check_markup($output, $filter, FALSE);
}
return $output;
}
/**
* Converts strings to plain utf-8 single line
*/
static function check_subject($text) {
$text = messaging_check_plain($text);
// taken from _sanitizeHeaders() in PEAR mail() : http://pear.php.net/package/Mail
$text = preg_replace('=((0x0A/%0A|0x0D/%0D|\\n|\\r)\\S).*=i', NULL, $text);
return $text;
}
/**
* Implement for testing
*/
function test($destination, $message) {
return TRUE;
}
/**
* Magic function, getting non existent properties
*/
public function __get($name) {
if (isset($this->info[$name])) {
return $this->info[$name];
}
}
/**
* Magic function, invoking non existent methods
*
* For backwards compatibility with old array callbacks
*/
public function __call($name, $arguments) {
// If we have an old style callback like this, go for it
if ($callback = $this
->get_callback($name)) {
if (is_array($callback)) {
// It is an array: function, arg1, arg2...
$function = array_shift($callback);
$arguments = array_unshift($callback, $arguments);
}
else {
// It is just a function name
$function = $callback;
}
return call_user_func_array($function, $params);
}
}
/**
* Get callback from method info
*/
public function get_callback($type) {
return $this
->get_info($type . ' callback');
}
/**
* Invoke callback with a variable number of arguments
*/
public function callback_invoke() {
$args = func_get_args();
$callback = array_shift($args);
if (is_array($callback)) {
// It is an array: function, arg1, arg2...
$function = array_shift($callback);
$params = $callback;
}
else {
// It is just a function name
$function = $callback;
$params = array();
}
// Merge parameters and go for it
$params = array_merge($params, $args);
return call_user_func_array($function, $params);
}
}
/**
* Base class for mail sending methods
*/
class Messaging_Mail_Method extends Messaging_Send_Method {
public $default_from;
function __construct($info, $method) {
parent::__construct($info, $method);
$this->default_from = variable_get('site_mail', ini_get('sendmail_from'));
}
function get_default_sender() {
return array(
'name' => variable_get('site_name', 'Drupal'),
'from' => $this->default_from,
);
}
/**
* Rebuild message in Drupal mail format
* @param $message
* Message object
*/
function message_prepare($message) {
if (empty($message->params['from'])) {
if (!empty($message->sender_account) && !empty($message->sender_account->mail)) {
$from = check_plain($message->sender_account->name) . ' <' . $message->sender_account->mail . '>';
}
elseif (!empty($message->sender_name) && $default_from) {
$from = check_plain($message->sender_name) . ' <' . $this->default_from . '>';
}
else {
$from = $this->default_from;
}
$message->params['from'] = $from;
}
$message->params['mail_headers'] = $this
->mail_headers($message);
}
/**
* Get mail headers. Helper function for mail methods
*/
function mail_headers($message) {
$headers = !empty($message->params['headers']) ? $message->params['headers'] : array();
// Add some default headers
$headers += array(
'MIME-Version' => '1.0',
'Content-Type' => 'text/plain; charset=UTF-8; format=flowed; delsp=yes',
'Content-Transfer-Encoding' => '8Bit',
'X-Mailer' => 'Drupal',
);
$from = !empty($message->params['from']) ? $message->params['from'] : $this->default_from;
// Set default headers depending on data
$headers += array(
'From' => $from,
'Reply-To' => $from,
);
if ($this->default_from) {
// To prevent e-mail from looking like spam, the addresses in the Sender and
// Return-Path headers should have a domain authorized to use the originating
// SMTP server. Errors-To is redundant, but shouldn't hurt.
$more_headers['Sender'] = $more_headers['Return-Path'] = $more_headers['Errors-To'] = $this->default_from;
$headers += $more_headers;
}
return $headers;
}
/**
* Message ready for sending, invoke mail alter
*/
function message_presend($message) {
$mail = array(
'id' => 'messaging_' . (!empty($message->type) ? 'message-' . $message->type : 'message'),
'to' => $message->destination,
'from' => $message->params['from'],
'language' => $message
->get_language(),
'params' => $message->params,
'subject' => $message->subject,
'body' => $message->body,
'headers' => $message->params['mail_headers'],
'attachments' => !empty($message->files) ? $message->files : array(),
);
// Invoke hook_mail_alter()
drupal_alter('mail', $mail);
// Rebuild message with results
$message->destination = $mail['to'];
$message->params = $mail['params'];
$message->params['from'] = $mail['from'];
$message->params['mail_headers'] = $mail['headers'];
$message->subject = $mail['subject'];
$message->body = $mail['body'];
// Other parts are not suppossed to change, like language, files
}
}
Classes
Name | Description |
---|---|
Messaging_Mail_Method | Base class for mail sending methods |
Messaging_Send_Method | Sending method, implements all specific method functionality |