Home    | Software    | Articles    | Tips'n Tricks    | Contacts    | Support Us  
Home arrow Articles arrow Sugar CRM integration with custom PHP applications (I)

Sugar CRM integration with custom PHP applications (I)

Basic Sugar CRM SOAP functions Introduction

It's becoming the rule, when exposing a project to potential customers what they're most fascinated by is the CRM side. They usually don't need it but they seem they can't do without it. That's it !! Or they already have a CRM and the proposed application must absolutely be integrated with it. Ok, white flag. If they want integration with a CRM, let's give it to them.
Sugar CRM is a very popular open source CRM. What interests us is its SOAP interface. By using it we can integrate a custom application with Sugar. This time we'll explore some basic querying methods to get lists of contacts from the crm.
In the next article of this series we'll focus on using sugar as an authentication system for our web applications.
Overview
Sugar crm SOAP interface exposes everything we need to get to the point. Provided your Sugar crm installation url is something like http://mysugar/, you can download the wsdl file at http://mysugar/soap.php?wsdl, while at http://mysugar/soap.php there's some documentation about exposed SOAP functions.
This time the SOAP methods we're interested in are:
  1. login, to log in into sugar crm
  2. get_entry_list to query sugar crm and get lists of Contacts,Accounts etc.

To access SOAP functionalities from PHP we'll use the nusoap library, which does not require any special PHP extension.
We're now going to build a PHP class encapsulating the functionalities we need. In the articles to come we'll expand this same class with new methods.

The code
Most sugar crm SOAP methods require a session id as one of the parameters to make sure we're authenticated users. We can get a session id by first calling the login method.
But first of all let's create a basic class with a constructor:

<?php
        require_once("nusoap.php");
        class SugarSoap{
                var $proxy;
                var $sess;
                function SugarSoap($soap_url,$login=true){
                        $soapclient = new soapclient($soap_url,true);
                        $this->proxy = $soapclient->getProxy();
                        if($login) $this->login();
                }
        }
?>  


The 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.
In the constructor, $soap_url is http://mysugar/soap.php?wsdl, changing mysugar with the real url of our sugar installation, and $login defaults to true, meaning we want to automatically log in.
We simply instantiate a soapclient( the 'true' as second parameter means we are using a wsdl), get a proxy from it and log in if required.
Now the login method (to be added inside the class). Here it is:

 

function login(){
    $params = array(
        'user_name' => 'myuser',
        'password'  => md5('mypassword'),
        'version'   => '.01'
    );
    $result = $this->proxy->login($params,'MyApp');
    $this->sess= $result['error']['number']==0 ? $result['id'] : null;
    return $this->sess;
}
 

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:
  1. user_name is a valid sugar user
  2. password is her/his password(note you need to pass it md5 encoded)
  3. version , a version number, not sure it gets checked some way
The second parameter of the login method is a free string (application name, in the documentation).
Now we have the result of the call in $result, and it's an array structure. We'll always have a $result['error'] array, and $result['error']['number']==0 means no error. If everything has gone fine, we'll get a valid session id in $result['id'], and we save it for future methods calls.



Querying Sugar CRM

At this point we have our session id , meaning we've been authenticated by sugar crm, and can therefore do some querying. Let's focus on the get_entry_list method. The parameters it needs are:
  1. session_id, what we get after using login()
  2. module_name, that is Contacts,Accounts,Notes,Cases etc
  3. query, a sql like query
  4. order_by, a sql like order by clause
  5. offset, to obtain something like a pagination
  6. select_fields, array of fields to be retrieved
  7. max_result, max number of entries to retrieve
  8. deleted, whether to show deleted entries or not deleted ones (thanks to Mark Clark for spotting an error here)


So, here is our getContacts method(to be added to SugarSoap class):

function getContacts($query='',$maxnum=0,$orderby=' contacts.last_name asc'){
    $result = $this->proxy->get_entry_list(
        $this->sess,
        'Contacts',
        $query,
        $orderby,
        0,
        array(
            'id',
            'first_name',
            'last_name',
            'account_name',
            'account_id',
            'email1',
            'phone_work',
        ),
        $maxnum,
        false
    );
    return $result;
}              
 


The usual call scheme, nothing new. Note the module_name with capital letter.
A note about the fields list: you can get a list of the fields of a module by means of the soap method get_module_fields. We'll see it in the next article, together with the use of custom fields.

Managing results
First 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's a problem with your query or order_by clause. As an advice, always use the notation "module.field"( i.e. "contacts.email1") when querying. This is I guess because in sugar crm, for any module there's an additional "_cstm" custom fields table(for "contacts" there's a "contacts_cstm" table), and fields are taken also from there when querying.
After calling our getContacts method, the result we get is again an array structure.
Here is an example:

Array
(
    [result_count] => 3
    [next_offset] => 3
    [field_list] => Array
        (
            [0] => Array
                (
                    [name] => id
                    [type] => id
                    [label] => ID:
                    [required] => 0
                    [options] => Array
                        (
                        )
                )
            [1] .........
        )

    [entry_list] => Array
        (
            [0] => Array
                (
                    [id] => 83567303-7aad-db69-0d7e-44bde634c3f7
                    [module_name] => Contacts
                    [name_value_list] => Array
                        (
                            [0] => Array
                                (
                                    [name] => id
                                    [value] => 83567303-7aad-db69-0d7e-44bde634c3f7
                                )

                            [1] => Array
                                (
                                    [name] => first_name
                                    [value] => Mauro
                                )
                            [2] => Array
                                (
                                    [name] => last_name
                                    [value] => Molino
                                )
                            [3] ........
                        )

                )
             [1] ........

        )

    [error] => Array
        (
            [number] => 0
            [name] => No Error
            [description] => No Error
        )

)        


We've already seen the [error] array, [result_count] and [next_offset] are simple, obvious values.
[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'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's implement the following method, to be put as usual inside our SugarSoap class:

function nameValuePairToSimpleArray($array){
    $my_array=array();
    while(list($name,$value)=each($array)){
        $my_array[$value['name']]=$value['value'];
    }
    return $my_array;



By passing for instance the [entry_list][0][name_value_list] array to the above method, we'll get back something like:

Array
(
        [id] => 83567303-7aad-db69-0d7e-44bde634c3f7
        [first_name] => Mauro
        [last_name] => Molino

 

A little example
We have now all we need to write down an example. Here it is:

require_once "SugarSoap.php";
$soap=new SugarSoap('http://mysugar/soap.php?wsdl'); // we automatically log in
$result=$soap->getContacts(" contacts.email1<>'' ",5," contacts.last_name desc");
if($result['result_count']>0){ 
    foreach($result['entry_list'] as $record){
        $array= $soap->nameValuePairToSimpleArray($record['name_value_list']);
        echo $array['first_name'] . " " . $array['last_name'] . " - " . $array['email1']. "<br>";              
    }
} else {
    echo "No contacts found";
}  


We are retrieving only contacts whose email field is not empty, a maximum of 5 records, order by last name in descending order.
The foreach gives us the retrieved entries as single records that we convert into a more useful associative array structure.
The visualization is done simply echoing. 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.

Notes
Please don'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.

Final thoughts
In this article we've seen the basics of sugar crm soap integration, yet we already have something useful to work on.
The next article will focus on deeper integration between sugar crm and a custom web application; in particular we'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.
Please don't hesitate to contact me for any question/doubt/advice.

Resources
Sugar CRM integration with custom PHP applications (II) - Using sugar crm as an authentication system
The second article of this series. It focuses on using sugar crm as authentication system and user manager for custom PHP applications.

Sugar CRM integration - website session and SOAP session
The third article of this series. It's about how to use web/soap session ids  in SugarCRM. 

 

 
< Prev   Next >

  Articles RSS feed

Latest Articles
Latest Software
   
designed by allmambo.com