Index: salesforce_api/salesforce_api.module =================================================================== --- salesforce_api/salesforce_api.module (revision 109) +++ salesforce_api/salesforce_api.module (working copy) @@ -34,6 +34,12 @@ define('SALESFORCE_LOG_SOME', 5); define('SALESFORCE_LOG_ALL', 10); +// Option values for fieldmap automatic synchronization settings. +// @see salesforce_api.admin.inc +define('SALESFORCE_AUTO_SYNC_OFF', 0); +define('SALESFORCE_AUTO_SYNC_ALL', 1); +define('SALESFORCE_AUTO_SYNC_CREATE', 2); +define('SALESFORCE_AUTO_SYNC_UPDATE', 3); /** * Implementation of hook_menu(). @@ -632,5 +638,8 @@ 'file' => 'salesforce_api.admin.inc', 'arguments' => array('form' => NULL), ), + 'salesforce_api_drupal_sfapi_automatic' => array( + 'arguments' => array('element' => NULL), + ), ); } Index: salesforce_api/salesforce_api.install =================================================================== --- salesforce_api/salesforce_api.install (revision 109) +++ salesforce_api/salesforce_api.install (working copy) @@ -101,11 +101,11 @@ 'default' => '', ), 'automatic' => array( - 'description' => 'Boolean indicating whether this action/map is automatic or triggered.', + 'description' => 'Indicates whether this action/map is automatic or triggered.', 'type' => 'int', 'unsigned' => TRUE, 'not null' => TRUE, - 'default' => 0, + 'default' => SALESFORCE_AUTO_SYNC_OFF, 'size' => 'tiny' ), 'fields' => array( Index: salesforce_api/salesforce_api.admin.inc =================================================================== --- salesforce_api/salesforce_api.admin.inc (revision 109) +++ salesforce_api/salesforce_api.admin.inc (working copy) @@ -285,11 +285,19 @@ } $form['drupal_sfapi_automatic'] = array( - '#type' => 'checkbox', - '#title' => t('Automatically Populate Salesforce?'), + '#type' => 'radios', + '#title' => t('Synchronize automatically with Salesforce'), + '#options' => array( + SALESFORCE_AUTO_SYNC_OFF => t('Never (Do not autopopulate)'), + SALESFORCE_AUTO_SYNC_ALL => t('On create and update'), + SALESFORCE_AUTO_SYNC_CREATE => t('On create only'), + SALESFORCE_AUTO_SYNC_UPDATE => t('On update only'), + // @see theme_salesforce_api_drupal_sfapi_automatic for option descriptions + ), '#return_value' => 1, '#default_value' => $map['automatic'], - '#description' => t('Automatically create and link new salesforce objects when Drupal objects are created?'), + '#theme' => 'salesforce_api_drupal_sfapi_automatic', + '#description' => 'Please indicate how Salesforce records should be handled when Drupal records are created or updated.' ); // Add the data to the form for the required fields table. @@ -426,6 +434,19 @@ return theme('table', $header, $rows, $attributes, $caption); } +// +function theme_salesforce_api_drupal_sfapi_automatic($element) { + $element[SALESFORCE_AUTO_SYNC_OFF]['#description'] = + t('Do not create or update Salesforce records automatically.'); + $element[SALESFORCE_AUTO_SYNC_ALL]['#description'] = + t('Create and link Salesforce records automatically when Drupal records are created and updated.'); + $element[SALESFORCE_AUTO_SYNC_CREATE]['#description'] = + t('Create and link Salesforce records automatically when Drupal records are created, but do not update them automatically.'); + $element[SALESFORCE_AUTO_SYNC_UPDATE]['#description'] = + t('Do not create and link Salesforce records automatically, but update Salesforce records if a link already exists.'); + return drupal_render($element); +} + /** * Demonstrates some of the API functionality through the Salesforce class and * fieldmap functionality. Index: sf_user/sf_user.module =================================================================== --- sf_user/sf_user.module (revision 109) +++ sf_user/sf_user.module (working copy) @@ -53,6 +53,50 @@ case 'load': $account->salesforce = salesforce_api_id_load('user', $account->uid); break; + case 'delete': + db_query('DELETE FROM {salesforce_ids} WHERE drupal_type = "user" AND drupal_id = %d', $account->uid); + break; + + case 'insert': + // When importing *from* Salesforce, don't export *back* to Salesforce. + if (isset($account->sf_user_skip_export) || isset($edit['sf_user_skip_export'])) { + break; + } + + $result = db_query("SELECT fieldmap FROM {salesforce_field_map} WHERE drupal = 'user' AND automatic IN (%d, %d)", + SALESFORCE_AUTO_SYNC_ALL, SALESFORCE_AUTO_SYNC_CREATE); + $map = db_fetch_object($result); + if (!$map) { + break; + } + // Use the first fieldmap. + $map = $map->fieldmap; + + // Check if there is more than one fieldmap in the result. + if (user_access('administer salesforce') and db_fetch_object($result)) { + drupal_set_message(t('Warning: more than one "automatic" salesforce mapping detected. Used fieldmap @map.', array('@map' => $map)), 'error'); + } + sf_user_export($account->uid, $map); + + break; + case 'update': + // When importing *from* Salesforce, don't export *back* to Salesforce. + if (isset($account->sf_user_skip_export) || isset($edit['sf_user_skip_export'])) { + break; + } + + $salesforce = salesforce_api_id_load('user', $account->uid); + if (empty($salesforce['fieldmap'])) { + $result = db_query("SELECT fieldmap FROM {salesforce_field_map} WHERE drupal = 'user' AND automatic IN (%d, %d)", + SALESFORCE_AUTO_SYNC_ALL, SALESFORCE_AUTO_SYNC_UPDATE); + } else { + $result = db_query("SELECT fieldmap FROM {salesforce_field_map} WHERE fieldmap = %d AND automatic IN (%d, %d)", $salesforce['fieldmap'], SALESFORCE_AUTO_SYNC_ALL, SALESFORCE_AUTO_SYNC_UPDATE); + } + if ($fieldmap = db_result($result)) { + sf_user_export($account->uid, $fieldmap, $salesforce['sfid']); + } + + break; } } @@ -104,7 +148,7 @@ drupal_not_found(); } - // Set the node page title. + // Set the user page title. drupal_set_title(check_plain($account->name)); $form = array(); @@ -114,7 +158,7 @@ '#value' => $uid, ); - // Display an export button if the node hasn't been exported before. + // Display an export button if the user hasn't been exported before. if (!$account->salesforce['sfid']) { $form['export'] = array( '#type' => 'fieldset', @@ -122,7 +166,7 @@ '#description' => t('This user may be exported to Salesforce using any fieldmap listed below.'), ); - // Get an array of fieldmaps that export nodes of this type to Salesforce. + // Get an array of fieldmaps that export users to Salesforce. $options = salesforce_api_fieldmap_options('user'); // If no corresponding fieldmaps were found... @@ -354,7 +398,7 @@ // If the export was successful... if ($response->success) { if (empty($sfid)) { - // Store the Salesforce ID for the node and return TRUE. + // Store the Salesforce ID for the user and return TRUE. salesforce_api_id_save('user', $uid, $response->id, $fieldmap); } @@ -402,10 +446,10 @@ $drupal_object = salesforce_api_fieldmap_objects_load('drupal', $map['drupal']); $salesforce_object = salesforce_api_fieldmap_objects_load('salesforce', $map['salesforce']); - // If a node was specified, attempt to load it. + // If a user was specified, attempt to load it. $account = user_load(array('uid' => $uid)); - // If the node exists, simply update the existing node. + // If the user exists, simply update the existing user. if ($account->uid) { // Loop through the fields on the fieldmap. foreach ($map['fields'] as $value => $key) { @@ -426,7 +470,12 @@ } //drupal_set_message('
'. print_r($changes, TRUE) .''); - user_save($account, $changes); + // We don't want to trigger an export while we're running import. + // sf_user_skip_export is a flag to tell hook_user not to export this object. + $account->sf_user_skip_export = TRUE; + $changes['sf_user_skip_export'] = TRUE; + $account = user_save($account, $changes); + unset($account->sf_user_skip_export); } return $account->uid; Index: sf_node/sf_node.module =================================================================== --- sf_node/sf_node.module (revision 109) +++ sf_node/sf_node.module (working copy) @@ -60,8 +60,9 @@ return; } - // Are there any automatic fieldmaps for this node type? - $result = db_query("SELECT fieldmap FROM {salesforce_field_map} WHERE drupal = '%s' AND automatic = 1", 'node_'. $node->type); + // Are there any automatic-synch-on-insert fieldmaps for this node type? + $result = db_query("SELECT fieldmap FROM {salesforce_field_map} WHERE drupal = '%s' AND automatic IN (%d, %d)", + 'node_'. $node->type, SALESFORCE_AUTO_SYNC_ALL, SALESFORCE_AUTO_SYNC_CREATE); $map = db_fetch_object($result); if (!$map) { return; @@ -84,9 +85,15 @@ return; } $salesforce = salesforce_api_id_load('node', $node->nid); - if ($salesforce['fieldmap'] && $salesforce['sfid']) { - sf_node_export($node, $salesforce['fieldmap'], $salesforce['sfid']); + if (empty($salesforce['fieldmap'])) { + $result = db_query("SELECT fieldmap FROM {salesforce_field_map} WHERE drupal = '%s' AND automatic IN (%d, %d)", + 'node_'. $node->type, SALESFORCE_AUTO_SYNC_ALL, SALESFORCE_AUTO_SYNC_UPDATE); + } else { + $result = db_query("SELECT fieldmap FROM {salesforce_field_map} WHERE fieldmap = %d AND automatic IN (%d, %d)", $salesforce['fieldmap'], SALESFORCE_AUTO_SYNC_ALL, SALESFORCE_AUTO_SYNC_UPDATE); } + if ($fieldmap = db_result($result)) { + sf_node_export($node, $fieldmap, $salesforce['sfid']); + } break; } }