import.class.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. <?php
  2. /* Copyright (C) 2011 Laurent Destailleur <eldy@users.sourceforge.net>
  3. * Copyright (C) 2016 Raphaël Doursenaud <rdoursenaud@gpcsolutions.fr>
  4. * Copyright (C) 2020 Ahmad Jamaly Rabib <rabib@metroworks.co.jp>
  5. *
  6. * This program is free software; you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation; either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. /**
  20. * \file htdocs/imports/class/import.class.php
  21. * \ingroup import
  22. * \brief File of class to manage imports
  23. */
  24. /**
  25. * Class to manage imports
  26. */
  27. class Import
  28. {
  29. public $array_import_module;
  30. public $array_import_perms;
  31. public $array_import_icon;
  32. public $array_import_code;
  33. public $array_import_label;
  34. public $array_import_tables;
  35. public $array_import_tables_creator;
  36. public $array_import_fields;
  37. public $array_import_fieldshidden;
  38. public $array_import_entities;
  39. public $array_import_regex;
  40. public $array_import_updatekeys;
  41. public $array_import_examplevalues;
  42. public $array_import_convertvalue;
  43. public $array_import_run_sql_after;
  44. /**
  45. * @var string Error code (or message)
  46. */
  47. public $error = '';
  48. /**
  49. * @var string[] Error codes (or messages)
  50. */
  51. public $errors = array();
  52. /**
  53. * Constructor
  54. *
  55. * @param DoliDB $db Database handler
  56. */
  57. public function __construct($db)
  58. {
  59. $this->db = $db;
  60. }
  61. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  62. /**
  63. * Load description int this->array_import_module, this->array_import_fields, ... of an importable dataset
  64. *
  65. * @param User $user Object user making import
  66. * @param string $filter Load a particular dataset only. Index will start to 0.
  67. * @return int <0 if KO, >0 if OK
  68. */
  69. public function load_arrays($user, $filter = '')
  70. {
  71. // phpcs:enable
  72. global $langs, $conf;
  73. dol_syslog(get_class($this)."::load_arrays user=".$user->id." filter=".$filter);
  74. $i = 0;
  75. require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
  76. $modulesdir = dolGetModulesDirs();
  77. // Load list of modules
  78. foreach ($modulesdir as $dir) {
  79. $handle = @opendir(dol_osencode($dir));
  80. if (!is_resource($handle)) {
  81. continue;
  82. }
  83. // Search module files
  84. while (($file = readdir($handle)) !== false) {
  85. if (!preg_match("/^(mod.*)\.class\.php/i", $file, $reg)) {
  86. continue;
  87. }
  88. $modulename = $reg[1];
  89. // Defined if module is enabled
  90. $enabled = true;
  91. $part = strtolower(preg_replace('/^mod/i', '', $modulename));
  92. // Adds condition for propal module
  93. if ($part === 'propale') {
  94. $part = 'propal';
  95. }
  96. if (empty($conf->$part->enabled)) {
  97. $enabled = false;
  98. }
  99. if (empty($enabled)) {
  100. continue;
  101. }
  102. // Init load class
  103. $file = $dir."/".$modulename.".class.php";
  104. $classname = $modulename;
  105. require_once $file;
  106. $module = new $classname($this->db);
  107. if (isset($module->import_code) && is_array($module->import_code)) {
  108. foreach ($module->import_code as $r => $value) {
  109. if ($filter && ($filter != $module->import_code[$r])) {
  110. continue;
  111. }
  112. // Test if permissions are ok
  113. /*$perm=$module->import_permission[$r][0];
  114. //print_r("$perm[0]-$perm[1]-$perm[2]<br>");
  115. if ($perm[2])
  116. {
  117. $bool=$user->rights->{$perm[0]}->{$perm[1]}->{$perm[2]};
  118. }
  119. else
  120. {
  121. $bool=$user->rights->{$perm[0]}->{$perm[1]};
  122. }
  123. if ($perm[0]=='user' && $user->admin) $bool=true;
  124. //print $bool." $perm[0]"."<br>";
  125. */
  126. // Load lang file
  127. $langtoload = $module->getLangFilesArray();
  128. if (is_array($langtoload)) {
  129. foreach ($langtoload as $key) {
  130. $langs->load($key);
  131. }
  132. }
  133. // Permission
  134. $this->array_import_perms[$i] = $user->rights->import->run;
  135. // Icon
  136. $this->array_import_icon[$i] = (isset($module->import_icon[$r]) ? $module->import_icon[$r] : $module->picto);
  137. // Code du dataset export
  138. $this->array_import_code[$i] = $module->import_code[$r];
  139. // Libelle du dataset export
  140. $this->array_import_label[$i] = $module->getImportDatasetLabel($r);
  141. // Array of tables to import (key=alias, value=tablename)
  142. $this->array_import_tables[$i] = $module->import_tables_array[$r];
  143. // Array of tables creator field to import (key=alias, value=creator field name)
  144. $this->array_import_tables_creator[$i] = (isset($module->import_tables_creator_array[$r]) ? $module->import_tables_creator_array[$r] : '');
  145. // Array of fields to import (key=field, value=label)
  146. $this->array_import_fields[$i] = $module->import_fields_array[$r];
  147. // Array of hidden fields to import (key=field, value=label)
  148. $this->array_import_fieldshidden[$i] = $module->import_fieldshidden_array[$r];
  149. // Tableau des entites a exporter (cle=champ, valeur=entite)
  150. $this->array_import_entities[$i] = $module->import_entities_array[$r];
  151. // Tableau des alias a exporter (cle=champ, valeur=alias)
  152. $this->array_import_regex[$i] = $module->import_regex_array[$r];
  153. // Array of columns allowed as UPDATE options
  154. $this->array_import_updatekeys[$i] = $module->import_updatekeys_array[$r];
  155. // Array of examples
  156. $this->array_import_examplevalues[$i] = $module->import_examplevalues_array[$r];
  157. // Tableau des regles de conversion d'une valeur depuis une autre source (cle=champ, valeur=tableau des regles)
  158. $this->array_import_convertvalue[$i] = (isset($module->import_convertvalue_array[$r]) ? $module->import_convertvalue_array[$r] : '');
  159. // Sql request to run after import
  160. $this->array_import_run_sql_after[$i] = (isset($module->import_run_sql_after_array[$r]) ? $module->import_run_sql_after_array[$r] : '');
  161. // Module
  162. $this->array_import_module[$i] = array('position_of_profile'=>($module->module_position.'-'.$module->import_code[$r]), 'module'=>$module);
  163. dol_syslog("Import loaded for module ".$modulename." with index ".$i.", dataset=".$module->import_code[$r].", nb of fields=".count($module->import_fields_array[$r]));
  164. $i++;
  165. }
  166. }
  167. }
  168. closedir($handle);
  169. }
  170. return 1;
  171. }
  172. // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
  173. /**
  174. * Build an import example file.
  175. * Arrays this->array_export_xxx are already loaded for required datatoexport
  176. *
  177. * @param string $model Name of import engine ('csv', ...)
  178. * @param string $headerlinefields Array of values for first line of example file
  179. * @param string $contentlinevalues Array of values for content line of example file
  180. * @param string $datatoimport Dataset to import
  181. * @return string <0 if KO, >0 if OK
  182. */
  183. public function build_example_file($model, $headerlinefields, $contentlinevalues, $datatoimport)
  184. {
  185. // phpcs:enable
  186. global $conf, $langs;
  187. $indice = 0;
  188. dol_syslog(get_class($this)."::build_example_file ".$model);
  189. // Creation de la classe d'import du model Import_XXX
  190. $dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
  191. $file = "import_".$model.".modules.php";
  192. $classname = "Import".$model;
  193. require_once $dir.$file;
  194. $objmodel = new $classname($this->db, $datatoimport);
  195. $outputlangs = $langs; // Lang for output
  196. $s = '';
  197. // Genere en-tete
  198. $s .= $objmodel->write_header_example($outputlangs);
  199. // Genere ligne de titre
  200. $s .= $objmodel->write_title_example($outputlangs, $headerlinefields);
  201. // Genere ligne de titre
  202. $s .= $objmodel->write_record_example($outputlangs, $contentlinevalues);
  203. // Genere pied de page
  204. $s .= $objmodel->write_footer_example($outputlangs);
  205. return $s;
  206. }
  207. /**
  208. * Save an export model in database
  209. *
  210. * @param User $user Object user that save
  211. * @return int <0 if KO, >0 if OK
  212. */
  213. public function create($user)
  214. {
  215. global $conf;
  216. dol_syslog("Import.class.php::create");
  217. // Check parameters
  218. if (empty($this->model_name)) {
  219. $this->error = 'ErrorWrongParameters'; return -1;
  220. }
  221. if (empty($this->datatoimport)) {
  222. $this->error = 'ErrorWrongParameters'; return -1;
  223. }
  224. if (empty($this->hexa)) {
  225. $this->error = 'ErrorWrongParameters'; return -1;
  226. }
  227. $this->db->begin();
  228. $sql = 'INSERT INTO '.MAIN_DB_PREFIX.'import_model (';
  229. $sql .= 'fk_user, label, type, field';
  230. $sql .= ')';
  231. $sql .= " VALUES (".($user->id > 0 ? $user->id : 0).", '".$this->db->escape($this->model_name)."', '".$this->db->escape($this->datatoimport)."', '".$this->db->escape($this->hexa)."')";
  232. dol_syslog(get_class($this)."::create", LOG_DEBUG);
  233. $resql = $this->db->query($sql);
  234. if ($resql) {
  235. $this->db->commit();
  236. return 1;
  237. } else {
  238. $this->error = $this->db->lasterror();
  239. $this->errno = $this->db->lasterrno();
  240. $this->db->rollback();
  241. return -1;
  242. }
  243. }
  244. /**
  245. * Load an import profil from database
  246. *
  247. * @param int $id Id of profil to load
  248. * @return int <0 if KO, >0 if OK
  249. */
  250. public function fetch($id)
  251. {
  252. $sql = 'SELECT em.rowid, em.field, em.label, em.type';
  253. $sql .= ' FROM '.MAIN_DB_PREFIX.'import_model as em';
  254. $sql .= ' WHERE em.rowid = '.((int) $id);
  255. dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
  256. $result = $this->db->query($sql);
  257. if ($result) {
  258. $obj = $this->db->fetch_object($result);
  259. if ($obj) {
  260. $this->id = $obj->rowid;
  261. $this->hexa = $obj->field;
  262. $this->model_name = $obj->label;
  263. $this->datatoimport = $obj->type;
  264. $this->fk_user = $obj->fk_user;
  265. return 1;
  266. } else {
  267. $this->error = "Model not found";
  268. return -2;
  269. }
  270. } else {
  271. dol_print_error($this->db);
  272. return -3;
  273. }
  274. }
  275. /**
  276. * Delete object in database
  277. *
  278. * @param User $user User that delete
  279. * @param int $notrigger 0=launch triggers after, 1=disable triggers
  280. * @return int <0 if KO, >0 if OK
  281. */
  282. public function delete($user, $notrigger = 0)
  283. {
  284. global $conf, $langs;
  285. $error = 0;
  286. $sql = "DELETE FROM ".MAIN_DB_PREFIX."import_model";
  287. $sql .= " WHERE rowid=".$this->id;
  288. $this->db->begin();
  289. dol_syslog(get_class($this)."::delete", LOG_DEBUG);
  290. $resql = $this->db->query($sql);
  291. if (!$resql) {
  292. $error++; $this->errors[] = "Error ".$this->db->lasterror();
  293. }
  294. if (!$error) {
  295. if (!$notrigger) {
  296. /* Not used. This is not a business object. To convert it we must herit from CommonObject
  297. // Call trigger
  298. $result=$this->call_trigger('IMPORT_DELETE',$user);
  299. if ($result < 0) $error++;
  300. // End call triggers
  301. */
  302. }
  303. }
  304. // Commit or rollback
  305. if ($error) {
  306. foreach ($this->errors as $errmsg) {
  307. dol_syslog(get_class($this)."::delete ".$errmsg, LOG_ERR);
  308. $this->error .= ($this->error ? ', '.$errmsg : $errmsg);
  309. }
  310. $this->db->rollback();
  311. return -1 * $error;
  312. } else {
  313. $this->db->commit();
  314. return 1;
  315. }
  316. }
  317. }