? add_user_api.patch
Index: autoresponder.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/autoresponder/autoresponder.module,v
retrieving revision 1.7.4.4
diff -u -p -r1.7.4.4 autoresponder.module
--- autoresponder.module	27 Feb 2009 12:37:54 -0000	1.7.4.4
+++ autoresponder.module	7 Oct 2009 22:52:08 -0000
@@ -1429,53 +1429,197 @@ function autoresponder_mail_edit_create_
   return $form;
 }
 
+/**
+ * Called when the user fills in the form with an email address requesting 
+ * that it be added to the list for autoresponses. This function validates that
+ * the email is in the right format; and that said user is not already   
+ * subscribed to the requested list.
+ *
+ * @param $form
+ *   A drupal form, not used in this function but present here so as to fit 
+ *   the pattern for ..._submit functions.
+ * @param $form_state
+ *   Associative array containing the state of the form fields.
+ *   $form_state['values']['set'] and $form_state['values']['email']
+ *   are used.
+ * @return
+ *   TRUE if the address "email" is subcribed to set "set".
+ */
+function autoresponder_email_subscribed_to_set($email, $set) {
+  $result = db_query("SELECT COUNT(*) FROM {autoresponder_users} au LEFT JOIN {autoresponder} a ON au.id = a.uid WHERE au.email = '%s' AND a.setid = %d", $email, $set);
+  $exist = db_result($result) > 0;
+  
+  return $exist;
+}  
+
+
+/**
+ * Called when the user fills in the form with an email address requesting 
+ * that it be added to the list for autoresponses. This function validates that
+ * the email is in the right format; and that said user is not already   
+ * subscribed to the requested list.
+ *
+ * @param $form
+ *   A drupal form, not used in this function but present here so as to fit 
+ *   the pattern for ..._submit functions.
+ * @param $form_state
+ *   Associative array containing the state of the form fields.
+ *   $form_state['values']['set'] and $form_state['values']['email']
+ *   are used.
+ */
 function autoresponder_email_enter_form_validate($form, &$form_state) {
-  if (!valid_email_address($form_state['values']['email']))
+  // set an error if the email is not the right format.
+  if (!valid_email_address($form_state['values']['email'])) {
     form_set_error('email', 'Email address is wrong. Example: <i>john@coolsite.com</i>');
-  $result = db_query("SELECT COUNT(*) FROM {autoresponder_users} au LEFT JOIN {autoresponder} a ON au.id = a.uid WHERE au.email = '%s' AND a.setid = %d", $form_state['values']['email'], $form_state['values']['set']);
-  $exist = db_result($result) > 0;
-  if ($exist)
+  }
+  
+  // set an error if the email is already subscribed to this list.
+  if(autoresponder_email_subscribed_to_set($form_state['values']['email'], $form_state['values']['set'])) {
     form_set_error('email',t('Your email address @mail is already subscribed for this list.', array('@mail' => $form_state['values']['email'])));
+  }
 }
 
+/**
+ * Adds an email address to any number of autoresponder sets, and returns 
+ * an array with all unlocalized "You're subscribed" messages.
+ *
+ * If a user is already subscribed to a given set, it is ignored. 
+ * If a set null, it is ignored. However, invalid set IDs are not ignored.
+ * If no valid sets are passed, no users are created.
+ * If an invalid email address is passed, it is ignored.
+ *
+ * @param $emails
+ *   An email address or an array of email addresses. Invalid email addresses 
+ *   are ignored..
+ * @param $sets
+ *   Associative array containing the state of the form fields.
+ *   every set should have the (id => id), so that if you want to subscribe to 
+ *   the set ids 3 and 4, you will pass an array(3 => 3, 4 => 4). The calling
+ *   function is responsible for ensuring that valid set ids are given.
+ * @return
+ *   An array of all *unlocalized* "You're subscribed" messages, for each email 
+ *   given. 
+ *
+ *   the format is array('email1@example.com' => array('message1', 'message2'), 
+ *   'email2@example.com => array('message1'));
+ *
+ *   note that in the above example, email2@example.com was already subscribed 
+ *   to the set which provides 'message2', so that message is not returned.
+ *
+ *   note also that the unlocalized messages will contain the %email placeholder
+ *   which you will have to resolve when translating.
+ *
+ *   * The reason the "You're subscribed" strings
+ *   are unlocalized is that we want this function to be as separate from 
+ *   the user interface as possible. We can imagine an example where this might
+ *   be called from an instance of drupal in language A, but the "You're
+ *   subscibed" message has to be displayed in language B, perhaps piped to an 
+ *   email message or some other messaging system, etc.
+ */
+function autoresponder_add_user($emails, $sets) {
+  // make sure the return is an array, even if it is empty.
+  $r = array();
+
+  // make sure the $email param is an array;
+  if(!is_array($emails)) {
+    $emails = array($emails);
+  }
+
+  // go through all email addresses and add them.
+  foreach($emails as $email) {
+    // ignore this email address if it is not valid
+    if(!valid_email_address($email)) {
+      continue;
+    }
+  
+    // the return must have a key for this email
+    $r[$email] = array();
+    
+    // check if the user already exists in the list, and create it if it does not exist. In both cases, store the user id in $auid
+    $sql = 'SELECT id FROM {autoresponder_users} WHERE email = \'%s\'';
+    $result = db_query($sql, $email);
+    if ($us = db_fetch_object($result)) {
+      $auid = $us->id;
+    }
+    else {
+      $auobj = new stdClass();
+      $auobj->email = strtolower($email);
+      $auobj->reg_date = time();
+      drupal_write_record('autoresponder_users', $auobj);
+      $auid = $auobj->id;
+      unset($auobj);
+    }
+    
+    // now that we know we have a valid user id ($auid), go through the desired sets and link this user to the desired set id (the value), 
+    foreach ($sets as $key => $value) {
+      // don't subscribe an email to a null set or to a set to which it is 
+      // already subscribed. However, we are not checking for invalid sets;
+      // the calling function is responsible for that.
+      if ($value && !autoresponder_email_subscribed_to_set($email, $value)) {
+        $aobj = new stdClass();
+        $aobj->uid = $auid;
+        $aobj->setid = $value;
+        drupal_write_record('autoresponder', $aobj);
+        unset($aobj);
+        
+        // grab all messages set for day 0.
+        $result_messages = db_query('SELECT * FROM {autoresponder_messages} WHERE day = %d AND mset = %d', 0, $value);
+        while ($mail = db_fetch_object($result_messages)) {
+  
+          // grab the user's email from the form
+          $u->mail = $email;
+          $u->uid = $auid;
+          $u->setid = $value;
+  
+          // send day 0 mail to the user.
+          autoresponder_mail($u, $mail);
+          
+          // display the "you're subscribed" message to the user, as it is defined in relation with the set we are currently looking at.
+          $message = db_result(db_query_range('SELECT message FROM {autoresponder_sets} WHERE id = %d', $value, 0, 1));
+          
+          $r[$email][] = $message;
+        }
+      }
+    }
+  }
+  
+  return $r;
+}
+
+/**
+ * Called when the user fills in the form with an email address requesting 
+ * that it be added to the list for autoresponses.
+ *
+ * @param $form
+ *   A drupal form, not used in this function but present here so as to fit 
+ *   the pattern for ..._submit functions.
+ * @param $form_state
+ *   Associative array containing the state of the form fields.
+ *   $form_state['values']['set'] and $form_state['values']['email']
+ *   are used.
+ */
 function autoresponder_email_enter_form_submit($form, &$form_state) {
-  if (!is_array($form_state['values']['set']))
+  // make sure the set is actually an array.
+  if (!is_array($form_state['values']['set'])) {
     $form_state['values']['set'] = array($form_state['values']['set'] => (int)$form_state['values']['set']);
+  }
+  
+  // let the user know that no sets are available if such is the case.
   if (isset($form_state['values']['set']['empty'])) {
     drupal_set_message(t('No sets available to subscribe.'));
     return;
   }
-  $sql = 'SELECT id FROM {autoresponder_users} WHERE email = \'%s\'';
-  $result = db_query($sql, $form_state['values']['email']);
-  if ($us = db_fetch_object($result)) {
-    $auid = $us->id;
-  }
-  else {
-    $auobj = new stdClass();
-    $auobj->email = strtolower($form_state['values']['email']);
-    $auobj->reg_date = time();
-    drupal_write_record('autoresponder_users', $auobj);
-    $auid = $auobj->id;
-    unset($auobj);
-  }
-  foreach ($form_state['values']['set'] as $key => $value) {
-    if ($value) {
-      $aobj = new stdClass();
-      $aobj->uid = $auid;
-      $aobj->setid = $value;
-      drupal_write_record('autoresponder', $aobj);
-      unset($aobj);
-      $result_messages = db_query('SELECT * FROM {autoresponder_messages} WHERE day = %d AND mset = %d', 0, $value);
-      while ($mail = db_fetch_object($result_messages)) {
-        $u->mail = $form_state['values']['email'];
-        $u->uid = $auid;
-        $u->setid = $value;
-        autoresponder_mail($u, $mail);
-        $message = t(db_result(db_query_range('SELECT message FROM {autoresponder_sets} WHERE id = %d', $value, 0, 1)), array('%email' => $form_state['values']['email']));
-        drupal_set_message($message);
-      }
-    }
+  // call the api function autoresponder_add_user() to add the users and sets.
+  $messages = autoresponder_add_user($form_state['values']['email'], $form_state['values']['set']);
+  
+  // set all the messages related to the newly subscribed sets. Note that 
+  // autoresponder_add_user() returns an array of unlocalized messages, so we 
+  // must translate them here.
+  foreach($messages[$form_state['values']['email']] as $message) {
+    drupal_set_message(t($message, array('%email' => $form_state['values']['email'])));
   }
+  
+  // go to the home page.
   drupal_goto();
 }
 
