Binary files ../salesforce_orig/._salesforce.module and sites/all/modules/salesforce/._salesforce.module differ
Only in sites/all/modules/salesforce/includes: ._salesforce_api.inc
diff -urp ../salesforce_orig/includes/salesforce_api.inc sites/all/modules/salesforce/includes/salesforce_api.inc
--- ../salesforce_orig/includes/salesforce_api.inc	2007-05-04 04:09:05.000000000 -0500
+++ sites/all/modules/salesforce/includes/salesforce_api.inc	2007-11-08 16:37:53.000000000 -0600
@@ -105,7 +105,7 @@ function salesforce_contact($op, $accoun
         if ($result['success'] == 'true') {
           _salesforce_insert('contact_id', $result['id'], $account);
           if (user_access('administer salesforce')) {
-            drupal_set_message(t('a contact was created in salesforce for the user %user', array('%user' => "<strong>$account->first_name $account->last_name</strong>")));
+            drupal_set_message(t('a contact was created in salesforce for the user <strong>@user</strong>', array('@user' => "$account->first_name $account->last_name")));
             return array('id' => $result['id'], 'status' => 'inserted');
           }
         } else {
@@ -126,7 +126,7 @@ function salesforce_contact($op, $accoun
 
         if ($result['success'] == 'true') {
           if ($admin) {
-            drupal_set_message(t('updated contact in salesforce for the user %user', array('%user' => "<strong>$account->first_name $account->last_name</strong>")));
+            drupal_set_message(t('updated contact in salesforce for the user <strong>@user</strong>', array('@user' => "$account->first_name $account->last_name")));
             return array('status' => 'updated');
           }
         } else {
@@ -147,6 +147,27 @@ function salesforce_contact($op, $accoun
         return array('error' => $error);
       }
       break;
+
+		case 'insert from remote':
+			// New user is being created from new contact on salesforce
+			db_query('INSERT INTO {salesforce_users} (uid,contact_id,account_id,created) VALUES (%d,"%s","%s",%d)', $account->uid, $account->contact_id, $account->account_id, time());
+			break;
+
+		case 'update from remote':
+			// Information was updated in salesforce, we need to mirror it locally, called by cron.php
+			$contact = salesforce_contact_select($account,array('FirstName','LastName','Phone','Fax','Email','IsDeleted'));
+			$status = ($contact['IsDeleted'] == 'true') ? 0 : 1;
+			if ($account->mail != $contact['Email'] ) {
+				user_save($account, array('mail' => $contact['Email'], 'status' => $status, 'update_from_salesforce' => TRUE));
+			}
+			user_save($account, array('first_name' => $contact['FirstName'],
+															'last_name' => $contact['LastName'],
+															'phone' => $contact['Phone'],
+															'fax' => $contact['Fax'],
+															'company' => $account->company,
+															'update_from_salesforce' => TRUE),
+														'Profile Information');
+			break;
   }
 }
 
@@ -196,7 +217,7 @@ function salesforce_lead($op, $account, 
         if ($result['success'] == 'true') {
           _salesforce_insert('lead_id', $result['id'], $account);
           if (user_access('administer salesforce')) {
-            drupal_set_message(t('a lead was created in salesforce for the user %user', array('%user' => "<strong>$account->first_name $account->last_name</strong>")));
+            drupal_set_message(t('a lead was created in salesforce for the user <strong>@user</strong>', array('@user' => "$account->first_name $account->last_name")));
             return array('id' => $result['id'], 'status' => 'inserted');
           }
         } else {
@@ -215,7 +236,7 @@ function salesforce_lead($op, $account, 
 
         if ($result['success'] == 'true') {
           if ($admin) {
-            drupal_set_message(t('updated lead in salesforce for the user %user', array('%user' => "<strong>$account->first_name $account->last_name</strong>")));
+            drupal_set_message(t('updated lead in salesforce for the user <strong>@user</strong>', array('@user' => "$account->first_name $account->last_name")));
             return array('status' => 'updated');
           }
         } else {
@@ -227,7 +248,7 @@ function salesforce_lead($op, $account, 
             case 'INVALID_ID_FIELD':
               if ($admin) {
                 db_query("DELETE FROM {salesforce_users} WHERE lead_id = '%s'", $account->salesforce['lead_id']);
-                drupal_set_message(t('the lead for the user %user was removed from salesforce', array('%user' => "<strong>$account->first_name $account->last_name</strong>")));
+                drupal_set_message(t('the lead for the user <strong>@user</strong> was removed from salesforce', array('@user' => "$account->first_name $account->last_name")));
                 return array('status' => 'lead_removed_from_salesforce');
               }
               break;
@@ -248,6 +269,33 @@ function salesforce_lead($op, $account, 
         return array('error' => $error);
       }
       break;
+
+		// New user is being created from new contact on salesforce
+		case 'insert from remote':
+			db_query('INSERT INTO {salesforce_users} (uid,lead_id,account_id,created) VALUES (%d,"%s","%s",%d)', $account->uid, $account->lead_id, $account->account_id, time());
+			break;
+			
+		// Information was updated in salesforce, we need to mirror it locally, called by cron.php
+		case 'update from remote':
+			$lead = salesforce_lead_select($account,array('FirstName','LastName','Phone','Fax','Email','IsConverted','ConvertedAccountId','ConvertedContactId'));
+			$status = variable_get('salesforce_lead_account_status', 0);
+			// Has this Lead been converted to a Contact?
+			if ($lead['IsConverted'] == 'true') {
+				$status = 1;
+				db_query('UPDATE {salesforce_users} SET lead_id="", contact_id="%s", account_id="%s" WHERE uid=%d', $lead['ConvertedContactId'], $lead['ConvertedAcountId'], $account->uid);
+			}
+			
+			if ($account->mail != $lead['Email'] ) {
+				user_save($account, array('mail' => $lead['Email'], 'status' => $status, 'update_from_salesforce' => TRUE));
+			}
+			user_save($account, array('first_name' => $lead['FirstName'],
+															'last_name' => $lead['LastName'],
+															'phone' => $lead['Phone'],
+															'fax' => $lead['Fax'],
+															'company' => $account->company,
+															'update_from_salesforce' => TRUE),
+														'Profile Information');
+			break;
   }
 }
 
@@ -288,7 +336,7 @@ function salesforce_event($op, $subject,
 
   if ($result['success'] == 'true') {
     if ($admin) {
-      drupal_set_message(t('an event was created in salesforce for the user %user', array('%user' => "<strong>$account->first_name $account->last_name</strong>")));
+      drupal_set_message(t('an event was created in salesforce for the user <strong>@user</strong>', array('@user' => "$account->first_name $account->last_name")));
       return array('id' => $result['id'], 'status' => 'inserted');
     }
   } else {
@@ -322,17 +370,18 @@ function salesforce_event($op, $subject,
 /**
  *  select from the salesforce contact table
  */
-function salesforce_account_select($account = NULL, $params = array(), $cache = true) {
+function salesforce_contact_select($account = NULL, $params = array(), $cache = true) {
   $salesforce = salesforce();
   $account = _salesforce_select_account($account);
 
   // make sure we're dealing with a contact
   if (!$account->salesforce['contact_id']) return array('error' => 'NO_CONTACT_ID');
 
-  $defaults = array('accountId');
+  $defaults = array('AccountId');
   $params = array_merge($defaults, $params);
   // query salesforce for the contact's account_id
   $contact = $salesforce->query("SELECT ". implode(',', $params) ." FROM contact WHERE id = '". $account->salesforce['contact_id'] ."'");
+
   $id = $contact['records']->values['AccountId'];
   if ($id) {
     if ($cache) {
@@ -343,6 +392,27 @@ function salesforce_account_select($acco
 }
 
 /**
+ * Select from the salesforce lead table
+ */
+function salesforce_lead_select($account = NULL, $params = array(), $cache = true) {
+	$salesforce = salesforce();
+	$account = _salesforce_select_account($account);
+	
+	// make sure we're dealing with a lead
+	if (!$account->salesforce['lead_id']) return array('error' => 'NO_LEAD_ID');
+	
+	$defaults = array('Id');
+	$params = array_merge($defaults,$params);
+
+	$lead = $salesforce->query("SELECT ". implode(',', $params) ." FROM lead WHERE id = '". $account->salesforce['lead_id'] ."'");
+	//$lead = $salesforce->query("SELECT id, FirstName, LastName, Email, Phone, Fax, IsConverted, ConvertedAccountId, ConvertedContactId FROM lead WHERE id = '". $account->salesforce['lead_id'] ."'");
+		
+	if (count($lead['records'])) {
+		return $lead['records']->values;
+	}
+}
+
+/**
  *  retreive contract information from an account
  */
 function salesforce_contract_select($account = NULL, $params = array(), $defaults = true) {
@@ -352,7 +422,7 @@ function salesforce_contract_select($acc
 
   // first we need to make sure we have an account_id to work with
   if (!$account->salesforce['account_id']) {
-    $result = salesforce_account_select($account);
+    $result = salesforce_contact_select($account);
     $account->salesforce['account_id'] = $result['AccountId'];
     if (!$account->salesforce['account_id']) return array('error' => 'NO_ACCOUNT_ID_FOUND');
   }
@@ -375,3 +445,39 @@ function salesforce_contract_select($acc
 
   return $contracts;
 }
+
+/**
+ * get a list of all udpated objects of type within specified date range
+ */
+function salesforce_get_updated($type, $startDate, $endDate='') {
+	$salesforce = salesforce();
+	$endDate = ( !$endDate ) ? time() : $endDate;
+	$res = $salesforce->getUpdated($type, gmdate('c',$startDate), gmdate('c',$endDate));
+	$updated = array();
+	if (count($res['ids']) > 1) {
+		foreach($res['ids'] as $id) {
+			$updated[$id] = salesforce_user_load($id);
+		}
+	} else if (count($res)) {
+		$updated[$res['ids']] = salesforce_user_load($res['ids']);
+	}
+	return (count($updated)) ? $updated : false;
+}
+
+/**
+ * Load a user object if their is a user that matches salesforce lead_id, or contact_id
+ *
+ * @param $id
+ *		Salesforce lead or contact id to look up.
+ * @return
+ *		$user object if present, else FALSE
+ */
+function salesforce_user_load($id) {
+	$uid = db_result(db_query('SELECT uid FROM {salesforce_users} WHERE lead_id="%s" OR contact_id="%s"', $id, $id));
+	if ($uid) {
+		return user_load(array('uid' => $uid));
+	} else {
+		return FALSE;
+	}
+}
+
diff -urp ../salesforce_orig/salesforce.module sites/all/modules/salesforce/salesforce.module
--- ../salesforce_orig/salesforce.module	2007-11-03 09:07:40.000000000 -0500
+++ sites/all/modules/salesforce/salesforce.module	2007-11-08 16:40:40.000000000 -0600
@@ -137,6 +137,14 @@ function salesforce_admin_settings() {
   '#collapsible' => true
   );
 
+	$form['salesforce_options']['salesforce_lead_account_status'] = array(
+	'#type' => 'radios',
+	'#title' => t('Lead account status'),
+	'#default_value' => variable_get('salesforce_lead_account_status', 0),
+	'#options' => array(t('Blocked'),t('Active')),
+	'#description' => t('when creating a new user account from a Salesforce lead the account will be given this status.')
+	);
+
   $form['salesforce_options']['salesforce_leads_create_forms'] = array(
   '#type' => 'textarea',
   '#title' => t('Create Leads on form processes'),
@@ -166,6 +174,20 @@ function salesforce_cron() {
       _salesforce_cron_run($row);
     }
   }
+
+	$time = time();
+	// Check for updated Leads
+	$leads = salesforce_get_updated('Lead', variable_get('salesforce_last', $time-1), $time);
+	if(count($leads)) {
+		_salesforce_cron_user_update($leads, 'lead_id');
+	}
+	// Check for updated Contacts
+	$contacts = salesforce_get_updated('Contact', variable_get('salesforce_last', $time-1), $time);
+	if(count($contacts)) {
+		_salesforce_cron_user_update($contacts, 'contact_id');
+	}
+	// Log current time for next run
+	variable_set('salesforce_last', $time);
 }
 
 /**
@@ -187,27 +209,47 @@ function salesforce_user($op, &$edit, &$
       // we check on a form value so we can display a checkbox instead of a hidden field if it's an admin viewing the page
       if ($edit['create_lead']) {
         // must reload the object with user_load() to grab the updated profile fields
-        salesforce_lead('insert', user_load(array('uid' => $account->uid)), array('Description' => t('new site user: %date', array('%date' => format_date(time(), 'large')))));
-      }
+        salesforce_lead('insert', user_load(array('uid' => $account->uid)), array('Description' => t('new site user: @date', array('@date' => format_date(time(), 'large')))));
+
+      } else if ($edit['contact_id'] || $edit['lead_id']) {
+				// user is being created form salesforce contact/lead
+				$account->contact_id = $edit['contact_id'];
+				$account->lead_id = $edit['lead_id'];
+				$account->account_id = $edit['account_id'];
+								
+				if ($account->contact_id) {
+					salesforce_contact('insert from remote', $account);
+				} else if ($account->lead_id) {
+					salesforce_lead('insert from remote', $account);
+				}
+			}
       break;
 
     case 'update':
-      if (_salesforce_is_form('leads', 'user_edit')) {
+      if (_salesforce_is_form('leads', 'user_edit') && !$edit['update_from_salesforce']) {
         // must reload the object with user_load() to grab the updated profile fields
         $updated_account = user_load(array('uid' => $account->uid));
         if ($account->salesforce['contact_id']) {
           salesforce_contact('update', $updated_account);
         } else if ($account->salesforce['lead_id']) {
-          salesforce_lead('update', $updated_account, array('Description' => t('last updated account information: %date', array('%date' => format_date(time(), 'large')))));
+          salesforce_lead('update', $updated_account, array('Description' => t('last updated account information: @date', array('@date' => format_date(time(), 'large')))));
         } else {
           // we check on a form value so we can display a checkbox instead of a hidden field if it's an admin viewing the page
           if ($edit['create_lead']) {
             // must reload the object with user_load() to grab the updated profile fields
-            salesforce_lead('insert', user_load(array('uid' => $account->uid)), array('Description' => t('admin adding lead: %date', array('%date' => format_date(time(), 'large')))));
+            salesforce_lead('insert', user_load(array('uid' => $account->uid)), array('Description' => t('admin adding lead: @date', array('@date' => format_date(time(), 'large')))));
           }
         }
       }
       break;
+		case 'register':
+			// Add these fields to the registration form so we can make use of them later.
+			$form = array();
+			$form['account_id'] = array('#type' => 'hidden', '#value' => '');
+			$form['lead_id'] = array('#type' => 'hidden', '#value' => '');
+			$form['contact_id'] = array('#type' => 'hidden', '#value' => '');
+			return $form;
+			break;
     case 'view':
       break;
   }
@@ -286,7 +328,7 @@ function salesforce_contact_form($form_i
   //drupal_set_message('account: ' . serialize($account) . ' k: ' . $k . ' name: ' . serialize($name));
   //drupal_set_message($form_values['']);
   
-  $result = salesforce_lead('insert', $account, array('Description' => t('contact us form with the subject: %subject', array('%subject' => $_POST['edit']['subject']))));
+  $result = salesforce_lead('insert', $account, array('Description' => t('contact us form with the subject: @subject', array('@subject' => $_POST['edit']['subject']))));
 }
 
 /**
@@ -438,22 +480,22 @@ function _salesforce_admin_list($op) {
   $sf = 'https://na1.salesforce.com/';
 
   if ($op == 'lead' || $op == 'contact') {
-    $result = db_query("SELECT s.uid FROM {salesforce_users} s WHERE %s != ''", 's.'. $op .'_id');
+    $result = db_query("SELECT * FROM {salesforce_users} s WHERE %s != ''", 's.'. $op .'_id');
     if (db_num_rows($result) > 0) {
-      $cols = array(array('data' => t('User'), 'class' => 'user'), array('data' => t('%i', array('%i' => ucfirst($op) .' ID')), 'class' => 'id'));
+      $cols = array(array('data' => t('User'), 'class' => 'user'), array('data' => t('Name')), array('data' => t('%i', array('%i' => ucfirst($op) .' ID')), 'class' => 'id'));
       if ($op == 'contact') {
         $cols[] = array('data' => t('Account ID', array('%i' => ucfirst($op))), 'class' => 'id');
       }
 
       while ($row = db_fetch_object($result)) {
-        if ($op == 'contact') {
+        if ($op == 'contact' && !$row->account_id) {
           // we do this incase we don't have a cached account id
-          salesforce_account_select(user_load(array('uid' => $row->uid)));
+          salesforce_contact_select(user_load(array('uid' => $row->uid)));
         }
         $account = user_load(array('uid' => $row->uid));
         // remove the extra 3 chars that are not used in this case
         $link = $sf . substr($account->salesforce[$op.'_id'], 0, strlen($account->salesforce[$op.'_id']) - 3);
-        $rows[$row->uid] = array(theme('username', $account), l($account->salesforce[$op.'_id'], $link));
+        $rows[$row->uid] = array(theme('username', $account), $account->first_name .' '. $account->last_name, l($account->salesforce[$op.'_id'], $link));
         if ($op == 'contact') {
           if ($account->salesforce['account_id']) {
             $account_link = $sf . substr($account->salesforce['account_id'], 0, strlen($account->salesforce['account_id']) - 3);
@@ -522,6 +564,53 @@ function _salesforce_cron_run($row) {
 }
 
 /**
+ * Apply updated salesforce information to a local user account
+ */
+function _salesforce_cron_user_update($updated, $type='contact_id') {
+	foreach($updated as $id => $user) {
+		// if they already have an account locally we just update it.
+		if ($user && $id) {
+			if ($type == 'contact_id') {
+				salesforce_contact('update from remote', $user);
+			} else if ($type == 'lead_id') {
+				salesforce_lead('update from remote', $user);
+			}
+			watchdog('salesforce', t('Updated @user from Salesforce', array('@user' => $user->name)));
+			
+		} else if ($id) {
+			// This is a record that exists on salesforce but not locally so we need to create one.
+			$account->salesforce[$type] = $id;
+
+			// TODO: Rather than select each one individually can we select all of them at once? This would be faster
+			// and require less calls to salesforce
+			$fields = array('FirstName', 'LastName', 'Phone', 'Fax', 'Email');
+			if ($type == 'contact_id') {
+				$contact = salesforce_contact_select($account, $fields);
+			} else if ($type == 'lead_id') {
+				$contact = salesforce_lead_select($account, $fields);
+			}
+
+			$values = array();
+			$values['name'] = $contact['FirstName'] . $contact['LastName'];
+			$values['mail'] = $contact['Email'];
+			$values['pass'] = user_password();
+			$values['notify'] = 1;
+			$values['create_lead'] = 0;
+			$values['first_name'] = $contact['FirstName'];
+			$values['last_name'] = $contact['LastName'];
+			$values['phone'] = $contact['Phone'];
+			$values['fax'] = $contact['Fax'];
+			$values[$type] = $id;
+			$values['account_id'] = $contact['AccountId'];
+			// Register the user account. Doing it this way allows Drupal to call all the necessary hooks
+			user_register_submit('user_register', $values);
+			watchdog('salesforce', t('Inserted user @user from Salesforce', array('@user' => $contact['FirstName'].$contact['LastName'])));
+		}	
+	}
+	return true;
+}
+
+/**
  *  used for inserting a single column into the salesforce_users table
  */
 function _salesforce_insert($col, $value, $account = NULL) {
