+ Reply to Thread
Page 1 of 2
1 2 LastLast
Results 1 to 10 of 18

Thread: PHP -> Salesforce "upsert", can't get tutorial example working

  1. #1

    Unhappy PHP -> Salesforce "upsert", can't get tutorial example working

    I saw your tutorial example on how to implement a PHP -> Salesforce "upsert".

    I am pulling my hair out because it isn't working, and I can't see to find any proper documentation online.

    I am guessing that your tutorial is out of date, compared to the current Salesforce API.
    Can you help point me in the right direction?


    I am looking at this example:

    Salesforce PHP Upsert Tutorial - developer.force.com
    and
    Salesforce Code Example #1

    I am stuck in 2 places:

    1. There is no definition of "sObject" anywhere in the code (even the included code).
    Therefore, the line containing "new sObject();" fails with a fatal error:

    foreach ($all_fields as $fieldset)
    {
    $sObject = new sObject();
    $sObject->type = 'Account'; // Salesforce Table or object that you will perform the upsert on
    $sObject->fields = $fieldset;
    array_push($sObjects, $sObject);
    }

    I have fiddled around with changing it to "new stdClass();", but I can't get it to work properly.


    2. At least there is no PHP fatal error when I substitute stdClass for sObject,
    but then at run-time, I get an error from Salesforce:

    INVALID_FIELD: No such column 'fields' on entity 'Calls__c'. If you are attempting to use a custom field, be sure to append the '__c' after the custom field name. Please reference your WSDL or the describe call for the appropriate names.

    I have included the source code below. I simply want to "upsert" 2 records of my custom object.
    If I could just get this example working, I could do anything.

    The problem seems to be that Salesforce thinks that "fields" is the name of a column in my custom "Calls__c" object,
    where it is intended to be an array containing field names and values.

    This makes me think I am calling the API wrong, ... but I followed your example, ... so I am really stuck.
    I can't figure out the proper way to present the parameters and record data through the API.

    Any insight you could provide would be much appreciated.
    There doesn't seem to be much good documentation on the PHP version of the API.

    - - - - -

    PHP Code:
    <? // sf/test-login.php
    ?>
    <html>
    <head>
    </head>
    <body>

    <?
    ini_set
    ("soap.wsdl_cache_enabled""0");

    require_once(
    'sf-phptoolkit-13-1/soapclient/SforceEnterpriseClient.php');
    require_once(
    'sf-phptoolkit-13-1/soapclient/SforceHeaderOptions.php');

    $cr "\n";

    $sf_option = array(
        
    'username' => 'use@host.com',
        
    'password' => 'pass',
        
    'security-token' => '-some-stuff-',
    );


    $sf = new SforceEnterpriseClient();
    $soap_client $sf->createConnection('enterprise.wsdl.xml');
    try {
        
    $sf_login $sf->login($sf_option['username'], $sf_option['password'] . $sf_option['security-token']);
    } catch (
    Exception $e) {
        
    $sf_login null;
        echo 
    'Salesforce Login Error' $cr;
        echo 
    $e->faultstring;
    }

    echo 
    '<pre>';
    print_r($sf_login);
    echo 
    '</pre>';


    $data = array();
    $row['NAME'] = 'beta-one';
    $row['CALLED__C'] = '9051234567';
    $row['CALLER__C'] = '4165551212';
    $data[] = $row;
    $row['NAME'] = 'beta-two';
    $row['CALLED__C'] = '9051235555';
    $row['CALLER__C'] = '4164443333';
    $data[] = $row;

    $sObject_list = array();
    foreach (
    $data as $row) {
        
    $sObject = new stdClass();
        
    $sObject->type 'Calls__c';
        
    $sObject->fields $row;
        
    $sObject_list[] = $sObject;
    }
    try {
        
    $result $sf->upsert('Name'$sObject_list);
    } catch (
    Exception $e) {
        
    $result null;
        echo 
    'Salesforce Upsert Error' $cr;
        echo 
    '<pre>';
        
    print_r($e);
        echo 
    '</pre>';
    }


    echo 
    '<pre>';
    print_r($result);
    echo 
    '</pre>';

    ?>
    </body>
    </html>

  2. #2
    Join Date
    May 2007
    Posts
    506
    Blog Entries
    3
    let me see if I can get this working

    Can you tell me what version of the toolkit you are using?

  3. #3
    Join Date
    May 2007
    Posts
    506
    Blog Entries
    3
    One thing that I noticed right from the start is that you are using the EnterPriseClient.php and this was developed using the partner client, I will get back to you

    ~Mike

  4. #4
    Join Date
    May 2007
    Posts
    506
    Blog Entries
    3
    Another thing that I just noticed is that your trying to upsert on a field in Salesforce called Name on a custom object called Calls__c. Do you have this field set to an external ID?

  5. #5
    Join Date
    May 2007
    Posts
    506
    Blog Entries
    3

    Thumbs up

    Again there was some discrepancies with your script and it is so much easier and better to use the partner WSDL file.

    I did get it to work on my developers org > http://www.mikesimonds.com/salesforce/upsert.php


    Here is your modified code using the partner client:


    PHP Code:

    <?php

    ini_set
    ("soap.wsdl_cache_enabled""0");

    require_once (
    '/home/mike/public_html/salesforce/soapclient/SforcePartnerClient.php');


    $cr "\n";

    $sf_option = array('username' => 'sportsrant2002@yahoo.com'
                       
    'password' => 'mas=1212',
                       
    'security-token' => 'UjhgAORkjgLp0dCztejrKu2X', );


    $sf = new SforcePartnerClient();
    $soap_client $sf->createConnection('/home/mike/public_html/salesforce/soapclient/partner.wsdl.xml');
    try
    {
        
    $sf_login $sf->login($sf_option['username'], $sf_option['password'] . $sf_option['security-token']);
    }
    catch (
    exception $e)
    {
        
    $sf_login null;
        echo 
    'Salesforce Login Error' $cr;
        echo 
    $e->faultstring;
    }

    $data = array();

    $row = array ( 'Name' => 'beta_one',
                   
    'Called__c' => '9051234567',
                   
    'Caller__c' => '9995551212'
                 
    );
    array_push($data$row);             
    $row = array ( 'Name' => 'beta_two',
                   
    'Called__c' => '9051235555',
                   
    'Caller__c' => '4164443333'
                 
    );               


    array_push($data$row);



    $sObjects = array();

    foreach (
    $data as $row)
    {
        
    $sObject = new sObject();
        
    $sObject->type 'Calls__c';
        
    $sObject->fields $row;
        
    array_push($sObjects$sObject);
    }


    echo 
    '<pre>' print_r($sObjectstrue) . '</pre>';

    //exit;

    try
    {
        
    $result $sf->upsert('Name'$sObjects);
    }
    catch (
    exception $e)
    {
        
    $result null;
        echo 
    'Salesforce Upsert Error' $cr;
        echo 
    '<pre>' print_r($etrue) . '</pre>';
    }


    echo 
    '<pre>' print_r($resulttrue) . '</pre>';

    ?>


    You can login to my salesforce org using the credentials that are located in the code above

    let me know if you can get this working, you should be able too

    Hope that helps!!

    ~Mike

  6. #6
    To answer your questions:

    1. I am using version 13.1 of the Salesforce PHP Toolkit. This is the latest.
    There is a known bug in the SforceEnterpriseClient.php near Line 90
    that hard-codes the type of the sObjects being "upserted" as "Contact".

    Here is the one-line correction. I don't know who in Salesforce tech-support to contact
    to notify them of this serious bug.

    PHP Code:
    public function upsert($ext_Id$sObjects) {
        
    $arg = new stdClass;
        
    $arg->externalIDFieldName = new SoapVar($ext_IdXSD_STRING'string''http://www.w3.org/2001/XMLSchema');
        foreach (
    $sObjects as &$sObject) {
    //      $sObject = new SoapVar($sObject, SOAP_ENC_OBJECT, 'Contact', $this->namespace);
            
    $sObject = new SoapVar($sObjectSOAP_ENC_OBJECT$sObject->type$this->namespace);
        }
        
    $arg->sObjects $sObjects;
        return 
    parent::_upsert($arg);
      } 
    2. I am using EnterpriseClient because I want to access my own Custom Object.
    I thought the PartnerClient was for accessing generic Objects already built-in to Salesforce.
    I must be missing something. Can anyone clarify when you would ever use EnterpriseClient
    if PartnerClient is also able to access your Custom Objects?

    3. I am trying to "upsert" data into my Custom Objects called "Calls__c", which is intended
    to store Call Records. I am free to change the fields. I don't fully understand the Salesforce
    conventions, so I am not sure about how to use the "external ID" properly, and how it gets
    accessed externally (through PHP) and internally (inside Salesforce). Any guidance or pointers
    to documentation would be appreciated.

    What I would *like* to do is have a special field in my Custom Object that is a unique id
    that I generate externally and use to identify Call Records, so I can do an "upsert"
    and whenever the unique id matches, it will overwrite the record, instead of inserting a new one.

    I will take a look at the example code you have posted, and I'll let you know if I get it working on my end.

    thanks,
    David Jones

  7. #7

    Unhappy

    Mike,

    Your example includes a reference to "new sObject()". Can you tell me where the class for "sObject" gets defined? I can't find it. It comes up undefined, ... at least when I try to use the EnterpriseClient.

    PHP Code:
    $sObject = new sObject(); 
    I have seen other people posting questions on the web about this, so I know I am not alone.

    Perhaps some more clarification on when to use PartnerClient vs. EnterpriseClient would help.

    </span></span>-- David

  8. #8
    Join Date
    May 2007
    Posts
    506
    Blog Entries
    3
    Okay so here are the differences between the Partner Client and Enterprise Client.


    Partner Client
    The partner client is flexible
    can be used on any org > great for developers.
    Can access custom objects and fields

    Enterprise Client
    for your specific Org
    No flexibility

    if you took my code and tried to change it to the enterprise client, it wont work because if you use the partner client, you have to create a new Object otherwise it will fail

    I would go with the partner client man it is just easier to work with


    If you feel that there is a bug in the toolkit, you need to contact Dave Carroll at Salesforce, he is the one that is in charge of the Toolkit these days.


    Go with the partner client, you wont be sorry!!

    ~Mike

  9. #9
    Join Date
    May 2007
    Posts
    506
    Blog Entries
    3
    Quote Originally Posted by dxjones View Post
    2. I am using EnterpriseClient because I want to access my own Custom Object.
    I thought the PartnerClient was for accessing generic Objects already built-in to Salesforce.
    I must be missing something. Can anyone clarify when you would ever use EnterpriseClient
    if PartnerClient is also able to access your Custom Objects?


    I think I already answered this, but I will try again. The partner client is flexible and the easiest to user out of the two. You can access all custom objects and fields with it


    Quote Originally Posted by dxjones View Post
    3. I am trying to "upsert" data into my Custom Objects called "Calls__c", which is intended
    to store Call Records. I am free to change the fields. I don't fully understand the Salesforce
    conventions, so I am not sure about how to use the "external ID" properly, and how it gets
    accessed externally (through PHP) and internally (inside Salesforce). Any guidance or pointers
    to documentation would be appreciated.

    the external Id in Salesforce is a field that is user created and marked in Salesforce when you create a field. What it does use the field to see if the record that is being upserted is in Salesforce, if it is not, it will create it, if it is, it will update it. So we have the same sort of ID that you are wanting to use. In our accounts table we have an internal ID called the Sales_ID__c and we use that to upsert accounts. When we run our account upsert script, if the Sales ID is in Salesforce, then the record is updated. If the Sales ID is not in Salesforce, it is then inserted. So when you do a print_r on $results using the upsert, you will see a response like this for updated accounts or records:

    Code:
    Array
    (
        [0] => stdClass Object
            (
                [created] => 
                [id] => a03A00000016bNcIAI
                [success] => 1
            )
    
        [1] => stdClass Object
            (
                [created] => 
                [id] => a03A00000016bNdIAI
                [success] => 1
            )
    
    )
    if the account is created you will see
    Code:
    Array
    (
        [0] => stdClass Object
            (
                [created] => 1
                [id] => a03A00000016bNcIAI
                [success] => 1
            )
    
        [1] => stdClass Object
            (
                [created] => 1
                [id] => a03A00000016bNdIAI
                [success] => 1
            )
    
    )
    Quote Originally Posted by dxjones View Post
    What I would *like* to do is have a special field in my Custom Object that is a unique id
    that I generate externally and use to identify Call Records, so I can do an "upsert"
    and whenever the unique id matches, it will overwrite the record, instead of inserting a new one.
    read above, I think that explains it and you can do this for sure


    Hope this helps!!

    ~Mike

  10. #10
    I remain puzzled about the distinction between EnterpriseClient and PartnerClient.

    When I look inside enterprise.wsdl.xml, I see it contains a definition of my Custom Object "Calls__c".
    When I look inside partner.wsdl.xml, there is no reference to "Calls__c" at all.

    What is the purpose of having the WSDL if the PartnerClient can do all operations
    on any Custom Object without ever knowing any details about it?

    -- David Jones

+ Reply to Thread
Page 1 of 2
1 2 LastLast

Similar Threads

  1. Create Your own UPSERT script to Salesforce using PHP
    By mike in forum Salesforce PHP Tutorials
    Replies: 0
    Last Post: 11-30-2007, 08:15 AM

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts

SEO by vBSEO 3.5.0 RC1 PL1