dolibarr 22.0.5
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
62 public $label_lib; // Label of external lib used by driver
63
67 public $version_lib; // Version of external lib used by driver
68
72 public $separator;
73
77 public $file; // Path of file
78
82 public $handle; // Handle fichier
83
84 public $cacheconvert = array(); // Array to cache list of value found after a conversion
85
86 public $cachefieldtable = array(); // Array to cache list of value found into fields@tables
87
88 public $nbinsert = 0; // # of insert done during the import
89
90 public $nbupdate = 0; // # of update done during the import
91
95 public $workbook; // temporary import file
96
100 public $record; // current record
101
105 public $headers;
106
110 public $countcolumns = 0; // cached column count to avoid re-parsing the file on each row
111
112
119 public function __construct($db, $datatoimport)
120 {
121 global $langs;
122
123 parent::__construct();
124 $this->db = $db;
125
126 // this is used as an extension from the example file code, so we have to put xlsx here !!!
127 $this->id = 'xlsx'; // Same value as xxx in file name export_xxx.modules.php
128 $this->label = 'Excel 2007'; // Label of driver
129 $this->desc = $langs->trans("Excel2007FormatDesc");
130 $this->extension = 'xlsx'; // Extension for generated file by this driver
131 $this->picto = 'mime/xls'; // Picto (This is not used by the example file code as Mime type, too bad ...)
132 $this->version = '1.0'; // Driver version
133 $this->phpmin = array(7, 1); // Minimum version of PHP required by module
134
135 require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
136 if (versioncompare($this->phpmin, versionphparray()) > 0) {
137 dol_syslog("Module need a higher PHP version");
138 $this->error = "Module need a higher PHP version";
139 return;
140 }
141
142 // If driver use an external library, put its name here
143 require_once DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpspreadsheet/src/autoloader.php';
144 require_once DOL_DOCUMENT_ROOT.'/includes/Psr/autoloader.php';
145 require_once PHPEXCELNEW_PATH.'Spreadsheet.php';
146 $this->workbook = new Spreadsheet();
147
148 // If driver use an external library, put its name here
149 if (!class_exists('ZipArchive')) { // For Excel2007
150 $langs->load("errors");
151 $this->error = $langs->trans('ErrorPHPNeedModule', 'zip');
152 return;
153 }
154 $this->label_lib = 'PhpSpreadSheet';
155 $this->version_lib = '1.8.0';
156
157 $arrayofstreams = stream_get_wrappers();
158 if (!in_array('zip', $arrayofstreams)) {
159 $langs->load("errors");
160 $this->error = $langs->trans('ErrorStreamMustBeEnabled', 'zip');
161 return;
162 }
163
164 $this->datatoimport = $datatoimport;
165 if (preg_match('/^societe_/', $datatoimport)) {
166 $this->thirdpartyobject = new Societe($this->db);
167 }
168 }
169
170
171 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
178 public function write_header_example($outputlangs)
179 {
180 // phpcs:enable
181 global $user, $conf, $langs, $file;
182 // create a temporary object, the final output will be generated in footer
183 $this->workbook->getProperties()->setCreator($user->getFullName($outputlangs) . ' - Dolibarr ' . DOL_VERSION);
184 $this->workbook->getProperties()->setTitle($outputlangs->trans("Import") . ' - ' . $file);
185 $this->workbook->getProperties()->setSubject($outputlangs->trans("Import") . ' - ' . $file);
186 $this->workbook->getProperties()->setDescription($outputlangs->trans("Import") . ' - ' . $file);
187
188 $this->workbook->setActiveSheetIndex(0);
189 $this->workbook->getActiveSheet()->setTitle($outputlangs->trans("Sheet"));
190 $this->workbook->getActiveSheet()->getDefaultRowDimension()->setRowHeight(16);
191
192 return '';
193 }
194
195 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
203 public function write_title_example($outputlangs, $headerlinefields)
204 {
205 // phpcs:enable
206 global $conf;
207 $this->workbook->getActiveSheet()->getStyle('1')->getFont()->setBold(true);
208 $this->workbook->getActiveSheet()->getStyle('1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT);
209
210 $col = 1;
211 foreach ($headerlinefields as $field) {
212 $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, 1, $outputlangs->transnoentities($field));
213 // set autowidth
214 //$this->workbook->getActiveSheet()->getColumnDimension($this->column2Letter($col + 1))->setAutoSize(true);
215 $col++;
216 }
217
218 return ''; // final output will be generated in footer
219 }
220
221 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
229 public function write_record_example($outputlangs, $contentlinevalues)
230 {
231 // phpcs:enable
232 $col = 1;
233 $row = 2;
234 foreach ($contentlinevalues as $cell) {
235 $this->workbook->getActiveSheet()->SetCellValueByColumnAndRow($col, $row, $cell);
236 $col++;
237 }
238
239 return ''; // final output will be generated in footer
240 }
241
242 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
249 public function write_footer_example($outputlangs)
250 {
251 // phpcs:enable
252 // return the file content as a string
253 $tempfile = tempnam(sys_get_temp_dir(), 'dol');
254 $objWriter = new PhpOffice\PhpSpreadsheet\Writer\Xlsx($this->workbook);
255 $objWriter->save($tempfile);
256 $this->workbook->disconnectWorksheets();
257 unset($this->workbook);
258
259 $content = file_get_contents($tempfile);
260 unlink($tempfile);
261 return $content;
262 }
263
264
265
266 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
273 public function import_open_file($file)
274 {
275 // phpcs:enable
276 $ret = 1;
277
278 dol_syslog(get_class($this) . "::open_file file=" . $file);
279
280 $reader = new Xlsx();
281 $this->workbook = $reader->load($file);
282 $this->record = 1;
283 $this->file = $file;
284
285 return $ret;
286 }
287
288
289 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
296 public function import_get_nb_of_lines($file)
297 {
298 // phpcs:enable
299 $reader = new Xlsx();
300 $this->workbook = $reader->load($file);
301
302 $rowcount = $this->workbook->getActiveSheet()->getHighestDataRow();
303
304 $this->workbook->disconnectWorksheets();
305 unset($this->workbook);
306
307 return $rowcount;
308 }
309
310
311 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
317 public function import_read_header()
318 {
319 // phpcs:enable
320 // This is not called by the import code !!!
321 $this->headers = array();
322 $xlsx = new Xlsx();
323 $info = $xlsx->listWorksheetinfo($this->file);
324 $countcolumns = $info[0]['totalColumns'];
325 for ($col = 1; $col <= $countcolumns; $col++) {
326 $this->headers[$col] = $this->workbook->getActiveSheet()->getCellByColumnAndRow($col, 1)->getValue();
327 }
328 return 0;
329 }
330
331
332 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
338 public function import_read_record()
339 {
340 // phpcs:enable
341 $rowcount = $this->workbook->getActiveSheet()->getHighestDataRow();
342 if ($this->record > $rowcount) {
343 return false;
344 }
345 $array = array();
346
347 if (empty($this->countcolumns)) {
348 $xlsx = new Xlsx();
349 $info = $xlsx->listWorksheetinfo($this->file);
350 $this->countcolumns = $info[0]['totalColumns'];
351 unset($xlsx);
352 }
353 $countcolumns = $this->countcolumns;
354
355 for ($col = 1; $col <= $countcolumns; $col++) {
356 $tmpcell = $this->workbook->getActiveSheet()->getCellByColumnAndRow($col, $this->record);
357
358 $val = $tmpcell->getValue();
359
360 if (Date::isDateTime($tmpcell)) {
361 // For date field, we use the standard date format string.
362 $dateValue = Date::excelToDateTimeObject($val);
363 $val = $dateValue->format('Y-m-d H:i:s');
364 }
365
366 $array[$col]['val'] = $val;
367 $array[$col]['type'] = (dol_strlen($val) ? 1 : -1); // If empty we consider it null
368 }
369 $this->record++;
370
371 return $array;
372 }
373
374 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
380 public function import_close_file()
381 {
382 // phpcs:enable
383 $this->workbook->disconnectWorksheets();
384 unset($this->workbook);
385 return 0;
386 }
387
388
389 // What is this doing here ? it is common to all imports, is should be in the parent class
390 // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
402 public function import_insert($arrayrecord, $array_match_file_to_database, $objimport, $maxfields, $importid, $updatekeys)
403 {
404 // phpcs:enable
405 global $langs, $conf, $user;
406 global $thirdparty_static; // Specific to thirdparty import
407 global $tablewithentity_cache; // Cache to avoid to call desc at each rows on tables
408
409 $error = 0;
410 $warning = 0;
411 $this->errors = array();
412 $this->warnings = array();
413
414 //dol_syslog("import_csv.modules maxfields=".$maxfields." importid=".$importid);
415
416 //var_dump($array_match_file_to_database);
417 //var_dump($arrayrecord); exit;
418
419 $array_match_database_to_file = array_flip($array_match_file_to_database);
420 $sort_array_match_file_to_database = $array_match_file_to_database;
421 ksort($sort_array_match_file_to_database);
422
423 //var_dump($sort_array_match_file_to_database);
424
425 if (count($arrayrecord) == 0 || (count($arrayrecord) == 1 && empty($arrayrecord[1]['val']))) {
426 //print 'W';
427 $this->warnings[$warning]['lib'] = $langs->trans('EmptyLine');
428 $this->warnings[$warning]['type'] = 'EMPTY';
429 $warning++;
430 } else {
431 $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)
432 $updatedone = false;
433 $insertdone = false;
434 // For each table to insert, me make a separate insert
435 foreach ($objimport->array_import_tables[0] as $alias => $tablename) {
436 // Build sql request
437 $sql = '';
438 $listfields = array();
439 $listvalues = array();
440 $i = 0;
441 $errorforthistable = 0;
442
443 // Define $tablewithentity_cache[$tablename] if not already defined
444 if (!isset($tablewithentity_cache[$tablename])) { // keep this test with "isset"
445 dol_syslog("Check if table " . $tablename . " has an entity field");
446 $resql = $this->db->DDLDescTable($tablename, 'entity');
447 if ($resql) {
448 $obj = $this->db->fetch_object($resql);
449 if ($obj) {
450 $tablewithentity_cache[$tablename] = 1; // table contains entity field
451 } else {
452 $tablewithentity_cache[$tablename] = 0; // table does not contain entity field
453 }
454 } else {
455 dol_print_error($this->db);
456 }
457 } else {
458 //dol_syslog("Table ".$tablename." check for entity into cache is ".$tablewithentity_cache[$tablename]);
459 }
460
461 // Define an array to convert fields ('c.ref', ...) into column index (1, ...)
462 $arrayfield = array();
463 foreach ($sort_array_match_file_to_database as $key => $val) {
464 $arrayfield[$val] = ($key);
465 }
466
467 // $arrayrecord start at key 1
468 // $sort_array_match_file_to_database start at key 1
469
470 // Loop on each fields in the match array: $key = 1..n, $val=alias of field (s.nom)
471 foreach ($sort_array_match_file_to_database as $key => $val) {
472 $fieldalias = preg_replace('/\..*$/i', '', $val);
473 $fieldname = preg_replace('/^.*\./i', '', $val);
474
475 if ($alias != $fieldalias) {
476 continue; // Not a field of current table
477 }
478
479 if ($key <= $maxfields) {
480 // Set $newval with value to insert and set $listvalues with sql request part for insert
481 $newval = '';
482 if ($arrayrecord[($key)]['type'] > 0) {
483 $newval = $arrayrecord[($key)]['val']; // If type of field into input file is not empty string (so defined into input file), we get value
484 }
485
486 //var_dump($newval);var_dump($val);
487 //var_dump($objimport->array_import_convertvalue[0][$val]);
488
489 // Make some tests on $newval
490
491 // Is it a required field ?
492 if (preg_match('/\*/', $objimport->array_import_fields[0][$val]) && ((string) $newval == '')) {
493 $this->errors[$error]['lib'] = $langs->trans('ErrorMissingMandatoryValue', num2Alpha($key - 1));
494 $this->errors[$error]['type'] = 'NOTNULL';
495 $errorforthistable++;
496 $error++;
497 } else {
498 // Test format only if field is not a missing mandatory field (field may be a value or empty but not mandatory)
499 // We convert field if required
500 if (!empty($objimport->array_import_convertvalue[0][$val])) {
501 //print 'Must convert '.$newval.' with rule '.join(',',$objimport->array_import_convertvalue[0][$val]).'. ';
502 if ($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeid'
503 || $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromref'
504 || $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeorlabel'
505 ) {
506 // 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.
507 $isidorref = 'id';
508 if (!is_numeric($newval) && $newval != '' && !preg_match('/^id:/i', $newval)) {
509 $isidorref = 'ref';
510 }
511 $newval = preg_replace('/^(id|ref):/i', '', $newval); // Remove id: or ref: that was used to force if field is id or ref
512 //print 'Newval is now "'.$newval.'" and is type '.$isidorref."<br>\n";
513
514 if ($isidorref == 'ref') { // If value into input import file is a ref, we apply the function defined into descriptor
515 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
516 $class = $objimport->array_import_convertvalue[0][$val]['class'];
517 $method = $objimport->array_import_convertvalue[0][$val]['method'];
518 if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_'][$newval] != '') {
519 $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_'][$newval];
520 } else {
521 $resultload = dol_include_once($file);
522 if (empty($resultload)) {
523 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
524 break;
525 }
526 $classinstance = new $class($this->db);
527 if ($class == 'CGenericDic') {
528 $classinstance->element = $objimport->array_import_convertvalue[0][$val]['element'];
529 $classinstance->table_element = $objimport->array_import_convertvalue[0][$val]['table_element'];
530 }
531
532 // Try the fetch from code or ref
533 $param_array = array('', $newval);
534 if ($class == 'AccountingAccount') {
535 //var_dump($arrayrecord[0]['val']);
536 /*include_once DOL_DOCUMENT_ROOT.'/accountancy/class/accountancysystem.class.php';
537 $tmpchartofaccount = new AccountancySystem($this->db);
538 $tmpchartofaccount->fetch(getDolGlobalInt('CHARTOFACCOUNTS'));
539 //var_dump($tmpchartofaccount->ref.' - '.$arrayrecord[0]['val']);
540 if ((! (getDolGlobalInt('CHARTOFACCOUNTS') > 0)) || $tmpchartofaccount->ref != $arrayrecord[0]['val'])
541 {
542 $this->errors[$error]['lib']=$langs->trans('ErrorImportOfChartLimitedToCurrentChart', $tmpchartofaccount->ref);
543 $this->errors[$error]['type']='RESTRICTONCURRENCTCHART';
544 $errorforthistable++;
545 $error++;
546 }*/
547 $param_array = array('', $newval, 0, $arrayrecord[0]['val']); // Param to fetch parent from account, in chart.
548 }
549
550 $result = call_user_func_array(array($classinstance, $method), $param_array);
551
552 // If duplicate record found
553 if (!($classinstance->id != '') && $result == -2) {
554 $this->errors[$error]['lib'] = $langs->trans('ErrorMultipleRecordFoundFromRef', $newval);
555 $this->errors[$error]['type'] = 'FOREIGNKEY';
556 $errorforthistable++;
557 $error++;
558 }
559
560 // If not found, try the fetch from label
561 if (!($classinstance->id != '') && $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeorlabel') {
562 $param_array = array('', '', $newval);
563 call_user_func_array(array($classinstance, $method), $param_array);
564 }
565 $this->cacheconvert[$file . '_' . $class . '_' . $method . '_'][$newval] = $classinstance->id;
566
567 //print 'We have made a '.$class.'->'.$method.' to get id from code '.$newval.'. ';
568 if ($classinstance->id != '') { // id may be 0, it is a found value
569 $newval = $classinstance->id;
570 } elseif (! $error) {
571 if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
572 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
573 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'code', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
574 } elseif (!empty($objimport->array_import_convertvalue[0][$val]['element'])) {
575 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
576 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldRefNotIn', $key, $newval, $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['element']));
577 } else {
578 $this->errors[$error]['lib'] = 'ErrorBadDefinitionOfImportProfile';
579 }
580 $this->errors[$error]['type'] = 'FOREIGNKEY';
581 $errorforthistable++;
582 $error++;
583 }
584 }
585 }
586 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeandlabel') {
587 $isidorref = 'id';
588 if (!is_numeric($newval) && $newval != '' && !preg_match('/^id:/i', $newval)) {
589 $isidorref = 'ref';
590 }
591 $newval = preg_replace('/^(id|ref):/i', '', $newval);
592
593 if ($isidorref == 'ref') {
594 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
595 $class = $objimport->array_import_convertvalue[0][$val]['class'];
596 $method = $objimport->array_import_convertvalue[0][$val]['method'];
597 $codefromfield = $objimport->array_import_convertvalue[0][$val]['codefromfield'];
598 $code = $arrayrecord[$arrayfield[$codefromfield]]['val'];
599 if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] != '') {
600 $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$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 . ', code=' . $code);
605 break;
606 }
607 $classinstance = new $class($this->db);
608 // Try the fetch from code and ref
609 $param_array = array('', $newval, $code);
610 call_user_func_array(array($classinstance, $method), $param_array);
611 $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $code][$newval] = $classinstance->id;
612 if ($classinstance->id > 0) { // we found record
613 $newval = $classinstance->id;
614 } else {
615 if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
616 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
617 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
618 } else {
619 $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn';
620 }
621 $this->errors[$error]['type'] = 'FOREIGNKEY';
622 $errorforthistable++;
623 $error++;
624 }
625 }
626 }
627 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'zeroifnull') {
628 if (empty($newval)) {
629 $newval = '0';
630 }
631 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeunits' || $objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchscalefromcodeunits') {
632 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
633 $class = $objimport->array_import_convertvalue[0][$val]['class'];
634 $method = $objimport->array_import_convertvalue[0][$val]['method'];
635 $units = $objimport->array_import_convertvalue[0][$val]['units'];
636 if ($this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $units][$newval] != '') {
637 $newval = $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $units][$newval];
638 } else {
639 $resultload = dol_include_once($file);
640 if (empty($resultload)) {
641 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method . ', units=' . $units);
642 break;
643 }
644 $classinstance = new $class($this->db);
645 // Try the fetch from code or ref
646 call_user_func_array(array($classinstance, $method), array('', '', $newval, $units));
647 $scaleorid = (($objimport->array_import_convertvalue[0][$val]['rule'] == 'fetchidfromcodeunits') ? $classinstance->id : $classinstance->scale);
648 $this->cacheconvert[$file . '_' . $class . '_' . $method . '_' . $units][$newval] = $scaleorid;
649 //print 'We have made a '.$class.'->'.$method." to get a value from key '".$newval."' and we got '".$scaleorid."'.";exit;
650 if ($classinstance->id > 0) { // we found record
651 $newval = $scaleorid ? $scaleorid : 0;
652 } else {
653 if (!empty($objimport->array_import_convertvalue[0][$val]['dict'])) {
654 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
655 $this->errors[$error]['lib'] = $langs->trans('ErrorFieldValueNotIn', $key, $newval, 'scale', $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$val]['dict']));
656 } else {
657 $this->errors[$error]['lib'] = 'ErrorFieldValueNotIn';
658 }
659 $this->errors[$error]['type'] = 'FOREIGNKEY';
660 $errorforthistable++;
661 $error++;
662 }
663 }
664 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getcustomercodeifauto') {
665 if (strtolower($newval) == 'auto') {
666 $this->thirdpartyobject->get_codeclient(null, 0);
667 $newval = $this->thirdpartyobject->code_client;
668 //print 'code_client='.$newval;
669 }
670 if (empty($newval)) {
671 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
672 }
673 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getsuppliercodeifauto') {
674 if (strtolower($newval) == 'auto') {
675 $this->thirdpartyobject->get_codefournisseur(null, 1);
676 $newval = $this->thirdpartyobject->code_fournisseur;
677 //print 'code_fournisseur='.$newval;
678 }
679 if (empty($newval)) {
680 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
681 }
682 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getcustomeraccountancycodeifauto') {
683 if (strtolower($newval) == 'auto') {
684 $this->thirdpartyobject->get_codecompta('customer');
685 $newval = $this->thirdpartyobject->code_compta_client;
686 //print 'code_compta='.$newval;
687 }
688 if (empty($newval)) {
689 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
690 }
691 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getsupplieraccountancycodeifauto') {
692 if (strtolower($newval) == 'auto') {
693 $this->thirdpartyobject->get_codecompta('supplier');
694 $newval = $this->thirdpartyobject->code_compta_fournisseur;
695 if (empty($newval)) {
696 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
697 }
698 //print 'code_compta_fournisseur='.$newval;
699 }
700 if (empty($newval)) {
701 $arrayrecord[($key)]['type'] = -1; // If we get empty value, we will use "null"
702 }
703 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'getrefifauto') {
704 if (strtolower($newval) == 'auto') {
705 $defaultref = '';
706
707 $classModForNumber = $objimport->array_import_convertvalue[0][$val]['class'];
708 $pathModForNumber = $objimport->array_import_convertvalue[0][$val]['path'];
709
710 if (!empty($classModForNumber) && !empty($pathModForNumber) && is_readable(DOL_DOCUMENT_ROOT.$pathModForNumber)) {
711 require_once DOL_DOCUMENT_ROOT.$pathModForNumber;
712 $modForNumber = new $classModForNumber();
713 '@phan-var-force ModeleNumRefMembers|ModeleNumRefCommandes|ModeleNumRefSuppliersInvoices|ModeleNumRefSuppliersOrders|ModeleNumRefProjects|ModeleNumRefTask|ModeleNumRefPropales $modForNumber';
714
715 $tmpobject = null;
716 // Set the object with the date property when we can
717 if (!empty($objimport->array_import_convertvalue[0][$val]['classobject'])) {
718 $pathForObject = $objimport->array_import_convertvalue[0][$val]['pathobject'];
719 require_once DOL_DOCUMENT_ROOT.$pathForObject;
720 $tmpclassobject = $objimport->array_import_convertvalue[0][$val]['classobject'];
721 $tmpobject = new $tmpclassobject($this->db);
722 foreach ($arrayfield as $tmpkey => $tmpval) { // $arrayfield is array('c.ref'=>1, ...)
723 if (in_array($tmpkey, array('t.date', 'c.date_commande'))) {
724 $tmpobject->date = dol_stringtotime($arrayrecord[$arrayfield[$tmpkey]]['val'], 1);
725 }
726 }
727 }
728
729 $defaultref = $modForNumber->getNextValue(null, $tmpobject);
730 }
731 if (is_numeric($defaultref) && $defaultref <= 0) { // If error
732 $defaultref = '';
733 }
734 $newval = $defaultref;
735 }
736 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'compute') {
737 $file = (empty($objimport->array_import_convertvalue[0][$val]['classfile']) ? $objimport->array_import_convertvalue[0][$val]['file'] : $objimport->array_import_convertvalue[0][$val]['classfile']);
738 $class = $objimport->array_import_convertvalue[0][$val]['class'];
739 $method = $objimport->array_import_convertvalue[0][$val]['method'];
740 $resultload = dol_include_once($file);
741 if (empty($resultload)) {
742 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
743 break;
744 }
745 $classinstance = new $class($this->db);
746 $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $arrayfield, $key));
747 if (empty($classinstance->error) && empty($classinstance->errors)) {
748 $newval = $res; // We get new value computed.
749 } else {
750 $this->errors[$error]['type'] = 'CLASSERROR';
751 $this->errors[$error]['lib'] = implode(
752 "\n",
753 array_merge([$classinstance->error], $classinstance->errors)
754 );
755 $errorforthistable++;
756 $error++;
757 }
758 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'numeric') {
759 $newval = price2num($newval);
760 } elseif ($objimport->array_import_convertvalue[0][$val]['rule'] == 'accountingaccount') {
761 if (!getDolGlobalString('ACCOUNTING_MANAGE_ZERO')) {
762 $newval = rtrim(trim($newval), "0");
763 } else {
764 $newval = trim($newval);
765 }
766 }
767
768 //print 'Val to use as insert is '.$newval.'<br>';
769 }
770
771 // Test regexp
772 if (!empty($objimport->array_import_regex[0][$val]) && ($newval != '')) {
773 // If test is "Must exist in a field@table or field@table:..."
774 $reg = array();
775 if (preg_match('/^(.+)@([^:]+)(:.+)?$/', $objimport->array_import_regex[0][$val], $reg)) {
776 $field = $reg[1];
777 $table = $reg[2];
778 $filter = !empty($reg[3]) ? substr($reg[3], 1) : '';
779
780 $cachekey = $field . '@' . $table;
781 if (!empty($filter)) {
782 $cachekey .= ':' . $filter;
783 }
784
785 // Load content of field@table into cache array
786 if (!is_array($this->cachefieldtable[$cachekey])) { // If content of field@table not already loaded into cache
787 $sql = "SELECT " . $field . " as aliasfield FROM " . $table;
788 if (!empty($filter)) {
789 $sql .= ' WHERE ' . $filter;
790 }
791
792
793 $resql = $this->db->query($sql);
794 if ($resql) {
795 $num = $this->db->num_rows($resql);
796 $i = 0;
797 while ($i < $num) {
798 $obj = $this->db->fetch_object($resql);
799 if ($obj) {
800 $this->cachefieldtable[$cachekey][] = $obj->aliasfield;
801 }
802 $i++;
803 }
804 } else {
805 dol_print_error($this->db);
806 }
807 }
808
809 // Now we check cache is not empty (should not) and key is into cache
810 if (!is_array($this->cachefieldtable[$cachekey]) || !in_array($newval, $this->cachefieldtable[$cachekey])) {
811 $tableforerror = $table;
812 if (!empty($filter)) {
813 $tableforerror .= ':' . $filter;
814 }
815 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
816 $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorFieldValueNotIn', $key, $newval, $field, $tableforerror);
817 $this->errors[$error]['type'] = 'FOREIGNKEY';
818 $errorforthistable++;
819 $error++;
820 }
821 } elseif (!preg_match('/' . $objimport->array_import_regex[0][$val] . '/i', $newval)) {
822 // If test is just a static regex
823 //if ($key == 19) print "xxx".$newval."zzz".$objimport->array_import_regex[0][$val]."<br>";
824 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
825 $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorWrongValueForField', $key, $newval, $objimport->array_import_regex[0][$val]);
826 $this->errors[$error]['type'] = 'REGEX';
827 $errorforthistable++;
828 $error++;
829 }
830 }
831
832 // Check HTML injection
833 $inj = testSqlAndScriptInject($newval, 0);
834 if ($inj) {
835 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
836 $this->errors[$error]['lib'] = $langs->transnoentitiesnoconv('ErrorHtmlInjectionForField', $key, dol_trunc($newval, 100));
837 $this->errors[$error]['type'] = 'HTMLINJECTION';
838 $errorforthistable++;
839 $error++;
840 }
841
842 // Other tests
843 // ...
844 }
845
846 // Define $listfields and $listvalues to build the SQL request
847 if (isModEnabled("socialnetworks") && strpos($fieldname, "socialnetworks") !== false) {
848 if (!in_array("socialnetworks", $listfields)) {
849 $listfields[] = "socialnetworks";
850 $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array. Example socialkey=19
851 $listvalues[$socialkey] = '';
852 }
853 if (!empty($newval) && $arrayrecord[($key)]['type'] > 0) {
854 $socialkey = array_search("socialnetworks", $listfields); // Return position of 'socialnetworks' key in array. Example socialkey=19
855 $socialnetwork = explode("_", $fieldname)[1];
856 if (empty($listvalues[$socialkey]) || $listvalues[$socialkey] == "null") {
857 $json = new stdClass();
858 $json->$socialnetwork = $newval;
859 $listvalues[$socialkey] = json_encode($json);
860 } else {
861 $jsondata = $listvalues[$socialkey];
862 $json = json_decode($jsondata);
863 $json->$socialnetwork = $newval;
864 $listvalues[$socialkey] = json_encode($json);
865 }
866 }
867 } else {
868 $listfields[] = $fieldname;
869
870 // Note: arrayrecord (and 'type') is filled with ->import_read_record called by import.php page before calling import_insert
871 if (empty($newval) && $arrayrecord[($key)]['type'] < 0) {
872 $listvalues[] = ($newval == '0' ? (int) $newval : "null");
873 } elseif (empty($newval) && $arrayrecord[($key)]['type'] == 0) {
874 $listvalues[] = "''";
875 } else {
876 $listvalues[] = "'".$this->db->escape($newval)."'";
877 }
878 }
879 }
880 $i++;
881 }
882
883 // We add hidden fields (but only if there is at least one field to add into table)
884 // We process here all the fields that were declared into the array $this->import_fieldshidden_array of the descriptor file.
885 // Previously we processed the ->import_fields_array.
886 if (!empty($listfields) && is_array($objimport->array_import_fieldshidden[0])) {
887 // Loop on each hidden fields to add them into listfields/listvalues
888 foreach ($objimport->array_import_fieldshidden[0] as $key => $val) {
889 if (!preg_match('/^' . preg_quote($alias, '/') . '\./', $key)) {
890 continue; // Not a field of current table
891 }
892 $keyfieldcache = preg_replace('/^' . preg_quote($alias, '/') . '\./', '', $key);
893 if (in_array($keyfieldcache, $listfields)) { // avoid duplicates in insert
894 continue;
895 } elseif ($val == 'user->id') {
896 $listfields[] = $keyfieldcache;
897 $listvalues[] = ((int) $user->id);
898 } elseif (preg_match('/^lastrowid-/', $val)) {
899 $tmp = explode('-', $val);
900 $lastinsertid = (isset($last_insert_id_array[$tmp[1]])) ? $last_insert_id_array[$tmp[1]] : 0;
901 $listfields[] = $keyfieldcache;
902 $keyfield = $keyfieldcache;
903 $listvalues[] = (int) $lastinsertid;
904 //print $key."-".$val."-".$listfields."-".$listvalues."<br>";exit;
905 } elseif (preg_match('/^const-/', $val)) {
906 $tmp = explode('-', $val, 2);
907 $listfields[] = $keyfieldcache;
908 $listvalues[] = "'".$this->db->escape($tmp[1])."'";
909 } elseif (preg_match('/^rule-/', $val)) {
910 $fieldname = $key;
911 $classinstance = null;
912 if (!empty($objimport->array_import_convertvalue[0][$fieldname])) {
913 if ($objimport->array_import_convertvalue[0][$fieldname]['rule'] == 'compute') {
914 $file = (empty($objimport->array_import_convertvalue[0][$fieldname]['classfile']) ? $objimport->array_import_convertvalue[0][$fieldname]['file'] : $objimport->array_import_convertvalue[0][$fieldname]['classfile']);
915 $class = $objimport->array_import_convertvalue[0][$fieldname]['class'];
916 $method = $objimport->array_import_convertvalue[0][$fieldname]['method'];
917 $type = $objimport->array_import_convertvalue[0][$fieldname]['type'];
918 $resultload = dol_include_once($file);
919 if (empty($resultload)) {
920 dol_print_error(null, 'Error trying to call file=' . $file . ', class=' . $class . ', method=' . $method);
921 break;
922 }
923 $classinstance = new $class($this->db);
924 $res = call_user_func_array(array($classinstance, $method), array(&$arrayrecord, $arrayfield, $key));
925 $fieldArr = explode('.', $fieldname);
926 if (count($fieldArr) > 0) {
927 $fieldname = $fieldArr[1];
928 }
929
930 // Set $listfields and $listvalues
931 $listfields[] = $fieldname;
932 if ($type == 'int') {
933 $listvalues[] = (int) $res;
934 } elseif ($type == 'double') {
935 $listvalues[] = (float) $res;
936 } else {
937 $listvalues[] = "'".$this->db->escape($res)."'";
938 }
939 } else {
940 $this->errors[$error]['type'] = 'CLASSERROR';
941 if (is_object($classinstance)) { // @phpstan-ignore-line
942 $this->errors[$error]['lib'] = implode(
943 "\n",
944 array_merge([$classinstance->error], $classinstance->errors)
945 );
946 } else {
947 $this->errors[$error]['lib']
948 = "Unexpected rule ".$objimport->array_import_convertvalue[0][$fieldname]['rule'];
949 }
950
951 $errorforthistable++;
952 $error++;
953 }
954 }
955 } else {
956 $this->errors[$error]['lib'] = 'Bad value of profile setup ' . $val . ' for array_import_fieldshidden';
957 $this->errors[$error]['type'] = 'Import profile setup';
958 $error++;
959 }
960 }
961 }
962 //print 'listfields='.$listfields.'<br>listvalues='.$listvalues.'<br>';
963
964 // If no error for this $alias/$tablename, we have a complete $listfields and $listvalues that are defined
965 // so we can try to make the insert or update now.
966 if (!$errorforthistable) {
967 //print "$alias/$tablename/$listfields/$listvalues<br>";
968 if (!empty($listfields)) {
969 $updatedone = false;
970 $insertdone = false;
971
972 $is_table_category_link = false;
973 $fname = 'rowid';
974 if (strpos($tablename, '_categorie_') !== false) {
975 $is_table_category_link = true;
976 $fname = '*';
977 }
978
979 if (!empty($updatekeys)) {
980 // We do SELECT to get the rowid, if we already have the rowid, it's to be used below for related tables (extrafields)
981
982 if (empty($lastinsertid)) { // No insert done yet for a parent table
983 $sqlSelect = "SELECT ".$fname." FROM " . $tablename;
984
985 $data = array_combine($listfields, $listvalues);
986
987 $where = array(); // filters to forge SQL request
988 // @phpstan-ignore-next-line
989 '@phan-var string[] $where';
990 $filters = array(); // filters to forge output error message
991 foreach ($updatekeys as $key) {
992 $col = $objimport->array_import_updatekeys[0][$key];
993 $key = preg_replace('/^.*\./i', '', $key);
994 if (isModEnabled("socialnetworks") && strpos($key, "socialnetworks") !== false) {
995 $tmp = explode("_", $key);
996 $key = $tmp[0];
997 $socialnetwork = $tmp[1];
998 $jsondata = $data[$key];
999 $json = json_decode($jsondata);
1000 $stringtosearch = json_encode($socialnetwork).':'.json_encode($json->$socialnetwork);
1001 //var_dump($stringtosearch);
1002 //var_dump($this->db->escape($stringtosearch)); // This provide a value for sql string (but not for a like)
1003 $where[] = $key." LIKE '%".$this->db->escape($this->db->escapeforlike($stringtosearch))."%'";
1004 $filters[] = $col." LIKE '%".$this->db->escape($this->db->escapeforlike($stringtosearch))."%'";
1005 //var_dump($where[1]); // This provide a value for sql string inside a like
1006 } else {
1007 $where[] = $key.' = '.$data[$key];
1008 $filters[] = $col.' = '.$data[$key];
1009 }
1010 }
1011 if (!empty($tablewithentity_cache[$tablename])) {
1012 $where[] = "entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
1013 $filters[] = "entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
1014 }
1015 $sqlSelect .= " WHERE " . implode(' AND ', $where);
1016
1017 $resql = $this->db->query($sqlSelect);
1018 if ($resql) {
1019 $num_rows = $this->db->num_rows($resql);
1020 if ($num_rows == 1) {
1021 $res = $this->db->fetch_object($resql);
1022 $lastinsertid = $res->rowid;
1023 $keyfield = 'rowid';
1024 if ($is_table_category_link) {
1025 $lastinsertid = 'linktable';
1026 } // 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
1027 $last_insert_id_array[$tablename] = $lastinsertid;
1028 } elseif ($num_rows > 1) {
1029 $this->errors[$error]['lib'] = $langs->trans('MultipleRecordFoundWithTheseFilters', implode(', ', $filters));
1030 $this->errors[$error]['type'] = 'SQL';
1031 $error++;
1032 } else {
1033 // No record found with filters, insert will be tried below
1034 }
1035 } else {
1036 //print 'E';
1037 $this->errors[$error]['lib'] = $this->db->lasterror();
1038 $this->errors[$error]['type'] = 'SQL';
1039 $error++;
1040 }
1041 } else {
1042 // We have a last INSERT ID (got by previous pass), so we check if we have a row referencing this foreign key.
1043 // This is required when updating table with some extrafields. When inserting a record in parent table, we can make
1044 // a direct insert into subtable extrafields, but when me wake an update, the insertid is defined and the child record
1045 // may already exists. So we rescan the extrafield table to know if record exists or not for the rowid.
1046 // Note: For extrafield tablename, we have in importfieldshidden_array an entry 'extra.fk_object'=>'lastrowid-tableparent' so $keyfield is 'fk_object'
1047 $sqlSelect = "SELECT rowid FROM " . $tablename;
1048 if (empty($keyfield)) {
1049 $keyfield = 'rowid';
1050 }
1051
1052 $sqlSelect .= " WHERE ".$keyfield." = ".((int) $lastinsertid);
1053
1054 if (!empty($tablewithentity_cache[$tablename])) {
1055 $sqlSelect .= " AND entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
1056 }
1057
1058 $resql = $this->db->query($sqlSelect);
1059 if ($resql) {
1060 $res = $this->db->fetch_object($resql);
1061 if ($this->db->num_rows($resql) == 1) {
1062 // We have a row referencing this last foreign key, continue with UPDATE.
1063 } else {
1064 // No record found referencing this last foreign key,
1065 // force $lastinsertid to 0 so we INSERT below.
1066 $lastinsertid = 0;
1067 }
1068 } else {
1069 //print 'E';
1070 $this->errors[$error]['lib'] = $this->db->lasterror();
1071 $this->errors[$error]['type'] = 'SQL';
1072 $error++;
1073 }
1074 }
1075
1076 if (!empty($lastinsertid)) {
1077 // We db escape social network field because he isn't in field creation
1078 if (in_array("socialnetworks", $listfields)) {
1079 $socialkey = array_search("socialnetworks", $listfields);
1080 $tmpsql = $listvalues[$socialkey];
1081 $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'";
1082 }
1083
1084 // Build SQL UPDATE request
1085 $sqlstart = "UPDATE " . $tablename;
1086
1087 $data = array_combine($listfields, $listvalues);
1088 $set = array();
1089 foreach ($data as $key => $val) {
1090 $set[] = $key." = ".$val; // $val was escaped/sanitized previously
1091 }
1092 $sqlstart .= " SET " . implode(', ', $set) . ", import_key = '" . $this->db->escape($importid) . "'";
1093 if (empty($keyfield)) {
1094 $keyfield = 'rowid';
1095 }
1096
1097 $sqlend = " WHERE " . $keyfield . " = ".((int) $lastinsertid);
1098
1099 if ($is_table_category_link) {
1100 '@phan-var-force string[] $where';
1101 $sqlend = " WHERE " . implode(' AND ', $where);
1102 }
1103
1104 if (!empty($tablewithentity_cache[$tablename])) {
1105 $sqlend .= " AND entity IN (".getEntity($this->getElementFromTableWithPrefix($tablename)).")";
1106 }
1107
1108 $sql = $sqlstart . $sqlend;
1109
1110 // Run update request
1111 $resql = $this->db->query($sql);
1112 if ($resql) {
1113 // No error, update has been done. $this->db->db->affected_rows can be 0 if data hasn't changed
1114 $updatedone = true;
1115 } else {
1116 //print 'E';
1117 $this->errors[$error]['lib'] = $this->db->lasterror();
1118 $this->errors[$error]['type'] = 'SQL';
1119 $error++;
1120 }
1121 }
1122 }
1123
1124 // Update not done, we do insert
1125 if (!$error && !$updatedone) {
1126 // We db escape social network field because he isn't in field creation
1127 if (in_array("socialnetworks", $listfields)) {
1128 $socialkey = array_search("socialnetworks", $listfields);
1129 $tmpsql = $listvalues[$socialkey];
1130 $listvalues[$socialkey] = "'".$this->db->escape($tmpsql)."'";
1131 }
1132
1133 // Build SQL INSERT request
1134 $sqlstart = "INSERT INTO " . $tablename . "(" . implode(", ", $listfields) . ", import_key";
1135 $sqlend = ") VALUES(" . implode(', ', $listvalues) . ", '" . $this->db->escape($importid) . "'";
1136 if (!empty($tablewithentity_cache[$tablename])) {
1137 $sqlstart .= ", entity";
1138 $sqlend .= ", " . $conf->entity;
1139 }
1140 if (!empty($objimport->array_import_tables_creator[0][$alias])) {
1141 $sqlstart .= ", " . $objimport->array_import_tables_creator[0][$alias];
1142 $sqlend .= ", " . $user->id;
1143 }
1144 $sql = $sqlstart . $sqlend . ")";
1145 //dol_syslog("import_xlsx.modules", LOG_DEBUG);
1146
1147 // Run insert request
1148 if ($sql) {
1149 $resql = $this->db->query($sql);
1150 if ($resql) {
1151 if (!$is_table_category_link) {
1152 $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).
1153 }
1154 $insertdone = true;
1155 } else {
1156 //print 'E';
1157 $this->errors[$error]['lib'] = $this->db->lasterror();
1158 $this->errors[$error]['type'] = 'SQL';
1159 $error++;
1160 }
1161 }
1162 }
1163 }
1164 /*else
1165 {
1166 dol_print_error(null,'ErrorFieldListEmptyFor '.$alias."/".$tablename);
1167 }*/
1168 }
1169
1170 if ($error) {
1171 break;
1172 }
1173 }
1174
1175 if ($updatedone) {
1176 $this->nbupdate++;
1177 }
1178 if ($insertdone) {
1179 $this->nbinsert++;
1180 }
1181 }
1182
1183 return 1;
1184 }
1185}
versionphparray()
Return version PHP.
versioncompare($versionarray1, $versionarray2)
Compare 2 versions (stored into 2 arrays), to know if a version (a,b,c) is lower than (x,...
Definition admin.lib.php:71
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:431
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.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
testSqlAndScriptInject($val, $type)
Security: WAF layer for SQL Injection and XSS Injection (scripts) protection (Filters on GET,...
Definition waf.inc.php:103