Index: phplist.module
===================================================================
RCS file: /cvs/drupal-contrib/contributions/modules/phplist/phplist.module,v
retrieving revision 1.8
diff -u -r1.8 phplist.module
--- phplist.module	14 Feb 2008 11:16:34 -0000	1.8
+++ phplist.module	25 Feb 2008 08:59:43 -0000
@@ -146,6 +146,24 @@
     '#default_value' => variable_get('phplist_prefix', 'phplist_'),
     '#description' => t('Prefix for the database tables')
   );
+  
+  $form['block'] = array(
+    '#type' => 'fieldset',
+    '#title' => t('Block settings'),
+    '#description' => t("The subscribe block is only available to anonymous users if you have granted them the 'access lists' permission in the <a href='@url'>PHPList section of the Access control</a> admin panel.", array('@url' => url('admin/user/access', NULL, 'module-phplist'))),
+  );
+  $form['block']['phplist_subscribe_url'] = array(
+    '#type' => 'textfield',
+    '#title' => t('PHPList URL'),
+    '#required' => TRUE,
+    '#description' => t('The absolute path or URL of your PHPList front page, for example: <em>/lists/</em> or <em>http://lists.mydomain.com/</em><br />Used for joining the mailing list via the block.'),
+    '#default_value' => variable_get('phplist_subscribe_url', '/lists'),
+  );
+  $form['block']['phplist_email_confirm'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show email confirmation field in subscribe block'),
+    '#default_value' => variable_get('phplist_email_confirm', 0),
+  );
 
   if (module_exists('profile')) {
     $form['general']['mapping'] = array(
@@ -192,6 +210,16 @@
     '#type' => 'fieldset'
     );
 
+  $form['user']['phplist_subscribe_on_register'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Show subscription checkboxes in user registration form'),
+    '#default_value' => variable_get('phplist_subscribe_on_register', 0),
+  );
+  $form['user']['phplist_autosubscribe_on_register'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Automatically subscribe users to first listed newsletter'),
+    '#default_value' => variable_get('phplist_autosubscribe_on_register', 0),
+  );
   $form['user']['phplist_preamble'] = array(
     '#type' => 'textarea',
     '#title' => t('Text to show on the My Newsletters page'),
@@ -252,13 +280,32 @@
     case 'login':
   	  // Check phpList in sync at first login
       if ($user->login == 0) {
-  	  	// Add them to phpList's database
-        $phplistid = _phplist_lookup_phplistid($user->mail);
+        // sync new user with phpList's database
+        $phplistid = _phplist_lookup_phplistid($user->mail, $strprefix);
 
-        _phplist_sync_user($phplistid, $user);
+        _phplist_sync_user($phplistid, $user, $strprefix);
 
-  	  	// Subscribe them to the first listed newsletter
-        _phplist_manage_subscription($user->mail, _phplist_uniqueid($user->mail));
+        // subscribe new user to requested lists
+        $subscribe_on_reg = variable_get('phplist_subscribe_on_register', 0);
+        $autosubscribe_on_reg = variable_get('phplist_autosubscribe_on_register', 0);
+
+        if ($subscribe_on_reg || $autosubscribe_on_reg) {
+          $lists = _phplist_get_public_lists($user);
+          if ($autosubscribe_on_reg) {
+            $lists = array_slice($lists, 0, 1);
+          }
+          foreach ($lists as $l) {
+            if (isset($user->phplist_subscribe_lists[$l->lid]) && !isset($l->userid)) {
+              _phplist_manage_subscription($user->mail, $l->lid);
+              drupal_set_message(t('You have been subscribed to %name at %mail', array('%name' => $l->name, '%mail' => $user->mail)));
+            }
+            elseif (isset($l->userid)) {
+              drupal_set_message(t('You are already subscribed to %name', array('%name' => $l->name)));
+            }
+          }
+          unset($user->phplist_subscribe_lists);
+          user_save($user);
+        }
       }
       break;
 
@@ -698,4 +745,236 @@
 
   db_set_active('default');
   return $id;
-}
\ No newline at end of file
+}
+
+/**
+ * Implementation of hook_block().
+ */
+function phplist_block($op = 'list', $delta = 0, $edit = array()) {
+  if ($op == 'list') {
+    $blocks[0] = array(
+      'info' => t('PHPList subscribe'),
+    );
+    return $blocks;
+  }
+
+  elseif ($op == 'configure' && $delta == 0) {
+    $block_body = variable_get('phplist_subscribe_block_header', array());
+    
+    // basically straight out of block.module lines 554-566
+    $form['body_filter']['#weight'] = -17;
+    $form['body_filter']['phplist_subscribe_block_header'] = array(
+      '#type' => 'textarea',
+      '#title' => t('Block text'),
+      '#default_value' => $block_body['content'],
+      '#rows' => 15,
+      '#description' => t('Explanatory text that will be displayed above the subscription form.'),
+      '#weight' => -17,
+    );
+    if (!isset($block_body['format'])) {
+      $block_body['format'] = FILTER_FORMAT_DEFAULT;
+    }
+    $form['body_filter']['phplist_subscribe_block_header_format'] = filter_form($block_body['format'], -16);
+    return $form;
+  }
+
+  elseif ($op == 'save' && $delta == 0) {
+    if (!filter_access($edit['phplist_subscribe_block_header_format'])) {
+      $edit['phplist_subscribe_block_header_format'] = FILTER_FORMAT_DEFAULT;
+    }
+    variable_set('phplist_subscribe_block_header', array('content' => $edit['phplist_subscribe_block_header'], 'format' => $edit['phplist_subscribe_block_header_format']));
+    return TRUE;
+  }
+
+  elseif ($op == 'view' && $delta == 0 && user_access('access lists')) {
+    global $user;
+    $block = array(
+      'subject' => t('Subscribe to our mailing list'),
+      'content' => ($user->uid ? l('Your subscriptions', 'newsletters') : drupal_get_form('phplist_subscribe_form')),
+    );
+    return $block;
+  }
+}
+
+/*
+ * Implementation of hook_form_alter().
+ * 
+ * Adds checkboxes to the user registration form so that users can subscribe to
+ * lists as they register.
+ * 
+ * Adds a submit function (phplist_admin_settings_submit_pass()) to the admin
+ * settings form so that the PHPList database password isn't blanked out.
+ */
+function phplist_form_alter($form_id, &$form) {
+  if ($form_id == 'user_register' && variable_get('phplist_subscribe_on_register', 0)) {
+    $form['mailing_lists'] = array(
+      '#type' => 'fieldset',
+      '#title' => t('Mailing lists'),
+      '#weight' => 29,
+    );
+
+    $form['mailing_lists']['lists'] = phplist_subscribe_checkboxes(FALSE);
+  }
+  elseif ($form_id == 'phplist_admin_settings') {
+    // prevent saving settings from resetting phplist db password
+    $form['#submit']['phplist_admin_settings_submit_pass'] = array();
+    $form['#submit'] = array_reverse($form['#submit']);
+  }
+}
+
+/*
+ * This submit function is added to the phplist_admin_settings() form to make 
+ * sure PHPList database password isn't unset by saving the admin settings.
+ *
+ * If the phplist_dbpass variable is (1) already set and (2) hasn't been reset
+ * on this edit, this function removes the phplist_dbpass field from the form
+ * before it is saved so that the password is not *unset* by saving the form.
+ */
+function phplist_admin_settings_submit_pass($form_id, &$form_values) {
+  if (variable_get('phplist_dbpass', '') && !$form_values['phplist_dbpass']) {
+    unset($form_values['phplist_dbpass']);
+  }
+}
+
+/*
+ * Create the 'subscribe' form (for non- drupal users)
+ */
+function phplist_subscribe_form() {
+  $form = array();
+
+  $block_body = variable_get('phplist_subscribe_block_header', array('content' => '', 'format' => FILTER_FORMAT_DEFAULT));
+  $form['subscribe_block_header'] = array(
+    '#value' => check_markup($block_body['content'], $block_body['format'], FALSE),
+  );
+
+  $form['mail'] = array(
+    '#type' => 'textfield',
+    '#title' => t('E-mail'),
+    //'#size' => 16,
+  );
+  
+  if (variable_get('phplist_email_confirm', 0)) {
+    $form['mailconfirm'] = array(
+      '#type' => 'textfield',
+      '#title' => t('Confirm e-mail'),
+      '#size' => 16,
+    );
+  }
+
+  $form['lists'] = phplist_subscribe_checkboxes();
+
+  $form['submit'] = array(
+    '#type' => 'submit',
+    '#value' => t('Subscribe'),
+  );
+  
+  return $form;
+}
+
+/**
+ * Generate a checkbox for each configured mailing list.
+ * Returns a 'checkboxes' form element.
+ */
+function phplist_subscribe_checkboxes($hide_one = TRUE) {
+  global $user;
+  $lists = _phplist_get_public_lists($user);
+  $options = array();
+  foreach ($lists as $l) {
+    $options[$l->lid] = $l->name;
+  }
+  
+  if (count($options) == 1 && $hide_one) {
+    $form_checkboxes['phplist_subscribe_lists'] = array(
+      '#type' => 'value',
+      '#value' => array_keys($options),
+    );
+  }
+  else {
+    $form_checkboxes['phplist_subscribe_lists'] = array(
+      '#type' => 'checkboxes',
+      '#title' => t('Subscribe me to'),
+      '#default_value' => array_keys($options),
+      '#options' => $options,
+    );
+  }
+  
+  $form_checkboxes['phplist_html'] = array(
+    '#type' => 'checkbox',
+    '#title' => t('Receive emails in text format'),
+    '#options' => array(0, 1),
+    '#default_value' => 0,
+  );
+  
+  return $form_checkboxes;
+}
+
+/*
+ * Validate the subscribe form:
+ * - validate the email address
+ * - check that the email field matches email confirm field
+ * - confirm that there is at least one subscription selected
+ */
+function phplist_subscribe_form_validate($form_id, $form_values) {
+  if (! valid_email_address($form_values['mail'])) {
+    form_set_error('mail', t('Please enter a valid email address.'));
+  }
+  elseif (variable_get('phplist_email_confirm', 0) && $form_values['mail'] !== $form_values['mailconfirm']) {
+    form_set_error('mailconfirm', t('The email address you entered does not match.'));
+  }
+  
+  if (_phplist_lookup_phplistid($form_values['mail']) > 0) {
+  	form_set_error('mailconfirm', t('This email address is already registered.'));
+  }
+  
+  if (count($form_values['phplist_subscribe_lists']) == 0) {
+    form_set_error('phplist_subscribe_lists', t('You did not select any mailing lists to subscribe to.'));
+  }
+}
+
+/*
+ * This uses what I would call 'AHAX' -- it's like AJAX but without the 
+ * Javascript and with HTML instead of XML. Or maybe that should just be 'HAX'
+ * since it's not Asynchronous either :)
+ * 
+ * Takes the user's email and list subscription preferences from the
+ * phplist_subscribe_form() (validated already by phplist_subscribe_form_validate()) 
+ * and submits them to phplist's 'subscribe' page as if it were a normally-POSTed
+ * form. Checks the response for the string "Thank you for subscribing" which
+ * means that PHPList has added the user to the list (and will send out its own
+ * confirmation email)
+ */
+function phplist_subscribe_form_submit($form_id, $form_values) {
+  global $user;
+
+  $data = array(
+    'email' => $form_values['mail'],
+    'emailconfirm' => $form_values['mail'], // this has already been checked in the _validate function
+    'htmlemail' => ($form_values['phplist_html'] ? 0 : 1), // looks backwards, is not. see usage in _phplist_sync_user()
+    'subscribe' => 'Subscribe',
+  );
+  
+  $lists = _phplist_get_public_lists($user);
+  foreach ($lists as $l) {
+    if ($form_values['phplist_subscribe_lists'][$l->lid]) {
+      $listkey = '['. $l->lid .']';
+      $data['list'. $listkey] = 'subscribe';
+    }
+  }
+  
+  $postdata = '';
+  foreach ($data as $key => $val) {
+    $postdata .= ($postdata ? '&' : '') . urlencode($key) .'='. urlencode($val);
+  }
+  
+  $subscribe_url = url(variable_get('phplist_subscribe_url', 'lists'), 'p=subscribe', NULL, TRUE);
+  $headers = array('Content-Type' => 'application/x-www-form-urlencoded');
+  
+  $result = drupal_http_request($subscribe_url, $headers, 'POST', $postdata);
+  
+  if (strpos($result->data, 'Thank you for subscribing') !== FALSE) {
+    drupal_set_message(t('You will be e-mailed shortly with a request to confirm your membership. Please make sure to click the link in that message to confirm your subscription.'));
+  }
+  else {
+    drupal_set_message(t('Oops, you have not been added to the mailing list; please contact a site administrator.'));
+  }
+}
