2526 lines
93 KiB
PHP
Raw Permalink Normal View History

2024-09-06 20:28:06 +08:00
<?php
/* Copyright (C) 2005-2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@inodbox.com>
* Copyright (C) 2012 Christophe Battarel <christophe.battarel@altairis.fr>
* Copyright (C) 2022 Charlene Benke <charlene@patas-monkey.com>
* Copyright (C) 2024 MDW <mdeweerd@users.noreply.github.com>
* Copyright (C) 2024 Frédéric France <frederic.france@free.fr>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
/**
* \file htdocs/imports/import.php
* \ingroup import
* \brief Pages of import Wizard
*/
require_once '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formother.class.php';
require_once DOL_DOCUMENT_ROOT.'/imports/class/import.class.php';
require_once DOL_DOCUMENT_ROOT.'/core/modules/import/modules_import.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/import.lib.php';
// Load translation files required by the page
$langs->loadLangs(array('exports', 'compta', 'errors', 'projects', 'admin'));
// Initialize a technical object to manage hooks of page. Note that conf->hooks_modules contains an array of hook context
$hookmanager->initHooks(array('imports'));
// Security check
$result = restrictedArea($user, 'import');
// Map icons, array duplicated in export.php, was not synchronized, TODO put it somewhere only once
$entitytoicon = array(
'invoice' => 'bill',
'invoice_line' => 'bill',
'order' => 'order',
'order_line' => 'order',
'propal' => 'propal',
'propal_line' => 'propal',
'intervention' => 'intervention',
'inter_line' => 'intervention',
'member' => 'user',
'member_type' => 'group',
'subscription' => 'payment',
'payment' => 'payment',
'tax' => 'bill',
'tax_type' => 'generic',
'other' => 'generic',
'account' => 'account',
'product' => 'product',
'virtualproduct' => 'product',
'subproduct' => 'product',
'product_supplier_ref' => 'product',
'stock' => 'stock',
'warehouse' => 'stock',
'batch' => 'stock',
'stockbatch' => 'stock',
'category' => 'category',
'shipment' => 'sending',
'shipment_line' => 'sending',
'reception' => 'sending',
'reception_line' => 'sending',
'expensereport' => 'trip',
'expensereport_line' => 'trip',
'holiday' => 'holiday',
'contract_line' => 'contract',
'translation' => 'generic',
'bomm' => 'bom',
'bomline' => 'bom'
);
// Translation code, array duplicated in export.php, was not synchronized, TODO put it somewhere only once
$entitytolang = array(
'user' => 'User',
'company' => 'Company',
'contact' => 'Contact',
'invoice' => 'Bill',
'invoice_line' => 'InvoiceLine',
'order' => 'Order',
'order_line' => 'OrderLine',
'propal' => 'Proposal',
'propal_line' => 'ProposalLine',
'intervention' => 'Intervention',
'inter_line' => 'InterLine',
'member' => 'Member',
'member_type' => 'MemberType',
'subscription' => 'Subscription',
'tax' => 'SocialContribution',
'tax_type' => 'DictionarySocialContributions',
'account' => 'BankTransactions',
'payment' => 'Payment',
'product' => 'Product',
'virtualproduct' => 'AssociatedProducts',
'subproduct' => 'SubProduct',
'product_supplier_ref' => 'SupplierPrices',
'service' => 'Service',
'stock' => 'Stock',
'movement' => 'StockMovement',
'batch' => 'Batch',
'stockbatch' => 'StockDetailPerBatch',
'warehouse' => 'Warehouse',
'category' => 'Category',
'other' => 'Other',
'trip' => 'TripsAndExpenses',
'shipment' => 'Shipments',
'shipment_line' => 'ShipmentLine',
'project' => 'Projects',
'projecttask' => 'Tasks',
'task_time' => 'TaskTimeSpent',
'action' => 'Event',
'expensereport' => 'ExpenseReport',
'expensereport_line' => 'ExpenseReportLine',
'holiday' => 'TitreRequestCP',
'contract' => 'Contract',
'contract_line' => 'ContractLine',
'translation' => 'Translation',
'bom' => 'BOM',
'bomline' => 'BOMLine'
);
$datatoimport = GETPOST('datatoimport');
$format = GETPOST('format');
$filetoimport = GETPOST('filetoimport');
$action = GETPOST('action', 'alpha');
$confirm = GETPOST('confirm', 'alpha');
$step = (GETPOST('step') ? GETPOST('step') : 1);
$import_name = GETPOST('import_name');
$hexa = GETPOST('hexa');
$importmodelid = GETPOSTINT('importmodelid');
$excludefirstline = (GETPOST('excludefirstline') ? GETPOST('excludefirstline') : 2);
$endatlinenb = (GETPOST('endatlinenb') ? GETPOST('endatlinenb') : '');
$updatekeys = (GETPOST('updatekeys', 'array') ? GETPOST('updatekeys', 'array') : array());
$separator = (GETPOST('separator', 'nohtml') ? GETPOST('separator', 'nohtml', 3) : '');
$enclosure = (GETPOST('enclosure', 'nohtml') ? GETPOST('enclosure', 'nohtml') : '"'); // We must use 'nohtml' and not 'alphanohtml' because we must accept "
$charset = GETPOST('charset', 'aZ09');
$separator_used = str_replace('\t', "\t", $separator);
$objimport = new Import($db);
$objimport->load_arrays($user, ($step == 1 ? '' : $datatoimport));
if (empty($updatekeys) && !empty($objimport->array_import_preselected_updatekeys[0])) {
$updatekeys = $objimport->array_import_preselected_updatekeys[0];
}
$objmodelimport = new ModeleImports();
$form = new Form($db);
$htmlother = new FormOther($db);
$formfile = new FormFile($db);
// Init $array_match_file_to_database from _SESSION
if (empty($array_match_file_to_database)) {
$serialized_array_match_file_to_database = isset($_SESSION["dol_array_match_file_to_database_select"]) ? $_SESSION["dol_array_match_file_to_database_select"] : '';
$array_match_file_to_database = array();
$fieldsarray = explode(',', $serialized_array_match_file_to_database);
foreach ($fieldsarray as $elem) {
$tabelem = explode('=', $elem, 2);
$key = $tabelem[0];
$val = (isset($tabelem[1]) ? $tabelem[1] : '');
if ($key && $val) {
$array_match_file_to_database[$key] = $val;
}
}
}
/*
* Actions
*/
if ($action == 'deleteprof' && $user->hasRight('import', 'run')) {
if (GETPOSTINT("id")) {
$objimport->fetch(GETPOSTINT("id"));
$result = $objimport->delete($user);
}
}
// Save import config to database
if ($action == 'add_import_model' && $user->hasRight('import', 'run')) {
if ($import_name) {
// Set save string
$hexa = '';
foreach ($array_match_file_to_database as $key => $val) {
if ($hexa) {
$hexa .= ',';
}
$hexa .= $key.'='.$val;
}
$objimport->model_name = $import_name;
$objimport->datatoimport = $datatoimport;
$objimport->hexa = $hexa;
$objimport->fk_user = (GETPOST('visibility', 'aZ09') == 'all' ? 0 : $user->id);
$result = $objimport->create($user);
if ($result >= 0) {
setEventMessages($langs->trans("ImportModelSaved", $objimport->model_name), null, 'mesgs');
$import_name = '';
} else {
$langs->load("errors");
if ($objimport->errno == 'DB_ERROR_RECORD_ALREADY_EXISTS') {
setEventMessages($langs->trans("ErrorImportDuplicateProfil"), null, 'errors');
} else {
setEventMessages($objimport->error, null, 'errors');
}
}
} else {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("ImportModelName")), null, 'errors');
}
}
if ($step == 3 && $datatoimport) {
if (GETPOST('sendit') && getDolGlobalString('MAIN_UPLOAD_DOC')) {
dol_mkdir($conf->import->dir_temp);
$nowyearmonth = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
$fullpath = $conf->import->dir_temp."/".$nowyearmonth.'-'.$_FILES['userfile']['name'];
if (dol_move_uploaded_file($_FILES['userfile']['tmp_name'], $fullpath, 1) > 0) {
dol_syslog("File ".$fullpath." was added for import");
} else {
$langs->load("errors");
setEventMessages($langs->trans("ErrorFailedToSaveFile"), null, 'errors');
}
}
// Delete file
if ($action == 'confirm_deletefile' && $confirm == 'yes') {
$langs->load("other");
$param = '&datatoimport='.urlencode($datatoimport).'&format='.urlencode($format);
if ($excludefirstline) {
$param .= '&excludefirstline='.urlencode($excludefirstline);
}
if ($endatlinenb) {
$param .= '&endatlinenb='.urlencode($endatlinenb);
}
$file = $conf->import->dir_temp.'/'.GETPOST('urlfile');
$ret = dol_delete_file($file);
if ($ret) {
setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs');
} else {
setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors');
}
header('Location: '.$_SERVER["PHP_SELF"].'?step='.$step.$param);
exit;
}
}
if ($step == 4 && $action == 'select_model' && $user->hasRight('import', 'run')) {
// Reinit match arrays
$_SESSION["dol_array_match_file_to_database"] = '';
$serialized_array_match_file_to_database = '';
$array_match_file_to_database = array();
// Load model from $importmodelid and set $array_match_file_to_database
// and $_SESSION["dol_array_match_file_to_database"]
$result = $objimport->fetch($importmodelid);
if ($result > 0) {
$serialized_array_match_file_to_database = $objimport->hexa;
$fieldsarray = explode(',', $serialized_array_match_file_to_database);
foreach ($fieldsarray as $elem) {
$tabelem = explode('=', $elem);
$key = $tabelem[0];
$val = $tabelem[1];
if ($key && $val) {
$array_match_file_to_database[$key] = $val;
}
}
$_SESSION["dol_array_match_file_to_database"] = $serialized_array_match_file_to_database;
$_SESSION['dol_array_match_file_to_database_select'] = $_SESSION["dol_array_match_file_to_database"];
}
}
if ($action == 'saveselectorder' && $user->hasRight('import', 'run')) {
// Enregistrement de la position des champs
$serialized_array_match_file_to_database = '';
dol_syslog("selectorder=".GETPOST('selectorder'), LOG_DEBUG);
$selectorder = explode(",", GETPOST('selectorder'));
$fieldtarget = $fieldstarget = $objimport->array_import_fields[0];
foreach ($selectorder as $key => $code) {
$serialized_array_match_file_to_database .= $key.'='.$code;
$serialized_array_match_file_to_database .= ',';
}
$serialized_array_match_file_to_database = substr($serialized_array_match_file_to_database, 0, -1);
dol_syslog('dol_array_match_file_to_database_select='.$serialized_array_match_file_to_database);
$_SESSION["dol_array_match_file_to_database_select"] = $serialized_array_match_file_to_database;
echo "{}";
exit(0);
}
/*
* View
*/
$help_url = 'EN:Module_Imports_En|FR:Module_Imports|ES:M&oacute;dulo_Importaciones';
// STEP 1: Page to select dataset to import
if ($step == 1 || !$datatoimport) {
// Clean saved file-database matching
$serialized_array_match_file_to_database = '';
$array_match_file_to_database = array();
$_SESSION["dol_array_match_file_to_database"] = '';
$_SESSION["dol_array_match_file_to_database_select"] = '';
$param = '';
if ($excludefirstline) {
$param .= '&excludefirstline='.urlencode($excludefirstline);
}
if ($endatlinenb) {
$param .= '&endatlinenb='.urlencode($endatlinenb);
}
if ($separator) {
$param .= '&separator='.urlencode($separator);
}
if ($enclosure) {
$param .= '&enclosure='.urlencode($enclosure);
}
llxHeader('', $langs->trans("NewImport"), $help_url);
$head = import_prepare_head($param, 1);
print dol_get_fiche_head($head, 'step1', '', -1);
print '<div class="opacitymedium">'.$langs->trans("SelectImportDataSet").'</div><br>';
// Affiche les modules d'imports
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
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("Module").'</td>';
print '<td>'.$langs->trans("ImportableDatas").'</td>';
print '<td>&nbsp;</td>';
print '</tr>';
if (count($objimport->array_import_module)) {
$sortedarrayofmodules = dol_sort_array($objimport->array_import_module, 'position_of_profile', 'asc', 0, 0, 1);
foreach ($sortedarrayofmodules as $key => $value) {
//var_dump($key.' '.$value['position_of_profile'].' '.$value['import_code'].' '.$objimport->array_import_module[$key]['module']->getName().' '.$objimport->array_import_code[$key]);
print '<tr class="oddeven"><td>';
$titleofmodule = $objimport->array_import_module[$key]['module']->getName();
// Special cas for import common to module/services
if (in_array($objimport->array_import_code[$key], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
$titleofmodule = $langs->trans("ProductOrService");
}
print $titleofmodule;
print '</td><td>';
$entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[$key]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
print img_object($objimport->array_import_module[$key]['module']->getName(), $entityicon).' ';
print $objimport->array_import_label[$key];
print '</td><td style="text-align: right">';
if ($objimport->array_import_perms[$key]) {
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>';
} else {
print $langs->trans("NotEnoughPermissions");
}
print '</td></tr>';
}
} else {
print '<tr><td class="oddeven" colspan="3">'.$langs->trans("NoImportableData").'</td></tr>';
}
print '</table>';
print '</div>';
print dol_get_fiche_end();
}
// STEP 2: Page to select input format file
if ($step == 2 && $datatoimport) {
$param = '&datatoimport='.urlencode($datatoimport);
if ($excludefirstline) {
$param .= '&excludefirstline='.urlencode($excludefirstline);
}
if ($endatlinenb) {
$param .= '&endatlinenb='.urlencode($endatlinenb);
}
if ($separator) {
$param .= '&separator='.urlencode($separator);
}
if ($enclosure) {
$param .= '&enclosure='.urlencode($enclosure);
}
llxHeader('', $langs->trans("NewImport"), $help_url);
$head = import_prepare_head($param, 2);
print dol_get_fiche_head($head, 'step2', '', -2);
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table class="border tableforfield centpercent">';
// Module
print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
print '<td>';
$titleofmodule = $objimport->array_import_module[0]['module']->getName();
// Special cas for import common to module/services
if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
$titleofmodule = $langs->trans("ProductOrService");
}
print $titleofmodule;
print '</td></tr>';
// Dataset to import
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
print '<td>';
$entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
print $objimport->array_import_label[0];
print '</td></tr>';
print '</table>';
print '</div>';
print dol_get_fiche_end();
print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" METHOD="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<br>';
print '<span class="opacitymedium">';
$s = $langs->trans("ChooseFormatOfFileToImport", '{s1}');
$s = str_replace('{s1}', img_picto('', 'next'), $s);
print $s;
print '</span><br><br>';
print '<br>';
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
print '<table class="noborder centpercent" cellpadding="4">';
$filetoimport = '';
// Add format information and link to download example
print '<tr class="liste_titre"><td colspan="5">';
print $langs->trans("FileMustHaveOneOfFollowingFormat");
print '</td></tr>';
$list = $objmodelimport->listOfAvailableImportFormat($db);
foreach ($list as $key) {
print '<tr class="oddeven">';
print '<td width="16">'.img_picto_common($key, $objmodelimport->getPictoForKey($key)).'</td>';
$htmltext = $objmodelimport->getDriverDescForKey($key);
print '<td>'.$form->textwithpicto($objmodelimport->getDriverLabelForKey($key), $htmltext).'</td>';
print '<td style="text-align:center">';
if (empty($objmodelimport->drivererror[$key])) {
$filename = $langs->transnoentitiesnoconv("ExampleOfImportFile").'_'.$datatoimport.'.'.$key;
print '<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.$param.'&output=file&file='.urlencode($filename).'" target="_blank" rel="noopener noreferrer">';
print img_picto('', 'download', 'class="paddingright opacitymedium"');
print $langs->trans("DownloadEmptyExampleShort");
print '</a>';
print $form->textwithpicto('', $langs->trans("DownloadEmptyExample").'.<br>'.$langs->trans("StarAreMandatory"));
} else {
print dolPrintHTML($objmodelimport->drivererror[$key]);
}
print '</td>';
// Action button
print '<td style="text-align:right">';
if (empty($objmodelimport->drivererror[$key])) {
print '<a href="'.DOL_URL_ROOT.'/imports/import.php?step=3&format='.$key.$param.'">'.img_picto($langs->trans("SelectFormat"), 'next', 'class="fa-15"').'</a>';
}
print '</td>';
print '</tr>';
}
print '</table>';
print '</div>';
print '</form>';
}
// STEP 3: Page to select file
if ($step == 3 && $datatoimport) {
$param = '&datatoimport='.urlencode($datatoimport).'&format='.urlencode($format);
if ($excludefirstline) {
$param .= '&excludefirstline='.urlencode($excludefirstline);
}
if ($endatlinenb) {
$param .= '&endatlinenb='.urlencode($endatlinenb);
}
if ($separator) {
$param .= '&separator='.urlencode($separator);
}
if ($enclosure) {
$param .= '&enclosure='.urlencode($enclosure);
}
$list = $objmodelimport->listOfAvailableImportFormat($db);
llxHeader('', $langs->trans("NewImport"), $help_url);
$head = import_prepare_head($param, 3);
print dol_get_fiche_head($head, 'step3', '', -2);
/*
* Confirm delete file
*/
if ($action == 'delete') {
print $form->formconfirm($_SERVER["PHP_SELF"].'?urlfile='.urlencode(GETPOST('urlfile')).'&step=3'.$param, $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile', '', 0, 1);
}
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table class="border tableforfield centpercent">';
// Module
print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
print '<td>';
$titleofmodule = $objimport->array_import_module[0]['module']->getName();
// Special cas for import common to module/services
if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
$titleofmodule = $langs->trans("ProductOrService");
}
print $titleofmodule;
print '</td></tr>';
// Lot de donnees a importer
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
print '<td>';
$entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
print $objimport->array_import_label[0];
print '</td></tr>';
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border tableforfield">';
// Source file format
print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
print '<td class="nowraponall">';
$text = $objmodelimport->getDriverDescForKey($format);
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
print '</td><td style="text-align:right" class="nowrap">';
$filename = $langs->transnoentitiesnoconv("ExampleOfImportFile").'_'.$datatoimport.'.'.$format;
print '<a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$format.$param.'&output=file&file='.urlencode($filename).'" target="_blank" rel="noopener noreferrer">';
print img_picto('', 'download', 'class="paddingright opacitymedium"');
print $langs->trans("DownloadEmptyExampleShort");
print '</a>';
print $form->textwithpicto('', $langs->trans("DownloadEmptyExample").'.<br>'.$langs->trans("StarAreMandatory"));
print '</td></tr>';
print '</table>';
print '</div>';
print dol_get_fiche_end();
if ($format == 'xlsx' && !class_exists('XMLWriter')) {
$langs->load("install");
print info_admin($langs->trans("ErrorPHPDoesNotSupport", 'php-xml'), 0, 0, 1, 'error');
}
print '<br><br>';
print '<form name="userfile" action="'.$_SERVER["PHP_SELF"].'" enctype="multipart/form-data" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" value="'.$step.'" name="step">';
print '<input type="hidden" value="'.dol_escape_htmltag($format).'" name="format">';
print '<input type="hidden" value="'.$excludefirstline.'" name="excludefirstline">';
print '<input type="hidden" value="'.$endatlinenb.'" name="endatlinenb">';
print '<input type="hidden" value="'.dol_escape_htmltag($separator).'" name="separator">';
print '<input type="hidden" value="'.dol_escape_htmltag($enclosure).'" name="enclosure">';
print '<input type="hidden" value="'.dol_escape_htmltag($datatoimport).'" name="datatoimport">';
print '<span class="opacitymedium">';
$s = $langs->trans("ChooseFileToImport", '{s1}');
$s = str_replace('{s1}', img_picto('', 'next'), $s);
print $s;
print '</span><br><br>';
$filetoimport = '';
// Input file name box
print '<div class="marginbottomonly">';
$maxfilesizearray = getMaxFileSizeArray();
$maxmin = $maxfilesizearray['maxmin'];
if ($maxmin > 0) {
print '<input type="hidden" name="MAX_FILE_SIZE" value="'.($maxmin * 1024).'">'; // MAX_FILE_SIZE must precede the field type=file
}
print '<input type="file" name="userfile" size="20" maxlength="80"> &nbsp; &nbsp; ';
$out = (!getDolGlobalString('MAIN_UPLOAD_DOC') ? ' disabled' : '');
print '<input type="submit" class="button small" value="'.$langs->trans("AddFile").'"'.$out.' name="sendit">';
$out = '';
if (getDolGlobalString('MAIN_UPLOAD_DOC')) {
$max = getDolGlobalString('MAIN_UPLOAD_DOC'); // In Kb
$maxphp = @ini_get('upload_max_filesize'); // In unknown
if (preg_match('/k$/i', $maxphp)) {
$maxphp = (int) substr($maxphp, 0, -1);
}
if (preg_match('/m$/i', $maxphp)) {
$maxphp = (int) substr($maxphp, 0, -1) * 1024;
}
if (preg_match('/g$/i', $maxphp)) {
$maxphp = (int) substr($maxphp, 0, -1) * 1024 * 1024;
}
if (preg_match('/t$/i', $maxphp)) {
$maxphp = (int) substr($maxphp, 0, -1) * 1024 * 1024 * 1024;
}
$maxphp2 = @ini_get('post_max_size'); // In unknown
if (preg_match('/k$/i', $maxphp2)) {
$maxphp2 = (int) substr($maxphp2, 0, -1);
}
if (preg_match('/m$/i', $maxphp2)) {
$maxphp2 = (int) substr($maxphp2, 0, -1) * 1024;
}
if (preg_match('/g$/i', $maxphp2)) {
$maxphp2 = (int) substr($maxphp2, 0, -1) * 1024 * 1024;
}
if (preg_match('/t$/i', $maxphp2)) {
$maxphp2 = (int) substr($maxphp2, 0, -1) * 1024 * 1024 * 1024;
}
// Now $max and $maxphp and $maxphp2 are in Kb
$maxmin = $max;
$maxphptoshow = $maxphptoshowparam = '';
if ($maxphp > 0) {
$maxmin = min($max, $maxphp);
$maxphptoshow = $maxphp;
$maxphptoshowparam = 'upload_max_filesize';
}
if ($maxphp2 > 0) {
$maxmin = min($max, $maxphp2);
if ($maxphp2 < $maxphp) {
$maxphptoshow = $maxphp2;
$maxphptoshowparam = 'post_max_size';
}
}
$langs->load('other');
$out .= ' ';
$out .= info_admin($langs->trans("ThisLimitIsDefinedInSetup", $max, $maxphptoshow), 1);
} else {
$out .= ' ('.$langs->trans("UploadDisabled").')';
}
print $out;
print '</div>';
// Search available imports
$filearray = dol_dir_list($conf->import->dir_temp, 'files', 0, '', '', 'name', SORT_DESC);
if (count($filearray) > 0) {
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
print '<table class="noborder centpercent" width="100%" cellpadding="4">';
$dir = $conf->import->dir_temp;
// Search available files to import
$i = 0;
foreach ($filearray as $key => $val) {
$file = $val['name'];
// readdir return value in ISO and we want UTF8 in memory
if (!utf8_check($file)) {
$file = mb_convert_encoding($file, 'UTF-8', 'ISO-8859-1');
}
if (preg_match('/^\./', $file)) {
continue;
}
$modulepart = 'import';
$urlsource = $_SERVER["PHP_SELF"].'?step='.$step.$param.'&filetoimport='.urlencode($filetoimport);
$relativepath = $file;
print '<tr class="oddeven">';
print '<td>';
print img_mime($file, '', 'pictofixedwidth');
print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=3'.$param.'" target="_blank" rel="noopener noreferrer">';
print $file;
print '</a>';
print '</td>';
// Affiche taille fichier
print '<td style="text-align:right">'.dol_print_size(dol_filesize($dir.'/'.$file)).'</td>';
// Affiche date fichier
print '<td style="text-align:right">'.dol_print_date(dol_filemtime($dir.'/'.$file), 'dayhour').'</td>';
// Del button
print '<td style="text-align:right"><a href="'.$_SERVER['PHP_SELF'].'?action=delete&token='.newToken().'&step=3'.$param.'&urlfile='.urlencode($relativepath);
print '">'.img_delete().'</a></td>';
// Action button
print '<td style="text-align:right">';
print '<a href="'.$_SERVER['PHP_SELF'].'?step=4'.$param.'&filetoimport='.urlencode($relativepath).'">'.img_picto($langs->trans("NewImport"), 'next', 'class="fa-15"').'</a>';
print '</td>';
print '</tr>';
}
print '</table>';
print '</div>';
}
print '</form>';
}
// STEP 4: Page to make matching between source file and database fields
if ($step == 4 && $datatoimport) {
//var_dump($_SESSION["dol_array_match_file_to_database_select"]);
$serialized_array_match_file_to_database = isset($_SESSION["dol_array_match_file_to_database_select"]) ? $_SESSION["dol_array_match_file_to_database_select"] : '';
$fieldsarray = explode(',', $serialized_array_match_file_to_database);
$array_match_file_to_database = array(); // Same than $fieldsarray but with mapped value only (col1 => 's.fielda', col2 => 's.fieldb'...)
foreach ($fieldsarray as $elem) {
$tabelem = explode('=', $elem, 2);
$key = $tabelem[0];
$val = (isset($tabelem[1]) ? $tabelem[1] : '');
if ($key && $val) {
$array_match_file_to_database[$key] = $val;
}
}
//var_dump($serialized_array_match_file_to_database);
//var_dump($fieldsarray);
//var_dump($array_match_file_to_database);
$model = $format;
$list = $objmodelimport->listOfAvailableImportFormat($db);
if (empty($separator)) {
$separator = (!getDolGlobalString('IMPORT_CSV_SEPARATOR_TO_USE') ? ',' : $conf->global->IMPORT_CSV_SEPARATOR_TO_USE);
}
// The separator has been defined, if it is a unique char, we check it is valid by reading the source file
if ($model == 'csv' && strlen($separator) == 1 && !GETPOSTISSET('separator')) {
'@phan-var-force ImportCsv $obj';
// Count the char in first line of file.
$fh = fopen($conf->import->dir_temp.'/'.$filetoimport, 'r');
if ($fh) {
$sline = fgets($fh, 1000000);
fclose($fh);
$nboccurence = substr_count($sline, $separator);
$nboccurencea = substr_count($sline, ',');
$nboccurenceb = substr_count($sline, ';');
//var_dump($nboccurence." ".$nboccurencea." ".$nboccurenceb);exit;
if ($nboccurence == 0) {
if ($nboccurencea > 2) {
$separator = ',';
} elseif ($nboccurenceb > 2) {
$separator = ';';
}
}
}
}
// The value to use
$separator_used = str_replace('\t', "\t", $separator);
// Create class to use for import
$dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
$file = "import_".$model.".modules.php";
$classname = "Import".ucfirst($model);
require_once $dir.$file;
$obj = new $classname($db, $datatoimport);
'@phan-var-force ModeleImports $obj';
if ($model == 'csv') {
'@phan-var-force ImportCsv $obj';
$obj->separator = $separator_used;
$obj->enclosure = $enclosure;
$obj->charset = '';
}
if ($model == 'xlsx') {
'@phan-var-force ImportXlsx $obj';
if (!preg_match('/\.xlsx$/i', $filetoimport)) {
$langs->load("errors");
$param = '&datatoimport='.$datatoimport.'&format='.$format;
setEventMessages($langs->trans("ErrorFileMustHaveFormat", $model), null, 'errors');
header("Location: ".$_SERVER["PHP_SELF"].'?step=3'.$param.'&filetoimport='.urlencode($relativepath));
exit;
}
}
if (GETPOST('update')) {
$array_match_file_to_database = array();
}
// Load the source fields from input file into variable $arrayrecord
$fieldssource = array();
/** @var array<string,string> $fieldssource */
$result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
if ($result >= 0) {
// Read first line
$arrayrecord = $obj->import_read_record();
// Create array $fieldssource starting with 1 with values found of first line.
$i = 1;
foreach ($arrayrecord as $key => $val) {
if ($val["type"] != -1) {
$fieldssource[$i]['example1'] = dol_trunc($val['val'], 128);
$i++;
} else {
$fieldssource[$i]['example1'] = $langs->trans('Empty');
$i++;
}
$fieldssource[$i]['imported'] = 0;
}
$obj->import_close_file();
}
// Load targets fields in database
$fieldstarget = $objimport->array_import_fields[0];
$minpos = min(count($fieldssource), count($fieldstarget));
//var_dump($array_match_file_to_database);
$initialloadofstep4 = false;
if (empty($_SESSION['dol_array_match_file_to_database_select'])) {
$initialloadofstep4 = true;
}
// Is it a first time in page (if yes, we must initialize array_match_file_to_database)
if (count($array_match_file_to_database) == 0) {
// This is first input in screen, we need to define
// $array_match_file_to_database
// $serialized_array_match_file_to_database
// $_SESSION["dol_array_match_file_to_database"]
$pos = 1;
$num = count($fieldssource);
while ($pos <= $num) {
if ($num >= 1 && $pos <= $num) {
$posbis = 1;
foreach ($fieldstarget as $key => $val) {
if ($posbis < $pos) {
$posbis++;
continue;
}
// We found the key of targets that is at position pos
$array_match_file_to_database[$pos] = $key;
break;
}
}
$pos++;
}
}
$array_match_database_to_file = array_flip($array_match_file_to_database);
//var_dump($array_match_database_to_file);
//var_dump($_SESSION["dol_array_match_file_to_database_select"]);
$fieldstarget_tmp = array();
$arraykeysfieldtarget = array_keys($fieldstarget);
$position = 0;
foreach ($fieldstarget as $key => $label) {
$isrequired = preg_match('/\*$/', $label);
if (!empty($isrequired)) {
$newlabel = substr($label, 0, -1);
$fieldstarget_tmp[$key] = array("label" => $newlabel, "required" => true);
} else {
$fieldstarget_tmp[$key] = array("label" => $label, "required" => false);
}
if (!empty($array_match_database_to_file[$key])) {
$fieldstarget_tmp[$key]["imported"] = true;
$fieldstarget_tmp[$key]["position"] = $array_match_database_to_file[$key] - 1;
$keytoswap = $key;
while (!empty($array_match_database_to_file[$keytoswap])) {
if ($position + 1 > $array_match_database_to_file[$keytoswap]) {
$keytoswapwith = $array_match_database_to_file[$keytoswap] - 1;
$tmp = [$keytoswap => $fieldstarget_tmp[$keytoswap]];
unset($fieldstarget_tmp[$keytoswap]);
$fieldstarget_tmp = arrayInsert($fieldstarget_tmp, $keytoswapwith, $tmp);
$keytoswapwith = $arraykeysfieldtarget[$array_match_database_to_file[$keytoswap] - 1];
$tmp = $fieldstarget_tmp[$keytoswapwith];
unset($fieldstarget_tmp[$keytoswapwith]);
$fieldstarget_tmp[$keytoswapwith] = $tmp;
$keytoswap = $keytoswapwith;
} else {
break;
}
}
} else {
$fieldstarget_tmp[$key]["imported"] = false;
}
$position++;
}
$fieldstarget = $fieldstarget_tmp;
//print $serialized_array_match_file_to_database;
//print $_SESSION["dol_array_match_file_to_database"];
//print $_SESSION["dol_array_match_file_to_database_select"];
//var_dump($array_match_file_to_database);exit;
// Now $array_match_file_to_database contains fieldnb(1,2,3...)=>fielddatabase(key in $array_match_file_to_database)
$param = '&format='.$format.'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport);
if ($excludefirstline) {
$param .= '&excludefirstline='.urlencode($excludefirstline);
}
if ($endatlinenb) {
$param .= '&endatlinenb='.urlencode($endatlinenb);
}
if ($separator) {
$param .= '&separator='.urlencode($separator);
}
if ($enclosure) {
$param .= '&enclosure='.urlencode($enclosure);
}
llxHeader('', $langs->trans("NewImport"), $help_url);
$head = import_prepare_head($param, 4);
print dol_get_fiche_head($head, 'step4', '', -2);
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table class="centpercent border tableforfield">';
// Module
print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
print '<td>';
$titleofmodule = $objimport->array_import_module[0]['module']->getName();
// Special cas for import common to module/services
if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
$titleofmodule = $langs->trans("ProductOrService");
}
print $titleofmodule;
print '</td></tr>';
// Lot de donnees a importer
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
print '<td>';
$entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
print $objimport->array_import_label[0];
print '</td></tr>';
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border tableforfield">';
// Source file format
print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
print '<td>';
$text = $objmodelimport->getDriverDescForKey($format);
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
print '</td></tr>';
// Separator and enclosure
if ($model == 'csv') {
'@phan-var-force ImportCsv $obj';
print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
print '<td>';
print '<form method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" value="'.$step.'" name="step">';
print '<input type="hidden" value="'.$format.'" name="format">';
print '<input type="hidden" value="'.$excludefirstline.'" name="excludefirstline">';
print '<input type="hidden" value="'.$endatlinenb.'" name="endatlinenb">';
print '<input type="hidden" value="'.$datatoimport.'" name="datatoimport">';
print '<input type="hidden" value="'.$filetoimport.'" name="filetoimport">';
print $langs->trans("Separator").' : ';
print '<input type="text" class="width25 center" name="separator" value="'.dol_escape_htmltag($separator).'"/>';
print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : ';
print '<input type="text" class="width25 center" name="enclosure" value="'.dol_escape_htmltag($enclosure).'"/> ';
print '<input name="update" type="submit" value="'.$langs->trans('Update').'" class="button smallpaddingimp" />';
print '</form>';
print '</td></tr>';
}
// File to import
print '<tr><td>'.$langs->trans("FileToImport").'</td>';
print '<td>';
$modulepart = 'import';
$relativepath = GETPOST('filetoimport');
print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
print img_mime($file, '', 'pictofixedwidth');
print $filetoimport;
print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"');
print '</a>';
print '</td></tr>';
print '</table>';
print '</div>';
print dol_get_fiche_end();
print '<br>'."\n";
// List of source fields
print '<!-- List of source fields -->'."\n";
print '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="select_model">';
print '<input type="hidden" name="step" value="4">';
print '<input type="hidden" name="format" value="'.$format.'">';
print '<input type="hidden" name="datatoimport" value="'.$datatoimport.'">';
print '<input type="hidden" name="filetoimport" value="'.$filetoimport.'">';
print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
print '<input type="hidden" name="separator" value="'.dol_escape_htmltag($separator).'">';
print '<input type="hidden" name="enclosure" value="'.dol_escape_htmltag($enclosure).'">';
// Import profile to use/load
print '<div class="marginbottomonly">';
print '<span class="opacitymedium">';
$s = $langs->trans("SelectImportFieldsSource", '{s1}');
$s = str_replace('{s1}', img_picto('', 'grip_title', '', false, 0, 0, '', '', 0), $s);
print $s;
print '</span> ';
$htmlother->select_import_model($importmodelid, 'importmodelid', $datatoimport, 1, $user->id);
print '<input type="submit" class="button small reposition" value="'.$langs->trans("Select").'">';
print '</div>';
print '</form>';
// Title of array with fields
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
print '<table class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("FieldsInSourceFile").'</td>';
print '<td>'.$langs->trans("FieldsInTargetDatabase").'</td>';
print '</tr>';
//var_dump($array_match_file_to_database);
print '<tr valign="top"><td width="50%" class="nopaddingleftimp">';
$fieldsplaced = array();
$valforsourcefieldnb = array();
$listofkeys = array();
foreach ($array_match_file_to_database as $key => $val) {
$listofkeys[$key] = 1;
}
print "\n<!-- Box left container -->\n";
print '<div id="left" class="connectedSortable">'."\n";
// List of source fields
$lefti = 1;
foreach ($fieldssource as $key => $val) {
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
show_elem($fieldssource, $key, $val); // key is field number in source file
$listofkeys[$key] = 1;
$fieldsplaced[$key] = 1;
$valforsourcefieldnb[$lefti] = $key;
$lefti++;
/*if ($lefti > count($fieldstarget)) {
break; // Other fields are in the not imported area
}*/
}
//var_dump($valforsourcefieldnb);
print "</div>\n";
print "<!-- End box left container -->\n";
print '</td><td width="50%" class="nopaddingrightimp">';
// Set the list of all possible target fields in Dolibarr.
$optionsall = array();
foreach ($fieldstarget as $code => $line) {
$tmparray = explode('|', $line["label"]); // If label of field is several translation keys separated with |
$labeltoshow = '';
foreach ($tmparray as $tmpkey => $tmpval) {
$labeltoshow .= ($labeltoshow ? ' '.$langs->trans('or').' ' : '').$langs->transnoentities($tmpval);
}
// TODO Get type from a new array into module descriptor.
// $picto = 'email';
$picto = '';
$optionsall[$code] = array(
'labelkey' => $line['label'],
'labelkeyarray' => $tmparray,
'label' => $labeltoshow,
'required' => (empty($line["required"]) ? 0 : 1),
'position' => (!empty($line['position']) ? $line['position'] : 0),
'picto' => $picto,
);
}
// $optionsall is an array of all possible target fields. key=>array('label'=>..., 'xxx')
$height = '32px'; //needs px for css height attribute below
$i = 0;
$mandatoryfieldshavesource = true;
//var_dump($fieldstarget);
//var_dump($optionsall);
//exit;
//var_dump($_SESSION['dol_array_match_file_to_database']);
//var_dump($_SESSION['dol_array_match_file_to_database_select']);
//exit;
//var_dump($optionsall);
//var_dump($fieldssource);
//var_dump($fieldstarget);
$modetoautofillmapping = 'session'; // Use setup in session
if ($initialloadofstep4) {
$modetoautofillmapping = 'guess';
}
//var_dump($modetoautofillmapping);
print '<table class="nobordernopadding centpercent tableimport">';
foreach ($fieldssource as $code => $line) { // $fieldssource is an array code=column num, line=content on first line for column in source file.
/*if ($i == $minpos) {
break;
}*/
print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
// Note: $code is int, but index should be fieldname? -> @phan-suppress-next-line PhanTypeMismatchDimFetch
$entity = (!empty($objimport->array_import_entities[0][$code]) ? $objimport->array_import_entities[0][$code] : $objimport->array_import_icon[0]);
$entityicon = !empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity; // $entityicon must string name of picto of the field like 'project', 'company', 'contact', 'modulename', ...
$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', ...
print '<td class="nowraponall hideonsmartphone" style="font-weight: normal">=> </td>';
print '<td class="nowraponall" style="font-weight: normal">';
$selectforline = '';
$selectforline .= '<select id="selectorderimport_'.($i + 1).'" class="targetselectchange minwidth300" name="select_'.($i + 1).'">';
if (!empty($line["imported"])) {
$selectforline .= '<option value="-1">&nbsp;</option>';
} else {
$selectforline .= '<option selected="" value="-1">&nbsp;</option>';
}
$j = 0;
$codeselectedarray = array();
foreach ($optionsall as $tmpcode => $tmpval) { // Loop on each entry to add into each combo list.
$label = '';
if (!empty($tmpval['picto'])) {
$label .= img_picto('', $tmpval['picto'], 'class="pictofixedwidth"');
}
$label .= $tmpval['required'] ? '<strong>' : '';
$label .= $tmpval['label'];
$label .= $tmpval['required'] ? '*</strong>' : '';
$tablealias = preg_replace('/(\..*)$/i', '', $tmpcode);
$tablename = !empty($objimport->array_import_tables[0][$tablealias]) ? $objimport->array_import_tables[0][$tablealias] : "";
$htmltext = '';
$filecolumn = ($i + 1);
// Source field info
if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need conversion
$filecolumntoshow = num2Alpha($i);
} else {
if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') {
$htmltext .= $langs->trans("DataComeFromIdFoundFromRef", $langs->transnoentitiesnoconv($entitylang)).'<br>';
}
if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') {
$htmltext .= $langs->trans("DataComeFromIdFoundFromCodeId", $langs->transnoentitiesnoconv($objimport->array_import_convertvalue[0][$tmpcode]['dict'])).'<br>';
}
}
// Source required
$example = !empty($objimport->array_import_examplevalues[0][$tmpcode]) ? $objimport->array_import_examplevalues[0][$tmpcode] : "";
// Example
if (empty($objimport->array_import_convertvalue[0][$tmpcode])) { // If source file does not need conversion
if ($example) {
$htmltext .= $langs->trans("SourceExample").': <b>'.str_replace('"', '', $example).'</b><br>';
}
} else {
if ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromref') {
$htmltext .= $langs->trans("SourceExample").': <b>'.$langs->transnoentitiesnoconv("ExampleAnyRefFoundIntoElement", $entitylang).($example ? ' ('.$langs->transnoentitiesnoconv("Example").': '.str_replace('"', '', $example).')' : '').'</b><br>';
} elseif ($objimport->array_import_convertvalue[0][$tmpcode]['rule'] == 'fetchidfromcodeid') {
$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>';
} elseif ($example) {
$htmltext .= $langs->trans("SourceExample").': <b>'.str_replace('"', '', $example).'</b><br>';
}
}
// Format control rule
if (!empty($objimport->array_import_regex[0][$tmpcode])) {
$htmltext .= $langs->trans("FormatControlRule").': <b>'.str_replace('"', '', $objimport->array_import_regex[0][$tmpcode]).'</b><br>';
}
//var_dump($htmltext);
$htmltext .= $langs->trans("InformationOnTargetTables").': &nbsp; <b>'.$tablename."->".preg_replace('/^.*\./', '', $tmpcode)."</b>";
$labelhtml = $label.' '.$form->textwithpicto('', $htmltext, 1, 'help', '', 1);
$selectforline .= '<option value="'.$tmpcode.'"';
if ($modetoautofillmapping == 'orderoftargets') {
// 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.
if ($j == $i) {
$selectforline .= ' selected';
}
} elseif ($modetoautofillmapping == 'guess') {
// The mode where we try to guess which value to preselect from the name in first column of source file.
// $line['example1'] is the label of the column found on first line
$regs = array();
if (preg_match('/^(.+)\((.+\..+)\)$/', $line['example1'], $regs)) { // If text is "Label (x.abc)"
$tmpstring1 = $regs[1];
$tmpstring2 = $regs[2];
} else {
$tmpstring1 = $line['example1'];
$tmpstring2 = '';
}
$tmpstring1 = strtolower(dol_string_unaccent(str_replace('*', '', trim($tmpstring1))));
$tmpstring2 = strtolower(dol_string_unaccent(str_replace('*', '', trim($tmpstring2))));
// $tmpstring1 and $tmpstring2 are string from the input file title of column "Label (fieldname)".
// $tmpval is array of target fields read from the module import profile.
foreach ($tmpval['labelkeyarray'] as $tmpval2) {
$labeltarget = $langs->transnoentities($tmpval2);
//var_dump($tmpstring1.' - '.$tmpstring2.' - '.$tmpval['labelkey'].' - '.$tmpval['label'].' - '.$tmpval2.' - '.$labeltarget);
if ($tmpstring1 && ($tmpstring1 == $tmpcode || $tmpstring1 == strtolower($labeltarget)
|| $tmpstring1 == strtolower(dol_string_unaccent($labeltarget)) || $tmpstring1 == strtolower($tmpval2))) {
if (empty($codeselectedarray[$code])) {
$selectforline .= ' selected';
$codeselectedarray[$code] = 1;
break;
}
} elseif ($tmpstring2 && ($tmpstring2 == $tmpcode || $tmpstring2 == strtolower($labeltarget)
|| $tmpstring2 == strtolower(dol_string_unaccent($labeltarget)) || $tmpstring2 == strtolower($tmpval2))) {
if (empty($codeselectedarray[$code])) {
$selectforline .= ' selected';
$codeselectedarray[$code] = 1;
break;
}
}
}
} elseif ($modetoautofillmapping == 'session' && !empty($_SESSION['dol_array_match_file_to_database_select'])) {
$tmpselectioninsession = dolExplodeIntoArray($_SESSION['dol_array_match_file_to_database_select'], ',', '=');
//var_dump($code);
if (!empty($tmpselectioninsession[(string) ($i + 1)]) && $tmpselectioninsession[(string) ($i + 1)] == $tmpcode) {
$selectforline .= ' selected';
}
$selectforline .= ' data-debug="'.$tmpcode.'-'.$code.'-'.$j.'-'.(!empty($tmpselectioninsession[(string) ($i + 1)]) ? $tmpselectioninsession[(string) ($i + 1)] : "").'"';
}
$selectforline .= ' data-html="'.dol_escape_htmltag($labelhtml).'"';
$selectforline .= '>';
$selectforline .= $label;
$selectforline .= '</options>';
$j++;
}
$selectforline .= '</select>';
$selectforline .= ajax_combobox('selectorderimport_'.($i + 1));
print $selectforline;
print '</td>';
// Tooltip at end of line
print '<td class="nowraponall" style="font-weight:normal; text-align:right">';
// Source field info
$htmltext = '<b><u>'.$langs->trans("FieldSource").'</u></b><br>';
$filecolumntoshow = num2Alpha($i);
$htmltext .= $langs->trans("DataComeFromFileFieldNb", $filecolumntoshow).'<br>';
print $form->textwithpicto('', $htmltext);
print '</td>';
print '</tr>';
$i++;
}
print '</table>';
print '</td></tr>';
// Lines for remark
print '<tr class="liste_titre"><td colspan="2">'.$langs->trans("Note").'</td></tr>';
print '<tr><td colspan="2"><div id="div-mandatory-target-fields-not-mapped"></div></td></tr>';
print '</table>';
print '</div>';
if (!empty($conf->use_javascript_ajax)) {
print '<script type="text/javascript">'."\n";
print 'var previousselectedvalueimport = "0";'."\n";
print 'var previousselectedlabelimport = "0";'."\n";
print 'var arrayofselectedvalues = [];'."\n";
print 'var arrayoftargetfields = [];'."\n";
print 'var arrayoftargetmandatoryfields = [];'."\n";
// Loop on $fieldstarget (seems sorted by 'position') to store php array into javascript array
$tmpi = 0;
foreach ($fieldstarget as $key => $val) {
print "arrayoftargetfields[".$tmpi."] = '".dol_escape_js($langs->trans($val['label']))."'; ";
if ($val['required']) {
print "arrayoftargetmandatoryfields[".$tmpi."] = '".dol_escape_js($key)."'; ";
}
$tmpi++;
}
print "\n";
print '$(document).ready(function () {'."\n";
print 'setOptionsToDisabled();'."\n";
print 'saveSelection();'."\n";
print '$(".targetselectchange").focus(function(){'."\n";
print ' previousselectedvalueimport = $(this).val();'."\n";
print ' previousselectedlabelimport = $(this).children("option:selected").text();'."\n";
print ' console.log("previousselectedvalueimport="+previousselectedvalueimport)'."\n";
print '})'."\n";
// Function to set the disabled flag
// - We set all option to "enabled"
// - Then we scan all combo to get the value currently selected and save them into the array arrayofselectedvalues
// - Then we set to disabled all fields that are selected
print 'function setOptionsToDisabled() {'."\n";
print ' console.log("Remove the disabled flag everywhere");'."\n";
print ' $("select.targetselectchange").not($( this )).find(\'option\').prop("disabled", false);'."\n"; // Enable all options
print ' arrayofselectedvalues = [];'."\n";
print ' $("select.targetselectchange").each(function(){'."\n";
print ' id = $(this).attr(\'id\')'."\n";
print ' value = $(this).val()'."\n";
print ' console.log("a selected value has been found for component "+id+" = "+value);'."\n";
print ' arrayofselectedvalues.push(value);'."\n";
print ' });'."\n";
print ' console.log("List of all selected values arrayofselectedvalues");'."\n";
print ' console.log(arrayofselectedvalues);'."\n";
print ' console.log("Set the option to disabled for every entry that is currently selected somewhere else (so into arrayofselectedvalues)");'."\n";
print ' $.each(arrayofselectedvalues, function(key, value) {'."\n"; // Loop on each selected value
print ' if (value != -1) {'."\n";
print ' console.log("Process key="+key+" value="+value+" to disable.");'."\n";
print ' $("select.targetselectchange").find(\'option[value="\'+value+\'"]:not(:selected)\').prop("disabled", true);'."\n"; // Set to disabled except if currently selected
print ' }'."\n";
print ' });'."\n";
print '}'."\n";
// Function to save the selection in database
print 'function saveSelection() {'."\n";
//print ' console.log(arrayofselectedvalues);'."\n";
print ' arrayselectedfields = [];'."\n";
print ' arrayselectedfields.push(0);'."\n";
print ' $.each( arrayofselectedvalues, function( key, value ) {'."\n";
print ' if (value != -1) {'."\n";
print ' arrayselectedfields.push(value);'."\n";
print ' } else {'."\n";
print ' arrayselectedfields.push(0);'."\n";
print ' }'."\n";
print ' });'."\n";
print " $.ajax({\n";
print " type: 'POST',\n";
print " dataType: 'json',\n";
print " url: '".dol_escape_js($_SERVER["PHP_SELF"])."?action=saveselectorder&token=".newToken()."',\n";
print " data: 'selectorder='+arrayselectedfields.toString(),\n";
print " success: function(){\n";
print " console.log('The selected fields have been saved into '+arrayselectedfields.toString());\n";
print " },\n";
print ' });'."\n";
// Now we loop on all target fields that are mandatory to show if they are not mapped yet.
print ' console.log("arrayselectedfields");';
print ' console.log(arrayselectedfields);';
print ' console.log("arrayoftargetmandatoryfields");';
print ' console.log(arrayoftargetmandatoryfields);';
print " listtoshow = '';";
print " nbelement = arrayoftargetmandatoryfields.length
for (let i = 0; i < nbelement; i++) {
if (arrayoftargetmandatoryfields[i] && ! arrayselectedfields.includes(arrayoftargetmandatoryfields[i])) {
console.log(arrayoftargetmandatoryfields[i]+' not mapped');
listtoshow = listtoshow + (listtoshow ? ', ' : '') + '<b>' + arrayoftargetfields[i] + '*</b>';
}
}
console.log(listtoshow);
if (listtoshow) {
listtoshow = '".dol_escape_js(img_warning($langs->trans("MandatoryTargetFieldsNotMapped")).' '.$langs->trans("MandatoryTargetFieldsNotMapped")).": ' + listtoshow;
$('#div-mandatory-target-fields-not-mapped').html(listtoshow);
} else {
$('#div-mandatory-target-fields-not-mapped').html('<span class=\"opacitymedium\">".dol_escape_js($langs->trans("AllTargetMandatoryFieldsAreMapped"))."</span>');
}
";
print '}'."\n";
// If we make a change on a selectbox
print '$(".targetselectchange").change(function(){'."\n";
print ' setOptionsToDisabled();'."\n";
print ' if(previousselectedlabelimport != "" && previousselectedvalueimport != -1) {'."\n";
print ' let valuetochange = $(this).val(); '."\n";
print ' $(".boxtdunused").each(function(){'."\n";
print ' if ($(this).text().includes(valuetochange)){'."\n";
print ' arraychild = $(this)[0].childNodes'."\n";
print ' arraytexttomodify = arraychild[0].textContent.split(" ")'."\n";
print ' arraytexttomodify[1] = previousselectedvalueimport '."\n";
print ' textmodified = arraytexttomodify.join(" ") '."\n";
print ' arraychild[0].textContent = textmodified'."\n";
print ' arraychild[1].innerHTML = previousselectedlabelimport'."\n";
print ' }'."\n";
print ' })'."\n";
print ' }'."\n";
print ' $(this).blur()'."\n";
print ' saveSelection()'."\n";
print '});'."\n";
print '})'."\n";
print '</script>'."\n";
}
/*
* Action bar
*/
print '<div class="tabsAction">';
if (count($array_match_file_to_database)) {
if ($mandatoryfieldshavesource) {
print '<a class="butAction saveorderselect" href="import.php?step=5'.$param.'&filetoimport='.urlencode($filetoimport).'">'.$langs->trans("NextStep").'</a>';
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("SomeMandatoryFieldHaveNoSource")).'">'.$langs->trans("NextStep").'</a>';
}
}
print '</div>';
// Area for profils import
if (count($array_match_file_to_database)) {
print '<br>'."\n";
print '<!-- Area to add new import profile -->'."\n";
print '<div class="marginbottomonly"><span class="opacitymedium">'.$langs->trans("SaveImportModel").'</span></div>';
print '<form class="nocellnopadd" action="'.$_SERVER["PHP_SELF"].'" method="post">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="action" value="add_import_model">';
print '<input type="hidden" name="step" value="'.$step.'">';
print '<input type="hidden" name="format" value="'.$format.'">';
print '<input type="hidden" name="datatoimport" value="'.$datatoimport.'">';
print '<input type="hidden" name="filetoimport" value="'.$filetoimport.'">';
print '<input type="hidden" name="hexa" value="'.$hexa.'">';
print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
print '<input type="hidden" name="page_y" value="">';
print '<input type="hidden" value="'.dol_escape_htmltag($separator).'" name="separator">';
print '<input type="hidden" value="'.dol_escape_htmltag($enclosure).'" name="enclosure">';
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
print '<table summary="selectofimportprofil" class="noborder centpercent">';
print '<tr class="liste_titre">';
print '<td>'.$langs->trans("ImportModelName").'</td>';
print '<td>'.$langs->trans("Visibility").'</td>';
print '<td></td>';
print '</tr>';
$nameofimportprofile = str_replace(' ', '-', $langs->trans("ImportProfile").' '.$titleofmodule.' '.dol_print_date(dol_now('gmt'), 'dayxcard'));
if (GETPOST('import_name')) { // If we have submitted a form, we take value used for the update try
$nameofimportprofile = $import_name;
}
print '<tr class="oddeven">';
print '<td><input name="import_name" class="minwidth300" value="'.$nameofimportprofile.'"></td>';
print '<td>';
$arrayvisibility = array('private' => $langs->trans("Private"), 'all' => $langs->trans("Everybody"));
print $form->selectarray('visibility', $arrayvisibility, 'private');
print '</td>';
print '<td class="right">';
print '<input type="submit" class="button smallpaddingimp reposition" value="'.$langs->trans("SaveImportProfile").'">';
print '</td></tr>';
// List of existing import profils
$sql = "SELECT rowid, label, fk_user, entity";
$sql .= " FROM ".MAIN_DB_PREFIX."import_model";
$sql .= " WHERE type = '".$db->escape($datatoimport)."'";
if (!getDolGlobalString('EXPORTS_SHARE_MODELS')) { // EXPORTS_SHARE_MODELS means all templates are visible, whatever is owner.
$sql .= " AND fk_user IN (0, ".((int) $user->id).")";
}
$sql .= " ORDER BY rowid";
$resql = $db->query($sql);
if ($resql) {
$num = $db->num_rows($resql);
$tmpuser = new User($db);
$i = 0;
while ($i < $num) {
$obj = $db->fetch_object($resql);
print '<tr class="oddeven"><td>';
print $obj->label;
print '</td>';
print '<td class="tdoverflowmax150">';
if (empty($obj->fk_user)) {
print $langs->trans("Everybody");
} else {
$tmpuser->fetch($obj->fk_user);
print $tmpuser->getNomUrl(-1);
}
print '</td>';
print '<td class="right">';
print '<a class="reposition" href="'.$_SERVER["PHP_SELF"].'?step='.$step.$param.'&action=deleteprof&token='.newToken().'&id='.$obj->rowid.'&filetoimport='.urlencode($filetoimport).'">';
print img_delete();
print '</a>';
print '</tr>';
$i++;
}
} else {
dol_print_error($db);
}
print '</table>';
print '</div>';
print '</form>';
}
}
// STEP 5: Summary of choices and launch simulation
if ($step == 5 && $datatoimport) {
$max_execution_time_for_importexport = getDolGlobalInt('IMPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined
$max_time = @ini_get("max_execution_time");
if ($max_time && $max_time < $max_execution_time_for_importexport) {
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.");
@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
}
$model = $format;
$list = $objmodelimport->listOfAvailableImportFormat($db);
// Create class to use for import
$dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
$file = "import_".$model.".modules.php";
$classname = "Import".ucfirst($model);
require_once $dir.$file;
$obj = new $classname($db, $datatoimport);
'@phan-var-force ModeleImports $obj';
if ($model == 'csv') {
'@phan-var-force ImportCsv $obj';
$obj->separator = $separator_used;
$obj->enclosure = $enclosure;
}
// Load source fields in input file
$fieldssource = array();
$result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
if ($result >= 0) {
// Read first line
$arrayrecord = $obj->import_read_record();
// Put into array fieldssource starting with 1.
$i = 1;
foreach ($arrayrecord as $key => $val) {
$fieldssource[$i]['example1'] = dol_trunc($val['val'], 24);
$i++;
}
$obj->import_close_file();
}
$nboflines = $obj->import_get_nb_of_lines($conf->import->dir_temp.'/'.$filetoimport);
$param = '&leftmenu=import&format='.urlencode($format).'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport).'&nboflines='.((int) $nboflines).'&separator='.urlencode($separator).'&enclosure='.urlencode($enclosure);
$param2 = $param; // $param2 = $param without excludefirstline and endatlinenb
if ($excludefirstline) {
$param .= '&excludefirstline='.urlencode($excludefirstline);
}
if ($endatlinenb) {
$param .= '&endatlinenb='.urlencode($endatlinenb);
}
if (!empty($updatekeys)) {
$param .= '&updatekeys[]='.implode('&updatekeys[]=', $updatekeys);
}
llxHeader('', $langs->trans("NewImport"), $help_url);
$head = import_prepare_head($param, 5);
print '<form action="'.$_SERVER["PHP_SELF"].'?'.$param2.'" method="POST">';
print '<input type="hidden" name="token" value="'.newToken().'">';
print '<input type="hidden" name="step" value="5">'; // step 5
print '<input type="hidden" name="action" value="launchsimu">'; // step 5
print dol_get_fiche_head($head, 'step5', '', -2);
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border tableforfield">';
// Module
print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
print '<td>';
$titleofmodule = $objimport->array_import_module[0]['module']->getName();
// Special cas for import common to module/services
if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
$titleofmodule = $langs->trans("ProductOrService");
}
print $titleofmodule;
print '</td></tr>';
// Lot de donnees a importer
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
print '<td>';
$entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
print $objimport->array_import_label[0];
print '</td></tr>';
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border tableforfield">';
// Source file format
print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
print '<td>';
$text = $objmodelimport->getDriverDescForKey($format);
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
print '</td></tr>';
// Separator and enclosure
if ($model == 'csv') {
'@phan-var-force ImportCsv $obj';
print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
print '<td>';
print $langs->trans("Separator").' : '.dol_escape_htmltag($separator);
print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : '.dol_escape_htmltag($enclosure);
print '</td></tr>';
}
// File to import
print '<tr><td>'.$langs->trans("FileToImport").'</td>';
print '<td>';
$modulepart = 'import';
$relativepath = GETPOST('filetoimport');
print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
print img_mime($file, '', 'pictofixedwidth');
print $filetoimport;
print img_picto($langs->trans("Download"), 'download', 'class="paddingleft opacitymedium"');
print '</a>';
print '</td></tr>';
// Total lines in source file
print '<tr><td>';
print $langs->trans("NbOfSourceLines");
print '</td><td>';
print $nboflines;
print '</td></tr>';
// Range of lines to import
print '<tr><td>';
print $langs->trans("ImportFromToLine");
print '</td><td>';
if ($action == 'launchsimu') {
print '<input type="number" class="maxwidth50 right" name="excludefirstlinebis" disabled="disabled" value="'.$excludefirstline.'">';
print '<input type="hidden" name="excludefirstline" value="'.$excludefirstline.'">';
} else {
print '<input type="number" class="maxwidth50 right" name="excludefirstline" value="'.$excludefirstline.'">';
print $form->textwithpicto("", $langs->trans("SetThisValueTo2ToExcludeFirstLine"));
}
print ' - ';
if ($action == 'launchsimu') {
print '<input type="text" class="maxwidth50" name="endatlinenbbis" disabled="disabled" value="'.$endatlinenb.'">';
print '<input type="hidden" name="endatlinenb" value="'.$endatlinenb.'">';
} else {
print '<input type="text" class="maxwidth50" name="endatlinenb" value="'.$endatlinenb.'">';
print $form->textwithpicto("", $langs->trans("KeepEmptyToGoToEndOfFile"));
}
if ($action == 'launchsimu') {
print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?step=5'.$param.'">'.$langs->trans("Modify").'</a>';
}
if ($excludefirstline == 2) {
print $form->textwithpicto("", $langs->trans("WarningFirstImportedLine", $excludefirstline), 1, 'warning', "warningexcludefirstline");
print '<script>
$( document ).ready(function() {
$("input[name=\'excludefirstline\']").on("change",function(){
if($(this).val() <= 1){
$(".warningexcludefirstline").hide();
}else{
$(".warningexcludefirstline").show();
}
})
});
</script>';
}
print '</td></tr>';
// Keys for data UPDATE (not INSERT of new data)
print '<tr><td>';
print $form->textwithpicto($langs->trans("KeysToUseForUpdates"), $langs->trans("SelectPrimaryColumnsForUpdateAttempt"));
print '</td><td>';
if ($action == 'launchsimu') {
if (count($updatekeys)) {
print $form->multiselectarray('updatekeysbis', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%', 'disabled');
} else {
print '<span class="opacitymedium">'.$langs->trans("NoUpdateAttempt").'</span> &nbsp; -';
}
foreach ($updatekeys as $val) {
print '<input type="hidden" name="updatekeys[]" value="'.$val.'">';
}
print ' &nbsp; <a href="'.$_SERVER["PHP_SELF"].'?step=5'.$param.'">'.$langs->trans("Modify").'</a>';
} else {
if (is_array($objimport->array_import_updatekeys[0]) && count($objimport->array_import_updatekeys[0])) { //TODO dropdown UL is created inside nested SPANS
print $form->multiselectarray('updatekeys', $objimport->array_import_updatekeys[0], $updatekeys, 0, 0, '', 1, '80%');
//print $form->textwithpicto("", $langs->trans("SelectPrimaryColumnsForUpdateAttempt"));
} else {
print '<span class="opacitymedium">'.$langs->trans("UpdateNotYetSupportedForThisImport").'</span>';
}
}
/*echo '<pre>';
print_r($objimport->array_import_updatekeys);
echo '</pre>';*/
print '</td></tr>';
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnTargetTables"), '', 'file-import');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border tableforfield">';
// Tables imported
print '<tr><td class="titlefieldcreate">';
print $langs->trans("TablesTarget");
print '</td><td>';
$listtables = array();
$sort_array_match_file_to_database = $array_match_file_to_database;
foreach ($array_match_file_to_database as $code => $label) {
//var_dump($fieldssource);
if ($code > count($fieldssource)) {
continue;
}
//print $code.'-'.$label;
$alias = preg_replace('/(\..*)$/i', '', $label);
$listtables[$alias] = $objimport->array_import_tables[0][$alias];
}
if (count($listtables)) {
$newval = '';
//ksort($listtables);
foreach ($listtables as $val) {
if ($newval) {
print ', ';
}
$newval = $val;
// Link to Dolibarr wiki pages
/*$helppagename='EN:Table_'.$newval;
if ($helppagename && empty($conf->global->MAIN_HELP_DISABLELINK))
{
// Get helpbaseurl, helppage and mode from helppagename and langs
$arrayres=getHelpParamFor($helppagename,$langs);
$helpbaseurl=$arrayres['helpbaseurl'];
$helppage=$arrayres['helppage'];
$mode=$arrayres['mode'];
$newval.=' <a href="'.sprintf($helpbaseurl,$helppage).'">'.img_picto($langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'),DOL_URL_ROOT.'/theme/common/helpdoc.png','',1).'</a>';
}*/
print $newval;
}
} else {
print $langs->trans("Error");
}
print '</td></tr>';
// Fields imported
print '<tr><td>';
print $langs->trans("FieldsTarget").'</td><td>';
$listfields = array();
$i = 0;
//print 'fieldsource='.$fieldssource;
$sort_array_match_file_to_database = $array_match_file_to_database;
ksort($sort_array_match_file_to_database);
//var_dump($sort_array_match_file_to_database);
foreach ($sort_array_match_file_to_database as $code => $label) {
$i++;
//var_dump($fieldssource);
if ($code > count($fieldssource)) {
continue;
}
//print $code.'-'.$label;
$alias = preg_replace('/(\..*)$/i', '', $label);
$listfields[$i] = '<span class="nowrap">'.$langs->trans("Column").' '.num2Alpha((int) $code - 1).' -> '.$label.'</span>';
}
print count($listfields) ? (implode(', ', $listfields)) : $langs->trans("Error");
print '</td></tr>';
print '</table>';
print '</div>';
print dol_get_fiche_end();
if ($action != 'launchsimu') {
// Show import id
print '<br><span class="opacitymedium">';
print $langs->trans("NowClickToTestTheImport", $langs->transnoentitiesnoconv("RunSimulateImportFile")).'</span><br>';
print '<br>';
// Actions
print '<div class="center">';
if ($user->hasRight('import', 'run')) {
print '<input type="submit" class="butAction" value="'.$langs->trans("RunSimulateImportFile").'">';
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunSimulateImportFile").'</a>';
}
print '</div>';
} else {
// Launch import
$arrayoferrors = array();
$arrayofwarnings = array();
$maxnboferrors = !getDolGlobalString('IMPORT_MAX_NB_OF_ERRORS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_ERRORS;
$maxnbofwarnings = !getDolGlobalString('IMPORT_MAX_NB_OF_WARNINGS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_WARNINGS;
$nboferrors = 0;
$nbofwarnings = 0;
$importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
//var_dump($array_match_file_to_database);
$db->begin();
// Open input file
$nbok = 0;
$pathfile = $conf->import->dir_temp.'/'.$filetoimport;
$result = $obj->import_open_file($pathfile);
if ($result > 0) {
global $tablewithentity_cache;
$tablewithentity_cache = array();
$sourcelinenb = 0;
$endoffile = 0;
// Loop on each input file record
while (($sourcelinenb < $nboflines) && !$endoffile) {
$sourcelinenb++;
// Read line and store it into $arrayrecord
//dol_syslog("line ".$sourcelinenb.' - '.$nboflines.' - '.$excludefirstline.' - '.$endatlinenb);
$arrayrecord = $obj->import_read_record();
if ($arrayrecord === false) {
$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');
$endoffile++;
continue;
}
if ($excludefirstline && ($sourcelinenb < $excludefirstline)) {
continue;
}
if ($endatlinenb && ($sourcelinenb > $endatlinenb)) {
break;
}
$parameters = array(
'step' => $step,
'datatoimport' => $datatoimport,
'obj' => &$obj,
'arrayrecord' => $arrayrecord,
'array_match_file_to_database' => $array_match_file_to_database,
'objimport' => $objimport,
'fieldssource' => $fieldssource,
'importid' => $importid,
'updatekeys' => $updatekeys,
'arrayoferrors' => &$arrayoferrors,
'arrayofwarnings' => &$arrayofwarnings,
'nbok' => &$nbok,
);
$reshook = $hookmanager->executeHooks('ImportInsert', $parameters);
if ($reshook < 0) {
$arrayoferrors[$sourcelinenb][] = [
'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
];
}
if (empty($reshook)) {
// Run import
$result = $obj->import_insert($arrayrecord, $array_match_file_to_database, $objimport, count($fieldssource), $importid, $updatekeys);
if (count($obj->errors)) {
$arrayoferrors[$sourcelinenb] = $obj->errors;
}
if (count($obj->warnings)) {
$arrayofwarnings[$sourcelinenb] = $obj->warnings;
}
if (!count($obj->errors) && !count($obj->warnings)) {
$nbok++;
}
}
}
// Close file
$obj->import_close_file();
} else {
print $langs->trans("ErrorFailedToOpenFile", $pathfile);
}
$error = 0;
// Run the sql after import if defined
//var_dump($objimport->array_import_run_sql_after[0]);
if (!empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0])) {
$i = 0;
foreach ($objimport->array_import_run_sql_after[0] as $sqlafterimport) {
$i++;
$resqlafterimport = $db->query($sqlafterimport);
if (!$resqlafterimport) {
$arrayoferrors['none'][] = array('lib' => $langs->trans("Error running final request: ".$sqlafterimport));
$error++;
}
}
}
$db->rollback(); // We force rollback because this was just a simulation.
// Show OK
if (!count($arrayoferrors) && !count($arrayofwarnings)) {
print '<br>';
print '<div class="info">';
print '<div class=""><b>'.$langs->trans("ResultOfSimulationNoError").'</b></div>';
print $langs->trans("NbInsertSim", empty($obj->nbinsert) ? 0 : $obj->nbinsert).'<br>';
print $langs->trans("NbUpdateSim", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'<br>';
print '</div>';
print '<br>';
} else {
print '<br>';
print '<div class="warning">';
print $langs->trans("NbOfLinesOK", $nbok).'...<br>';
print '</div>';
print '<br>';
}
// Show Errors
//var_dump($arrayoferrors);
if (count($arrayoferrors)) {
print img_error().' <b>'.$langs->trans("ErrorsOnXLines", count($arrayoferrors)).'</b><br>';
print '<table width="100%" class="border"><tr><td>';
foreach ($arrayoferrors as $key => $val) {
$nboferrors++;
if ($nboferrors > $maxnboferrors) {
print $langs->trans("TooMuchErrors", (count($arrayoferrors) - $nboferrors))."<br>";
break;
}
print '* '.$langs->trans("Line").' '.dol_escape_htmltag($key).'<br>';
foreach ($val as $i => $err) {
print ' &nbsp; &nbsp; > '.dol_escape_htmltag($err['lib']).'<br>';
}
}
print '</td></tr></table>';
print '<br>';
}
// Show Warnings
//var_dump($arrayoferrors);
if (count($arrayofwarnings)) {
print img_warning().' <b>'.$langs->trans("WarningsOnXLines", count($arrayofwarnings)).'</b><br>';
print '<table width="100%" class="border"><tr><td>';
foreach ($arrayofwarnings as $key => $val) {
$nbofwarnings++;
if ($nbofwarnings > $maxnbofwarnings) {
print $langs->trans("TooMuchWarnings", (count($arrayofwarnings) - $nbofwarnings))."<br>";
break;
}
print ' * '.$langs->trans("Line").' '.dol_escape_htmltag((string) $key).'<br>';
foreach ($val as $i => $err) {
print ' &nbsp; &nbsp; > '.dol_escape_htmltag($err['lib']).'<br>';
}
}
print '</td></tr></table>';
print '<br>';
}
// Show import id
$importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
print '<div class="center">';
print '<span class="opacitymedium">'.$langs->trans("NowClickToRunTheImport", $langs->transnoentitiesnoconv("RunImportFile")).'</span><br>';
/*if (empty($nboferrors)) {
print $langs->trans("DataLoadedWithId", $importid).'<br>';
}*/
print '</div>';
print '<br>';
// Actions
print '<div class="center">';
if ($user->hasRight('import', 'run')) {
if (empty($nboferrors)) {
print '<a class="butAction" href="'.DOL_URL_ROOT.'/imports/import.php?leftmenu=import&step=6&importid='.$importid.$param.'">'.$langs->trans("RunImportFile").'</a>';
} else {
//print '<input type="submit" class="butAction" value="'.dol_escape_htmltag($langs->trans("RunSimulateImportFile")).'">';
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("CorrectErrorBeforeRunningImport")).'">'.$langs->trans("RunImportFile").'</a>';
}
} else {
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunSimulateImportFile").'</a>';
print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->transnoentitiesnoconv("NotEnoughPermissions")).'">'.$langs->trans("RunImportFile").'</a>';
}
print '</div>';
}
print '</form>';
}
// STEP 6: Real import
if ($step == 6 && $datatoimport) {
$max_execution_time_for_importexport = getDolGlobalInt('IMPORT_MAX_EXECUTION_TIME', 300); // 5mn if not defined
$max_time = @ini_get("max_execution_time");
if ($max_time && $max_time < $max_execution_time_for_importexport) {
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.");
@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
}
$model = $format;
$list = $objmodelimport->listOfAvailableImportFormat($db);
$importid = GETPOST("importid", 'alphanohtml');
// Create class to use for import
$dir = DOL_DOCUMENT_ROOT."/core/modules/import/";
$file = "import_".$model.".modules.php";
$classname = "Import".ucfirst($model);
require_once $dir.$file;
$obj = new $classname($db, $datatoimport);
'@phan-var-force ModeleImports $obj';
if ($model == 'csv') {
'@phan-var-force ImportCsv $obj';
$obj->separator = $separator_used;
$obj->enclosure = $enclosure;
}
// Load source fields in input file
$fieldssource = array();
$result = $obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport);
if ($result >= 0) {
// Read first line
$arrayrecord = $obj->import_read_record();
// Put into array fieldssource starting with 1.
$i = 1;
foreach ($arrayrecord as $key => $val) {
$fieldssource[$i]['example1'] = dol_trunc($val['val'], 24);
$i++;
}
$obj->import_close_file();
}
$nboflines = (GETPOSTISSET("nboflines") ? GETPOSTINT("nboflines") : dol_count_nb_of_line($conf->import->dir_temp.'/'.$filetoimport));
$param = '&format='.$format.'&datatoimport='.urlencode($datatoimport).'&filetoimport='.urlencode($filetoimport).'&nboflines='.((int) $nboflines);
if ($excludefirstline) {
$param .= '&excludefirstline='.urlencode($excludefirstline);
}
if ($endatlinenb) {
$param .= '&endatlinenb='.urlencode($endatlinenb);
}
if ($separator) {
$param .= '&separator='.urlencode($separator);
}
if ($enclosure) {
$param .= '&enclosure='.urlencode($enclosure);
}
llxHeader('', $langs->trans("NewImport"), $help_url);
$head = import_prepare_head($param, 6);
print dol_get_fiche_head($head, 'step6', '', -1);
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border">';
// Module
print '<tr><td class="titlefieldcreate">'.$langs->trans("Module").'</td>';
print '<td>';
$titleofmodule = $objimport->array_import_module[0]['module']->getName();
// Special cas for import common to module/services
if (in_array($objimport->array_import_code[0], array('produit_supplierprices', 'produit_multiprice', 'produit_languages'))) {
$titleofmodule = $langs->trans("ProductOrService");
}
print $titleofmodule;
print '</td></tr>';
// Lot de donnees a importer
print '<tr><td>'.$langs->trans("DatasetToImport").'</td>';
print '<td>';
$entity = preg_replace('/:.*$/', '', $objimport->array_import_icon[0]);
$entityicon = strtolower(!empty($entitytoicon[$entity]) ? $entitytoicon[$entity] : $entity);
print img_object($objimport->array_import_module[0]['module']->getName(), $entityicon).' ';
print $objimport->array_import_label[0];
print '</td></tr>';
print '</table>';
print '</div>';
print load_fiche_titre($langs->trans("InformationOnSourceFile"), '', 'file-export');
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table width="100%" class="border">';
// Source file format
print '<tr><td class="titlefieldcreate">'.$langs->trans("SourceFileFormat").'</td>';
print '<td>';
$text = $objmodelimport->getDriverDescForKey($format);
// @phan-suppress-next-line PhanPluginSuspiciousParamPosition
print $form->textwithpicto($objmodelimport->getDriverLabelForKey($format), $text);
print '</td></tr>';
// Separator and enclosure
if ($model == 'csv') {
'@phan-var-force ImportCsv $obj';
print '<tr><td>'.$langs->trans("CsvOptions").'</td>';
print '<td>';
print $langs->trans("Separator").' : ';
print htmlentities($separator);
print '&nbsp;&nbsp;&nbsp;&nbsp;'.$langs->trans("Enclosure").' : ';
print htmlentities($enclosure);
print '</td></tr>';
}
// File to import
print '<tr><td>'.$langs->trans("FileToImport").'</td>';
print '<td>';
$modulepart = 'import';
$relativepath = GETPOST('filetoimport');
print '<a data-ajax="false" href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4'.$param.'" target="_blank" rel="noopener noreferrer">';
print img_mime($file, '', 'pictofixedwidth');
print $filetoimport;
print '</a>';
print '</td></tr>';
// Nb of fields
print '<tr><td>';
print $langs->trans("NbOfSourceLines");
print '</td><td>';
print $nboflines;
print '</td></tr>';
// Do not import first lines
print '<tr><td>';
print $langs->trans("ImportFromLine");
print '</td><td>';
print '<input type="text" size="4" name="excludefirstline" disabled="disabled" value="'.$excludefirstline.'">';
print '</td></tr>';
// Do not import end lines
print '<tr><td>';
print $langs->trans("EndAtLineNb");
print '</td><td>';
print '<input type="text" size="4" name="endatlinenb" disabled="disabled" value="'.$endatlinenb.'">';
print '</td></tr>';
print '</table>';
print '</div>';
print '<br>';
print '<b>'.$langs->trans("InformationOnTargetTables").'</b>';
print '<div class="underbanner clearboth"></div>';
print '<div class="fichecenter">';
print '<table class="border centpercent">';
// Tables imported
print '<tr><td width="25%">';
print $langs->trans("TablesTarget");
print '</td><td>';
$listtables = array();
foreach ($array_match_file_to_database as $code => $label) {
//var_dump($fieldssource);
if ($code > count($fieldssource)) {
continue;
}
//print $code.'-'.$label;
$alias = preg_replace('/(\..*)$/i', '', $label);
$listtables[$alias] = $objimport->array_import_tables[0][$alias];
}
if (count($listtables)) {
$newval = '';
foreach ($listtables as $val) {
if ($newval) {
print ', ';
}
$newval = $val;
// Link to Dolibarr wiki pages
/*$helppagename='EN:Table_'.$newval;
if ($helppagename && empty($conf->global->MAIN_HELP_DISABLELINK))
{
// Get helpbaseurl, helppage and mode from helppagename and langs
$arrayres=getHelpParamFor($helppagename,$langs);
$helpbaseurl=$arrayres['helpbaseurl'];
$helppage=$arrayres['helppage'];
$mode=$arrayres['mode'];
$newval.=' <a href="'.sprintf($helpbaseurl,$helppage).'">'.img_picto($langs->trans($mode == 'wiki' ? 'GoToWikiHelpPage': 'GoToHelpPage'),DOL_URL_ROOT.'/theme/common/helpdoc.png','',1).'</a>';
}*/
print $newval;
}
} else {
print $langs->trans("Error");
}
print '</td></tr>';
// Fields imported
print '<tr><td>';
print $langs->trans("FieldsTarget").'</td><td>';
$listfields = array();
$i = 0;
$sort_array_match_file_to_database = $array_match_file_to_database;
ksort($sort_array_match_file_to_database);
//var_dump($sort_array_match_file_to_database);
foreach ($sort_array_match_file_to_database as $code => $label) {
$i++;
//var_dump($fieldssource);
if ($code > count($fieldssource)) {
continue;
}
//print $code.'-'.$label;
$alias = preg_replace('/(\..*)$/i', '', $label);
$listfields[$i] = $langs->trans("Field").' '.$code.'->'.$label;
}
print count($listfields) ? (implode(', ', $listfields)) : $langs->trans("Error");
print '</td></tr>';
print '</table>';
print '</div>';
// Launch import
$arrayoferrors = array();
$arrayofwarnings = array();
$maxnboferrors = !getDolGlobalString('IMPORT_MAX_NB_OF_ERRORS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_ERRORS;
$maxnbofwarnings = !getDolGlobalString('IMPORT_MAX_NB_OF_WARNINGS') ? 50 : $conf->global->IMPORT_MAX_NB_OF_WARNINGS;
$nboferrors = 0;
$nbofwarnings = 0;
$importid = dol_print_date(dol_now(), '%Y%m%d%H%M%S');
//var_dump($array_match_file_to_database);
$db->begin();
// Open input file
$nbok = 0;
$pathfile = $conf->import->dir_temp.'/'.$filetoimport;
$result = $obj->import_open_file($pathfile);
if ($result > 0) {
global $tablewithentity_cache;
$tablewithentity_cache = array();
$sourcelinenb = 0;
$endoffile = 0;
while ($sourcelinenb < $nboflines && !$endoffile) {
$sourcelinenb++;
$arrayrecord = $obj->import_read_record();
if ($arrayrecord === false) {
$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');
$endoffile++;
continue;
}
if ($excludefirstline && ($sourcelinenb < $excludefirstline)) {
continue;
}
if ($endatlinenb && ($sourcelinenb > $endatlinenb)) {
break;
}
$parameters = array(
'step' => $step,
'datatoimport' => $datatoimport,
'obj' => &$obj,
'arrayrecord' => $arrayrecord,
'array_match_file_to_database' => $array_match_file_to_database,
'objimport' => $objimport,
'fieldssource' => $fieldssource,
'importid' => $importid,
'updatekeys' => $updatekeys,
'arrayoferrors' => &$arrayoferrors,
'arrayofwarnings' => &$arrayofwarnings,
'nbok' => &$nbok,
);
$reshook = $hookmanager->executeHooks('ImportInsert', $parameters);
if ($reshook < 0) {
$arrayoferrors[$sourcelinenb][] = [
'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
];
}
if (empty($reshook)) {
// Run import
$result = $obj->import_insert($arrayrecord, $array_match_file_to_database, $objimport, count($fieldssource), $importid, $updatekeys);
if (count($obj->errors)) {
$arrayoferrors[$sourcelinenb] = $obj->errors;
}
if (count($obj->warnings)) {
$arrayofwarnings[$sourcelinenb] = $obj->warnings;
}
if (!count($obj->errors) && !count($obj->warnings)) {
$nbok++;
}
}
$reshook = $hookmanager->executeHooks('AfterImportInsert', $parameters);
if ($reshook < 0) {
$arrayoferrors[$sourcelinenb][] = [
'lib' => implode("<br>", array_merge([$hookmanager->error], $hookmanager->errors))
];
}
}
// Close file
$obj->import_close_file();
} else {
print $langs->trans("ErrorFailedToOpenFile", $pathfile);
}
if (count($arrayoferrors) > 0) {
$db->rollback(); // We force rollback because this was errors.
} else {
$error = 0;
// Run the sql after import if defined
//var_dump($objimport->array_import_run_sql_after[0]);
if (!empty($objimport->array_import_run_sql_after[0]) && is_array($objimport->array_import_run_sql_after[0])) {
$i = 0;
foreach ($objimport->array_import_run_sql_after[0] as $sqlafterimport) {
$i++;
$resqlafterimport = $db->query($sqlafterimport);
if (!$resqlafterimport) {
$arrayoferrors['none'][] = array('lib' => $langs->trans("Error running final request: ".$sqlafterimport));
$error++;
}
}
}
if (!$error) {
$db->commit(); // We can commit if no errors.
} else {
$db->rollback();
}
}
print dol_get_fiche_end();
// Show result
print '<br>';
print '<div class="info">';
print $langs->trans("NbOfLinesImported", $nbok).'</b><br>';
print $langs->trans("NbInsert", empty($obj->nbinsert) ? 0 : $obj->nbinsert).'<br>';
print $langs->trans("NbUpdate", empty($obj->nbupdate) ? 0 : $obj->nbupdate).'<br>';
print '</div>';
print '<div class="center">';
print $langs->trans("FileWasImported", $importid).'<br>';
print '<span class="opacitymedium">'.$langs->trans("YouCanUseImportIdToFindRecord", $importid).'</span><br>';
print '</div>';
}
print '<br>';
// End of page
llxFooter();
$db->close();
/**
* Function to put the movable box of a source field
*
* @param array $fieldssource List of source fields
* @param int $pos Pos
* @param string $key Key
* @return void
*/
function show_elem($fieldssource, $pos, $key)
{
global $conf, $langs;
$height = '32px';
if ($key == 'none') {
//stop multiple duplicate ids with no number
print "\n\n<!-- Box_no-key start-->\n";
print '<div class="box boximport" style="padding:0;">'."\n";
print '<table summary="boxtable_no-key" class="centpercent nobordernopadding">'."\n";
} else {
print "\n\n<!-- Box ".$pos." start -->\n";
print '<div class="box boximport" style="padding: 0;" id="boxto_'.$pos.'">'."\n";
print '<table summary="boxtable'.$pos.'" class="nobordernopadding centpercent tableimport">'."\n";
}
if (($pos && $pos > count($fieldssource)) && (!isset($fieldssource[$pos]["imported"]))) { // No fields
/*
print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
print '<td class="nocellnopadding" width="16" style="font-weight: normal">';
print '</td>';
print '<td style="font-weight: normal">';
print $langs->trans("NoFields");
print '</td>';
print '</tr>';
*/
} elseif ($key == 'none') { // Empty line
print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
print '<td class="nocellnopadding" width="16" style="font-weight: normal">';
print '&nbsp;';
print '</td>';
print '<td style="font-weight: normal">';
print '&nbsp;';
print '</td>';
print '</tr>';
} else {
// Print field of source file
print '<tr style="height:'.$height.'" class="trimport oddevenimport">';
print '<td class="nocellnopadding" width="16" style="font-weight: normal">';
// 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
//print img_picto($langs->trans("MoveField", $pos), 'grip_title', 'class="boxhandle" style="cursor:move;"');
print img_picto($langs->trans("Column").' '.num2Alpha($pos - 1), 'file', 'class="pictofixedwith"');
print '</td>';
if (isset($fieldssource[$pos]['imported']) && $fieldssource[$pos]['imported'] == false) {
print '<td class="nowraponall boxtdunused" style="font-weight: normal">';
} else {
print '<td class="nowraponall tdoverflowmax500" style="font-weight: normal">';
}
print $langs->trans("Column").' '.num2Alpha($pos - 1).' (#'.$pos.')';
if (empty($fieldssource[$pos]['example1'])) {
$example = $fieldssource[$pos]['label'];
} else {
$example = $fieldssource[$pos]['example1'];
}
if ($example) {
if (!utf8_check($example)) {
$example = mb_convert_encoding($example, 'UTF-8', 'ISO-8859-1');
}
// if (!empty($conf->dol_optimize_smallscreen)) { //print '<br>'; }
print ' - ';
print '<i class="opacitymedium">'.dol_escape_htmltag($example).'</i>';
}
print '</td>';
print '</tr>';
}
print "</table>\n";
print "</div>\n";
print "<!-- Box end -->\n\n";
}
/**
* Return not used field number
*
* @param array $fieldssource Array of field source
* @param array $listofkey Array of keys
* @return integer
*/
function getnewkey(&$fieldssource, &$listofkey)
{
$i = count($fieldssource) + 1;
// Max number of key
$maxkey = 0;
foreach ($listofkey as $key => $val) {
$maxkey = max($maxkey, $key);
}
// Found next empty key
while ($i <= $maxkey) {
if (empty($listofkey[$i])) {
break;
} else {
$i++;
}
}
$listofkey[$i] = 1;
return $i;
}
/**
* Return array with element inserted in it at position $position
*
* @param array $array Array of field source
* @param mixed $position key of position to insert to
* @param array $insertArray Array to insert
* @return array
*/
function arrayInsert($array, $position, $insertArray)
{
$ret = [];
if ($position == count($array)) {
$ret = $array + $insertArray;
} else {
$i = 0;
foreach ($array as $key => $value) {
if ($position == $i++) {
$ret += $insertArray;
}
$ret[$key] = $value;
}
}
return $ret;
}