WebServices, SOAP

De Wikijoan
Dreceres ràpides: navegació, cerca

En el manual del desenvolupador hi ha un apartat que fa una introducció de com podem accedir al Sugar CRM a través dels Web Services.

SugarCRM proporciona una API de Web Services a través de la implementació del protocol SOAP que fa NuSOAP PHP. SOAP significa Simple Object Access Protocol. S'utilitza per fer Crides a Procediments Remots (RPC, Remote Procedure Calls) a través del protocol HTTP mitjançant missatges XML.

La API de SugarSoap està construïda utilitzant la llibreria NuSOAP que s'inclou en les tres versions de Sugar CRM. Es pot veure l'API a:

http://localhost/sugarcrm/soap.php

El fitxer SugarSoap WSDL (Web Services Description Language) es troba a:

http://localhost/sugarcrm/soap.php?wsdl

Gràcies als diversos toolkits disponibles, és fàcil fer efectiu l'ús dels SOAP Web Services des d'una varietat de llenguatges de programació, en particular amb Sugar i la seva ampla llista de serveis basats en SOAP que ofereix.

Per als següents exemples s'utilitza PHP juntament amb el toolkit NuSOAP. Evidentment ens podrem connectar al SugarCRM via SOAP i escriure les nostres pròpies aplicacions en Java, C++ o qualsevol altre llenguatge de programació amb capacitat SOAP.

Nota: el primer que hem de fer és assegurar-nos que el fitxer de variables config.php funciona correctament: http://localhost/sugarcrm/config.php

En la carpeta examples hi ha exemples de connexió:

El primer que passa quan executem SoapTest.php és un error:

http://localhost/sugarcrm/examples/SoapTest.php
error: Not a valid entry point

Això es soluciona ficant define('sugarEntry', TRUE); a dalt de tot:

Your code is fine actually. When you include 'nusoap/nusoap.php' toward the top of your file, it's using the copy of nuSOAP found in Sugar (which has protections built in for entry points). You can either add this line to the top of your PHP file:

PHP Code:
define('sugarEntry', TRUE);  

i ara ja funciona.

Un exemple mínim per connectar-se als Web Services de Sugar CRM:

fitxer echoprova.php

<?php
define('sugarEntry', TRUE);  

require_once('../include/nusoap/nusoap.php');

$client = new nusoapclient('http://localhost/sugarcrm/soap.php');

$auth_array = array(
'user_auth' => array(
'user_name' => 'admin',
'password' => md5('****'),
)
);
 
$login_results = $client->call('login',$auth_array);
$session_id = $login_results['id'];
$user_guid = $client->call('get_user_id',$session_id);
printf("\n".$auth_array['user_auth']['user_name'].' has a GUID of ' . $user_guid . "\n\n");
?>

Bàsicament ens connectem amb el login i pwd (substituir pel password correcte), fa un call i visualitzem el GUID del login amb què ens hem connectat.

L'exemple SoapTestPortal.php i SoapTestPortal2.php són més complets, però no funcionen perquè es necessita Sugar Portal i la versió Enterprise o Professional de Sugar

Contingut

Exemple2. Inserir un lead

inserir_lead.php (ha funcionat)

<?php
 define('sugarEntry', TRUE);
 //Use the NuSOAP files
 require_once('../include/nusoap/nusoap.php');
 
 $soapclient = new nusoapclient('http://localhost/sugarcrm/soap.php?wsdl',true);
 
 $user_auth = array(
                 'user_auth' => array(
                       'user_name' => 'admin',
                       'password' => md5('****'),
                       'version' => '0.1'
                       ),
                 'application_name' => 'soapleadcapture');



 $result_array = $soapclient->call('login',$user_auth);
 
 $session_id =  $result_array['id'];

 $user_guid = $soapclient->call('get_user_id',$session_id);
  
 // Up until now, we have not introduced anything new
 // The following lines will use the set_entry SOAP call to add
 // a Lead from a mixture of POST variables and hard coded
 // values, then assign to the authenticated Sugar user...
/* $set_entry_params = array(
                       'session' => $session_id,
                       'module_name' => 'Leads',
                       'name_value_list'=>array(
                           array('name'=>'first_name','value'=>$_POST['first_name']),
                           array('name'=>'last_name','value'=>$_POST['last_name']),
                           array('name'=>'status', 'value'=>'New'),
                           array('name'=>'phone_work', 'value'=>$_POST['phone']),
                           array('name'=>'phone_fax', 'value'=>$_POST['fax']),
                           array('name'=>'account_name','value'=>$_POST['companyname']),
                           array('name'=>'lead_source','value'=>'Web Site'),
                           array('name'=>'description','value'=>$_POST['prod_desc']),
                           array('name'=>'assigned_user_id', 'value'=>$user_guid)));
*/
 $set_entry_params = array(
                       'session' => $session_id,
                       'module_name' => 'Leads',
                       'name_value_list'=>array(
                           array('name'=>'first_name','value'=>'Pere'),
                           array('name'=>'last_name','value'=>'Pruna'), 
                           array('name'=>'status', 'value'=>'New'),
                           array('name'=>'phone_work', 'value'=>'659.00.61.56'),
                           array('name'=>'phone_fax', 'value'=>'93.456.56.56'),
                           array('name'=>'account_name','value'=>'Balmes SCCP'),
                           array('name'=>'lead_source','value'=>'www.balmessccp.org'),
                           array('name'=>'description','value'=>'la descripció del possible client'),
                           array('name'=>'assigned_user_id', 'value'=>$user_guid)));

 $result = $soapclient->call('set_entry',$set_entry_params);
 
 // this redirects to a page specified in the previous page...
 //header("Location:  " . $_POST['redirect']);
 
 ?>

On veig la llista de tots els camps que es poden omplir per a un lead? Doncs a /sugarcrm/modules/leads/metadata/detailedviewdefs.php.

Aquí puc veure que per exemple hi ha un camp que és el do_not_call, i per tant puc afegir la línia

array('name'=>'do_not_call','value'=>True),

Recordar que a http://mysugar/soap.php hi ha la documentació bàsica sobre els mètodes exposats de les funcions SOAP.

Exemple3. Login with error checking

És una funció que valida un login i password de SugarCRM. Podria servir per validar l'entrada a una aplicació web amb els logins i passwords de Sugar.

<? 
function wsLogin($userName, $Password)
{
	
echo "including";
require_once('../include/nusoap/nusoap.php');
  
$Connectionstring = 'http://localhost/sugarcrm/soap.php?wsdl';
$wsdl="http://localhost/sugarcrm/soap.php?wsdl";

$sugar_client = new soapclient($wsdl, true);
echo "get the client ";
$proxy =  $sugar_client->getProxy();

echo "proxy ";
  $ret =  $proxy->test('OK');
echo "test is: $ret";
echo "password conded is: ". md5($Password) . "";
  
$user_auth = array(
	'user_name' => $userName,
     	'password' => md5($Password),
	'version' => "1",    		
);
			  			
$login_results=  $proxy->login($user_auth, "pipo");
	 				 
if($login_results['error']['name']=="No Error")
{
	return   $session_id =  $login_results['id'];
}
else
{
	return $login_results['error']['name'];
}
   
}
?>

Llistar casos

Després de barallar-me bastant, he aconseguit llistar els casos que hi ha ficats al SugarCRM, amb la possibilitat de filtrar i d'ordenar. El mètode response és important per depurar doncs dóna molta informació d'on estan els errors.

<?php
define('sugarEntry', TRUE);  

require_once('../include/nusoap/nusoap.php');

$client = new nusoapclient('http://localhost/sugarcrm/soap.php?wsdl',true);

$pass = md5('****');
echo "Login Result: ";
echo $client->call('create_session', array('user_name'=>'admin', 'password'=>$pass));
echo "<br />";


$auth_array = array(
'user_auth' => array(
'user_name' => 'admin',
'password' => md5('****'),
)
);

$login_results = $client->call('login',$auth_array);
$session_id = $login_results['id'];
printf("Session ID: ". $session_id . "<br />");


$module_name='Cases';
$query='cases.name like "%warning%"';
$order_by='cases.id';
$offset=0;
$select_fields=array(
'id',
'case_number',
'name',
'status',
);
$max_results=5;
$deleted=0;

$search_list=$client->call('get_entry_list',array($session_id,$module_name,$query,$order_by,$offset,$select_fields,$max_results,$deleted));
echo "numero de resultats ".$search_list['result_count']."<br />";
echo "el mètode response va molt bé per editar errors. Per exemple, si faig referència a un camp que no existeix en el order by<br />";
echo $client->response;
echo "<br /><br />";



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

echo "Search result is <pre>";
if($search_list['result_count']>0){
foreach($search_list['entry_list'] as $record){
$array= nameValuePairToSimpleArray($record['name_value_list']);
echo $array['id'] . " :: " . $array['case_number'] . " - " . $array['name'] . " - " . $array['status'] . "<br>";
}
}
else { echo "No cases found";
echo "<br />";
}


// End the session
echo "Closing Session: ";
echo $client->call('end_session', array('user_name'=>'admin'));
echo "<br />";

//kill the client
unset($client);

?>

Llistar contactes (classe PHP)

Ara faig el mateix que l'anterior exercici però definint una classe PHP.

La classe SugarSoap la defineixo en el fitxer SugarSoap.php:

<?php

define('sugarEntry', TRUE);
require_once('../include/nusoap/nusoap.php');
class SugarSoap{
	var $soapclient;
	var $proxy;
	var $sess;

	function SugarSoap(){
		$soap_url='http://localhost/sugarcrm/soap.php?wsdl';
		$soapclient = new nusoapclient($soap_url,true);
		$this->proxy = $soapclient->getProxy();
		$this->login();

	}

	function login(){
		$auth_array = array(
			'user_auth' => array(
			'user_name' => 'admin',
			'password' => md5('****'),
			)
		);
		$result = $this->proxy->call('login',$auth_array);
	    	$this->sess= $result['error']['number']==0 ? $result['id'] : null;	    
	    	return $this->sess;
	} 

	function getContacts($query='',$maxnum=0,$orderby=' contacts.last_name asc'){
		$contact_array = array(
			$this->sess,
			'Contacts',
			$query,
			$orderby,
			0,
			array(
			    'id',
			    'first_name',
			    'last_name',
			    'account_name',
			    'account_id',
			    'email1',
			    'phone_work',
			),
			$maxnum,
			false
		);
	    	$result = $this->proxy->call('get_entry_list',$contact_array);
		echo "el mètode response va molt bé per editar errors. Per exemple, si faig referència a un camp que no existeix en el order by<br />";
		echo $this->proxy->response."<br /><br />";
		return $result;
	}              
 
	function nameValuePairToSimpleArray($array){
	$my_array=array();
	while(list($name,$value)=each($array)){
	$my_array[$value['name']]=$value['value'];
	}
	return $my_array;
	}

}
?>  

i el fitxer llistar_contactes.php és el que crida a la classe:

<?php

require_once "SugarSoap.php";
$soap=new SugarSoap(); // we automatically log in

$result=$soap->getContacts(" contacts.phone_work<>'' ",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']. " - " . $array['phone_work']. "<br>";              
    }
} else {
    echo "No contacts found";
}  
?>

Compte perquè si en el filtre fico

contacts.email1<>

falla, i això és perquè no existeix el camp mail1 en la taula contacts. El tractament dels mails és una mica més complexe, és una relació 1:M i els mails estan en la taula email_addr_bean_rel i el camp primary_address. La consulta que s'envia és

SELECT count(*) c FROM contacts LEFT JOIN users ON contacts.assigned_user_id=users.id LEFT JOIN accounts_contacts ON contacts.id=accounts_contacts.contact_id and accounts_contacts.deleted = 0 LEFT JOIN accounts ON accounts_contacts.account_id=accounts.id AND accounts.deleted=0 LEFT JOIN email_addr_bean_rel eabl ON eabl.bean_id = contacts.id AND eabl.bean_module = 'Contacts' and eabl.primary_address = 1 and eabl.deleted=0 LEFT JOIN email_addresses ea ON (ea.id = eabl.email_address_id) 
where ( contacts.email1<>'' ) AND contacts.deleted=0

i falla perquè

MySQL error 1054: Unknown column 'contacts.email1' in 'where clause'

Analitzant la clàusula SQL veig que he de ficar la línia

eabl.primary_address<>

i ara sí que puc filtar els contactes que tenen email1<>

Al MySQL, per veure les taules i la descripció de les taules és:

mysql> show tables;
mysql> SHOW FIELDS FROM `contacts`;
mysql> SHOW FIELDS FROM `email_addr_bean_rel`;
Eines de l'usuari
Espais de noms
Variants
Accions
Navegació
IES Jaume Balmes
Màquines recreatives
CNC
Informàtica musical
joanillo.org Planet
Eines