--- sf_rpc.module.original 2009-10-21 14:31:20.000000000 -0400 +++ sf_rpc.module 2009-10-22 12:15:17.000000000 -0400 @@ -15,22 +15,33 @@ function sf_rpc_xmlrpc() { // SF Toolkit only gets included on salesforce_api_connect, which we've no reason to call. require_once(drupal_get_path('module', 'salesforce_api') .'/salesforce.class.inc'); - $data = fopen('php://input','rb'); - $content = fread($data, 8192); - while ($more = fread($data, 8192)) { - $content .= $more; - } - - $dom = new DOMDocument(); - $dom->loadXML($content); - $result_array = _sf_rpc_parse_message($dom); - $ret = _sf_rpc_handle_message($result_array); + + // Needed for the reference to SObject in parse_message, otherwise it just seems to die + // when it tries to call new SObject() + require_once(drupal_get_path('module', 'salesforce_api') .'/toolkit/soapclient/SforcePartnerClient.php'); + + $data = fopen('php://input','rb'); + $content = stream_get_contents( $data ); + // I think stream_get_contents might do the same job as the below loop and + // has better feof handling + // vfilby 20091019 + // + //$content = fread($data, 8192); + //while ($more = fread($data, 8192)) { + // $content .= $more; + //} + + + $dom = new DOMDocument(); + $dom->loadXML($content); + $result_array = _sf_rpc_parse_message($dom); + $ret = _sf_rpc_handle_message($result_array); - // To avoid clogging the SalesForce Outbound Message queue, always send ACK. - _sf_rpc_soap_respond('true'); + // To avoid clogging the SalesForce Outbound Message queue, always send ACK. + _sf_rpc_soap_respond('true'); - fclose($data); - exit; + fclose($data); + exit; } /** @@ -51,24 +62,32 @@ function _sf_rpc_handle_message($objects // Load all fieldmaps for easy reference. static $fieldmaps; if (empty($fieldmaps)) { - $fieldmaps = array(); - foreach (range(0, salesforce_api_fieldmap_next_index() - 1) as $i) { - if ($map = salesforce_api_fieldmap_load($i)) { + $fieldmaps = array(); + $fieldmapsCountQuery = 'SELECT fieldmap FROM {salesforce_field_map}'; + $results = db_query( $fieldmapsCountQuery ); + while( $row = db_fetch_array( $results ) ) { + $fieldmap_id = $row['fieldmap']; + if ($map = salesforce_api_fieldmap_load( $fieldmap_id ) ) { $fieldmaps[$map['salesforce']][] = $map; } } } + + // For each Drupal object matching a SF object, update or delete it according // to the appropriat fieldmap. - foreach ($objects['drupal'] as $info) { - $sfid = $info['sfid']; + foreach ($objects['drupal'] as $info) { + $sfid = $info['sfid']; $obj = $objects['salesforce'][$sfid]; - $map = salesforce_api_fieldmap_load($info['fieldmap']); + $map = salesforce_api_fieldmap_load( $info['fieldmap'] ); + // If we get this far, this record is not new. unset($new_records[$sfid]); - // Booleans from SalesForce are strings "true" and "false". - if ($obj->fields->IsDeleted == 'true') { + + // Booleans from SalesForce are strings "true" and "false". + if ($obj->fields->IsDeleted == 'true') { + // Try to delete the local record. if ($row['drupal_type'] == 'user') { user_delete(array(), $row['drupal_id']); @@ -76,35 +95,37 @@ function _sf_rpc_handle_message($objects elseif ($row['drupal_type'] == 'node') { node_delete($row['drupal_id']); } - continue; - } - + continue; + } + $function = 'sf_' . $info['drupal_type'] . '_import'; if (function_exists($function)) { - $id = $function($sfid, $info['fieldmap'], $info['drupal_id'], $obj); - } + $id = $function($sfid, $info['fieldmap'], $info['oid'], $obj); + } - if ($id && $map['automatic']) { - salesforce_api_id_save($info['drupal_type'], $id, $sfid, $map['index']); + if ($id && $map['automatic']) { + salesforce_api_id_save( $info['drupal_type'], $id, $sfid, $info['fieldmap'] ); } - } + } // For each record for which there is no existing Drupal object, attempt to create one. - foreach ($new_records as $sfid => $record) { - // There may be multiple fieldmaps for a single SF Object type. - foreach ($fieldmaps[$record->type] as $info) { - $drupal_type = $info['drupal'] == 'user' ? 'user' : 'node'; + foreach ($new_records as $sfid => $record) { + + // There may be multiple fieldmaps for a single SF Object type. + foreach ($fieldmaps[$record->type] as $info) { + $drupal_type = $info['drupal'] == 'user' ? 'user' : 'node'; $function = 'sf_' . $drupal_type . '_import'; if (function_exists($function)) { - $id = $function($sfid, $info['index'], NULL, $record); - } - if ($id && $map['automatic']) { - salesforce_api_id_save($drupal_type, $id, $sfid, $map['index']); + $id = $function($sfid, $info['fieldmap'], NULL, $record); + } + if ($id && $info['automatic']) { + salesforce_api_id_save( $drupal_type, $id, $sfid, $info['fieldmap'] ); } } - } + } } + /** * Parse SOAP message into its component parts and gather any corresponding Drupal objects. * @@ -127,7 +148,7 @@ function _sf_rpc_parse_message($domDoc) $sObjType = $sObjectNode->getAttribute('xsi:type'); if (substr_count($sObjType,'sf:')) { $sObjType = substr($sObjType,3); - } + } $obj = new SObject(); $obj->type = $sObjType; $elements = $sObjectNode->getElementsByTagNameNS('urn:sobject.enterprise.soap.sforce.com','*'); @@ -143,17 +164,18 @@ function _sf_rpc_parse_message($domDoc) array_push($obj->fieldnames, $fieldname); } } - $result['salesforce'][$obj->Id] = $obj; + $result['salesforce'][$obj->Id] = $obj; } if (!empty($sfids)) { $dbresult = db_query( - 'SELECT drupal_id, sfid, fieldmap, drupal_type FROM salesforce_ids + 'SELECT oid, sfid, fieldmap, drupal_type FROM {salesforce_object_map} WHERE sfid IN (' . db_placeholders($sfids, 'varchar') . ')', $sfids); while ($row = db_fetch_array($dbresult)) { $result['drupal'][] = $row; } } + return $result; } @@ -166,11 +188,11 @@ function _sf_rpc_parse_message($domDoc) function _sf_rpc_soap_respond($tf = 'true') { print ' - - - '.$tf.' - - + + + '.$tf.' + + '; }