<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHP and Salesforce &#187; Lead Generation</title>
	<atom:link href="http://phpandsalesforce.com/category/lead-generation/feed/" rel="self" type="application/rss+xml" />
	<link>http://phpandsalesforce.com</link>
	<description>A CRM Reference For PHP Developers</description>
	<lastBuildDate>Wed, 26 May 2010 22:19:50 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Creating a Lead via the Salesforce.com API</title>
		<link>http://phpandsalesforce.com/2009/06/23/creating-a-lead-via-the-salesforce-com-api/</link>
		<comments>http://phpandsalesforce.com/2009/06/23/creating-a-lead-via-the-salesforce-com-api/#comments</comments>
		<pubDate>Tue, 23 Jun 2009 16:20:00 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Getting Started]]></category>
		<category><![CDATA[Lead Generation]]></category>
		<category><![CDATA[PHP Toolkit]]></category>
		<category><![CDATA[Salesforce API Development]]></category>

		<guid isPermaLink="false">http://phpandsalesforce.com/?p=9</guid>
		<description><![CDATA[In our next installment, we&#8217;re going to take a closer look the lead generation code from the end the first post, as well as finish getting your SFDC development environment set up.  
Choosing the Right WSDL For You and Your Organization
Salesforce uses SOAP as its Web Services protocol, and SOAP uses an XML file [...]]]></description>
			<content:encoded><![CDATA[<p>In our next installment, we&#8217;re going to take a closer look the lead generation code from the end the first post, as well as finish getting your SFDC development environment set up.  </p>
<h3>Choosing the Right WSDL For You and Your Organization</h3>
<p>Salesforce uses SOAP as its Web Services protocol, and SOAP uses an XML file called a WSDL (Web Services Definition Language) file that defines how a client (our code) can interact with a server (Salesforce).  For our purposes, there are two different types of WSDL files, Enterprise and Partner.  Here are the specifics:</p>
<p>Enterprise WSDL</p>
<ul>
<li>Is strongly typed</li>
<li>Contains the metadata about all standard and custom fields and objects</li>
<li>Can only be used against your Salesforce instance</li>
</ul>
<p>Partner WSDL</p>
<ul>
<li>Is loosely typed</li>
<li>Takes an array of key-value pairs</li>
<li>Does not contain metadata about objects and fields</li>
<li>Can be used against many Salesforce.com organizations</li>
</ul>
<p>In our organization, we use the Enterprise WSDL, and the main reason why is that we like having a reference of all custom fields and objects readily available in the XML.  Having the type of every field right there next to the field name at hand is nice as well.  This being said, if we had a need to interact with many Salesforce.com instances, we might choose to use the Partner WSDL instead.</p>
<p>For the purposes of this blog, we&#8217;re generally going to be writing against the Enterprise WSDL, but our first example will be presented at the end in an &#8216;Enterprise&#8217; version and a &#8216;Partner&#8217; version.  Those of you who find you prefer the Partner WSDL should be able to take the Partner example and adapt it in the future very easily.  </p>
<h3>Generating the WSDL</h3>
<p>Each instance of Salesforce (each sandbox and production instance) will have their own corresponding WSDL file.  It can be generated by going to Setup &gt; Develop &gt; API &gt; Generate Enterprise WSDL (or Generate Partner WSDL) and downloading the generated XML.  I prefer to keep the default name and put each file in a dev/, staging/, and production/ folder, but you could just as easily call the files dev.enterprise.wsdl.xml, or something to that effect.</p>
<h3>Taking a Look at the Lead Generation Code</h3>
<p>Now that we&#8217;re set up with our WSDL, let&#8217;s take a look at the code at the bottom of the previous post.  I have removed the logout() call, after I read (and subsequently validated) <a href="http://eng.genius.com/blog/2009/05/06/salesforcecom-api-gotchas-1/">this absolutely terrific article</a> that pointed out that a user&#8217;s API connections <b>all get the same session ID</b>!  This means that logout() actually invalidates all of the concurrent connections for that user.  This is somewhat of an edge case for us, as page load times are generally very short, but all the same, we won&#8217;t be using the logout() call going forward.  If you&#8217;re wondering, logging out through the Salesforce API does not log the same user out of any API connections.  At any rate, here is the code, slightly modified, and this time with some comments:</p>
<p>Configuration passages:</p>
<pre>
define('SALESFORCE_USER', 'integration@example.com.sbox1');
define('SALESFORCE_PASS', '*password here*');
define('SALESFORCE_TOKEN', '*security token here*');
define('SALESFORCE_WSDL', '/path/to/enterprise.wsdl.xml');
</pre>
<p>Code:</p>
<pre>
require_once('SforceEnterpriseClient.php');

/**
 * explicitly turn off WSDL caching
 * there is a bug in PHP with this setting in php.ini
 * http://bugs.php.net/bug.php?id=41665
 * so it's safest to set it in the PHP source
 *
 * This param should take an int, not a string like most examples use
 * see http://us3.php.net/manual/en/soap.configuration.php
*/
ini_set('soap.wsdl_cache_enabled', 0);

// instantiate a new Salesforce Enterprise object
$crmHandle = new SforceEnterpriseClient();

// instantiate a SOAP connection to Salesforce
try {
  $crmHandle->createConnection(SALESFORCE_WSDL);
} catch (Exception $e) {
  // handle exception - did you set the WSDL path above?
  // we may also be in a Salesforce outage right now
}

// log in to Salesforce
try {
  $crmHandle->login(SALESFORCE_USER, SALESFORCE_PASS . SALESFORCE_TOKEN);
} catch (Exception $e) {
  // handle exception - did you modify the credentials above to your own?
}

// create our lead
$lead = array();
$lead['FirstName'] = 'Joe';
$lead['LastName'] = 'Moke';
$lead['Email'] = 'jmoke@example.com';
$lead['Title'] = 'CEO';

// create the lead
// $lead must be wrapped in an array, as create() can create
// many objects with a single API call
$result = $crmHandle->create(array($lead), 'Lead');
</pre>
<h3>But Wait, Where&#8217;s Our Lead?</h3>
<p>In this case, there was no exception thrown, but a var_dump() of the $result object will reveal what went wrong:</p>
<pre>
  ["errors"]=>
  object(stdClass)#8 (3) {
    ["fields"]=>
    string(7) "Company"
    ["message"]=>
    string(38) "Required fields are missing: [Company]"
    ["statusCode"]=>
    string(22) "REQUIRED_FIELD_MISSING"
  }
  ["id"]=>
  NULL
  ["success"]=>
  bool(false)
</pre>
<p>Salesforce will usually throw an exception when things go haywire, but not always, as in our example.  When there is an error, and no exception is thrown, $result->success will equal false, so always be prepared for both possibilities, and you can re-throw or create an exception as it applies to your situation.  </p>
<p>The REQUIRED_FIELD_MISSING error is actually fairly unusual to see in the API.  In nearly all cases, creating and updating via the API will exempt you from populating required fields, except where it would render the resulting object useless (omitting LastName from a lead, for instance).  So, let&#8217;s set the company, and take another look at var_dump($result):</p>
<pre>
$lead['Company'] = 'Bob\'s Country Bunker';

object(stdClass)#7 (2) {
  ["id"]=>
  string(18) "00QS00000034zU4MAI"
  ["success"]=>
  bool(true)
}
</pre>
<h3>Creating a Lead with the Partner WSDL</h3>
<p>As promised, the complete version that is compatible with the Partner WSDL is as follows:</p>
<pre>
define('SALESFORCE_USER', 'integration@example.com.sbox1');
define('SALESFORCE_PASS', '*password here*');
define('SALESFORCE_TOKEN', '*security token here*');
define('SALESFORCE_WSDL', '/path/to/partner.wsdl.xml');

require_once('SforcePartnerClient.php');

/**
 * explicitly turn off WSDL caching
 * there is a bug in PHP with this setting in php.ini
 * http://bugs.php.net/bug.php?id=41665
 * so it's safest to set it in the PHP source
 *
 * This param should take an int, not a string like most examples use
 * see http://us3.php.net/manual/en/soap.configuration.php
*/
ini_set('soap.wsdl_cache_enabled', 0);

// instantiate a new Salesforce Partner object
$crmHandle = new SforcePartnerClient();

// instantiate a SOAP connection to Salesforce
try {
  $crmHandle->createConnection(SALESFORCE_WSDL);
} catch (Exception $e) {
  // handle exception - did you set the WSDL path above?
  // we may also be in a Salesforce outage right now
}

// log in to Salesforce
try {
  $crmHandle->login(SALESFORCE_USER, SALESFORCE_PASS . SALESFORCE_TOKEN);
} catch (Exception $e) {
  // handle exception - did you modify the credentials above to your own?
}

// create our lead
$lead = new sObject();
$lead->type = 'Lead';
$lead->fields = array('FirstName' => 'Joe',
                      'LastName' => 'Moke',
                      'Email' => 'jmoke@example.com',
                      'Title' => 'CEO',
                      'Company' => 'Bob\'s Country Bunker');

// create the lead
// $lead must be wrapped in an array, as create() can create
// many objects with a single API call
$result = $crmHandle->create(array($lead), 'Lead');
</pre>
<h3>WSDL Type Mismatches</h3>
<p>Specifying the wrong WSDL such as pointing Salesforce to the Enterprise WSDL when you&#8217;re instantiating the SalesforcePartnerClient or vice-versa can give some obscure exception messages, such as this one:</p>
<pre>
Fatal error: Uncaught SoapFault exception: [soapenv:Client] Element {}item invalid
    at this location in /var/www...
</pre>
<p>Hopefully, if you see this message, this post will jog your memory.</p>
<h3>API Coding Style</h3>
<p>I always use the variable $crmHandle as the handle to my CRM object, and names like $lead or $contact as references to individual objects.  From now on, we will leave the error/exception handling to you, as the different approaches vary widely.  As Salesforce does routinely undergo maintenance, and does on occasion throw exceptions itself (Java socket exceptions, etc&#8230;) I would strongly recommend that you try/catch essential calls (e.g. createConnection()), and that you handle these exceptions in a way that doesn&#8217;t bring down your site if they occur.  Registering a global exception handler with set_exception_handler() and re-throwing exceptions as CrmException($e->getMessage) or CrmCreateException&#8230; is certainly a good start.</p>
<h3>User Input Considerations</h3>
<p>There are a couple of simple things you can check user-supplied data for to avoid throwing exceptions left, right, and center.  </p>
<ul>
<li>Validate email addresses.  An extremely thorough, yet untested (by me) script can be found <a href="http://snipplr.com/view/11616/rfccompliant-email-address-validator/">here</a>.  Salesforce will throw an exception if the email address is not RFC-compliant.</li>
<li>Enforce field length limits.  Have a look at Setup &gt; Customize &gt; {Object Name} &gt; Fields for lengths.  Data exceeding field lengths will throw an exception.  Salesforce will trim whitespace for you, so factor that into your length calculations.</li>
</ul>
<h3>Documentation and References</h3>
<p>Apart from the lack of PHP code examples, you&#8217;ll find that the <a href="http://www.salesforce.com/us/developer/docs/api/index.htm">API Developer&#8217;s Guide</a> is an invaluable resource throughout your Salesforce PHP development.</p>
<p>A handy (and extensive) reference regarding the differences in capabilities and thresholds between the different Salesforce editions can be found <a href="http://www.salesforce.com/assets/pdf/datasheets/DS_RightSFDC.pdf">here</a>.  This PDF is quite useful to keep at hand in order to understand exactly the limitations of your particular instance.</p>
<h3>Wrapping Up</h3>
<p>I realize this was lengthy, but to paraphrase Albert Einstein, I tried to make things as simple as possible, but not simpler.  Coming up, we&#8217;ll take a look at some examples involving converting leads with the API, and creating and updating Contact and Account objects in Salesforce.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Creating+a+Lead+via+the+Salesforce.com+API+http://is.gd/5EHEK" title="Post to Twitter"><img class="nothumb" src="http://phpandsalesforce.com/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="[Post to Twitter]" border="0" /></a> <a class="tt" href="http://twitter.com/home/?status=Creating+a+Lead+via+the+Salesforce.com+API+http://is.gd/5EHEK" title="Post to Twitter">Tweet This Post</a>&nbsp; </p>]]></content:encoded>
			<wfw:commentRss>http://phpandsalesforce.com/2009/06/23/creating-a-lead-via-the-salesforce-com-api/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Lead Generation via the Salesforce.com API vs. Web-to-Lead</title>
		<link>http://phpandsalesforce.com/2009/06/21/lead-generation-via-the-salesforce-com-api-vs-web-to-lead/</link>
		<comments>http://phpandsalesforce.com/2009/06/21/lead-generation-via-the-salesforce-com-api-vs-web-to-lead/#comments</comments>
		<pubDate>Sun, 21 Jun 2009 16:57:52 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Lead Generation]]></category>
		<category><![CDATA[Salesforce API Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Toolkit]]></category>

		<guid isPermaLink="false">http://phpandsalesforce.com/?p=104</guid>
		<description><![CDATA[What we mean by the term &#8220;lead generation via the API&#8221; is not the same concept as the term &#8216;Web-to-Lead&#8217; that you may have heard.  Creating leads via the API allows you to attach Salesforce functionality to your existing lead-generating forms, whereas Web-to-Lead is a tool provided by Salesforce that allows you auto-generate registration [...]]]></description>
			<content:encoded><![CDATA[<p>What we mean by the term &#8220;lead generation via the API&#8221; is not the same concept as the term &#8216;Web-to-Lead&#8217; that you may have heard.  Creating leads via the API allows you to attach Salesforce functionality to your existing lead-generating forms, whereas Web-to-Lead is a tool provided by Salesforce that allows you auto-generate registration forms that send a POST request to Salesforce.  It should be noted that this discussion is based on using Salesforce&#8217;s auto-generated forms, but the lead creation can actually be done on the server side as well, as demonstrated <a href="http://sim.plified.com/2009/02/13/pushing-leads-to-salesforce-with-php/">here</a>, with a great example in PHP.  A few advantages that the API method holds over the client-side Web-to-Lead implementation include:</p>
<ul>
<li>Privacy.  No need to send your users&#8217; passwords to Salesforce.</li>
<li>Stability.  No need to change your existing field names to match Salesforce.</li>
<li>Security.  The Web-to-Lead tool can be used to create spam leads.  See <a href="http://ideas.salesforce.com/article/show/29238/Web_2_Lead___webform_spam">here</a>.</li>
<li>Flexibility.  Easily avoid creating duplicate leads by de-duping on email address.</li>
</ul>
<p>There are two main advantages that the Web-to-Lead method holds, both in terms of simplicity:</p>
<ul>
<li>All of the form creation and handling is done for you.</li>
<li>In case of an outage, queuing of the new leads is handled for you.</li>
</ul>
<p>That Web-to-Lead queues your new leads during outages is not an inconsiderable point, and &#8216;queuing strategies and the API&#8217; is a topic we&#8217;re going to discuss in the very near future.  If you&#8217;re interested, you can learn more about Web-to-Lead <a href="http://blogs.salesforce.com/marketing/2007/03/capturing_leads.html">here</a>.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Lead+Generation+via+the+Salesforce.com+API+vs.+Web-to-Lead+http://is.gd/dFfAz" title="Post to Twitter"><img class="nothumb" src="http://phpandsalesforce.com/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="[Post to Twitter]" border="0" /></a> <a class="tt" href="http://twitter.com/home/?status=Lead+Generation+via+the+Salesforce.com+API+vs.+Web-to-Lead+http://is.gd/dFfAz" title="Post to Twitter">Tweet This Post</a>&nbsp; </p>]]></content:encoded>
			<wfw:commentRss>http://phpandsalesforce.com/2009/06/21/lead-generation-via-the-salesforce-com-api-vs-web-to-lead/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
		</item>
	</channel>
</rss>
