diff --git modules/sms_user/includes/sms_user_handler_field_status.inc modules/sms_user/includes/sms_user_handler_field_status.inc index 0439f2e..f74881a 100644 --- modules/sms_user/includes/sms_user_handler_field_status.inc +++ modules/sms_user/includes/sms_user_handler_field_status.inc @@ -16,6 +16,7 @@ class sms_user_handler_field_status extends views_handler_field { $status_defined = array( SMS_USER_PENDING => t('Pending'), SMS_USER_CONFIRMED => t('Confirmed'), + SMS_USER_ACTIVE => t('Confirmed and Active'), ); return $status_defined[$status]; } diff --git modules/sms_user/includes/sms_user_handler_filter_status.inc modules/sms_user/includes/sms_user_handler_filter_status.inc index 2fd164f..a23fba7 100644 --- modules/sms_user/includes/sms_user_handler_filter_status.inc +++ modules/sms_user/includes/sms_user_handler_filter_status.inc @@ -15,6 +15,7 @@ class sms_user_handler_filter_status extends views_handler_filter_in_operator { $this->value_options = array( SMS_USER_PENDING => t('Pending'), SMS_USER_CONFIRMED => t('Confirmed'), + SMS_USER_ACTIVE => t('Confirmed and Active'), ); } } diff --git modules/sms_user/sms_user.admin.inc modules/sms_user/sms_user.admin.inc index 033e3f4..0e47853 100644 --- modules/sms_user/sms_user.admin.inc +++ modules/sms_user/sms_user.admin.inc @@ -35,6 +35,13 @@ function sms_user_admin_settings() { $form['tokens']['content']['#value'] = theme('token_help', 'sms_user'); + $form['sms_user_multiple_numbers'] = array( + '#type' => 'checkbox', + '#title' => t('Enable multiple mobile numbers'), + '#description' => t('If checked, users will be able to add more than one mobile number for their account. One can be set active for outgoing messages, all work for incoming.'), + '#default_value' => variable_get('sms_user_multiple_numbers', FALSE), + ); + $form['sms_user_sleep'] = array( '#type' => 'checkbox', '#title' => t('Enable sleep hours'), diff --git modules/sms_user/sms_user.install modules/sms_user/sms_user.install index 3dc643e..9cb048c 100644 --- modules/sms_user/sms_user.install +++ modules/sms_user/sms_user.install @@ -13,6 +13,7 @@ function sms_user_install() { function sms_user_schema() { $schema['sms_user'] = array( 'fields' => array( + 'sid' => array('description' => 'SMS number id', 'type' => 'serial', 'unsigned' => TRUE, 'not null' => TRUE, ), 'uid' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE), 'number' => array('type' => 'varchar', 'not null' => TRUE, 'length' => 32), 'status' => array('type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE), @@ -20,12 +21,19 @@ function sms_user_schema() { 'gateway' => array('type' => 'text'), ), 'primary key' => array('number'), - 'indexes' => array('uid' => array('uid')), + 'indexes' => array('uid' => array('uid'), 'sid' => array('sid')), ); return $schema; } +function sms_user_update_2() { + $ret = array(); + // @todo update all SMS_USER_CONFIRMED 2 status to SMS_USER_ACTIVE 3 + return $ret; +} + + /** * Implementation of hook_update(). * @@ -56,4 +64,4 @@ function sms_user_uninstall() { variable_del($variable); } -} \ No newline at end of file +} diff --git modules/sms_user/sms_user.module modules/sms_user/sms_user.module index 1f6cfc6..230b8e5 100644 --- modules/sms_user/sms_user.module +++ modules/sms_user/sms_user.module @@ -7,6 +7,7 @@ define('SMS_USER_PENDING', 1); define('SMS_USER_CONFIRMED', 2); +define('SMS_USER_ACTIVE', 3); define('SMS_USER_MAX_CHARS', 140); @@ -34,23 +35,65 @@ function sms_user_menu() { 'description' => 'Edit options for SMS and user integration.', 'page callback' => 'drupal_get_form', 'page arguments' => array('sms_user_admin_settings'), - 'access arguments' => array('administer sms'), + 'access arguments' => array('administer smsframework'), 'file' => 'sms_user.admin.inc', ); $items['user/%user/edit/mobile'] = array( 'title' => 'Mobile', - 'page callback' => 'sms_user_settings', + 'page callback' => 'sms_user_settings_page', 'page arguments' => array(1), 'type' => MENU_LOCAL_TASK, 'access callback' => 'sms_user_edit_access', 'access arguments' => array(1), 'tab_parent' => 'user/%/edit', + 'file' => 'sms_user.settings.inc', ); + + $items['user/%user/edit/mobile/add'] = array( + 'title' => 'Add mobile number', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('sms_user_settings_add_form', 1), + 'type' => MENU_CALLBACK, + 'access callback' => 'sms_user_edit_access', // @todo and not if set and no multiple + 'access arguments' => array(1), + 'file' => 'sms_user.settings.inc', + ); + + $items['user/%user/edit/mobile/%/delete'] = array( + 'title' => 'Delete mobile number', + 'page callback' => 'drupal_get_form', + 'page arguments' => array('sms_user_settings_delete_form', 1, 4), + 'type' => MENU_CALLBACK, + 'access callback' => 'sms_user_delete_access', + 'access arguments' => array(1, 4), + 'file' => 'sms_user.settings.inc', + ); + return $items; } /** + * Implementation of hook_theme(). + */ +function sms_user_theme() { + return array( + 'sms_user_settings_page' => array( + 'arguments' => array('content' => NULL), + 'file' => 'sms_user.settings.inc', + ), + 'sms_user_settings_active_form' => array( + 'arguments' => array('form' => NULL), + 'file' => 'sms_user.settings.inc', + ), + 'sms_user_settings_confirm_form' => array( + 'arguments' => array('form' => NULL), + 'file' => 'sms_user.settings.inc', + ), + ); +} + +/** * Access control on edit users sms number. */ function sms_user_edit_access($account) { @@ -58,6 +101,18 @@ function sms_user_edit_access($account) { } /** + * Access control on delete users sms number. + */ +function sms_user_delete_access($account, $number) { + if (sms_user_edit_access($account)) { + if ($account->uid == sms_user_get_uid($number)) { + return TRUE; + } + } + return FALSE; +} + +/** * Send a message to a user. */ function sms_user_send($uid, $message) { @@ -132,212 +187,6 @@ function _sms_user_sleep_active($account) { return FALSE; } -/** - * Menu callback; provides the forms for adding and confirming a user's mobile number. - */ -function sms_user_settings($account) { - switch (isset($account->sms_user) ? $account->sms_user['status'] : 0) { - case 0: - $output = drupal_get_form('sms_user_settings_add_form', $account); - break; - case SMS_USER_PENDING: - $output = drupal_get_form('sms_user_settings_confirm_form', $account); - break; - case SMS_USER_CONFIRMED: - $output = drupal_get_form('sms_user_settings_reset_form', $account); - break; - } - - if (variable_get('sms_user_sleep', 1)) { - $output .= drupal_get_form('sms_user_settings_sleep_form', $account); - } - - return $output; -} - -function sms_user_settings_add_form(&$form_state, $account) { - $form = sms_send_form(); - $form['uid'] = array( - '#type' => 'hidden', - '#value' => $account->uid, - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Confirm number'), - ); - - return $form; -} - -function sms_user_settings_add_form_validate($form, &$form_state) { - if ($error = sms_user_validate_number($form_state['values']['number'])) { - form_set_error('number', $error); - } - - if (empty($form_state['values']['gateway'])) { - $form_state['values']['gateway'] = array(); - } -} - -function sms_user_settings_add_form_submit($form, &$form_state, $account = NULL) { - if (!$account) { - $account = user_load(array('uid' => $form_state['values']['uid'])); - } - sms_user_send_confirmation($account, $form_state['values']['number'], $form_state['values']['gateway']); -} - -function sms_user_settings_confirm_form(&$form_state, $account) { - $form['uid'] = array( - '#type' => 'hidden', - '#value' => $account->uid, - ); - $form['number'] = array( - '#type' => 'item', - '#title' => t('Mobile phone number'), - '#value' => $account->sms_user['number'], - ); - $form['confirm_code'] = array( - '#type' => 'textfield', - '#title' => t('Confirmation code'), - '#description' => t('Enter the confirmation code sent by SMS to your mobile phone.'), - '#size' => 4, - '#maxlength' => 4, - ); - $form['submit'] = array( - '#type' => 'submit', - '#value' => t('Confirm number'), - ); - $form['reset'] = array( - '#type' => 'submit', - '#value' => t('Delete & start over'), - '#access' => user_access('edit own sms number'), - ); - return $form; -} - -function sms_user_settings_confirm_form_validate($form, &$form_state) { - if ($form_state['clicked_button']['#value'] == t('Confirm number')) { - $account = user_load(array('uid' => $form_state['values']['uid'])); - if ($form_state['values']['confirm_code'] != $account->sms_user['code']) { - form_set_error('confirm_code', t('The confirmation code is invalid.')); - } - } -} - -function sms_user_settings_confirm_form_submit($form, &$form_state) { - $account = user_load(array('uid' => $form_state['values']['uid'])); - if ($form_state['clicked_button']['#value'] == t('Delete & start over')) { - sms_user_delete($account->uid); - } - else { - $data = array( - 'number' => $account->sms_user['number'], - 'status' => SMS_USER_CONFIRMED, - 'gateway' => $account->sms_user['gateway'], - ); - - user_save($account, array('sms_user' => $data), 'mobile'); - // If the rule module is installed, fire rules - if (module_exists('rules')) { - rules_invoke_event('sms_user_validated', $account); - } - } -} - -function sms_user_settings_reset_form(&$form_state, $account) { - $form['uid'] = array( - '#type' => 'hidden', - '#value' => $account->uid, - ); - $form['sms_user']['number'] = array( - '#type' => 'item', - '#title' => t('Your mobile phone number'), - '#value' => $account->sms_user['number'], - '#description' => t('Your mobile phone number has been confirmed.') - ); - - $form['reset'] = array( - '#type' => 'submit', - '#value' => t('Delete & start over'), - '#access' => user_access('edit own sms number'), - ); - - return $form; -} - -function sms_user_settings_reset_form_submit($form, &$form_state) { - $account = user_load(array('uid' => $form_state['values']['uid'])); - sms_user_delete($account->uid); - if (module_exists('rules')) { - rules_invoke_event('sms_user_removed', $account); - } - drupal_set_message(t('Your mobile information has been removed'), 'status'); -} - -function sms_user_settings_sleep_form(&$form_state, $account) { - $form['uid'] = array( - '#type' => 'hidden', - '#value' => $account->uid, - ); - $form['sleep'] = array( - '#type' => 'fieldset', - '#title' => t('Sleep Time'), - '#collapsible' => TRUE, - ); - - $form['sleep']['sleep_enabled'] = array( - '#type' => 'checkbox', - '#title' => t('Disable messages between these hours'), - '#description' => t('If enabled, you will not receive messages between the specified hours.'), - '#default_value' => isset($account->sms_user['sleep_enabled']) ? $account->sms_user['sleep_enabled'] : NULL, - ); - - // Determine whether to use the 24-hour or 12-hour clock based on site settings - if (strpos(variable_get('date_format_short', 'm/d/Y - H:i'), 'g')) { - $format = 'g A'; - } - else { - $format = 'H:00'; - } - // Build the list of options based on format - $hour = 0; - while ($hour < 24) { - $options[$hour] = date($format, mktime($hour)); - $hour++; - } - - $form['sleep']['sleep_start_time'] = array( - '#type' => 'select', - '#multiple' => FALSE, - '#options' => $options, - '#default_value' => isset($account->sms_user['sleep_start_time']) ? $account->sms_user['sleep_start_time'] : NULL, - ); - - $form['sleep']['sleep_end_time'] = array( - '#type' => 'select', - '#multiple' => FALSE, - '#options' => $options, - '#default_value' => isset($account->sms_user['sleep_end_time']) ? $account->sms_user['sleep_end_time'] : NULL, - ); - - $form['sleep']['save'] = array( - '#type' => 'submit', - '#value' => t('Save'), - ); - - return $form; -} - -function sms_user_settings_sleep_form_submit($form, &$form_state) { - $account = user_load(array('uid' => $form_state['values']['uid'])); - $data = $account->sms_user; - $data['sleep_enabled'] = $form_state['values']['sleep_enabled']; - $data['sleep_start_time'] = $form_state['values']['sleep_start_time']; - $data['sleep_end_time'] = $form_state['values']['sleep_end_time']; - user_save($account, array('sms_user' => $data), 'mobile'); - drupal_set_message(t('The changes have been saved.'), 'status'); -} - function sms_user_send_confirmation($account, $number, $options) { $code = rand(1000, 9999); $number = sms_formatter($number); @@ -347,11 +196,54 @@ function sms_user_send_confirmation($account, $number, $options) { 'code' => $code, 'gateway' => $options, ); - user_save($account, array('sms_user' => $data), 'mobile'); sms_send($number, _sms_user_confirm_message($code), $options); } +/** + * Confirm a number with confirmation code. + * + * @param $account + * user object. + * @param $number + * number to confirm. + * @param $code + * confirmation code. + * @param + * bool TRUE if only validating and not confirming. + * @return + * bool TRUE if code correct for number. + */ +function sms_user_confirm($account, $number, $code, $validate = FALSE) { + foreach ($account->sms_user as $acc_number) { + if ($acc_number['number'] == $number) { + if ($acc_number['code'] != $code) { + // incorrect code. + return FALSE; + } + if (! $validate) { + $data = array( + 'number' => $number, + 'status' => isset($account->sms_user[1]) ? SMS_USER_CONFIRMED : SMS_USER_ACTIVE, + 'gateway' => $acc_number['gateway'], + ); + + user_save($account, array('sms_user' => $data), 'mobile'); + // If the rule module is installed, fire rules + if (module_exists('rules')) { + rules_invoke_event('sms_user_validated', $account); + } + } + + // correct code for number. + return TRUE; + } + } + + // incorrect number. + return FALSE; +} + function sms_user_validate_number(&$number) { if ($error = sms_validate_number($number)) { return $error; @@ -368,7 +260,7 @@ function sms_user_user($op, &$edit, &$account, $category = NULL) { global $user; switch ($op) { case 'load': - return sms_user_load($edit, $account, $category); + return sms_user_load($account, $category); case 'update': case 'insert': return sms_user_save($edit, $account, $category); @@ -403,7 +295,7 @@ function sms_user_user($op, &$edit, &$account, $category = NULL) { break; case 'login': // Check if first it's the user's first time logging in. - if (!$account->access && !empty($account->sms_user['number']) && $account->sms_user['status'] != SMS_USER_CONFIRMED) { + if (!$account->access && !empty($account->sms_user['number']) && $account->sms_user['status'] < SMS_USER_CONFIRMED) { sms_user_send_confirmation($account, $account->sms_user['number'], $account->sms_user['gateway']); drupal_set_message(t('A confirmation message has been sent to your mobile phone. Please !link.', array('!link' => l(t('confirm your number'), 'user/'. $account->uid .'/edit/mobile'))), 'status'); } @@ -421,24 +313,40 @@ function sms_user_user($op, &$edit, &$account, $category = NULL) { /** * Load user mobile data into the user object. * + * @todo this is called often, the $account->sms_user content could be + * update and trusted? * @see sms_user_user() */ -function sms_user_load(&$edit, &$account, $category) { - $result = db_query("SELECT number, status, code, gateway FROM {sms_user} WHERE uid = %d", $account->uid); - +function sms_user_load(&$account, $category) { $account->sms_user = array(); - while ($data = db_fetch_array($result)) { + + if (variable_get('sms_user_sleep', 1)) { + // all the sms_user data is stored in {users}.data + // using this for sleep settings, + // but trusting the {sms_user} table for numbers $user_data = unserialize($account->data); - $account->sms_user = $user_data['sms_user']; - $account->sms_user['number'] = $data['number']; - $account->sms_user['status'] = $data['status']; - $account->sms_user['code'] = $data['code']; - $account->sms_user['gateway'] = unserialize($data['gateway']); + $account->sms_user['sleep_enabled'] = isset($user_data['sms_user']['sleep_enabled']) ? $user_data['sms_user']['sleep_enabled'] : FALSE; + $account->sms_user['sleep_start_time'] = isset($user_data['sms_user']['sleep_start_time']) ? $user_data['sms_user']['sleep_start_time'] : 0; + $account->sms_user['sleep_end_time'] = isset($user_data['sms_user']['sleep_end_time']) ? $user_data['sms_user']['sleep_end_time'] : 0; } - // @todo: the following is to support messaging that expect account details - // with a delta of 0 - $account->sms_user[0] = $account->sms_user; + $result = db_query("SELECT number, status, code, gateway FROM {sms_user} WHERE uid = %d", $account->uid); + + while ($data = db_fetch_array($result)) { + $data['gateway'] = unserialize($data['gateway']); + + /** + * At present modules access $sms_user['field'] + * or $sms_user[0]['field'] to get the active number's 'field'. + */ + if ($data['status'] == SMS_USER_ACTIVE) { + array_unshift($account->sms_user, $data); + array_merge($account->sms_user, $data); + } + else { + $account->sms_user[] = $data; + } + } } /** @@ -449,18 +357,15 @@ function sms_user_load(&$edit, &$account, $category) { function sms_user_save(&$edit, &$account, $category) { if (($category == 'mobile' || $category == 'account') && $edit['sms_user']) { $number = $edit['sms_user']; - $db_values = array($number['number'], $number['status'], isset($number['code']) ? $number['code'] : NULL, serialize($number['gateway'])); + $number['gateway'] = serialize($number['gateway']); + $number['uid'] = $account->uid; - db_query("UPDATE {sms_user} SET number = '%s', status = %d, code = '%s', gateway = '%s' - WHERE uid = %d AND number = '%s'", array_merge($db_values, array($account->uid, $number['number']))); - if ($number['number'] && !db_affected_rows()) { - db_query("INSERT INTO {sms_user} (number, status, code, gateway, uid) - VALUES ('%s', %d, '%s', '%s', %d)", array_merge($db_values, array($account->uid))); + drupal_write_record('sms_user', $number, array('number', 'uid')); + if (! db_affected_rows()) { + $result = drupal_write_record('sms_user', $number); } - $edit['sms_user']['number'] = NULL; - $edit['sms_user']['status'] = NULL; - $edit['sms_user']['code'] = NULL; - $edit['sms_user']['gateway'] = NULL; + + $account->sms_user = $edit; } } @@ -472,6 +377,8 @@ function sms_user_save(&$edit, &$account, $category) { * @param $number * The number to delete. Defaults to FALSE which will delete all numbers. * + * Note: this doesn't delete from $account->sms_user that removed on re-load. + * * @see sms_user_user() */ function sms_user_delete($uid, $number = FALSE) { @@ -488,6 +395,21 @@ function sms_user_delete($uid, $number = FALSE) { } /** + * Set active number. + * + * For sms_user_multiple_numbers. + * + * @param $uid + * User id. + * @param $number + * Mobile number to set as default. + */ +function sms_user_active_set($uid, $number) { + db_query('UPDATE {sms_user} SET status = %d WHERE uid = %d AND status = %d', SMS_USER_CONFIRMED, $uid, SMS_USER_ACTIVE); + db_query("UPDATE {sms_user} SET status = %d WHERE uid = %d AND number = '%s'", SMS_USER_ACTIVE, $uid, $number); +} + +/** * Create a confirmation message sent to a user, this contains a code which is * used to confirm that the number is actually correct. * @@ -765,8 +687,62 @@ function sms_user_logout() { } /** + * Helper function returns numbers array indexed by status, or number. + * + * @param $account + * User object. + * @param $index + * string key to use to index. + * @param $nocache + * bool set to true when user account could have just been updated. + * @return + * array numbers indexed by key value. + */ +function sms_user_numbers($account, $index, $nocache = FALSE) { + static $numbers = array(); + + if ($nocache) { + $numbers[$account->uid] = array(); + } + + if (! isset($numbers[$account->uid][$index])) { + foreach ($account->sms_user as $key => $number) { + // skip the active number elements that are included as $sms_user['key']; + if (! is_numeric($key) || ! is_array($number)) { + continue; + } + if ($index == 'number') { + $numbers[$account->uid][$index][$number[$index]] = $number; + } + else { + $numbers[$account->uid][$index][$number[$index]][] = $number; + } + } + } + + return $numbers[$account->uid][$index]; +} + +/** * Implementation of hook_views_api(). */ function sms_user_views_api() { return array('api' => 2); } + +/** + * Implements hook_usermerge_merge_users(). + * + * Takes numbers from user to delete and adds them to user to keep. + * @todo sleep settings. + */ +function sms_user_usermerge_merge_users($user_to_delete, $user_to_keep) { + $numbers = db_query('SELECT * FROM {sms_user} WHERE uid = %d', $user_to_delete->uid); + while ($number = db_fetch_object($numbers)) { + $number->uid = $user_to_keep->uid; + if (! drupal_write_record('sms_user', $number, 'number')) { + // bail out - @todo error + return; + } + } +} diff --git modules/sms_user/sms_user.settings.inc modules/sms_user/sms_user.settings.inc new file mode 100644 index 0000000..8dd632c --- /dev/null +++ modules/sms_user/sms_user.settings.inc @@ -0,0 +1,421 @@ + 'value', '#value' => $account->uid); + $form['add'] = sms_send_form(); + $form['add']['add_submit'] = array( + '#type' => 'submit', + '#value' => t('Add number'), + ); + + // place in a fieldset if there is more than one number + if (count($numbers)) { + $form['add']['#type'] = 'fieldset'; + $form['add']['#title'] = t('Add another number'); + $form['add']['#collapsible'] = TRUE; + $form['add']['#collapsed'] = TRUE; + } + return $form; +} + +function sms_user_settings_add_form_validate($form, &$form_state) { + if ($error = sms_user_validate_number($form_state['values']['number'])) { + form_set_error('number', $error); + } + + if (empty($form_state['values']['gateway'])) { + $form_state['values']['gateway'] = array(); + } +} + +function sms_user_settings_add_form_submit($form, &$form_state) { + $account = user_load(array('uid' => $form_state['values']['uid'])); + sms_user_send_confirmation($account, $form_state['values']['number'], $form_state['values']['gateway']); +} + +/** + * Form: Confirm a mobile number. + * + * @param $account + * User object. + * @param $number + * Number array (@todo or delta?) + */ +function sms_user_settings_confirm_form(&$form_state, $account, $number) { + // get and reset numbers list, return if none pending confirmation. + $numbers = sms_user_numbers($account, 'status', TRUE); + if (! count($numbers[SMS_USER_PENDING])) { + return; + } + + $form = array(); + // force a reload of the numbers, if just changed gets new account + $form['uid'] = array('#type' => 'value', '#value' => $account->uid); + + foreach ($numbers[SMS_USER_PENDING] as $number) { + $form[$number['number']]['confirm_number[' . $number['number'] .']'] = array( + '#type' => 'item', + '#title' => t('Mobile phone number'), + '#value' => $number['number'], + ); + $form[$number['number']]['confirm_code[' . $number['number'] .']'] = array( + '#type' => 'textfield', + '#title' => t('Confirmation code'), + '#description' => t('The code sent by SMS to your mobile phone.'), + '#size' => 4, + '#maxlength' => 4, + '#parent' => $number['number'], + ); + $form[$number['number']]['confirm_submit[' . $number['number'] . ']'] = array( + '#type' => 'submit', + '#value' => t('Confirm'), + ); + $form[$number['number']]['confirm_delete[' . $number['number'] .']'] = array( + '#type' => 'item', + '#value' => l(t('Delete'), 'user/' . $account->uid . '/edit/mobile/' . $number['number'] . '/delete', array('query' => drupal_get_destination())), + '#access' => user_access('edit own sms number'), + ); + } + + return $form; +} + +function sms_user_settings_confirm_form_validate($form, &$form_state) { + $account = user_load(array('uid' => $form_state['values']['uid'])); + $filled = FALSE; + foreach ($form_state['clicked_button']['#post']['confirm_code'] as $number => $code) { + if (! empty($code)) { + $filled = TRUE; + if (! sms_user_confirm($account, $number, $code, TRUE)) { + form_set_error('confirm_code[' . $number . ']', t('The confirmation code for number %number is invalid.', array('%number' => $number))); + } + } + } + // @todo do we want this message, if so it might need attaching to something. + if (! $filled) { + form_set_error(NULL, t('To confirm a number you must enter the code sent by SMS to you mobile phone.')); + } +} + +function sms_user_settings_confirm_form_submit($form, &$form_state) { + $account = user_load(array('uid' => $form_state['values']['uid'])); + foreach ($form_state['clicked_button']['#post']['confirm_code'] as $number => $code) { + if (! empty($code)) { + sms_user_confirm($account, $number, $code); + } + } +} + +/** + * Form: Lists confirmed number(s). For multiples allows setting active number. + */ +function sms_user_settings_active_form(&$form_state, $account) { + $form = array(); + $form['uid'] = array('#type' => 'value', '#value' => $account->uid); + + // we want to list numbers in a consistent order. + $numbers = sms_user_numbers($account, 'number', TRUE); + ksort($numbers); + + foreach ($numbers as $number) { + if ($number['status'] == SMS_USER_PENDING) { + // skip numbers that aren't confirmed. + continue; + } + $row = array(); + $row['number'] = array( + '#type' => 'item', + '#title' => t('Your mobile phone number'), + '#value' => $number['number'], + '#description' => t('Your mobile phone number has been confirmed.') + ); + if (variable_get('sms_user_multiple_numbers', FALSE)) { + $options[$number['number']] = ''; + if ($number['status'] == SMS_USER_ACTIVE) { + $active = $number['number']; + } + } + $row['confirm_delete'] = array( + '#type' => 'item', + '#value' => l(t('Delete'), 'user/' . $account->uid . '/edit/mobile/' . $number['number'] . '/delete', array('query' => drupal_get_destination())), + '#access' => user_access('edit own sms number'), + ); + $form[$number['number']] = $row; + } + + // if there is more than one number, add radio buttons to select the active one. + if (variable_get('sms_user_multiple_numbers', FALSE)) { + $form['active'] = array( + '#type' => 'radios', + '#options' => $options, + '#default_value' => $active, + ); + if (count($options)) { + $form['submit'] = array( + '#type' => 'submit', + '#value' => t('Set active'), + ); + } + } + + return $form; +} + +function sms_user_settings_active_form_submit($form, &$form_state) { + sms_user_active_set($form_state['values']['uid'], $form_state['values']['active']); +} + +/** + * Form: Delete number from account. + */ +function sms_user_settings_delete_form(&$form_state, $account, $number) { + $form = array(); + $form['uid'] = array('#type' => 'value', '#value' => $account->uid); + $form['number'] = array('#type' => 'value', '#value' => $number); + + return confirm_form($form, + t('Are you sure you want to delete mobile number %number?', array('%number' => $number)), + isset($_GET['destination']) ? $_GET['destination'] : 'user/'. $account->uid .'/edit/mobile', + NULL, + t('Delete'), + t('Cancel') + ); +} + +function sms_user_settings_delete_form_submit($form, &$form_state) { + if ($form_state['clicked_button']['#value'] == t('Delete')) { + sms_user_delete($form_state['values']['uid'], $form_state['values']['number']); + } + drupal_goto(); +} + +/** + * Form: Account mobile sleep settings. + * + * @param $account + * User object. + * @param $fieldset + * Bool TRUE if should be in a fieldset. + */ +function sms_user_settings_sleep_form(&$form_state, $account, $fieldset = FALSE) { + $form['uid'] = array('#type' => 'value', '#value' => $account->uid); + + $form['sleep']['sleep_enabled'] = array( + '#type' => 'checkbox', + '#title' => t('Disable messages between these hours'), + '#description' => t('If enabled, you will not receive messages between the specified hours.'), + '#default_value' => isset($account->sms_user['sleep_enabled']) ? $account->sms_user['sleep_enabled'] : NULL, + ); + + // Determine whether to use the 24-hour or 12-hour clock based on site settings + if (strpos(variable_get('date_format_short', 'm/d/Y - H:i'), 'g')) { + $format = 'g A'; + } + else { + $format = 'H:00'; + } + // Build the list of options based on format + $hour = 0; + while ($hour < 24) { + $options[$hour] = date($format, mktime($hour)); + $hour++; + } + + $form['sleep']['sleep_start_time'] = array( + '#type' => 'select', + '#multiple' => FALSE, + '#options' => $options, + '#default_value' => isset($account->sms_user['sleep_start_time']) ? $account->sms_user['sleep_start_time'] : NULL, + ); + + $form['sleep']['sleep_end_time'] = array( + '#type' => 'select', + '#multiple' => FALSE, + '#options' => $options, + '#default_value' => isset($account->sms_user['sleep_end_time']) ? $account->sms_user['sleep_end_time'] : NULL, + ); + + $form['sleep']['save'] = array( + '#type' => 'submit', + '#value' => t('Save'), + ); + + if ($fieldset) { + $form['sleep']['#type'] = 'fieldset'; + $form['sleep']['#title'] = t('Set sleep Time'); + $form['sleep']['#collapsible'] = TRUE; + $form['sleep']['#collapsed'] = TRUE; + } + + return $form; +} + +function sms_user_settings_sleep_form_submit($form, &$form_state) { + $account = user_load(array('uid' => $form_state['values']['uid'])); + $data = $account->sms_user; + $data['sleep_enabled'] = $form_state['values']['sleep_enabled']; + $data['sleep_start_time'] = $form_state['values']['sleep_start_time']; + $data['sleep_end_time'] = $form_state['values']['sleep_end_time']; + user_save($account, array('sms_user' => $data), 'mobile'); + drupal_set_message(t('The changes have been saved.'), 'status'); +} + +/******** + * Theme Functions + */ + +/** + * Theme function for combined user settings page. + * + * @param $content + * array of forms: active, validate, add and sleep. + * @ingroup themeable + */ +function theme_sms_user_settings_page($content) { + $output = $content['active']; + $output .= $content['validate']; + $output .= $content['add']; + $output .= $content['sleep']; + return $output; +} + +/** + * Theme function for the confirm numbers form. + * + * @param $form + * An associative array containing the structure of the form. + * @ingroup themeable + */ +function theme_sms_user_settings_confirm_form($form) { + $output = ''; + + if (variable_get('sms_user_multiple_numbers', FALSE)) { + $rows = array(); + + foreach (element_children($form) as $key) { + if (! isset($form[$key]['confirm_number[' . $key . ']'])) { + // just putting the numbers (and their selector) in a table + continue; + } + + $number = $form[$key]; + unset($form[$key]); + + unset($number['confirm_code[' . $key . ']']['#title']); + unset($number['confirm_code[' . $key . ']']['#description']); + + $row = array(); + $row[] = $number['confirm_number[' . $key . ']']['#value']; + $row[] = drupal_render($number['confirm_code[' . $key . ']']); + $row[] = drupal_render($number['confirm_submit[' . $key . ']']); + $row[] = drupal_render($number['confirm_delete[' . $key . ']']); + $rows[] = $row; + + } + + if (count($rows)) { + $header = array(t('Mobile phone number'), t('Confirmation code'), '', ''); + $output .= theme('table', $header, $rows); + $output .= t('The confirmation code sent by SMS to your mobile phone.'); + } + } + + $output .= drupal_render($form); + return $output; +} + + +/** + * Theme function for the active numbers form. + * + * @param $form + * An associative array containing the structure of the form. + * @ingroup themeable + */ +function theme_sms_user_settings_active_form($form) { + $output = ''; + + if (variable_get('sms_user_multiple_numbers', FALSE)) { + $rows = array(); + + foreach (element_children($form) as $key) { + if (! isset($form[$key]['number'])) { + // just putting the numbers (and their selector) in a table + continue; + } + $number = $form[$key]; + unset($form[$key]); + + $row = array(); + $row[] = $number['number']['#value']; + $row[] = drupal_render($form['active'][$key]); + $row[] = drupal_render($number['confirm_delete']); + $rows[] = $row; + } + + if (count($rows)) { + $header = array(t('Mobile phone number'), t('Active'), ''); + $output .= theme('table', $header, $rows); + $output .= t('You can select the active number to receive SMS from the site. All numbers will be able to send SMS to the site.'); + } + } + + $output .= drupal_render($form); + return $output; +} +