I have the need to be able to replicate Salesforce Accounts in Drupal in such a way that users of the Drupal site can browse through the Accounts in a directory style. By state, by city, and various other fields. In order to integrate this with Drupal as seamlessly as possible I wanted to be able to use CCK to allow the administrator to have full control over the Account content type within Drupal, and views to allow for the amazing flexibility it provides when creating lists of nodes. This is what I've come up with so far.
In order to achieve this I decided to write a companion module for the existing salesforce.module called salesforce_account.module. This new module makes use of the salesforce.module settings information, and the include salesforce.php, and salesforce_api.inc files. So make sure you have that installed and configured first.
After downloading these files just place them into your existing modules/salesforce/ directory and then enable the module via the normal means.
Here's what this module does currently.
Once installed you can navigate to Administer > Settings > Salesforce > Salesforce Accounts where there is a tool for replicating your Salesforce account object in Drupal. Running this script will query the Salesforce API for a description of your Account object and the related fields and will then use that information to create a new node type (salesforce_account) with all the appropriate fields. The fields are created using the CCK (content.module) methods so you'll have to have that installed as well, along with date.module for handling date fields.
Once you've run the script you should be able to navigate to Administer > Content Management > Content Types > Salesforce Account and see all the relevant fields just like you would with any other CCK content type. Feel free to adjust the description/weight and names of field as you see fit. This "shouldn't" have any adverse affect on the module. (I haven't done much testing with deleting fields yet, do so at your own risk).
If you update your Account object structure in Salesforce later you can come back and run this script again to get updated field definitions. It will attempt to preserve all existing data, but as per usual with this kind of thing backing up is a really good idea.
Adding a new Salesforce Account node in Drupal should also add the relevant information to your Salesforce database.
Editing that account in either Drupal or Salesforce should be automatically mirrored in the other. If you edit it in Salesforce it will not be updated in Drupal until the next time cron.php is run.
The module will also import any Accounts from Salesforce into Drupal that have been added or edited after the module is installed. I don't currently have a method for importing all existing accounts from Salesforce but will in the near future.
Deleting an Account in Salesforce will cause the relevant node in Drupal to be flagged as un-published. Further updates to that node in Drupal will NOT be reflected in Salesforce since the Account has been deleted.
Deleting a salesforce_account node in Drupal doesn't really do much of anything other than remove the node at the moment. If you don't delete that Account from Salesforce as well it will just be re-imported into Drupal next time it is updated in Salesforce. This functionality is open to discussion, but for my current uses I won't need it as Accounts will only ever be deleted from Salesforce.
Once imported/create the new content types should behave just like any other Drupal content type. You can theme them in the normal ways, access all the fields via views, and whatever else you do with your content.
When mirroring data to/from Salesforce via cron the module currently only updates 10 nodes per cron run, and the rest are logged in the database for next time. This is similar to how the search module allows you to limit the number of nodes to index per cron run and is intended to keep cron.php from timing out when it has to update a whole bunch of nodes from Salesforce.
Future plans include. But are by no means limited to ...
The ability to flag Accounts within Salesforce for inclusion in the Drupal site so that only the flagged accounts will be mirrored.
Integration with the existing salesforce.module so that Drupal users who are also Salesforce Contacts can be given permission to edit their Accounts information within Drupal and have those changes mirrored in Salesforce.
Inclusion of some default views for browsing through Salesforce Accounts on your Drupal site.
This module hasn't been heavily tested yet. I did do some basic test and so far it seems to be working quite well. If you install and test this code please let me know of any errors so that I can work on fixing them.
I've also tried to abstract as much of the data replication as possible into it's own file. salesforce_sync_api.inc with the intent of being able to then easily write another module to replicate other Salesforce objects like Opportunities, or Events, or whatever else you need. Some of this duplicates functionality in the existing salesforce.module code, but the two can probably eventually be merged.
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | added_uninstall.patch | 768 bytes | tom friedhof |
| #14 | duplicate_field_names.patch | 3.31 KB | tom friedhof |
| #8 | salesforce_account3.tgz | 9.61 KB | eojthebrave |
| #5 | salesforce_account1.tgz | 8.72 KB | eojthebrave |
| salesforce_account.tgz | 8.2 KB | eojthebrave |
Comments
Comment #1
eojthebraveForgot to mention that when updating nodes in Drupal if the module can't make a connection with Salesforce, or fails to insert the information into Salesforce for any reason it will log that it needs to do so and attempt to insert it again the next time cron.php is run. There isn't a means to view the log at the moment, but you can just take a look at the salesforce_sync_log table if things get stuck/out of whack.
Comment #2
victorkane commentedWow, what a lot of work you have put into this.
On the one hand, I encourage testing, looks very interesting for those interested in mirroring account objects within Drupal.
Some of us were discussing some kind of cache feature without actually making all Salesforce account persist in Drupal redundantly... I encourage you to participate in the thread I have opened at http://groups.drupal.org/node/7065, just to see what others who are participating in the discussion think of this.
Very interested to see how this develops and tests out.
On the other, once again, we are most concerned with getting the legacy Salesforce module out, then forking to a version 2 which will add functionality on the basis of a refactored architecture, to be discussed on the aforementioned group thread. Please participate in that group/thread (there may not be many posters but there are quite a few readers :)
So it's going to be on the basis of that current discussion, which takes into account the widest set of use cases possible, that decisions will be made as to the future architecture and feature set of this module.
Comment #3
bjacob commentedThis sounds very interesting. I will definitely test your module.
In my point of view this is a very important function. I think this should be a core function in the salesforce module. What do you think Victor? Didn't you plan to integrate such a function as well?
Comment #4
eojthebraveOkay, so after thinking about this a bit more I realized that this code does essentially already support mass importing of Salesforce Accounts. You just need to create a record for every account in the salesforce_sync_log table. Then every time cron runs it will sync 10 more accounts until they have all been added. I just tested this out, and granted I only have 15 accounts in my Salesforce database everything seemed to work fine.
If you have devel.module installed you can just run this code using the PHP block.
This will query salesforce for the IDs of all your Accounts and insert them into to the salesforce_sync_log table. Then just run cron.php until they're all imported.
I'll work on patching this into the original code I posted earlier.
Comment #5
eojthebraveFeatures Added:
If you have salesforce.module installed, and configured, users that have an associated AccountId will be able to edit their account from within Drupal and save those changes to both Salesforce and Drupal. This is configurable from Admin > User Management > Access control
Ability to limit what Accounts from Salesforce are synchronized in Drupal. You can now specify an SOQL where clause that allows you to filter the Accounts that will be synchronized. This is configurable from Admin > Site configuration > Salesforce > Salesforce Accounts
Obviously this doesn't work in the other direction. If you create a salesforce_account in Drupal it will always be inserted into Salesforce. However, if you create a new account in Drupal, and that account gets ignored by the limiting SOQL clause then changes to that account made in Salesforce will NOT be applied to the Account in Drupal. Any better ideas about how to handle this?
Add ability to queue your entire Salesforce Account database for insert/update in Drupal. This will create a record in the synchronization log for every Account in Salesforce, then every time cron is run the module will import/update another ten items from the log until it is complete. You can access this at Admin >> Site configuration > Salesforce > Salesforce Accounts
Improved Legibility of code, and help text presented by the module.
Further abstraction of some basic operations into salesforce_sync_api.inc to make it even easier to create your own synced objects.
Continues to work with most recent development version of salesforce.module
I'm curious to know if people think it's a good idea to create some basic default views for this module, or if you would rather just create your own as needed? If so, any suggestions as to what you would like to see.
Comment #6
victorkane commentedPlease contact me via skype or gtalk in order to discuss incorporating this great extension patch (and others you have done) into the salesforce module (want to get an idea of most stable / general version) codebase.
Comment #7
victorkane commentedPlans: upon final version, this patch will be commited to current 5.x development release
Comment #8
eojthebraveCouple more fixes including a bug that caused the _salesforce_sync_put_object function be called when non-salesforce related nodes were edited.
Comment #9
tom friedhof commentedThis module looks very promising. I've just downloaded it to see it in action.
One thing I noticed is this module is dependent on PHP 5, just in case anyone is trying to install this on PHP 4.
Comment #10
eojthebraveAny idea what is making it PHP5 only? I don't see any reason that it couldn't be used on PHP4. What errors did it give you?
Comment #11
tom friedhof commentedThe only thing that is stopping it from being PHP4 from what I noticed so far is the date format character used "c" (ISO 8601 date) when pulling in data from salesforce.
It's very minor, but I think this module should be geared toward php5 anyway, especially for the 2.0 version. This way we can use the Salesforce PHP Toolkit rather than the nusoap implementation.
Comment #12
victorkane commentedPrecisely, that is the Roadmap!
Comment #13
eojthebraveIf you want to use the existing code and all of my patches/extra modules in PHP4 you can simply replace the 'c' option to all gmdate() calls with 'Y-m-d\TH:i:s+00:00'. Just tested, and it seems to be working fine in PHP4 now.
Though for the long haul I agree that we should take advantage of what PHP5 has to offer.
Comment #14
tom friedhof commentedI changed the way the _salesforce_sync_make_field truncates the name. I had a few salesforce fields that were longer than 32 characters, but the first 13 characters were identical causing this module not to be able to create the fields in CCK because of a duplicate field name.
I changed the _salesforce_sync_truncate_field_name() function to _salesforce_sync_make_field_name() and added the same logic that content_admin.inc of CCK uses when determining what the field value will be.
Also the current implementation of _salesforce_sync_truncate_field_name() allowed for 26 character long CCK field names. I'm thinking this is because of taking in to account "_value" to reach the full 32 characters. I believe the CCK field lengths can be a full 37 characters with the "_value" string appended to it. The cck_admin.inc file truncates field names to 31 and the content type tables show field names as long as 37 characters. CCK appears to be ok with 37 character field name lengths. Let me know if I'm wrong here.
Check out the patch and let me know if it works.
Tom
Comment #15
tom friedhof commentedHere is a patch to add an uninstall feature to salesforce_account.module. When you disable the module, the content type goes away and deletes all the fields. When you re-enable the module you can't re-import all the fields unless you remove everything from the salesforce_field_map table.
Doing an uninstall and reinstall fixes this.
Comment #16
eojthebraveThanks tom. I'll add those to my code as soon as I get the chance.
Comment #17
bjacob commentedTom, it's great that you're also submitting patches. Haven't you seen that eojthebrave has submitted a patch for this feature as well? Please have a look at http://drupal.org/node/193235#comment-708565. It seams we have to decide what's the better method to go with...
Comment #18
tom friedhof commentedI didn't see that issue there. The patch you are referring to has two fixes in it. One for handing booleans and one for handling long field names.
I think the patch I submitted for handling long field names should be used. The patch I submitted handles long field names the same way that the cck_admin.inc file handles long field names. I also moved a few lines of code around in the salesforce_sync_api.inc file that pertains to the field name into a function that makes the field name and changed the function name from _salesforce_sync_truncate_field_name to _salesforce_sync_make_field_name.
We probably should have started another issue for this, rather than adding it to this issue. When will salesforce_account.module and such become part of the salesforce module?
Comment #19
eojthebravetom's updates improve on the ones I made. His will provide field names that are more consistent with the way CCK handles them which is probably a much better way to do it than mine. The change in function names is a good idea as well since the new name better describes what is going on in that function.
I have no idea when this code will become part of the module, that's really up to victor kane. I agree that it would be nice to get it in there though, and think it would make using the issue queue much easier.
Victor, I can provide you with a .zip that contains all my updates and new code so you don't have to bother with all the patching if that helps.
Comment #20
tom friedhof commentedFYI, I created another issue regarding bypassing fields on node update in the salesforce_account module over here.
We need to get the salesforce_account module committed to the dev version of the salesforce module or create another project for it, or patches are going to become very hard to manage.
Comment #21
jbomb commentedsubscribing
Comment #22
ceege111 commentedBack at this - I tried generating a new token because I was getting login failed and that log entry went away but it's still not generating leads. It does it handily in the demo/developer account! Argh!
I scoured the settings for differences and came up with a "user marketing license" checkbox which was checked on the demo account but not the main account - but when I tried checking it I got this:
No Marketing User Licenses Available
There are no Marketing User Licenses available. If you wish to add Marketing User Licenses, please submit a case. A salesforce.com representative will contact you.
If you wish to add or update this user now without the Marketing User license, click the Back button in your browser to return to the previous page. Deselect the Marketing User checkbox and click Save.
so I'm waiting to talk to a "sales representative" who might be able to help. We'll see
Comment #23
eojthebraveNot sure if it will help or not but you might want to try updating your partner.wsdl file. See this issue: #214224: partner.wsdl is outdated
May or may not help. I haven't been doing anything with Salesforce lately so I'm a little out of touch.
Victor, are you still working on this module? Do you have any updates? Or plans for future direction of the module?
Comment #24
ceege111 commentedWell after a lot of dorking around with them I upgraded the account from pro to enterprise - but it still didn't work. Did some more looking around and found that there's a whole new module posted that seems to be unrelated to this one - see it at
http://drupal.org/project/salesforcewebform
might be just the thing - seems more up to date, anyway.
Comment #25
amariotti commentedSorry bout that. I should've jumped in here and responded. We had that module developed. It's pretty slick too... go try it out!
Comment #26
jbomb commenteddevelopment on 5.x branch has been halted.