This patch adds basic support for the following. It HAS NOT been tested in a production environment. It has however been tested for all of the following cases.
Adding a Lead or a Contact in Salesforce creates an account for that person in Drupal. The login for the new account is the person's first and last name's combined without any spaces. When a new account is created Drupal handles it in the same manner as if the administrator had created the account manually.
Converting a Lead to a Contact in Salesforce will be reflected in associated Drupal account.
Updating the FirstName, LastName, Phone, Fax, or Email fields for a Contact or Lead on Salesforce will update the respective information in Drupal.
Deleting a Contact or Lead in Salesforce marks the associated Drupal account as blocked.
There is a new option under Admin >> Settings >> Salesforce that allows you to select the user account status for new accounts created from Salesforce Leads.
NOTE: This patch does not support updating the "Company" field for a Drupal user profile when it is updated in Salesforce. The company field is actually asscociated with the Salesforce Account and not the Contact and since I have additional plans for handling accounts in the future this will remain un-fixed until then.
The following additional fixes and changes have been made as well.
Changed "salesforce_account_select()" to "salesforce_contact_select()", account_select was misleading since the function actually selects from the contact object.
Added salesforce_lead_select() function. This and the salesforce_contact_select() function could probably be merged as they are "almost" identical.
Includes fixes from this patch. http://drupal.org/node/190516
Fixes use of <string> tags in status messages.
Includes fixes from this patch. http://drupal.org/node/190521
Removes unnecessary calls to Salesforce.
Includes fixes from this patch. http://drupal.org/node/190557
Fixes use of <em> tags in Salesforce "Description" field.
Applies changes from this patch. http://drupal.org/node/190628
Adds a Name column to tables on Lead/Contact lists in Drupal.
TODO:
Add some kind of method for importing all existing Contacts/Leads into Drupal. Currently this patch only works on Contacts/Leads that are updated or added after this has been enabled on your Drupal site.
Test, test, test. Any help you can provide testing and squashing bugs would be much appreciated.
| Comment | File | Size | Author |
|---|---|---|---|
| #43 | sync_sforce_updates6.patch.txt | 40.79 KB | tom friedhof |
| #34 | sync_sforce_updates5.patch | 40.8 KB | eojthebrave |
| #28 | sync_sforce_updates4.patch | 38.94 KB | eojthebrave |
| #23 | sync_sforce_updates3.patch | 25.48 KB | eojthebrave |
| #15 | sync_sforce_updates2.patch | 23.19 KB | eojthebrave |
Comments
Comment #1
bjacob commentedI've applied your patch and I'd like to test your features. I'm happy that you've developed all the mentioned functions. I think it's absolutely necessary that we're having functions to synchronize the data between Salesforce and Drupal. From my point of perspective the patch should go into the module as core functions (after review). What do the other users think? What about you Victor? Right now I'm missing an overview what we want to achieve with the salesforce module. Why don't we setup a place (like a group) where we can discuss the core functions/features/additions of the module?
After a first test in my log file appeared the following error:
type: php
message: Invalid argument supplied for foreach() in /sites/all/modules/salesforce/salesforce.module on line 569
severity: error
This is the code:
I haven't done something special. I've just applied your patch and changed a lead in Salesforce.
Comment #2
victorkane commented"Why don't we setup a place (like a group) where we can discuss the core functions/features/additions of the module?"
We have done just that! We are using the already existing group Enterprise CRM Integration
http://groups.drupal.org/enterprise-crm-integration
for this, and on the basis of various discussions, we have started the following Salesforce specific thread:
http://groups.drupal.org/node/7065
Comment #3
eojthebraveWas the lead updated on your Drupal site after updating them in Salesforce despite this error, or did it fail to update?
Comment #4
bjacob commentedThank you Victor for the group. I will definitely take part in the discussion...
Comment #5
bjacob commentedHi eojthebrave,
I've done some further testing. Here are my results:
1. Lead - create
name: Lead Test2
result:
- user - New user: LeadTest2 created, status: blocked
- salesforce - Inserted user LeadTest2 from Salesforce
- since I've inserted email address login data was sent and event was created (don't know where to find this)
suggestions:
- there should be a function which transforms the usernames in lower case
- We should come up with a function to make sure that German umlauts and other special chars are recognized by your update function. In Salesforce I've added an account with my name "Björn Jacob". The new user in Drupal is named "Bj Jacob". As you can see the first name is cut off.
2. Lead - update
name: Lead Test2
result: user "LeadTest2" was updated, but sometimes error message in log (I had to start the cron manually 3 times):
EDIT !!!
---------
php: Invalid argument supplied for foreach() in /sites/all/modules/salesforce/salesforce.module on line 569.
php: Invalid argument supplied for foreach() in /sites/all/modules/salesforce/salesforce.module on line 569.
3. Lead - delete
name: Lead Test2 "LeadTest2"
result: user not deleted
question: Am I doing something wrong? What do you want to achieve? What happens if someone deletes a lead in Salesforce? Does Drupal delete the user or does Drupal change the status say from active to blocked? What do you suggest? I think status blocked is better.
I've also recognized that the page admin/content/salesforce/lead is not updated properly.
And I'm getting again the error message which I've described above (lin 569). I don't know if it's related to the update task or to the delete task...
EDIT !!!
----------
4. Lead - convert
name: Lead Test2 "LeadTest2"
result: success, status of user is now "active", appears under admin/content/salesforce/contact (moved from admin/content/salesforce/lead), log shows the following:
- salesforce: Updated LeadTest2 from Salesforce
- salesforce: Updated LeadTest2 from Salesforce
Just one thing: Drupal shows the wrong phone and fax number. In Salesforce the number is for both fields "111". Drupal shows "11". But this can also be a problem which is related to the many entries I've done. I will check it later.
Comment #6
eojthebraveThanks for all the input. I'll work on trying to replicate/fix the php: Invalid argument error in the next day or two. The problem seems to come from the result that is returned by the S
Couple of questions for you.
"- since I've inserted email address login data was sent and event was created (don't know where to find this)
suggestions:"
Is this something that Salesforce is doing or Drupal? If Drupal, the way the new user registration is set up it should function exactly the same as if the administrator went and filled out the Add a New User form. So, depending on how your Drupal installation is configured this will vary. If it's something else though ... I'm not really a Salesforce expert as this is my first foray, so any insight would be helpful.
"- We should come up with a function to make sure that German umlauts and other special chars are recognized by your update function. In Salesforce I've added an account with my name "Björn Jacob". The new user in Drupal is named "Bj Jacob". As you can see the first name is cut off."
At the moment I really have no idea how to go about dealing with this. So if you or anyone else has suggestions on how to handle the encoded characters let me know. In the meantime I'll work on abstracting the username creation into it's own function so that it's easier to modify in the future.
"Am I doing something wrong? What do you want to achieve? What happens if someone deletes a lead in Salesforce? Does Drupal delete the user or does Drupal change the status say from active to blocked? What do you suggest? I think status blocked is better."
Currently I have it setup to mark the Drupal user account as blocked when the contact is deleted from Salesforce. I agree that this is the better way to handle it as Drupal gets kind of finicky with deleted users sometimes.
"I've also recognized that the page admin/content/salesforce/lead is not updated properly."
I think I know what's going on with this one and will try and replicate/fix it in the near future.
Thanks again for your input.
Comment #7
bjacob commentedThank you for your fast reply. I'm happy that I could help somehow (with my limited PHP knowledge)...
What did I do? I've created a new lead in Salesforce (entered the following data: first name, last name, company, phone, fax, email). Then I've run the cron manually. After that Drupal told me it has created a new user and email with login data was sent (as you said it depends on the registration process in my Drupal version). Everything is fine and works very well. Furthermore it appeared a message which said an event was created. I think this is something in Salesforce, isn't it? I couldn't find a new event in Salesforce. So this made me wonder. We have to figure out what should happen. Maybe its not working because of this line in salesforce.module:
Yesterday I've posted a problem and Victor came up with a solution (http://drupal.org/node/191527). There was a problem with the $_POST variable. Maybe we can try this line:
It is a good idea having a seperate function for the username creation. The problem with the umlauts... mmh. Maybe we need something like utf8_decode. Or is it a problem with the database. I've looked it up on drupal.org (see http://drupal.org/search/node/german+umlauts). I will check my database settings and let you know. Someone wrote Drupal supports utf8 now...
Comment #8
eojthebraveThis new patch should apply against the current development version of salesforce.module
Fixes this problem. I think.
Invalid argument supplied for foreach() in /sites/all/modules/salesforce/salesforce.module on line 569
Abstracts username creation into it's own function for easier customization in the future.
Fixes this problem, "I've also recognized that the page admin/content/salesforce/lead is not updated properly.". The module now deletes any Leads/Users from Drupal when the equivalent Lead is deleted in Salesforce.
Some cleaning up of sloppy code.
Comment #9
victorkane commentedPlans: upon new version making this two-way synching optional via admin panel (checkbox somewhere), this patch will be committed to current 5.x dev release.
Comment #10
bjacob commentedI've applied your great patch but I receive the following error message:
The line is:
Comment #11
eojthebraveLooks like this line
$salesforce = salesforce();Is not returning a valid salesforce object. Could you verify that your API username/login is correct. What were you trying to do when you received that error?
Comment #12
bjacob commentedI think you are right. I had to change my Salesforce password in order to give my manager the ability to get access to my developer account. I'm so stupid! But this shows again that we need a global validation function which checks if the salesforce login data is correct... In my case I've tried to run the cron job manually. Then I've received the error message. Anyway, thank you for your adivce!
Comment #13
bjacob commentedMore testing with your new patch (after my Salesforce connecting is up and running again):
1st TRY
======
1. Lead - create (Salesforce --> Drupal)
- name: Lead Test1
- results (recent log entries)
- user - New user: LeadTest1 <>. <-- Why do we get these brackets? EDIT: I see: I didn't enter an email address... Within these brackets the email address is supposed to be displayed.
- salesforce - Inserted user LeadTest1 from Salesforce
- status of user: blocked
- problems
- Company not filled out (but we now the problem, right?!)
2. Lead - update (Salesforce --> Drupal)
- name: Lead Test1
- results (recent log entries)
- salesforce - Updated LeadTest1 from Salesforce
- no problems, no php errors anymore! Great!
2nd TRY
=======
1. Lead - create (Salesforce --> Drupal)
- name: Lead Test2
- results after cron run/problems
* user warning: Duplicate entry 'LeadTest2' for key 2 query: INSERT INTO drupal_users (name, mail, pass, init, uid, created) VALUES ('LeadTest2', 'email@domain.de', '2fd1aab3f511eef13e7ea5293e50ac23', 'email@domain.de', 16, 1196415002) in /includes/database.mysql.inc on line 172.
* user warning: Duplicate entry '0' for key 1 query: INSERT INTO drupal_salesforce_users (uid,lead_id,account_id,created) VALUES (0,"00Q7000000J5NBbEAN","",1196415002) in /includes/database.mysql.inc on line 172.
--> Every time the cron runs it tries to create this user. In the recent log entries you can find the following messages:
- salesforce - Inserted user LeadTest2 from Salesforce
- php - Duplicate entry 'LeadTest2' for key 2 query: INSERT INTO drupal_users (name, mail, pass, init, status, uid, created) VALUES ('LeadTest2', 'email@domain.de', '4501359faf5b2ded4fcfdc2c54d56293', 'email@domain.de', 0, 18, 1196415354) in /includes/database.mysql.inc on line 172.
What happend? Some days ago I've testesd the module. I created a new lead "Lead Test2" in Salesforce and synchronized it with Drupal. The user LeadTest2 was created and is active since then. Later I've deleted the Lead/Contact in Salesforce but the user was not deleted in Drupal. Somehow it was still active. What can we do? Is this useful information? Is this a case which can happen in the real world as well? I still think we shouldn't delete users in Drupal. Do we have to come up with another if-case? If such a naming-problem happens should we create a new user with a slightly different username like "LeadTest2_1" or something like that?
3rd TRY
=======
1. Lead - create (Salesforce --> Drupal)
- name: Lead Test10
- results (recent log entries)
- user - New user: LeadTest10 .
- salesforce - Inserted user LeadTest10 from Salesforce
- status of user: blocked
- Drupal login email is sent
2a. Lead - update (Salesforce --> Drupal)
- name: Lead Test10
- results (recent log entries)
- salesforce - Updated LeadTest10 from Salesforce
- no problems, no php errors anymore! Great!
2b. Lead - update (Drupal --> Salesforce)
- name: Lead Test10
- activated user in Drupal
- messages:
- updated lead in salesforce for the user Lead Test10
- The changes have been saved.
- An event was created in salesforce for the user Lead Test10
- checked Salesforce:
- new event: user_edit - Friday, November 30, 2007 - 10:50 <-- Why do we get these html tags?
- problems
- in a second browser I've logged in as LeadTest10 and edited my account data (phone, fax)
- the data was not changed in Salesforce
- no event was created in Salesforce
- EDIT: if inserted a company name (existing one in Salesforce) and changed the phone number and received the following message:
warning: htmlspecialchars() expects parameter 1 to be string, object given in /includes/bootstrap.inc on line 631.
and another problem in the recent log entries:
salesforce - invalid cross reference id - for the user %user
I think this is related to the Company Problem
3a. Lead - delete (Salesforce --> Drupal)
- name: Lead Test10
- results (recent log entries)
- nothing
- problems
- nothing happend, i.e. user in Drupal still active (cron ran 4 times)
- EDIT: after a long time (30 minutes / 6 cron runs) the user LeadTest10 was not avialable anymore under /admin/user/user and admin/content/salesforce/lead --> so it seems that this function is working
3b. Lead - delete (Drupal --> Salesforce)
- name: Lead Test20
- results (recent log entries)
- user - Deleted user: LeadTest20 .
- user - New user: LeadTest20 .
- salesforce - Inserted user LeadTest20 from Salesforce
- problems
- as you can see the user is deleted and the entry under admin/content/salesforce/lead is removed. great! but a new user is created in Drupal because the old lead is not deleted in Salesforce. I know it's not a bug it's a feature. So what should happen if someone deletes a user in Drupal?
- another wired thing happens:
- I've deleted some other users in Drupal (they were created some weaks ago related to my first tests)
- after a cron run I'm getting a lot of messages like this:
user - Deleted user: <>.
salesforce - Deleted user because the Lead was removed from Salesforce
So it seems that the cron is hanging somewhere...
4. Lead - convert
- name: Lead Test30
- status: blocked
- messages after manual cron run
- Password and further instructions have been e-mailed to the new user LeadTest30.
- user warning: Duplicate entry 'LeadTest30' for key 2 query: INSERT INTO drupal_users (name, mail, pass, init, uid, created) VALUES ('LeadTest30', 'email@domain.de', '950cf3971cebc7194367d099f50ae713', 'email@domain.de', 23, 1196421375) in /includes/database.mysql.inc on line 172.
- results (recent log entries)
- php ... (see above)
- user - New user: LeadTest30 .
- salesforce - Inserted user LeadTest30 from Salesforce
- salesforce - Updated LeadTest30 from Salesforce
- BUT: the user is now active in Drupal :)
- user appears under admin/content/salesforce/contact (moved from admin/content/salesforce/lead)
Okay, enough testing for now. Let me know if this helps you a little bit...
Comment #14
eojthebraveThis is great! Thanks for all the testing. I'll work on trying reproduce, test, and fix things over the next couple of days.
Comment #15
eojthebraveUPDATE: This patch contains everything from above plus the following fixes and enhancements.
Contains fixes for most of the problems mentioned in this thread. http://drupal.org/node/197718
Fixed problem with duplicate usernames when a Contact/Lead has the same name as another. Now when users are imported from Salesforce if there is already a user with the same name it will add a unique integer to the end of their username. ie.).
TestUser, TestUser_1, TestUser_2, etc ...
Fixed a problem where if you created a new contact in Salesforce without assigning them to an account an "Anonymous" user was created in Drupal.
Fixed a bug that caused the e-mail address associated with a Drupal user to be lost when syncing with Salesforce.
Made sync of Contacts/Leads from Salesforce into Drupal optional, both default to off. After applying this patch you MUST go to Admin > Settings > Salesforce and enable syncing before Drupal will start (continue) collecting/updating information from Salesforce.
Made sync of contacts/leads use {salesforce_sync_log} to log update/deleted leads and contacts, and then process 10 of them per cron run. This should help with timing out issues. In order for this to work you have to have the {salesforce_sync_log} table, which you can get by either re-installing the module salesforce.module after applying this patch, or manually adding it. If you've previously installed the salesforce.module you will need to add the table manually or edit your {system} table so that the .install file gets run again.
Change the process for detecting when Contacts/Leads are deleted in Salesforce because the IsDeleted field on both models seems to be depreciated, or at least doesn't work anymore. Now uses $salesforce->getDeleted() method. This is probably a better way to do it anyway.
Fixed problem where deleting a Contact in Salesforce did not mark the associated Drupal user as inactive which it should have been doing.
This patch should apply against the current development version of the salesforce module.
Comment #16
bjacob commentedThank you very much for your patch! It's great that you put such a lot of effort in this. Wow! I've applied your fix but somehow Drupal says "Failed to authenticate on SalesForce.com". I don't understand the problem. I didn't change my login data. Therefore it should work. Now I've installed a new Drupal (5.5) and installed all the modules but still the same problem. I've checked my login data several times. Do you encounter the same problem?
Comment #17
victorkane commentedI think it's great that you are testing the patch and your work is a great contribution to the efforts which will be crowned shortly with the official release of the Salesforce module for Drupal 5.x and the complete refactoring / redesign for Drupal 6.
However, please don't change a thread to a bug report when dealing with patches not made part of the development release.
Am changing from bug back to feature request (there is no bug report relative to any official or development release of the modules, and there is an advisory on the patch that it is not ready for prime time).
Comment #18
eojthebraveI haven't had any problems connecting. Do you have the developer module installed? Could you try putting this code into the PHP block and executing it. Or adding it to a page in your site.
This might at least give you some idea as to why it is not connecting. Looking through the code, the error you are receiving is raised if drupal fails to login to salesforce, and if the user trying to run the process has "administer salesforce" permissions.
Comment #19
bjacob commentedThanks. I've installed the recent version of the salesforce.module (without any changes). I've created a new page and pasted your code (entered my username and password which I had checked at salesforce.com). I've received the following message:
Fatal error: Class 'salesforce' not found in /includes/common.inc(1347) : eval()'d code on line 6.
Then I've entered my username and passwort several times and got all the time the same message: "Failed to authenticate on SalesForce.com". It's a new installation of Drupal and it should work. Right now I've no idea. Is there anything I can administer in salesforce.com? Is there a function which I've switched on and now I've got a problem... ?
Thank you for any help.
Bjoern
EDIT: I'm a little bit angry. Today I found the reason why it's not working. I've changed my salesforce password (it was my last hope) and I received an email. There a security token was enclosed. And that's the solution! I have to combine the password and the token and now my system is running again...
Comment #20
bjacob commented@victorkane: I'm sorry that I've changed the category of this post quite often. You are absolutelly right and I understand what you are saying. It's my first time that I'm working with this "bug tracker"...
I've done some more testing ;)
That's a great function but I think I've found a problem:
What can we do? Should we tell the administrator not to run the cron within 600 seconds? Should we check the ContactID or something like that?
I've got a question about a database query. You can find it in line 426, function salesforce_contact_select()
$contact = $salesforce->query("SELECT ". implode(',', $params) ." FROM contact WHERE Id = '". $account->salesforce['contact_id'] ."'");I couldn't find an "Id" field in the Salesforce API documentation. Why don't we use "AccountId" which is documented?
Another question. As I reviewed your changes I've seen the following lines:
What's the purpose of this code? Do you want to insert the company name into the appropriate field in Drupal? If yes I think it's not working on my system. After several cron runs the company field is still empty in Drupal.
Thank's again for your work and effort!
Comment #21
eojthebraveI'll look into the issues with creating duplicate users and see what I can come up with. I think I've got it figured out in my head already, just have to implement it.
To answer your question about the salesforce query above. The "Id" field is a valid salesforce field. Every salesforce Object has a uniquie Id field. Using AccountId in this case would give us the unique Id of the Account that this Contact is associated with, not the Contact Id that we need. Hope that clarifies things, let me know if it doesn't.
The second bit of code you mention above is there because Victor wanted to make sure that using the "sync via cron" was optional and could be turned off. Since his original code contains code to update the "Company", or Account field for a contact that conflicted with my code which doesn't deal with the Account field directly but expects it to be handled separately from the Contact this code checks to see if "sync via cron" has been enabled and if so ignores the $account->company field. This is really just a temporary solution. I for one would still like to see the Contact, and Account objects handled by separate modules, and this is a step in that direction.
Basically, if you've enabled "sync via cron" then the company field will be ignored in Drupal. You can set it in Salesforce, but it won't be synced, and visa versa.
Comment #22
bjacob commentedeojthebrave, I just wanted to ask if you could make some progress. Is there anything I can do to help you a little bit?
Comment #23
eojthebraveHere's a patch with the progress I've made recently. At the moment I haven't been working on it much as I've been busy with other stuff. This one has sort of been put on the back burner.
I'll just copy and paste my notes about what I've changed recently
----------------------
Fixes -
Refactor salesforce() in salesforce_api.inc so that it re-uses the $salesforce object rather than creating a new one each time.
Additions -
SOQL Limiter for contact sync operations
You can now supply arguments to define which contacts from Salesforce are available for sync operations. Use the supplied field on the Salesforce settings page to enter the WHERE clause of the SOQL that is used to SELECT contacts from Salesforce for udpate/insert operations. For example entering 'FirstName="Joe"' would make sure that only people with the First Name "Joe" would be synced from Salesforce into Drupal.
Support for custom profile fields.
If you add fields via profile.module that conform to the following naming convention they will by synced (when possible) with the equivalent Salesforce field.
All new profile.module fields must be part of the "Personal Information" category.
New profile.module field names must be prefixed with "sf_" and then match exactly the name of the field in Salesforce. So for example if you have a custom field in Salesforce named "Technical_Skills__c" and create the equivilant field named sf_Technical_Skills__c using profile.module the salesforce module will attempt to sync that field as well.
This works (limited testing) with date fields and select lists as well. Remember, to try and match the salesforce field type. Date fields in salesforce should be date fields in profile.module, Salesforce multi-select list to profile.module free-form list etc..
I'm sure this method could be improved, but since I'm in favor of ditching profile.module in the long run I'm not going to spend to much time on it beyond what is needed for a current project.
----------------------------------
This patch should apply against the current DEV version of the salesforce module. If you've already installed the module you'll need to add the MySQL table from a few comments up, or re-install.
bjacob, are there specific things that you're hoping to accomplish, or problems that you need fixed. Let me know and I'll see what I can do as time permits.
Comment #24
bjacob commentedThanks eojthebrave for your patch. I've applied it and I'll test the new features ASAP. You're asking what I want to accomplish. Okay, here's the plan:
What needs to be done:
I think this is a lot of work which has to be done. I've found a developer who's currently working on some issues.
To achieve some of our goals it would be great if you could fix the problem mentioned in comment #20 (http://drupal.org/node/190631#comment-655676).
We've also found some other problems in your great salesforce_cases.module (see comment #8 http://drupal.org/node/193235#comment-664314). Yesterday, the developer could come up with some answers to the questions in comment #8. He told me he wants to post his ideas/solution/whatever today...
---
EDIT: I think I've found a bug. As I said I've applied your patch. Then I've created a new profile field called 'sf_MobilePhone'. The field 'MobilePhone' is a standard field in Salesforce. Watchdog prints the following errors:
I'll check the source again.
Comment #25
bjacob commentedAfter some tests I realized that I can't synchronize contacts anymore. The PHP error makes it impossible.
And I think I've encountered another problem. Here's what I did:
Comment #26
eojthebravebjacob have you made any other changes to the code? Your line numbers don't seem to match up with anything relevant in my code.
salesforce.module
Line: 719 = $values['create_lead'] = 0;
salesforce_api.inc
Line: 444 = _salesforce_insert('account_id', $contact['records']->values['AccountId'], $account);
Do you have any other profile.module fields using the new sf_* naming convention? I just added the sf_MobilePhone to my profile.module fields and it seems to be working as expected so far.
Any help replicating the problem would be great.
Comment #27
bjacob commentedeojthebrave, I'm totally sorry. In order to develop own functions I've added some new lines to the module and api files. Therefore the line numbers are not very helpful. Line 719 in salesforce.module is the following one (function _salesforce_cron_user_update):
Line 444 in salesforce_api.inc is the following one (function salesforce_contact_select):
Line 452:
In the meantime something has changed. Now it seems to work. The other day (after I've applied your patch) I've dropped each and every table which was related to the salesforce and salesforce_case module. I cleared the system table and the profile tables. Afterwards I've made a new installation of the salesforce module. I've deleted all users. Then I've added a new field sf_MobilePhone and now it's synchronized. I don't know why it wasn't working. Maybe some old data caused the problem.
Comment #28
eojthebraveAnother huge patch. This one fixes/adds support for a bunch of things I needed for a current project and hopefully irons out some of the bugs mentioned earlier.
bjacob, this "should" eliminate the problems you were having above. If it doesn't let me know.
Copied from my notes --
- Updated some of the comments, and fixed some of the language used in places.
- Fixed problem with timestamp not being correctly set in {salesforce_users} created field
- Reworked the logic in hook_user('update') to allow syncing of information with Salesforce without requiring the _salesforce_is_form('leads', 'user_edit') to return TRUE. This means you can now remove all the values from the Create Lead on Forms in Admin > Settings > Salesforce and things will still work as expected.
- Ability to choose wether or not users created from Salesforce contacts are blocked or active by default.
- Ability to assign roles to users created from Salesforce contacts
- Refactored code in salesforce_admin_settings to make the page itself easier to understand and bring the code inline with Drupal coding standards. http://drupal.org/coding-standards
- When attempting to create a new Drupal user from a salesforce contact the code will now check to see if a Drupal user with that e-mail address exists and if so will create the link between Drupal User and Contact rather than inserting a new user.
PTP Specific Changes
- Had to download and use a newer version of the partner.wsdl. Downloaded from Salesforce account and replaced the current one in salesforce/includes/partner.wsdl, change name of old one to partner.wsdl-a
- Modified includes/salesforce.php so that it now allows HTTPS connections to Salesforce. In order to get this working you'll also need to download a newer version of the partner.wsdl from Salesforce and replace the one in salesforce/includes/
- Some checks have been put in place to hopefully prevent the problems discussed here http://drupal.org/node/190631#comment-693324
-----------------------------------------------------------------
This patch also includes everything presented by the other three patches in this thread and is intended to work against the current dev version of the module.
Comment #29
victorkane commentedGreat work, indeed!
As soon as I can I will review and test, and commit.
If we are sure everything is stable, we should come out with the 5.x stable version.
Then we can get on with the roadmap (new features for the 6.x.dev version).
Comment #30
bjacob commentedHi there,
wow this is just awesome! I've applied the patch and started testing some of the features. As you know I've also installed the salesforce_case.module. After I've run the cronjob manually I've received the following error in the status log:
The corresponding line in salesforce_case.module is:
in function salesforce_case_cron().
I found out that the new partner.wsdl is causing the error. I've replaced the new one I've downloaded today with the old one and the error is gone. So what can we do in order to use the new partner.wsdl?
On Monday I'll spend more time on testing the module. So Victor if you can wait till Monday... :)
Comment #31
victorkane commentedAbsolutely, thanks for your enthusiasm.
In any case, we need to identify the subset which will be needed by most users.
(corrected inadvertent change of issue title)
Comment #32
bjacob commented1. created contact (Salesforce -> Drupal)
settings
result
problem
2. updated contact from test 1 (Drupal -> Salesforce)
result
problem
3. created contact (Salesforce -> Drupal)
settings
result
no problems
4. created contact with same name as in test 1 (Salesforce -> Drupal)
settings
result
no problems
5. created contact with same name and same email address(Salesforce -> Drupal)
settings
result
no problems
6. deleted 2 contacts (Salesforce -> Drupal)
process / result
7. deleted contact (Drupal -> Salesforce)
process / result
conclusion
--------------
IMHO we have to address the following issues:
Tomorrow I will do the same tests with leads.
Comment #33
eojthebraveIn response to #30 above - http://drupal.org/node/190631#comment-697682
Looks like the new .wsdl has a different return value for the getDeleted() API call.
Just replace this ( ~ line 115 )
with this
"Should" take care of the problem.
Comment #34
eojthebrave- Modified handling of results returned by $salesforce->getDeleted(), seems like something may have changed in the newer versions of the .wsdl - Reported here: http://drupal.org/node/190631#comment-699708, This should also address the issue reported in part 6 of the testing in the previously mentioned comment where only one of the two deleted contacts is properly updating the associated Drupal account as blocked.
- Add "last_sync INT(10) NOT NULL DEFAULT 0" to {salesforce_users} table. - If you have previously installed the module you'll either need to re-install it completely so that the .install file is run again, or manually add this new column to your MySQL table.
- Added check in salesforce_contact('update from remote') that compares the Salesforce contact's LastModifiedDate to the last_sync date and only performs the update if the LastModifiedDate is more recent. This should eliminate the problem where Contacts are updated multiple times if you run cron.php multiple times in a row. These changes were made for the salesforce_lead('update from remote') as well. - Hopefully addresses the issues here http://drupal.org/node/190631
- Added uft8_encode() creating a username from a Salesforce contact. This eliminates the problem where names with accented characters get truncted, but may not be the best solution overall. Is there some way we can get Salesforce to return it's results as UTF-8? Otherwise we might need to just start using utf8_encode on all strings returned from Salesforce to make sure we don't truncate anything due to "bad" characters. - First reported here http://drupal.org/node/190631#comment-628496
This patch is intended to be applied against the current DEV version of salesforce.module and incorporates everything from the first 4 patches in this thread as well.
----------------------------------------
In regards to "Synchronization of field company/account." from bjacobs comment above. I haven't done much with this since I really think the Account object should be handled by a seprate module. ie. (http://drupal.org/node/192605) - and have no need or desire to handle it otherwise in my current project. However, if someone wants to implement it it should be pretty easy to modify the code in the salesforce_api.inc file to do so.
In regards to "Unchecking checkbox "create a lead in salesforce" impossible.", I haven't done much with this other than figure out how to disable it completely since I don't need to deal with Leads at all in my application. I did rewrite some of the code so that you can just remove all of the form ids form the text field on the Salesforce settings page in Drupal and the check box will no longer show up. If I get some free time in the future I'll look into this one further. This is my temporary solution for allowing people to disable this function completely, but not remove it from the module. I do think that this is another section that needs some serious work.
Comment #35
bjacob commentedThanks eojthebrave for your patch. I've applied it and I'm very happy what you've accomplished. But right now I've got some serious problems. All the testing has massed up my system. Therefore I've installed a brand new Drupal on a different Server with a different IP address. I've activated some modules (cck, views, token, pathauto) and set up salesforce.module. Then I went to admin/settings/salesforce and entered Salesforce username and password...
I know it's an old story but I can't connect to Salesforce. All the time I'm getting the message "Failed to authenticate on SalesForce.com" and when starting the cron I'm getting a PHP error:
So I started investigating the problem: checked my password settings; changed password; received new security token and added it to my password; went to Salesforce Admin area and added via Setup / Security Controls / Network Access my IP and the IP of the server (even IP ranges); went to Setup / Manage Users and checked login History (no event i.e. salesforce.module is not even trying to connect); downloaded new partner.wsdl; tried a second developer account login data (same problem)... As you can see I've done a lot but still it's not working.
Any ideas?
Comment #36
eojthebraveI would try opening up the salesforce/includes/salesforce_api.inc file and try putting a print_r($salesforce); exit(); right after this line
$salesforce = new salesforce($_SERVER['DOCUMENT_ROOT'] . base_path() . drupal_get_path('module', 'salesforce') . '/includes/partner.wsdl');in the salesforce() function. Then run something that will invoke salesforce().
Might at least give you some idea as to why your connection is failing. Does salesforce return any errors when you're trying to login with the php client.
Comment #37
bjacob commentedI've done what you've supposed. Drupal prints an extremely long list. Right now I don't know what's important to look at. If you want you can find the formatted output file at http://www.drupal.contrend.de. It would be great if someone could have a look on it.
Salesforce doesn't return any error message :(
Comment #38
bjacob commented--- edit --- sry, same as #37 ---
Comment #39
eojthebraveLooks like there is something wrong with your WSDL.
wsdl error: XML error parsing WSDL from /www/115088_07745/projects/drupal/drupal_truition_2/sites/all/modules/salesforce/includes/partner.wsdl on line 1: Reserved XML Name
What version are you using? If you updated can you try reverting to the older version of the file and and see if that solves the problem.
Can you check the permissions on your .wsdl file? You might need to set the executable bit on it. It looks like the old .wsdl that comes with the module has it set. Though mine seems to be working fine without setting it. ( chmod +x partner.wsdl )
Comment #40
bjacob commentedThanks eojthebrave, the problem was my partner.wsdl. I've downloaded the .wsdl you've provided at http://drupal.org/node/214224. Now it seems to work...
Comment #41
bjacob commentedOur project is moving forward and I had time to test the synchronization of contacts. I've got an existing contact in Salesforce. The contact was synched to Drupal. So far everything is okay.
Now I've logged in as the user and went to the user's account page (/user/xxx) and edited the "Personal information". I've changed the fields "Phone" ($user->phone) and the "Title" ($user->sf_Title). This is synched to Salesforce. After that I've cleared the fields for phone and title (empty fields) in Drupal. I've started the cron and instead of having no values the phone and title fields showed the old values which are stored in Salesforce and should be overwritten.
IMHO we have to write a function which pays attention to this special case. Do we have to include a timestamp check or something like that (or a check to find out which entry is newer)...
EDIT: I've seen that the same happens when clearing a field which was generated by the salesforce_case module.
Comment #42
bjacob commentedI've got another question. I would really like to synch the company field (in Salesfore name of account). How can I achieve this? I went to the salesforce_api.inc and changed the following lines in function salesforce_contact:
and
But it's no working. It would be great if someone could help me. Thanks, Bjoern
Comment #43
tom friedhof commentedSmall bug in sync_sforce_updates5.patch file. When it converts a profile date to a date format that SFDC likes it has the date variables in the wrong order in the mktime function. I've rearranged that line of code to properly convert the date.
There seems to be a timezone issue with the profile date field. It looks it grabs the system timezone and adjusts the date that is fed supplied and modifies it. This is another issue that I need to look into, but at least now my dates are only off by 7 hours.
Here is the same patch, but with the mktime function corrected
Comment #44
bjacob commentedHi Tom,
can you outline the code you've changed. I don't want to go through all the code.
@all
What's the recent status of the project / modules. Can anyone help me with my questions from comments #41 and #42? That would be great.
Comment #45
tom friedhof commentedThe patch above is actually a patch that eojthebrave did a while back for syncing fields. I just made one minor modification. If I remember correctly, when syncing the dates the mktime function was formating the month, day, and year in the wrong order.
To see what I actually changed from his original patch, you'll have to run a diff between my patch above and eojthebrave's version 5 patch.
Comment #46
bjacob commentedI think I've found a bug ;)
You can see that a database table {salesforce_logs} is updated. This table doesn't exist. Instead we have to use {salesforce_log}.
Comment #47
TimAlsop commentedHas anybody been working on this module since April 2008 ? I wondered if it has been made to work with Drupal 6 and using the latest Salesforce API module ?
Comment #48
aaronbaumanTim, as far as I know the 5.x branch of this module is dead. (see #702614: 5.x branch is no longer relevant. Let's drop it.).
I believe the 6.x branch supercedes this functionality anyway by implementing a generic mapping strategy instead of supporting specific objects.
Marking postponed, pending
#702614: 5.x branch is no longer relevant. Let's drop it.
Comment #49
aaronbauman