Little help needed on newsletter opt in module

Posts: 12
Joined: 12/09/2007

Hi folks,

I have the checkout pane for opting in to a newsletter working fine, but am having a little trouble "grabbing" the address/email variables to pass to my newsletter management software via curl. What am I missing? Thanks in advance:

<?php
// $Id$

/**
* @file
* Defines a checkout pane that lets customers opt-in to receive an email newsletter
* When you install this module, you should go to the Checkout panes settings
* page and add newsletter opt-in options to appear during checkout.
*/


/*******************************************************************************
* Hook Functions (Ubercart)
******************************************************************************/

/**
* Implementation of hook_checkout_pane().
*/
function uc_newsletter_checkout_pane() {
  $panes[] = array(
    'id' => 'newsletter',
    'callback' => 'uc_checkout_pane_newsletter',
    'title' => t('Stay in Touch'),
    'desc' => t('Join our e-newsletter list to stay informed about specials and promotions. We promise never to sell, rent or give away your personal information.'),
    'weight' => 8,
  );

  return $panes;
}

/**
* Implementation of hook_order().
*/
function uc_newsletter_order($op, &$arg1, $arg2) {
  switch ($op) {
    case 'submit':
      if ($arg1->newsletter['opt_in'] == 1) {
        $postvars = array(
          'fields_email'=>$arg1->customer['primary_email'],
          'fields_fname'=>$arg1->billing['billing_first_name'],
          'fields_lname'=>$arg1->billing['billing_last_name'],
          'fields_address1'=>$arg1->billing['billing_street1'],
          'fields_address2'=>$arg1->billing['billing_street2'],
          'fields_city'=>$arg1->billing['billing_city'],
          'fields_state'=>$arg1->billing['billing_zone'],
          'fields_zip'=>$arg1->billing['billing_postal_code'],
          'fields_phone'=>$arg1->billing['billing_phone'],
          'listid'=>9907524,
          'specialid:3388'=>'JICV',
          'clientid'=>190495,
          'realistid'=>1,
          'doubleopt'=>0,
        );
      $url = 'http://app.intellicontact.com/icp/signup.php';
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, $url);
      curl_setopt($ch, CURLOPT_POST, 1);
      curl_setopt($ch, CURLOPT_POSTFIELDS, $postvars);
      $result = curl_exec($ch);
      if (curl_errno($ch)) {
        $result = curl_error($ch);
      }
      curl_close($ch);
      }
}
}

/*******************************************************************************
* Callback Functions, Forms, and Tables
******************************************************************************/
function uc_checkout_pane_newsletter($op, &$arg1, $arg2) {
  switch ($op) {
    case 'view':
      $description = t('Would you like to recieve promotions and special offers from Desert Sun? Sign up to receive our e-newsletter!');
      $contents['opt_in'] = array(
        '#type' => 'checkboxes',
        '#title' => t('Check the box below to opt in.'),
        '#options' => array(
          '1' => t('Subscribe Me'),
         ),
        '#default_value' => $arg1->newsletter['opt_in'],
     );
      return array(
        'description' => $description,
        'contents' => $contents,
        );
    case 'process':
        $arg1->newsletter['opt_in'] = $arg2['opt_in'];
      return TRUE;
  }
}

Posts: 5617
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

The main problem here is what may possibly be a deficiency in the checkout pane system due to my inexperience when the API was written. Basically, when the 'process' $op is run for your checkout pane, it's adding the value of the opt-in to the order object... but that doesn't handle saving. Saving/loading the data would be handled through hook_order(). Now... what should probably happen is to add a catch-all data field to orders that you can add to and have Ubercart handle saving/loading it so each little module doesn't need to create a DB table for every little piece of data.

In the meantime... for a case like yours, you can more simply store the value of the opt-in in $_SESSION in the 'process' code instead of $arg1. Then in your 'submit' $op for hook_order(), check the session variable, perform the curl request if needed, and then unset the session variable.

Posts: 5617
Joined: 08/07/2007
AdministratorHead Code Monkey - I eat bugs.

Small note... I did go ahead and commit code to allow for the saving/loading of data to the order object. You can add to/manipulate the data array for an order object and it will be saved/loaded automatically... but you should not simply erase or reset the data array as you never know what other modules will be using it for.

I'm sure this can be tightened up in the future by including manipulation functions in other APIs, but for now you should just deal w/ the array directly.

This will help simplify some routine tasks like adding small bits of information to an order that you may want to pull up with the order later. For storing larger amounts of data against an order or to have data that is available w/o loading an entire order object, you'd be advised to store the data in a separate table using the other method of saving/loading with hook_order().