In salesforce_mapping_property_fieldmap_pull_value(), $value often (but not always) ends up as an empty string even when the source value is null. This has the effect of sort of deleting the existing value in Drupal if it exists. If it is null, the value doesn't get removed in Drupal. With it set to an empty string, it is saved as an empty string, resulting in getting displayed as a field label with only an empty string for a value.
What would be preferable is to fully delete the field value, instead of setting it to an empty string. If it's null at salesforce, it's safe to assume it should be removed in Drupal.
Solution would probably deal with looking at the node data build and node save operations. Something like: if field is mapped and sf field value is null, remove existing drupal values.
| Comment | File | Size | Author |
|---|---|---|---|
| #19 | salesforce-pull-null-2199951-19.patch | 5.87 KB | olivier.bouwman |
| #18 | interdiff-2199951-15-18.txt | 1.02 KB | vaish |
| #18 | salesforce-pull-null-2199951-18.patch | 5.17 KB | vaish |
| #15 | salesforce-pull-null-2199951-15.patch | 5.68 KB | chrisolof |
| #13 | fully_support_deleting-2199951-13.patch | 4.67 KB | nielsonm |
Comments
Comment #1
nadavoid commentedComment #2
nadavoid commentedComment #3
nadavoid commentedFound the pattern of nulls vs empty strings. Any Drupal data type that is not explicitly handled in
salesforce_mapping_property_fieldmap_pull_value()ends up being null, if it comes from Salesforce as null. The data types currently handled are list (multi-value select fields), date, boolean, and text. That leaves all other types unhandled, including uri, integer, and decimal. This has the effect of those types not getting deleted from Drupal when they are deleted in Salesforce.Comment #4
nadavoid commentedAttached patch should resolve the issue. In my testing, values are properly deleted when pulled from salesforce, with this patch. Tested with simple fields as well as picklists/arrays.
Comment #5
nadavoid commentedThere are likely still problems with #4. I haven't tested with related entities, which is probably the reason for having that $parent variable which points to a field wrapper.
Comment #6
merilainen commentedAt least the patch is a step forward, now empty decimal fields are emptied correctly in Drupal. Perhaps related entities could be handled in a separate issue? Probably a lot less popular use case.
Comment #7
tauno commentedHere's another approach - the idea is to not push empty values in the first place. This may not properly delete existing values yet, but it's a similar issue. Needs much more testing and work.
Comment #8
tauno commentedSome additional work to attempt to delete field values as well as only triggering saves when at least one field value has changed.
Comment #9
nrackleff commentedHave not tried the patch yet, but in response to #3. The experience I am having on text fields is when they are deleted in SF and come down as null in the SF object, they do not get adjusted at all. Not set to empty string or to null. They just remain as is, not changed at all. So for me, text fields deleted in SalesForce are not getting deleted in Drupal. Will try the patch ASAP.
Comment #10
pianomansam commentedPatch in #4 mostly worked for me, but it resulted in some address fields loosing data.
Comment #11
pianomansam commentedAfter more tests, I've confirmed that #8 is working for me. Patch #4 should NOT be used as it results in data loss. Basically, #4 assumes that if the mapped property is empty, the entire field should become blank. This is a problem, though, because the mapped property might be an optional property. And if it's optional we don't want to make the whole field empty.
Comment #12
aaronbaumanThis has a minor potential side-effect of nullifying "0" (zero) or "FALSE" values.
Need to ensure that this truly only applies to NULL.
Comment #13
nielsonm commentedRe-rolling for latest dev.
Comment #14
mariacha1 commentedI agree with aaronbauman on this one: The latest patch has the side effect of clearing out any fields with any values that come down from Salesforce as FALSE or 0 or empty arrays due to the nature of empty(). I'm not sure this would always be desired.
Here's a list of test cases with what I assume is the desired result vs the current results. Current Outcome (with patch #13), if they are not the Desired Outcome, are in italics:
Case 1:
Drupal Field: No value (empty)
Salesforce Field: No value (empty)
Desired Outcome: Nothing happens
Case 2:
Drupal Field: Set as 0
Salesforce Field: No value (empty)
Desired Outcome: Drupal field value is deleted
Case 3:
Drupal Field: No value (empty)
Salesforce Field: Set as 0
Desired Outcome: Drupal field is set to 0
Current Outcome: Drupal field value is deleted
Case 4:
Drupal Field: No value (empty)
Salesforce Field: Set as FALSE
Desired Outcome: Drupal field is set to FALSE
Current Outcome: Drupal field value is deleted
Case 5:
Drupal Field: No value (empty)
Salesforce Field: Set as "" (empty string)
Desired Outcome: Drupal field is set to "" (empty string)
Current Outcome: Drupal field value is deleted
Case 6:
Drupal Field: Set as any value (1 let's say)
Salesforce Field: No value (empty)
Desired Outcome: Drupal field value is deleted
If I'm wrong about the desired outcome on any of these, I'm open to hear arguments. Otherwise, we need to think a bit more about the use of empty() in the included patch.
Comment #15
chrisolofI believe the attached patch satisfies mariacha1's test cases, but needs community testing and feedback.
The approach is to essentially let NULL flow through to the field set operation and only process/alter/Drupalize the value if there is, in fact, a value provided from SF.
Comment #16
nielsonm commented@chrisolof -
Thanks for picking this up. However it looks like the if statement in the mapping skips over Case 6: field value deletion. I'm going to see if I can take care of that particular edge case since deleting a value in SalesForce, then doing a pull results in an exception. Let me know if you have any thoughts on the issue.
Mike
Comment #17
chrisolof@nielsonm We've got the patch in #15 running on a production site and case 6 is working reliably for us.
If you're getting an exception on Pull after applying this patch, it's been my experience that you probably have a required field in Drupal mapped to an optional field (or occasionally empty field) in SF. When you pull empty (NULL) into a required Drupal field you'll get an exception.
Quick fix is to make the field optional on Drupal.
If that's not possible you may want to look into utilizing hook_salesforce_pull_entity_value_alter() to convert empty (NULL) values coming from the Salesforce field into some sort of default value that can then be stored into the required Drupal field.
If you're curious as to why this happens - the guts of the SF module utilize entity metadata wrappers to set field data. Entity metadata wrappers throw an exception when you attempt to empty a required field on an entity.
Comment #18
vaish commentedPatch in #15 works great. We are using it in production for last 3 months without any issues. However, now that we introduced multi-select picklist in Salesforce, I noticed that clearing of all values in Drupal is broken - only first selected value gets cleared on each pull.
How to reproduce:
Attached patch ensures empty value (NULL) received from Salesforce if muti-select picklist is emptied is handled correctly and empties select list on Drupal side.
I left code for handling case where value returned by SF is not array, although in my testing I couldn't reproduce such situation. If only single value is selected in SF,
explode()insalesforce_mapping_property_fieldmap_pull_value()will still convert this value in array with one element.Comment #19
olivier.bouwman commentedI was getting the following error when clearing a url field in Salesforce and syncing to Drupal: "Invalid data value given. Be sure it matches the required data type and format."
The reason is that when a field with multiple properties (like a link field) has a property that is required (url in the link field example) we cannot set the property/child value to null. We can however set the parent to null since it is not required. In case a field linked to a property gets cleared in Salesforce we assume it's fine to clear the parent of the property in Drupal.
This patch based on #18 should solve this. Many thanks to @gcb for his help with this patch.
There are a lot of changes in the patch, most is coding style, this is the actual change.
Comment #22
mariacha1 commented