[resolu] import de client dans dolibarr avec l'api

Bonjour

J’essaye d’ajouter des client à dolibarr2.7 en utilisant l’api depuis un autre site web

Mon site web fait donc appel à une fonction user_dolibarr_transmit()

dont le contenu est le suivant :

[code]
function user_dolibarr_transmit(){
require_once(« dolibarr/master.inc.php »);
require_once(DOL_DOCUMENT_ROOT."/cron/functions_cron.lib.php");
$langs->load(« main »);
$version=’$Revision: 1.16 $’;
$error=0;
require_once(DOL_DOCUMENT_ROOT."/user.class.php");
require_once(DOL_DOCUMENT_ROOT."/societe.class.php");
$user=new User($db);
$client=new Societe($db);
$user->id = 0;
// informations client //
$client->client=1;
$client->code_client=456;
$client->email="[email protected]";
$client->nom=« un autre test »;
$client->prenom=« nicolas »;
$client->adresse=« rue des babouins »;
$client->cp=« 49000 »;
$client->ville=« rennes »;
$client->tel=« 04324343 »;
$idclient = $client->create($user);
if ($idclient < 0) dol_print_error($db,$client->error);
if (! $error){
$db->commit();
print $db->error."\n";
print ‹ — end ok ›."\n";
}else{

	print '--- end error code='.$error."\n";
	$db->rollback();
}

$db->close();
return $error;
}[/code]

mais je suis confronté au probleme suivant :
la requete sql plante. la requete qui est réellement executé est la suivante :
INSERT INTO llx_societe (nom, entity, datec, datea, fk_user_creat) VALUES (‹ un autre test ›, , 20090828190529, 20090828190529, null)

le champ entity est donc vide.

en regardant de près j’ai vu que l’objet $conf perdait la plupart de ses valeurs dont entity au moment de l’appel à $client->create($user);

pourtant $conf est bien déclaré en tant que globale dans cette fonction
avec xdebug je vois que l’objet a bien toute ses valeurs avant et apres l’appel à la fonction mais qu’il n’a plus que pour valeur :

[code]
$conf =

object(stdClass)[64]
public ‹ format_date_short › => string ‹ %d/%m/%Y › (length=8)
public ‹ format_date_short_java › => string ‹ dd/MM/yyyy › (length=10)
public ‹ format_hour_short › => string ‹ %H:%M › (length=5)
public ‹ format_date_text_short › => string ‹ %d %b %Y › (length=8)
public ‹ format_date_text › => string ‹ %d %B %Y › (length=8)
public ‹ format_date_hour_short › => string ‹ %d/%m/%Y %H:%M › (length=14)
public ‹ format_date_hour_text_short › => string ‹ %d %b %Y %H:%M › (length=14)
public ‹ format_date_hour_text › => string ‹ %d %B %Y %H:%M › (length=14)
[/code] lors de l’appel au global dans le corp de la fonction create

en revanche, si je fais appel au script avec les même paramètres mais en ligne de commande l’import fonctionne

Il y a de quoi devenir fou :woohoo:
Je n’ai pas d’autre valeur ou objet $conf dans le site et il n’y a pas de raison qu’il perde des valeurs comme ca :confused:
Le bug doit probablement provenir de ma conf de php ou du site web puisque ça fonctionne en console mais je n’ai pas d’idée sur ce dont il peut s’agir exactement…
je suis ouvert à toute remarque/ propositions / aide puisqu’il s’agit un peu d’un SOS :unhappy:

ps: Je songe à l’occasion qu’il aurait peut être été préférable que dolibarr utilise des singletons/multitons dans la mesure du possible plutôt que des variables globales

Non, cela ne vient probablement pas de ta config mais plutot d’un bug dans l’implémentation de l’entity qui sert a gerer du multiinstance dolibarr et qui est mal implémenté.
Pour vérifier, j’ai fait une modif dans le CVS, peut tu retester avec le fichier
$Id: master.inc.php,v 1.257 2009/09/01 15:51:21 eldy Exp $

Si tu as tjs un pb, désactive le commentaire sur la ligne
//print "Will work with data…
et dis nous quelle valeur tu as pour conf->entity

Tu devrais avoir 1.

j’ai testé avec la version 1.258
j’ai toujours une erreur mais pas exactement au même endroit
si j’affiche la valeur de $conf->entity dans master.inc.php j’ai bien 1
de même si j’affiche la valeur avant ou apres le $client->create() dans le corp de ma fonction

en revanche dans la classe societe.class.php
si dans la fonction create je met :

function create($user='')
	{
		echo "avant globale";
		xdebug_var_dump($conf);
		global $langs,$conf;
		echo "apres globale";
		xdebug_var_dump($conf);

j’ai le resultat suivant :

avant globale null apres globale object(stdClass)[64] public 'format_date_short' => string '%d/%m/%Y' (length=8) public 'format_date_short_java' => string 'dd/MM/yyyy' (length=10) public 'format_hour_short' => string '%H:%M' (length=5) public 'format_date_text_short' => string '%d %b %Y' (length=8) public 'format_date_text' => string '%d %B %Y' (length=8) public 'format_date_hour_short' => string '%d/%m/%Y %H:%M' (length=14) public 'format_date_hour_text_short' => string '%d %b %Y %H:%M' (length=14) public 'format_date_hour_text' => string '%d %B %Y %H:%M' (length=14)

mon php.ini a pourtant bien le register_global à 1

xdebug me donne pour erreur :

[code]
" Warning: Invalid argument supplied for foreach() in /var/dolibarr/htdocs/translate.class.php on line 191 "

Translate->Load( string(4), ???, ??? ) …/functions.lib.php:1701[/code]

edit: autre nouveauté j’ai du coup dolibarr qui me remonte l’erreur :

DatabaseTypeManager: mysql
RequestLastAccessInError: SET NAMES ‹  ›
ReturnCodeLastAccessInError: DB_ERROR_1115
InformationLastAccessInError: Unknown character set: ‹  ›

sur la ligne : if ($idclient < 0) dol_print_error($db,$client->error);

update :
j’ai ecrit le script suivant :

require_once("dolibarr/master.inc.php");
require_once(DOL_DOCUMENT_ROOT."/cron/functions_cron.lib.php");
$langs->load("main");
$version='$Revision: 1.16 $';
	require_once(DOL_DOCUMENT_ROOT."/societe.class.php");
	$query="SELECT rowid FROM ".MAIN_DB_PREFIX."societe where code_client='42'";
	$client=new Societe($db);
	$resql = $db->query($query);
	if($resql){
		$row = $db->fetch_row($resql);
		$id =  $row[0];
		$client->fetch($id);

		$client->client=1;
		$client->code_client=42;
		$client->email="[email protected]";
		$client->nom="42 le sens de la vie";
		$client->prenom="prenom 42";
		$client->adresse="rue des babouins";
		$client->cp="49080";
		$client->ville="rennes";
		$client->tel="04324343";
		$client->pays_id="Fr";
		$result = $client->update($id);
	}
	else{
		$client->client=1;
		$client->code_client=42;
		$client->email="[email protected]";
		$client->nom="42 le sens de la vie";
		$client->prenom="prenom 42";
		$client->adresse="rue des babouins";
		$client->cp="49000";
		$client->ville="rennes";
		$client->tel="04324343";
		$client->pays_id="Fr";
		$result = $client->create();
	}
		if ($result>=0)
		{
			$db->commit();
			print '--- end ok'."\n";
		}
		else
		{
			print '--- end error code:'.$client->error."\n";
			$db->rollback();
		}
		$db->close();

si j’execute le script directement dans mon navigateur cela fonctionne bien.

si j’include le script à partir du site cela fonctionne également :

Je travaille sur un site qui s’appuie sur phpnuke
la page admin envoie une variable $op permettant de connaitre l’opération à effectuer
j’ai donc :

switch($op) {
	case "userdolibarr":
	include(myscript.php);
	Header("Location: admin.php?op=adminMain");
	break;

en revanche si je fais :

switch($op) {
	case "userdolibarr":
	user_dolibarr_transmit();
	Header("Location: admin.php?op=adminMain");
	break;

avec l’include de myscript.php dans la fonction user_dolibarr_transmit() cela ne fonctionne plus.

Il semble que l’api n’aime pas être appelée dans le contexte d’une fonction ?

( solution pour l’instant remplacer les fonctions par des includes… )

Edit: apparemment phpnuke utilise une variable $user , peut être que dolibarr recupère cette valeur en faisant un global $user au lieu de celle qu’il devrait?!

Si tu passes par un fonction user_dolibarr_transmet, pour assurer la propagation (descente et remontée) de $user de dolibarr, il faut inclure global $user dans ta fonction.
Il est conseillé de le faire pour
global $user, $lang, $conf

Après avoir fait un script pour renommer toutes mes variables $user de phpnuke:


<?php
   $path = realpath($argv[1]);
   $oRecursiveDirectoryIterator = new RecursiveDirectoryIterator($path);
   $oIt = new RecursiveIteratorIterator($oRecursiveDirectoryIterator, RecursiveIteratorIterator::SELF_FIRST);
   foreach($oIt as $iKey=>$oFile) {
        if(preg_match("/.php/" ,$oFile->getFilename())){
                if ($oFile->isWritable() && $oFile->isReadable()) {
                        $content = file_get_contents($oFile->__toString());
                        if(preg_match("/[$]user[^a-zA-Z1-9_]/", $content)){
                         preg_match_all("/[$]user[^a-zA-Z1-9_]/", $content,$array);
                                foreach($array['0'] as $key => $tochange){
                                        $content = str_replace("$tochange" , "\$user_phpnuke".substr($tochange,5,1),$content);
                                }
                                        $fileobj = $oFile->openFile('w');
                                        $fileobj->fwrite($content);

                        }
                }
   }
}
?>

Il semble que cela fonctionne si dans la fonction on utilise
global $user, $conf, $langs, $db;

($db est indispensable aussi)
comme tu disais
Je note le thread en résolu tant que le problème ne réapparait pas.

Edit: la balise code n’a pas l’air d’aimer le mien :unhappy: