dolibarr 21.0.3
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 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.'-'.$_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') {
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', '', -1);
349
350 print '<div class="opacitymedium">'.$langs->trans("SelectImportDataSet").'</div><br>';
351
352 // Affiche les modules d'imports
353 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
354 print '<table class="noborder centpercent nomarginbottom">';
355 print '<tr class="liste_titre">';
356 print '<td>'.$langs->trans("Module").'</td>';
357 print '<td>'.$langs->trans("ImportableDatas").'</td>';
358 print '<td>&nbsp;</td>';
359 print '</tr>';
360
361 if (count($objimport->array_import_module)) {
362 $sortedarrayofmodules = dol_sort_array($objimport->array_import_module, 'position_of_profile', 'asc', 0, 0, 1);
363 foreach ($sortedarrayofmodules as $key => $value) {
364 //var_dump($key.' '.$value['position_of_profile'].' '.$value['import_code'].' '.$objimport->array_import_module[$key]['module']->getName().' '.$objimport->array_import_code[$key]);
365 $titleofmodule = $objimport->array_import_module[$key]['module']->getName();
366 print '<tr class="oddeven"><td class="tdoverflowmax200" title="'.dolPrintHTML($titleofmodule).'">';
367 // Special case for import common to module/services
368 if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
369 $titleofmodule = $langs->trans("ProductOrService");
370 }
371 print dolPrintHTML($titleofmodule);
372 print '</td><td>';
373 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]);
374 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
375 $label = $objimport->array_import_label[$key];
376 print '<div class="twolinesmax-normallineheight minwidth200onall">';
377 print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon, 'class="pictofixedwidth"');
378 print dolPrintHTML($label);
379 print '</div>';
380 print '</td><td style="text-align: right">';
381 if ($objimport->array_import_perms[$key]) {
382 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>';
383 } else {
384 print $langs->trans("NotEnoughPermissions");
385 }
386 print '</td></tr>';
387 }
388 } else {
389 print '<tr><td class="oddeven" colspan="3">'.$langs->trans("NoImportableData").'</td></tr>';
390 }
391 print '</table>';
392 print '</div>';
393
394 print dol_get_fiche_end();
395}
396
397
398// STEP 2: Page to select input format file
399if ($step == 2 && $datatoimport) {
400 $param = '&datatoimport='.urlencode($datatoimport);
401 if ($excludefirstline) {
402 $param .= '&excludefirstline='.urlencode($excludefirstline);
403 }
404 if ($endatlinenb) {
405 $param .= '&endatlinenb='.urlencode($endatlinenb);
406 }
407 if ($separator) {
408 $param .= '&separator='.urlencode($separator);
409 }
410 if ($enclosure) {
411 $param .= '&enclosure='.urlencode($enclosure);
412 }
413
414 llxHeader('', $langs->trans("NewImport"), $help_url);
415
416 $head = import_prepare_head($param, 2);
417
418 print dol_get_fiche_head($head, 'step2', '', -2);
419
420 print '<div class="underbanner clearboth"></div>';
421 print '<div class="fichecenter">';
422
423 print '<table class="border tableforfield centpercent">';
424
425 // Module
426 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
427 print '<td>';
428 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
429 // Special case for import common to module/services
430 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
431 $titleofmodule = $langs->trans("ProductOrService");
432 }
433 print $titleofmodule;
434 print '</td></tr>';
435
436 // Dataset to import
437 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
438 print '<td>';
439 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
440 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
441 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
442 print $objimport->array_import_label[0];
443 print '</td></tr>';
444
445 print '</table>';
446 print '</div>';
447
448 print dol_get_fiche_end();
449
450 print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
451 print '<input type="hidden" name="token" value="'.newToken().'">';
452
453 print '<br>';
454
455 print '<span class="opacitymedium">';
456 $s = $langs->trans("ChooseFormatOfFileToImport", '{s1}');
457 $s = str_replace('{s1}', img_picto('', 'next'), $s);
458 print $s;
459 print '</span><br><br>';
460
461 print '<br>';
462
463 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
464 print '<table class="noborder centpercent" cellpadding="4">';
465
466 $filetoimport = '';
467
468 // Add format information and link to download example
469 print '<tr class="liste_titre"><td colspan="5">';
470 print $langs->trans("FileMustHaveOneOfFollowingFormat");
471 print '</td></tr>';
472 $list = $objmodelimport->listOfAvailableImportFormat($db);
473 foreach ($list as $key) {
474 print '<tr class="oddeven">';
475 print '<td width="16">'.img_picto_common($key, $objmodelimport->getPictoForKey($key)).'</td>';
476 $htmltext = $objmodelimport->getDriverDescForKey($key);
477 print '<td>'.$form->textwithpicto($objmodelimport->getDriverLabelForKey($key), $htmltext).'</td>';
478 print '<td style="text-align:center">';
479 if (empty($objmodelimport->drivererror[$key])) {
480 $filename = $langs->transnoentitiesnoconv("ExampleOfImportFile").'_'.$datatoimport.'.'.$key;
481 print '<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.$param.'&output=file&file='.urlencode($filename).'" target="_blank" rel="noopener noreferrer">';
482 print img_picto('', 'download', 'class="paddingright opacitymedium"');
483 print $langs->trans("DownloadEmptyExampleShort");
484 print '</a>';
485 print $form->textwithpicto('', $langs->trans("DownloadEmptyExample").'.<br>'.$langs->trans("StarAreMandatory"));
486 } else {
487 print dolPrintHTML($objmodelimport->drivererror[$key]);
488 }
489 print '</td>';
490 // Action button
491 print '<td style="text-align:right">';
492 if (empty($objmodelimport->drivererror[$key])) {
493 print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=3&format='.$key.$param.'">'.img_picto($langs->trans("SelectFormat"), 'next', 'class="fa-15"').'</a>';
494 }
495 print '</td>';
496 print '</tr>';
497 }
498
499 print '</table>';
500 print '</div>';
501
502 print '</form>';
503}
504
505
506// STEP 3: Page to select file
507if ($step == 3 && $datatoimport) {
508 $param = '&datatoimport='.urlencode($datatoimport).'&format='.urlencode($format);
509 if ($excludefirstline) {
510 $param .= '&excludefirstline='.urlencode($excludefirstline);
511 }
512 if ($endatlinenb) {
513 $param .= '&endatlinenb='.urlencode($endatlinenb);
514 }
515 if ($separator) {
516 $param .= '&separator='.urlencode($separator);
517 }
518 if ($enclosure) {
519 $param .= '&enclosure='.urlencode($enclosure);
520 }
521
522 $list = $objmodelimport->listOfAvailableImportFormat($db);
523
524 llxHeader('', $langs->trans("NewImport"), $help_url);
525
526 $head = import_prepare_head($param, 3);
527
528 print dol_get_fiche_head($head, 'step3', '', -2);
529
530 /*
531 * Confirm delete file
532 */
533 if ($action == 'delete') {
534 print $form->formconfirm($_SERVER["PHP_SELF"].'?urlfile='.urlencode(GETPOST('urlfile')).'&step=3'.$param, $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1);
535 }
536
537 print '<div class="underbanner clearboth"></div>';
538 print '<div class="fichecenter">';
539
540 print '<table class="border tableforfield centpercent">';
541
542 // Module
543 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
544 print '<td>';
545 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
546 // Special case for import common to module/services
547 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
548 $titleofmodule = $langs->trans("ProductOrService");
549 }
550 print $titleofmodule;
551 print '</td></tr>';
552
553 // Lot de donnees a importer
554 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
555 print '<td>';
556 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
557 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
558 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
559 print $objimport->array_import_label[0];
560 print '</td></tr>';
561
562 print '</table>';
563 print '</div>';
564
565 print '<br>';
566
567 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
568
569 print '<div class="underbanner clearboth"></div>';
570 print '<div class="fichecenter">';
571 print '<table width="100%" class="border tableforfield">';
572
573 // Source file format
574 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
575 print '<td class="nowraponall">';
576 $text = $objmodelimport->getDriverDescForKey($format);
577 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
578 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
579 print '</td><td style="text-align:right" class="nowrap">';
580 $filename = $langs->transnoentitiesnoconv("ExampleOfImportFile").'_'.$datatoimport.'.'.$format;
581 print '<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$format.$param.'&output=file&file='.urlencode($filename).'" target="_blank" rel="noopener noreferrer">';
582 print img_picto('', 'download', 'class="paddingright opacitymedium"');
583 print $langs->trans("DownloadEmptyExampleShort");
584 print '</a>';
585 print $form->textwithpicto('', $langs->trans("DownloadEmptyExample").'.<br>'.$langs->trans("StarAreMandatory"));
586 print '</td></tr>';
587
588 print '</table>';
589 print '</div>';
590
591 print dol_get_fiche_end();
592
593
594 if ($format == 'xlsx' && !class_exists('XMLWriter')) {
595 $langs->load("install");
596 print info_admin($langs->trans("ErrorPHPDoesNotSupport", 'php-xml'), 0, 0, '1', 'error');
597 }
598
599
600 print '<br><br>';
601
602 print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" method="POST">';
603 print '<input type="hidden" name="token" value="'.newToken().'">';
604 print '<input type="hidden" value="'.$step.'" name="step">';
605 print '<input type="hidden" value="'.dol_escape_htmltag($format).'" name="format">';
606 print '<input type="hidden" value="'.$excludefirstline.'" name="excludefirstline">';
607 print '<input type="hidden" value="'.$endatlinenb.'" name="endatlinenb">';
608 print '<input type="hidden" value="'.dol_escape_htmltag($separator).'" name="separator">';
609 print '<input type="hidden" value="'.dol_escape_htmltag($enclosure).'" name="enclosure">';
610 print '<input type="hidden" value="'.dol_escape_htmltag($datatoimport).'" name="datatoimport">';
611
612 print '<span class="opacitymedium">';
613 $s = $langs->trans("ChooseFileToImport", '{s1}');
614 $s = str_replace('{s1}', img_picto('', 'next'), $s);
615 print $s;
616 print '</span><br><br>';
617
618 $filetoimport = '';
619
620 // Input file name box
621 print '<div class="marginbottomonly">';
622 $maxfilesizearray = getMaxFileSizeArray();
623 $maxmin = $maxfilesizearray['maxmin'];
624 if ($maxmin > 0) {
625 print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
626 }
627 print '<input type="file" name="userfile" size="20" maxlength="80"> &nbsp; &nbsp; ';
628 $out = (!getDolGlobalString('MAIN_UPLOAD_DOC') ? ' disabled' : '');
629 print '<input type="submit" class="button small" value="'.$langs->trans("AddFile").'"'.$out.' name="sendit">';
630 $out = '';
631 if (getDolGlobalString('MAIN_UPLOAD_DOC')) {
632 $max = getDolGlobalString('MAIN_UPLOAD_DOC'); // In Kb
633 $maxphp = @ini_get('upload_max_filesize'); // In unknown
634 if (preg_match('/k$/i', $maxphp)) {
635 $maxphp = (int) substr($maxphp, 0, -1);
636 }
637 if (preg_match('/m$/i', $maxphp)) {
638 $maxphp = (int) substr($maxphp, 0, -1) * 1024;
639 }
640 if (preg_match('/g$/i', $maxphp)) {
641 $maxphp = (int) substr($maxphp, 0, -1) * 1024 * 1024;
642 }
643 if (preg_match('/t$/i', $maxphp)) {
644 $maxphp = (int) substr($maxphp, 0, -1) * 1024 * 1024 * 1024;
645 }
646 $maxphp2 = @ini_get('post_max_size'); // In unknown
647 if (preg_match('/k$/i', $maxphp2)) {
648 $maxphp2 = (int) substr($maxphp2, 0, -1);
649 }
650 if (preg_match('/m$/i', $maxphp2)) {
651 $maxphp2 = (int) substr($maxphp2, 0, -1) * 1024;
652 }
653 if (preg_match('/g$/i', $maxphp2)) {
654 $maxphp2 = (int) substr($maxphp2, 0, -1) * 1024 * 1024;
655 }
656 if (preg_match('/t$/i', $maxphp2)) {
657 $maxphp2 = (int) substr($maxphp2, 0, -1) * 1024 * 1024 * 1024;
658 }
659 // Now $max and $maxphp and $maxphp2 are in Kb
660 $maxmin = $max;
661 $maxphptoshow = $maxphptoshowparam = '';
662 if ($maxphp > 0) {
663 $maxmin = min($max, $maxphp);
664 $maxphptoshow = $maxphp;
665 $maxphptoshowparam = 'upload_max_filesize';
666 }
667 if ($maxphp2 > 0) {
668 $maxmin = min($max, $maxphp2);
669 if ($maxphp2 < $maxphp) {
670 $maxphptoshow = $maxphp2;
671 $maxphptoshowparam = 'post_max_size';
672 }
673 }
674
675 $langs->load('other');
676 $out .= ' ';
677 $out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphptoshow), 1);
678 } else {
679 $out .= ' ('.$langs->trans("UploadDisabled").')';
680 }
681 print $out;
682 print '</div>';
683
684 // Search available imports
685 $filearray = dol_dir_list($conf->import->dir_temp, 'files', 0, '', '', 'name', SORT_DESC);
686 if (count($filearray) > 0) {
687 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
688 print '<table class="noborder centpercent" width="100%" cellpadding="4">';
689
690 $dir = $conf->import->dir_temp;
691
692 // Search available files to import
693 $i = 0;
694 foreach ($filearray as $key => $val) {
695 $file = $val['name'];
696
697 // readdir return value in ISO and we want UTF8 in memory
698 if (!utf8_check($file)) {
699 $file = mb_convert_encoding($file, 'UTF-8', 'ISO-8859-1');
700 }
701
702 if (preg_match('/^\./', $file)) {
703 continue;
704 }
705
706 $modulepart = 'import';
707 $urlsource = $_SERVER["PHP_SELF"].'?step='.$step.$param.'&filetoimport='.urlencode($filetoimport);
708 $relativepath = $file;
709
710 print '<tr class="oddeven">';
711 print '<td>';
712 print img_mime($file, '', 'pictofixedwidth');
713 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=3'.$param.'" target="_blank" rel="noopener noreferrer">';
714 print $file;
715 print '</a>';
716 print '</td>';
717 // Affiche taille fichier
718 print '<td style="text-align:right">'.dol_print_size(dol_filesize($dir.'/'.$file)).'</td>';
719 // Affiche date fichier
720 print '<td style="text-align:right">'.dol_print_date(dol_filemtime($dir.'/'.$file), 'dayhour').'</td>';
721 // Del button
722 print '<td style="text-align:right"><a href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&step=3'.$param.'&urlfile='.urlencode($relativepath);
723 print '">'.img_delete().'</a></td>';
724 // Action button
725 print '<td style="text-align:right">';
726 print '<a href="'.$_SERVER['PHP_SELF'].'?step=4'.$param.'&filetoimport='.urlencode($relativepath).'">'.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').'</a>';
727 print '</td>';
728 print '</tr>';
729 }
730
731 print '</table>';
732 print '</div>';
733 }
734
735 print '</form>';
736}
737
738
739// STEP 4: Page to make matching between source file and database fields
740if ($step == 4 && $datatoimport) {
741 //var_dump($_SESSION["dol_array_match_file_to_database_select"]);
742 $serialized_array_match_file_to_database = isset($_SESSION["dol_array_match_file_to_database_select"]) ? $_SESSION["dol_array_match_file_to_database_select"] : '';
743 $fieldsarray = explode(',', $serialized_array_match_file_to_database);
744 $array_match_file_to_database = array(); // Same than $fieldsarray but with mapped value only (col1 => 's.fielda', col2 => 's.fieldb'...)
745 foreach ($fieldsarray as $elem) {
746 $tabelem = explode('=', $elem, 2);
747 $key = $tabelem[0];
748 $val = (isset($tabelem[1]) ? $tabelem[1] : '');
749 if ($key && $val) {
750 $array_match_file_to_database[$key] = $val;
751 }
752 }
753
754 //var_dump($serialized_array_match_file_to_database);
755 //var_dump($fieldsarray);
756 //var_dump($array_match_file_to_database);
757
758 $model = $format;
759 $list = $objmodelimport->listOfAvailableImportFormat($db);
760
761 if (empty($separator)) {
762 $separator = (!getDolGlobalString('IMPORT_CSV_SEPARATOR_TO_USE') ? ',' : $conf->global->IMPORT_CSV_SEPARATOR_TO_USE);
763 }
764
765 // The separator has been defined, if it is a unique char, we check it is valid by reading the source file
766 if ($model == 'csv' && strlen($separator) == 1 && !GETPOSTISSET('separator')) {
767 '@phan-var-force ImportCsv $obj';
768 // Count the char in first line of file.
769 $fh = fopen($conf->import->dir_temp.'/'.$filetoimport, 'r');
770 if ($fh) {
771 $sline = fgets($fh, 1000000);
772 fclose($fh);
773 $nboccurence = substr_count($sline, $separator);
774 $nboccurencea = substr_count($sline, ',');
775 $nboccurenceb = substr_count($sline, ';');
776 //var_dump($nboccurence." ".$nboccurencea." ".$nboccurenceb);exit;
777 if ($nboccurence == 0) {
778 if ($nboccurencea > 2) {
779 $separator = ',';
780 } elseif ($nboccurenceb > 2) {
781 $separator = ';';
782 }
783 }
784 }
785 }
786
787 // The value to use
788 $separator_used = str_replace('\t', "\t", $separator);
789
790 // Create class to use for import
791 $dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
792 $file = "import_".$model.".modules.php";
793 $classname = "Import".ucfirst($model);
794 require_once $dir.$file;
795 $obj = new $classname($db, $datatoimport);
796 '@phan-var-force ModeleImports $obj';
797
798 if (!empty($obj->error)) {
799 $langs->load("errors");
800 $param = '&datatoimport='.$datatoimport.'&format='.$format;
801 setEventMessages($obj->error, null, 'errors');
802 header("Location: ".$_SERVER["PHP_SELF"].'?step=3'.$param.'&filetoimport='.urlencode($relativepath));
803 exit;
804 }
805
806 if ($model == 'csv') {
807 '@phan-var-force ImportCsv $obj';
808 $obj->separator = $separator_used;
809 $obj->enclosure = $enclosure;
810 $obj->charset = '';
811 }
812 if ($model == 'xlsx') {
813 '@phan-var-force ImportXlsx $obj';
814 if (!preg_match('/\.xlsx$/i', $filetoimport)) {
815 $langs->load("errors");
816 $param = '&datatoimport='.$datatoimport.'&format='.$format;
817 setEventMessages($langs->trans("ErrorFileMustHaveFormat", $model), null, 'errors');
818 header("Location: ".$_SERVER["PHP_SELF"].'?step=3'.$param.'&filetoimport='.urlencode($relativepath));
819 exit;
820 }
821 }
822
823 if (GETPOST('update')) {
824 $array_match_file_to_database = array();
825 }
826
827 // Load the source fields from input file into variable $arrayrecord
828 $fieldssource = array();
830 $result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
831 if ($result >= 0) {
832 // Read first line
833 $arrayrecord = $obj->import_read_record();
834
835 // Create array $fieldssource starting with 1 with values found of first line.
836 $i = 1;
837 foreach ($arrayrecord as $key => $val) {
838 if ($val["type"] != -1) {
839 $fieldssource[$i]['example1'] = dol_trunc($val['val'], 128);
840 $i++;
841 } else {
842 $fieldssource[$i]['example1'] = $langs->trans('Empty');
843 $i++;
844 }
845 $fieldssource[$i]['imported'] = 0;
846 }
847 $obj->import_close_file();
848 }
849
850 // Load targets fields in database
851 $fieldstarget = $objimport->array_import_fields[0];
852 $minpos = min(count($fieldssource), count($fieldstarget));
853 //var_dump($array_match_file_to_database);
854
855
856 $initialloadofstep4 = false;
857 if (empty($_SESSION['dol_array_match_file_to_database_select'])) {
858 $initialloadofstep4 = true;
859 }
860
861 // Is it a first time in page (if yes, we must initialize array_match_file_to_database)
862 if (count($array_match_file_to_database) == 0) {
863 // This is first input in screen, we need to define
864 // $array_match_file_to_database
865 // $serialized_array_match_file_to_database
866 // $_SESSION["dol_array_match_file_to_database"]
867 $pos = 1;
868 $num = count($fieldssource);
869 while ($pos <= $num) {
870 if ($num >= 1 && $pos <= $num) {
871 $posbis = 1;
872 foreach ($fieldstarget as $key => $val) {
873 if ($posbis < $pos) {
874 $posbis++;
875 continue;
876 }
877 // We found the key of targets that is at position pos
878 $array_match_file_to_database[$pos] = $key;
879 break;
880 }
881 }
882 $pos++;
883 }
884 }
885 $array_match_database_to_file = array_flip($array_match_file_to_database);
886 //var_dump($array_match_database_to_file);
887 //var_dump($_SESSION["dol_array_match_file_to_database_select"]);
888
889 $fieldstarget_tmp = array();
890 $arraykeysfieldtarget = array_keys($fieldstarget);
891 $position = 0;
892 foreach ($fieldstarget as $key => $label) {
893 $isrequired = preg_match('/\*$/', $label);
894 if (!empty($isrequired)) {
895 $newlabel = substr($label, 0, -1);
896 $fieldstarget_tmp[$key] = array("label" => $newlabel, "required" => true);
897 } else {
898 $fieldstarget_tmp[$key] = array("label" => $label, "required" => false);
899 }
900 if (!empty($array_match_database_to_file[$key])) {
901 $fieldstarget_tmp[$key]["imported"] = true;
902 $fieldstarget_tmp[$key]["position"] = (int) $array_match_database_to_file[$key] - 1;
903 $keytoswap = $key;
904 while (!empty($array_match_database_to_file[$keytoswap])) {
905 if ($position + 1 > $array_match_database_to_file[$keytoswap]) {
906 $keytoswapwith = $array_match_database_to_file[$keytoswap] - 1;
907 $tmp = [$keytoswap => $fieldstarget_tmp[$keytoswap]];
908 unset($fieldstarget_tmp[$keytoswap]);
909 $fieldstarget_tmp = arrayInsert($fieldstarget_tmp, $keytoswapwith, $tmp);
910 $keytoswapwith = $arraykeysfieldtarget[$array_match_database_to_file[$keytoswap] - 1];
911 $tmp = $fieldstarget_tmp[$keytoswapwith];
912 unset($fieldstarget_tmp[$keytoswapwith]);
913 $fieldstarget_tmp[$keytoswapwith] = $tmp;
914 $keytoswap = $keytoswapwith;
915 } else {
916 break;
917 }
918 }
919 } else {
920 $fieldstarget_tmp[$key]["imported"] = false;
921 }
922 $position++;
923 }
924 $fieldstarget = $fieldstarget_tmp;
925
926 //print $serialized_array_match_file_to_database;
927 //print $_SESSION["dol_array_match_file_to_database"];
928 //print $_SESSION["dol_array_match_file_to_database_select"];
929 //var_dump($array_match_file_to_database);exit;
930
931 // Now $array_match_file_to_database contains fieldnb(1,2,3...)=>fielddatabase(key in $array_match_file_to_database)
932
933 $param = '&format='.$format.'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport);
934 if ($excludefirstline) {
935 $param .= '&excludefirstline='.urlencode($excludefirstline);
936 }
937 if ($endatlinenb) {
938 $param .= '&endatlinenb='.urlencode($endatlinenb);
939 }
940 if ($separator) {
941 $param .= '&separator='.urlencode($separator);
942 }
943 if ($enclosure) {
944 $param .= '&enclosure='.urlencode($enclosure);
945 }
946
947 llxHeader('', $langs->trans("NewImport"), $help_url);
948
949 $head = import_prepare_head($param, 4);
950
951 print dol_get_fiche_head($head, 'step4', '', -2);
952
953 print '<div class="underbanner clearboth"></div>';
954 print '<div class="fichecenter">';
955
956 print '<table class="centpercent border tableforfield">';
957
958 // Module
959 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
960 print '<td>';
961 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
962 // Special case for import common to module/services
963 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
964 $titleofmodule = $langs->trans("ProductOrService");
965 }
966 print $titleofmodule;
967 print '</td></tr>';
968
969 // Lot de donnees a importer
970 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
971 print '<td>';
972 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
973 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
974 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
975 print $objimport->array_import_label[0];
976 print '</td></tr>';
977
978 print '</table>';
979 print '</div>';
980
981 print '<br>';
982
983 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
984
985 print '<div class="underbanner clearboth"></div>';
986 print '<div class="fichecenter">';
987 print '<table width="100%" class="border tableforfield">';
988
989 // Source file format
990 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
991 print '<td class="nowraponall">';
992 $text = $objmodelimport->getDriverDescForKey($format);
993 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
994 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
995 print '</td></tr>';
996
997 // Separator and enclosure
998 if ($model == 'csv') {
999 '@phan-var-force ImportCsv $obj';
1000 print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
1001 print '<td>';
1002 print '<form method="POST">';
1003 print '<input type="hidden" name="token" value="'.newToken().'">';
1004 print '<input type="hidden" value="'.$step.'" name="step">';
1005 print '<input type="hidden" value="'.$format.'" name="format">';
1006 print '<input type="hidden" value="'.$excludefirstline.'" name="excludefirstline">';
1007 print '<input type="hidden" value="'.$endatlinenb.'" name="endatlinenb">';
1008 print '<input type="hidden" value="'.$datatoimport.'" name="datatoimport">';
1009 print '<input type="hidden" value="'.$filetoimport.'" name="filetoimport">';
1010 print $langs->trans("Separator").' : ';
1011 print '<input type="text" class="width25 center" name="separator" value="'.dol_escape_htmltag($separator).'"/>';
1012 print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : ';
1013 print '<input type="text" class="width25 center" name="enclosure" value="'.dol_escape_htmltag($enclosure).'"/> ';
1014 print '<input name="update" type="submit" value="'.$langs->trans('Update').'" class="button smallpaddingimp" />';
1015 print '</form>';
1016 print '</td></tr>';
1017 }
1018
1019 // File to import
1020 print '<tr><td>'.$langs->trans("FileToImport").'</td>';
1021 print '<td>';
1022 $modulepart = 'import';
1023 $relativepath = GETPOST('filetoimport');
1024 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
1025 print img_mime($file, '', 'pictofixedwidth');
1026 print $filetoimport;
1027 print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"');
1028 print '</a>';
1029 print '</td></tr>';
1030
1031 print '</table>';
1032 print '</div>';
1033
1034 print dol_get_fiche_end();
1035
1036 print '<br>'."\n";
1037
1038
1039 // List of source fields
1040 print '<!-- List of source fields -->'."\n";
1041 print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
1042 print '<input type="hidden" name="token" value="'.newToken().'">';
1043 print '<input type="hidden" name="action" value="select_model">';
1044 print '<input type="hidden" name="step" value="4">';
1045 print '<input type="hidden" name="format" value="'.$format.'">';
1046 print '<input type="hidden" name="datatoimport" value="'.$datatoimport.'">';
1047 print '<input type="hidden" name="filetoimport" value="'.$filetoimport.'">';
1048 print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
1049 print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
1050 print '<input type="hidden" name="separator" value="'.dol_escape_htmltag($separator).'">';
1051 print '<input type="hidden" name="enclosure" value="'.dol_escape_htmltag($enclosure).'">';
1052
1053 // Import profile to use/load
1054 print '<div class="marginbottomonly">';
1055 print '<span class="opacitymedium">';
1056 $s = $langs->trans("SelectImportFieldsSource", '{s1}');
1057 $s = str_replace('{s1}', img_picto('', 'grip_title', '', 0, 0, 0, '', '', 0), $s);
1058 print $s;
1059 print '</span> ';
1060 $htmlother->select_import_model($importmodelid, 'importmodelid', $datatoimport, 1, $user->id);
1061 print '<input type="submit" class="button small reposition" value="'.$langs->trans("Select").'">';
1062 print '</div>';
1063 print '</form>';
1064
1065 // Title of array with fields
1066 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
1067 print '<table class="noborder centpercent">';
1068 print '<tr class="liste_titre">';
1069 print '<td>'.$langs->trans("FieldsInSourceFile").'</td>';
1070 print '<td>'.$langs->trans("FieldsInTargetDatabase").'</td>';
1071 print '</tr>';
1072
1073 //var_dump($array_match_file_to_database);
1074
1075 print '<tr valign="top"><td width="50%" class="nopaddingleftimp">';
1076
1077 $fieldsplaced = array();
1078 $valforsourcefieldnb = array();
1079 $listofkeys = array();
1080 foreach ($array_match_file_to_database as $key => $val) {
1081 $listofkeys[$key] = 1;
1082 }
1083
1084 print "\n<!-- Box left container -->\n";
1085 print '<div id="left" class="connectedSortable">'."\n";
1086
1087 // List of source fields
1088
1089 $lefti = 1;
1090 foreach ($fieldssource as $key => $val) {
1091 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1092 show_elem($fieldssource, $key, $val); // key is field number in source file
1093 $listofkeys[$key] = 1;
1094 $fieldsplaced[$key] = 1;
1095 $valforsourcefieldnb[$lefti] = $key;
1096 $lefti++;
1097
1098 /*if ($lefti > count($fieldstarget)) {
1099 break; // Other fields are in the not imported area
1100 }*/
1101 }
1102 //var_dump($valforsourcefieldnb);
1103
1104 print "</div>\n";
1105 print "<!-- End box left container -->\n";
1106
1107
1108 print '</td><td width="50%" class="nopaddingrightimp">';
1109
1110 // Set the list of all possible target fields in Dolibarr.
1111
1112 $optionsall = array();
1113 foreach ($fieldstarget as $code => $line) {
1114 $tmparray = explode('|', $line["label"]); // If label of field is several translation keys separated with |
1115 $labeltoshow = '';
1116 foreach ($tmparray as $tmpkey => $tmpval) {
1117 $labeltoshow .= ($labeltoshow ? ' '.$langs->trans('or').' ' : '').$langs->transnoentities($tmpval);
1118 }
1119 // TODO Get type from a new array into module descriptor.
1120 // $picto = 'email';
1121 $picto = '';
1122 $optionsall[$code] = array(
1123 'labelkey' => $line['label'],
1124 'labelkeyarray' => $tmparray,
1125 'label' => $labeltoshow,
1126 'required' => (empty($line["required"]) ? 0 : 1),
1127 'position' => (!empty($line['position']) ? $line['position'] : 0),
1128 'picto' => $picto,
1129 );
1130 }
1131 // $optionsall is an array of all possible target fields. key=>array('label'=>..., 'xxx')
1132
1133 $height = '32px'; //needs px for css height attribute below
1134 $i = 0;
1135 $mandatoryfieldshavesource = true;
1136
1137 //var_dump($fieldstarget);
1138 //var_dump($optionsall);
1139 //exit;
1140
1141 //var_dump($_SESSION['dol_array_match_file_to_database']);
1142 //var_dump($_SESSION['dol_array_match_file_to_database_select']);
1143 //exit;
1144 //var_dump($optionsall);
1145 //var_dump($fieldssource);
1146 //var_dump($fieldstarget);
1147
1148 $modetoautofillmapping = 'session'; // Use setup in session
1149 if ($initialloadofstep4) {
1150 $modetoautofillmapping = 'guess';
1151 }
1152 //var_dump($modetoautofillmapping);
1153
1154 print '<table class="nobordernopadding centpercent tableimport">';
1155 foreach ($fieldssource as $code => $line) { // $fieldssource is an array code=column num, line=content on first line for column in source file.
1156 /*if ($i == $minpos) {
1157 break;
1158 }*/
1159 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
1160 // Note: $code is int, but index should be fieldname? -> @phan-suppress-next-line PhanTypeMismatchDimFetch
1161 $entity = (!empty($objimport->array_import_entities[0][$code]) ? $objimport->array_import_entities[0][$code] : $objimport->array_import_icon[0]);
1162
1163 $entityicon = !empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity; // $entityicon must string name of picto of the field like 'project', 'company', 'contact', 'modulename', ...
1164 $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', ...
1165
1166 print '<td class="nowraponall hideonsmartphone" style="font-weight: normal">=> </td>';
1167 print '<td class="nowraponall" style="font-weight: normal">';
1168
1169 $selectforline = '';
1170 $selectforline .= '<select id="selectorderimport_'.($i + 1).'" class="targetselectchange minwidth300" name="select_'.($i + 1).'">';
1171 if (!empty($line["imported"])) {
1172 $selectforline .= '<option value="-1">&nbsp;</option>';
1173 } else {
1174 $selectforline .= '<option selected="" value="-1">&nbsp;</option>';
1175 }
1176
1177 $j = 0;
1178 $codeselectedarray = array();
1179 foreach ($optionsall as $tmpcode => $tmpval) { // Loop on each entry to add into each combo list.
1180 $label = '';
1181 if (!empty($tmpval['picto'])) {
1182 $label .= img_picto('', $tmpval['picto'], 'class="pictofixedwidth"');
1183 }
1184 $label .= $tmpval['required'] ? '<strong>' : '';
1185 $label .= $tmpval['label'];
1186 $label .= $tmpval['required'] ? '*</strong>' : '';
1187
1188 $tablealias = preg_replace('/(\..*)$/i', '', $tmpcode);
1189 $tablename = !empty($objimport->array_import_tables[0][$tablealias]) ? $objimport->array_import_tables[0][$tablealias] : "";
1190
1191 $htmltext = '';
1192
1193 $filecolumn = ($i + 1);
1194 // Source field info
1195 if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need conversion
1196 $filecolumntoshow = num2Alpha($i);
1197 } else {
1198 if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') {
1199 $htmltext .= $langs->trans("DataComeFromIdFoundFromRef", $langs->transnoentitiesnoconv($entitylang)).'<br>';
1200 }
1201 if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') {
1202 $htmltext .= $langs->trans("DataComeFromIdFoundFromCodeId", $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$tmpcode]['dict'])).'<br>';
1203 }
1204 }
1205 // Source required
1206 $example = !empty($objimport->array_import_examplevalues[0][$tmpcode]) ? $objimport->array_import_examplevalues[0][$tmpcode] : "";
1207 // Example
1208 if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need conversion
1209 if ($example) {
1210 $htmltext .= $langs->trans("SourceExample").': <b>'.str_replace('"', '', $example).'</b><br>';
1211 }
1212 } else {
1213 if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') {
1214 $htmltext .= $langs->trans("SourceExample").': <b>'.$langs->transnoentitiesnoconv("ExampleAnyRefFoundIntoElement", $entitylang).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.str_replace('"', '', $example).')' : '').'</b><br>';
1215 } elseif ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') {
1216 $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>';
1217 } elseif ($example) {
1218 $htmltext .= $langs->trans("SourceExample").': <b>'.str_replace('"', '', $example).'</b><br>';
1219 }
1220 }
1221 // Format control rule
1222 if (!empty($objimport->array_import_regex[0][$tmpcode])) {
1223 $htmltext .= $langs->trans("FormatControlRule").': <b>'.str_replace('"', '', $objimport->array_import_regex[0][$tmpcode]).'</b><br>';
1224 }
1225
1226 //var_dump($htmltext);
1227 $htmltext .= $langs->trans("InformationOnTargetTables").': &nbsp; <b>'.$tablename."->".preg_replace('/^.*\./', '', $tmpcode)."</b>";
1228
1229 $labelhtml = $label.' '.$form->textwithpicto('', $htmltext, 1, 'help', '', 1);
1230
1231 $selectforline .= '<option value="'.$tmpcode.'"';
1232 if ($modetoautofillmapping == 'orderoftargets') {
1233 // 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.
1234 if ($j == $i) {
1235 $selectforline .= ' selected';
1236 }
1237 } elseif ($modetoautofillmapping == 'guess') {
1238 // The mode where we try to guess which value to preselect from the name in first column of source file.
1239 // $line['example1'] is the label of the column found on first line
1240 $regs = array();
1241 if (preg_match('/^(.+)\‍((.+\..+)\‍)$/', $line['example1'], $regs)) { // If text is "Label (x.abc)"
1242 $tmpstring1 = $regs[1];
1243 $tmpstring2 = $regs[2];
1244 } else {
1245 $tmpstring1 = $line['example1'];
1246 $tmpstring2 = '';
1247 }
1248 $tmpstring1 = strtolower(dol_string_unaccent(str_replace('*', '', trim($tmpstring1))));
1249 $tmpstring2 = strtolower(dol_string_unaccent(str_replace('*', '', trim($tmpstring2))));
1250
1251 // $tmpstring1 and $tmpstring2 are string from the input file title of column "Label (fieldname)".
1252 // $tmpval is array of target fields read from the module import profile.
1253 foreach ($tmpval['labelkeyarray'] as $tmpval2) {
1254 $labeltarget = $langs->transnoentities($tmpval2);
1255 //var_dump($tmpstring1.' - '.$tmpstring2.' - '.$tmpval['labelkey'].' - '.$tmpval['label'].' - '.$tmpval2.' - '.$labeltarget);
1256 if ($tmpstring1 && ($tmpstring1 == $tmpcode || $tmpstring1 == strtolower($labeltarget)
1257 || $tmpstring1 == strtolower(dol_string_unaccent($labeltarget)) || $tmpstring1 == strtolower($tmpval2))) {
1258 if (empty($codeselectedarray[$code])) {
1259 $selectforline .= ' selected';
1260 $codeselectedarray[$code] = 1;
1261 break;
1262 }
1263 } elseif ($tmpstring2 && ($tmpstring2 == $tmpcode || $tmpstring2 == strtolower($labeltarget)
1264 || $tmpstring2 == strtolower(dol_string_unaccent($labeltarget)) || $tmpstring2 == strtolower($tmpval2))) {
1265 if (empty($codeselectedarray[$code])) {
1266 $selectforline .= ' selected';
1267 $codeselectedarray[$code] = 1;
1268 break;
1269 }
1270 }
1271 }
1272 } elseif ($modetoautofillmapping == 'session' && !empty($_SESSION['dol_array_match_file_to_database_select'])) {
1273 $tmpselectioninsession = dolExplodeIntoArray($_SESSION['dol_array_match_file_to_database_select'], ',', '=');
1274 //var_dump($code);
1275 if (!empty($tmpselectioninsession[(string) ($i + 1)]) && $tmpselectioninsession[(string) ($i + 1)] == $tmpcode) {
1276 $selectforline .= ' selected';
1277 }
1278 $selectforline .= ' data-debug="'.$tmpcode.'-'.$code.'-'.$j.'-'.(!empty($tmpselectioninsession[(string) ($i + 1)]) ? $tmpselectioninsession[(string) ($i + 1)] : "").'"';
1279 }
1280 $selectforline .= ' data-html="'.dol_escape_htmltag($labelhtml).'"';
1281 $selectforline .= '>';
1282 $selectforline .= $label;
1283 $selectforline .= '</options>';
1284 $j++;
1285 }
1286 $selectforline .= '</select>';
1287 $selectforline .= ajax_combobox('selectorderimport_'.($i + 1));
1288
1289 print $selectforline;
1290
1291 print '</td>';
1292
1293 // Tooltip at end of line
1294 print '<td class="nowraponall" style="font-weight:normal; text-align:right">';
1295
1296 // Source field info
1297 $htmltext = '<b><u>'.$langs->trans("FieldSource").'</u></b><br>';
1298 $filecolumntoshow = num2Alpha($i);
1299 $htmltext .= $langs->trans("DataComeFromFileFieldNb", $filecolumntoshow).'<br>';
1300
1301 print $form->textwithpicto('', $htmltext);
1302
1303 print '</td>';
1304 print '</tr>';
1305 $i++;
1306 }
1307 print '</table>';
1308
1309 print '</td></tr>';
1310
1311 // Lines for remark
1312 print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Note").'</td></tr>';
1313 print '<tr><td colspan="2"><div id="div-mandatory-target-fields-not-mapped"></div></td></tr>';
1314
1315 print '</table>';
1316 print '</div>';
1317
1318
1319 if (!empty($conf->use_javascript_ajax)) {
1320 print '<script type="text/javascript">'."\n";
1321 print 'var previousselectedvalueimport = "0";'."\n";
1322 print 'var previousselectedlabelimport = "0";'."\n";
1323 print 'var arrayofselectedvalues = [];'."\n";
1324 print 'var arrayoftargetfields = [];'."\n";
1325 print 'var arrayoftargetmandatoryfields = [];'."\n";
1326
1327 // Loop on $fieldstarget (seems sorted by 'position') to store php array into javascript array
1328 $tmpi = 0;
1329 foreach ($fieldstarget as $key => $val) {
1330 print "arrayoftargetfields[".$tmpi."] = '".dol_escape_js($langs->trans($val['label']))."'; ";
1331 if ($val['required']) {
1332 print "arrayoftargetmandatoryfields[".$tmpi."] = '".dol_escape_js($key)."'; ";
1333 }
1334 $tmpi++;
1335 }
1336 print "\n";
1337
1338 print '$(document).ready(function () {'."\n";
1339
1340 print 'setOptionsToDisabled();'."\n";
1341 print 'saveSelection();'."\n";
1342
1343 print '$(".targetselectchange").focus(function(){'."\n";
1344 print ' previousselectedvalueimport = $(this).val();'."\n";
1345 print ' previousselectedlabelimport = $(this).children("option:selected").text();'."\n";
1346 print ' console.log("previousselectedvalueimport="+previousselectedvalueimport)'."\n";
1347 print '})'."\n";
1348
1349 // Function to set the disabled flag
1350 // - We set all option to "enabled"
1351 // - Then we scan all combo to get the value currently selected and save them into the array arrayofselectedvalues
1352 // - Then we set to disabled all fields that are selected
1353 print 'function setOptionsToDisabled() {'."\n";
1354 print ' console.log("Remove the disabled flag everywhere");'."\n";
1355 print ' $("select.targetselectchange").not($( this )).find(\'option\').prop("disabled", false);'."\n"; // Enable all options
1356 print ' arrayofselectedvalues = [];'."\n";
1357
1358 print ' $("select.targetselectchange").each(function(){'."\n";
1359 print ' id = $(this).attr(\'id\')'."\n";
1360 print ' value = $(this).val()'."\n";
1361 print ' console.log("a selected value has been found for component "+id+" = "+value);'."\n";
1362 print ' arrayofselectedvalues.push(value);'."\n";
1363 print ' });'."\n";
1364
1365 print ' console.log("List of all selected values arrayofselectedvalues");'."\n";
1366 print ' console.log(arrayofselectedvalues);'."\n";
1367 print ' console.log("Set the option to disabled for every entry that is currently selected somewhere else (so into arrayofselectedvalues)");'."\n";
1368
1369 print ' $.each(arrayofselectedvalues, function(key, value) {'."\n"; // Loop on each selected value
1370 print ' if (value != -1) {'."\n";
1371 print ' console.log("Process key="+key+" value="+value+" to disable.");'."\n";
1372 print ' $("select.targetselectchange").find(\'option[value="\'+value+\'"]:not(:selected)\').prop("disabled", true);'."\n"; // Set to disabled except if currently selected
1373 print ' }'."\n";
1374 print ' });'."\n";
1375 print '}'."\n";
1376
1377 // Function to save the selection in database
1378 print 'function saveSelection() {'."\n";
1379 //print ' console.log(arrayofselectedvalues);'."\n";
1380 print ' arrayselectedfields = [];'."\n";
1381 print ' arrayselectedfields.push(0);'."\n";
1382
1383 print ' $.each( arrayofselectedvalues, function( key, value ) {'."\n";
1384 print ' if (value != -1) {'."\n";
1385 print ' arrayselectedfields.push(value);'."\n";
1386 print ' } else {'."\n";
1387 print ' arrayselectedfields.push(0);'."\n";
1388 print ' }'."\n";
1389 print ' });'."\n";
1390
1391 print " $.ajax({\n";
1392 print " type: 'POST',\n";
1393 print " dataType: 'json',\n";
1394 print " url: '".dol_escape_js($_SERVER["PHP_SELF"])."?action=saveselectorder&token=".newToken()."',\n";
1395 print " data: 'selectorder='+arrayselectedfields.toString(),\n";
1396 print " success: function(){\n";
1397 print " console.log('The selected fields have been saved into '+arrayselectedfields.toString());\n";
1398 print " },\n";
1399 print ' });'."\n";
1400
1401 // Now we loop on all target fields that are mandatory to show if they are not mapped yet.
1402 print ' console.log("arrayselectedfields");';
1403 print ' console.log(arrayselectedfields);';
1404 print ' console.log("arrayoftargetmandatoryfields");';
1405 print ' console.log(arrayoftargetmandatoryfields);';
1406 print " listtoshow = '';";
1407 print " nbelement = arrayoftargetmandatoryfields.length
1408 for (let i = 0; i < nbelement; i++) {
1409 if (arrayoftargetmandatoryfields[i] && ! arrayselectedfields.includes(arrayoftargetmandatoryfields[i])) {
1410 console.log(arrayoftargetmandatoryfields[i]+' not mapped');
1411 listtoshow = listtoshow + (listtoshow ? ', ' : '') + '<b>' + arrayoftargetfields[i] + '*</b>';
1412 }
1413 }
1414 console.log(listtoshow);
1415 if (listtoshow) {
1416 listtoshow = '".dol_escape_js(img_warning($langs->trans("MandatoryTargetFieldsNotMapped")).' '.$langs->trans("MandatoryTargetFieldsNotMapped")).": ' + listtoshow;
1417 $('#div-mandatory-target-fields-not-mapped').html(listtoshow);
1418 } else {
1419 $('#div-mandatory-target-fields-not-mapped').html('<span class=\"opacitymedium\">".dol_escape_js($langs->trans("AllTargetMandatoryFieldsAreMapped"))."</span>');
1420 }
1421 ";
1422
1423 print '}'."\n";
1424
1425 // If we make a change on a selectbox
1426 print '$(".targetselectchange").change(function(){'."\n";
1427 print ' setOptionsToDisabled();'."\n";
1428
1429 print ' if(previousselectedlabelimport != "" && previousselectedvalueimport != -1) {'."\n";
1430 print ' let valuetochange = $(this).val(); '."\n";
1431 print ' $(".boxtdunused").each(function(){'."\n";
1432 print ' if ($(this).text().includes(valuetochange)){'."\n";
1433 print ' arraychild = $(this)[0].childNodes'."\n";
1434 print ' arraytexttomodify = arraychild[0].textContent.split(" ")'."\n";
1435 print ' arraytexttomodify[1] = previousselectedvalueimport '."\n";
1436 print ' textmodified = arraytexttomodify.join(" ") '."\n";
1437 print ' arraychild[0].textContent = textmodified'."\n";
1438 print ' arraychild[1].innerHTML = previousselectedlabelimport'."\n";
1439 print ' }'."\n";
1440 print ' })'."\n";
1441 print ' }'."\n";
1442 print ' $(this).blur()'."\n";
1443
1444 print ' saveSelection()'."\n";
1445 print '});'."\n";
1446
1447 print '})'."\n";
1448 print '</script>'."\n";
1449 }
1450
1451 /*
1452 * Action bar
1453 */
1454 print '<div class="tabsAction">';
1455
1456 if (count($array_match_file_to_database)) {
1457 if ($mandatoryfieldshavesource) {
1458 print '<a class="butAction saveorderselect" href="import.php?step=5'.$param.'&filetoimport='.urlencode($filetoimport).'">'.$langs->trans("NextStep").'</a>';
1459 } else {
1460 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("SomeMandatoryFieldHaveNoSource")).'">'.$langs->trans("NextStep").'</a>';
1461 }
1462 }
1463
1464 print '</div>';
1465
1466
1467 // Area for profils import
1468 if (count($array_match_file_to_database)) {
1469 print '<br>'."\n";
1470 print '<!-- Area to add new import profile -->'."\n";
1471 print '<div class="marginbottomonly"><span class="opacitymedium">'.$langs->trans("SaveImportModel").'</span></div>';
1472
1473 print '<form class="nocellnopadd" action="'.$_SERVER["PHP_SELF"].'" method="post">';
1474 print '<input type="hidden" name="token" value="'.newToken().'">';
1475 print '<input type="hidden" name="action" value="add_import_model">';
1476 print '<input type="hidden" name="step" value="'.$step.'">';
1477 print '<input type="hidden" name="format" value="'.$format.'">';
1478 print '<input type="hidden" name="datatoimport" value="'.$datatoimport.'">';
1479 print '<input type="hidden" name="filetoimport" value="'.$filetoimport.'">';
1480 print '<input type="hidden" name="hexa" value="'.$hexa.'">';
1481 print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
1482 print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
1483 print '<input type="hidden" name="page_y" value="">';
1484 print '<input type="hidden" value="'.dol_escape_htmltag($separator).'" name="separator">';
1485 print '<input type="hidden" value="'.dol_escape_htmltag($enclosure).'" name="enclosure">';
1486
1487 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
1488 print '<table summary="selectofimportprofil" class="noborder centpercent">';
1489 print '<tr class="liste_titre">';
1490 print '<td>'.$langs->trans("ImportModelName").'</td>';
1491 print '<td>'.$langs->trans("Visibility").'</td>';
1492 print '<td></td>';
1493 print '</tr>';
1494
1495 $nameofimportprofile = str_replace(' ', '-', $langs->trans("ImportProfile").' '.$titleofmodule.' '.dol_print_date(dol_now('gmt'), 'dayxcard'));
1496 if (GETPOST('import_name')) { // If we have submitted a form, we take value used for the update try
1497 $nameofimportprofile = $import_name;
1498 }
1499
1500 print '<tr class="oddeven">';
1501 print '<td><input name="import_name" class="minwidth300" value="'.$nameofimportprofile.'"></td>';
1502 print '<td>';
1503 $arrayvisibility = array('private' => $langs->trans("Private"), 'all' => $langs->trans("Everybody"));
1504 print $form->selectarray('visibility', $arrayvisibility, 'private');
1505 print '</td>';
1506 print '<td class="right">';
1507 print '<input type="submit" class="button smallpaddingimp reposition" value="'.$langs->trans("SaveImportProfile").'">';
1508 print '</td></tr>';
1509
1510 // List of existing import profils
1511 $sql = "SELECT rowid, label, fk_user, entity";
1512 $sql .= " FROM ".MAIN_DB_PREFIX."import_model";
1513 $sql .= " WHERE type = '".$db->escape($datatoimport)."'";
1514 if (!getDolGlobalString('EXPORTS_SHARE_MODELS')) { // EXPORTS_SHARE_MODELS means all templates are visible, whatever is owner.
1515 $sql .= " AND fk_user IN (0, ".((int) $user->id).")";
1516 }
1517 $sql .= " ORDER BY rowid";
1518
1519 $resql = $db->query($sql);
1520 if ($resql) {
1521 $num = $db->num_rows($resql);
1522
1523 $tmpuser = new User($db);
1524
1525 $i = 0;
1526 while ($i < $num) {
1527 $obj = $db->fetch_object($resql);
1528
1529 print '<tr class="oddeven"><td>';
1530 print $obj->label;
1531 print '</td>';
1532 print '<td class="tdoverflowmax150">';
1533 if (empty($obj->fk_user)) {
1534 print $langs->trans("Everybody");
1535 } else {
1536 $tmpuser->fetch($obj->fk_user);
1537 print $tmpuser->getNomUrl(-1);
1538 }
1539 print '</td>';
1540 print '<td class="right">';
1541 print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?step='.$step.$param.'&action=deleteprof&token='.newToken().'&id='.$obj->rowid.'&filetoimport='.urlencode($filetoimport).'">';
1542 print img_delete();
1543 print '</a>';
1544 print '</tr>';
1545 $i++;
1546 }
1547 } else {
1548 dol_print_error($db);
1549 }
1550
1551 print '</table>';
1552 print '</div>';
1553
1554 print '</form>';
1555 }
1556}
1557
1558// STEP 5: Summary of choices and launch simulation
1559if ($step == 5 && $datatoimport) {
1560 $max_execution_time_for_importexport = getDolGlobalInt('IMPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined
1561 $max_time = @ini_get("max_execution_time");
1562 if ($max_time && $max_time < $max_execution_time_for_importexport) {
1563 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.");
1564 @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
1565 }
1566
1567 $model = $format;
1568 $list = $objmodelimport->listOfAvailableImportFormat($db);
1569
1570 // Create class to use for import
1571 $dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
1572 $file = "import_".$model.".modules.php";
1573 $classname = "Import".ucfirst($model);
1574 require_once $dir.$file;
1575 $obj = new $classname($db, $datatoimport);
1576 '@phan-var-force ModeleImports $obj';
1577 if ($model == 'csv') {
1578 '@phan-var-force ImportCsv $obj';
1579 $obj->separator = $separator_used;
1580 $obj->enclosure = $enclosure;
1581 }
1582
1583 // Load source fields in input file
1584 $fieldssource = array();
1585 $result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
1586
1587 if ($result >= 0) {
1588 // Read first line
1589 $arrayrecord = $obj->import_read_record();
1590 // Put into array fieldssource starting with 1.
1591 $i = 1;
1592 foreach ($arrayrecord as $key => $val) {
1593 $fieldssource[$i]['example1'] = dol_trunc($val['val'], 24);
1594 $i++;
1595 }
1596 $obj->import_close_file();
1597 }
1598
1599 $nboflines = $obj->import_get_nb_of_lines($conf->import->dir_temp.'/'.$filetoimport);
1600
1601 $param = '&leftmenu=import&format='.urlencode($format).'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport).'&nboflines='.((int) $nboflines).'&separator='.urlencode($separator).'&enclosure='.urlencode($enclosure);
1602 $param2 = $param; // $param2 = $param without excludefirstline and endatlinenb
1603 if ($excludefirstline) {
1604 $param .= '&excludefirstline='.urlencode($excludefirstline);
1605 }
1606 if ($endatlinenb) {
1607 $param .= '&endatlinenb='.urlencode($endatlinenb);
1608 }
1609 if (!empty($updatekeys)) {
1610 $param .= '&updatekeys[]='.implode('&updatekeys[]=', $updatekeys);
1611 }
1612
1613 llxHeader('', $langs->trans("NewImport"), $help_url);
1614
1615 $head = import_prepare_head($param, 5);
1616
1617
1618 print '<form action="'.$_SERVER["PHP_SELF"].'?'.$param2.'" method="POST">';
1619 print '<input type="hidden" name="token" value="'.newToken().'">';
1620 print '<input type="hidden" name="step" value="5">'; // step 5
1621 print '<input type="hidden" name="action" value="launchsimu">'; // step 5
1622
1623 print dol_get_fiche_head($head, 'step5', '', -2);
1624
1625 print '<div class="underbanner clearboth"></div>';
1626 print '<div class="fichecenter">';
1627
1628 print '<table width="100%" class="border tableforfield">';
1629
1630 // Module
1631 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
1632 print '<td>';
1633 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
1634 // Special case for import common to module/services
1635 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
1636 $titleofmodule = $langs->trans("ProductOrService");
1637 }
1638 print $titleofmodule;
1639 print '</td></tr>';
1640
1641 // Lot de donnees a importer
1642 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
1643 print '<td>';
1644 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
1645 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
1646 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
1647 print $objimport->array_import_label[0];
1648 print '</td></tr>';
1649
1650 print '</table>';
1651 print '</div>';
1652
1653 print '<br>';
1654
1655 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
1656
1657 print '<div class="underbanner clearboth"></div>';
1658 print '<div class="fichecenter">';
1659 print '<table width="100%" class="border tableforfield">';
1660
1661 // Source file format
1662 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
1663 print '<td class="nowraponall">';
1664 $text = $objmodelimport->getDriverDescForKey($format);
1665 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
1666 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
1667 print '</td></tr>';
1668
1669 // Separator and enclosure
1670 if ($model == 'csv') {
1671 '@phan-var-force ImportCsv $obj';
1672 print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
1673 print '<td>';
1674 print $langs->trans("Separator").' : '.dol_escape_htmltag($separator);
1675 print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : '.dol_escape_htmltag($enclosure);
1676 print '</td></tr>';
1677 }
1678
1679 // File to import
1680 print '<tr><td>'.$langs->trans("FileToImport").'</td>';
1681 print '<td>';
1682 $modulepart = 'import';
1683 $relativepath = GETPOST('filetoimport');
1684 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
1685 print img_mime($file, '', 'pictofixedwidth');
1686 print $filetoimport;
1687 print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"');
1688 print '</a>';
1689 print '</td></tr>';
1690
1691 // Total lines in source file
1692 print '<tr><td>';
1693 print $langs->trans("NbOfSourceLines");
1694 print '</td><td>';
1695 print $nboflines;
1696 print '</td></tr>';
1697
1698 // Range of lines to import
1699 print '<tr><td>';
1700 print $langs->trans("ImportFromToLine");
1701 print '</td><td>';
1702 if ($action == 'launchsimu') {
1703 print '<input type="number" class="maxwidth50 right" name="excludefirstlinebis" disabled="disabled" value="'.$excludefirstline.'">';
1704 print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
1705 } else {
1706 print '<input type="number" class="maxwidth50 right" name="excludefirstline" value="'.$excludefirstline.'">';
1707 print $form->textwithpicto("", $langs->trans("SetThisValueTo2ToExcludeFirstLine"));
1708 }
1709 print ' - ';
1710 if ($action == 'launchsimu') {
1711 print '<input type="text" class="maxwidth50" name="endatlinenbbis" disabled="disabled" value="'.$endatlinenb.'">';
1712 print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
1713 } else {
1714 print '<input type="text" class="maxwidth50" name="endatlinenb" value="'.$endatlinenb.'">';
1715 print $form->textwithpicto("", $langs->trans("KeepEmptyToGoToEndOfFile"));
1716 }
1717 if ($action == 'launchsimu') {
1718 print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?step=5'.$param.'">'.$langs->trans("Modify").'</a>';
1719 }
1720 if ($excludefirstline == 2) {
1721 print $form->textwithpicto("", $langs->trans("WarningFirstImportedLine", $excludefirstline), 1, 'warning', "warningexcludefirstline");
1722 print '<script>
1723 $( document ).ready(function() {
1724 $("input[name=\'excludefirstline\']").on("change",function(){
1725 if($(this).val() <= 1){
1726 $(".warningexcludefirstline").hide();
1727 }else{
1728 $(".warningexcludefirstline").show();
1729 }
1730 })
1731 });
1732 </script>';
1733 }
1734 print '</td></tr>';
1735
1736 // Keys for data UPDATE (not INSERT of new data)
1737 print '<tr><td>';
1738 print $form->textwithpicto($langs->trans("KeysToUseForUpdates"), $langs->trans("SelectPrimaryColumnsForUpdateAttempt"));
1739 print '</td><td>';
1740 if ($action == 'launchsimu') {
1741 if (count($updatekeys)) {
1742 print $form->multiselectarray('updatekeysbis', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%', 'disabled');
1743 } else {
1744 print '<span class="opacitymedium">'.$langs->trans("NoUpdateAttempt").'</span> &nbsp; -';
1745 }
1746 foreach ($updatekeys as $val) {
1747 print '<input type="hidden" name="updatekeys[]" value="'.$val.'">';
1748 }
1749 print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?step=5'.$param.'">'.$langs->trans("Modify").'</a>';
1750 } else {
1751 if (is_array($objimport->array_import_updatekeys[0]) && count($objimport->array_import_updatekeys[0])) { //TODO dropdown UL is created inside nested SPANS
1752 print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%');
1753 //print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt"));
1754 } else {
1755 print '<span class="opacitymedium">'.$langs->trans("UpdateNotYetSupportedForThisImport").'</span>';
1756 }
1757 }
1758 /*echo '<pre>';
1759 print_r($objimport->array_import_updatekeys);
1760 echo '</pre>';*/
1761 print '</td></tr>';
1762
1763 print '</table>';
1764 print '</div>';
1765
1766 print '<br>';
1767
1768 print load_fiche_titre($langs->trans("InformationOnTargetTables"), '', 'file-import');
1769
1770 print '<div class="underbanner clearboth"></div>';
1771 print '<div class="fichecenter">';
1772
1773 print '<table width="100%" class="border tableforfield">';
1774
1775 // Tables imported
1776 print '<tr><td class="titlefieldcreate">';
1777 print $langs->trans("TablesTarget");
1778 print '</td><td>';
1779 $listtables = array();
1780 $sort_array_match_file_to_database = $array_match_file_to_database;
1781 foreach ($array_match_file_to_database as $code => $label) {
1782 //var_dump($fieldssource);
1783 if ($code > count($fieldssource)) {
1784 continue;
1785 }
1786 //print $code.'-'.$label;
1787 $alias = preg_replace('/(\..*)$/i', '', $label);
1788 $listtables[$alias] = $objimport->array_import_tables[0][$alias];
1789 }
1790 if (count($listtables)) {
1791 $newval = '';
1792 //ksort($listtables);
1793 foreach ($listtables as $val) {
1794 if ($newval) {
1795 print ', ';
1796 }
1797 $newval = $val;
1798 // Link to Dolibarr wiki pages
1799 /*$helppagename='EN:Table_'.$newval;
1800 if ($helppagename && empty($conf->global->MAIN_HELP_DISABLELINK))
1801 {
1802 // Get helpbaseurl, helppage and mode from helppagename and langs
1803 $arrayres=getHelpParamFor($helppagename,$langs);
1804 $helpbaseurl=$arrayres['helpbaseurl'];
1805 $helppage=$arrayres['helppage'];
1806 $mode=$arrayres['mode'];
1807 $newval.=' <a href="'.sprintf($helpbaseurl,$helppage).'">'.img_picto($langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'),DOL_URL_ROOT.'/theme/common/helpdoc.png','',1).'</a>';
1808 }*/
1809 print $newval;
1810 }
1811 } else {
1812 print $langs->trans("Error");
1813 }
1814 print '</td></tr>';
1815
1816 // Fields imported
1817 print '<tr><td>';
1818 print $langs->trans("FieldsTarget").'</td><td>';
1819 $listfields = array();
1820 $i = 0;
1821 //print 'fieldsource='.$fieldssource;
1822 $sort_array_match_file_to_database = $array_match_file_to_database;
1823 ksort($sort_array_match_file_to_database);
1824 //var_dump($sort_array_match_file_to_database);
1825 foreach ($sort_array_match_file_to_database as $code => $label) {
1826 $i++;
1827 //var_dump($fieldssource);
1828 if ($code > count($fieldssource)) {
1829 continue;
1830 }
1831 //print $code.'-'.$label;
1832 $alias = preg_replace('/(\..*)$/i', '', $label);
1833 $listfields[$i] = '<span class="nowrap">'.$langs->trans("Column").' '.num2Alpha((int) $code - 1).' -> '.$label.'</span>';
1834 }
1835 print count($listfields) ? (implode(', ', $listfields)) : $langs->trans("Error");
1836 print '</td></tr>';
1837
1838 print '</table>';
1839 print '</div>';
1840
1841 print dol_get_fiche_end();
1842
1843
1844 if ($action != 'launchsimu') {
1845 // Show import id
1846 print '<br><span class="opacitymedium">';
1847 print $langs->trans("NowClickToTestTheImport", $langs->transnoentitiesnoconv("RunSimulateImportFile")).'</span><br>';
1848 print '<br>';
1849
1850 // Actions
1851 print '<div class="center">';
1852 if ($user->hasRight('import', 'run')) {
1853 print '<input type="submit" class="butAction" value="'.$langs->trans("RunSimulateImportFile").'">';
1854 } else {
1855 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunSimulateImportFile").'</a>';
1856 }
1857 print '</div>';
1858 } else {
1859 // Launch import
1860 $arrayoferrors = array();
1861 $arrayofwarnings = array();
1862 $maxnboferrors = !getDolGlobalString('IMPORT_MAX_NB_OF_ERRORS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_ERRORS;
1863 $maxnbofwarnings = !getDolGlobalString('IMPORT_MAX_NB_OF_WARNINGS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_WARNINGS;
1864 $nboferrors = 0;
1865 $nbofwarnings = 0;
1866
1867 $importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
1868
1869 //var_dump($array_match_file_to_database);
1870
1871 $db->begin();
1872
1873 // Open input file
1874 $nbok = 0;
1875 $pathfile = $conf->import->dir_temp.'/'.$filetoimport;
1876 $result = $obj->import_open_file($pathfile);
1877 if ($result > 0) {
1878 global $tablewithentity_cache;
1879 $tablewithentity_cache = array();
1880 $sourcelinenb = 0;
1881 $endoffile = 0;
1882
1883 // Loop on each input file record
1884 while (($sourcelinenb < $nboflines) && !$endoffile) {
1885 $sourcelinenb++;
1886 // Read line and store it into $arrayrecord
1887 //dol_syslog("line ".$sourcelinenb.' - '.$nboflines.' - '.$excludefirstline.' - '.$endatlinenb);
1888 $arrayrecord = $obj->import_read_record();
1889 if ($arrayrecord === false) {
1890 $arrayofwarnings[$sourcelinenb][0] = array('lib' => 'File has '.$nboflines.' lines. However we reach the end of file or an empty line at record '.$sourcelinenb.'. This may occurs when some records are split onto several lines and not correctly delimited by the "Char delimiter", or if there is line with no data on all fields.', 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
1891 $endoffile++;
1892 continue;
1893 }
1894 if ($excludefirstline && ($sourcelinenb < $excludefirstline)) {
1895 continue;
1896 }
1897 if ($endatlinenb && ($sourcelinenb > $endatlinenb)) {
1898 break;
1899 }
1900
1901 $parameters = array(
1902 'step' => $step,
1903 'datatoimport' => $datatoimport,
1904 'obj' => &$obj,
1905 'arrayrecord' => $arrayrecord,
1906 'array_match_file_to_database' => $array_match_file_to_database,
1907 'objimport' => $objimport,
1908 'fieldssource' => $fieldssource,
1909 'importid' => $importid,
1910 'updatekeys' => $updatekeys,
1911 'arrayoferrors' => &$arrayoferrors,
1912 'arrayofwarnings' => &$arrayofwarnings,
1913 'nbok' => &$nbok,
1914 );
1915
1916 $reshook = $hookmanager->executeHooks('ImportInsert', $parameters);
1917 if ($reshook < 0) {
1918 $arrayoferrors[$sourcelinenb][] = [
1919 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
1920 ];
1921 }
1922
1923 if (empty($reshook)) {
1924 // Run import
1925 $result = $obj->import_insert($arrayrecord, $array_match_file_to_database, $objimport, count($fieldssource), $importid, $updatekeys);
1926
1927 if (count($obj->errors)) {
1928 $arrayoferrors[$sourcelinenb] = $obj->errors;
1929 }
1930 if (count($obj->warnings)) {
1931 $arrayofwarnings[$sourcelinenb] = $obj->warnings;
1932 }
1933 if (!count($obj->errors) && !count($obj->warnings)) {
1934 $nbok++;
1935 }
1936 }
1937
1938 $reshook = $hookmanager->executeHooks('AfterImportInsert', $parameters);
1939 if ($reshook < 0) {
1940 $arrayoferrors[$sourcelinenb][] = [
1941 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
1942 ];
1943 }
1944 }
1945 // Close file
1946 $obj->import_close_file();
1947 } else {
1948 print $langs->trans("ErrorFailedToOpenFile", $pathfile);
1949 }
1950
1951 $error = 0;
1952
1953 // Run the sql after import if defined
1954 //var_dump($objimport->array_import_run_sql_after[0]);
1955 if (!empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0])) {
1956 $i = 0;
1957 foreach ($objimport->array_import_run_sql_after[0] as $sqlafterimport) {
1958 $i++;
1959 $resqlafterimport = $db->query($sqlafterimport);
1960 if (!$resqlafterimport) {
1961 $arrayoferrors['none'][] = array('lib' => $langs->trans("Error running final request: ".$sqlafterimport));
1962 $error++;
1963 }
1964 }
1965 }
1966
1967 $db->rollback(); // We force rollback because this was just a simulation.
1968
1969 // Show OK
1970 if (!count($arrayoferrors) && !count($arrayofwarnings)) {
1971 print '<br>';
1972 print '<div class="info">';
1973 print '<div class=""><b>'.$langs->trans("ResultOfSimulationNoError").'</b></div>';
1974 print $langs->trans("NbInsertSim", empty($obj->nbinsert) ? 0 : $obj->nbinsert).'<br>';
1975 print $langs->trans("NbUpdateSim", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'<br>';
1976 print '</div>';
1977 print '<br>';
1978 } else {
1979 print '<br>';
1980 print '<div class="warning">';
1981 print $langs->trans("NbOfLinesOK", $nbok).'...<br>';
1982 print '</div>';
1983 print '<br>';
1984 }
1985
1986 // Show Errors
1987 //var_dump($arrayoferrors);
1988 if (count($arrayoferrors)) {
1989 print img_error().' <b>'.$langs->trans("ErrorsOnXLines", count($arrayoferrors)).'</b><br>';
1990 print '<table width="100%" class="border"><tr><td>';
1991 foreach ($arrayoferrors as $key => $val) {
1992 $nboferrors++;
1993 if ($nboferrors > $maxnboferrors) {
1994 print $langs->trans("TooMuchErrors", (count($arrayoferrors) - $nboferrors))."<br>";
1995 break;
1996 }
1997 print '* '.$langs->trans("Line").' '.dol_escape_htmltag($key).'<br>';
1998 foreach ($val as $i => $err) {
1999 print ' &nbsp; &nbsp; > '.dol_escape_htmltag($err['lib']).'<br>';
2000 }
2001 }
2002 print '</td></tr></table>';
2003 print '<br>';
2004 }
2005
2006 // Show Warnings
2007 //var_dump($arrayoferrors);
2008 if (count($arrayofwarnings)) {
2009 print img_warning().' <b>'.$langs->trans("WarningsOnXLines", count($arrayofwarnings)).'</b><br>';
2010 print '<table width="100%" class="border"><tr><td>';
2011 foreach ($arrayofwarnings as $key => $val) {
2012 $nbofwarnings++;
2013 if ($nbofwarnings > $maxnbofwarnings) {
2014 print $langs->trans("TooMuchWarnings", (count($arrayofwarnings) - $nbofwarnings))."<br>";
2015 break;
2016 }
2017 print ' * '.$langs->trans("Line").' '.dol_escape_htmltag((string) $key).'<br>';
2018 foreach ($val as $i => $err) {
2019 print ' &nbsp; &nbsp; > '.dol_escape_htmltag($err['lib']).'<br>';
2020 }
2021 }
2022 print '</td></tr></table>';
2023 print '<br>';
2024 }
2025
2026 // Show import id
2027 $importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
2028
2029 print '<div class="center">';
2030 print '<span class="opacitymedium">'.$langs->trans("NowClickToRunTheImport", $langs->transnoentitiesnoconv("RunImportFile")).'</span><br>';
2031 /*if (empty($nboferrors)) {
2032 print $langs->trans("DataLoadedWithId", $importid).'<br>';
2033 }*/
2034 print '</div>';
2035
2036 print '<br>';
2037
2038 // Actions
2039 print '<div class="center">';
2040 if ($user->hasRight('import', 'run')) {
2041 if (empty($nboferrors)) {
2042 print '<a class="butAction" href="'.DOL_URL_ROOT.'/imports/import.php?leftmenu=import&step=6&importid='.$importid.$param.'">'.$langs->trans("RunImportFile").'</a>';
2043 } else {
2044 //print '<input type="submit" class="butAction" value="'.dol_escape_htmltag($langs->trans("RunSimulateImportFile")).'">';
2045
2046 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("CorrectErrorBeforeRunningImport")).'">'.$langs->trans("RunImportFile").'</a>';
2047 }
2048 } else {
2049 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunSimulateImportFile").'</a>';
2050
2051 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunImportFile").'</a>';
2052 }
2053 print '</div>';
2054 }
2055
2056 print '</form>';
2057}
2058
2059
2060// STEP 6: Real import
2061if ($step == 6 && $datatoimport) {
2062 $max_execution_time_for_importexport = getDolGlobalInt('IMPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined
2063 $max_time = @ini_get("max_execution_time");
2064 if ($max_time && $max_time < $max_execution_time_for_importexport) {
2065 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.");
2066 @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
2067 }
2068
2069 $model = $format;
2070 $list = $objmodelimport->listOfAvailableImportFormat($db);
2071 $importid = GETPOST("importid", 'alphanohtml');
2072
2073
2074 // Create class to use for import
2075 $dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
2076 $file = "import_".$model.".modules.php";
2077 $classname = "Import".ucfirst($model);
2078 require_once $dir.$file;
2079 $obj = new $classname($db, $datatoimport);
2080 '@phan-var-force ModeleImports $obj';
2081 if ($model == 'csv') {
2082 '@phan-var-force ImportCsv $obj';
2083 $obj->separator = $separator_used;
2084 $obj->enclosure = $enclosure;
2085 }
2086
2087 // Load source fields in input file
2088 $fieldssource = array();
2089 $result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
2090 if ($result >= 0) {
2091 // Read first line
2092 $arrayrecord = $obj->import_read_record();
2093 // Put into array fieldssource starting with 1.
2094 $i = 1;
2095 foreach ($arrayrecord as $key => $val) {
2096 $fieldssource[$i]['example1'] = dol_trunc($val['val'], 24);
2097 $i++;
2098 }
2099 $obj->import_close_file();
2100 }
2101
2102 $nboflines = (GETPOSTISSET("nboflines") ? GETPOSTINT("nboflines") : dol_count_nb_of_line($conf->import->dir_temp.'/'.$filetoimport));
2103
2104 $param = '&format='.$format.'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport).'&nboflines='.((int) $nboflines);
2105 if ($excludefirstline) {
2106 $param .= '&excludefirstline='.urlencode($excludefirstline);
2107 }
2108 if ($endatlinenb) {
2109 $param .= '&endatlinenb='.urlencode($endatlinenb);
2110 }
2111 if ($separator) {
2112 $param .= '&separator='.urlencode($separator);
2113 }
2114 if ($enclosure) {
2115 $param .= '&enclosure='.urlencode($enclosure);
2116 }
2117
2118 llxHeader('', $langs->trans("NewImport"), $help_url);
2119
2120 $head = import_prepare_head($param, 6);
2121
2122 print dol_get_fiche_head($head, 'step6', '', -1);
2123
2124 print '<div class="underbanner clearboth"></div>';
2125 print '<div class="fichecenter">';
2126
2127 print '<table width="100%" class="border">';
2128
2129 // Module
2130 print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
2131 print '<td>';
2132 $titleofmodule = $objimport->array_import_module[0]['module']->getName();
2133 // Special case for import common to module/services
2134 if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
2135 $titleofmodule = $langs->trans("ProductOrService");
2136 }
2137 print $titleofmodule;
2138 print '</td></tr>';
2139
2140 // Lot de donnees a importer
2141 print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
2142 print '<td>';
2143 $entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
2144 $entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
2145 print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
2146 print $objimport->array_import_label[0];
2147 print '</td></tr>';
2148
2149 print '</table>';
2150 print '</div>';
2151
2152 print '<br>';
2153
2154 print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
2155
2156 print '<div class="underbanner clearboth"></div>';
2157 print '<div class="fichecenter">';
2158 print '<table width="100%" class="border tableforfield">';
2159
2160 // Source file format
2161 print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
2162 print '<td class="nowraponall">';
2163 $text = $objmodelimport->getDriverDescForKey($format);
2164 // @phan-suppress-next-line PhanPluginSuspiciousParamPosition
2165 print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
2166 print '</td></tr>';
2167
2168 // Separator and enclosure
2169 if ($model == 'csv') {
2170 '@phan-var-force ImportCsv $obj';
2171 print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
2172 print '<td>';
2173 print $langs->trans("Separator").' : ';
2174 print htmlentities($separator);
2175 print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : ';
2176 print htmlentities($enclosure);
2177 print '</td></tr>';
2178 }
2179
2180 // File to import
2181 print '<tr><td>'.$langs->trans("FileToImport").'</td>';
2182 print '<td>';
2183 $modulepart = 'import';
2184 $relativepath = GETPOST('filetoimport');
2185 print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
2186 print img_mime($file, '', 'pictofixedwidth');
2187 print $filetoimport;
2188 print '</a>';
2189 print '</td></tr>';
2190
2191 // Nb of fields
2192 print '<tr><td>';
2193 print $langs->trans("NbOfSourceLines");
2194 print '</td><td>';
2195 print $nboflines;
2196 print '</td></tr>';
2197
2198 // Do not import first lines
2199 print '<tr><td>';
2200 print $langs->trans("ImportFromLine");
2201 print '</td><td>';
2202 print '<input type="text" size="4" name="excludefirstline" disabled="disabled" value="'.$excludefirstline.'">';
2203 print '</td></tr>';
2204
2205 // Do not import end lines
2206 print '<tr><td>';
2207 print $langs->trans("EndAtLineNb");
2208 print '</td><td>';
2209 print '<input type="text" size="4" name="endatlinenb" disabled="disabled" value="'.$endatlinenb.'">';
2210 print '</td></tr>';
2211
2212 print '</table>';
2213 print '</div>';
2214
2215 print '<br>';
2216
2217 print '<b>'.$langs->trans("InformationOnTargetTables").'</b>';
2218 print '<div class="underbanner clearboth"></div>';
2219 print '<div class="fichecenter">';
2220 print '<table class="border centpercent">';
2221
2222 // Tables imported
2223 print '<tr><td width="25%">';
2224 print $langs->trans("TablesTarget");
2225 print '</td><td>';
2226 $listtables = array();
2227 foreach ($array_match_file_to_database as $code => $label) {
2228 //var_dump($fieldssource);
2229 if ($code > count($fieldssource)) {
2230 continue;
2231 }
2232 //print $code.'-'.$label;
2233 $alias = preg_replace('/(\..*)$/i', '', $label);
2234 $listtables[$alias] = $objimport->array_import_tables[0][$alias];
2235 }
2236 if (count($listtables)) {
2237 $newval = '';
2238 foreach ($listtables as $val) {
2239 if ($newval) {
2240 print ', ';
2241 }
2242 $newval = $val;
2243 // Link to Dolibarr wiki pages
2244 /*$helppagename='EN:Table_'.$newval;
2245 if ($helppagename && empty($conf->global->MAIN_HELP_DISABLELINK))
2246 {
2247 // Get helpbaseurl, helppage and mode from helppagename and langs
2248 $arrayres=getHelpParamFor($helppagename,$langs);
2249 $helpbaseurl=$arrayres['helpbaseurl'];
2250 $helppage=$arrayres['helppage'];
2251 $mode=$arrayres['mode'];
2252 $newval.=' <a href="'.sprintf($helpbaseurl,$helppage).'">'.img_picto($langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'),DOL_URL_ROOT.'/theme/common/helpdoc.png','',1).'</a>';
2253 }*/
2254 print $newval;
2255 }
2256 } else {
2257 print $langs->trans("Error");
2258 }
2259 print '</td></tr>';
2260
2261 // Fields imported
2262 print '<tr><td>';
2263 print $langs->trans("FieldsTarget").'</td><td>';
2264 $listfields = array();
2265 $i = 0;
2266 $sort_array_match_file_to_database = $array_match_file_to_database;
2267 ksort($sort_array_match_file_to_database);
2268 //var_dump($sort_array_match_file_to_database);
2269 foreach ($sort_array_match_file_to_database as $code => $label) {
2270 $i++;
2271 //var_dump($fieldssource);
2272 if ($code > count($fieldssource)) {
2273 continue;
2274 }
2275 //print $code.'-'.$label;
2276 $alias = preg_replace('/(\..*)$/i', '', $label);
2277 $listfields[$i] = $langs->trans("Field").' '.$code.'->'.$label;
2278 }
2279 print count($listfields) ? (implode(', ', $listfields)) : $langs->trans("Error");
2280 print '</td></tr>';
2281
2282 print '</table>';
2283 print '</div>';
2284
2285 // Launch import
2286 $arrayoferrors = array();
2287 $arrayofwarnings = array();
2288 $maxnboferrors = !getDolGlobalString('IMPORT_MAX_NB_OF_ERRORS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_ERRORS;
2289 $maxnbofwarnings = !getDolGlobalString('IMPORT_MAX_NB_OF_WARNINGS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_WARNINGS;
2290 $nboferrors = 0;
2291 $nbofwarnings = 0;
2292
2293 $importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
2294
2295 //var_dump($array_match_file_to_database);
2296
2297 $db->begin();
2298
2299 // Open input file
2300 $nbok = 0;
2301 $pathfile = $conf->import->dir_temp.'/'.$filetoimport;
2302 $result = $obj->import_open_file($pathfile);
2303 if ($result > 0) {
2304 global $tablewithentity_cache;
2305 $tablewithentity_cache = array();
2306 $sourcelinenb = 0;
2307 $endoffile = 0;
2308
2309 while ($sourcelinenb < $nboflines && !$endoffile) {
2310 $sourcelinenb++;
2311 $arrayrecord = $obj->import_read_record();
2312 if ($arrayrecord === false) {
2313 $arrayofwarnings[$sourcelinenb][0] = array('lib' => 'File has '.$nboflines.' lines. However we reach the end of file or an empty line at record '.$sourcelinenb.'. This may occurs when some records are split onto several lines and not correctly delimited by the "Char delimiter", or if there is line with no data on all fields.', 'type' => 'EOF_RECORD_ON_SEVERAL_LINES');
2314 $endoffile++;
2315 continue;
2316 }
2317 if ($excludefirstline && ($sourcelinenb < $excludefirstline)) {
2318 continue;
2319 }
2320 if ($endatlinenb && ($sourcelinenb > $endatlinenb)) {
2321 break;
2322 }
2323
2324 $parameters = array(
2325 'step' => $step,
2326 'datatoimport' => $datatoimport,
2327 'obj' => &$obj,
2328 'arrayrecord' => $arrayrecord,
2329 'array_match_file_to_database' => $array_match_file_to_database,
2330 'objimport' => $objimport,
2331 'fieldssource' => $fieldssource,
2332 'importid' => $importid,
2333 'updatekeys' => $updatekeys,
2334 'arrayoferrors' => &$arrayoferrors,
2335 'arrayofwarnings' => &$arrayofwarnings,
2336 'nbok' => &$nbok,
2337 );
2338
2339 $reshook = $hookmanager->executeHooks('ImportInsert', $parameters);
2340 if ($reshook < 0) {
2341 $arrayoferrors[$sourcelinenb][] = [
2342 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
2343 ];
2344 }
2345
2346 if (empty($reshook)) {
2347 // Run import
2348 $result = $obj->import_insert($arrayrecord, $array_match_file_to_database, $objimport, count($fieldssource), $importid, $updatekeys);
2349
2350 if (count($obj->errors)) {
2351 $arrayoferrors[$sourcelinenb] = $obj->errors;
2352 }
2353 if (count($obj->warnings)) {
2354 $arrayofwarnings[$sourcelinenb] = $obj->warnings;
2355 }
2356
2357 if (!count($obj->errors) && !count($obj->warnings)) {
2358 $nbok++;
2359 }
2360 }
2361
2362 $reshook = $hookmanager->executeHooks('AfterImportInsert', $parameters);
2363 if ($reshook < 0) {
2364 $arrayoferrors[$sourcelinenb][] = [
2365 'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
2366 ];
2367 }
2368 }
2369 // Close file
2370 $obj->import_close_file();
2371 } else {
2372 print $langs->trans("ErrorFailedToOpenFile", $pathfile);
2373 }
2374
2375 if (count($arrayoferrors) > 0) {
2376 $db->rollback(); // We force rollback because this was errors.
2377 } else {
2378 $error = 0;
2379
2380 // Run the sql after import if defined
2381 //var_dump($objimport->array_import_run_sql_after[0]);
2382 if (!empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0])) {
2383 $i = 0;
2384 foreach ($objimport->array_import_run_sql_after[0] as $sqlafterimport) {
2385 $i++;
2386 $resqlafterimport = $db->query($sqlafterimport);
2387 if (!$resqlafterimport) {
2388 $arrayoferrors['none'][] = array('lib' => $langs->trans("Error running final request: ".$sqlafterimport));
2389 $error++;
2390 }
2391 }
2392 }
2393
2394 if (!$error) {
2395 $db->commit(); // We can commit if no errors.
2396 } else {
2397 $db->rollback();
2398 }
2399 }
2400
2401 print dol_get_fiche_end();
2402
2403
2404 // Show result
2405 print '<br>';
2406 print '<div class="info">';
2407 print $langs->trans("NbOfLinesImported", $nbok).'</b><br>';
2408 print $langs->trans("NbInsert", empty($obj->nbinsert) ? 0 : $obj->nbinsert).'<br>';
2409 print $langs->trans("NbUpdate", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'<br>';
2410 print '</div>';
2411 print '<div class="center">';
2412 print $langs->trans("FileWasImported", $importid).'<br>';
2413 print '<span class="opacitymedium">'.$langs->trans("YouCanUseImportIdToFindRecord", $importid).'</span><br>';
2414 print '</div>';
2415}
2416
2417
2418
2419print '<br>';
2420
2421// End of page
2422llxFooter();
2423$db->close();
2424
2425
2434function show_elem($fieldssource, $pos, $key)
2435{
2436 global $conf, $langs;
2437
2438 $height = '32px';
2439
2440 if ($key == 'none') {
2441 //stop multiple duplicate ids with no number
2442 print "\n\n<!-- Box_no-key start-->\n";
2443 print '<div class="box boximport" style="padding:0;">'."\n";
2444 print '<table summary="boxtable_no-key" class="centpercent nobordernopadding">'."\n";
2445 } else {
2446 print "\n\n<!-- Box ".$pos." start -->\n";
2447 print '<div class="box boximport" style="padding: 0;" id="boxto_'.$pos.'">'."\n";
2448
2449 print '<table summary="boxtable'.$pos.'" class="nobordernopadding centpercent tableimport">'."\n";
2450 }
2451
2452 if (($pos && $pos > count($fieldssource)) && (!isset($fieldssource[$pos]["imported"]))) { // No fields
2453 /*
2454 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
2455 print '<td class="nocellnopadd" width="16" style="font-weight: normal">';
2456 print '</td>';
2457 print '<td style="font-weight: normal">';
2458 print $langs->trans("NoFields");
2459 print '</td>';
2460 print '</tr>';
2461 */
2462 } elseif ($key == 'none') { // Empty line
2463 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
2464 print '<td class="nocellnopadd" width="16" style="font-weight: normal">';
2465 print '&nbsp;';
2466 print '</td>';
2467 print '<td style="font-weight: normal">';
2468 print '&nbsp;';
2469 print '</td>';
2470 print '</tr>';
2471 } else {
2472 // Print field of source file
2473 print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
2474 print '<td class="nocellnopadd" width="16" style="font-weight: normal">';
2475 // 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
2476 //print img_picto($langs->trans("MoveField", $pos), 'grip_title', 'class="boxhandle" style="cursor:move;"');
2477 print img_picto($langs->trans("Column").' '.num2Alpha($pos - 1), 'file', 'class="pictofixedwidth"');
2478 print '</td>';
2479 if (isset($fieldssource[$pos]['imported']) && $fieldssource[$pos]['imported'] == false) {
2480 print '<td class="nowraponall boxtdunused" style="font-weight: normal">';
2481 } else {
2482 print '<td class="nowraponall tdoverflowmax500" style="font-weight: normal">';
2483 }
2484 print $langs->trans("Column").' '.num2Alpha($pos - 1).' (#'.$pos.')';
2485 if (empty($fieldssource[$pos]['example1'])) {
2486 $example = $fieldssource[$pos]['label'];
2487 } else {
2488 $example = $fieldssource[$pos]['example1'];
2489 }
2490 if ($example) {
2491 if (!utf8_check($example)) {
2492 $example = mb_convert_encoding($example, 'UTF-8', 'ISO-8859-1');
2493 }
2494 // if (!empty($conf->dol_optimize_smallscreen)) { //print '<br>'; }
2495 print ' - ';
2496 print '<i class="opacitymedium">'.dol_escape_htmltag($example).'</i>';
2497 }
2498 print '</td>';
2499 print '</tr>';
2500 }
2501
2502 print "</table>\n";
2503
2504 print "</div>\n";
2505 print "<!-- Box end -->\n\n";
2506}
2507
2508
2516function getnewkey(&$fieldssource, &$listofkey)
2517{
2518 $i = count($fieldssource) + 1;
2519 // Max number of key
2520 $maxkey = 0;
2521 foreach ($listofkey as $key => $val) {
2522 $maxkey = max($maxkey, $key);
2523 }
2524 // Found next empty key
2525 while ($i <= $maxkey) {
2526 if (empty($listofkey[$i])) {
2527 break;
2528 } else {
2529 $i++;
2530 }
2531 }
2532
2533 $listofkey[$i] = 1;
2534 return $i;
2535}
2544function arrayInsert($array, $position, $insertArray)
2545{
2546 $ret = [];
2547
2548 if ($position == count($array)) {
2549 $ret = $array + $insertArray;
2550 } else {
2551 $i = 0;
2552 foreach ($array as $key => $value) {
2553 if ($position == $i++) {
2554 $ret += $insertArray;
2555 }
2556
2557 $ret[$key] = $value;
2558 }
2559 }
2560
2561 return $ret;
2562}
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:459
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:87
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:71
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_move_uploaded_file($src_file, $dest_file, $allowoverwrite, $disablevirusscan=0, $uploaderrorcode=0, $nohook=0, $varfiles='addedfile', $upload_dir='')
Check validity of a file upload from an GUI page, and move it to its final destination.
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
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)
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_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.
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:2434
getnewkey(&$fieldssource, &$listofkey)
Return not used field number.
Definition import.php:2516
arrayInsert($array, $position, $insertArray)
Return array with element inserted in it at position $position.
Definition import.php:2544
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.