Reply
 
LinkBack Thread Tools Rate Thread
  #1  
Old 07-16-2007, 08:34 AM
Administrator
 
Join Date: May 2007
Posts: 378
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike
Salesforce – PHP To MySQL Database Replication Script
Over the past few weeks I have been writing tutorials, giving out code snippets, and data base schema's trying to help PHP developers, that work with Salesforce, some idea on how to build a local database replication system so that an organization can use their salesforce data with their own systems. Today I am releasing the first of a series of scripts that can be used as is or modified that will create a copy of your data in a MySQL database. I am starting this series on the Salesforce Account Object / Table.

I have successfully created PHP scripts which export my organizations data from salesforce into Oracle 10g. I know that many organizations use MySQL (since it is open source) and very stable. I have not seen any examples of exporting data from Salesforce into MySQL so I thought I would try and help out a little.

Attached is a schema for the account object / table for MySQL, also attached is complete working export script that will export the account object from salesforce and store it in MySQL, given the schema that I am providing. To run this script you have to have the following:
  • PHP 5
  • ADOdb database abstraction layer / class
  • Your salesforce username and password
  • MySQL connection strings (password, user, and database name)
In this example you have to change line 14 of the script with your MySQL account settings:

PHP Code:
$db->Connect("localhost""Username""password""TargetDatabaseName"); 
I also added a new part to the script that allows for the truncation of the local MySQL table. I use this because the data coming in is really a data dump and this will also eliminate duplicates in your data. Someone asked me why I also do not set a Primary key on this or other tables when working with salesforce. Well if you try and set such a key, let's say on the Id field and you try and run this script on a weekly basis without a truncate, you will not be able to insert data into the table because it will error on inserting on a primary key. I have tested this and it will error, I assure you.

You can comment out the code if you wish, look around line 19-21:

PHP Code:
$sql "TRUNCATE TABLE sforce_account";
if (
$db->Execute($sql))
echo 
"Salesforce Account Table Truncated
"

In order to get this account table replication working, I suggest this:

Open the account SQL file and import it into your database or test database using phpmyadmin or some other data base tool.

Open and edit the attached PHP script and change the MySQL database settings and your salesforce connection (user and pass)

Check the paths in the PHP script (see line 6 - 8):
PHP Code:
require_once ('./includes/soapclient/SforcePartnerClient.php');
require_once (
'./includes/soapclient/SforceHeaderOptions.php');
require_once (
'adodb.inc.php'); 
Then just run the script and once it is complete, compare the number of records you have in your instance of Salesforce.com to the record count of MySQL:
Code:
SELECT count( * ) FROM sforce_account
The script already performs a count of your accounts (see line 37):

PHP Code:
echo 'There are currently ' count($accounts) . ' accounts:'
I hope this works for you and if you have any questions, please feel free to contact me

Thanks,
Mike


Please remember that while this and other scripts on my site work in my environment, they are just examples. Use of these scripts and tutorials are at the risk of whomever downloads and uses them as is I assume no risk what so ever.
Attached Files:

Last edited by mike; 07-16-2007 at 08:35 AM. Reason: Forgot to add scripts!
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #2  
Old 08-24-2007, 09:28 AM
Junior Member
 
Join Date: Aug 2007
Posts: 10
Send a message via MSN to slugmandrew
Thumbs up Great work!
Hi,

I stumbled across your site yesterday while researching the salesforce.com API. Some of the stuff you have here is really excellent and definitely much needed as there is so little on this subject on the web so far. (from what I've found)

I'm currently in the process of learning php and MySQL and have built a simple database for use on our site. Then I started to think about exchanging data between salesforce and our own db so that customer leads, accounts and user information could be shared seamlessly.

One problem I have is that I have never come across ADOdb before so this is somewhat of a stumbling block for me as I am only just getting to grips with MySQL. Is there any chance you will do a replication script using plain MySQL statements? Even just some basic examples would be great because I'm finding it difficult to understand what parts require ADOdb and which parts don't.

Keep up the good work.

Slugmandrew
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #3  
Old 08-24-2007, 03:40 PM
Administrator
 
Join Date: May 2007
Posts: 378
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike
Originally Posted by slugmandrew View Post
Hi,

I stumbled across your site yesterday while researching the salesforce.com API. Some of the stuff you have here is really excellent and definitely much needed as there is so little on this subject on the web so far. (from what I've found)

I'm currently in the process of learning php and MySQL and have built a simple database for use on our site. Then I started to think about exchanging data between salesforce and our own db so that customer leads, accounts and user information could be shared seamlessly.

One problem I have is that I have never come across ADOdb before so this is somewhat of a stumbling block for me as I am only just getting to grips with MySQL. Is there any chance you will do a replication script using plain MySQL statements? Even just some basic examples would be great because I'm finding it difficult to understand what parts require ADOdb and which parts don't.

Keep up the good work.

Slugmandrew
You should really start using ADOdb for your connections, but if you do not want to do it that way I can understand. I will try and get some sort of example on what you are looking for in the next day or so, but cannot promise anything.

If you download some of my examples and ADOdb and try it, it should work out of the box

Sorry I have been in Hawaii on vacation and have not had access to the Internet what so ever

~Mike
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #4  
Old 08-29-2007, 11:30 AM
Junior Member
 
Join Date: Aug 2007
Posts: 10
Send a message via MSN to slugmandrew
Mike,

Thanks for your advice. Since posting the last message i've had a bit of a read about ADOdb and it doesn't seem that hard to learn and may come in useful in the future so i will give it a go. What the hell, i'm neck-deep in new code anyway

I have now got my installs of everything working ok and I have tested with the sample login script with the php toolkit, but i'm getting an error when i try to update an account that has an ampersand in it's name. I posted on the ADN board here. If anyone more experienced than me can help i'd appreciate it.

Thanks,

Slugmandrew
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #5  
Old 08-30-2007, 10:48 AM
Administrator
 
Join Date: May 2007
Posts: 378
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike
Are you having problems with the Ampersands in the samples from the PHP Toolkit? Let me know, I may have a solution

If you open the edit.php from the samples and search for this line (around line number 56):

PHP Code:
$name $_POST['AccountName']; 
change it to:

PHP Code:
$name htmlspecialchars($_POST['AccountName']); 
that will convert the & to & so it can be used over SOAP(XML format)

Try that and let me know if that works

~Mike
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #6  
Old 08-31-2007, 04:20 AM
Junior Member
 
Join Date: Aug 2007
Posts: 10
Send a message via MSN to slugmandrew
Thumbs up
Your change works great! Thanks so much.

Yes, it was the samples in the toolkit. Strange that I found a post about it on the ADN but there was no solution there. The guy who had the problem before said he used a php function to replace any & with & but that seemed a bit like re-inventing the wheel to me.

Just one question, I'm a bit lost as to why SF would give out developer accounts with demo account names full of ampersands when the php toolkit doesn't convert them properly in the code samples?!? Any ideas why, or is it something i've done? This doesn't seem to be a common problem.

Thanks again.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #7  
Old 08-31-2007, 08:16 AM
Administrator
 
Join Date: May 2007
Posts: 378
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike
I have found that you will run across simple errors as this from time to time. I also came across some errors in the Toolkit when I started to use it. Believe me it is not done intentional or is not something that you have done. Nick Tran is the only one at Salesforce that works on the toolkit and is always looking for people to help correct items such as this. What I would do is post your problem on the forums or maybe even the solution and then he will make the change, that is what I do.

You should also add htmlspecialchars to any field, except the Id field, that you will be sending to SForce in the future. I did not know this at one time but started to receive the same errors that you did.

One way to accomplish this to your whole array at one time is to use a php function called <a href="http://us3.php.net/array_map">array_map</a>

Look at this example:

PHP Code:
while ($row $recordSet->FetchRow())
{
                
$row array_map('htmlspecialchars'array_map('stripslashes'$row));

                
$all_fields[$i]['ISACTIVE']  =  $row['ISACTIVE'];
                
$all_fields[$i]['PRICEBOOK2ID']  =  $row['PRICEBOOK2ID'];
                
$all_fields[$i]['PRODUCT2ID']  =  $row['PRODUCT2ID'];
                
$all_fields[$i]['UNITPRICE']  =  $row['UNITPRICE'];
                
$all_fields[$i]['USESTANDARDPRICE']  =  $row['USESTANDARDPRICE'];
                
$i++;

The first line inside the While loop:
PHP Code:
$row array_map('htmlspecialchars'array_map('stripslashes'$row)); 
applies this to all rows, all fields. so if you have to remove, change, or add any fields to the array, you still apply the htmlspecialchars to the affected rows

Hope this helps

~Mike
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #8  
Old 08-31-2007, 09:37 PM
Junior Member
 
Join Date: Aug 2007
Posts: 1
How do you get the mysql table structure?
Hi Mike,

I like your site. Well done Now, can you kindly tell me how I can get the mysql equivalent table generation for the Account and Case tables? I saw your account sql, but I wanted to know how you got it. I'm looking to do db backups of those to mysql. I'd appreciate whatever you can to help educate me

Thanks,
David
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #9  
Old 09-01-2007, 09:50 AM
Administrator
 
Join Date: May 2007
Posts: 378
Send a message via AIM to mike Send a message via MSN to mike Send a message via Yahoo to mike Send a message via Skype™ to mike
David

To get those tables and all your other objects to tables, Have you tried this?

Salesforce PHP MySQL Database Replication Tool
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
  #10  
Old 09-07-2007, 07:02 AM
Junior Member
 
Join Date: Aug 2007
Posts: 10
Send a message via MSN to slugmandrew
Question Using array_map to add htmlspecialchars function
Mike,

Thanks for your help yet again. This looks like a useful function. At first I couldn't really work out how to use it but I think I have it now.

So in your previous example, you are taking each row as an array, $row, using array_map to stripslashes and add htmlspecialchars, and then passing the 'cleaned' array back into $row itself?

It took me a while to work out how to change this code:

PHP Code:
if (isset($_POST['doUpdate'])) 
  {
    
    
$sfid $_POST['sfid'];
    
$ct htmlspecialchars($_POST['City']);
    
$st htmlspecialchars($_POST['State']);
    
$phone htmlspecialchars($_POST['Phone']);
    
$fax htmlspecialchars($_POST['Fax']);
    
$name htmlspecialchars($_POST['AccountName']);  // added 'specialchars' to remove &
    
    
$fieldsToUpdate = array('Id' => $sfid,
                            
'Name'=>$name,
                            
'BillingCity'=>$ct,
                            
'BillingState'=>$st,
                            
'Phone'=>$phone,
                            
'Fax'=>$fax);  // create array from posted variables
    
    
$sObject = new SObject();  // declare new sObject
    
$sObject->fields $fieldsToUpdate;  // set fields of new sObject
    
$sObject->type 'Account';  // set type to account
    
$acct $mySforceConnection->update(array ($sObject));  // update sObject

    
header('Location: welcome.php');   // redirect to welcome.php
  

into something that used array_map on the last 5 values but not on the id.
I saw some examples that declared an array and then used array_map to pass the values into another array, so I came up with this:

PHP Code:

  
if (isset($_POST['doUpdate'])) 
  {
    
$sfid $_POST['sfid'];
    
$ct $_POST['City'];
    
$st $_POST['State'];
    
$phone $_POST['Phone'];
    
$fax $_POST['Fax'];
    
$name $_POST['AccountName'];  
    
    
$fieldsToClean = array('Id'=>'',
                            
'Name'=>$name,
                            
'BillingCity'=>$ct,
                            
'BillingState'=>$st,
                            
'Phone'=>$phone,
                            
'Fax'=>$fax);  // create array to clean from posted variables
                            
    
$fieldsToUpdate array_map('htmlspecialchars'$fieldsToClean);   // map the first array using htmlspecialchars, with empty id                    
    
$fieldsToUpdate['Id'] = $sfid;  // add the id field
        
    
$sObject = new SObject();  // declare new sObject
    
$sObject->fields $fieldsToUpdate;  // set fields of new sObject
    
$sObject->type 'Account';  // set type to account
    
$acct $mySforceConnection->update(array ($sObject));  // update sObject

    
header('Location: welcome.php');   // redirect to welcome.php
  

Declaring the id field before the array_map function was the only way I could get this to work. I tried using array_map on the main 5 first and then adding the id field to the array afterwards, but it didn't update the records correctly. Is this due to the order of items in the array? I thought being an associative array it wouldn't matter that the Id was at the end.

Any feedback is appreciated.
Digg this Post!Add Post to del.icio.usBookmark Post in TechnoratiFurl this Post!
Reply With Quote
Reply

Tags
mysql data replication, salesforce oracle

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



All times are GMT -5. The time now is 08:30 PM.



SEO by vBSEO 3.3.0 ©2009, Crawlability, Inc.

1 2 3 4 5