{"id":44,"date":"2016-05-06T08:56:48","date_gmt":"2016-05-06T08:56:48","guid":{"rendered":"http:\/\/symbioticindia.in\/docu\/?p=44"},"modified":"2016-05-06T08:56:48","modified_gmt":"2016-05-06T08:56:48","slug":"sugar-crm-integration-with-custom-php-applications-i","status":"publish","type":"post","link":"http:\/\/symbioticindia.in\/docu\/2016\/05\/06\/sugar-crm-integration-with-custom-php-applications-i\/","title":{"rendered":"Sugar CRM integration with custom PHP applications (I)"},"content":{"rendered":"<table class=\"contentpaneopen\">\n<tbody>\n<tr>\n<td colspan=\"2\" valign=\"top\"><span style=\"font-size: small;\">documentation about exposed SOAP functions.<br \/>\nThis time the SOAP methods we&#8217;re interested in are:<\/span><\/p>\n<ol>\n<li><em>login<\/em>, to log in into sugar crm<\/li>\n<li><em>get_entry_list<\/em> to query sugar crm and get lists of Contacts,Accounts etc.<\/li>\n<\/ol>\n<p>To access SOAP functionalities from PHP we&#8217;ll use the <a href=\"http:\/\/sourceforge.net\/projects\/nusoap\/\">nusoap<\/a> library, which does not require any special PHP extension.<br \/>\nWe&#8217;re now going to build a PHP class encapsulating the functionalities we need. In the articles to come we&#8217;ll expand this same class with new methods.<\/p>\n<p><strong>The code<\/strong><br \/>\nMost sugar crm SOAP methods require a session id as one of the parameters to make sure we&#8217;re authenticated users. We can get a session id by first calling the <em>login<\/em> method.<br \/>\nBut first of all let&#8217;s create a basic class with a constructor:<\/p>\n<p>&lt;?php<br \/>\nrequire_once(&#8220;nusoap.php&#8221;);<br \/>\nclass SugarSoap{<br \/>\nvar $proxy;<br \/>\nvar $sess;<br \/>\nfunction SugarSoap($soap_url,$login=true){<br \/>\n$soapclient = new soapclient($soap_url,true);<br \/>\n$this-&gt;proxy = $soapclient-&gt;getProxy();<br \/>\nif($login) $this-&gt;login();<br \/>\n}<br \/>\n}<br \/>\n?&gt;<br \/>\nThe instance variable $sess is the session id we need for most method calls, $proxy is an instance of the soap proxy created by nusoap that allows us to call the required methods.<br \/>\nIn the constructor, $soap_url is <em>http:\/\/mysugar\/soap.php?wsdl<\/em>, changing <em>mysugar<\/em> with the real url of our sugar installation, and $login defaults to true, meaning we want to automatically log in.<br \/>\nWe simply instantiate a soapclient( the &#8216;true&#8217; as second parameter means we are using a wsdl), get a proxy from it and log in if required.<br \/>\nNow the login method (to be added inside the class). Here it is:<\/p>\n<p>&nbsp;<\/p>\n<p>function login(){<br \/>\n$params = array(<br \/>\n&#8216;user_name&#8217; =&gt; &#8216;myuser&#8217;,<br \/>\n&#8216;password&#8217;\u00a0 =&gt; md5(&#8216;mypassword&#8217;),<br \/>\n&#8216;version&#8217;\u00a0\u00a0 =&gt; &#8216;.01&#8242;<br \/>\n);<br \/>\n$result = $this-&gt;proxy-&gt;login($params,&#8217;MyApp&#8217;);<br \/>\n$this-&gt;sess= $result[&#8216;error&#8217;][&#8216;number&#8217;]==0 ? $result[&#8216;id&#8217;] : null;<br \/>\nreturn $this-&gt;sess;<br \/>\n}<br \/>\n<span style=\"font-size: small;\">Quite easy! We use the soap client proxy to call the login method, passing an array containing the parameters it requires. To be more precise:<\/span><\/p>\n<ol>\n<li><em>user_name<\/em> is a valid sugar user<\/li>\n<li><em>password<\/em> is her\/his password(note you need to pass it md5 encoded)<\/li>\n<li><em>version<\/em> , a version number, not sure it gets checked some way<\/li>\n<\/ol>\n<p><span style=\"font-size: small;\">The second parameter of the login method is a free string (application name, in the documentation).<br \/>\nNow we have the result of the call in $result, and it&#8217;s an array structure. We&#8217;ll always have a $result[&#8216;error&#8217;] array, and $result[&#8216;error&#8217;][&#8216;number&#8217;]==0 means no error. If everything has gone fine, we&#8217;ll get a valid session id in $result[&#8216;id&#8217;], and we save it for future methods calls.<\/p>\n<p><\/span><\/p>\n<h4><strong>Querying Sugar CRM<\/strong><\/h4>\n<p><span style=\"font-size: small;\">At this point we have our session id , meaning we&#8217;ve been authenticated by sugar crm, and can therefore do some querying. Let&#8217;s focus on the <em>get_entry_list<\/em> method. The parameters it needs are:<br \/>\n<\/span><\/p>\n<ol>\n<li><em>session_id<\/em>, what we get after using login()<\/li>\n<li><em>module_name<\/em>, that is Contacts,Accounts,Notes,Cases etc<\/li>\n<li><em>query<\/em>, a sql like query<\/li>\n<li><em>order_by<\/em>, a sql like order by clause<\/li>\n<li><em>offset<\/em>, to obtain something like a pagination<\/li>\n<li><em>select_fields<\/em>, array of fields to be retrieved<\/li>\n<li><em>max_result<\/em>, max number of entries to retrieve<\/li>\n<li><em>deleted<\/em>, whether to show deleted entries or not deleted ones (thanks to Mark Clark for spotting an error here)<\/li>\n<\/ol>\n<p>So, here is our getContacts method(to be added to SugarSoap class):<\/p>\n<p>function getContacts($query=&#8221;,$maxnum=0,$orderby=&#8217; contacts.last_name asc&#8217;){<br \/>\n$result = $this-&gt;proxy-&gt;get_entry_list(<br \/>\n$this-&gt;sess,<br \/>\n&#8216;Contacts&#8217;,<br \/>\n$query,<br \/>\n$orderby,<br \/>\n0,<br \/>\narray(<br \/>\n&#8216;id&#8217;,<br \/>\n&#8216;first_name&#8217;,<br \/>\n&#8216;last_name&#8217;,<br \/>\n&#8216;account_name&#8217;,<br \/>\n&#8216;account_id&#8217;,<br \/>\n&#8217;email1&#8242;,<br \/>\n&#8216;phone_work&#8217;,<br \/>\n),<br \/>\n$maxnum,<br \/>\nfalse<br \/>\n);<br \/>\nreturn $result;<br \/>\n}<\/p>\n<p>The usual call scheme, nothing new. Note the module_name with capital letter.<br \/>\nA note about the fields list: you can get a list of the fields of a module by means of the soap method <em>get_module_fields<\/em>. We&#8217;ll see it in the next article, together with the use of custom fields.<\/p>\n<p><strong>Managing results<\/strong><br \/>\nFirst of all, please remember a general rule: if a soap call to sugar crm gives back an empty value(no array), you can be sure there&#8217;s a problem with your query or order_by clause. As an advice, always use the notation &#8220;module.field&#8221;( i.e. &#8220;contacts.email1&#8221;) when querying. This is I guess because in sugar crm, for any module there&#8217;s an additional &#8220;_cstm&#8221; custom fields table(for &#8220;contacts&#8221; there&#8217;s a &#8220;contacts_cstm&#8221; table), and fields are taken also from there when querying.<br \/>\nAfter calling our <em>getContacts<\/em> method, the result we get is again an array structure.<br \/>\nHere is an example:<\/p>\n<p>Array<br \/>\n(<br \/>\n[result_count] =&gt; 3<br \/>\n[next_offset] =&gt; 3<br \/>\n[field_list] =&gt; Array<br \/>\n(<br \/>\n[0] =&gt; Array<br \/>\n(<br \/>\n[name] =&gt; id<br \/>\n[type] =&gt; id<br \/>\n[label] =&gt; ID:<br \/>\n[required] =&gt; 0<br \/>\n[options] =&gt; Array<br \/>\n(<br \/>\n)<br \/>\n)<br \/>\n[1] &#8230;&#8230;&#8230;<br \/>\n)<\/p>\n<p>[entry_list] =&gt; Array<br \/>\n(<br \/>\n[0] =&gt; Array<br \/>\n(<br \/>\n[id] =&gt; 83567303-7aad-db69-0d7e-44bde634c3f7<br \/>\n[module_name] =&gt; Contacts<br \/>\n[name_value_list] =&gt; Array<br \/>\n(<br \/>\n[0] =&gt; Array<br \/>\n(<br \/>\n[name] =&gt; id<br \/>\n[value] =&gt; 83567303-7aad-db69-0d7e-44bde634c3f7<br \/>\n)<\/p>\n<p>[1] =&gt; Array<br \/>\n(<br \/>\n[name] =&gt; first_name<br \/>\n[value] =&gt; Mauro<br \/>\n)<br \/>\n[2] =&gt; Array<br \/>\n(<br \/>\n[name] =&gt; last_name<br \/>\n[value] =&gt; Molino<br \/>\n)<br \/>\n[3] &#8230;&#8230;..<br \/>\n)<\/p>\n<p>)<br \/>\n[1] &#8230;&#8230;..<\/p>\n<p>)<\/p>\n<p>[error] =&gt; Array<br \/>\n(<br \/>\n[number] =&gt; 0<br \/>\n[name] =&gt; No Error<br \/>\n[description] =&gt; No Error<br \/>\n)<\/p>\n<p>)<br \/>\nWe&#8217;ve already seen the [error] array, [result_count] and [next_offset] are simple, obvious values.<br \/>\n[field_list] contains a multi-dimensional array with data about the fields we have requested, but what really interests us is the [entry_list] array structure. It&#8217;s again a multi-dimensional array containing the single records of our search. Every item contains, together with a couple of other fields, a [name_value_list] array , itself containing record data in the form of name\/value pair fields. Now, it is usually more convenient to have these data in the form of a key\/value associative array, so let&#8217;s implement the following method, to be put as usual inside our SugarSoap class:<\/p>\n<p>function nameValuePairToSimpleArray($array){<br \/>\n$my_array=array();<br \/>\nwhile(list($name,$value)=each($array)){<br \/>\n$my_array[$value[&#8216;name&#8217;]]=$value[&#8216;value&#8217;];<br \/>\n}<br \/>\nreturn $my_array;<br \/>\n}<\/p>\n<p>By passing for instance the [entry_list][0][name_value_list] array to the above method, we&#8217;ll get back something like:<\/p>\n<p>Array<br \/>\n(<br \/>\n[id] =&gt; 83567303-7aad-db69-0d7e-44bde634c3f7<br \/>\n[first_name] =&gt; Mauro<br \/>\n[last_name] =&gt; Molino<br \/>\n)<\/p>\n<p>&nbsp;<\/p>\n<p><strong>A little example<\/strong><br \/>\nWe have now all we need to write down an example. Here it is:<\/p>\n<p>require_once &#8220;SugarSoap.php&#8221;;<br \/>\n$soap=new SugarSoap(&#8216;http:\/\/mysugar\/soap.php?wsdl&#8217;); \/\/ we automatically log in<br \/>\n$result=$soap-&gt;getContacts(&#8221; contacts.email1&lt;&gt;&#8221; &#8220;,5,&#8221; contacts.last_name desc&#8221;);<br \/>\nif($result[&#8216;result_count&#8217;]&gt;0){<br \/>\nforeach($result[&#8216;entry_list&#8217;] as $record){<br \/>\n$array= $soap-&gt;nameValuePairToSimpleArray($record[&#8216;name_value_list&#8217;]);<br \/>\necho $array[&#8216;first_name&#8217;] . &#8221; &#8221; . $array[&#8216;last_name&#8217;] . &#8221; &#8211; &#8221; . $array[&#8217;email1&#8242;]. &#8220;&lt;br&gt;&#8221;;<br \/>\n}<br \/>\n} else {<br \/>\necho &#8220;No contacts found&#8221;;<br \/>\n}<\/p>\n<p><span style=\"font-size: small;\"><br \/>\nWe are retrieving only contacts whose email field is not empty, a maximum of 5 records, order by last name in descending order.<br \/>\nThe <em>foreach<\/em> gives us the retrieved entries as single records that we convert into a more useful associative array structure.<br \/>\nThe visualization is done simply <em>echoing<\/em>. Having the result as a simple array it is quite easy to use it with a templating system like Smarty, to have a nice view of our data.<\/p>\n<p><strong>Notes<\/strong><br \/>\nPlease don&#8217;t be too severe with my code quality. To partially justify me, consider I try to go directly to the point, thus ignoring things like error management. I think, but this is only my opinion, that for intermediate\/experienced developers essential code is more readable.<\/p>\n<p><strong>Final thoughts<\/strong><br \/>\nIn this article we&#8217;ve seen the basics of sugar crm soap integration, yet we already have something useful to work on.<br \/>\nThe next article will focus on deeper integration between sugar crm and a custom web application; in particular we&#8217;ll see how to use sugar crm as an authentication\/user-management system for our web apps, relieving from the burden of implementing it from scratch, while giving us an appealing weapon towards our customers.<br \/>\nPlease don&#8217;t hesitate to contact me for any question\/doubt\/advice.<\/p>\n<p><strong>Resources<\/strong><br \/>\n<a href=\"http:\/\/www.beanizer.org\/site\/index.php\/en\/Articles\/Sugar-CRM-integration-with-custom-PHP-applications-II.html\">Sugar CRM integration with custom PHP applications (II) &#8211; Using sugar crm as an authentication system<\/a><br \/>\nThe second article of this series. It focuses on using sugar crm as authentication system and user manager for custom PHP applications.<\/span><a href=\"http:\/\/www.beanizer.org\/site\/index.php\/Articoli\/SugarCRM-integration-website-session-and-SOAP-session.html\">Sugar CRM integration &#8211; website session and SOAP session<\/a><br \/>\nThe third article of this series. It&#8217;s about how to use web\/soap session ids\u00a0 in SugarCRM.<\/p>\n<p>&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n","protected":false},"excerpt":{"rendered":"<p>documentation about exposed SOAP functions. This time the SOAP methods we&#8217;re interested in are: login, to log in into sugar crm get_entry_list to query sugar crm and get lists of Contacts,Accounts etc. To access SOAP functionalities from PHP we&#8217;ll use the nusoap library, which does not require any special PHP extension. We&#8217;re now going to ..<\/p>\n<div class=\"clear-fix\"><\/div>\n<p><a href=\"http:\/\/symbioticindia.in\/docu\/2016\/05\/06\/sugar-crm-integration-with-custom-php-applications-i\/\" title=\"read more...\">Read more<\/a><\/p>\n","protected":false},"author":5,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,2],"tags":[],"class_list":["post-44","post","type-post","status-publish","format-standard","hentry","category-php","category-sugarcrm"],"_links":{"self":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/44","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/users\/5"}],"replies":[{"embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/comments?post=44"}],"version-history":[{"count":1,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/44\/revisions"}],"predecessor-version":[{"id":45,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/posts\/44\/revisions\/45"}],"wp:attachment":[{"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/media?parent=44"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/categories?post=44"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/symbioticindia.in\/docu\/wp-json\/wp\/v2\/tags?post=44"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}