export.class.php 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838
  1. <?php
  2. /* Copyright (C) 2005-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
  4. * Copyright (C) 2012 Charles-Fr BENKE <charles.fr@benke.fr>
  5. * Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
  6. *
  7. * This program is free software; you can redistribute it and/or modify
  8. * it under the terms of the GNU General Public License as published by
  9. * the Free Software Foundation; either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * This program is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  15. * GNU General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /**
  21. * \file htdocs/exports/class/export.class.php
  22. * \ingroup export
  23. * \brief File of class to manage exports
  24. */
  25. /**
  26. * Class to manage exports
  27. */
  28. class Export
  29. {
  30. var $db;
  31. var $array_export_code=array(); // Tableau de "idmodule_numlot"
  32. var $array_export_module=array(); // Tableau de "nom de modules"
  33. var $array_export_label=array(); // Tableau de "libelle de lots"
  34. var $array_export_sql_start=array(); // Tableau des "requetes sql"
  35. var $array_export_sql_end=array(); // Tableau des "requetes sql"
  36. var $array_export_sql_order=array(); // Tableau des "requetes sql"
  37. var $array_export_fields=array(); // Tableau des listes de champ+libelle a exporter
  38. var $array_export_TypeFields=array(); // Tableau des listes de champ+Type de filtre
  39. var $array_export_FilterValue=array(); // Tableau des listes de champ+Valeur a filtrer
  40. var $array_export_entities=array(); // Tableau des listes de champ+alias a exporter
  41. var $array_export_dependencies=array(); // array of list of entities that must take care of the DISTINCT if a field is added into export
  42. var $array_export_special=array(); // Tableau des operations speciales sur champ
  43. var $array_export_examplevalues=array(); // array with examples
  44. // To store export modules
  45. var $hexa;
  46. var $hexafiltervalue;
  47. var $datatoexport;
  48. var $model_name;
  49. var $sqlusedforexport;
  50. /**
  51. * Constructor
  52. *
  53. * @param DoliDB $db Database handler
  54. */
  55. function __construct($db)
  56. {
  57. $this->db=$db;
  58. }
  59. /**
  60. * Load an exportable dataset
  61. *
  62. * @param User $user Object user making export
  63. * @param string $filter Load a particular dataset only
  64. * @return int <0 if KO, >0 if OK
  65. */
  66. function load_arrays($user,$filter='')
  67. {
  68. global $langs,$conf,$mysoc;
  69. dol_syslog(get_class($this)."::load_arrays user=".$user->id." filter=".$filter);
  70. $var=true;
  71. $i=0;
  72. // Define list of modules directories into modulesdir
  73. require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
  74. $modulesdir = dolGetModulesDirs();
  75. foreach($modulesdir as $dir)
  76. {
  77. // Search available exports
  78. $handle=@opendir(dol_osencode($dir));
  79. if (is_resource($handle))
  80. {
  81. // Search module files
  82. while (($file = readdir($handle))!==false)
  83. {
  84. if (is_readable($dir.$file) && preg_match("/^(mod.*)\.class\.php$/i",$file,$reg))
  85. {
  86. $modulename=$reg[1];
  87. // Defined if module is enabled
  88. $enabled=true;
  89. $part=strtolower(preg_replace('/^mod/i','',$modulename));
  90. if ($part == 'propale') $part='propal';
  91. if (empty($conf->$part->enabled)) $enabled=false;
  92. if ($enabled)
  93. {
  94. // Loading Class
  95. $file = $dir.$modulename.".class.php";
  96. $classname = $modulename;
  97. require_once $file;
  98. $module = new $classname($this->db);
  99. if (isset($module->export_code) && is_array($module->export_code))
  100. {
  101. foreach($module->export_code as $r => $value)
  102. {
  103. //print $i.'-'.$filter.'-'.$modulename.'-'.join(',',$module->export_code).'<br>';
  104. if ($filter && ($filter != $module->export_code[$r])) continue;
  105. // Test if condition to show are ok
  106. if (! empty($module->export_enabled[$r]) && ! verifCond($module->export_enabled[$r])) continue;
  107. // Test if permissions are ok
  108. $bool=true;
  109. foreach($module->export_permission[$r] as $val)
  110. {
  111. $perm=$val;
  112. //print_r("$perm[0]-$perm[1]-$perm[2]<br>");
  113. if (! empty($perm[2]))
  114. {
  115. $bool=$user->rights->{$perm[0]}->{$perm[1]}->{$perm[2]};
  116. }
  117. else
  118. {
  119. $bool=$user->rights->{$perm[0]}->{$perm[1]};
  120. }
  121. if ($perm[0]=='user' && $user->admin) $bool=true;
  122. if (! $bool) break;
  123. }
  124. //print $bool." $perm[0]"."<br>";
  125. // Permissions ok
  126. // if ($bool)
  127. // {
  128. // Charge fichier lang en rapport
  129. $langtoload=$module->getLangFilesArray();
  130. if (is_array($langtoload))
  131. {
  132. foreach($langtoload as $key)
  133. {
  134. $langs->load($key);
  135. }
  136. }
  137. // Module
  138. $this->array_export_module[$i]=$module;
  139. // Permission
  140. $this->array_export_perms[$i]=$bool;
  141. // Icon
  142. $this->array_export_icon[$i]=(isset($module->export_icon[$r])?$module->export_icon[$r]:$module->picto);
  143. // Code du dataset export
  144. $this->array_export_code[$i]=$module->export_code[$r];
  145. // Libelle du dataset export
  146. $this->array_export_label[$i]=$module->getExportDatasetLabel($r);
  147. // Tableau des champ a exporter (cle=champ, valeur=libelle)
  148. $this->array_export_fields[$i]=$module->export_fields_array[$r];
  149. // Tableau des champs a filtrer (cle=champ, valeur1=type de donnees) on verifie que le module a des filtres
  150. $this->array_export_TypeFields[$i]=(isset($module->export_TypeFields_array[$r])?$module->export_TypeFields_array[$r]:'');
  151. // Tableau des entites a exporter (cle=champ, valeur=entite)
  152. $this->array_export_entities[$i]=$module->export_entities_array[$r];
  153. // Tableau des entites qui requiert abandon du DISTINCT (cle=entite, valeur=champ id child records)
  154. $this->array_export_dependencies[$i]=(! empty($module->export_dependencies_array[$r])?$module->export_dependencies_array[$r]:'');
  155. // Tableau des operations speciales sur champ
  156. $this->array_export_special[$i]=(! empty($module->export_special_array[$r])?$module->export_special_array[$r]:'');
  157. // Array of examples
  158. $this->array_export_examplevalues[$i]=$module->export_examplevalues_array[$r];
  159. // Requete sql du dataset
  160. $this->array_export_sql_start[$i]=$module->export_sql_start[$r];
  161. $this->array_export_sql_end[$i]=$module->export_sql_end[$r];
  162. $this->array_export_sql_order[$i]=$module->export_sql_order[$r];
  163. //$this->array_export_sql[$i]=$module->export_sql[$r];
  164. dol_syslog(get_class($this)."::load_arrays loaded for module ".$modulename." with index ".$i.", dataset=".$module->export_code[$r].", nb of fields=".(! empty($module->export_fields_code[$r])?count($module->export_fields_code[$r]):''));
  165. $i++;
  166. // }
  167. }
  168. }
  169. }
  170. }
  171. }
  172. closedir($handle);
  173. }
  174. }
  175. return 1;
  176. }
  177. /**
  178. * Build the sql export request.
  179. * Arrays this->array_export_xxx are already loaded for required datatoexport
  180. *
  181. * @param int $indice Indice of export
  182. * @param array $array_selected Filter fields on array of fields to export
  183. * @param array $array_filterValue Filter records on array of value for fields
  184. * @return string SQL String. Example "select s.rowid as r_rowid, s.status as s_status from ..."
  185. */
  186. function build_sql($indice, $array_selected, $array_filterValue)
  187. {
  188. // Build the sql request
  189. $sql=$this->array_export_sql_start[$indice];
  190. $i=0;
  191. //print_r($array_selected);
  192. foreach ($this->array_export_fields[$indice] as $key => $value)
  193. {
  194. if (! array_key_exists($key, $array_selected)) continue; // Field not selected
  195. if ($i > 0) $sql.=', ';
  196. else $i++;
  197. if (strpos($key, ' as ')===false) {
  198. $newfield=$key.' as '.str_replace(array('.', '-','(',')'),'_',$key);
  199. } else {
  200. $newfield=$key;
  201. }
  202. $sql.=$newfield;
  203. }
  204. $sql.=$this->array_export_sql_end[$indice];
  205. // Add the WHERE part. Filtering into sql if a filtering array is provided
  206. if (is_array($array_filterValue) && !empty($array_filterValue))
  207. {
  208. $sqlWhere='';
  209. // Loop on each condition to add
  210. foreach ($array_filterValue as $key => $value)
  211. {
  212. if (preg_match('/GROUP_CONCAT/i', $key)) continue;
  213. if ($value != '') $sqlWhere.=" and ".$this->build_filterQuery($this->array_export_TypeFields[$indice][$key], $key, $array_filterValue[$key]);
  214. }
  215. $sql.=$sqlWhere;
  216. }
  217. // Add the order
  218. $sql.=$this->array_export_sql_order[$indice];
  219. // Add the HAVING part.
  220. if (is_array($array_filterValue) && !empty($array_filterValue))
  221. {
  222. // Loop on each condition to add
  223. foreach ($array_filterValue as $key => $value)
  224. {
  225. if (preg_match('/GROUP_CONCAT/i', $key) and $value != '') $sql.=" HAVING ".$this->build_filterQuery($this->array_export_TypeFields[$indice][$key], $key, $array_filterValue[$key]);
  226. }
  227. }
  228. return $sql;
  229. }
  230. /**
  231. * Build the conditionnal string from filter the query
  232. *
  233. * @param string $TypeField Type of Field to filter
  234. * @param string $NameField Name of the field to filter
  235. * @param string $ValueField Value of the field for filter. Must not be ''
  236. * @return string sql string of then field ex : "field='xxx'>"
  237. */
  238. function build_filterQuery($TypeField, $NameField, $ValueField)
  239. {
  240. //print $TypeField." ".$NameField." ".$ValueField;
  241. $InfoFieldList = explode(":", $TypeField);
  242. // build the input field on depend of the type of file
  243. switch ($InfoFieldList[0]) {
  244. case 'Text':
  245. if (! (strpos($ValueField, '%') === false))
  246. $szFilterQuery.=" ".$NameField." LIKE '".$ValueField."'";
  247. else
  248. $szFilterQuery.=" ".$NameField."='".$ValueField."'";
  249. break;
  250. case 'Date':
  251. if (strpos($ValueField, "+") > 0)
  252. {
  253. // mode plage
  254. $ValueArray = explode("+", $ValueField);
  255. $szFilterQuery ="(".$this->conditionDate($NameField,$ValueArray[0],">=");
  256. $szFilterQuery.=" AND ".$this->conditionDate($NameField,$ValueArray[1],"<=").")";
  257. }
  258. else
  259. {
  260. if (is_numeric(substr($ValueField,0,1)))
  261. $szFilterQuery=$this->conditionDate($NameField,$ValueField,"=");
  262. else
  263. $szFilterQuery=$this->conditionDate($NameField,substr($ValueField,1),substr($ValueField,0,1));
  264. }
  265. break;
  266. case 'Duree':
  267. break;
  268. case 'Numeric':
  269. // si le signe -
  270. if (strpos($ValueField, "+") > 0)
  271. {
  272. // mode plage
  273. $ValueArray = explode("+", $ValueField);
  274. $szFilterQuery ="(".$NameField.">=".$ValueArray[0];
  275. $szFilterQuery.=" AND ".$NameField."<=".$ValueArray[1].")";
  276. }
  277. else
  278. {
  279. if (is_numeric(substr($ValueField,0,1)))
  280. $szFilterQuery=" ".$NameField."=".$ValueField;
  281. else
  282. $szFilterQuery=" ".$NameField.substr($ValueField,0,1).substr($ValueField,1);
  283. }
  284. break;
  285. case 'Boolean':
  286. $szFilterQuery=" ".$NameField."=".(is_numeric($ValueField) ? $ValueField : ($ValueField =='yes' ? 1: 0) );
  287. break;
  288. case 'Status':
  289. case 'List':
  290. if (is_numeric($ValueField))
  291. $szFilterQuery=" ".$NameField."=".$ValueField;
  292. else
  293. $szFilterQuery=" ".$NameField."='".$ValueField."'";
  294. break;
  295. default:
  296. dol_syslog("Error we try to forge an sql export request with a condition on a field with type '".$InfoFieldList[0]."' (defined into module descriptor) but this type is unknown/not supported. It looks like a bug into module descriptor.", LOG_ERROR);
  297. }
  298. return $szFilterQuery;
  299. }
  300. /**
  301. * conditionDate
  302. *
  303. * @param string $Field Field operand 1
  304. * @param string $Value Value operand 2
  305. * @param string $Sens Comparison operator
  306. * @return string
  307. */
  308. function conditionDate($Field, $Value, $Sens)
  309. {
  310. // TODO date_format is forbidden, not performant and not portable. Use instead BETWEEN
  311. if (strlen($Value)==4) $Condition=" date_format(".$Field.",'%Y') ".$Sens." '".$Value."'";
  312. elseif (strlen($Value)==6) $Condition=" date_format(".$Field.",'%Y%m') ".$Sens." '".$Value."'";
  313. else $Condition=" date_format(".$Field.",'%Y%m%d') ".$Sens." ".$Value;
  314. return $Condition;
  315. }
  316. /**
  317. * Build an input field used to filter the query
  318. *
  319. * @param string $TypeField Type of Field to filter. Example: Text, Date, List:c_country:label:rowid, List:c_stcom:label:code, Numeric or Number, Boolean
  320. * @param string $NameField Name of the field to filter
  321. * @param string $ValueField Initial value of the field to filter
  322. * @return string html string of the input field ex : "<input type=text name=... value=...>"
  323. */
  324. function build_filterField($TypeField, $NameField, $ValueField)
  325. {
  326. global $conf,$langs;
  327. $szFilterField='';
  328. $InfoFieldList = explode(":", $TypeField);
  329. // build the input field on depend of the type of file
  330. switch ($InfoFieldList[0])
  331. {
  332. case 'Text':
  333. case 'Date':
  334. $szFilterField='<input type="text" name="'.$NameField.'" value="'.$ValueField.'">';
  335. break;
  336. case 'Duree':
  337. case 'Numeric':
  338. case 'Number':
  339. case 'Status':
  340. if (! empty($conf->global->MAIN_ACTIVATE_HTML5)) $szFilterField='<input type="number" size="6" name="'.$NameField.'" value="'.$ValueField.'">';
  341. else $szFilterField='<input type="text" size="6" name="'.$NameField.'" value="'.$ValueField.'">';
  342. break;
  343. case 'Boolean':
  344. $szFilterField='<select name="'.$NameField.'" class="flat">';
  345. $szFilterField.='<option ';
  346. if ($ValueField=='') $szFilterField.=' selected ';
  347. $szFilterField.=' value="">&nbsp;</option>';
  348. $szFilterField.='<option ';
  349. if ($ValueField=='yes' || $ValueField == '1') $szFilterField.=' selected ';
  350. $szFilterField.=' value="1">'.yn(1).'</option>';
  351. $szFilterField.='<option ';
  352. if ($ValueField=='no' || $ValueField=='0') $szFilterField.=' selected ';
  353. $szFilterField.=' value="0">'.yn(0).'</option>';
  354. $szFilterField.="</select>";
  355. break;
  356. case 'List':
  357. // 0 : Type du champ
  358. // 1 : Nom de la table
  359. // 2 : Nom du champ contenant le libelle
  360. // 3 : Name of field with key (if it is not "rowid"). Used this field as key for combo list.
  361. if (count($InfoFieldList)==4)
  362. $keyList=$InfoFieldList[3];
  363. else
  364. $keyList='rowid';
  365. $sql = 'SELECT '.$keyList.' as rowid, '.$InfoFieldList[2].' as label'.(empty($InfoFieldList[3])?'':', '.$InfoFieldList[3].' as code');
  366. if ($InfoFieldList[1] == 'c_stcomm') $sql = 'SELECT id as id, '.$keyList.' as rowid, '.$InfoFieldList[2].' as label'.(empty($InfoFieldList[3])?'':', '.$InfoFieldList[3].' as code');
  367. if ($InfoFieldList[1] == 'c_country') $sql = 'SELECT '.$keyList.' as rowid, '.$InfoFieldList[2].' as label, code as code';
  368. $sql.= ' FROM '.MAIN_DB_PREFIX .$InfoFieldList[1];
  369. $resql = $this->db->query($sql);
  370. if ($resql)
  371. {
  372. $szFilterField='<select class="flat" name="'.$NameField.'">';
  373. $szFilterField.='<option value="0">&nbsp;</option>';
  374. $num = $this->db->num_rows($resql);
  375. $i = 0;
  376. if ($num)
  377. {
  378. while ($i < $num)
  379. {
  380. $obj = $this->db->fetch_object($resql);
  381. if ($obj->label == '-')
  382. {
  383. // Discard entry '-'
  384. $i++;
  385. continue;
  386. }
  387. //var_dump($InfoFieldList[1]);
  388. $labeltoshow=dol_trunc($obj->label,18);
  389. if ($InfoFieldList[1] == 'c_stcomm')
  390. {
  391. $langs->load("companies");
  392. $labeltoshow=(($langs->trans("StatusProspect".$obj->id) != "StatusProspect".$obj->id)?$langs->trans("StatusProspect".$obj->id):$obj->label);
  393. }
  394. if ($InfoFieldList[1] == 'c_country')
  395. {
  396. //var_dump($sql);
  397. $langs->load("dict");
  398. $labeltoshow=(($langs->trans("Country".$obj->code) != "Country".$obj->code)?$langs->trans("Country".$obj->code):$obj->label);
  399. }
  400. if (!empty($ValueField) && $ValueField == $obj->rowid)
  401. {
  402. $szFilterField.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
  403. }
  404. else
  405. {
  406. $szFilterField.='<option value="'.$obj->rowid.'" >'.$labeltoshow.'</option>';
  407. }
  408. $i++;
  409. }
  410. }
  411. $szFilterField.="</select>";
  412. $this->db->free($resql);
  413. }
  414. else dol_print_error($this->db);
  415. break;
  416. }
  417. return $szFilterField;
  418. }
  419. /**
  420. * Build an input field used to filter the query
  421. *
  422. * @param string $TypeField Type of Field to filter
  423. * @return string html string of the input field ex : "<input type=text name=... value=...>"
  424. */
  425. function genDocFilter($TypeField)
  426. {
  427. global $langs;
  428. $szMsg='';
  429. $InfoFieldList = explode(":", $TypeField);
  430. // build the input field on depend of the type of file
  431. switch ($InfoFieldList[0]) {
  432. case 'Text':
  433. $szMsg= $langs->trans('ExportStringFilter');
  434. break;
  435. case 'Date':
  436. $szMsg = $langs->trans('ExportDateFilter');
  437. break;
  438. case 'Duree':
  439. break;
  440. case 'Numeric':
  441. $szMsg = $langs->trans('ExportNumericFilter');
  442. break;
  443. case 'Boolean':
  444. break;
  445. case 'List':
  446. break;
  447. }
  448. return $szMsg;
  449. }
  450. /**
  451. * Build export file.
  452. * File is built into directory $conf->export->dir_temp.'/'.$user->id
  453. * Arrays this->array_export_xxx are already loaded for required datatoexport
  454. *
  455. * @param User $user User that export
  456. * @param string $model Export format
  457. * @param string $datatoexport Name of dataset to export
  458. * @param array $array_selected Filter on array of fields to export
  459. * @param array $array_filterValue Filter on array of fields with a filter
  460. * @param string $sqlquery If set, transmit the sql request for select (otherwise, sql request is generated from arrays)
  461. * @return int <0 if KO, >0 if OK
  462. */
  463. function build_file($user, $model, $datatoexport, $array_selected, $array_filterValue, $sqlquery = '')
  464. {
  465. global $conf,$langs;
  466. $indice=0;
  467. asort($array_selected);
  468. dol_syslog(get_class($this)."::".__FUNCTION__." ".$model.", ".$datatoexport.", ".implode(",", $array_selected));
  469. // Check parameters or context properties
  470. if (empty($this->array_export_fields) || ! is_array($this->array_export_fields))
  471. {
  472. $this->error="ErrorBadParameter";
  473. return -1;
  474. }
  475. // Creation de la classe d'export du model ExportXXX
  476. $dir = DOL_DOCUMENT_ROOT . "/core/modules/export/";
  477. $file = "export_".$model.".modules.php";
  478. $classname = "Export".$model;
  479. require_once $dir.$file;
  480. $objmodel = new $classname($this->db);
  481. if (! empty($sqlquery)) $sql = $sqlquery;
  482. else
  483. {
  484. // Define value for indice from $datatoexport
  485. $foundindice=0;
  486. foreach($this->array_export_code as $key => $dataset)
  487. {
  488. if ($datatoexport == $dataset)
  489. {
  490. $indice=$key;
  491. $foundindice++;
  492. //print "Found indice = ".$indice." for dataset=".$datatoexport."\n";
  493. break;
  494. }
  495. }
  496. if (empty($foundindice))
  497. {
  498. $this->error="ErrorBadParameter can't find dataset ".$datatoexport." into preload arrays this->array_export_code";
  499. return -1;
  500. }
  501. $sql=$this->build_sql($indice, $array_selected, $array_filterValue);
  502. }
  503. // Run the sql
  504. $this->sqlusedforexport=$sql;
  505. dol_syslog(get_class($this)."::".__FUNCTION__."", LOG_DEBUG);
  506. $resql = $this->db->query($sql);
  507. if ($resql)
  508. {
  509. //$this->array_export_label[$indice]
  510. if ($conf->global->EXPORT_PREFIX_SPEC)
  511. $filename=$conf->global->EXPORT_PREFIX_SPEC."_".$datatoexport;
  512. else
  513. $filename="export_".$datatoexport;
  514. $filename.='.'.$objmodel->getDriverExtension();
  515. $dirname=$conf->export->dir_temp.'/'.$user->id;
  516. $outputlangs = clone $langs; // We clone to have an object we can modify (for example to change output charset by csv handler) without changing original value
  517. // Open file
  518. dol_mkdir($dirname);
  519. $result=$objmodel->open_file($dirname."/".$filename, $outputlangs);
  520. if ($result >= 0)
  521. {
  522. // Genere en-tete
  523. $objmodel->write_header($outputlangs);
  524. // Genere ligne de titre
  525. $objmodel->write_title($this->array_export_fields[$indice],$array_selected,$outputlangs,$this->array_export_TypeFields[$indice]);
  526. $var=true;
  527. while ($objp = $this->db->fetch_object($resql))
  528. {
  529. $var=!$var;
  530. // Process special operations
  531. if (! empty($this->array_export_special[$indice]))
  532. {
  533. foreach ($this->array_export_special[$indice] as $key => $value)
  534. {
  535. if (! array_key_exists($key, $array_selected)) continue; // Field not selected
  536. // Operation NULLIFNEG
  537. if ($this->array_export_special[$indice][$key]=='NULLIFNEG')
  538. {
  539. //$alias=$this->array_export_alias[$indice][$key];
  540. $alias=str_replace(array('.', '-','(',')'),'_',$key);
  541. if ($objp->$alias < 0) $objp->$alias='';
  542. }
  543. // Operation ZEROIFNEG
  544. if ($this->array_export_special[$indice][$key]=='ZEROIFNEG')
  545. {
  546. //$alias=$this->array_export_alias[$indice][$key];
  547. $alias=str_replace(array('.', '-','(',')'),'_',$key);
  548. if ($objp->$alias < 0) $objp->$alias='0';
  549. }
  550. }
  551. }
  552. // end of special operation processing
  553. $objmodel->write_record($array_selected,$objp,$outputlangs,$this->array_export_TypeFields[$indice]);
  554. }
  555. // Genere en-tete
  556. $objmodel->write_footer($outputlangs);
  557. // Close file
  558. $objmodel->close_file();
  559. return 1;
  560. }
  561. else
  562. {
  563. $this->error=$objmodel->error;
  564. dol_syslog("Export::build_file Error: ".$this->error, LOG_ERR);
  565. return -1;
  566. }
  567. }
  568. else
  569. {
  570. $this->error=$this->db->error()." - sql=".$sql;
  571. return -1;
  572. }
  573. }
  574. /**
  575. * Save an export model in database
  576. *
  577. * @param User $user Object user that save
  578. * @return int <0 if KO, >0 if OK
  579. */
  580. function create($user)
  581. {
  582. global $conf;
  583. dol_syslog("Export.class.php::create");
  584. $this->db->begin();
  585. $filter='';
  586. $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'export_model (';
  587. $sql.= 'label,';
  588. $sql.= 'type,';
  589. $sql.= 'field,';
  590. $sql.= 'filter';
  591. $sql.= ') VALUES (';
  592. $sql.= "'".$this->db->escape($this->model_name)."',";
  593. $sql.= "'".$this->db->escape($this->datatoexport)."',";
  594. $sql.= "'".$this->db->escape($this->hexa)."',";
  595. $sql.= "'".$this->db->escape($this->hexafiltervalue)."'";
  596. $sql.= ")";
  597. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  598. $resql=$this->db->query($sql);
  599. if ($resql)
  600. {
  601. $this->db->commit();
  602. return 1;
  603. }
  604. else
  605. {
  606. $this->error=$this->db->lasterror();
  607. $this->errno=$this->db->lasterrno();
  608. $this->db->rollback();
  609. return -1;
  610. }
  611. }
  612. /**
  613. * Load an export profil from database
  614. *
  615. * @param int $id Id of profil to load
  616. * @return int <0 if KO, >0 if OK
  617. */
  618. function fetch($id)
  619. {
  620. $sql = 'SELECT em.rowid, em.label, em.type, em.field, em.filter';
  621. $sql.= ' FROM '.MAIN_DB_PREFIX.'export_model as em';
  622. $sql.= ' WHERE em.rowid = '.$id;
  623. dol_syslog("Export::fetch", LOG_DEBUG);
  624. $result = $this->db->query($sql);
  625. if ($result)
  626. {
  627. $obj = $this->db->fetch_object($result);
  628. if ($obj)
  629. {
  630. $this->id = $obj->rowid;
  631. $this->model_name = $obj->label;
  632. $this->datatoexport = $obj->type;
  633. $this->hexa = $obj->field;
  634. $this->hexafiltervalue = $obj->filter;
  635. return 1;
  636. }
  637. else
  638. {
  639. $this->error="ModelNotFound";
  640. return -2;
  641. }
  642. }
  643. else
  644. {
  645. dol_print_error($this->db);
  646. return -3;
  647. }
  648. }
  649. /**
  650. * Delete object in database
  651. *
  652. * @param User $user User that delete
  653. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  654. * @return int <0 if KO, >0 if OK
  655. */
  656. function delete($user, $notrigger=0)
  657. {
  658. global $conf, $langs;
  659. $error=0;
  660. $sql = "DELETE FROM ".MAIN_DB_PREFIX."export_model";
  661. $sql.= " WHERE rowid=".$this->id;
  662. $this->db->begin();
  663. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  664. $resql = $this->db->query($sql);
  665. if (! $resql) { $error++; $this->errors[]="Error ".$this->db->lasterror(); }
  666. if (! $error)
  667. {
  668. if (! $notrigger)
  669. {
  670. // Uncomment this and change MYOBJECT to your own tag if you
  671. // want this action call a trigger.
  672. //// Call triggers
  673. //include_once DOL_DOCUMENT_ROOT . '/core/class/interfaces.class.php';
  674. //$interface=new Interfaces($this->db);
  675. //$result=$interface->run_triggers('MYOBJECT_DELETE',$this,$user,$langs,$conf);
  676. //if ($result < 0) { $error++; $this->errors=$interface->errors; }
  677. //// End call triggers
  678. }
  679. }
  680. // Commit or rollback
  681. if ($error)
  682. {
  683. foreach($this->errors as $errmsg)
  684. {
  685. dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
  686. $this->error.=($this->error?', '.$errmsg:$errmsg);
  687. }
  688. $this->db->rollback();
  689. return -1*$error;
  690. }
  691. else
  692. {
  693. $this->db->commit();
  694. return 1;
  695. }
  696. }
  697. /**
  698. * Output list all export models
  699. * TODO Move this into a class htmlxxx.class.php
  700. *
  701. * @return void
  702. */
  703. function list_export_model()
  704. {
  705. global $conf, $langs;
  706. $sql = "SELECT em.rowid, em.field, em.label, em.type, em.filter";
  707. $sql.= " FROM ".MAIN_DB_PREFIX."export_model as em";
  708. $sql.= " ORDER BY rowid";
  709. $result = $this->db->query($sql);
  710. if ($result)
  711. {
  712. $num = $this->db->num_rows($result);
  713. $i = 0;
  714. while ($i < $num)
  715. {
  716. $obj = $this->db->fetch_object($result);
  717. $keyModel = array_search($obj->type, $this->array_export_code);
  718. print "<tr>";
  719. print '<td><a href=export.php?step=2&action=select_model&exportmodelid='.$obj->rowid.'&datatoexport='.$obj->type.'>'.$obj->label.'</a></td>';
  720. print '<td>';
  721. print img_object($this->array_export_module[$keyModel]->getName(),$this->array_export_icon[$keyModel]).' ';
  722. print $this->array_export_module[$keyModel]->getName().' - ';
  723. // recuperation du nom de l'export
  724. $string=$langs->trans($this->array_export_label[$keyModel]);
  725. print ($string!=$this->array_export_label[$keyModel]?$string:$this->array_export_label[$keyModel]);
  726. print '</td>';
  727. //print '<td>'.$obj->type.$keyModel.'</td>';
  728. print '<td>'.str_replace(',',' , ',$obj->field).'</td>';
  729. if (! empty($obj->filter)) {
  730. $filter = json_decode($obj->filter, true);
  731. print '<td>'.str_replace(',',' , ',$filter['field']).'</td>';
  732. print '<td>'.str_replace(',',' , ',$filter['value']).'</td>';
  733. }
  734. // suppression de l'export
  735. print '<td align="right">';
  736. print '<a href="'.$_SERVER["PHP_SELF"].'?action=deleteprof&id='.$obj->rowid.'">';
  737. print img_delete();
  738. print '</a>';
  739. print "</tr>";
  740. $i++;
  741. }
  742. }
  743. else {
  744. dol_print_error($this->db);
  745. }
  746. }
  747. }