<?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; Salesforce</title>
	<atom:link href="http://phpandsalesforce.com/tag/salesforce/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>Salesforce Gotchas and Undocumented &#8216;Features&#8217;</title>
		<link>http://phpandsalesforce.com/2009/06/29/salesforce-gotchas-and-undocumented-features/</link>
		<comments>http://phpandsalesforce.com/2009/06/29/salesforce-gotchas-and-undocumented-features/#comments</comments>
		<pubDate>Tue, 30 Jun 2009 05:27:35 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Getting Started]]></category>
		<category><![CDATA[Gotchas]]></category>
		<category><![CDATA[PHP Toolkit]]></category>
		<category><![CDATA[Salesforce API Development]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Salesforce]]></category>

		<guid isPermaLink="false">http://phpandsalesforce.com/?p=62</guid>
		<description><![CDATA[Today we&#8217;re going to go through some things that I hope you find interesting and informative, things that hopefully will make your development process a lot easier.  With many of the following issues, I&#8217;ve found the documentation either sparse, obscured, or non-existent.
- Objects (such as individual leads or contacts) have either a 15-character or [...]]]></description>
			<content:encoded><![CDATA[<p>Today we&#8217;re going to go through some things that I hope you find interesting and informative, things that hopefully will make your development process a lot easier.  With many of the following issues, I&#8217;ve found the documentation either sparse, obscured, or non-existent.</p>
<p>- Objects (such as individual leads or contacts) have either a 15-character or an 18-character <b>case-sensitive</b> ID (e.g. 00Q6000000OaR87).  You should not count on one format or the other being returned.  The two formats can normally be used interchangeably (you can pass either version to an API call), but one notable exception to this rule is the Excel Connector, which integrates Salesforce and Excel.  <del datetime="2009-07-19T04:21:41+00:00">The 18-character version has some extra non-essential metadata about the object that&#8217;s not present in the earlier 15-character version.</del>  CORRECTION:  This is wrong.  The lesson here is that when your motivation for writing a blog is your horrible experience with your Salesforce integrators, you shouldn&#8217;t take what they say as gospel.  <a href="http://www.x2od.com/">David Schach</a> pointed out that the 15-character version is simply case-sensitive.  There is no metadata whatsoever.  I apologize again for failing to fact-check this.</p>
<p>- Object IDs have a three-character prefix, which will be consistent for standard objects and will differ between instances for custom objects.  This is not very well documented, and in fact, a Google search for &#8220;salesforce id prefix&#8221; returns no results (except this entry, after it gets indexed).  If you don&#8217;t yet have any objects of a particular type, but need the ID, you can get it from the URL after clicking on the tab (or the &#8216;&gt;&#8217; to the right of the tabs if you don&#8217;t see the object you&#8217;re looking for).  The URL will be something like &#8216;https://cs1.salesforce.com/00Q/o&#8217;, and the prefix is between the slashes (here, &#8216;00Q,&#8217; for leads).  Prefixes for common standard objects include:</p>
<ul>
<li>00Q (Leads)</li>
<li>003 (Contacts)</li>
<li>001 (Accounts)</li>
<li>006 (Opportunities)</li>
<li>701 (Campaigns)</li>
<li>500 (Cases)</li>
</ul>
<p>- Salesforce API logins (including logins from other third-party applications, like the Outlook tool) have the concept of a security token, which can be reset by going to Setup &gt; My Personal Information &gt; Reset My Security Token.</p>
<p>- Security tokens are appended to passwords when logging in via the API, so you might login with the username &#8216;joe&#8217; and the password &#8216;mypasswordmytoken&#8217;.</p>
<p>- Security tokens change automatically when a password changes &#8211; <b>watch out for this!</b></p>
<p>- There are no default administrator profiles whose passwords do not expire.  <b>This means that your API user&#8217;s password may expire, and your entire API integration will suddenly fail.</b>  I highly recommend making a new administrator profile called something like &#8216;Admins &#8211; Passwords Do Not Expire&#8217; and adding your API and other back-end users to it.  The original profile will not (currently) let you check the &#8216;Passwords do not expire&#8217; checkbox.</p>
<p>- Avoid using the logout() call.  As discussed before, all logins for a single user <b>share a session id</b>.  Calling logout() will log out all concurrent connections for that Salesforce user via the API.  Note also that this behavior is undocumented.  Not to worry, the PHP Toolkit gracefully cleans up the SOAP connection for you.</p>
<p>- Deleted and merged data (e.g. deleted leads) can wreak havoc if your application relies on valid Salesforce IDs.  Just because a lead exists today doesn&#8217;t mean Sales isn&#8217;t going to mass-delete those 10,000 &#8216;junk&#8217; leads tomorrow.</p>
<p>- Salesforce objects are always referred to in the API in the singular form, so &#8216;Lead&#8217; rather than &#8216;Leads.&#8217;</p>
<p>- Custom fields append __c to the field name, e.g. My_Custom_Field__c.</p>
<p>- There are a couple of Salesforce expressions that I&#8217;ll use here to be consistent, including &#8216;picklist&#8217; to mean an HTML select element, &#8216;dependent picklist&#8217; to mean a picklist whose appearance or values depend on another picklist, &#8216;auto number&#8217; to mean an auto-increment field, and &#8216;upsert&#8217; to mean a call that will update if a record with the specified ID exists, or else insert a new record.</p>
<p>Lastly, a quick aside about languages and operating systems.  The code examples presented here assume a POSIX-compliant OS, such as Linux, but Windows-specific considerations should pretty much non-existent.  PHP is fairly OS-agnostic for what we&#8217;re going to be doing, but inevitably there will be an OS-specific issue that will creep in.  As far as portable paths go, PHP lets you use &#8216;/&#8217; as a path separator in scripts on all OSes, but you could certainly instead use the native (and portable) DIRECTORY_SEPARATOR constant or &#8216;\\&#8217; in the paths if you prefer.  Lastly, in this blog, &#8216;native&#8217; is taken to mean &#8216;native to PHP, written in C&#8217; &#8211; an example of this is the native SOAP client (versus the much slower NuSOAP client written in PHP).</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Salesforce+Gotchas+and+Undocumented+%27%3BFeatures%27+http://is.gd/9Lk2O" 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=Salesforce+Gotchas+and+Undocumented+%27%3BFeatures%27+http://is.gd/9Lk2O" title="Post to Twitter">Tweet This Post</a>&nbsp; </p>]]></content:encoded>
			<wfw:commentRss>http://phpandsalesforce.com/2009/06/29/salesforce-gotchas-and-undocumented-features/feed/</wfw:commentRss>
		<slash:comments>6</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>
		<item>
		<title>Welcome to PHP and Salesforce!</title>
		<link>http://phpandsalesforce.com/2009/06/16/welcome-to-php-and-salesforce/</link>
		<comments>http://phpandsalesforce.com/2009/06/16/welcome-to-php-and-salesforce/#comments</comments>
		<pubDate>Tue, 16 Jun 2009 23:57:51 +0000</pubDate>
		<dc:creator>admin</dc:creator>
				<category><![CDATA[Getting Started]]></category>
		<category><![CDATA[API]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Salesforce]]></category>
		<category><![CDATA[Sandbox]]></category>
		<category><![CDATA[Toolkit]]></category>

		<guid isPermaLink="false">http://phpandsalesforce.com/?p=3</guid>
		<description><![CDATA[PHP and Salesforce is a new blog dedicated to helping web developers take control over their CRM integration.  Most of the early entries will focus on building a reference of Salesforce PHP examples, followed by discussions on topics including performance, concurrency, CRM framework architecture (and whether you should consider building one), and strategies for [...]]]></description>
			<content:encoded><![CDATA[<p>PHP and Salesforce is a new blog dedicated to helping web developers take control over their CRM integration.  Most of the early entries will focus on building a reference of Salesforce PHP examples, followed by discussions on topics including performance, concurrency, CRM framework architecture (and whether you should consider building one), and strategies for handling scheduled and unscheduled outages.</p>
<p>Before we go any further, <b>you must have either the Enterprise Edition or the Unlimited Edition</b> to access the API with your production Salesforce.com instance.  Those of you who are using the Group Edition or the Professional Edition can test your API code against the Developer Edition, by signing up <a href="http://www.developerforce.com/events/regular/registration.php">here</a>.  However, there is currently a limit of 5,000 API calls per 24 hour period in the Developer Edition.  </p>
<h3>Downloading The Toolkit</h3>
<p>Today, we&#8217;re going to walk through getting the PHP Toolkit set up and a sandbox copied off.  Let&#8217;s start by downloading the Toolkit:</p>
<ul>
<li><a href="http://wiki.developerforce.com/index.php/PHP_Toolkit">Toolkit for PHP 5.2+</a></li>
<li><a href="http://wiki.developerforce.com/index.php/PHP_Toolkit_11.0">Toolkit for PHP 5.1.2+</a></li>
<li><a href="http://wiki.developerforce.com/index.php/PHP_Toolkit_1.1">Toolkit for PHP 5.0+</a> (free DeveloperForce login required)</li>
</ul>
<p>All versions of the Toolkit require the curl, openssl, and soap extensions, the installation status of which can be determined by issuing `php -m` at the command line.</p>
<h3>Unpacking the Toolkit</h3>
<p>To set up the toolkit, simply unpack it.  I normally unpack it to lib/crm/salesforce, but the only thing that&#8217;s really important is to keep the Toolkit in its own directory so it can easily be upgraded.</p>
<h3>Sandboxes</h3>
<p>If you have sandbox access, I highly recommend testing your code there before running it against your production instance.  One reason for this (aside from inadvertently creating or deleting thousands of records, of course) is that the number of API calls per 24-hour period is metered, and once you&#8217;re out, you&#8217;re out.  This means that if your site relies on Salesforce being available via the API to function correctly, the results could be very damaging to your business.  If you have sandbox access, you can view your entitlement under Setup &gt; Data Management &gt; Sandbox.  The current API limits can be found <a href="http://www.salesforce.com/us/developer/docs/api/Content/implementation_considerations.htm#topic-title_request_metering">here</a>.</p>
<p>If you don&#8217;t have a sandbox already, go ahead and clone one off by going to Setup &gt; Data Management &gt; Sandbox.  The three types of sandboxes are:</p>
<ul>
<li>Configuration Only &#8211; Production configuration without the data.  Holds 500 MB.</li>
<li>Developer &#8211; The same as Configuration Only, but holds only 10 MB.</li>
<li>Full &#8211; A full copy of your production instance.</li>
</ul>
<p>A Configuration or Developer sandbox will be probably be fine, and if you do need a Full sandbox, keep in mind that it can take upwards of several hours to create.  Also, <b>sandboxes can only be refreshed every 30 days</b>, and you can typically only have one full copy at a time.  Another gotcha with sandboxes is that labels cannot currently be edited after the sandbox is created or refreshed, so go ahead and label yours now.  You don&#8217;t want to have to worry about someone refreshing your critical sandbox instance because they didn&#8217;t realize it was in use.  I tend to name my sandboxes &#8217;sbox1&#8242;, &#8217;sbox2&#8242;, etc., and to log into a sandbox called &#8217;sbox1&#8242;, &#8216;user@example.com&#8217; would log into SFDC at https://test.salesforce.com with the username &#8216;user@example.com.sbox1&#8242; and the same password they use on production.</p>
<p>Yet another thing to bear in mind when cloning off a sandbox is that the process will copy over your existing workflow rules from production, <b>and leave them active</b>.  This can cause a variety of issues, particularly if you have rules that trigger emails to mailing lists.  Depending on your IT infrastructure, mail loops can inadvertently be created because of this.  So, now would be a good time to disable any unnecessary workflow rules (under Setup &gt; Create &gt; Workflow &#038; Approvals &gt; Workflow Rules).</p>
<h3>Finally, Some Code</h3>
<p>We&#8217;ll go over this code in detail in the next entry, but I wanted to give you at least an idea of how straightforward it can be to develop against the API and integrate Salesforce and PHP.  The following snippet will declare some configuration constants, log in, create a lead, and log out.</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>
$crmHandle = new SforceEnterpriseClient();
$crmHandle->createConnection(SALESFORCE_WSDL);
$crmHandle->login(SALESFORCE_USER, SALESFORCE_PASS . SALESFORCE_TOKEN);

// create our lead
$lead = array();
$lead['FirstName'] = 'Joe';
$lead['LastName'] = 'Moke';
$lead['Email'] = 'jmoke@example.com';
$lead['Title'] = 'CEO';
$lead['Company'] = 'Acme Widget Corporation';
$result = $crmHandle->create(array($lead), 'Lead');

$crmHandle->logout();
</pre>
<h3>Final Thoughts</h3>
<p>I hope you enjoyed my first entry, and I hope it was helpful.  I&#8217;ll generally be posting one or two entries a week, and next time, we&#8217;ll walk through getting your PHP environment configured to make the above snippet go, and start looking at some SFDC development considerations, gotchas, and quirks.  See you again shortly!</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Welcome+to+PHP+and+Salesforce%21+http://is.gd/9LKEL" 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=Welcome+to+PHP+and+Salesforce%21+http://is.gd/9LKEL" title="Post to Twitter">Tweet This Post</a>&nbsp; </p>]]></content:encoded>
			<wfw:commentRss>http://phpandsalesforce.com/2009/06/16/welcome-to-php-and-salesforce/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
	</channel>
</rss>
