friendly_register.module 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <?php
  2. /**
  3. * @file
  4. * Primary logic for the friendly_register module that allows for checking of username and email.
  5. */
  6. define('FRIENDLY_REGISTER_MAX_HITS', 300);
  7. define('FRIENDLY_REGISTER_EXPIRES', 86400);
  8. /**
  9. * Implements hook_menu().
  10. */
  11. function friendly_register_menu() {
  12. $items['ajax/check-email'] = array(
  13. 'page callback' => 'friendly_register_check_email',
  14. 'page arguments' => array(2),
  15. 'access callback' => TRUE,
  16. 'type' => MENU_CALLBACK,
  17. );
  18. $items['ajax/check-user'] = array(
  19. 'page callback' => 'friendly_register_check_user',
  20. 'page arguments' => array(2),
  21. 'access callback' => TRUE,
  22. 'type' => MENU_CALLBACK,
  23. );
  24. return $items;
  25. }
  26. /**
  27. * Implements hook_permission().
  28. */
  29. function friendly_register_permission() {
  30. return array(
  31. 'ignore flood' => array(
  32. 'title' => t('Ignore Flood Checking'),
  33. 'description' => t('Allows users to have unlimited checks against friendly register.'),
  34. 'restrict access' => FALSE,
  35. ),
  36. );
  37. }
  38. /**
  39. * Implements hook_cron().
  40. */
  41. function friendly_register_cron() {
  42. $expires = REQUEST_TIME - FRIENDLY_REGISTER_EXPIRES;
  43. db_delete('friendly_register_flood')
  44. ->condition('lasthit', $expires, '<=')
  45. ->execute();
  46. }
  47. /**
  48. * Implements hook_form_FORM_ID_alter().
  49. */
  50. function friendly_register_form_user_register_form_alter(&$form, &$form_state, $form_id) {
  51. foreach (array('name', 'mail') as $field) {
  52. $class = 'friendly-register-' . $field;
  53. if (isset($form['account'][$field]['#attributes']['class'])) {
  54. $form['account'][$field]['#attributes']['class'][] = $class;
  55. }
  56. elseif (isset($form['account'][$field]['#attributes'])) {
  57. $form['account'][$field]['#attributes']['class'] = array(
  58. $class,
  59. );
  60. }
  61. else {
  62. $form['account'][$field]['#attributes'] = array(
  63. 'class' => array(
  64. $class,
  65. ),
  66. );
  67. }
  68. }
  69. friendly_register_load_resources();
  70. }
  71. /**
  72. * Utility function for load required resources.
  73. */
  74. function friendly_register_load_resources() {
  75. $path = drupal_get_path('module', 'friendly_register');
  76. drupal_add_js($path . '/js/friendly_register.js', 'file');
  77. drupal_add_css($path . '/css/friendly_register.css');
  78. }
  79. /**
  80. * JSON callback to check the email address.
  81. *
  82. * @param $address
  83. */
  84. function friendly_register_check_email($address) {
  85. $email_is_valid = TRUE;
  86. $all_email_checks = module_invoke_all('validate_email_address', $address);
  87. foreach ($all_email_checks as $check) {
  88. $email_is_valid = $check && $email_is_valid;
  89. }
  90. // Check if it is a valid email address. No need to check if it is not
  91. if ($email_is_valid) {
  92. drupal_json_output(_friendly_register_check_field('mail', $address));
  93. }
  94. else {
  95. // This flag will return incomplete so the user doesn't see an error
  96. // if they are just starting to enter in their email address
  97. drupal_json_output(array('available' => 'incomplete'));
  98. }
  99. }
  100. /**
  101. * Implements hook_validate_email_address().
  102. *
  103. * @param string $address
  104. *
  105. * @return bool
  106. */
  107. function friendly_register_validate_email_address($address) {
  108. return valid_email_address($address);
  109. }
  110. /**
  111. * JSON callback to check the username.
  112. *
  113. * @param string $username
  114. */
  115. function friendly_register_check_user($username) {
  116. $user_is_valid = TRUE;
  117. $all_user_checks = module_invoke_all('validate_user_name', $username);
  118. foreach ($all_user_checks as $check) {
  119. $user_is_valid = $check && $user_is_valid;
  120. }
  121. if ($user_is_valid) {
  122. drupal_json_output(_friendly_register_check_field('name', $username));
  123. }
  124. else {
  125. drupal_json_output(array('available' => 'invalid'));
  126. }
  127. }
  128. /**
  129. * Checks the value of a field on the user table.
  130. *
  131. * @param string $field_name
  132. * @param string $value
  133. *
  134. * @return array
  135. */
  136. function _friendly_register_check_field($field_name, $value) {
  137. if (_friendly_register_check_flood()) {
  138. $result = db_query("SELECT uid FROM {users} WHERE " . $field_name . " = :value", array(':value' => $value))->fetchField();
  139. return array('available' => ($result == NULL));
  140. }
  141. else {
  142. return array('flood' => TRUE);
  143. }
  144. }
  145. /**
  146. * Checks to see if the user has too many requests (flood).
  147. *
  148. * @return bool
  149. */
  150. function _friendly_register_check_flood() {
  151. if (user_access('ignore flood')) {
  152. return TRUE;
  153. }
  154. else {
  155. $ip = ip_address();
  156. $q = 'SELECT hits FROM {friendly_register_flood} WHERE ip = :ip';
  157. $hits = db_query($q, array(':ip' => $ip))->fetchField();
  158. if ($hits == NULL) {
  159. db_insert('friendly_register_flood')
  160. ->fields(array(
  161. 'ip' => $ip,
  162. 'hits' => 1,
  163. 'lasthit' => REQUEST_TIME,
  164. ))->execute();
  165. }
  166. else {
  167. db_update('friendly_register_flood')
  168. ->expression('hits', 'hits + 1')
  169. ->expression('lasthit', REQUEST_TIME)
  170. ->condition('ip', $ip)
  171. ->execute();
  172. }
  173. return $hits < FRIENDLY_REGISTER_MAX_HITS;
  174. }
  175. }