'admin/smsframework',
'title' => t('SMS Framework'),
'description' => t('Control how your site uses SMS.'),
'position' => 'right',
'callback' => 'system_admin_menu_block_page',
'access' => user_access('administer smsframework'),
);
$items[] = array(
'path' => 'admin/smsframework/gateways',
'title' => t('Gateway configuration'),
'description' => t('Configure gateways and chose the default gateway.'),
'callback' => 'sms_admin_overview',
'access' => user_access('administer smsframework'),
);
}
else {
if (arg(0) == 'admin' && arg(1) == 'smsframework' && arg(2) == 'gateways' && arg(3)) {
$gateways = sms_gateways();
if (isset($gateways[arg(3)])) {
$items[] = array(
'path' => 'admin/smsframework/gateways/'. arg(3),
'title' => t("!gateway gateway", array('!gateway' => $gateways[arg(3)]['name'])),
'callback' => 'drupal_get_form',
'callback arguments' => array('sms_admin_gateway_form', $gateways[arg(3)], arg(3)),
'access' => user_access('administer smsframework'),
'type' => MENU_CALLBACK,
);
}
}
}
return $items;
}
/**
* Implementation of hook_perm().
*/
function sms_perm() {
return array('administer smsframework');
}
function sms_admin_overview() {
$output = drupal_get_form('sms_admin_default_form');
$output .= drupal_get_form('sms_admin_mapping_form');
return $output;
}
function sms_admin_default_form() {
$gateways = sms_gateways();
foreach ($gateways as $identifier => $gateway) {
$active = ($identifier == variable_get('sms_default_gateway', 0));
$options[$identifier] = '';
$form[$gateway['name']]['id'] = array('#value' => $identifier);
if (is_array($gateway['options'])) {
$form[$gateway['name']]['configure'] = array('#value' => l(t('configure'), 'admin/smsframework/gateways/'. $identifier));
}
else {
$form[$gateway['name']]['configure'] = array('#value' => t('No configuration options'));
}
}
$form['default'] = array('#type' => 'radios', '#options' => $options, '#default_value' => variable_get('sms_default_gateway', 0));
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Set default gateway'),
);
return $form;
}
function sms_admin_default_form_submit($form_id, $form_values) {
// Process form submission to set the default gateway
if ($form_values['default']) {
drupal_set_message(t('Default gateway updated.'));
variable_set('sms_default_gateway', $form_values['default']);
}
}
function theme_sms_admin_default_form($form) {
$rows = array();
foreach ($form as $name => $element) {
if (isset($element['id']) && is_array($element['id'])) {
$rows[] = array(
drupal_render($form['default'][$element['id']['#value']]),
check_plain($name),
drupal_render($element['configure']),
);
unset($form[$name]);
}
}
$header = array(t('Default'), t('Name'), array('data' => t('Operations'), 'colspan' => 1));
$output = '
Default gateway
';
$output .= theme('table', $header, $rows);
$output .= drupal_render($form);
return $output;
}
function sms_admin_mapping_form() {
$gateway_options = array_merge(array('Default'), sms_gateways('names'));
$modules = module_implements('behavior_info');
sort($modules);
$form['modules'] = array('#tree' => TRUE);
foreach ($modules as $module) {
if ($behaviors = module_invoke($module, 'behavior_info')) {
asort($behaviors);
foreach ($behaviors as $behavior_id => $behavior) {
$form['modules'][$module][$behavior_id] = array('#value' => $behavior['name']);
$form['modules'][$module][$behavior_id]['gateway'] = array(
'#type' => 'radios',
'#options' => $gateway_options,
'#default_value' => sms_behavior_gateway($module, $behavior_id),
);
}
}
}
foreach ($gateway_options as $key => $option) {
$form['gateway_options'][$key] = array('#value' => $option);
}
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save mappings'),
);
return $form;
}
function theme_sms_admin_mapping_form($form) {
foreach (element_children($form['modules']) as $module) {
$row = array();
$row[] = array('data' => t('@module module', array('@module' => $module)), 'class' => 'module', 'id' => 'module-'. $module, 'colspan' => count($form['gateway_options']) + 1);
$rows[] = $row;
foreach (element_children($form['modules'][$module]) as $behavior) {
$row = array();
if (is_array($form['modules'][$module][$behavior])) {
$row[] = array('data' => $form['modules'][$module][$behavior]['#value'], 'class' => 'behavior');
foreach (element_children($form['modules'][$module][$behavior]['gateway']) as $radio) {
$title = $form['modules'][$module][$behavior]['gateway'][$radio]['#title'];
$row[] = array('data' => drupal_render($form['modules'][$module][$behavior]['gateway'][$radio]), 'title' => $title);
}
$form['modules'][$module][$behavior]['#printed'] = TRUE;
$rows[] = $row;
}
}
}
$header[] = (t('Behavior'));
foreach (element_children($form['gateway_options']) as $gateway) {
if (is_array($form['gateway_options'][$gateway])) {
$header[] = drupal_render($form['gateway_options'][$gateway]);
}
}
$output = 'Gateway Mappings
';
$output .= theme('table', $header, $rows, array('id' => 'mappings'));
$output .= drupal_render($form);
return $output;
}
function sms_admin_mapping_form_submit($form_id, $form_values) {
foreach ($form_values['modules'] as $module_name => $module) {
if (is_array($module) && module_exists($module_name)) {
foreach ($module as $behavior_name => $behavior) {
$is_existing = FALSE;
$is_existing = db_num_rows(db_query("SELECT * FROM {sms_mapping} WHERE module = '%s' AND behavior = '%s'", $module_name, $behavior_name));
if ($is_existing) {
db_query("UPDATE {sms_mapping} SET gateway = '%s' WHERE module = '%s' AND behavior = '%s'", $behavior['gateway'], $module_name, $behavior_name);
}
else {
db_query('INSERT INTO {sms_mapping} (module, behavior, gateway) VALUES("%s", "%s", "%s")', $module_name, $behavior_name, $behavior['gateway']);
}
}
}
}
drupal_set_message(t('Gateway mappings saved.'));
}
function sms_admin_gateway_form($gateway = NULL, $gateway_id = '') {
if (isset($gateway) && is_array($gateway)) {
$form = $gateway['options'];
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Save'),
);
$form['#validate'] = array('sms_admin_gateway_form_validate' => array(), $gateway['validate'] => array());
$form['gateway'] = array('#type' => 'value', '#value' => $gateway);
$form['gateway_id'] = array('#type' => 'value', '#value' => $gateway_id);
return $form;
}
}
function sms_admin_gateway_form_submit($form_id, $form_values) {
$gateway = $form_values['gateway'];
if (is_array($gateway['options'])) {
foreach ($gateway['options'] as $key => $option) {
variable_set($key, $form_values[$key]);
}
}
drupal_set_message(t('The gateway settings have been saved.'));
return 'admin/smsframework/gateways';
}
/**
* Get a list of all gateways
*
* @param $op
* The format in which to return the list. When set to 'gateway' or 'name',
* only the specified gateway is returned. When set to 'gateways' or 'names',
* all gateways are returned.
*
* @param $gateway
* A gateway identifier string that indicates the gateway to return. Leave at default
* value (NULL) to return all gateways.
*
* @return
* Either an array of all gateways or a single gateway, in a variable format.
**/
function sms_gateways($op = 'gateways', $gateway = NULL) {
list($_gateways, $_names) = _gateways_build();
switch ($op) {
case 'gateways':
return $_gateways;
case 'gateway':
return $_gateways[$gateway];
case 'names':
return $_names;
case 'name':
return $_names[$gateway];
}
}
function _gateways_build() {
$_gateways = array();
$_names = array();
$gateway_array = module_invoke_all('gateway_info');
foreach ($gateway_array as $identifier => $info) {
if (is_array($info['options'])) {
foreach ($info['options'] as $key => $option) {
$info['configuration'][$key] = variable_get($key, '');
}
}
$_gateways[$identifier] = $info;
$_names[$identifier] = $info['name'];
}
asort($_names);
return array($_gateways, $_names);
}
/**
* Get a list of all module supplied behaviors
*/
function sms_behaviors($op = 'behaviors', $behavior = NULL) {
list($_behaviors, $_names) = _behaviors_build();
switch ($op) {
case 'behaviors':
return $_behaviors;
case 'behavior':
return $_behaviors[$behavior];
case 'names':
return $_names;
case 'name':
return $_names[$behavior];
}
}
function _behaviors_build() {
$_behaviors = array();
$_names = array();
$behavior_array = module_invoke_all('behavior_info');
foreach ($behavior_array as $identifier => $info) {
if (is_array($info['options'])) {
foreach ($info['options'] as $key => $option) {
$info['configuration'][$key] = variable_get($key, '');
}
}
$_behaviors[$identifier] = $info;
$_names[$identifier] = $info['name'];
}
asort($_names);
return array($_behaviors, $_names);
}
function sms_behavior_gateway($module, $behavior) {
$mappings = _sms_mappings();
if ($mappings[$module][$behavior]) {
return $mappings[$module][$behavior];
}
return 0;
}
function _sms_mappings($reset = FALSE) {
static $mappings;
if ($reset || !isset($mappings)) {
$mappings = array();
$gateway_result = db_query('SELECT module, behavior, gateway FROM {sms_mapping}');
while ($row = db_fetch_array($gateway_result)) {
$mappings[$row['module']][$row['behavior']] = $row['gateway'];
}
}
return $mappings;
}
/**
* Sends a message using the active gateway.
*
* @param $destination
* An array of $destination objects. Each object must at least contain $destination->number. Additional properties may be defined by gateways.
* @param $message
* The text of the messsage to send.
* @param $extra
*/
function sms_send($destinations, $message, $extra = array()) {
if (!is_array($destinations)) {
return 0;
}
$gateway_id = sms_behavior_gateway($extra['module'], $extra['behavior']);
if (!$gateway_id) {
$gateway_id = variable_get('sms_default_gateway', 0);
}
$gateway = sms_gateways('gateway', $gateway_id);
if (function_exists($gateway['send'])) {
$gateway['send']($destinations, $message);
}
}
function sms_log_message($number, $message, $gateway) {
$mid = db_next_id('{sms_messages}');
if (db_query('INSERT INTO {sms_messages} (mid, sent, status, destination, message, gateway) VALUES(%d, %d, %d, "%s", "%s", "%s")', $mid, time(), 0, $number, $message, $gateway['identifier'])) {
return $mid;
}
}
function sms_number_format($number) {
$gateway = sms_gateways('gateway', variable_get('sms_default_gateway', 0));
if ($gateway['number_formatter'] && function_exists($gateway['number_formatter'])) {
return $gateway['number_formatter']($number_formatter);
}
else {
return $number;
}
}
function sms_formatter($number, $format = 1) {
// Remove non-number characters
$number = preg_replace("/[^0-9]/", '', $number);
if (strlen($number) > 10) {
if ($number[0] == 1) {
$number = ltrim($number, 1);
}
else {
return FALSE;
}
}
elseif (strlen($number) < 10) {
return FALSE;
}
return $number;
}
/**
* Generates a SMS sending form and adds gateway defined elements
*
* TODO
* - If the user is logged in, look for a number stored
* - Show a 'remeber this info' field and store as a cookie depending on admin settings
*/
function sms_send_form($form = NULL, $destination = NULL, $required = TRUE) {
$gateway_id = sms_behavior_gateway($form['module']['#value'], $form['behavior']['#value']);
if ($gateway_id) {
$gateway = sms_gateways('gateway', $gateway_id);
}
else {
$gateway = sms_gateways('gateway', variable_get('sms_default_gateway', 0));
}
$sms_form['number'] = array(
'#type' => 'textfield',
'#title' => t('Phone number'),
'#size' => 40,
'#maxlength' => 255,
'#required' => $required,
'#weight' => -5,
'#default_value' => $destination->number,
);
if ($gateway['send_form'] && function_exists($gateway['send_form'])) {
$sms_form['gateway']['#tree'] = TRUE;
$sms_form['gateway']['#weight'] = -5;
$sms_form['gateway'] += $gateway['send_form']($destination, $required);
}
if (is_array($form)) {
$form['sms'] = $sms_form;
$form['#base'] = 'sms_send_form';
$form['submit'] = array(
'#type' => 'submit',
'#value' => t('Send'),
'#weight' => 20,
);
return $form;
}
return $sms_form;
}
/**
* Performs a simple send on submit.
*
*/
function sms_send_form_submit($form_id, $form_values) {
$form_values['number'] = sms_formatter($form_values['number']);
foreach ($form_values['gateway'] as $key => $gateway_fields) {
$destination->$key = $gateway_fields;
}
$destination->number = $form_values['number'];
sms_send(array($destination), $form_values['message'], $form_values);
}
function sms_send_form_validate($form_id, &$form_values) {
if (!sms_formatter($form_values['number'])) {
form_set_error('number', t('You must enter a valid ten digit phone number.'));
}
}