I. Présentation de XML-RPC▲
English version of the tutorial here :
Odoo Tutorial: Interaction between Odoo and PHP via XML-RPCOdoo Tutorial: Interaction between Odoo and PHP via XML-RPC
Pour faire simple, le Web Service XML-RPC est un ensemble d'outils et de spécifications qui permettent aux logiciels fonctionnant sur différents systèmes d'exploitation, en cours d'exécution dans des environnements différents, de faire des appels de procédure sur Internet.
C'est l'appel de procédure à distance via le protocole HTTP comme transport et XML comme encodage. XML-RPC est conçu pour être aussi simple que possible, tout en permettant à des structures de données complexes d'être transmises, traitées et renvoyées.
II. Prérequis▲
Pour pouvoir utiliser le protocole XML-RPC avec PHP, vous aurez besoin de la bibliothèque PHPXML-RPC.
Le site officiel :XML-RPC for PHPSite officiel XML-RPC for PHP
Pour se plonger dans ce tutoriel, il faut une bonne connaissance des langages de programmation suivants :
- PHP ;
- Python ;
- XML.
Et il faut assurément être bien familiarisé avec l'ORM d'OpenERP.
III. Installation▲
Téléchargez la bibliothèque, puis décompressez l'archive.
Copiez les fichiers qui se trouvent dans le répertoire « lib » sur votre serveur.
Astuce
Pour plus de clarté et pour faciliter la maintenance, je vous recommande de créer un répertoire « xmlrpc_lib » (par exemple) sur votre serveur et d'y placer les fichiers.
IV. Rappel▲
Nous allons agir sur Odoo depuis un site Web en utilisant le langage de programmation PHP. Pour le tutoriel, j’ai installé OpenERP 7 (7.0-20140627-231127) avec les données de démo sur un serveur Debian 7 (Wheezy). J'ai créé un hôte virtuel Apache sur un serveur Suse Linux 10, déjà configuré pour le Web (PHP, MySQL, etc.).
Donc, Odoo est sur le serveur Debian, et les scripts PHP seront exécutés sur le serveur Suse. Ces tests sont réalisés sur mon réseau local, donc, il faudra bien sûr modifier les URL dans les scripts.
Également, je vous montre les différentes connexions HTTP/HTTPS, mais les tests sont réalisés en local en HTTP.
V. Connexion à Odoo▲
Pour exécuter des fonctions dans Odoo, il est nécessaire en premier lieu, de se connecter, puis d'appeler ensuite une fonction d'un module.
Pour établir la connexion, nous allons créer un client XML-RPC :
$server_url
=
'
https://www.mon-serveur-openerp.com:8069
'
;
//connexion sécurisée
$sock
=
new xmlrpc_client($server_url
.
"
/xmlrpc/common
"
);
$sock
->
setSSLVerifyPeer(0
);
Astuce
Si vous utilisez une connexion sécurisée, vous pouvez outrepasser la vérification du certificat SSL avec setSSLVerifyPeer(0);
La connexion peut échouer dans le cas d'un certificat autosigné, par exemple.
Nous allons ensuite envoyer une commande XML-RPC, c'est à dire : nous appelons une fonction Python de Odoo. Ici, nous appelons la fonction « login »
Pour passer des paramètres à cette fonction, nous utiliserons la fonction addParam() en créant un objet xmlrpcval() (valeur au format XML-RPC) :
$user
=
'
admin
'
;
$password
=
'
mY5up3rPwd
'
;
$dbname
=
'
test
'
;
$server_url
=
'
https://www.monsite.com:8069
'
;
//connexion sécurisée
$connexion
=
new xmlrpc_client($server_url
.
"
/xmlrpc/common
"
);
$connexion
->
setSSLVerifyPeer(0
);
$c_msg
=
new xmlrpcmsg('
login
'
);
$c_msg
->
addParam(new xmlrpcval($dbname
,
"
string
"
));
$c_msg
->
addParam(new xmlrpcval($user
,
"
string
"
));
$c_msg
->
addParam(new xmlrpcval($password
,
"
string
"
));
$c_response
=
$connexion
->
send($c_msg
);
Info
Nous utilisons l'URL /xmlrpc/common pour les méthodes suivantes :
'login', 'about', 'timezone_get', 'get_server_environment', 'login_message','get_stats', 'check_connectivity', 'list_http_services', 'version', 'authenticate'
Il suffit ensuite de récupérer la réponse pour vérifier si la connexion a bien été établie.
if ($c_response
->
errno !=
0
){
echo '
<p>error :
'
.
$c_response
->
faultString() .
'
</p>
'
;
}
else{
//… on continue le script
}
Ici, si errno!= 0, il y a donc un message d'erreur et la connexion a été refusée. Sinon, on a bien établi la connexion, on pourra alors récupérer l'UID de l'utilisateur. C'est cet UID qui sera ensuite envoyé à chaque requête XML-RPC.
Si vous vous rappelez bien, la majeure partie des fonctions Python de Odoo nécessitent l'ID de l'utilisateur :
def function(self, cr, uid, …)
$uid
=
$c_response
->
value()->
scalarval();
VI. xmlprcval()▲
On l'a vu, pour passer des paramètres aux fonctions nous formatons les données avec l'objet xmlrpcval(valeur, type).
Les différents types acceptés sont : string, i4, int, double, boolean, dateTime.iso8601, base64, null, array et struct.
struct permet de passer des noms de champs et leur valeur au format xmlprcval().
Dans l'exemple ci-dessous, on va créer un client (partner) :
$val
=
array (
"
name
"
=>
new xmlrpcval("
Godin
"
,
"
string
"
),
"
city
"
=>
new xmlrpcval("
Marne la Vallée
"
,
"
string
"
),
"
zip
"
=>
new xmlrpcval("
77000
"
,
"
string
"
),
"
website
"
=>
new xmlrpcval("
http://www.lapinmoutardepommedauphine.com
"
,
"
string
"
),
"
lang
"
=>
new xmlrpcval("
fr_FR
"
,
"
string
"
),
"
tz
"
=>
new xmlrpcval("
Europe/Paris
"
,
"
string
"
),
);
VII. Exécution de la méthode create()▲
Nous allons maintenant établir une autre connexion pour appeler directement la méthode execute() sur l'objet res.partner.
Info
Nous utilisons l'URL /xmlrpc/object pour les méthodes suivantes :
'execute', 'execute_kw', 'exec_workflow'.
$client
=
new xmlrpc_client($server_url
.
"
/xmlrpc/object
"
);
$client
->
setSSLVerifyPeer(0
);
$msg
=
new xmlrpcmsg('
execute
'
);
$msg
->
addParam(new xmlrpcval($dbname
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($uid
,
"
int
"
));
$msg
->
addParam(new xmlrpcval($password
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
res.partner
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
create
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($val
,
"
struct
"
));
$response
=
$client
->
send($msg
);
Il suffit d'afficher ensuite la réponse avec :
Pour rappel, la méthode create() renvoie l'ID de l'enregistrement créé.
VIII. Le script create() complet▲
<
meta http-
equiv=
"
Content-Type
"
content=
"
text/html; charset=utf-8
"
/>
<?php
echo '<h2>XML-RPC AVEC OPENERP/ODOO ET PHP</h2>'
;
include("xmlrpc_lib/xmlrpc.inc.php"
);
include("xmlrpc_lib/xmlrpcs.inc.php"
);
$GLOBALS
[
'xmlrpc_internalencoding'
]=
'UTF-8'
;
$user
=
'admin'
;
$password
=
'mY5up3rPwd'
;
$dbname
=
'test'
;
$server_url
=
'http://192.168.1.120:8069'
;
$connexion
=
new
xmlrpc_client($server_url
.
"/xmlrpc/common"
);
$connexion
->
setSSLVerifyPeer(0
);
$c_msg
=
new
xmlrpcmsg('login'
);
$c_msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($user
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$c_response
=
$connexion
->
send($c_msg
);
if
($c_response
->
errno !=
0
){
echo '<p>error : '
.
$c_response
->
faultString() .
'</p>'
;
}
else
{
$uid
=
$c_response
->
value()->
scalarval();
$val
=
array
(
"name"
=>
new
xmlrpcval("Godin Thierry"
,
"string"
),
"street"
=>
new
xmlrpcval("Au fond à gauche"
,
"string"
),
"city"
=>
new
xmlrpcval("Marne la Vallée"
,
"string"
),
"zip"
=>
new
xmlrpcval("77000"
,
"string"
),
"website"
=>
new
xmlrpcval("http://www.lapinmoutardepommedauphine.com"
,
"string"
),
"lang"
=>
new
xmlrpcval("fr_FR"
,
"string"
),
"tz"
=>
new
xmlrpcval("Europe/Paris"
,
"string"
),
);
$client
=
new
xmlrpc_client($server_url
.
"/xmlrpc/object"
);
$client
->
setSSLVerifyPeer(0
);
$msg
=
new
xmlrpcmsg('execute'
);
$msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$msg
->
addParam(new
xmlrpcval($uid
,
"int"
));
$msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$msg
->
addParam(new
xmlrpcval("res.partner"
,
"string"
));
$msg
->
addParam(new
xmlrpcval("create"
,
"string"
));
$msg
->
addParam(new
xmlrpcval($val
,
"struct"
));
$response
=
$client
->
send($msg
);
echo 'Partner created - partner_id = '
.
$response
->
value()->
scalarval();
}
?>
IX. Les méthodes search() et read()▲
Nous avons vu comment créer un enregistrement par le biais de la méthode create(), nous allons maintenant voir les méthodes search() et read().
Nous utilisons la méthode search() en utilisant un filtre de domaine pour récupérer la liste des ID des enregistrements que nous voulons lire avec la méthode read().
En effet, rappelez-vous, la méthode read() nécessite plusieurs arguments, dont l'ID de l'enregistrement à lire.
$domain_filter
=
array (
new xmlrpcval(
array(new xmlrpcval('
is_company
'
,
"
string
"
),
new xmlrpcval('
!=
'
,
"
string
"
),
new xmlrpcval('
True
'
,
"
string
"
)
),
"
array
"
),
);
Comme on le voit dans le code ci-dessus, on recherche tous les clients qui ne sont pas des sociétés.
Ce filtre se traduirait en Python dans Odoo à :
[(
'is_company'
, '!='
, True
)]
On établit donc une nouvelle connexion puis on exécute la méthode search() comme ci-dessous :
$client
=
new xmlrpc_client($server_url
.
"
/xmlrpc/object
"
);
$client
->
setSSLVerifyPeer(0
);
$msg
=
new xmlrpcmsg('
execute
'
);
$msg
->
addParam(new xmlrpcval($dbname
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($uid
,
"
int
"
));
$msg
->
addParam(new xmlrpcval($password
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
res.partner
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
search
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($domain_filter
,
"
array
"
));
$response
=
$client
->
send($msg
);
$result
=
$response
->
value();
$ids
=
$result
->
scalarval();
Ensuite, nous formatons les ID pour les passer à la méthode read() comme ci-dessous :
$id_list
=
array();
for($i
=
0
;
$i
<
count($ids
);
$i
++
){
$id_list
[]=
new xmlrpcval($ids
[
$i
]->
me[
'
int
'
],
'
int
'
);
}
Puis, on crée la liste des champs que l'on veut lire :
$field_list
=
array(
new xmlrpcval("
name
"
,
"
string
"
),
new xmlrpcval("
email
"
,
"
string
"
),
new xmlrpcval("
street
"
,
"
string
"
),
new xmlrpcval("
city
"
,
"
string
"
),
new xmlrpcval("
zip
"
,
"
string
"
),
);
Puis, on exécute la méthode read() :
$msg
=
new xmlrpcmsg('
execute
'
);
$msg
->
addParam(new xmlrpcval($dbname
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($uid
,
"
int
"
));
$msg
->
addParam(new xmlrpcval($password
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
res.partner
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
read
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($id_list
,
"
array
"
));
$msg
->
addParam(new xmlrpcval($field_list
,
"
array
"
));
$resp
=
$client
->
send($msg
);
if ($resp
->
faultCode()){
echo $resp
->
faultString();
}
$result
=
$resp
->
value()->
scalarval();
Et enfin, on affiche les clients :
for($i
=
0
;
$i
<
count($result
);
$i
++
){
echo '
<h1>
'
.
$result
[
$i
]->
me[
'
struct
'
][
'
name
'
]->
me[
'
string
'
]
.
'
</h1>
'
.
'
<ol>
'
.
'
<li><strong>Email</strong> :
'
.
$result
[
$i
]->
me[
'
struct
'
][
'
email
'
]->
me[
'
string
'
]
.
'
</li>
'
.
'
<li><strong>Street</strong> :
'
.
$result
[
$i
]->
me[
'
struct
'
][
'
street
'
]->
me[
'
string
'
]
.
'
</li>
'
.
'
<li><strong>City</strong> :
'
.
$result
[
$i
]->
me[
'
struct
'
][
'
city
'
]->
me[
'
string
'
]
.
'
</li>
'
.
'
<li><strong>Zip code</strong> :
'
.
$result
[
$i
]->
me[
'
struct
'
][
'
zip
'
]->
me[
'
string
'
]
.
'
</li>
'
.
'
</ol>
'
.
'
<hr />
'
;
}
X. Explication du résultat▲
Si on fait un print_r($result) on obtient ceci :
Array ( [0] => xmlrpcval Object ( [me] => Array ( [struct] => Array ( [city] => xmlrpcval Object ( [me] => Array ( [boolean] => ) [mytype] => 1 [_php_class] => ) [name] => xmlrpcval Object ( [me] => Array ( [string] => Administrator ) [mytype] => 1 [_php_class] => ) [zip] => xmlrpcval Object ( [me] => Array ( [boolean] => ) [mytype] => 1 [_php_class] => ) [email] => xmlrpcval Object ( [me] => Array ( [string] => admin@example.com ) [mytype] => 1 [_php_class] => ) [street] => xmlrpcval Object ( [me] => Array ( [boolean] => ) [mytype] => 1 [_php_class] => ) [id] => xmlrpcval Object ( [me] => Array ( [int] => 3 ) [mytype] => 1 [_php_class] => ) ) ) [mytype] => 3 [_php_class] => ) [1] => xmlrpcval Object ( [me] => Array ( [struct] => Array ( [city] => xmlrpcval Object ( [me] => Array ( [string] => Wavre ) [mytype] => 1 [_php_class] => ) [name] => xmlrpcval Object ( [me] => Array ( [string] => Michel Fletcher ) [mytype] => 1 [_php_class] => ) [zip] => xmlrpcval Object ( [me] => Array ( [string] => 1300 ) [mytype] => 1 [_php_class] => ) [email] => xmlrpcval Object ( [me] => Array ( [string] => m.fletcher@agrolait.com ) [mytype] => 1 [_php_class] => ) [street] => xmlrpcval Object ( [me] => Array ( [string] => 69 rue de Namur ) [mytype] => 1 [_php_class] => ) [id] => xmlrpcval Object ( [me] => Array ( [int] => 31 ) [mytype] => 1 [_php_class] => ) ) ) [mytype] => 3 [_php_class] => ) [2] => xmlrpcval Object ( [me] => Array ( [struct] => Array ( [city] => xmlrpcval Object ( [me] => Array ( [string] => Wavre ) [mytype] => 1 [_php_class] => ) [name] => xmlrpcval Object ( [me] => Array ( [string] => Thomas Passot ) [mytype] => 1 [_php_class] => ) [zip] => xmlrpcval Object ( [me] => Array ( [string] => 1300 ) [mytype] => 1 [_php_class] => ) [email] => xmlrpcval Object ( [me] => Array ( [string] => p.thomas@agrolait.com ) [mytype] => 1 [_php_class] => ) [street] => xmlrpcval Object ( [me] => Array ( [string] => 69 rue de Namur ) [mytype] => 1 [_php_class] => ) [id] => xmlrpcval Object ( [me] => Array ( [int] => 30 ) [mytype] => 1 [_php_class] => ) ) ) [mytype] => 3 [_php_class] => ) [3] => xmlrpcval Object ( [me] => Array ( [struct] => Array ( [city] => xmlrpcval Object ( [me] => Array ( [string] => Taipei ) [mytype] => 1 [_php_class] => ) [name] => xmlrpcval Object ( [me] => Array ( [string] => Joseph Walters ) [mytype] => 1 [_php_class] => ) [zip] => xmlrpcval Object ( [me] => Array ( [string] => 106 ) [mytype] => 1 [_php_class] => ) [email] => xmlrpcval Object ( [me] => Array ( [string] => joseph.walters@asustek.com ) [mytype] => 1 [_php_class] => ) [street] => xmlrpcval Object ( [me] => Array ( [string] => 31 Hong Kong street ) [mytype] => 1 [_php_class] => ) [id] => xmlrpcval Object ( [me] => Array ( [int] => 29 ) [mytype] => 1 [_php_class] => ) ) ) [mytype] => 3 [_php_class] => ) [4] => xmlrpcval Object ( [me] => Array …....
$result est donc un tableau d'objets xmlrpcval().
Si on veut par exemple récupérer la valeur du champ name du premier enregistrement retourné, il faudra écrire ceci :
// Array ( [0] => xmlrpcval Object ( [me] => Array ( [struct] => Array
// ( [city] => xmlrpcval Object ( [me] => Array ( [boolean] => )
// [mytype] => 1 [_php_class] => ) [name] => xmlrpcval Object (
// [me] => Array ( [string] => Administrator )
echo $result
[
0
]->
me[
'
struct
'
][
'
name
'
]->
me[
'
string
'
]
// = Administrator
XI. Le script search() et read() complet▲
<
meta http-
equiv=
"
Content-Type
"
content=
"
text/html; charset=utf-8
"
/>
<?php
echo '<h2>XML-RPC AVEC OPENERP/ODOO ET PHP</h2>'
;
include("xmlrpc_lib/xmlrpc.inc.php"
);
include("xmlrpc_lib/xmlrpcs.inc.php"
);
$GLOBALS
[
'xmlrpc_internalencoding'
]=
'UTF-8'
;
$user
=
'admin'
;
$password
=
'mY5up3rPwd'
;
$dbname
=
'test'
;
$server_url
=
'http://192.168.1.120:8069'
;
$connexion
=
new
xmlrpc_client($server_url
.
"/xmlrpc/common"
);
$connexion
->
setSSLVerifyPeer(0
);
$c_msg
=
new
xmlrpcmsg('login'
);
$c_msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($user
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$c_response
=
$connexion
->
send($c_msg
);
if
($c_response
->
errno !=
0
){
echo '<p>error : '
.
$c_response
->
faultString() .
'</p>'
;
}
else
{
$uid
=
$c_response
->
value()->
scalarval();
$domain_filter
=
array
(
new
xmlrpcval(
array
(new
xmlrpcval('is_company'
,
"string"
),
new
xmlrpcval('!='
,
"string"
),
new
xmlrpcval('True'
,
"string"
)
),
"array"
),
);
$client
=
new
xmlrpc_client($server_url
.
"/xmlrpc/object"
);
$client
->
setSSLVerifyPeer(0
);
$msg
=
new
xmlrpcmsg('execute'
);
$msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$msg
->
addParam(new
xmlrpcval($uid
,
"int"
));
$msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$msg
->
addParam(new
xmlrpcval("res.partner"
,
"string"
));
$msg
->
addParam(new
xmlrpcval("search"
,
"string"
));
$msg
->
addParam(new
xmlrpcval($domain_filter
,
"array"
));
$response
=
$client
->
send($msg
);
$result
=
$response
->
value();
$ids
=
$result
->
scalarval();
$id_list
=
array
();
for
($i
=
0
;
$i
<
count($ids
);
$i
++
){
$id_list
[]=
new
xmlrpcval($ids
[
$i
]->
me[
'int'
],
'int'
);
}
$field_list
=
array
(
new
xmlrpcval("name"
,
"string"
),
new
xmlrpcval("email"
,
"string"
),
new
xmlrpcval("street"
,
"string"
),
new
xmlrpcval("city"
,
"string"
),
new
xmlrpcval("zip"
,
"string"
),
);
$msg
=
new
xmlrpcmsg('execute'
);
$msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$msg
->
addParam(new
xmlrpcval($uid
,
"int"
));
$msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$msg
->
addParam(new
xmlrpcval("res.partner"
,
"string"
));
$msg
->
addParam(new
xmlrpcval("read"
,
"string"
));
$msg
->
addParam(new
xmlrpcval($id_list
,
"array"
));
$msg
->
addParam(new
xmlrpcval($field_list
,
"array"
));
$resp
=
$client
->
send($msg
);
if
($resp
->
faultCode()){
echo $resp
->
faultString();
}
$result
=
$resp
->
value()->
scalarval();
echo '<h2>Resultat brut de la requête avec print_r($result) :</h2>'
;
print_r($result
);
echo '<hr />'
;
echo '<h2>Liste des partners qui ne sont pas des sociétés:</h2>'
;
for
($i
=
0
;
$i
<
count($result
);
$i
++
){
echo '<h1>'
.
$result
[
$i
]->
me[
'struct'
][
'name'
]->
me[
'string'
]
.
'</h1>'
.
'<ol>'
.
'<li><strong>Email</strong> : '
.
$result
[
$i
]->
me[
'struct'
][
'email'
]->
me[
'string'
]
.
'</li>'
.
'<li><strong>Street</strong> : '
.
$result
[
$i
]->
me[
'struct'
][
'street'
]->
me[
'string'
]
.
'</li>'
.
'<li><strong>City</strong> : '
.
$result
[
$i
]->
me[
'struct'
][
'city'
]->
me[
'string'
]
.
'</li>'
.
'<li><strong>Zip code</strong> : '
.
$result
[
$i
]->
me[
'struct'
][
'zip'
]->
me[
'string'
]
.
'</li>'
.
'</ol>'
.
'<hr />'
;
}
}
?>
XII. Les méthodes search() et unlink()▲
De la même façon que précédemment, nous allons maintenant utiliser la méthode search() pour rechercher tous les clients dont le nom comporte le terme « godin » (ce sont les clients que nous avons créés au début de ce tutoriel) puis nous allons tous les supprimer avec la méthode unlink().
On va donc reformuler le filtre de domaine comme ceci :
$domain_filter
=
array (
new xmlrpcval(
array(new xmlrpcval('
name
'
,
"
string
"
),
new xmlrpcval('
ilike
'
,
"
string
"
),
new xmlrpcval('
godin
'
,
"
string
"
)
),
"
array
"
),
);
Puis, on exécute la méthode search() :
$msg
=
new xmlrpcmsg('
execute
'
);
$msg
->
addParam(new xmlrpcval($dbname
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($uid
,
"
int
"
));
$msg
->
addParam(new xmlrpcval($password
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
res.partner
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
search
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($domain_filter
,
"
array
"
));
$response
=
$client
->
send($msg
);
$result
=
$response
->
value();
$ids
=
$result
->
scalarval();
Et finalement, on reformate la liste des ID et on exécute la méthode unlink() pour supprimer tous les clients dont le nom contient « godin » :
$id_list
=
array();
for($i
=
0
;
$i
<
count($ids
);
$i
++
){
$id_list
[]=
new xmlrpcval($ids
[
$i
]->
me[
'
int
'
],
'
int
'
);
}
$msg
=
new xmlrpcmsg('
execute
'
);
$msg
->
addParam(new xmlrpcval($dbname
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($uid
,
"
int
"
));
$msg
->
addParam(new xmlrpcval($password
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
res.partner
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval("
unlink
"
,
"
string
"
));
$msg
->
addParam(new xmlrpcval($id_list
,
"
array
"
));
$resp
=
$client
->
send($msg
);
if ($resp
->
faultCode()){
echo $resp
->
faultString();
}
XIII. Le script search() and unlink() complet :▲
<
meta http-
equiv=
"
Content-Type
"
content=
"
text/html; charset=utf-8
"
/>
<?php
echo '<h2>XML-RPC AVEC OPENERP/ODOO ET PHP</h2>'
;
include("xmlrpc_lib/xmlrpc.inc.php"
);
include("xmlrpc_lib/xmlrpcs.inc.php"
);
$GLOBALS
[
'xmlrpc_internalencoding'
]=
'UTF-8'
;
$user
=
'admin'
;
$password
=
'mY5up3rPwd'
;
$dbname
=
'test'
;
$server_url
=
'http://192.168.1.120:8069'
;
$connexion
=
new
xmlrpc_client($server_url
.
"/xmlrpc/common"
);
$connexion
->
setSSLVerifyPeer(0
);
$c_msg
=
new
xmlrpcmsg('login'
);
$c_msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($user
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$c_response
=
$connexion
->
send($c_msg
);
if
($c_response
->
errno !=
0
){
echo '<p>error : '
.
$c_response
->
faultString() .
'</p>'
;
}
else
{
$uid
=
$c_response
->
value()->
scalarval();
$domain_filter
=
array
(
new
xmlrpcval(
array
(new
xmlrpcval('name'
,
"string"
),
new
xmlrpcval('ilike'
,
"string"
),
new
xmlrpcval('godin'
,
"string"
)
),
"array"
),
);
$client
=
new
xmlrpc_client($server_url
.
"/xmlrpc/object"
);
$client
->
setSSLVerifyPeer(0
);
$msg
=
new
xmlrpcmsg('execute'
);
$msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$msg
->
addParam(new
xmlrpcval($uid
,
"int"
));
$msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$msg
->
addParam(new
xmlrpcval("res.partner"
,
"string"
));
$msg
->
addParam(new
xmlrpcval("search"
,
"string"
));
$msg
->
addParam(new
xmlrpcval($domain_filter
,
"array"
));
$response
=
$client
->
send($msg
);
$result
=
$response
->
value();
$ids
=
$result
->
scalarval();
$id_list
=
array
();
for
($i
=
0
;
$i
<
count($ids
);
$i
++
){
$id_list
[]=
new
xmlrpcval($ids
[
$i
]->
me[
'int'
],
'int'
);
}
$msg
=
new
xmlrpcmsg('execute'
);
$msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$msg
->
addParam(new
xmlrpcval($uid
,
"int"
));
$msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$msg
->
addParam(new
xmlrpcval("res.partner"
,
"string"
));
$msg
->
addParam(new
xmlrpcval("unlink"
,
"string"
));
$msg
->
addParam(new
xmlrpcval($id_list
,
"array"
));
$resp
=
$client
->
send($msg
);
if
($resp
->
faultCode()){
echo $resp
->
faultString();
}
echo '<h2>Liste des id des partners qui ont été supprimés:</h2>'
;
for
($i
=
0
;
$i
<
count($id_list
);
$i
++
){
echo '<li><strong>ID</strong> : '
.
$id_list
[
$i
]->
me[
'int'
]
.
'</li>'
;
}
}
?>
Évidemment, on n'est pas obligé d'utiliser la méthode search() si on connaît les ID des enregistrements à lire/modifier/supprimer.
XIV. La méthode write()▲
Voici maintenant la méthode write().
Dans l'exemple ci-dessous, je n'utilise pas la méthode search(), on part du principe que je connais l'ID de l'enregistrement que je veux modifier.
<
meta http-
equiv=
"
Content-Type
"
content=
"
text/html; charset=utf-8
"
/>
<?php
echo '<h2>XML-RPC AVEC OPENERP/ODOO ET PHP</h2>'
;
include("xmlrpc_lib/xmlrpc.inc.php"
);
include("xmlrpc_lib/xmlrpcs.inc.php"
);
$GLOBALS
[
'xmlrpc_internalencoding'
]=
'UTF-8'
;
$user
=
'admin'
;
$password
=
'mY5up3rPwd'
;
$dbname
=
'test'
;
$server_url
=
'http://192.168.1.120:8069'
;
$connexion
=
new
xmlrpc_client($server_url
.
"/xmlrpc/common"
);
$connexion
->
setSSLVerifyPeer(0
);
$c_msg
=
new
xmlrpcmsg('login'
);
$c_msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($user
,
"string"
));
$c_msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$c_response
=
$connexion
->
send($c_msg
);
if
($c_response
->
errno !=
0
){
echo '<p>error : '
.
$c_response
->
faultString() .
'</p>'
;
}
else
{
$uid
=
$c_response
->
value()->
scalarval();
$id_list
=
array
();
$id_list
[]=
new
xmlrpcval(89
,
'int'
);
$values
=
array
(
'street'
=>
new
xmlrpcval('Rue de la gare'
,
"string"
),
'city'
=>
new
xmlrpcval('Fontainebleau'
,
"string"
),
'zip'
=>
new
xmlrpcval('77120'
,
"string"
)
);
$client
=
new
xmlrpc_client($server_url
.
"/xmlrpc/object"
);
$client
->
setSSLVerifyPeer(0
);
$msg
=
new
xmlrpcmsg('execute'
);
$msg
->
addParam(new
xmlrpcval($dbname
,
"string"
));
$msg
->
addParam(new
xmlrpcval($uid
,
"int"
));
$msg
->
addParam(new
xmlrpcval($password
,
"string"
));
$msg
->
addParam(new
xmlrpcval("res.partner"
,
"string"
));
$msg
->
addParam(new
xmlrpcval("write"
,
"string"
));
$msg
->
addParam(new
xmlrpcval($id_list
,
"array"
));
$msg
->
addParam(new
xmlrpcval($values
,
"struct"
));
$response
=
$client
->
send($msg
);
if
($response
->
faultCode()){
echo $response
->
faultString();
}
echo '<h2>Mise à jour effectuée</h2>'
;
}
?>
XV. Et après ???▲
Eh bien après, il ne vous reste plus qu'à appeler n'importe quelle méthode de n'importe quel module en faisant attention à passer les paramètres attendus.
Lorsque vous appelez une méthode via XML-RPC , celles-ci sont exécutées dans les mêmes conditions que lorsqu'elles sont appelées depuis l'interface d'Odoo. Ainsi une méthode peut échouer si l'utilisateur n'a pas les droits suffisants.
Ici, pour le tutoriel, j'ai utilisé l'utilisateur « admin », mais, pour des raisons de sécurité, je vous recommande de créer un utilisateur spécifique auquel vous aurez attribué seulement les droits suffisants pour exécuter les méthodes dont vous avez besoin et rien d'autre.
XVI. Téléchargement▲
Téléchargez les scripts ci-dessus : odoo_xmlrpc_php_files.zipodoo_xmlrpc_php_files.zip
XVII. Documentation▲
Vous trouverez de la documentation sur le site officiel.
Odoo: XML-RPC Web servicesOdoo: XML-RPC Web services
Cette documentation semble avoir été écrite pour OpenERP 6.2, mais elle fonctionne avec la version 7. Je n'ai pas encore testé avec la version 8 d'Odoo.
XVIII. Remerciements▲
Remerciements à OpenERP SA pour leur logiciel OdooOdoo/OpenERP.
Remerciements à Philippe DuvalPhilippe Duval pour ses conseils et corrections.