import.class.php 12 KB

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