dolibarr 22.0.5
import.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2005-2016 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
4 * Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
5 * Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
6 * Copyright (C) 2024-2025 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 */
22
29require_once '../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
31require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
32require_once DOL_DOCUMENT_ROOT.'/imports/class/import.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/modules/import/modules_import.php';
34require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
35require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
36require_once DOL_DOCUMENT_ROOT.'/core/lib/import.lib.php';
37
46// Load translation files required by the page
47$langs->loadLangs(array('exports', 'compta', 'errors', 'projects', 'admin'));
48
49// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
50$hookmanager->initHooks(array('imports'));
51
52// Security check
53$result = restrictedArea($user, 'import');
54
55// Map icons, array duplicated in export.php, was not synchronized, TODO put it somewhere only once
56$entitytoicon = array(
57 'invoice' => 'bill',
58 'invoice_line' => 'bill',
59 'order' => 'order',
60 'order_line' => 'order',
61 'propal' => 'propal',
62 'propal_line' => 'propal',
63 'intervention' => 'intervention',
64 'inter_line' => 'intervention',
65 'member' => 'user',
66 'member_type' => 'group',
67 'subscription' => 'payment',
68 'payment' => 'payment',
69 'tax' => 'bill',
70 'tax_type' => 'generic',
71 'other' => 'generic',
72 'account' => 'account',
73 'product' => 'product',
74 'virtualproduct' => 'product',
75 'subproduct' => 'product',
76 'product_supplier_ref' => 'product',
77 'stock' => 'stock',
78 'warehouse' => 'stock',
79 'batch' => 'stock',
80 'stockbatch' => 'stock',
81 'category' => 'category',
82 'shipment' => 'sending',
83 'shipment_line' => 'sending',
84 'reception' => 'sending',
85 'reception_line' => 'sending',
86 'expensereport' => 'trip',
87 'expensereport_line' => 'trip',
88 'holiday' => 'holiday',
89 'contract_line' => 'contract',
90 'translation' => 'generic',
91 'bomm' => 'bom',
92 'bomline' => 'bom'
93);
94
95// Translation code, array duplicated in export.php, was not synchronized, TODO put it somewhere only once
96$entitytolang = array(
97 'user' => 'User',
98 'company' => 'Company',
99 'contact' => 'Contact',
100 'invoice' => 'Bill',
101 'invoice_line' => 'InvoiceLine',
102 'order' => 'Order',
103 'order_line' => 'OrderLine',
104 'propal' => 'Proposal',
105 'propal_line' => 'ProposalLine',
106 'intervention' => 'Intervention',
107 'inter_line' => 'InterLine',
108 'member' => 'Member',
109 'member_type' => 'MemberType',
110 'subscription' => 'Subscription',
111 'tax' => 'SocialContribution',
112 'tax_type' => 'DictionarySocialContributions',
113 'account' => 'BankTransactions',
114 'payment' => 'Payment',
115 'product' => 'Product',
116 'virtualproduct' => 'AssociatedProducts',
117 'subproduct' => 'SubProduct',
118 'product_supplier_ref' => 'SupplierPrices',
119 'service' => 'Service',
120 'stock' => 'Stock',
121 'movement' => 'StockMovement',
122 'batch' => 'Batch',
123 'stockbatch' => 'StockDetailPerBatch',
124 'warehouse' => 'Warehouse',
125 'category' => 'Category',
126 'other' => 'Other',
127 'trip' => 'TripsAndExpenses',
128 'shipment' => 'Shipments',
129 'shipment_line' => 'ShipmentLine',
130 'project' => 'Projects',
131 'projecttask' => 'Tasks',
132 'task_time' => 'TaskTimeSpent',
133 'action' => 'Event',
134 'expensereport' => 'ExpenseReport',
135 'expensereport_line' => 'ExpenseReportLine',
136 'holiday' => 'TitreRequestCP',
137 'contract' => 'Contract',
138 'contract_line' => 'ContractLine',
139 'translation' => 'Translation',
140 'bom' => 'BOM',
141 'bomline' => 'BOMLine'
142);
143
144$datatoimport = GETPOST('datatoimport');
145$format = GETPOST('format');
146$filetoimport = GETPOST('filetoimport');
147$action = GETPOST('action', 'alpha');
148$confirm = GETPOST('confirm', 'alpha');
149$step = (GETPOST('step') ? GETPOST('step') : 1);
150$import_name = GETPOST('import_name');
151$hexa = GETPOST('hexa');
152$importmodelid = GETPOSTINT('importmodelid');
153$excludefirstline = (GETPOST('excludefirstline') ? GETPOST('excludefirstline') : 2);
154$endatlinenb = (GETPOST('endatlinenb') ? GETPOST('endatlinenb') : '');
155$updatekeys = (GETPOST('updatekeys', 'array') ? GETPOST('updatekeys', 'array') : array());
156$separator = (GETPOST('separator', 'nohtml') ? GETPOST('separator', 'nohtml', 3) : '');
157$enclosure = (GETPOST('enclosure', 'nohtml') ? GETPOST('enclosure', 'nohtml') : '"'); // We must use 'nohtml' and not 'alphanohtml' because we must accept "
158$charset = GETPOST('charset', 'aZ09');
159$separator_used = str_replace('\t', "\t", $separator);
160$relativepath = '';
161
162$objimport = new Import($db);
163$objimport->load_arrays($user, ($step == 1 ? '' : $datatoimport));
164
165if (empty($updatekeys) && !empty($objimport->array_import_preselected_updatekeys[0])) {
166 $updatekeys = $objimport->array_import_preselected_updatekeys[0];
167}
168
169$objmodelimport = new ModeleImports();
170
171$form = new Form($db);
172$htmlother = new FormOther($db);
173$formfile = new FormFile($db);
174
175// Init $array_match_file_to_database from _SESSION
176if (empty($array_match_file_to_database)) {
177 $serialized_array_match_file_to_database = isset($_SESSION["dol_array_match_file_to_database_select"]) ? $_SESSION["dol_array_match_file_to_database_select"] : '';
178 $array_match_file_to_database = array();
179 $fieldsarray = explode(',', $serialized_array_match_file_to_database);
180 foreach ($fieldsarray as $elem) {
181 $tabelem = explode('=', $elem, 2);
182 $key = $tabelem[0];
183 $val = (isset($tabelem[1]) ? $tabelem[1] : '');
184 if ($key && $val) {
185 $array_match_file_to_database[$key] = $val;
186 }
187 }
188}
189
190
191/*
192 * Actions
193 */
194
195if ($action == 'deleteprof' && $user->hasRight('import', 'run')) {
196 if (GETPOSTINT("id")) {
197 $objimport->fetch(GETPOSTINT("id"));
198 $result = $objimport->delete($user);
199 }
200}
201
202// Save import config to database
203if ($action == 'add_import_model' && $user->hasRight('import', 'run')) {
204 if ($import_name) {
205 // Set save string
206 $hexa = '';
207 foreach ($array_match_file_to_database as $key => $val) {
208 if ($hexa) {
209 $hexa .= ',';
210 }
211 $hexa .= $key.'='.$val;
212 }
213
214 $objimport->model_name = $import_name;
215 $objimport->datatoimport = $datatoimport;
216 $objimport->hexa = $hexa;
217 $objimport->fk_user = (GETPOST('visibility', 'aZ09') == 'all' ? 0 : $user->id);
218
219 $result = $objimport->create($user);
220 if ($result >= 0) {
221 setEventMessages($langs->trans("ImportModelSaved", $objimport->model_name), null, 'mesgs');
222 $import_name = '';
223 } else {
224 $langs->load("errors");
225 if ($objimport->errno == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
226 setEventMessages($langs->trans("ErrorImportDuplicateProfil"), null, 'errors');
227 } else {
228 setEventMessages($objimport->error, null, 'errors');
229 }
230 }
231 } else {
232 setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ImportModelName")), null, 'errors');
233 }
234}
235
236if ($step == 3 && $datatoimport) {
237 if (GETPOST('sendit') && getDolGlobalString('MAIN_UPLOAD_DOC')) {
238 dol_mkdir($conf->import->dir_temp);
239 $nowyearmonth = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
240
241 $fullpath = $conf->import->dir_temp."/".$nowyearmonth.'-'.dol_string_nohtmltag(dol_sanitizeFileName($_FILES['userfile']['name']));
242 if (dol_move_uploaded_file($_FILES['userfile']['tmp_name'], $fullpath, 1) > 0) {
243 dol_syslog("File ".$fullpath." was added for import");
244 } else {
245 $langs->load("errors");
246 setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
247 }
248 }
249
250 // Delete file
251 if ($action == 'confirm_deletefile' && $confirm == 'yes' && $user->hasRight('import', 'run')) {
252 $langs->load("other");
253
254 $param = '&datatoimport='.urlencode($datatoimport).'&format='.urlencode($format);
255 if ($excludefirstline) {
256 $param .= '&excludefirstline='.urlencode($excludefirstline);
257 }
258 if ($endatlinenb) {
259 $param .= '&endatlinenb='.urlencode($endatlinenb);
260 }
261
262 $file = $conf->import->dir_temp.'/'.GETPOST('urlfile');
263 $ret = dol_delete_file($file);
264 if ($ret) {
265 setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
266 } else {
267 setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
268 }
269 header('Location: '.$_SERVER["PHP_SELF"].'?step='.$step.$param);
270 exit;
271 }
272}
273
274if ($step == 4 && $action == 'select_model' && $user->hasRight('import', 'run')) {
275 // Reinit match arrays
276 $_SESSION["dol_array_match_file_to_database"] = '';
277 $serialized_array_match_file_to_database = '';
278 $array_match_file_to_database = array();
279
280 // Load model from $importmodelid and set $array_match_file_to_database
281 // and $_SESSION["dol_array_match_file_to_database"]
282 $result = $objimport->fetch($importmodelid);
283 if ($result > 0) {
284 $serialized_array_match_file_to_database = $objimport->hexa;
285 $fieldsarray = explode(',', $serialized_array_match_file_to_database);
286 foreach ($fieldsarray as $elem) {
287 $tabelem = explode('=', $elem);
288 $key = $tabelem[0];
289 $val = $tabelem[1];
290 if ($key && $val) {
291 $array_match_file_to_database[$key] = $val;
292 }
293 }
294 $_SESSION["dol_array_match_file_to_database"] = $serialized_array_match_file_to_database;
295 $_SESSION['dol_array_match_file_to_database_select'] = $_SESSION["dol_array_match_file_to_database"];
296 }
297}
298if ($action == 'saveselectorder' && $user->hasRight('import', 'run')) {
299 // Enregistrement de la position des champs
300 $serialized_array_match_file_to_database = '';
301 dol_syslog("selectorder=".GETPOST('selectorder'), LOG_DEBUG);
302 $selectorder = explode(",", GETPOST('selectorder'));
303 $fieldtarget = $fieldstarget = $objimport->array_import_fields[0];
304 foreach ($selectorder as $key => $code) {
305 $serialized_array_match_file_to_database .= $key.'='.$code;
306 $serialized_array_match_file_to_database .= ',';
307 }
308 $serialized_array_match_file_to_database = substr($serialized_array_match_file_to_database, 0, -1);
309 dol_syslog('dol_array_match_file_to_database_select='.$serialized_array_match_file_to_database);
310 $_SESSION["dol_array_match_file_to_database_select"] = $serialized_array_match_file_to_database;
311 echo "{}";
312 exit(0);
313}
314
315
316/*
317 * View
318 */
319
320$help_url = 'EN:Module_Imports_En|FR:Module_Imports|ES:M&oacute;dulo_Importaciones';
321
322// STEP 1: Page to select dataset to import
323if ($step == 1 || !$datatoimport) {
324 // Clean saved file-database matching
325 $serialized_array_match_file_to_database = '';
326 $array_match_file_to_database = array();
327 $_SESSION["dol_array_match_file_to_database"] = '';
328 $_SESSION["dol_array_match_file_to_database_select"] = '';
329
330 $param = '';
331 if ($excludefirstline) {
332 $param .= '&excludefirstline='.urlencode($excludefirstline);
333 }
334 if ($endatlinenb) {
335 $param .= '&endatlinenb='.urlencode($endatlinenb);
336 }
337 if ($separator) {
338 $param .= '&separator='.urlencode($separator);
339 }
340 if ($enclosure) {
341 $param .= '&enclosure='.urlencode($enclosure);
342 }
343
344 llxHeader('', $langs->trans("NewImport"), $help_url);
345
346 $head = import_prepare_head($param, 1);
347
348 print dol_get_fiche_head($head, 'step1', 'Import', -1, 'upload');
349
350 print '<div class="opacitymedium">'.$langs->trans("SelectImportDataSet").'</div>';
351
352
353 // Define $nbmodulesnotautoenabled - TODO This code is at different places
354 $nbmodulesnotautoenabled = count($conf->modules);
355 $listofmodulesautoenabled = array('user', 'agenda', 'fckeditor', 'export', 'import');
356 foreach ($listofmodulesautoenabled as $moduleautoenable) {
357 if (in_array($moduleautoenable, $conf->modules)) {
358 $nbmodulesnotautoenabled--;
359 }
360 }
361
362 if ($user->admin && $nbmodulesnotautoenabled < getDolGlobalInt('MAIN_MIN_NB_ENABLED_MODULE_FOR_WARNING', 1)) { // If only minimal initial modules enabled
363 print info_admin($langs->trans("WarningOnlyProfilesOfActivatedModules").' '.$langs->trans("YouCanEnableModulesFrom"));
364 }
365
366 print '<br>';
367
368 // Show profile for import
369 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
370 print '<table class="noborder centpercent nomarginbottom">';
371 print '<tr class="liste_titre">';
372 print '<td>'.$langs->trans("Module").'</td>';
373 print '<td>'.$langs->trans("ImportableDatas").'</td>';
374 print '<td>&nbsp;</td>';
375 print '</tr>';
376
377 if (count($objimport->array_import_module)) {
378 $sortedarrayofmodules = dol_sort_array($objimport->array_import_module, 'position_of_profile', 'asc', 0, 0, 1);
379 foreach ($sortedarrayofmodules as $key => $value) {
380 //var_dump($key.' '.$value['position_of_profile'].' '.$value['import_code'].' '.$objimport->array_import_module[$key]['module']->getName().' '.$objimport->array_import_code[$key]);
381 $titleofmodule = $objimport->array_import_module[$key]['module']->getName();
382 print '<tr class="oddeven"><td class="tdoverflowmax200" title="'.dolPrintHTML($titleofmodule).'">';
383 // Special case for import common to module/services
384 if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
385 $titleofmodule = $langs->trans("ProductOrService");
386 }
387 print dolPrintHTML($titleofmodule);
388 print '</td><td>';
389 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]);
390 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
391 $label = $objimport->array_import_label[$key];
392 print '<div class="twolinesmax-normallineheight minwidth200onall">';
393 print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon, 'class="pictofixedwidth"');
394 print dolPrintHTML($label);
395 print '</div>';
396 print '</td><td style="text-align: right">';
397 if ($objimport->array_import_perms[$key]) {
398 print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=2&datatoimport='.$objimport->array_import_code[$key].$param.'">'.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').'</a>';
399 } else {
400 print $langs->trans("NotEnoughPermissions");
401 }
402 print '</td></tr>';
403 }
404 } else {
405 print '<tr><td class="oddeven" colspan="3">'.$langs->trans("NoImportableData").'</td></tr>';
406 }
407 print '</table>';
408 print '</div>';
409
410 print dol_get_fiche_end();
411}
412
413
414// STEP 2: Page to select input format file
415if ($step == 2 && $datatoimport) {
416 $param = '&datatoimport='.urlencode($datatoimport);
417 if ($excludefirstline) {
418 $param .= '&excludefirstline='.urlencode($excludefirstline);
419 }
420 if ($endatlinenb) {
421 $param .= '&endatlinenb='.urlencode($endatlinenb);
422 }
423 if ($separator) {
424 $param .= '&separator='.urlencode($separator);
425 }
426 if ($enclosure) {
427 $param .= '&enclosure='.urlencode($enclosure);
428 }
429
430 llxHeader('', $langs->trans("NewImport"), $help_url);
431
432 $head = import_prepare_head($param, 2);
433
434 print dol_get_fiche_head($head, 'step2', 'Import', -2, 'upload');
435
436 print '<div class="underbanner clearboth"></div>';
437 print '<div class="fichecenter">';
438
439 print '<table class="border tableforfield centpercent">';
440
441 // Module
442 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
443 print '<td>';
444 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
445 // Special case for import common to module/services
446 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
447 $titleofmodule = $langs->trans("ProductOrService");
448 }
449 print $titleofmodule;
450 print '</td></tr>';
451
452 // Dataset to import
453 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
454 print '<td>';
455 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
456 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
457 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
458 print $objimport->array_import_label[0];
459 print '</td></tr>';
460
461 print '</table>';
462 print '</div>';
463
464 print dol_get_fiche_end();
465
466 print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
467 print '<input type="hidden" name="token" value="'.newToken().'">';
468
469 print '<br>';
470
471 print '<span class="opacitymedium">';
472 $s = $langs->trans("ChooseFormatOfFileToImport", '{s1}');
473 $s = str_replace('{s1}', img_picto('', 'next'), $s);
474 print $s;
475 print '</span><br><br>';
476
477 print '<br>';
478
479 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
480 print '<table class="noborder centpercent" cellpadding="4">';
481
482 $filetoimport = '';
483
484 // Add format information and link to download example
485 print '<tr class="liste_titre"><td colspan="5">';
486 print $langs->trans("FileMustHaveOneOfFollowingFormat");
487 print '</td></tr>';
488 $list = $objmodelimport->listOfAvailableImportFormat($db);
489 foreach ($list as $key) {
490 print '<tr class="oddeven">';
491 print '<td width="16">'.img_picto_common($key, $objmodelimport->getPictoForKey($key)).'</td>';
492 $htmltext = $objmodelimport->getDriverDescForKey($key);
493 print '<td>'.$form->textwithpicto($objmodelimport->getDriverLabelForKey($key), $htmltext).'</td>';
494 print '<td style="text-align:center">';
495 if (empty($objmodelimport->drivererror[$key])) {
496 $filename = $langs->transnoentitiesnoconv("ExampleOfImportFile").'_'.$datatoimport.'.'.$key;
497 print '<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.$param.'&output=file&file='.urlencode($filename).'" target="_blank" rel="noopener noreferrer">';
498 print img_picto('', 'download', 'class="paddingright opacitymedium"');
499 print $langs->trans("DownloadEmptyExampleShort");
500 print '</a>';
501 print $form->textwithpicto('', $langs->trans("DownloadEmptyExample").'.<br>'.$langs->trans("StarAreMandatory"));
502 } else {
503 print dolPrintHTML($objmodelimport->drivererror[$key]);
504 }
505 print '</td>';
506 // Action button
507 print '<td style="text-align:right">';
508 if (empty($objmodelimport->drivererror[$key])) {
509 print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=3&format='.$key.$param.'">'.img_picto($langs->trans("SelectFormat"), 'next', 'class="fa-15"').'</a>';
510 }
511 print '</td>';
512 print '</tr>';
513 }
514
515 print '</table>';
516 print '</div>';
517
518 print '</form>';
519}
520
521
522// STEP 3: Page to select file
523if ($step == 3 && $datatoimport) {
524 $param = '&datatoimport='.urlencode($datatoimport).'&format='.urlencode($format);
525 if ($excludefirstline) {
526 $param .= '&excludefirstline='.urlencode($excludefirstline);
527 }
528 if ($endatlinenb) {
529 $param .= '&endatlinenb='.urlencode($endatlinenb);
530 }
531 if ($separator) {
532 $param .= '&separator='.urlencode($separator);
533 }
534 if ($enclosure) {
535 $param .= '&enclosure='.urlencode($enclosure);
536 }
537
538 $list = $objmodelimport->listOfAvailableImportFormat($db);
539
540 llxHeader('', $langs->trans("NewImport"), $help_url);
541
542 $head = import_prepare_head($param, 3);
543
544 print dol_get_fiche_head($head, 'step3', 'Import', -2, 'upload');
545
546 /*
547 * Confirm delete file
548 */
549 if ($action == 'delete') {
550 print $form->formconfirm($_SERVER["PHP_SELF"].'?urlfile='.urlencode(GETPOST('urlfile')).'&step=3'.$param, $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1);
551 }
552
553 print '<div class="underbanner clearboth"></div>';
554 print '<div class="fichecenter">';
555
556 print '<table class="border tableforfield centpercent">';
557
558 // Module
559 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
560 print '<td>';
561 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
562 // Special case for import common to module/services
563 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
564 $titleofmodule = $langs->trans("ProductOrService");
565 }
566 print $titleofmodule;
567 print '</td></tr>';
568
569 // Lot de donnees a importer
570 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
571 print '<td>';
572 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
573 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
574 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
575 print $objimport->array_import_label[0];
576 print '</td></tr>';
577
578 print '</table>';
579 print '</div>';
580
581 print '<br>';
582
583 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
584
585 print '<div class="underbanner clearboth"></div>';
586 print '<div class="fichecenter">';
587 print '<table width="100%" class="border tableforfield">';
588
589 // Source file format
590 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
591 print '<td class="nowraponall">';
592 $text = $objmodelimport->getDriverDescForKey($format);
593 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
594 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
595 print '</td><td style="text-align:right" class="nowrap">';
596 $filename = $langs->transnoentitiesnoconv("ExampleOfImportFile").'_'.$datatoimport.'.'.$format;
597 print '<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$format.$param.'&output=file&file='.urlencode($filename).'" target="_blank" rel="noopener noreferrer">';
598 print img_picto('', 'download', 'class="paddingright opacitymedium"');
599 print $langs->trans("DownloadEmptyExampleShort");
600 print '</a>';
601 print $form->textwithpicto('', $langs->trans("DownloadEmptyExample").'.<br>'.$langs->trans("StarAreMandatory"));
602 print '</td></tr>';
603
604 print '</table>';
605 print '</div>';
606
607 print dol_get_fiche_end();
608
609
610 if ($format == 'xlsx' && !class_exists('XMLWriter')) {
611 $langs->load("install");
612 print info_admin($langs->trans("ErrorPHPDoesNotSupport", 'php-xml'), 0, 0, '1', 'error');
613 }
614
615
616 print '<br><br>';
617
618 print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" method="POST">';
619 print '<input type="hidden" name="token" value="'.newToken().'">';
620 print '<input type="hidden" value="'.$step.'" name="step">';
621 print '<input type="hidden" value="'.dol_escape_htmltag($format).'" name="format">';
622 print '<input type="hidden" value="'.$excludefirstline.'" name="excludefirstline">';
623 print '<input type="hidden" value="'.$endatlinenb.'" name="endatlinenb">';
624 print '<input type="hidden" value="'.dol_escape_htmltag($separator).'" name="separator">';
625 print '<input type="hidden" value="'.dol_escape_htmltag($enclosure).'" name="enclosure">';
626 print '<input type="hidden" value="'.dol_escape_htmltag($datatoimport).'" name="datatoimport">';
627
628 print '<span class="opacitymedium">';
629 $s = $langs->trans("ChooseFileToImport", '{s1}');
630 $s = str_replace('{s1}', img_picto('', 'next'), $s);
631 print $s;
632 print '</span><br><br>';
633
634 $filetoimport = '';
635
636 // Input file name box
637 print '<div class="marginbottomonly">';
638 $maxfilesizearray = getMaxFileSizeArray();
639 $maxmin = $maxfilesizearray['maxmin'];
640 if ($maxmin > 0) {
641 print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
642 }
643 print '<input type="file" name="userfile" size="20" maxlength="80"> &nbsp; &nbsp; ';
644 $out = (!getDolGlobalString('MAIN_UPLOAD_DOC') ? ' disabled' : '');
645 print '<input type="submit" class="button small" value="'.$langs->trans("AddFile").'"'.$out.' name="sendit">';
646 $out = '';
647 if (getDolGlobalString('MAIN_UPLOAD_DOC')) {
648 $max = getDolGlobalString('MAIN_UPLOAD_DOC'); // In Kb
649 $maxphp = @ini_get('upload_max_filesize'); // In unknown
650 if (preg_match('/k$/i', $maxphp)) {
651 $maxphp = (int) substr($maxphp, 0, -1);
652 }
653 if (preg_match('/m$/i', $maxphp)) {
654 $maxphp = (int) substr($maxphp, 0, -1) * 1024;
655 }
656 if (preg_match('/g$/i', $maxphp)) {
657 $maxphp = (int) substr($maxphp, 0, -1) * 1024 * 1024;
658 }
659 if (preg_match('/t$/i', $maxphp)) {
660 $maxphp = (int) substr($maxphp, 0, -1) * 1024 * 1024 * 1024;
661 }
662 $maxphp2 = @ini_get('post_max_size'); // In unknown
663 if (preg_match('/k$/i', $maxphp2)) {
664 $maxphp2 = (int) substr($maxphp2, 0, -1);
665 }
666 if (preg_match('/m$/i', $maxphp2)) {
667 $maxphp2 = (int) substr($maxphp2, 0, -1) * 1024;
668 }
669 if (preg_match('/g$/i', $maxphp2)) {
670 $maxphp2 = (int) substr($maxphp2, 0, -1) * 1024 * 1024;
671 }
672 if (preg_match('/t$/i', $maxphp2)) {
673 $maxphp2 = (int) substr($maxphp2, 0, -1) * 1024 * 1024 * 1024;
674 }
675 // Now $max and $maxphp and $maxphp2 are in Kb
676 $maxmin = $max;
677 $maxphptoshow = $maxphptoshowparam = '';
678 if ($maxphp > 0) {
679 $maxmin = min($max, $maxphp);
680 $maxphptoshow = $maxphp;
681 $maxphptoshowparam = 'upload_max_filesize';
682 }
683 if ($maxphp2 > 0) {
684 $maxmin = min($max, $maxphp2);
685 if ($maxphp2 < $maxphp) {
686 $maxphptoshow = $maxphp2;
687 $maxphptoshowparam = 'post_max_size';
688 }
689 }
690
691 $langs->load('other');
692 $out .= ' ';
693 $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphptoshow), 1);
694 } else {
695 $out .= ' ('.$langs->trans("UploadDisabled").')';
696 }
697 print $out;
698 print '</div>';
699
700 // Search available imports
701 $filearray = dol_dir_list($conf->import->dir_temp, 'files', 0, '', '', 'name', SORT_DESC);
702 if (count($filearray) > 0) {
703 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
704 print '<table class="noborder centpercent" width="100%" cellpadding="4">';
705
706 $dir = $conf->import->dir_temp;
707
708 // Search available files to import
709 $i = 0;
710 foreach ($filearray as $key => $val) {
711 $file = $val['name'];
712
713 // readdir return value in ISO and we want UTF8 in memory
714 if (!utf8_check($file)) {
715 $file = mb_convert_encoding($file, 'UTF-8', 'ISO-8859-1');
716 }
717
718 if (preg_match('/^\./', $file)) {
719 continue;
720 }
721
722 $modulepart = 'import';
723 $urlsource = $_SERVER["PHP_SELF"].'?step='.$step.$param.'&filetoimport='.urlencode($filetoimport);
724 $relativepath = $file;
725
726 print '<tr class="oddeven">';
727 print '<td>';
728 print img_mime($file, '', 'pictofixedwidth');
729 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=3'.$param.'" target="_blank" rel="noopener noreferrer">';
730 print $file;
731 print '</a>';
732 print '</td>';
733 // Affiche taille fichier
734 print '<td style="text-align:right">'.dol_print_size(dol_filesize($dir.'/'.$file)).'</td>';
735 // Affiche date fichier
736 print '<td style="text-align:right">'.dol_print_date(dol_filemtime($dir.'/'.$file), 'dayhour').'</td>';
737 // Del button
738 print '<td style="text-align:right"><a href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&step=3'.$param.'&urlfile='.urlencode($relativepath);
739 print '">'.img_delete().'</a></td>';
740 // Action button
741 print '<td style="text-align:right">';
742 print '<a href="'.$_SERVER['PHP_SELF'].'?step=4'.$param.'&filetoimport='.urlencode($relativepath).'">'.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').'</a>';
743 print '</td>';
744 print '</tr>';
745 }
746
747 print '</table>';
748 print '</div>';
749 }
750
751 print '</form>';
752}
753
754
755// STEP 4: Page to make matching between source file and database fields
756if ($step == 4 && $datatoimport) {
757 //var_dump($_SESSION["dol_array_match_file_to_database_select"]);
758 $serialized_array_match_file_to_database = isset($_SESSION["dol_array_match_file_to_database_select"]) ? $_SESSION["dol_array_match_file_to_database_select"] : '';
759 $fieldsarray = explode(',', $serialized_array_match_file_to_database);
760 $array_match_file_to_database = array(); // Same than $fieldsarray but with mapped value only (col1 => 's.fielda', col2 => 's.fieldb'...)
761 foreach ($fieldsarray as $elem) {
762 $tabelem = explode('=', $elem, 2);
763 $key = $tabelem[0];
764 $val = (isset($tabelem[1]) ? $tabelem[1] : '');
765 if ($key && $val) {
766 $array_match_file_to_database[$key] = $val;
767 }
768 }
769
770 //var_dump($serialized_array_match_file_to_database);
771 //var_dump($fieldsarray);
772 //var_dump($array_match_file_to_database);
773
774 $model = $format;
775 $list = $objmodelimport->listOfAvailableImportFormat($db);
776
777 if (empty($separator)) {
778 $separator = (!getDolGlobalString('IMPORT_CSV_SEPARATOR_TO_USE') ? ',' : $conf->global->IMPORT_CSV_SEPARATOR_TO_USE);
779 }
780
781 // The separator has been defined, if it is a unique char, we check it is valid by reading the source file
782 if ($model == 'csv' && strlen($separator) == 1 && !GETPOSTISSET('separator')) {
783 '@phan-var-force ImportCsv $obj';
784 // Count the char in first line of file.
785 $fh = fopen($conf->import->dir_temp.'/'.$filetoimport, 'r');
786 if ($fh) {
787 $sline = fgets($fh, 1000000);
788 fclose($fh);
789 $nboccurence = substr_count($sline, $separator);
790 $nboccurencea = substr_count($sline, ',');
791 $nboccurenceb = substr_count($sline, ';');
792 //var_dump($nboccurence." ".$nboccurencea." ".$nboccurenceb);exit;
793 if ($nboccurence == 0) {
794 if ($nboccurencea > 2) {
795 $separator = ',';
796 } elseif ($nboccurenceb > 2) {
797 $separator = ';';
798 }
799 }
800 }
801 }
802
803 // The value to use
804 $separator_used = str_replace('\t', "\t", $separator);
805
806 // Create class to use for import
807 $dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
808 $file = "import_".$model.".modules.php";
809 $classname = "Import".ucfirst($model);
810 require_once $dir.$file;
811 $obj = new $classname($db, $datatoimport);
812 '@phan-var-force ModeleImports $obj';
813
814 if (!empty($obj->error)) {
815 $langs->load("errors");
816 $param = '&datatoimport='.$datatoimport.'&format='.$format;
817 setEventMessages($obj->error, null, 'errors');
818 header("Location: ".$_SERVER["PHP_SELF"].'?step=3'.$param.'&filetoimport='.urlencode($relativepath));
819 exit;
820 }
821
822 if ($model == 'csv') {
823 '@phan-var-force ImportCsv $obj';
824 $obj->separator = $separator_used;
825 $obj->enclosure = $enclosure;
826 $obj->charset = '';
827 }
828 if ($model == 'xlsx') {
829 '@phan-var-force ImportXlsx $obj';
830 if (!preg_match('/\.xlsx$/i', $filetoimport)) {
831 $langs->load("errors");
832 $param = '&datatoimport='.$datatoimport.'&format='.$format;
833 setEventMessages($langs->trans("ErrorFileMustHaveFormat", $model), null, 'errors');
834 header("Location: ".$_SERVER["PHP_SELF"].'?step=3'.$param.'&filetoimport='.urlencode($relativepath));
835 exit;
836 }
837 }
838
839 if (GETPOST('update')) {
840 $array_match_file_to_database = array();
841 }
842
843 // Load the source fields from input file into variable $arrayrecord
844 $fieldssource = array();
846 $result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
847 if ($result >= 0) {
848 // Read first line
849 $arrayrecord = $obj->import_read_record();
850
851 // Create array $fieldssource starting with 1 with values found of first line.
852 $i = 1;
853 foreach ($arrayrecord as $key => $val) {
854 if ($val["type"] != -1) {
855 $fieldssource[$i]['example1'] = dol_trunc($val['val'], 128);
856 } else {
857 $fieldssource[$i]['example1'] = $langs->trans('Empty');
858 }
859 $fieldssource[$i]['imported'] = false;
860 $i++;
861 }
862 $obj->import_close_file();
863 }
864
865 // Load targets fields in database
866 $fieldstarget = $objimport->array_import_fields[0];
867 $minpos = min(count($fieldssource), count($fieldstarget));
868 //var_dump($array_match_file_to_database);
869
870
871 $initialloadofstep4 = false;
872 if (empty($_SESSION['dol_array_match_file_to_database_select'])) {
873 $initialloadofstep4 = true;
874 }
875
876 // Is it a first time in page (if yes, we must initialize array_match_file_to_database)
877 if (count($array_match_file_to_database) == 0) {
878 // This is first input in screen, we need to define
879 // $array_match_file_to_database
880 // $serialized_array_match_file_to_database
881 // $_SESSION["dol_array_match_file_to_database"]
882 $pos = 1;
883 $num = count($fieldssource);
884 while ($pos <= $num) {
885 if ($num >= 1 && $pos <= $num) {
886 $posbis = 1;
887 foreach ($fieldstarget as $key => $val) {
888 if ($posbis < $pos) {
889 $posbis++;
890 continue;
891 }
892 // We found the key of targets that is at position pos
893 $array_match_file_to_database[$pos] = $key;
894 break;
895 }
896 }
897 $pos++;
898 }
899 }
900 $array_match_database_to_file = array_flip($array_match_file_to_database);
901 //var_dump($array_match_database_to_file);
902 //var_dump($_SESSION["dol_array_match_file_to_database_select"]);
903
904 $fieldstarget_tmp = array();
905 $arraykeysfieldtarget = array_keys($fieldstarget);
906 $position = 0;
907 foreach ($fieldstarget as $key => $label) {
908 $isrequired = preg_match('/\*$/', $label);
909 if (!empty($isrequired)) {
910 $newlabel = substr($label, 0, -1);
911 $fieldstarget_tmp[$key] = array("label" => $newlabel, "required" => true);
912 } else {
913 $fieldstarget_tmp[$key] = array("label" => $label, "required" => false);
914 }
915 if (!empty($array_match_database_to_file[$key])) {
916 $fieldstarget_tmp[$key]["imported"] = true;
917 $fieldstarget_tmp[$key]["position"] = (int) $array_match_database_to_file[$key] - 1;
918 $keytoswap = $key;
919 while (!empty($array_match_database_to_file[$keytoswap])) {
920 if ($position + 1 > $array_match_database_to_file[$keytoswap]) {
921 $keytoswapwith = $array_match_database_to_file[$keytoswap] - 1;
922 $tmp = [$keytoswap => $fieldstarget_tmp[$keytoswap]];
923 unset($fieldstarget_tmp[$keytoswap]);
924 $fieldstarget_tmp = arrayInsert($fieldstarget_tmp, $keytoswapwith, $tmp);
925 $keytoswapwith = $arraykeysfieldtarget[$array_match_database_to_file[$keytoswap] - 1];
926 $tmp = $fieldstarget_tmp[$keytoswapwith];
927 unset($fieldstarget_tmp[$keytoswapwith]);
928 $fieldstarget_tmp[$keytoswapwith] = $tmp;
929 $keytoswap = $keytoswapwith;
930 } else {
931 break;
932 }
933 }
934 } else {
935 $fieldstarget_tmp[$key]["imported"] = false;
936 }
937 $position++;
938 }
939 $fieldstarget = $fieldstarget_tmp;
940
941 //print $serialized_array_match_file_to_database;
942 //print $_SESSION["dol_array_match_file_to_database"];
943 //print $_SESSION["dol_array_match_file_to_database_select"];
944 //var_dump($array_match_file_to_database);exit;
945
946 // Now $array_match_file_to_database contains fieldnb(1,2,3...)=>fielddatabase(key in $array_match_file_to_database)
947
948 $param = '&format='.$format.'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport);
949 if ($excludefirstline) {
950 $param .= '&excludefirstline='.urlencode($excludefirstline);
951 }
952 if ($endatlinenb) {
953 $param .= '&endatlinenb='.urlencode($endatlinenb);
954 }
955 if ($separator) {
956 $param .= '&separator='.urlencode($separator);
957 }
958 if ($enclosure) {
959 $param .= '&enclosure='.urlencode($enclosure);
960 }
961
962 llxHeader('', $langs->trans("NewImport"), $help_url);
963
964 $head = import_prepare_head($param, 4);
965
966 print dol_get_fiche_head($head, 'step4', 'Import', -2, 'upload');
967
968 print '<div class="underbanner clearboth"></div>';
969 print '<div class="fichecenter">';
970
971 print '<table class="centpercent border tableforfield">';
972
973 // Module
974 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
975 print '<td>';
976 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
977 // Special case for import common to module/services
978 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
979 $titleofmodule = $langs->trans("ProductOrService");
980 }
981 print $titleofmodule;
982 print '</td></tr>';
983
984 // Lot de donnees a importer
985 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
986 print '<td>';
987 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
988 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
989 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
990 print $objimport->array_import_label[0];
991 print '</td></tr>';
992
993 print '</table>';
994 print '</div>';
995
996 print '<br>';
997
998 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
999
1000 print '<div class="underbanner clearboth"></div>';
1001 print '<div class="fichecenter">';
1002 print '<table width="100%" class="border tableforfield">';
1003
1004 // Source file format
1005 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
1006 print '<td class="nowraponall">';
1007 $text = $objmodelimport->getDriverDescForKey($format);
1008 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1009 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
1010 print '</td></tr>';
1011
1012 // Separator and enclosure
1013 if ($model == 'csv') {
1014 '@phan-var-force ImportCsv $obj';
1015 print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
1016 print '<td>';
1017 print '<form method="POST">';
1018 print '<input type="hidden" name="token" value="'.newToken().'">';
1019 print '<input type="hidden" value="'.$step.'" name="step">';
1020 print '<input type="hidden" value="'.$format.'" name="format">';
1021 print '<input type="hidden" value="'.$excludefirstline.'" name="excludefirstline">';
1022 print '<input type="hidden" value="'.$endatlinenb.'" name="endatlinenb">';
1023 print '<input type="hidden" value="'.$datatoimport.'" name="datatoimport">';
1024 print '<input type="hidden" value="'.$filetoimport.'" name="filetoimport">';
1025 print $langs->trans("Separator").' : ';
1026 print '<input type="text" class="width25 center" name="separator" value="'.dol_escape_htmltag($separator).'"/>';
1027 print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : ';
1028 print '<input type="text" class="width25 center" name="enclosure" value="'.dol_escape_htmltag($enclosure).'"/> ';
1029 print '<input name="update" type="submit" value="'.$langs->trans('Update').'" class="button smallpaddingimp" />';
1030 print '</form>';
1031 print '</td></tr>';
1032 }
1033
1034 // File to import
1035 print '<tr><td>'.$langs->trans("FileToImport").'</td>';
1036 print '<td>';
1037 $modulepart = 'import';
1038 $relativepath = GETPOST('filetoimport');
1039 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
1040 print img_mime($file, '', 'pictofixedwidth');
1041 print $filetoimport;
1042 print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"');
1043 print '</a>';
1044 print '</td></tr>';
1045
1046 print '</table>';
1047 print '</div>';
1048
1049 print dol_get_fiche_end();
1050
1051 print '<br>'."\n";
1052
1053
1054 // List of source fields
1055 print '<!-- List of source fields -->'."\n";
1056 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1057 print '<input type="hidden" name="token" value="'.newToken().'">';
1058 print '<input type="hidden" name="action" value="select_model">';
1059 print '<input type="hidden" name="step" value="4">';
1060 print '<input type="hidden" name="format" value="'.$format.'">';
1061 print '<input type="hidden" name="datatoimport" value="'.$datatoimport.'">';
1062 print '<input type="hidden" name="filetoimport" value="'.$filetoimport.'">';
1063 print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
1064 print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
1065 print '<input type="hidden" name="separator" value="'.dol_escape_htmltag($separator).'">';
1066 print '<input type="hidden" name="enclosure" value="'.dol_escape_htmltag($enclosure).'">';
1067
1068 // Import profile to use/load
1069 print '<div class="marginbottomonly">';
1070 print '<span class="opacitymedium">';
1071 $s = $langs->trans("SelectImportFieldsSource", '{s1}');
1072 $s = str_replace('{s1}', img_picto('', 'grip_title', '', 0, 0, 0, '', '', 0), $s);
1073 print $s;
1074 print '</span> ';
1075 $htmlother->select_import_model((string) $importmodelid, 'importmodelid', $datatoimport, 1, $user->id);
1076 print '<input type="submit" class="button smallpaddingimp reposition" value="'.$langs->trans("Select").'">';
1077 print '</div>';
1078 print '</form>';
1079
1080 // Title of array with fields
1081 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
1082 print '<table class="noborder centpercent">';
1083 print '<tr class="liste_titre">';
1084 print '<td>'.$langs->trans("FieldsInSourceFile").'</td>';
1085 print '<td>'.$langs->trans("FieldsInTargetDatabase").'</td>';
1086 print '</tr>';
1087
1088 //var_dump($array_match_file_to_database);
1089
1090 print '<tr valign="top"><td width="50%" class="nopaddingleftimp">';
1091
1092 $fieldsplaced = array();
1093 $valforsourcefieldnb = array();
1094 $listofkeys = array();
1095 foreach ($array_match_file_to_database as $key => $val) {
1096 $listofkeys[$key] = 1;
1097 }
1098
1099 print "\n<!-- Box left container -->\n";
1100 print '<div id="left" class="connectedSortable">'."\n";
1101
1102 // List of source fields
1103
1104 $lefti = 1;
1105 foreach ($fieldssource as $key => $val) {
1106 show_elem($fieldssource, $key, (string) $key); // key is field number in source file @phan-suppress-current-line PhanPluginSuspiciousParamPosition
1107 $listofkeys[$key] = 1;
1108 $fieldsplaced[$key] = 1;
1109 $valforsourcefieldnb[$lefti] = $key;
1110 $lefti++;
1111
1112 /*if ($lefti > count($fieldstarget)) {
1113 break; // Other fields are in the not imported area
1114 }*/
1115 }
1116 //var_dump($valforsourcefieldnb);
1117
1118 print "</div>\n";
1119 print "<!-- End box left container -->\n";
1120
1121
1122 print '</td><td width="50%" class="nopaddingrightimp">';
1123
1124 // Set the list of all possible target fields in Dolibarr.
1125
1126 $optionsall = array();
1127 foreach ($fieldstarget as $code => $line) {
1128 $tmparray = explode('|', $line["label"]); // If label of field is several translation keys separated with |
1129 $labeltoshow = '';
1130 foreach ($tmparray as $tmpkey => $tmpval) {
1131 $labeltoshow .= ($labeltoshow ? ' '.$langs->trans('or').' ' : '').$langs->transnoentities($tmpval);
1132 }
1133 // TODO Get type from a new array into module descriptor.
1134 // $picto = 'email';
1135 $picto = '';
1136 $optionsall[$code] = array(
1137 'labelkey' => $line['label'],
1138 'labelkeyarray' => $tmparray,
1139 'label' => $labeltoshow,
1140 'required' => (empty($line["required"]) ? 0 : 1),
1141 'position' => (!empty($line['position']) ? $line['position'] : 0),
1142 'picto' => $picto,
1143 );
1144 }
1145 // $optionsall is an array of all possible target fields. key=>array('label'=>..., 'xxx')
1146
1147 $height = '32px'; //needs px for css height attribute below
1148 $i = 0;
1149 $mandatoryfieldshavesource = true;
1150
1151 //var_dump($fieldstarget);
1152 //var_dump($optionsall);
1153 //exit;
1154
1155 //var_dump($_SESSION['dol_array_match_file_to_database']);
1156 //var_dump($_SESSION['dol_array_match_file_to_database_select']);
1157 //exit;
1158 //var_dump($optionsall);
1159 //var_dump($fieldssource);
1160 //var_dump($fieldstarget);
1161
1162 $modetoautofillmapping = 'session'; // Use setup in session
1163 if ($initialloadofstep4) {
1164 $modetoautofillmapping = 'guess';
1165 }
1166 //var_dump($modetoautofillmapping);
1167
1168 print '<table class="nobordernopadding centpercent tableimport">';
1169 foreach ($fieldssource as $code => $line) { // $fieldssource is an array code=column num, line=content on first line for column in source file.
1170 /*if ($i == $minpos) {
1171 break;
1172 }*/
1173 //var_dump($line);
1174 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
1175 // Note: $code is int, but index should be fieldname? -> @phan-suppress-next-line PhanTypeMismatchDimFetch
1176 $entity = (!empty($objimport->array_import_entities[0][$code]) ? $objimport->array_import_entities[0][$code] : $objimport->array_import_icon[0]);
1177
1178 $entityicon = !empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity; // $entityicon must string name of picto of the field like 'project', 'company', 'contact', 'modulename', ...
1179 $entitylang = !empty($entitytolang[$entity]) ? $entitytolang[$entity] : $objimport->array_import_label[0]; // $entitylang must be a translation key to describe object the field is related to, like 'Company', 'Contact', 'MyModyle', ...
1180
1181 print '<td class="nowraponall hideonsmartphone" style="font-weight: normal">=> </td>';
1182 print '<td class="nowraponall" style="font-weight: normal">';
1183
1184 $selectforline = '';
1185 $selectforline .= '<select id="selectorderimport_'.($i + 1).'" class="targetselectchange minwidth300" name="select_'.($i + 1).'">';
1186 $selectforline .= '<option value="-1">&nbsp;</option>';
1187
1188 $j = 0;
1189 $codeselectedarray = array();
1190 foreach ($optionsall as $tmpcode => $tmpval) { // Loop on each entry to add into each combo list.
1191 $label = '';
1192 if (!empty($tmpval['picto'])) {
1193 $label .= img_picto('', $tmpval['picto'], 'class="pictofixedwidth"');
1194 }
1195 $label .= $tmpval['required'] ? '<strong>' : '';
1196 $label .= $tmpval['label'];
1197 $label .= $tmpval['required'] ? '*</strong>' : '';
1198
1199 $tablealias = preg_replace('/(\..*)$/i', '', $tmpcode);
1200 $tablename = !empty($objimport->array_import_tables[0][$tablealias]) ? $objimport->array_import_tables[0][$tablealias] : "";
1201
1202 $htmltext = '';
1203
1204 $filecolumn = ($i + 1);
1205 // Source field info
1206 if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need conversion
1207 $filecolumntoshow = num2Alpha($i);
1208 } else {
1209 if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') {
1210 $htmltext .= $langs->trans("DataComeFromIdFoundFromRef", $langs->transnoentitiesnoconv($entitylang)).'<br>';
1211 }
1212 if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') {
1213 $htmltext .= $langs->trans("DataComeFromIdFoundFromCodeId", $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$tmpcode]['dict'])).'<br>';
1214 }
1215 }
1216 // Source required
1217 $example = !empty($objimport->array_import_examplevalues[0][$tmpcode]) ? $objimport->array_import_examplevalues[0][$tmpcode] : "";
1218 // Example
1219 if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need conversion
1220 if ($example) {
1221 $htmltext .= $langs->trans("SourceExample").': <b>'.str_replace('"', '', $example).'</b><br>';
1222 }
1223 } else {
1224 if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') {
1225 $htmltext .= $langs->trans("SourceExample").': <b>'.$langs->transnoentitiesnoconv("ExampleAnyRefFoundIntoElement", $entitylang).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.str_replace('"', '', $example).')' : '').'</b><br>';
1226 } elseif ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') {
1227 $htmltext .= $langs->trans("SourceExample").': <b>'.$langs->trans("ExampleAnyCodeOrIdFoundIntoDictionary", $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$tmpcode]['dict'])).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.str_replace('"', '', $example).')' : '').'</b><br>';
1228 } elseif ($example) {
1229 $htmltext .= $langs->trans("SourceExample").': <b>'.str_replace('"', '', $example).'</b><br>';
1230 }
1231 }
1232 // Format control rule
1233 if (!empty($objimport->array_import_regex[0][$tmpcode])) {
1234 $htmltext .= $langs->trans("FormatControlRule").': <b>'.str_replace('"', '', $objimport->array_import_regex[0][$tmpcode]).'</b><br>';
1235 }
1236
1237 //var_dump($htmltext);
1238 $htmltext .= $langs->trans("InformationOnTargetTables").': &nbsp; <b>'.$tablename."->".preg_replace('/^.*\./', '', $tmpcode)."</b>";
1239
1240 $labelhtml = $label.' '.$form->textwithpicto('', $htmltext, 1, 'help', '', 1);
1241
1242 $selectforline .= '<option value="'.$tmpcode.'"';
1243 if ($modetoautofillmapping == 'orderoftargets') {
1244 // The mode where we fill the preselected value of combo one by one in order of available targets fields in the declaration in descriptor file.
1245 if ($j == $i) {
1246 $selectforline .= ' selected';
1247 }
1248 } elseif ($modetoautofillmapping == 'guess') {
1249 // The mode where we try to guess which value to preselect from the name in first column of source file.
1250 // $line['example1'] is the label of the column found on first line
1251 $regs = array();
1252 if (preg_match('/^(.+)\‍((.+\..+)\‍)$/', $line['example1'], $regs)) { // If text is "Label (x.abc)"
1253 $tmpstring1 = $regs[1];
1254 $tmpstring2 = $regs[2];
1255 } else {
1256 $tmpstring1 = $line['example1'];
1257 $tmpstring2 = '';
1258 }
1259 $tmpstring1 = strtolower(dol_string_unaccent(str_replace('*', '', trim($tmpstring1))));
1260 $tmpstring2 = strtolower(dol_string_unaccent(str_replace('*', '', trim($tmpstring2))));
1261
1262 // $tmpstring1 and $tmpstring2 are string from the input file title of column "Label (fieldname)".
1263 // $tmpval is array of target fields read from the module import profile.
1264 foreach ($tmpval['labelkeyarray'] as $tmpval2) {
1265 $labeltarget = $langs->transnoentities($tmpval2);
1266 //var_dump($tmpstring1.' - '.$tmpstring2.' - '.$tmpval['labelkey'].' - '.$tmpval['label'].' - '.$tmpval2.' - '.$labeltarget);
1267 if ($tmpstring1 && ($tmpstring1 == $tmpcode || $tmpstring1 == strtolower($labeltarget)
1268 || $tmpstring1 == strtolower(dol_string_unaccent($labeltarget)) || $tmpstring1 == strtolower($tmpval2))) {
1269 if (empty($codeselectedarray[$code])) {
1270 $selectforline .= ' selected';
1271 $codeselectedarray[$code] = 1;
1272 break;
1273 }
1274 } elseif ($tmpstring2 && ($tmpstring2 == $tmpcode || $tmpstring2 == strtolower($labeltarget)
1275 || $tmpstring2 == strtolower(dol_string_unaccent($labeltarget)) || $tmpstring2 == strtolower($tmpval2))) {
1276 if (empty($codeselectedarray[$code])) {
1277 $selectforline .= ' selected';
1278 $codeselectedarray[$code] = 1;
1279 break;
1280 }
1281 }
1282 }
1283 } elseif ($modetoautofillmapping == 'session' && !empty($_SESSION['dol_array_match_file_to_database_select'])) {
1284 $tmpselectioninsession = dolExplodeIntoArray($_SESSION['dol_array_match_file_to_database_select'], ',', '=');
1285 //var_dump($code);
1286 if (!empty($tmpselectioninsession[(string) ($i + 1)]) && $tmpselectioninsession[(string) ($i + 1)] == $tmpcode) {
1287 $selectforline .= ' selected';
1288 }
1289 $selectforline .= ' data-debug="'.$tmpcode.'-'.$code.'-'.$j.'-'.(!empty($tmpselectioninsession[(string) ($i + 1)]) ? $tmpselectioninsession[(string) ($i + 1)] : "").'"';
1290 }
1291 $selectforline .= ' data-html="'.dol_escape_htmltag($labelhtml).'"';
1292 $selectforline .= '>';
1293 $selectforline .= $label;
1294 $selectforline .= '</options>';
1295 $j++;
1296 }
1297 $selectforline .= '</select>';
1298 $selectforline .= ajax_combobox('selectorderimport_'.($i + 1));
1299
1300 print $selectforline;
1301
1302 print '</td>';
1303
1304 // Tooltip at end of line
1305 print '<td class="nowraponall" style="font-weight:normal; text-align:right">';
1306
1307 // Source field info
1308 $htmltext = '<b><u>'.$langs->trans("FieldSource").'</u></b><br>';
1309 $filecolumntoshow = num2Alpha($i);
1310 $htmltext .= $langs->trans("DataComeFromFileFieldNb", $filecolumntoshow).'<br>';
1311
1312 print $form->textwithpicto('', $htmltext);
1313
1314 print '</td>';
1315 print '</tr>';
1316 $i++;
1317 }
1318 print '</table>';
1319
1320 print '</td></tr>';
1321
1322 // Lines for remark
1323 print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Note").'</td></tr>';
1324 print '<tr><td colspan="2"><div id="div-mandatory-target-fields-not-mapped"></div></td></tr>';
1325
1326 print '</table>';
1327 print '</div>';
1328
1329
1330 if (!empty($conf->use_javascript_ajax)) {
1331 print '<script type="text/javascript">'."\n";
1332 print 'var previousselectedvalueimport = "0";'."\n";
1333 print 'var previousselectedlabelimport = "0";'."\n";
1334 print 'var arrayofselectedvalues = [];'."\n";
1335 print 'var arrayoftargetfields = [];'."\n";
1336 print 'var arrayoftargetmandatoryfields = [];'."\n";
1337
1338 // Loop on $fieldstarget (seems sorted by 'position') to store php array into javascript array
1339 $tmpi = 0;
1340 foreach ($fieldstarget as $key => $val) {
1341 print "arrayoftargetfields[".$tmpi."] = '".dol_escape_js($langs->trans($val['label']))."'; ";
1342 if ($val['required']) {
1343 print "arrayoftargetmandatoryfields[".$tmpi."] = '".dol_escape_js($key)."'; ";
1344 }
1345 $tmpi++;
1346 }
1347 print "\n";
1348
1349 print '$(document).ready(function () {'."\n";
1350
1351 print 'setOptionsToDisabled();'."\n";
1352 print 'saveSelection();'."\n";
1353
1354 print '$(".targetselectchange").focus(function(){'."\n";
1355 print ' previousselectedvalueimport = $(this).val();'."\n";
1356 print ' previousselectedlabelimport = $(this).children("option:selected").text();'."\n";
1357 print ' console.log("previousselectedvalueimport="+previousselectedvalueimport)'."\n";
1358 print '})'."\n";
1359
1360 // Function to set the disabled flag
1361 // - We set all option to "enabled"
1362 // - Then we scan all combo to get the value currently selected and save them into the array arrayofselectedvalues
1363 // - Then we set to disabled all fields that are selected
1364 print 'function setOptionsToDisabled() {'."\n";
1365 print ' console.log("Remove the disabled flag everywhere");'."\n";
1366 print ' $("select.targetselectchange").not($( this )).find(\'option\').prop("disabled", false);'."\n"; // Enable all options
1367 print ' arrayofselectedvalues = [];'."\n";
1368
1369 print ' $("select.targetselectchange").each(function(){'."\n";
1370 print ' id = $(this).attr(\'id\')'."\n";
1371 print ' value = $(this).val()'."\n";
1372 print ' console.log("a selected value has been found for component "+id+" = "+value);'."\n";
1373 print ' arrayofselectedvalues.push(value);'."\n";
1374 print ' });'."\n";
1375
1376 print ' console.log("List of all selected values arrayofselectedvalues");'."\n";
1377 print ' console.log(arrayofselectedvalues);'."\n";
1378 print ' console.log("Set the option to disabled for every entry that is currently selected somewhere else (so into arrayofselectedvalues)");'."\n";
1379
1380 print ' $.each(arrayofselectedvalues, function(key, value) {'."\n"; // Loop on each selected value
1381 print ' if (value != -1) {'."\n";
1382 print ' console.log("Process key="+key+" value="+value+" to disable.");'."\n";
1383 print ' $("select.targetselectchange").find(\'option[value="\'+value+\'"]:not(:selected)\').prop("disabled", true);'."\n"; // Set to disabled except if currently selected
1384 print ' }'."\n";
1385 print ' });'."\n";
1386 print '}'."\n";
1387
1388 // Function to save the selection in database
1389 print 'function saveSelection() {'."\n";
1390 //print ' console.log(arrayofselectedvalues);'."\n";
1391 print ' arrayselectedfields = [];'."\n";
1392 print ' arrayselectedfields.push(0);'."\n";
1393
1394 print ' $.each( arrayofselectedvalues, function( key, value ) {'."\n";
1395 print ' if (value != -1) {'."\n";
1396 print ' arrayselectedfields.push(value);'."\n";
1397 print ' } else {'."\n";
1398 print ' arrayselectedfields.push(0);'."\n";
1399 print ' }'."\n";
1400 print ' });'."\n";
1401
1402 print " $.ajax({\n";
1403 print " type: 'POST',\n";
1404 print " dataType: 'json',\n";
1405 print " url: '".dol_escape_js($_SERVER["PHP_SELF"])."?action=saveselectorder&token=".newToken()."',\n";
1406 print " data: 'selectorder='+arrayselectedfields.toString(),\n";
1407 print " success: function(){\n";
1408 print " console.log('The selected fields have been saved into '+arrayselectedfields.toString());\n";
1409 print " },\n";
1410 print ' });'."\n";
1411
1412 // Now we loop on all target fields that are mandatory to show if they are not mapped yet.
1413 print ' console.log("arrayselectedfields");';
1414 print ' console.log(arrayselectedfields);';
1415 print ' console.log("arrayoftargetmandatoryfields");';
1416 print ' console.log(arrayoftargetmandatoryfields);';
1417 print " listtoshow = '';";
1418 print " nbelement = arrayoftargetmandatoryfields.length
1419 for (let i = 0; i < nbelement; i++) {
1420 if (arrayoftargetmandatoryfields[i] && ! arrayselectedfields.includes(arrayoftargetmandatoryfields[i])) {
1421 console.log(arrayoftargetmandatoryfields[i]+' not mapped');
1422 listtoshow = listtoshow + (listtoshow ? ', ' : '') + '<b>' + arrayoftargetfields[i] + '*</b>';
1423 }
1424 }
1425 console.log(listtoshow);
1426 if (listtoshow) {
1427 listtoshow = '".dol_escape_js(img_warning($langs->trans("MandatoryTargetFieldsNotMapped")).' '.$langs->trans("MandatoryTargetFieldsNotMapped")).": ' + listtoshow;
1428 $('#div-mandatory-target-fields-not-mapped').html(listtoshow);
1429 } else {
1430 $('#div-mandatory-target-fields-not-mapped').html('<span class=\"opacitymedium\">".dol_escape_js($langs->trans("AllTargetMandatoryFieldsAreMapped"))."</span>');
1431 }
1432 ";
1433
1434 print '}'."\n";
1435
1436 // If we make a change on a selectbox
1437 print '$(".targetselectchange").change(function(){'."\n";
1438 print ' setOptionsToDisabled();'."\n";
1439
1440 print ' if(previousselectedlabelimport != "" && previousselectedvalueimport != -1) {'."\n";
1441 print ' let valuetochange = $(this).val(); '."\n";
1442 print ' $(".boxtdunused").each(function(){'."\n";
1443 print ' if ($(this).text().includes(valuetochange)){'."\n";
1444 print ' arraychild = $(this)[0].childNodes'."\n";
1445 print ' arraytexttomodify = arraychild[0].textContent.split(" ")'."\n";
1446 print ' arraytexttomodify[1] = previousselectedvalueimport '."\n";
1447 print ' textmodified = arraytexttomodify.join(" ") '."\n";
1448 print ' arraychild[0].textContent = textmodified'."\n";
1449 print ' arraychild[1].innerHTML = previousselectedlabelimport'."\n";
1450 print ' }'."\n";
1451 print ' })'."\n";
1452 print ' }'."\n";
1453 print ' $(this).blur()'."\n";
1454
1455 print ' saveSelection()'."\n";
1456 print '});'."\n";
1457
1458 print '})'."\n";
1459 print '</script>'."\n";
1460 }
1461
1462 /*
1463 * Action bar
1464 */
1465 print '<div class="tabsAction">';
1466
1467 if (count($array_match_file_to_database)) {
1468 if ($mandatoryfieldshavesource) {
1469 print '<a class="butAction saveorderselect" href="import.php?step=5'.$param.'&filetoimport='.urlencode($filetoimport).'">'.$langs->trans("NextStep").'</a>';
1470 } else {
1471 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("SomeMandatoryFieldHaveNoSource")).'">'.$langs->trans("NextStep").'</a>';
1472 }
1473 }
1474
1475 print '</div>';
1476
1477
1478 // Area for profils import
1479 if (count($array_match_file_to_database)) {
1480 print '<br>'."\n";
1481 print '<!-- Area to add new import profile -->'."\n";
1482 print '<div class="marginbottomonly"><span class="opacitymedium">'.$langs->trans("SaveImportModel").'</span></div>';
1483
1484 print '<form class="nocellnopadd" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1485 print '<input type="hidden" name="token" value="'.newToken().'">';
1486 print '<input type="hidden" name="action" value="add_import_model">';
1487 print '<input type="hidden" name="step" value="'.$step.'">';
1488 print '<input type="hidden" name="format" value="'.$format.'">';
1489 print '<input type="hidden" name="datatoimport" value="'.$datatoimport.'">';
1490 print '<input type="hidden" name="filetoimport" value="'.$filetoimport.'">';
1491 print '<input type="hidden" name="hexa" value="'.$hexa.'">';
1492 print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
1493 print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
1494 print '<input type="hidden" name="page_y" value="">';
1495 print '<input type="hidden" value="'.dol_escape_htmltag($separator).'" name="separator">';
1496 print '<input type="hidden" value="'.dol_escape_htmltag($enclosure).'" name="enclosure">';
1497
1498 print '<div class="div-table-responsive-no-min">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
1499 print '<table summary="selectofimportprofil" class="noborder centpercent">';
1500 print '<tr class="liste_titre">';
1501 print '<td>'.$langs->trans("ImportModelName").'</td>';
1502 print '<td>'.$langs->trans("Visibility").'</td>';
1503 print '<td></td>';
1504 print '</tr>';
1505
1506 $nameofimportprofile = str_replace(' ', '-', $langs->trans("ImportProfile").' '.$titleofmodule.' '.dol_print_date(dol_now('gmt'), 'dayxcard'));
1507 if (GETPOST('import_name')) { // If we have submitted a form, we take value used for the update try
1508 $nameofimportprofile = $import_name;
1509 }
1510
1511 print '<tr class="oddeven">';
1512 print '<td><input name="import_name" class="minwidth300" value="'.$nameofimportprofile.'"></td>';
1513 print '<td>';
1514 $arrayvisibility = array('private' => $langs->trans("Private"), 'all' => $langs->trans("Everybody"));
1515 print $form->selectarray('visibility', $arrayvisibility, 'private');
1516 print '</td>';
1517 print '<td class="right">';
1518 print '<input type="submit" class="button smallpaddingimp reposition" value="'.$langs->trans("SaveImportProfile").'">';
1519 print '</td></tr>';
1520
1521 // List of existing import profils
1522 $sql = "SELECT rowid, label, fk_user, entity";
1523 $sql .= " FROM ".MAIN_DB_PREFIX."import_model";
1524 $sql .= " WHERE type = '".$db->escape($datatoimport)."'";
1525 if (!getDolGlobalString('EXPORTS_SHARE_MODELS')) { // EXPORTS_SHARE_MODELS means all templates are visible, whatever is owner.
1526 $sql .= " AND fk_user IN (0, ".((int) $user->id).")";
1527 }
1528 $sql .= " ORDER BY rowid";
1529
1530 $resql = $db->query($sql);
1531 if ($resql) {
1532 $num = $db->num_rows($resql);
1533
1534 $tmpuser = new User($db);
1535
1536 $i = 0;
1537 while ($i < $num) {
1538 $obj = $db->fetch_object($resql);
1539
1540 print '<tr class="oddeven"><td>';
1541 print $obj->label;
1542 print '</td>';
1543 print '<td class="tdoverflowmax150">';
1544 if (empty($obj->fk_user)) {
1545 print $langs->trans("Everybody");
1546 } else {
1547 $tmpuser->fetch($obj->fk_user);
1548 print $tmpuser->getNomUrl(-1);
1549 }
1550 print '</td>';
1551 print '<td class="right">';
1552 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?step='.$step.$param.'&action=deleteprof&token='.newToken().'&id='.$obj->rowid.'&filetoimport='.urlencode($filetoimport).'">';
1553 print img_delete();
1554 print '</a>';
1555 print '</tr>';
1556 $i++;
1557 }
1558 } else {
1559 dol_print_error($db);
1560 }
1561
1562 print '</table>';
1563 print '</div>';
1564
1565 print '</form>';
1566 }
1567}
1568
1569// STEP 5: Summary of choices and launch simulation
1570if ($step == 5 && $datatoimport) {
1571 $max_execution_time_for_importexport = getDolGlobalInt('IMPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined
1572 $max_time = @ini_get("max_execution_time");
1573 if ($max_time && $max_time < $max_execution_time_for_importexport) {
1574 dol_syslog("max_execution_time=".$max_time." is lower than max_execution_time_for_importexport=".$max_execution_time_for_importexport.". We try to increase it dynamically.");
1575 @ini_set("max_execution_time", $max_execution_time_for_importexport); // This work only if safe mode is off. also web servers has timeout of 300
1576 }
1577
1578 $model = $format;
1579 $list = $objmodelimport->listOfAvailableImportFormat($db);
1580
1581 // Create class to use for import
1582 $dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
1583 $file = "import_".$model.".modules.php";
1584 $classname = "Import".ucfirst($model);
1585 require_once $dir.$file;
1586 $obj = new $classname($db, $datatoimport);
1587 '@phan-var-force ModeleImports $obj';
1588 if ($model == 'csv') {
1589 '@phan-var-force ImportCsv $obj';
1590 $obj->separator = $separator_used;
1591 $obj->enclosure = $enclosure;
1592 }
1593
1594 // Load source fields in input file
1595 $fieldssource = array();
1596 $result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
1597
1598 if ($result >= 0) {
1599 // Read first line
1600 $arrayrecord = $obj->import_read_record();
1601 // Put into array fieldssource starting with 1.
1602 $i = 1;
1603 foreach ($arrayrecord as $key => $val) {
1604 $fieldssource[$i]['example1'] = dol_trunc($val['val'], 24);
1605 $i++;
1606 }
1607 $obj->import_close_file();
1608 }
1609
1610 $nboflines = $obj->import_get_nb_of_lines($conf->import->dir_temp.'/'.$filetoimport);
1611
1612 $param = '&leftmenu=import&format='.urlencode($format).'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport).'&nboflines='.((int) $nboflines).'&separator='.urlencode($separator).'&enclosure='.urlencode($enclosure);
1613 $param2 = $param; // $param2 = $param without excludefirstline and endatlinenb
1614 if ($excludefirstline) {
1615 $param .= '&excludefirstline='.urlencode($excludefirstline);
1616 }
1617 if ($endatlinenb) {
1618 $param .= '&endatlinenb='.urlencode($endatlinenb);
1619 }
1620 if (!empty($updatekeys)) {
1621 $param .= '&updatekeys[]='.implode('&updatekeys[]=', $updatekeys);
1622 }
1623
1624 llxHeader('', $langs->trans("NewImport"), $help_url);
1625
1626 $head = import_prepare_head($param, 5);
1627
1628
1629 print '<form action="'.$_SERVER["PHP_SELF"].'?'.$param2.'" method="POST">';
1630 print '<input type="hidden" name="token" value="'.newToken().'">';
1631 print '<input type="hidden" name="step" value="5">'; // step 5
1632 print '<input type="hidden" name="action" value="launchsimu">'; // step 5
1633
1634 print dol_get_fiche_head($head, 'step5', 'Import', -2, 'upload');
1635
1636 print '<div class="underbanner clearboth"></div>';
1637 print '<div class="fichecenter">';
1638
1639 print '<table width="100%" class="border tableforfield">';
1640
1641 // Module
1642 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
1643 print '<td>';
1644 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
1645 // Special case for import common to module/services
1646 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
1647 $titleofmodule = $langs->trans("ProductOrService");
1648 }
1649 print $titleofmodule;
1650 print '</td></tr>';
1651
1652 // Lot de donnees a importer
1653 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
1654 print '<td>';
1655 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
1656 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
1657 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
1658 print $objimport->array_import_label[0];
1659 print '</td></tr>';
1660
1661 print '</table>';
1662 print '</div>';
1663
1664 print '<br>';
1665
1666 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
1667
1668 print '<div class="underbanner clearboth"></div>';
1669 print '<div class="fichecenter">';
1670 print '<table width="100%" class="border tableforfield">';
1671
1672 // Source file format
1673 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
1674 print '<td class="nowraponall">';
1675 $text = $objmodelimport->getDriverDescForKey($format);
1676 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1677 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
1678 print '</td></tr>';
1679
1680 // Separator and enclosure
1681 if ($model == 'csv') {
1682 '@phan-var-force ImportCsv $obj';
1683 print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
1684 print '<td>';
1685 print $langs->trans("Separator").' : '.dol_escape_htmltag($separator);
1686 print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : '.dol_escape_htmltag($enclosure);
1687 print '</td></tr>';
1688 }
1689
1690 // File to import
1691 print '<tr><td>'.$langs->trans("FileToImport").'</td>';
1692 print '<td>';
1693 $modulepart = 'import';
1694 $relativepath = GETPOST('filetoimport');
1695 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.urlencode($modulepart).'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
1696 print img_mime($file, '', 'pictofixedwidth');
1697 print $filetoimport;
1698 print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"');
1699 print '</a>';
1700 print '</td></tr>';
1701
1702 // Total lines in source file
1703 print '<tr><td>';
1704 print $langs->trans("NbOfSourceLines");
1705 print '</td><td>';
1706 print $nboflines;
1707 print '</td></tr>';
1708
1709 // Range of lines to import
1710 print '<tr><td>';
1711 print $langs->trans("ImportFromToLine");
1712 print '</td><td>';
1713 if ($action == 'launchsimu') {
1714 print '<input type="number" class="maxwidth50 right" name="excludefirstlinebis" disabled="disabled" value="'.$excludefirstline.'">';
1715 print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
1716 } else {
1717 print '<input type="number" class="maxwidth50 right" name="excludefirstline" value="'.$excludefirstline.'">';
1718 print $form->textwithpicto("", $langs->trans("SetThisValueTo2ToExcludeFirstLine"));
1719 }
1720 print ' - ';
1721 if ($action == 'launchsimu') {
1722 print '<input type="text" class="maxwidth50" name="endatlinenbbis" disabled="disabled" value="'.$endatlinenb.'">';
1723 print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
1724 } else {
1725 print '<input type="text" class="maxwidth50" name="endatlinenb" value="'.$endatlinenb.'">';
1726 print $form->textwithpicto("", $langs->trans("KeepEmptyToGoToEndOfFile"));
1727 }
1728 if ($action == 'launchsimu') {
1729 print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?step=5'.$param.'">'.$langs->trans("Modify").'</a>';
1730 }
1731 if ($excludefirstline == 2) {
1732 print $form->textwithpicto("", $langs->trans("WarningFirstImportedLine", $excludefirstline), 1, 'warning', "warningexcludefirstline");
1733 print '<script>
1734 $( document ).ready(function() {
1735 $("input[name=\'excludefirstline\']").on("change",function(){
1736 if($(this).val() <= 1){
1737 $(".warningexcludefirstline").hide();
1738 }else{
1739 $(".warningexcludefirstline").show();
1740 }
1741 })
1742 });
1743 </script>';
1744 }
1745 print '</td></tr>';
1746
1747 // Keys for data UPDATE (not INSERT of new data)
1748 print '<tr><td>';
1749 print $form->textwithpicto($langs->trans("KeysToUseForUpdates"), $langs->trans("SelectPrimaryColumnsForUpdateAttempt"));
1750 print '</td><td>';
1751 if ($action == 'launchsimu') {
1752 if (count($updatekeys)) {
1753 print $form->multiselectarray('updatekeysbis', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%', 'disabled');
1754 } else {
1755 print '<span class="opacitymedium">'.$langs->trans("NoUpdateAttempt").'</span> &nbsp; -';
1756 }
1757 foreach ($updatekeys as $val) {
1758 print '<input type="hidden" name="updatekeys[]" value="'.$val.'">';
1759 }
1760 print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?step=5'.$param.'">'.$langs->trans("Modify").'</a>';
1761 } else {
1762 if (is_array($objimport->array_import_updatekeys[0]) && count($objimport->array_import_updatekeys[0])) { //TODO dropdown UL is created inside nested SPANS
1763 print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%');
1764 //print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt"));
1765 } else {
1766 print '<span class="opacitymedium">'.$langs->trans("UpdateNotYetSupportedForThisImport").'</span>';
1767 }
1768 }
1769 /*echo '<pre>';
1770 print_r($objimport->array_import_updatekeys);
1771 echo '</pre>';*/
1772 print '</td></tr>';
1773
1774 print '</table>';
1775 print '</div>';
1776
1777 print '<br>';
1778
1779 print load_fiche_titre($langs->trans("InformationOnTargetTables"), '', 'file-import');
1780
1781 print '<div class="underbanner clearboth"></div>';
1782 print '<div class="fichecenter">';
1783
1784 print '<table class="centpercent border tableforfield">';
1785
1786 // Tables imported
1787 print '<tr><td class="titlefieldcreate">';
1788 print $langs->trans("TablesTarget");
1789 print '</td><td>';
1790 $listtables = array();
1791 $sort_array_match_file_to_database = $array_match_file_to_database;
1792 foreach ($array_match_file_to_database as $code => $label) {
1793 //var_dump($fieldssource);
1794 if ($code > count($fieldssource)) {
1795 continue;
1796 }
1797 //print $code.'-'.$label;
1798 $alias = preg_replace('/(\..*)$/i', '', $label);
1799 $listtables[$alias] = $objimport->array_import_tables[0][$alias];
1800 }
1801 if (count($listtables)) {
1802 $newval = '';
1803 //ksort($listtables);
1804 foreach ($listtables as $val) {
1805 if ($newval) {
1806 print ', ';
1807 }
1808 $newval = $val;
1809 // Link to Dolibarr wiki pages
1810 /*$helppagename='EN:Table_'.$newval;
1811 if ($helppagename && empty($conf->global->MAIN_HELP_DISABLELINK))
1812 {
1813 // Get helpbaseurl, helppage and mode from helppagename and langs
1814 $arrayres=getHelpParamFor($helppagename,$langs);
1815 $helpbaseurl=$arrayres['helpbaseurl'];
1816 $helppage=$arrayres['helppage'];
1817 $mode=$arrayres['mode'];
1818 $newval.=' <a href="'.sprintf($helpbaseurl,$helppage).'">'.img_picto($langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'),DOL_URL_ROOT.'/theme/common/helpdoc.png','',1).'</a>';
1819 }*/
1820 print $newval;
1821 }
1822 } else {
1823 print $langs->trans("Error");
1824 }
1825 print '</td></tr>';
1826
1827 // Fields imported
1828 print '<tr><td>';
1829 print $langs->trans("FieldsTarget").'</td><td class="small">';
1830 $listfields = array();
1831 $i = 0;
1832 //print 'fieldsource='.$fieldssource;
1833 $sort_array_match_file_to_database = $array_match_file_to_database;
1834 ksort($sort_array_match_file_to_database);
1835 //var_dump($sort_array_match_file_to_database);
1836 foreach ($sort_array_match_file_to_database as $code => $label) {
1837 $i++;
1838 //var_dump($fieldssource);
1839 if ($code > count($fieldssource)) {
1840 continue;
1841 }
1842 //print $code.'-'.$label;
1843 $alias = preg_replace('/(\..*)$/i', '', $label);
1844 $listfields[$i] = '<span class="nowrap">'.$langs->trans("Column").' '.num2Alpha((int) $code - 1).' -> '.$label.'</span>';
1845 }
1846 print count($listfields) ? (implode(', ', $listfields)) : $langs->trans("Error");
1847 print '</td></tr>';
1848
1849 print '</table>';
1850 print '</div>';
1851
1852 print dol_get_fiche_end();
1853
1854
1855 if ($action != 'launchsimu') {
1856 // Show import id
1857 print '<br><span class="opacitymedium">';
1858 print $langs->trans("NowClickToTestTheImport", $langs->transnoentitiesnoconv("RunSimulateImportFile")).'</span><br>';
1859 print '<br>';
1860
1861 // Actions
1862 print '<div class="center">';
1863 if ($user->hasRight('import', 'run')) {
1864 print '<input type="submit" class="butAction" value="'.$langs->trans("RunSimulateImportFile").'">';
1865 } else {
1866 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunSimulateImportFile").'</a>';
1867 }
1868 print '</div>';
1869 } else {
1870 // Launch import
1871 $arrayoferrors = array();
1872 $arrayofwarnings = array();
1873 $maxnboferrors = getDolGlobalInt('IMPORT_MAX_NB_OF_ERRORS', 50);
1874 $maxnbofwarnings = getDolGlobalInt('IMPORT_MAX_NB_OF_WARNINGS', 50);
1875 $nboferrors = 0;
1876 $nbofwarnings = 0;
1877
1878 $importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
1879
1880 //var_dump($array_match_file_to_database);
1881
1882 $db->begin();
1883
1884 // Open input file
1885 $nbok = 0;
1886 $pathfile = $conf->import->dir_temp.'/'.$filetoimport;
1887 $result = $obj->import_open_file($pathfile);
1888 if ($result > 0) {
1889 global $tablewithentity_cache;
1890 $tablewithentity_cache = array();
1891 $sourcelinenb = 0;
1892 $endoffile = 0;
1893
1894 // Loop on each input file record
1895 while (($sourcelinenb < $nboflines) && !$endoffile) {
1896 $sourcelinenb++;
1897 // Read line and store it into $arrayrecord
1898 //dol_syslog("line ".$sourcelinenb.' - '.$nboflines.' - '.$excludefirstline.' - '.$endatlinenb);
1899 $arrayrecord = $obj->import_read_record();
1900 if ($arrayrecord === false) {
1901 $arrayofwarnings[$sourcelinenb][0] = array('lib' => $langs->trans('ErrorFileLinesReachEOF', $nboflines, $sourcelinenb), 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
1902 $endoffile++;
1903 continue;
1904 }
1905 if ($excludefirstline && ($sourcelinenb < $excludefirstline)) {
1906 continue;
1907 }
1908 if ($endatlinenb && ($sourcelinenb > $endatlinenb)) {
1909 break;
1910 }
1911
1912 $parameters = array(
1913 'step' => $step,
1914 'datatoimport' => $datatoimport,
1915 'obj' => &$obj,
1916 'arrayrecord' => $arrayrecord,
1917 'array_match_file_to_database' => $array_match_file_to_database,
1918 'objimport' => $objimport,
1919 'fieldssource' => $fieldssource,
1920 'importid' => $importid,
1921 'updatekeys' => $updatekeys,
1922 'arrayoferrors' => &$arrayoferrors,
1923 'arrayofwarnings' => &$arrayofwarnings,
1924 'nbok' => &$nbok,
1925 );
1926
1927 $reshook = $hookmanager->executeHooks('ImportInsert', $parameters);
1928 if ($reshook < 0) {
1929 $arrayoferrors[$sourcelinenb][] = [
1930 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
1931 ];
1932 }
1933
1934 if (empty($reshook)) {
1935 // Run import
1936 $result = $obj->import_insert($arrayrecord, $array_match_file_to_database, $objimport, count($fieldssource), $importid, $updatekeys);
1937
1938 if (count($obj->errors)) {
1939 $arrayoferrors[$sourcelinenb] = $obj->errors;
1940 }
1941 if (count($obj->warnings)) {
1942 $arrayofwarnings[$sourcelinenb] = $obj->warnings;
1943 }
1944 if (!count($obj->errors) && !count($obj->warnings)) {
1945 $nbok++;
1946 }
1947 }
1948
1949 $reshook = $hookmanager->executeHooks('AfterImportInsert', $parameters);
1950 if ($reshook < 0) {
1951 $arrayoferrors[$sourcelinenb][] = [
1952 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
1953 ];
1954 }
1955 }
1956 // Close file
1957 $obj->import_close_file();
1958 } else {
1959 print $langs->trans("ErrorFailedToOpenFile", $pathfile);
1960 }
1961
1962 $error = 0;
1963
1964 // Run the sql after import if defined
1965 //var_dump($objimport->array_import_run_sql_after[0]);
1966 if (!empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0])) {
1967 $i = 0;
1968 foreach ($objimport->array_import_run_sql_after[0] as $sqlafterimport) {
1969 $i++;
1970 $resqlafterimport = $db->query($sqlafterimport);
1971 if (!$resqlafterimport) {
1972 $arrayoferrors['none'][] = array('lib' => $langs->trans("Error running final request: ".$sqlafterimport));
1973 $error++;
1974 }
1975 }
1976 }
1977
1978 $db->rollback(); // We force rollback because this was just a simulation.
1979
1980 // Show OK
1981 if (!count($arrayoferrors) && !count($arrayofwarnings)) {
1982 print '<br>';
1983 print '<div class="info">';
1984 print '<div class=""><b>'.$langs->trans("ResultOfSimulationNoError").'</b></div>';
1985 print $langs->trans("NbInsertSim", empty($obj->nbinsert) ? 0 : $obj->nbinsert).'<br>';
1986 print $langs->trans("NbUpdateSim", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'<br>';
1987 print '</div>';
1988 print '<br>';
1989 } else {
1990 print '<br>';
1991 print '<div class="warning">';
1992 print $langs->trans("NbOfLinesOK", $nbok).'...<br>';
1993 print '</div>';
1994 print '<br>';
1995 }
1996
1997 // Show Errors
1998 //var_dump($arrayoferrors);
1999 if (count($arrayoferrors)) {
2000 print img_error().' <b>'.$langs->trans("ErrorsOnXLines", count($arrayoferrors)).'</b><br>';
2001 print '<table width="100%" class="border"><tr><td>';
2002 foreach ($arrayoferrors as $key => $val) {
2003 $nboferrors++;
2004 if ($nboferrors > $maxnboferrors) {
2005 print $langs->trans("TooMuchErrors", (count($arrayoferrors) - $nboferrors))."<br>";
2006 break;
2007 }
2008 print '* '.$langs->trans("Line").' '.dol_escape_htmltag($key).'<br>';
2009 foreach ($val as $i => $err) {
2010 print ' &nbsp; &nbsp; > '.dol_escape_htmltag($err['lib']).'<br>';
2011 }
2012 }
2013 print '</td></tr></table>';
2014 print '<br>';
2015 }
2016
2017 // Show Warnings
2018 //var_dump($arrayoferrors);
2019 if (count($arrayofwarnings)) {
2020 print img_warning().' <b>'.$langs->trans("WarningsOnXLines", count($arrayofwarnings)).'</b><br>';
2021 print '<table width="100%" class="border"><tr><td>';
2022 foreach ($arrayofwarnings as $key => $val) {
2023 $nbofwarnings++;
2024 if ($nbofwarnings > $maxnbofwarnings) {
2025 print $langs->trans("TooMuchWarnings", (count($arrayofwarnings) - $nbofwarnings))."<br>";
2026 break;
2027 }
2028 print ' * '.$langs->trans("Line").' '.dol_escape_htmltag((string) $key).'<br>';
2029 foreach ($val as $i => $err) {
2030 print ' &nbsp; &nbsp; > '.dol_escape_htmltag($err['lib']).'<br>';
2031 }
2032 }
2033 print '</td></tr></table>';
2034 print '<br>';
2035 }
2036
2037 // Show import id
2038 $importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
2039
2040 print '<div class="center">';
2041 print '<span class="opacitymedium">'.$langs->trans("NowClickToRunTheImport", $langs->transnoentitiesnoconv("RunImportFile")).'</span><br>';
2042 /*if (empty($nboferrors)) {
2043 print $langs->trans("DataLoadedWithId", $importid).'<br>';
2044 }*/
2045 print '</div>';
2046
2047 print '<br>';
2048
2049 // Actions
2050 print '<div class="center">';
2051 if ($user->hasRight('import', 'run')) {
2052 if (empty($nboferrors)) {
2053 print '<a class="butAction" href="'.DOL_URL_ROOT.'/imports/import.php?leftmenu=import&step=6&importid='.$importid.$param.'">'.$langs->trans("RunImportFile").'</a>';
2054 } else {
2055 //print '<input type="submit" class="butAction" value="'.dol_escape_htmltag($langs->trans("RunSimulateImportFile")).'">';
2056
2057 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("CorrectErrorBeforeRunningImport")).'">'.$langs->trans("RunImportFile").'</a>';
2058 }
2059 } else {
2060 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunSimulateImportFile").'</a>';
2061
2062 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunImportFile").'</a>';
2063 }
2064 print '</div>';
2065 }
2066
2067 print '</form>';
2068}
2069
2070
2071// STEP 6: Real import
2072if ($step == 6 && $datatoimport) {
2073 $max_execution_time_for_importexport = getDolGlobalInt('IMPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined
2074 $max_time = @ini_get("max_execution_time");
2075 if ($max_time && $max_time < $max_execution_time_for_importexport) {
2076 dol_syslog("max_execution_time=".$max_time." is lower than max_execution_time_for_importexport=".$max_execution_time_for_importexport.". We try to increase it dynamically.");
2077 @ini_set("max_execution_time", $max_execution_time_for_importexport); // This work only if safe mode is off. also web servers has timeout of 300
2078 }
2079
2080 $model = $format;
2081 $list = $objmodelimport->listOfAvailableImportFormat($db);
2082 $importid = GETPOST("importid", 'alphanohtml');
2083
2084
2085 // Create class to use for import
2086 $dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
2087 $file = "import_".$model.".modules.php";
2088 $classname = "Import".ucfirst($model);
2089 require_once $dir.$file;
2090 $obj = new $classname($db, $datatoimport);
2091 '@phan-var-force ModeleImports $obj';
2092 if ($model == 'csv') {
2093 '@phan-var-force ImportCsv $obj';
2094 $obj->separator = $separator_used;
2095 $obj->enclosure = $enclosure;
2096 }
2097
2098 // Load source fields in input file
2099 $fieldssource = array();
2100 $result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
2101 if ($result >= 0) {
2102 // Read first line
2103 $arrayrecord = $obj->import_read_record();
2104 // Put into array fieldssource starting with 1.
2105 $i = 1;
2106 foreach ($arrayrecord as $key => $val) {
2107 $fieldssource[$i]['example1'] = dol_trunc($val['val'], 24);
2108 $i++;
2109 }
2110 $obj->import_close_file();
2111 }
2112
2113 $nboflines = (GETPOSTISSET("nboflines") ? GETPOSTINT("nboflines") : dol_count_nb_of_line($conf->import->dir_temp.'/'.$filetoimport));
2114
2115 $param = '&format='.$format.'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport).'&nboflines='.((int) $nboflines);
2116 if ($excludefirstline) {
2117 $param .= '&excludefirstline='.urlencode($excludefirstline);
2118 }
2119 if ($endatlinenb) {
2120 $param .= '&endatlinenb='.urlencode($endatlinenb);
2121 }
2122 if ($separator) {
2123 $param .= '&separator='.urlencode($separator);
2124 }
2125 if ($enclosure) {
2126 $param .= '&enclosure='.urlencode($enclosure);
2127 }
2128
2129 llxHeader('', $langs->trans("NewImport"), $help_url);
2130
2131 $head = import_prepare_head($param, 6);
2132
2133 print dol_get_fiche_head($head, 'step6', 'Import', -1, 'upload');
2134
2135 print '<div class="underbanner clearboth"></div>';
2136 print '<div class="fichecenter">';
2137
2138 print '<table width="100%" class="border">';
2139
2140 // Module
2141 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
2142 print '<td>';
2143 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
2144 // Special case for import common to module/services
2145 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
2146 $titleofmodule = $langs->trans("ProductOrService");
2147 }
2148 print $titleofmodule;
2149 print '</td></tr>';
2150
2151 // Lot de donnees a importer
2152 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
2153 print '<td>';
2154 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
2155 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
2156 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
2157 print $objimport->array_import_label[0];
2158 print '</td></tr>';
2159
2160 print '</table>';
2161 print '</div>';
2162
2163 print '<br>';
2164
2165 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
2166
2167 print '<div class="underbanner clearboth"></div>';
2168 print '<div class="fichecenter">';
2169 print '<table width="100%" class="border tableforfield">';
2170
2171 // Source file format
2172 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
2173 print '<td class="nowraponall">';
2174 $text = $objmodelimport->getDriverDescForKey($format);
2175 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2176 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
2177 print '</td></tr>';
2178
2179 // Separator and enclosure
2180 if ($model == 'csv') {
2181 '@phan-var-force ImportCsv $obj';
2182 print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
2183 print '<td>';
2184 print $langs->trans("Separator").' : ';
2185 print htmlentities($separator);
2186 print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : ';
2187 print htmlentities($enclosure);
2188 print '</td></tr>';
2189 }
2190
2191 // File to import
2192 print '<tr><td>'.$langs->trans("FileToImport").'</td>';
2193 print '<td>';
2194 $modulepart = 'import';
2195 $relativepath = GETPOST('filetoimport');
2196 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
2197 print img_mime($file, '', 'pictofixedwidth');
2198 print $filetoimport;
2199 print '</a>';
2200 print '</td></tr>';
2201
2202 // Nb of fields
2203 print '<tr><td>';
2204 print $langs->trans("NbOfSourceLines");
2205 print '</td><td>';
2206 print $nboflines;
2207 print '</td></tr>';
2208
2209 // Do not import first lines
2210 print '<tr><td>';
2211 print $langs->trans("ImportFromLine");
2212 print '</td><td>';
2213 print '<input type="text" size="4" name="excludefirstline" disabled="disabled" value="'.$excludefirstline.'">';
2214 print '</td></tr>';
2215
2216 // Do not import end lines
2217 print '<tr><td>';
2218 print $langs->trans("EndAtLineNb");
2219 print '</td><td>';
2220 print '<input type="text" size="4" name="endatlinenb" disabled="disabled" value="'.$endatlinenb.'">';
2221 print '</td></tr>';
2222
2223 print '</table>';
2224 print '</div>';
2225
2226 print '<br>';
2227
2228 print '<b>'.$langs->trans("InformationOnTargetTables").'</b>';
2229 print '<div class="underbanner clearboth"></div>';
2230 print '<div class="fichecenter">';
2231 print '<table class="border centpercent">';
2232
2233 // Tables imported
2234 print '<tr><td width="25%">';
2235 print $langs->trans("TablesTarget");
2236 print '</td><td>';
2237 $listtables = array();
2238 foreach ($array_match_file_to_database as $code => $label) {
2239 //var_dump($fieldssource);
2240 if ($code > count($fieldssource)) {
2241 continue;
2242 }
2243 //print $code.'-'.$label;
2244 $alias = preg_replace('/(\..*)$/i', '', $label);
2245 $listtables[$alias] = $objimport->array_import_tables[0][$alias];
2246 }
2247 if (count($listtables)) {
2248 $newval = '';
2249 foreach ($listtables as $val) {
2250 if ($newval) {
2251 print ', ';
2252 }
2253 $newval = $val;
2254 // Link to Dolibarr wiki pages
2255 /*$helppagename='EN:Table_'.$newval;
2256 if ($helppagename && empty($conf->global->MAIN_HELP_DISABLELINK))
2257 {
2258 // Get helpbaseurl, helppage and mode from helppagename and langs
2259 $arrayres=getHelpParamFor($helppagename,$langs);
2260 $helpbaseurl=$arrayres['helpbaseurl'];
2261 $helppage=$arrayres['helppage'];
2262 $mode=$arrayres['mode'];
2263 $newval.=' <a href="'.sprintf($helpbaseurl,$helppage).'">'.img_picto($langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'),DOL_URL_ROOT.'/theme/common/helpdoc.png','',1).'</a>';
2264 }*/
2265 print $newval;
2266 }
2267 } else {
2268 print $langs->trans("Error");
2269 }
2270 print '</td></tr>';
2271
2272 // Fields imported
2273 print '<tr><td>';
2274 print $langs->trans("FieldsTarget").'</td><td>';
2275 $listfields = array();
2276 $i = 0;
2277 $sort_array_match_file_to_database = $array_match_file_to_database;
2278 ksort($sort_array_match_file_to_database);
2279 //var_dump($sort_array_match_file_to_database);
2280 foreach ($sort_array_match_file_to_database as $code => $label) {
2281 $i++;
2282 //var_dump($fieldssource);
2283 if ($code > count($fieldssource)) {
2284 continue;
2285 }
2286 //print $code.'-'.$label;
2287 $alias = preg_replace('/(\..*)$/i', '', $label);
2288 $listfields[$i] = $langs->trans("Field").' '.$code.'->'.$label;
2289 }
2290 print count($listfields) ? (implode(', ', $listfields)) : $langs->trans("Error");
2291 print '</td></tr>';
2292
2293 print '</table>';
2294 print '</div>';
2295
2296 // Launch import
2297 $arrayoferrors = array();
2298 $arrayofwarnings = array();
2299 $maxnboferrors = !getDolGlobalString('IMPORT_MAX_NB_OF_ERRORS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_ERRORS;
2300 $maxnbofwarnings = !getDolGlobalString('IMPORT_MAX_NB_OF_WARNINGS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_WARNINGS;
2301 $nboferrors = 0;
2302 $nbofwarnings = 0;
2303
2304 $importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
2305
2306 //var_dump($array_match_file_to_database);
2307
2308 $db->begin();
2309
2310 // Open input file
2311 $nbok = 0;
2312 $pathfile = $conf->import->dir_temp.'/'.$filetoimport;
2313 $result = $obj->import_open_file($pathfile);
2314 if ($result > 0) {
2315 global $tablewithentity_cache;
2316 $tablewithentity_cache = array();
2317 $sourcelinenb = 0;
2318 $endoffile = 0;
2319
2320 while ($sourcelinenb < $nboflines && !$endoffile) {
2321 $sourcelinenb++;
2322 $arrayrecord = $obj->import_read_record();
2323 if ($arrayrecord === false) {
2324 $arrayofwarnings[$sourcelinenb][0] = array('lib' => $langs->trans('ErrorFileLinesReachEOF', $nboflines, $sourcelinenb), 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
2325 $endoffile++;
2326 continue;
2327 }
2328 if ($excludefirstline && ($sourcelinenb < $excludefirstline)) {
2329 continue;
2330 }
2331 if ($endatlinenb && ($sourcelinenb > $endatlinenb)) {
2332 break;
2333 }
2334
2335 $parameters = array(
2336 'step' => $step,
2337 'datatoimport' => $datatoimport,
2338 'obj' => &$obj,
2339 'arrayrecord' => $arrayrecord,
2340 'array_match_file_to_database' => $array_match_file_to_database,
2341 'objimport' => $objimport,
2342 'fieldssource' => $fieldssource,
2343 'importid' => $importid,
2344 'updatekeys' => $updatekeys,
2345 'arrayoferrors' => &$arrayoferrors,
2346 'arrayofwarnings' => &$arrayofwarnings,
2347 'nbok' => &$nbok,
2348 );
2349
2350 $reshook = $hookmanager->executeHooks('ImportInsert', $parameters);
2351 if ($reshook < 0) {
2352 $arrayoferrors[$sourcelinenb][] = [
2353 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
2354 ];
2355 }
2356
2357 if (empty($reshook)) {
2358 // Run import
2359 $result = $obj->import_insert($arrayrecord, $array_match_file_to_database, $objimport, count($fieldssource), $importid, $updatekeys);
2360
2361 if (count($obj->errors)) {
2362 $arrayoferrors[$sourcelinenb] = $obj->errors;
2363 }
2364 if (count($obj->warnings)) {
2365 $arrayofwarnings[$sourcelinenb] = $obj->warnings;
2366 }
2367
2368 if (!count($obj->errors) && !count($obj->warnings)) {
2369 $nbok++;
2370 }
2371 }
2372
2373 $reshook = $hookmanager->executeHooks('AfterImportInsert', $parameters);
2374 if ($reshook < 0) {
2375 $arrayoferrors[$sourcelinenb][] = [
2376 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
2377 ];
2378 }
2379 }
2380 // Close file
2381 $obj->import_close_file();
2382 } else {
2383 print $langs->trans("ErrorFailedToOpenFile", $pathfile);
2384 }
2385
2386 if (count($arrayoferrors) > 0) {
2387 $db->rollback(); // We force rollback because this was errors.
2388 } else {
2389 $error = 0;
2390
2391 // Run the sql after import if defined
2392 //var_dump($objimport->array_import_run_sql_after[0]);
2393 if (!empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0])) {
2394 $i = 0;
2395 foreach ($objimport->array_import_run_sql_after[0] as $sqlafterimport) {
2396 $i++;
2397 $resqlafterimport = $db->query($sqlafterimport);
2398 if (!$resqlafterimport) {
2399 $arrayoferrors['none'][] = array('lib' => $langs->trans("Error running final request: ".$sqlafterimport));
2400 $error++;
2401 }
2402 }
2403 }
2404
2405 if (!$error) {
2406 $db->commit(); // We can commit if no errors.
2407 } else {
2408 $db->rollback();
2409 }
2410 }
2411
2412 print dol_get_fiche_end();
2413
2414
2415 // Show result
2416 print '<br>';
2417 print '<div class="info">';
2418 print $langs->trans("NbOfLinesImported", $nbok).'</b><br>';
2419 print $langs->trans("NbInsert", empty($obj->nbinsert) ? 0 : $obj->nbinsert).'<br>';
2420 print $langs->trans("NbUpdate", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'<br>';
2421 print '</div>';
2422 print '<div class="center">';
2423 print $langs->trans("FileWasImported", $importid).'<br>';
2424 print '<span class="opacitymedium">'.$langs->trans("YouCanUseImportIdToFindRecord", $importid).'</span><br>';
2425 print '</div>';
2426}
2427
2428
2429
2430print '<br>';
2431
2432// End of page
2433llxFooter();
2434$db->close();
2435
2436
2445function show_elem($fieldssource, $pos, $key)
2446{
2447 global $conf, $langs;
2448
2449 $height = '32px';
2450
2451 if ($key == 'none') {
2452 //stop multiple duplicate ids with no number
2453 print "\n\n<!-- Box_no-key start-->\n";
2454 print '<div class="box boximport" style="padding:0;">'."\n";
2455 print '<table summary="boxtable_no-key" class="centpercent nobordernopadding">'."\n";
2456 } else {
2457 print "\n\n<!-- Box ".$pos." start -->\n";
2458 print '<div class="box boximport" style="padding: 0;" id="boxto_'.$pos.'">'."\n";
2459
2460 print '<table summary="boxtable'.$pos.'" class="nobordernopadding centpercent tableimport">'."\n";
2461 }
2462
2463 if (($pos && $pos > count($fieldssource)) && (!isset($fieldssource[$pos]["imported"]))) { // No fields
2464 /*
2465 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
2466 print '<td class="nocellnopadd" width="16" style="font-weight: normal">';
2467 print '</td>';
2468 print '<td style="font-weight: normal">';
2469 print $langs->trans("NoFields");
2470 print '</td>';
2471 print '</tr>';
2472 */
2473 } elseif ($key == 'none') { // Empty line
2474 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
2475 print '<td class="nocellnopadd" width="16" style="font-weight: normal">';
2476 print '&nbsp;';
2477 print '</td>';
2478 print '<td style="font-weight: normal">';
2479 print '&nbsp;';
2480 print '</td>';
2481 print '</tr>';
2482 } else {
2483 // Print field of source file
2484 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
2485 print '<td class="nocellnopadd" width="16" style="font-weight: normal">';
2486 // The image must have the class 'boxhandle' because it's value used in DOM draggable objects to define the area used to catch the full object
2487 //print img_picto($langs->trans("MoveField", $pos), 'grip_title', 'class="boxhandle" style="cursor:move;"');
2488 print img_picto($langs->trans("Column").' '.num2Alpha($pos - 1), 'file', 'class="pictofixedwidth marginleftonly"');
2489 print '</td>';
2490 if (isset($fieldssource[$pos]['imported']) && $fieldssource[$pos]['imported'] == false) {
2491 print '<td class="nowraponall boxtdunused" style="font-weight: normal">';
2492 } else {
2493 print '<td class="nowraponall tdoverflowmax500" style="font-weight: normal">';
2494 }
2495 print $langs->trans("Column").' '.num2Alpha($pos - 1).' (#'.$pos.')';
2496 if (empty($fieldssource[$pos]['example1'])) {
2497 $example = $fieldssource[$pos]['label'];
2498 } else {
2499 $example = $fieldssource[$pos]['example1'];
2500 }
2501 if ($example) {
2502 if (!utf8_check($example)) {
2503 $example = mb_convert_encoding($example, 'UTF-8', 'ISO-8859-1');
2504 }
2505 // if (!empty($conf->dol_optimize_smallscreen)) { //print '<br>'; }
2506 print ' - ';
2507 print '<i class="opacitymedium">'.dol_escape_htmltag($example).'</i>';
2508 }
2509 print '</td>';
2510 print '</tr>';
2511 }
2512
2513 print "</table>\n";
2514
2515 print "</div>\n";
2516 print "<!-- Box end -->\n\n";
2517}
2518
2519
2527function getnewkey(&$fieldssource, &$listofkey)
2528{
2529 $i = count($fieldssource) + 1;
2530 // Max number of key
2531 $maxkey = 0;
2532 foreach ($listofkey as $key => $val) {
2533 $maxkey = max($maxkey, $key);
2534 }
2535 // Found next empty key
2536 while ($i <= $maxkey) {
2537 if (empty($listofkey[$i])) {
2538 break;
2539 } else {
2540 $i++;
2541 }
2542 }
2543
2544 $listofkey[$i] = 1;
2545 return $i;
2546}
2555function arrayInsert($array, $position, $insertArray)
2556{
2557 $ret = [];
2558
2559 if ($position == count($array)) {
2560 $ret = $array + $insertArray;
2561 } else {
2562 $i = 0;
2563 foreach ($array as $key => $value) {
2564 if ($position == $i++) {
2565 $ret += $insertArray;
2566 }
2567
2568 $ret[$key] = $value;
2569 }
2570 }
2571
2572 return $ret;
2573}
ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $forcefocus=0, $widthTypeOfAutocomplete='resolve', $idforemptyvalue='-1', $morecss='')
Convert a html select field into an ajax combobox.
Definition ajax.lib.php:475
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class permettant la generation de composants html autre Only common components are here.
Class to manage imports.
Parent class for import file readers.
Class to manage Dolibarr users.
dol_filemtime($pathoffile)
Return time of a file.
dol_filesize($pathoffile)
Return size of a file.
dol_delete_file($file, $disableglob=0, $nophperrors=0, $nohook=0, $object=null, $allowdotdot=false, $indexdatabase=1, $nolog=0)
Remove a file or several files with a mask.
dol_count_nb_of_line($file)
Count number of lines in a file.
dol_dir_list($utf8_path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition files.lib.php:63
dol_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $keyforsourcefile='addedfile', $upload_dir='', $mode=0)
Check validity of a file upload from an GUI page, and move it to its final destination.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
dolExplodeIntoArray($string, $delimiter=';', $kv='=')
Split a string with 2 keys into key array.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
img_delete($titlealt='default', $other='class="pictodelete"', $morecss='')
Show delete logo.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dolPrintHTML($s, $allowiframe=0)
Return a string (that can be on several lines) ready to be output on a HTML page.
dol_string_nohtmltag($stringtoclean, $removelinefeed=1, $pagecodeto='UTF-8', $strip_tags=0, $removedoublespaces=1)
Clean a string from all HTML tags and entities.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
dol_now($mode='auto')
Return date for now.
img_mime($file, $titlealt='', $morecss='')
Show MIME img of a file.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dol_sort_array(&$array, $index, $order='asc', $natsort=0, $case_sensitive=0, $keepindex=0)
Advanced sort array by the value of a given key, which produces ascending (default) or descending out...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dol_string_unaccent($str)
Clean a string from all accent characters to be used as ref, login or by dol_sanitizeFileName.
num2Alpha($n)
Return a numeric value into an Excel like column number.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
img_error($titlealt='default')
Show error logo.
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.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='')
Show information in HTML for admin users or standard users.
utf8_check($str)
Check if a string is in UTF8.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
import_prepare_head($param, $maxstep=0)
Function to return list of tabs for import pages.
show_elem($fieldssource, $pos, $key)
Function to put the movable box of a source field.
Definition import.php:2445
getnewkey(&$fieldssource, &$listofkey)
Return not used field number.
Definition import.php:2527
arrayInsert($array, $position, $insertArray)
Return array with element inserted in it at position $position.
Definition import.php:2555
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
getMaxFileSizeArray()
Return the max allowed for file upload.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.