'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.')); } }