dolibarr 21.0.0-alpha
import_xlsx.modules.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2006-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2009-2012 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
5 * Copyright (C) 2012-2016 Juanjo Menent <jmenent@2byte.es>
6 * Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
7 * Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 3 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <https://www.gnu.org/licenses/>.
21 * or see https://www.gnu.org/
22 */
23
30use PhpOffice\PhpSpreadsheet\Reader\Xlsx;
31use PhpOffice\PhpSpreadsheet\Spreadsheet;
32use PhpOffice\PhpSpreadsheet\Style\Alignment;
33use PhpOffice\PhpSpreadsheet\Shared\Date;
34
35require_once DOL_DOCUMENT_ROOT . '/core/modules/import/modules_import.php';
36
37
42{
46 public $db;
47
51 public $id;
52
57 public $version = 'dolibarr';
58
59 public $label_lib; // Label of external lib used by driver
60
61 public $version_lib; // Version of external lib used by driver
62
63 public $separator;
64
65 public $file; // Path of file
66
67 public $handle; // Handle fichier
68
69 public $cacheconvert = array(); // Array to cache list of value found after a conversion
70
71 public $cachefieldtable = array(); // Array to cache list of value found into fields@tables
72
73 public $nbinsert = 0; // # of insert done during the import
74
75 public $nbupdate = 0; // # of update done during the import
76
77 public $workbook; // temporary import file
78
79 public $record; // current record
80
81 public $headers;
82
83
90 public function __construct($db, $datatoimport)
91 {
92 global $langs;
93
94 parent::__construct();
95 $this->db = $db;
96
97 // this is used as an extension from the example file code, so we have to put xlsx here !!!
98 $this->id = 'xlsx'; // Same value as xxx in file name export_xxx.modules.php
99 $this->label = 'Excel 2007'; // Label of driver
100 $this->desc = $langs->trans("Excel2007FormatDesc");
101 $this->extension = 'xlsx'; // Extension for generated file by this driver
102 $this->picto = 'mime/xls'; // Picto (This is not used by the example file code as Mime type, too bad ...)
103 $this->version = '1.0'; // Driver version
104 $this->phpmin = array(7, 1); // Minimum version of PHP required by module
105
106 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
107 if (versioncompare($this->phpmin, versionphparray()) > 0) {
108 dol_syslog("Module need a higher PHP version");
109 $this->error = "Module need a higher PHP version";
110 return;
111 }
112
113 // If driver use an external library, put its name here
114 require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/autoloader.php';
115 require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
116 require_once PHPEXCELNEW_PATH.'Spreadsheet.php';
117 $this->workbook = new Spreadsheet();
118
119 // If driver use an external library, put its name here
120 if (!class_exists('ZipArchive')) { // For Excel2007
121 $langs->load("errors");
122 $this->error = $langs->trans('ErrorPHPNeedModule', 'zip');
123 return;
124 }
125 $this->label_lib = 'PhpSpreadSheet';
126 $this->version_lib = '1.8.0';
127
128 $this->datatoimport = $datatoimport;
129 if (preg_match('/^societe_/', $datatoimport)) {
130 $this->thirdpartyobject = new Societe($this->db);
131 }
132 }
133
134
135 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
142 public function write_header_example($outputlangs)
143 {
144 // phpcs:enable
145 global $user, $conf, $langs, $file;
146 // create a temporary object, the final output will be generated in footer
147 $this->workbook->getProperties()->setCreator($user->getFullName($outputlangs) . ' - Dolibarr ' . DOL_VERSION);
148 $this->workbook->getProperties()->setTitle($outputlangs->trans("Import") . ' - ' . $file);
149 $this->workbook->getProperties()->setSubject($outputlangs->trans("Import") . ' - ' . $file);
150 $this->workbook->getProperties()->setDescription($outputlangs->trans("Import") . ' - ' . $file);
151
152 $this->workbook->setActiveSheetIndex(0);
153 $this->workbook->getActiveSheet()->setTitle($outputlangs->trans("Sheet"));
154 $this->workbook->getActiveSheet()->getDefaultRowDimension()->setRowHeight(16);
155
156 return '';
157 }
158
159 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
167 public function write_title_example($outputlangs, $headerlinefields)
168 {
169 // phpcs:enable
170 global $conf;
171 $this->workbook->getActiveSheet()->getStyle('1')->getFont()->setBold(true);
172 $this->workbook->getActiveSheet()->getStyle('1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
173
174 $col = 1;
175 foreach ($headerlinefields as $field) {
176 $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, 1, $outputlangs->transnoentities($field));
177 // set autowidth
178 //$this->workbook->getActiveSheet()->getColumnDimension($this->column2Letter($col + 1))->setAutoSize(true);
179 $col++;
180 }
181
182 return ''; // final output will be generated in footer
183 }
184
185 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
193 public function write_record_example($outputlangs, $contentlinevalues)
194 {
195 // phpcs:enable
196 $col = 1;
197 $row = 2;
198 foreach ($contentlinevalues as $cell) {
199 $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, $row, $cell);
200 $col++;
201 }
202
203 return ''; // final output will be generated in footer
204 }
205
206 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
213 public function write_footer_example($outputlangs)
214 {
215 // phpcs:enable
216 // return the file content as a string
217 $tempfile = tempnam(sys_get_temp_dir(), 'dol');
218 $objWriter = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($this->workbook);
219 $objWriter->save($tempfile);
220 $this->workbook->disconnectWorksheets();
221 unset($this->workbook);
222
223 $content = file_get_contents($tempfile);
224 unlink($tempfile);
225 return $content;
226 }
227
228
229
230 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
237 public function import_open_file($file)
238 {
239 // phpcs:enable
240 global $langs;
241 $ret = 1;
242
243 dol_syslog(get_class($this) . "::open_file file=" . $file);
244
245 $reader = new Xlsx();
246 $this->workbook = $reader->load($file);
247 $this->record = 1;
248 $this->file = $file;
249
250 return $ret;
251 }
252
253
254 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
261 public function import_get_nb_of_lines($file)
262 {
263 // phpcs:enable
264 $reader = new Xlsx();
265 $this->workbook = $reader->load($file);
266
267 $rowcount = $this->workbook->getActiveSheet()->getHighestDataRow();
268
269 $this->workbook->disconnectWorksheets();
270 unset($this->workbook);
271
272 return $rowcount;
273 }
274
275
276 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
282 public function import_read_header()
283 {
284 // phpcs:enable
285 // This is not called by the import code !!!
286 $this->headers = array();
287 $xlsx = new Xlsx();
288 $info = $xlsx->listWorksheetinfo($this->file);
289 $countcolumns = $info[0]['totalColumns'];
290 for ($col = 1; $col <= $countcolumns; $col++) {
291 $this->headers[$col] = $this->workbook->getActiveSheet()->getCellByColumnAndRow($col, 1)->getValue();
292 }
293 return 0;
294 }
295
296
297 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
303 public function import_read_record()
304 {
305 // phpcs:enable
306 $rowcount = $this->workbook->getActiveSheet()->getHighestDataRow();
307 if ($this->record > $rowcount) {
308 return false;
309 }
310 $array = array();
311
312 $xlsx = new Xlsx();
313 $info = $xlsx->listWorksheetinfo($this->file);
314 $countcolumns = $info[0]['totalColumns'];
315
316 for ($col = 1; $col <= $countcolumns; $col++) {
317 $tmpcell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($col, $this->record);
318
319 $val = $tmpcell->getValue();
320
321 if (Date::isDateTime($tmpcell)) {
322 // For date field, we use the standard date format string.
323 $dateValue = Date::excelToDateTimeObject($val);
324 $val = $dateValue->format('Y-m-d H:i:s');
325 }
326
327 $array[$col]['val'] = $val;
328 $array[$col]['type'] = (dol_strlen($val) ? 1 : -1); // If empty we consider it null
329 }
330 $this->record++;
331
332 unset($xlsx);
333
334 return $array;
335 }
336
337 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
343 public function import_close_file()
344 {
345 // phpcs:enable
346 $this->workbook->disconnectWorksheets();
347 unset($this->workbook);
348 return 0;
349 }
350
351
352 // What is this doing here ? it is common to all imports, is should be in the parent class
353 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
365 public function import_insert($arrayrecord, $array_match_file_to_database, $objimport, $maxfields, $importid, $updatekeys)
366 {
367 // phpcs:enable
368 global $langs, $conf, $user;
369 global $thirdparty_static; // Specific to thirdparty import
370 global $tablewithentity_cache; // Cache to avoid to call desc at each rows on tables
371
372 $error = 0;
373 $warning = 0;
374 $this->errors = array();
375 $this->warnings = array();
376
377 //dol_syslog("import_csv.modules maxfields=".$maxfields." importid=".$importid);
378
379 //var_dump($array_match_file_to_database);
380 //var_dump($arrayrecord); exit;
381
382 $array_match_database_to_file = array_flip($array_match_file_to_database);
383 $sort_array_match_file_to_database = $array_match_file_to_database;
384 ksort($sort_array_match_file_to_database);
385
386 //var_dump($sort_array_match_file_to_database);
387
388 if (count($arrayrecord) == 0 || (count($arrayrecord) == 1 && empty($arrayrecord[1]['val']))) {
389 //print 'W';
390 $this->warnings[$warning]['lib'] = $langs->trans('EmptyLine');
391 $this->warnings[$warning]['type'] = 'EMPTY';
392 $warning++;
393 } else {
394 $last_insert_id_array = array(); // store the last inserted auto_increment id for each table, so that dependent tables can be inserted with the appropriate id (eg: extrafields fk_object will be set with the last inserted object's id)
395 $updatedone = false;
396 $insertdone = false;
397 // For each table to insert, me make a separate insert
398 foreach ($objimport->array_import_tables[0] as $alias => $tablename) {
399 // Build sql request
400 $sql = '';
401 $listfields = array();
402 $listvalues = array();
403 $i = 0;
404 $errorforthistable = 0;
405
406 // Define $tablewithentity_cache[$tablename] if not already defined
407 if (!isset($tablewithentity_cache[$tablename])) { // keep this test with "isset"
408 dol_syslog("Check if table " . $tablename . " has an entity field");
409 $resql = $this->db->DDLDescTable($tablename, 'entity');
410 if ($resql) {
411 $obj = $this->db->fetch_object($resql);
412 if ($obj) {
413 $tablewithentity_cache[$tablename] = 1; // table contains entity field
414 } else {
415 $tablewithentity_cache[$tablename] = 0; // table does not contain entity field
416 }
417 } else {
418 dol_print_error($this->db);
419 }
420 } else {
421 //dol_syslog("Table ".$tablename." check for entity into cache is ".$tablewithentity_cache[$tablename]);
422 }
423
424 // Define an array to convert fields ('c.ref', ...) into column index (1, ...)
425 $arrayfield = array();
426 foreach ($sort_array_match_file_to_database as $key => $val) {
427 $arrayfield[$val] = ($key);
428 }
429
430 // $arrayrecord start at key 1
431 // $sort_array_match_file_to_database start at key 1
432
433 // Loop on each fields in the match array: $key = 1..n, $val=alias of field (s.nom)
434 foreach ($sort_array_match_file_to_database as $key => $val) {
435 $fieldalias = preg_replace('/\..*$/i', '', $val);
436 $fieldname = preg_replace('/^.*\./i', '', $val);
437
438 if ($alias != $fieldalias) {
439 continue; // Not a field of current table
440 }
441
442 if ($key <= $maxfields) {
443 // Set $newval with value to insert and set $listvalues with sql request part for insert
444 $newval = '';
445 if ($arrayrecord[($key)]['type'] > 0) {
446 $newval = $arrayrecord[($key)]['val']; // If type of field into input file is not empty string (so defined into input file), we get value
447 }
448
449 //var_dump($newval);var_dump($val);
450 //var_dump($objimport->array_import_convertvalue[0][$val]);
451
452 // Make some tests on $newval
453
454 // Is it a required field ?
455 if (preg_match('/\*/', $objimport->array_import_fields[0][$val]) && ((string) $newval == '')) {
456 $this->errors[$error]['lib'] = $langs->trans('ErrorMissingMandatoryValue', num2Alpha($key - 1));
457 $this->errors[$error]['type'] = 'NOTNULL';
458 $errorforthistable++;
459 $error++;
460 } else {
461 // Test format only if field is not a missing mandatory field (field may be a value or empty but not mandatory)
462 // We convert field if required
463 if (!empty($objimport->array_import_convertvalue[0][$val])) {
464 //print 'Must convert '.$newval.' with rule '.join(',',$objimport->array_import_convertvalue[0][$val]).'. ';
465 if ($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeid'
466 || $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromref'
467 || $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeorlabel'
468 ) {
469 // New val can be an id or ref. If it start with id: it is forced to id, if it start with ref: it is forced to ref. It not, we try to guess.
470 $isidorref = 'id';
471 if (!is_numeric($newval) && $newval != '' && !preg_match('/^id:/i', $newval)) {
472 $isidorref = 'ref';
473 }
474 $newval = preg_replace('/^(id|ref):/i', '', $newval); // Remove id: or ref: that was used to force if field is id or ref
475 //print 'Newval is now "'.$newval.'" and is type '.$isidorref."<br>\n";
476
477 if ($isidorref == 'ref') { // If value into input import file is a ref, we apply the function defined into descriptor
478 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
479 $class = $objimport->array_import_convertvalue[0][$val]['class'];
480 $method = $objimport->array_import_convertvalue[0][$val]['method'];
481 if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_'][$newval] != '') {
482 $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_'][$newval];
483 } else {
484 $resultload = dol_include_once($file);
485 if (empty($resultload)) {
486 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
487 break;
488 }
489 $classinstance = new $class($this->db);
490 if ($class == 'CGenericDic') {
491 $classinstance->element = $objimport->array_import_convertvalue[0][$val]['element'];
492 $classinstance->table_element = $objimport->array_import_convertvalue[0][$val]['table_element'];
493 }
494
495 // Try the fetch from code or ref
496 $param_array = array('', $newval);
497 if ($class == 'AccountingAccount') {
498 //var_dump($arrayrecord[0]['val']);
499 /*include_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancysystem.class.php';
500 $tmpchartofaccount = new AccountancySystem($this->db);
501 $tmpchartofaccount->fetch(getDolGlobalInt('CHARTOFACCOUNTS'));
502 //var_dump($tmpchartofaccount->ref.' - '.$arrayrecord[0]['val']);
503 if ((! (getDolGlobalInt('CHARTOFACCOUNTS') > 0)) || $tmpchartofaccount->ref != $arrayrecord[0]['val'])
504 {
505 $this->errors[$error]['lib']=$langs->trans('ErrorImportOfChartLimitedToCurrentChart', $tmpchartofaccount->ref);
506 $this->errors[$error]['type']='RESTRICTONCURRENCTCHART';
507 $errorforthistable++;
508 $error++;
509 }*/
510 $param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart.
511 }
512
513 $result = call_user_func_array(array($classinstance, $method), $param_array);
514
515 // If duplicate record found
516 if (!($classinstance->id != '') && $result == -2) {
517 $this->errors[$error]['lib'] = $langs->trans('ErrorMultipleRecordFoundFromRef', $newval);
518 $this->errors[$error]['type'] = 'FOREIGNKEY';
519 $errorforthistable++;
520 $error++;
521 }
522
523 // If not found, try the fetch from label
524 if (!($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeorlabel') {
525 $param_array = array('', '', $newval);
526 call_user_func_array(array($classinstance, $method), $param_array);
527 }
528 $this->cacheconvert[$file . '_' . $class . '_' . $method . '_'][$newval] = $classinstance->id;
529
530 //print 'We have made a '.$class.'->'.$method.' to get id from code '.$newval.'. ';
531 if ($classinstance->id != '') { // id may be 0, it is a found value
532 $newval = $classinstance->id;
533 } elseif (! $error) {
534 if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
535 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
536 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
537 } elseif (!empty($objimport->array_import_convertvalue[0][$val]['element'])) {
538 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
539 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldRefNotIn', $key, $newval, $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['element']));
540 } else {
541 $this->errors[$error]['lib'] = 'ErrorBadDefinitionOfImportProfile';
542 }
543 $this->errors[$error]['type'] = 'FOREIGNKEY';
544 $errorforthistable++;
545 $error++;
546 }
547 }
548 }
549 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeandlabel') {
550 $isidorref = 'id';
551 if (!is_numeric($newval) && $newval != '' && !preg_match('/^id:/i', $newval)) {
552 $isidorref = 'ref';
553 }
554 $newval = preg_replace('/^(id|ref):/i', '', $newval);
555
556 if ($isidorref == 'ref') {
557 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
558 $class = $objimport->array_import_convertvalue[0][$val]['class'];
559 $method = $objimport->array_import_convertvalue[0][$val]['method'];
560 $codefromfield = $objimport->array_import_convertvalue[0][$val]['codefromfield'];
561 $code = $arrayrecord[$arrayfield[$codefromfield]]['val'];
562 if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] != '') {
563 $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval];
564 } else {
565 $resultload = dol_include_once($file);
566 if (empty($resultload)) {
567 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method . ', code=' . $code);
568 break;
569 }
570 $classinstance = new $class($this->db);
571 // Try the fetch from code and ref
572 $param_array = array('', $newval, $code);
573 call_user_func_array(array($classinstance, $method), $param_array);
574 $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] = $classinstance->id;
575 if ($classinstance->id > 0) { // we found record
576 $newval = $classinstance->id;
577 } else {
578 if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
579 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
580 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
581 } else {
582 $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn';
583 }
584 $this->errors[$error]['type'] = 'FOREIGNKEY';
585 $errorforthistable++;
586 $error++;
587 }
588 }
589 }
590 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'zeroifnull') {
591 if (empty($newval)) {
592 $newval = '0';
593 }
594 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeunits' || $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchscalefromcodeunits') {
595 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
596 $class = $objimport->array_import_convertvalue[0][$val]['class'];
597 $method = $objimport->array_import_convertvalue[0][$val]['method'];
598 $units = $objimport->array_import_convertvalue[0][$val]['units'];
599 if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $units][$newval] != '') {
600 $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $units][$newval];
601 } else {
602 $resultload = dol_include_once($file);
603 if (empty($resultload)) {
604 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method . ', units=' . $units);
605 break;
606 }
607 $classinstance = new $class($this->db);
608 // Try the fetch from code or ref
609 call_user_func_array(array($classinstance, $method), array('', '', $newval, $units));
610 $scaleorid = (($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeunits') ? $classinstance->id : $classinstance->scale);
611 $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $units][$newval] = $scaleorid;
612 //print 'We have made a '.$class.'->'.$method." to get a value from key '".$newval."' and we got '".$scaleorid."'.";exit;
613 if ($classinstance->id > 0) { // we found record
614 $newval = $scaleorid ? $scaleorid : 0;
615 } else {
616 if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
617 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
618 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
619 } else {
620 $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn';
621 }
622 $this->errors[$error]['type'] = 'FOREIGNKEY';
623 $errorforthistable++;
624 $error++;
625 }
626 }
627 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getcustomercodeifauto') {
628 if (strtolower($newval) == 'auto') {
629 $this->thirdpartyobject->get_codeclient(0, 0);
630 $newval = $this->thirdpartyobject->code_client;
631 //print 'code_client='.$newval;
632 }
633 if (empty($newval)) {
634 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
635 }
636 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getsuppliercodeifauto') {
637 if (strtolower($newval) == 'auto') {
638 $this->thirdpartyobject->get_codefournisseur(0, 1);
639 $newval = $this->thirdpartyobject->code_fournisseur;
640 //print 'code_fournisseur='.$newval;
641 }
642 if (empty($newval)) {
643 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
644 }
645 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getcustomeraccountancycodeifauto') {
646 if (strtolower($newval) == 'auto') {
647 $this->thirdpartyobject->get_codecompta('customer');
648 $newval = $this->thirdpartyobject->code_compta_client;
649 //print 'code_compta='.$newval;
650 }
651 if (empty($newval)) {
652 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
653 }
654 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getsupplieraccountancycodeifauto') {
655 if (strtolower($newval) == 'auto') {
656 $this->thirdpartyobject->get_codecompta('supplier');
657 $newval = $this->thirdpartyobject->code_compta_fournisseur;
658 if (empty($newval)) {
659 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
660 }
661 //print 'code_compta_fournisseur='.$newval;
662 }
663 if (empty($newval)) {
664 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
665 }
666 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getrefifauto') {
667 if (strtolower($newval) == 'auto') {
668 $defaultref = '';
669
670 $classModForNumber = $objimport->array_import_convertvalue[0][$val]['class'];
671 $pathModForNumber = $objimport->array_import_convertvalue[0][$val]['path'];
672
673 if (!empty($classModForNumber) && !empty($pathModForNumber) && is_readable(DOL_DOCUMENT_ROOT.$pathModForNumber)) {
674 require_once DOL_DOCUMENT_ROOT.$pathModForNumber;
675 $modForNumber = new $classModForNumber();
676 '@phan-var-force ModeleNumRefMembers|ModeleNumRefCommandes|ModeleNumRefSuppliersInvoices|ModeleNumRefSuppliersOrders|ModeleNumRefProjects|ModeleNumRefTask|ModeleNumRefPropales $modForNumber';
677
678 $tmpobject = null;
679 // Set the object with the date property when we can
680 if (!empty($objimport->array_import_convertvalue[0][$val]['classobject'])) {
681 $pathForObject = $objimport->array_import_convertvalue[0][$val]['pathobject'];
682 require_once DOL_DOCUMENT_ROOT.$pathForObject;
683 $tmpclassobject = $objimport->array_import_convertvalue[0][$val]['classobject'];
684 $tmpobject = new $tmpclassobject($this->db);
685 foreach ($arrayfield as $tmpkey => $tmpval) { // $arrayfield is array('c.ref'=>1, ...)
686 if (in_array($tmpkey, array('t.date', 'c.date_commande'))) {
687 $tmpobject->date = dol_stringtotime($arrayrecord[$arrayfield[$tmpkey]]['val'], 1);
688 }
689 }
690 }
691
692 $defaultref = $modForNumber->getNextValue(null, $tmpobject);
693 }
694 if (is_numeric($defaultref) && $defaultref <= 0) { // If error
695 $defaultref = '';
696 }
697 $newval = $defaultref;
698 }
699 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'compute') {
700 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
701 $class = $objimport->array_import_convertvalue[0][$val]['class'];
702 $method = $objimport->array_import_convertvalue[0][$val]['method'];
703 $resultload = dol_include_once($file);
704 if (empty($resultload)) {
705 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
706 break;
707 }
708 $classinstance = new $class($this->db);
709 $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $arrayfield, $key));
710 if (empty($classinstance->error) && empty($classinstance->errors)) {
711 $newval = $res; // We get new value computed.
712 } else {
713 $this->errors[$error]['type'] = 'CLASSERROR';
714 $this->errors[$error]['lib'] = implode(
715 "\n",
716 array_merge([$classinstance->error], $classinstance->errors)
717 );
718 $errorforthistable++;
719 $error++;
720 }
721 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'numeric') {
722 $newval = price2num($newval);
723 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'accountingaccount') {
724 if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
725 $newval = rtrim(trim($newval), "0");
726 } else {
727 $newval = trim($newval);
728 }
729 }
730
731 //print 'Val to use as insert is '.$newval.'<br>';
732 }
733
734 // Test regexp
735 if (!empty($objimport->array_import_regex[0][$val]) && ($newval != '')) {
736 // If test is "Must exist in a field@table or field@table:..."
737 $reg = array();
738 if (preg_match('/^(.+)@([^:]+)(:.+)?$/', $objimport->array_import_regex[0][$val], $reg)) {
739 $field = $reg[1];
740 $table = $reg[2];
741 $filter = !empty($reg[3]) ? substr($reg[3], 1) : '';
742
743 $cachekey = $field . '@' . $table;
744 if (!empty($filter)) {
745 $cachekey .= ':' . $filter;
746 }
747
748 // Load content of field@table into cache array
749 if (!is_array($this->cachefieldtable[$cachekey])) { // If content of field@table not already loaded into cache
750 $sql = "SELECT " . $field . " as aliasfield FROM " . $table;
751 if (!empty($filter)) {
752 $sql .= ' WHERE ' . $filter;
753 }
754
755 $resql = $this->db->query($sql);
756 if ($resql) {
757 $num = $this->db->num_rows($resql);
758 $i = 0;
759 while ($i < $num) {
760 $obj = $this->db->fetch_object($resql);
761 if ($obj) {
762 $this->cachefieldtable[$cachekey][] = $obj->aliasfield;
763 }
764 $i++;
765 }
766 } else {
767 dol_print_error($this->db);
768 }
769 }
770
771 // Now we check cache is not empty (should not) and key is into cache
772 if (!is_array($this->cachefieldtable[$cachekey]) || !in_array($newval, $this->cachefieldtable[$cachekey])) {
773 $tableforerror = $table;
774 if (!empty($filter)) {
775 $tableforerror .= ':' . $filter;
776 }
777 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
778 $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorFieldValueNotIn', $key, $newval, $field, $tableforerror);
779 $this->errors[$error]['type'] = 'FOREIGNKEY';
780 $errorforthistable++;
781 $error++;
782 }
783 } elseif (!preg_match('/' . $objimport->array_import_regex[0][$val] . '/i', $newval)) {
784 // If test is just a static regex
785 //if ($key == 19) print "xxx".$newval."zzz".$objimport->array_import_regex[0][$val]."<br>";
786 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
787 $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorWrongValueForField', $key, $newval, $objimport->array_import_regex[0][$val]);
788 $this->errors[$error]['type'] = 'REGEX';
789 $errorforthistable++;
790 $error++;
791 }
792 }
793
794 // Check HTML injection
795 $inj = testSqlAndScriptInject($newval, 0);
796 if ($inj) {
797 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
798 $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorHtmlInjectionForField', $key, dol_trunc($newval, 100));
799 $this->errors[$error]['type'] = 'HTMLINJECTION';
800 $errorforthistable++;
801 $error++;
802 }
803
804 // Other tests
805 // ...
806 }
807
808 // Define $listfields and $listvalues to build the SQL request
809 if (isModEnabled("socialnetworks") && strpos($fieldname, "socialnetworks") !== false) {
810 if (!in_array("socialnetworks", $listfields)) {
811 $listfields[] = "socialnetworks";
812 $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array. Example socialkey=19
813 $listvalues[$socialkey] = '';
814 }
815 if (!empty($newval) && $arrayrecord[($key)]['type'] > 0) {
816 $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array. Example socialkey=19
817 $socialnetwork = explode("_", $fieldname)[1];
818 if (empty($listvalues[$socialkey]) || $listvalues[$socialkey] == "null") {
819 $json = new stdClass();
820 $json->$socialnetwork = $newval;
821 $listvalues[$socialkey] = json_encode($json);
822 } else {
823 $jsondata = $listvalues[$socialkey];
824 $json = json_decode($jsondata);
825 $json->$socialnetwork = $newval;
826 $listvalues[$socialkey] = json_encode($json);
827 }
828 }
829 } else {
830 $listfields[] = $fieldname;
831
832 // Note: arrayrecord (and 'type') is filled with ->import_read_record called by import.php page before calling import_insert
833 if (empty($newval) && $arrayrecord[($key)]['type'] < 0) {
834 $listvalues[] = ($newval == '0' ? (int) $newval : "null");
835 } elseif (empty($newval) && $arrayrecord[($key)]['type'] == 0) {
836 $listvalues[] = "''";
837 } else {
838 $listvalues[] = "'".$this->db->escape($newval)."'";
839 }
840 }
841 }
842 $i++;
843 }
844
845 // We add hidden fields (but only if there is at least one field to add into table)
846 // We process here all the fields that were declared into the array $this->import_fieldshidden_array of the descriptor file.
847 // Previously we processed the ->import_fields_array.
848 if (!empty($listfields) && is_array($objimport->array_import_fieldshidden[0])) {
849 // Loop on each hidden fields to add them into listfields/listvalues
850 foreach ($objimport->array_import_fieldshidden[0] as $key => $val) {
851 if (!preg_match('/^' . preg_quote($alias, '/') . '\./', $key)) {
852 continue; // Not a field of current table
853 }
854 $keyfield = preg_replace('/^' . preg_quote($alias, '/') . '\./', '', $key);
855
856 if (in_array($keyfield, $listfields)) { // avoid duplicates in insert
857 continue;
858 } elseif ($val == 'user->id') {
859 $listfields[] = $keyfield;
860 $listvalues[] = ((int) $user->id);
861 } elseif (preg_match('/^lastrowid-/', $val)) {
862 $tmp = explode('-', $val);
863 $lastinsertid = (isset($last_insert_id_array[$tmp[1]])) ? $last_insert_id_array[$tmp[1]] : 0;
864 $listfields[] = $keyfield;
865 $listvalues[] = (int) $lastinsertid;
866 //print $key."-".$val."-".$listfields."-".$listvalues."<br>";exit;
867 } elseif (preg_match('/^const-/', $val)) {
868 $tmp = explode('-', $val, 2);
869 $listfields[] = $keyfield;
870 $listvalues[] = "'".$this->db->escape($tmp[1])."'";
871 } elseif (preg_match('/^rule-/', $val)) {
872 $fieldname = $key;
873 if (!empty($objimport->array_import_convertvalue[0][$fieldname])) {
874 if ($objimport->array_import_convertvalue[0][$fieldname]['rule'] == 'compute') {
875 $file = (empty($objimport->array_import_convertvalue[0][$fieldname]['classfile']) ? $objimport->array_import_convertvalue[0][$fieldname]['file'] : $objimport->array_import_convertvalue[0][$fieldname]['classfile']);
876 $class = $objimport->array_import_convertvalue[0][$fieldname]['class'];
877 $method = $objimport->array_import_convertvalue[0][$fieldname]['method'];
878 $type = $objimport->array_import_convertvalue[0][$fieldname]['type'];
879 $resultload = dol_include_once($file);
880 if (empty($resultload)) {
881 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
882 break;
883 }
884 $classinstance = new $class($this->db);
885 $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $arrayfield, $key));
886 $fieldArr = explode('.', $fieldname);
887 if (count($fieldArr) > 0) {
888 $fieldname = $fieldArr[1];
889 }
890
891 // Set $listfields and $listvalues
892 $listfields[] = $fieldname;
893 if ($type == 'int') {
894 $listvalues[] = (int) $res;
895 } elseif ($type == 'double') {
896 $listvalues[] = (float) $res;
897 } else {
898 $listvalues[] = "'".$this->db->escape($res)."'";
899 }
900 } else {
901 $this->errors[$error]['type'] = 'CLASSERROR';
902 $this->errors[$error]['lib'] = implode(
903 "\n",
904 array_merge([$classinstance->error], $classinstance->errors)
905 );
906 $errorforthistable++;
907 $error++;
908 }
909 }
910 } else {
911 $this->errors[$error]['lib'] = 'Bad value of profile setup ' . $val . ' for array_import_fieldshidden';
912 $this->errors[$error]['type'] = 'Import profile setup';
913 $error++;
914 }
915 }
916 }
917 //print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';
918
919 // If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
920 // so we can try to make the insert or update now.
921 if (!$errorforthistable) {
922 //print "$alias/$tablename/$listfields/$listvalues<br>";
923 if (!empty($listfields)) {
924 $updatedone = false;
925 $insertdone = false;
926
927 $is_table_category_link = false;
928 $fname = 'rowid';
929 if (strpos($tablename, '_categorie_') !== false) {
930 $is_table_category_link = true;
931 $fname = '*';
932 }
933
934 if (!empty($updatekeys)) {
935 // We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
936
937 if (empty($lastinsertid)) { // No insert done yet for a parent table
938 $sqlSelect = "SELECT ".$fname." FROM " . $tablename;
939
940 $data = array_combine($listfields, $listvalues);
941
942 $where = array(); // filters to forge SQL request
943 // @phpstan-ignore-next-line
944 '@phan-var string[] $where';
945 $filters = array(); // filters to forge output error message
946 foreach ($updatekeys as $key) {
947 $col = $objimport->array_import_updatekeys[0][$key];
948 $key = preg_replace('/^.*\./i', '', $key);
949 if (isModEnabled("socialnetworks") && strpos($key, "socialnetworks") !== false) {
950 $tmp = explode("_", $key);
951 $key = $tmp[0];
952 $socialnetwork = $tmp[1];
953 $jsondata = $data[$key];
954 $json = json_decode($jsondata);
955 $stringtosearch = json_encode($socialnetwork).':'.json_encode($json->$socialnetwork);
956 //var_dump($stringtosearch);
957 //var_dump($this->db->escape($stringtosearch)); // This provide a value for sql string (but not for a like)
958 $where[] = $key." LIKE '%".$this->db->escape($this->db->escapeforlike($stringtosearch))."%'";
959 $filters[] = $col." LIKE '%".$this->db->escape($this->db->escapeforlike($stringtosearch))."%'";
960 //var_dump($where[1]); // This provide a value for sql string inside a like
961 } else {
962 $where[] = $key.' = '.$data[$key];
963 $filters[] = $col.' = '.$data[$key];
964 }
965 }
966 if (!empty($tablewithentity_cache[$tablename])) {
967 $where[] = "entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
968 $filters[] = "entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
969 }
970 $sqlSelect .= " WHERE " . implode(' AND ', $where);
971
972 $resql = $this->db->query($sqlSelect);
973 if ($resql) {
974 $num_rows = $this->db->num_rows($resql);
975 if ($num_rows == 1) {
976 $res = $this->db->fetch_object($resql);
977 $lastinsertid = $res->rowid;
978 if ($is_table_category_link) {
979 $lastinsertid = 'linktable';
980 } // used to apply update on tables like llx_categorie_product and avoid being blocked for all file content if at least one entry already exists
981 $last_insert_id_array[$tablename] = $lastinsertid;
982 } elseif ($num_rows > 1) {
983 $this->errors[$error]['lib'] = $langs->trans('MultipleRecordFoundWithTheseFilters', implode(', ', $filters));
984 $this->errors[$error]['type'] = 'SQL';
985 $error++;
986 } else {
987 // No record found with filters, insert will be tried below
988 }
989 } else {
990 //print 'E';
991 $this->errors[$error]['lib'] = $this->db->lasterror();
992 $this->errors[$error]['type'] = 'SQL';
993 $error++;
994 }
995 } else {
996 // We have a last INSERT ID (got by previous pass), so we check if we have a row referencing this foreign key.
997 // This is required when updating table with some extrafields. When inserting a record in parent table, we can make
998 // a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
999 // may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
1000 // Note: For extrafield tablename, we have in importfieldshidden_array an entry 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
1001 $sqlSelect = "SELECT rowid FROM " . $tablename;
1002
1003
1004 if (empty($keyfield)) {
1005 $keyfield = 'rowid';
1006 }
1007 $sqlSelect .= " WHERE ".$keyfield." = ".((int) $lastinsertid);
1008
1009 if (!empty($tablewithentity_cache[$tablename])) {
1010 $sqlSelect .= " AND entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
1011 }
1012
1013 $resql = $this->db->query($sqlSelect);
1014 if ($resql) {
1015 $res = $this->db->fetch_object($resql);
1016 if ($this->db->num_rows($resql) == 1) {
1017 // We have a row referencing this last foreign key, continue with UPDATE.
1018 } else {
1019 // No record found referencing this last foreign key,
1020 // force $lastinsertid to 0 so we INSERT below.
1021 $lastinsertid = 0;
1022 }
1023 } else {
1024 //print 'E';
1025 $this->errors[$error]['lib'] = $this->db->lasterror();
1026 $this->errors[$error]['type'] = 'SQL';
1027 $error++;
1028 }
1029 }
1030
1031 if (!empty($lastinsertid)) {
1032 // We db escape social network field because he isn't in field creation
1033 if (in_array("socialnetworks", $listfields)) {
1034 $socialkey = array_search("socialnetworks", $listfields);
1035 $tmpsql = $listvalues[$socialkey];
1036 $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'";
1037 }
1038
1039 // Build SQL UPDATE request
1040 $sqlstart = "UPDATE " . $tablename;
1041
1042 $data = array_combine($listfields, $listvalues);
1043 $set = array();
1044 foreach ($data as $key => $val) {
1045 $set[] = $key." = ".$val; // $val was escaped/sanitized previously
1046 }
1047 $sqlstart .= " SET " . implode(', ', $set) . ", import_key = '" . $this->db->escape($importid) . "'";
1048
1049 if (empty($keyfield)) {
1050 $keyfield = 'rowid';
1051 }
1052 $sqlend = " WHERE " . $keyfield . " = ".((int) $lastinsertid);
1053
1054 if ($is_table_category_link) {
1055 '@phan-var-force string[] $where';
1056 $sqlend = " WHERE " . implode(' AND ', $where);
1057 }
1058
1059 if (!empty($tablewithentity_cache[$tablename])) {
1060 $sqlend .= " AND entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
1061 }
1062
1063 $sql = $sqlstart . $sqlend;
1064
1065 // Run update request
1066 $resql = $this->db->query($sql);
1067 if ($resql) {
1068 // No error, update has been done. $this->db->db->affected_rows can be 0 if data hasn't changed
1069 $updatedone = true;
1070 } else {
1071 //print 'E';
1072 $this->errors[$error]['lib'] = $this->db->lasterror();
1073 $this->errors[$error]['type'] = 'SQL';
1074 $error++;
1075 }
1076 }
1077 }
1078
1079 // Update not done, we do insert
1080 if (!$error && !$updatedone) {
1081 // We db escape social network field because he isn't in field creation
1082 if (in_array("socialnetworks", $listfields)) {
1083 $socialkey = array_search("socialnetworks", $listfields);
1084 $tmpsql = $listvalues[$socialkey];
1085 $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'";
1086 }
1087
1088 // Build SQL INSERT request
1089 $sqlstart = "INSERT INTO " . $tablename . "(" . implode(", ", $listfields) . ", import_key";
1090 $sqlend = ") VALUES(" . implode(', ', $listvalues) . ", '" . $this->db->escape($importid) . "'";
1091 if (!empty($tablewithentity_cache[$tablename])) {
1092 $sqlstart .= ", entity";
1093 $sqlend .= ", " . $conf->entity;
1094 }
1095 if (!empty($objimport->array_import_tables_creator[0][$alias])) {
1096 $sqlstart .= ", " . $objimport->array_import_tables_creator[0][$alias];
1097 $sqlend .= ", " . $user->id;
1098 }
1099 $sql = $sqlstart . $sqlend . ")";
1100 //dol_syslog("import_xlsx.modules", LOG_DEBUG);
1101
1102 // Run insert request
1103 if ($sql) {
1104 $resql = $this->db->query($sql);
1105 if ($resql) {
1106 if (!$is_table_category_link) {
1107 $last_insert_id_array[$tablename] = $this->db->last_insert_id($tablename); // store the last inserted auto_increment id for each table, so that child tables can be inserted with the appropriate id. This must be done just after the INSERT request, else we risk losing the id (because another sql query will be issued somewhere in Dolibarr).
1108 }
1109 $insertdone = true;
1110 } else {
1111 //print 'E';
1112 $this->errors[$error]['lib'] = $this->db->lasterror();
1113 $this->errors[$error]['type'] = 'SQL';
1114 $error++;
1115 }
1116 }
1117 }
1118 }
1119 /*else
1120 {
1121 dol_print_error(null,'ErrorFieldListEmptyFor '.$alias."/".$tablename);
1122 }*/
1123 }
1124
1125 if ($error) {
1126 break;
1127 }
1128 }
1129
1130 if ($updatedone) {
1131 $this->nbupdate++;
1132 }
1133 if ($insertdone) {
1134 $this->nbinsert++;
1135 }
1136 }
1137
1138 return 1;
1139 }
1140}
versionphparray()
Return version PHP.
versioncompare($versionarray1, $versionarray2)
Compare 2 versions (stored into 2 arrays).
Definition admin.lib.php:69
Class to import Excel files.
__construct($db, $datatoimport)
Constructor.
write_record_example($outputlangs, $contentlinevalues)
Output record of an example file for this format.
import_open_file($file)
Open input file.
import_insert($arrayrecord, $array_match_file_to_database, $objimport, $maxfields, $importid, $updatekeys)
Insert a record into database.
write_footer_example($outputlangs)
Output footer of an example file for this format.
import_read_header()
Input header line from file.
write_header_example($outputlangs)
Output header of an example file for this format.
import_read_record()
Return array of next record in input file.
write_title_example($outputlangs, $headerlinefields)
Output title line of an example file for this format.
import_get_nb_of_lines($file)
Return nb of records.
import_close_file()
Close file handle.
Parent class for import file readers.
getElementFromTableWithPrefix($tableNameWithPrefix)
Get element from table name with prefix.
Class to manage third parties objects (customers, suppliers, prospects...)
dol_stringtotime($string, $gm=1)
Convert a string date into a GM Timestamps date Warning: YYYY-MM-DDTHH:MM:SS+02:00 (RFC3339) is not s...
Definition date.lib.php:426
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_strlen($string, $stringencoding='UTF-8')
Make a strlen call.
if(!function_exists( 'dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
num2Alpha($n)
Return a numeric value into an Excel like column number.
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
dol_trunc($string, $size=40, $trunc='right', $stringencoding='UTF-8', $nodot=0, $display=0)
Truncate a string to a particular length adding '…' if string larger than length.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
testSqlAndScriptInject($val, $type)
Security: WAF layer for SQL Injection and XSS Injection (scripts) protection (Filters on GET,...
Definition main.inc.php:123