/[drupal]/contributions/modules/smsframework/sms.module
ViewVC logotype

Contents of /contributions/modules/smsframework/sms.module

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.14 - (show annotations) (download) (as text)
Fri Sep 5 20:05:17 2008 UTC (14 months, 3 weeks ago) by diggersf
Branch: MAIN
CVS Tags: HEAD
Changes since 1.13: +13 -1 lines
File MIME type: text/x-php
* Improved validation with sms_validate_number()
* Gateways can now define callbacks for custom validation.
1 <?php
2 // $Id: sms.module,v 1.13 2008/08/21 13:25:24 diggersf Exp $
3
4 /**
5 * @file
6 * The core of the SMS Framework. Provides gateway managment and API for
7 * sending and receiving SMS messages.
8 */
9
10 /**
11 * Sends a message using the active gateway.
12 *
13 * @param $number
14 * The destination number.
15 *
16 * @param $message
17 * The text of the messsage to send.
18 *
19 * @param $options
20 * An array of dditional properties as defined by gateway modules.
21 */
22 function sms_send($number, $message, $options = array()) {
23 $gateway = sms_default_gateway();
24
25 foreach (module_implements('sms_send') as $module) {
26 $function = $module .'_sms_send';
27 $function($number, $message, $options, $gateway);
28 }
29
30 if (function_exists($gateway['send'])) {
31 $response = $gateway['send']($number, $message, $options);
32 }
33 return sms_handle_result($response, $number, $message);
34 }
35
36 /**
37 * Callback for incoming messages. Allows gateways modules to pass messages in
38 * a standard format for processing.
39 *
40 * @param $number
41 * The sender's mobile number.
42 *
43 * @param $message
44 * The content of the text message.
45 */
46 function sms_incoming($number, $message) {
47 // Execute three phases
48 module_invoke_all('sms_incoming', 'pre process', $number, $message);
49 module_invoke_all('sms_incoming', 'process', $number, $message);
50 module_invoke_all('sms_incoming', 'post process', $number, $message);
51 }
52
53 /**
54 * Returns the current default gateway.
55 */
56 function sms_default_gateway() {
57 return sms_gateways('gateway', variable_get('sms_default_gateway', 'log'));
58 }
59
60 /**
61 * Implementation of hook_gateway_info().
62 */
63 function sms_gateway_info() {
64 return array(
65 'log' => array(
66 'name' => t('Log only'),
67 'send' => 'sms_send_log',
68 ),
69 );
70 }
71
72 function sms_send_log($number, $message, $options) {
73 watchdog('sms', 'SMS message sent to %number with the text: @message', array('%number' => $number, '@message' => $message), WATCHDOG_INFO);
74 return array('status' => TRUE);
75 }
76
77 /**
78 * Implementation of hook_menu().
79 */
80 function sms_menu() {
81 $items = array();
82
83 $items['admin/smsframework'] = array(
84 'title' => 'SMS Framework',
85 'description' => 'Control how your site uses SMS.',
86 'position' => 'right',
87 'page callback' => 'system_admin_menu_block_page',
88 'access arguments' => array('administer smsframework'),
89 'file' => 'system.admin.inc',
90 'file path' => drupal_get_path('module', 'system')
91 );
92
93 $items['admin/smsframework/gateways'] = array(
94 'title' => 'Gateway configuration',
95 'description' => 'Configure gateways and chose the default gateway.',
96 'page callback' => 'drupal_get_form',
97 'page arguments' => array('sms_admin_default_form', NULL),
98 'access arguments' => array('administer smsframework'),
99 );
100
101 $items['admin/smsframework/gateways/%'] = array(
102 'title callback' => 'sms_admin_gateway_title',
103 'title arguments' => array(3),
104 'page callback' => 'drupal_get_form',
105 'page arguments' => array('sms_admin_gateway_form', 3),
106 'access arguments' => array('administer smsframework'),
107 'type' => MENU_CALLBACK,
108 );
109 return $items;
110 }
111
112 /**
113 * Implementation of hook_perm().
114 */
115 function sms_perm() {
116 return array('administer smsframework');
117 }
118
119 /**
120 * Implementation of hook_theme().
121 */
122 function sms_theme() {
123 return array(
124 'sms_admin_default_form' => array(
125 'arguments' => array('form' => NULL),
126 )
127 );
128 }
129
130 /**
131 * SMS gateway menutitle callback.
132 */
133 function sms_admin_gateway_title($gateway_id) {
134 $gateway = sms_gateways('gateway', $gateway_id);
135 return sprintf('%s gateway', $gateway['name']);
136 }
137
138 function sms_admin_default_form() {
139 $gateways = sms_gateways();
140
141 foreach ($gateways as $identifier => $gateway) {
142 $active = ($identifier == variable_get('sms_default_gateway', 'log'));
143 $options[$identifier] = '';
144 $form[$gateway['name']]['id'] = array('#value' => $identifier);
145 if (function_exists($gateway['configure form'])) {
146 $form[$gateway['name']]['configure'] = array('#value' => l(t('configure'), 'admin/smsframework/gateways/'. $identifier));
147 }
148 else {
149 $form[$gateway['name']]['configure'] = array('#value' => t('No configuration options'));
150 }
151 }
152 $form['default'] = array('#type' => 'radios', '#options' => $options, '#default_value' => variable_get('sms_default_gateway', 'log'));
153
154 $form['submit'] = array(
155 '#type' => 'submit',
156 '#value' => t('Set default gateway'),
157 );
158
159 return $form;
160 }
161
162 function sms_admin_default_form_submit($form, &$form_state) {
163 // Process form submission to set the default gateway
164 if ($form_state['values']['default']) {
165 drupal_set_message(t('Default gateway updated.'));
166 variable_set('sms_default_gateway', $form_state['values']['default']);
167 }
168 }
169
170 function theme_sms_admin_default_form($form) {
171 $rows = array();
172 foreach ($form as $name => $element) {
173 if (isset($element['id']) && is_array($element['id'])) {
174 $rows[] = array(
175 drupal_render($form['default'][$element['id']['#value']]),
176 check_plain($name),
177 drupal_render($element['configure']),
178 );
179 unset($form[$name]);
180 }
181 }
182 $header = array(t('Default'), t('Name'), array('data' => t('Operations'), 'colspan' => 1));
183 $output .= theme('table', $header, $rows);
184 $output .= drupal_render($form);
185
186 return $output;
187 }
188
189 function sms_admin_gateway_form(&$form_state, $gateway_id) {
190 $gateway = sms_gateways('gateway', $gateway_id);
191 if ($gateway && function_exists($gateway['configure form'])) {
192 drupal_set_title(t('@gateway configuration', array('@gateway' => $gateway['name'])));
193 $form = $gateway['configure form']($gateway['configuration']);
194
195 $form['submit'] = array(
196 '#type' => 'submit',
197 '#value' => t('Save'),
198 );
199 $form['gateway'] = array('#type' => 'value', '#value' => $gateway);
200
201 return $form;
202 }
203 drupal_not_found();
204 exit();
205 }
206
207 /**
208 * Validation for gateway configuration. If the gateway defines a validation
209 * function it uses that.
210 */
211 function sms_admin_gateway_form_validate($form, &$form_state) {
212 // Pass validation to gateway
213 $function = $form_state['values']['gateway']['configure form'] .'_validate';
214 if (function_exists($function)) {
215 $function($form, &$form_state);
216 }
217 }
218
219 function sms_admin_gateway_form_submit($form, &$form_state) {
220 $gateway = $form_state['values']['gateway'];
221
222 // Remove uneccesary values
223 unset($form_state['values']['op'], $form_state['values']['submit'], $form_state['values']['gateway'], $form_state['values']['form_token'], $form_state['values']['form_id']);
224 variable_set('sms_'. $gateway['identifier'] .'_settings', $form_state['values']);
225 drupal_set_message(t('The gateway settings have been saved.'));
226 $form_state['redirect'] = 'admin/smsframework/gateways';
227 }
228
229 /**
230 * Get a list of all gateways
231 *
232 * @param $op
233 * The format in which to return the list. When set to 'gateway' or 'name',
234 * only the specified gateway is returned. When set to 'gateways' or 'names',
235 * all gateways are returned.
236 *
237 * @param $gateway
238 * A gateway identifier string that indicates the gateway to return. Leave at default
239 * value (NULL) to return all gateways.
240 *
241 * @return
242 * Either an array of all gateways or a single gateway, in a variable format.
243 **/
244 function sms_gateways($op = 'gateways', $gateway = NULL) {
245 list($_gateways, $_names) = _gateways_build();
246
247 switch ($op) {
248 case 'gateways':
249 return $_gateways;
250 case 'gateway':
251 $return = $_gateways[$gateway];
252 $return['identifier'] = $gateway;
253 return $return;
254 case 'names':
255 return $_names;
256 case 'name':
257 return $_names[$gateway];
258 }
259 }
260
261 function _gateways_build() {
262 $_gateways = array();
263 $_names = array();
264
265 $gateway_array = module_invoke_all('gateway_info');
266 foreach ($gateway_array as $identifier => $info) {
267 $info['configuration'] = variable_get('sms_'. $identifier .'_settings', '');
268 $_gateways[$identifier] = $info;
269 $_names[$identifier] = $info['name'];
270 }
271
272 asort($_names);
273
274 return array($_gateways, $_names);
275 }
276
277 function sms_handle_result($result, $number, $message) {
278 if ($result['status']) {
279 return TRUE;
280 }
281 else {
282 $error_message = 'Sending SMS to %number failed.';
283 $variables['%number'] = $number;
284 if ($result['message']) {
285 $error_message .= ' The gateway said '. $result['message'];
286 if (!empty($result['variables'])) {
287 $variables = array_merge($variables, $result['variables']);
288 }
289 }
290 watchdog('sms', $error_message, $variables, WATCHDOG_ERROR);
291 return FALSE;
292 }
293 }
294
295 function sms_number_format($number) {
296 $gateway = sms_default_gateway();
297
298 if ($gateway['number_formatter'] && function_exists($gateway['number_formatter'])) {
299 return $gateway['number_formatter']($number_formatter);
300 }
301 else {
302 return $number;
303 }
304 }
305
306 function sms_formatter($number, $format = 1) {
307 // Remove non-number characters
308 $number = preg_replace("/[^0-9]/", '', $number);
309
310 if (strlen($number) > 16) {
311 if ($number[0] == 1) {
312 $number = ltrim($number, 1);
313 }
314 else {
315 return FALSE;
316 }
317 }
318 elseif (strlen($number) < 10) {
319 return FALSE;
320 }
321
322 return $number;
323 }
324
325 /**
326 * Generates a SMS sending form and adds gateway defined elements. The form
327 * array that is returned can be merged with an existing form using
328 * array_merge().
329 *
330 * @param $required
331 * Specify if the user is required to provide information for the fields.
332 *
333 * @return $form
334 */
335 function sms_send_form($required = FALSE) {
336 $gateway = sms_default_gateway();
337 $form['number'] = array(
338 '#type' => 'textfield',
339 '#title' => t('Phone number'),
340 '#size' => 40,
341 '#maxlength' => 255,
342 '#required' => $required,
343 );
344
345 // Add gateway defined fields
346 if (function_exists($gateway['send form'])) {
347 $form['gateway']['#tree'] = TRUE;
348 $form['gateway'] = array_merge($gateway['send form']($required), $form['gateway']);
349 }
350
351 return $form;
352 }
353
354 function sms_send_form_validate($form, &$form_state) {
355 if (!sms_formatter($form_state['values']['number'])) {
356 form_set_error('number', t('You must enter a valid phone number.'));
357 }
358 }
359
360 function sms_validate_number(&$number) {
361 if (!strlen($number) || !$number = sms_formatter($number)) {
362 return t('The phone number is invalid.');
363 }
364
365 // Allow the active gateway to provide number validation
366 $gateway = sms_default_gateway();
367 if (function_exists($gateway['validate number']) && $error = $gateway['validate number']($number)) {
368 return $error;
369 }
370 }
371
372 /**
373 * Performs a simple send on submit.
374 */
375 function sms_send_form_submit($form, &$form_state) {
376 $form_state['values']['number'] = sms_formatter($form_state['values']['number']);
377 sms_send($form_state['values']['number'], $form_state['values']['message'], $form_state['values']['gateway']);
378 }

  ViewVC Help
Powered by ViewVC 1.1.2