diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index fe4edd12cb505022705f7321eb04f27149b9dceb..66e3dc4269d8a910fdbc6ac059bbf4016721b5c3 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -506,6 +506,8 @@ if ($step == 3 && $datatoimport) print '<td>'; $text=$objmodelimport->getDriverDesc($format); print $html->textwithpicto($objmodelimport->getDriverLabel($format),$text); + print '</td><td align="right" nowrap="nowrap" width="100"><a href="'.DOL_URL_ROOT.'/imports/emptyexample.php?format='.$key.'&datatoimport='.$datatoimport.'" target="_blank">'.$langs->trans("DownloadEmptyExample").'</a>'; + print '</td></tr>'; print '</table>'; @@ -559,7 +561,14 @@ if ($step == 3 && $datatoimport) $var=!$var; print '<tr '.$bc[$var].'>'; print '<td width="16">'.img_mime($file).'</td>'; - print '<td>'.$file.'</td>'; + print '<td>'; + $param='format='.$format.'&datatoimport='.$datatoimport; + $modulepart='import'; + //$relativepath=$filetoimport; + print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=3&format='.$format.'&datatoimport='.$datatoimport.'" target="_blank">'; + print $file; + print '</a>'; + print '</td>'; // Affiche taille fichier print '<td align="right">'.dol_print_size(dol_filesize($newdir.'/'.$newfile)).'</td>'; // Affiche date fichier @@ -610,7 +619,7 @@ if ($step == 4 && $datatoimport) $i=1; foreach($arrayrecord as $key => $val) { - $fieldssource[$i]['example1']=dol_trunc($val,24); + $fieldssource[$i]['example1']=dol_trunc($val['val'],24); $i++; } $obj->import_close_file(); @@ -717,14 +726,21 @@ if ($step == 4 && $datatoimport) // File to import print '<tr><td width="25%">'.$langs->trans("FileToImport").'</td>'; - print '<td>'.$filetoimport.'</td></tr>'; + print '<td>'; + $param='format='.$format.'&datatoimport='.$datatoimport; + $modulepart='import'; + //$relativepath=$filetoimport; + print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&file='.urlencode($relativepath).'&step=4&format='.$format.'&datatoimport='.$datatoimport.'" target="_blank">'; + print $filetoimport; + print '</a>'; + print '</td></tr>'; print '</table>'; print '<br>'."\n"; - // List of import models - print '<!-- List of import models -->'."\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="'.$_SESSION['newtoken'].'">'; print '<input type="hidden" name="action" value="select_model">'; @@ -1047,7 +1063,7 @@ if ($step == 5 && $datatoimport) $i=1; foreach($arrayrecord as $key => $val) { - $fieldssource[$i]['example1']=dol_trunc($val,24); + $fieldssource[$i]['example1']=dol_trunc($val['val'],24); $i++; } $obj->import_close_file(); @@ -1092,7 +1108,7 @@ if ($step == 5 && $datatoimport) print '</td></tr>'; // Lot de donnees a importer - print '<tr><td width="25%">'.$langs->trans("DatasetToImport").'</td>'; + print '<tr><td>'.$langs->trans("DatasetToImport").'</td>'; print '<td>'; print img_object($objimport->array_import_module[0]->getName(),$objimport->array_import_icon[0]).' '; print $objimport->array_import_label[0]; @@ -1104,7 +1120,7 @@ if ($step == 5 && $datatoimport) //print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnSourceFile").'</b></td></tr>'; // Source file format - print '<tr><td width="40%">'.$langs->trans("SourceFileFormat").'</td>'; + print '<tr><td width="25%">'.$langs->trans("SourceFileFormat").'</td>'; print '<td>'; $text=$objmodelimport->getDriverDesc($format); print $html->textwithpicto($objmodelimport->getDriverLabel($format),$text); @@ -1112,7 +1128,13 @@ if ($step == 5 && $datatoimport) // File to import print '<tr><td>'.$langs->trans("FileToImport").'</td>'; - print '<td>'.$filetoimport.'</td></tr>'; + print '<td>'; + $modulepart='import'; + //$relativepath=$filetoimport; + print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&step=4'.$param.'" target="_blank">'; + print $filetoimport; + print '</a>'; + print '</td></tr>'; // Nb of fields print '<tr><td>'; @@ -1135,10 +1157,11 @@ if ($step == 5 && $datatoimport) //print '<tr><td colspan="2"><b>'.$langs->trans("InformationOnTargetTables").'</b></td></tr>'; // Tables imported - print '<tr><td width="40%">'; + print '<tr><td width="25%">'; 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); @@ -1150,6 +1173,7 @@ if ($step == 5 && $datatoimport) if (sizeof($listtables)) { $newval=''; + //ksort($listtables); foreach ($listtables as $val) { if ($newval) print ', '; @@ -1177,8 +1201,10 @@ if ($step == 5 && $datatoimport) $listfields=array(); $i=0; //print 'fieldsource='.$fieldssource; - //var_dump($array_match_file_to_database); - foreach($array_match_file_to_database as $code=>$label) + $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); @@ -1202,7 +1228,7 @@ if ($step == 5 && $datatoimport) print '<center>'; if ($user->rights->import->run) { - print '<a class="butAction" href="'.DOL_URL_ROOT.'/imports/import.php?leftmenu=import&step=6&'.$param.'">'.$langs->trans("RunSimulateImportFile").'</a>'; + print '<a class="butAction" href="'.DOL_URL_ROOT.'/imports/import.php?leftmenu=import&step=6'.$param.'">'.$langs->trans("RunSimulateImportFile").'</a>'; } else { @@ -1243,7 +1269,7 @@ if ($step == 6 && $datatoimport) $i=1; foreach($arrayrecord as $key => $val) { - $fieldssource[$i]['example1']=dol_trunc($val,24); + $fieldssource[$i]['example1']=dol_trunc($val['val'],24); $i++; } $obj->import_close_file(); @@ -1312,7 +1338,13 @@ if ($step == 6 && $datatoimport) // File to import print '<tr><td>'.$langs->trans("FileToImport").'</td>'; - print '<td>'.$filetoimport.'</td></tr>'; + print '<td>'; + $modulepart='import'; + //$relativepath=$filetoimport; + print '<a href="'.DOL_URL_ROOT.'/document.php?modulepart='.$modulepart.'&step=4'.$param.'" target="_blank">'; + print $filetoimport; + print '</a>'; + print '</td></tr>'; // Nb of fields print '<tr><td>'; @@ -1376,7 +1408,10 @@ if ($step == 6 && $datatoimport) print $langs->trans("FieldsTarget").'</td><td>'; $listfields=array(); $i=0; - foreach($array_match_file_to_database as $code=>$label) + $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); @@ -1393,33 +1428,59 @@ if ($step == 6 && $datatoimport) print '<br>'; // Launch import - $arrayofresult=array(); + $arrayoferrors=array(); + $arrayofwarnings=array(); + $maxnboferrors=empty($conf->global->IMPORT_MAX_NB_OF_ERRORS)?100:$conf->global->IMPORT_MAX_NB_OF_ERRORS; + $maxnbofwarnings=empty($conf->global->IMPORT_MAX_NB_OF_WARNINGS)?100:$conf->global->IMPORT_MAX_NB_OF_WARNINGS; + $nboferrors=0; + $nbofwarnings=0; + $db->begin(); + //var_dump($array_match_file_to_database); + // Open input file - $result=$obj->import_open_file($conf->import->dir_temp.'/'.$filetoimport,$langs); + $pathfile=$conf->import->dir_temp.'/'.$filetoimport; + $result=$obj->import_open_file($pathfile,$langs); if ($result > 0) { - $i=1; + $sourcelinenb=0; // Loop on each input file record while ($arrayrecord=$obj->import_read_record()) { - $i++; - $result=$obj->import_insert($arrayrecord,$array_match_file_to_database,$objimport); - $arrayofresult[$result]++; + $sourcelinenb++; + $result=$obj->import_insert($arrayrecord,$array_match_file_to_database,$objimport,sizeof($fieldssource)); + if (sizeof($obj->errors)) + { + $arrayoferrors[$sourcelinenb]=$obj->errors; + } + if (sizeof($obj->warnings)) + { + $arrayofwarnings[$sourcelinenb]=$obj->warnings; + } } // Close file $obj->import_close_file(); } + else + { + print $langs->trans("ErrorFailedToOpenFile",$pathfile); + } $db->rollback(); // We force rollback because this was just a simulation. + var_dump($arrayoferrors); + // Print result $arrayoferrors + foreach ($arrayoferrors as $key => $val) + { + //print $langs->trans("Result".$key)." ".$arrayofresult[$key].'<br>'; + } - // Print $arrayofresult - // TODO - + $importid=dol_print_date(dol_now('tzserver'),'%Y%m%d%H%M%S'); + print '<br>'; print $langs->trans("NowClickToRunTheImport",$langs->transnoentitiesnoconv("RunImportFile")).'<br>'; + print $langs->trans("DataLoadedWithId",$importid).'<br>'; print '</div>'; @@ -1460,7 +1521,7 @@ function show_elem($fieldssource,$i,$pos,$key,$var,$nostyle='') print '<div style="padding: 0px 0px 0px 0px;" id="boxto_'.$pos.'">'."\n"; print '<table summary="boxtable'.$pos.'" width="100%" class="nobordernopadding">'."\n"; - if ($pos && $pos > sizeof($fieldssource)) // NoFields + if ($pos && $pos > sizeof($fieldssource)) // No fields { print '<tr '.($nostyle?'':$bc[$var]).' height="20">'; print '<td class="nocellnopadding" width="16" style="font-weight: normal">'; @@ -1471,7 +1532,7 @@ function show_elem($fieldssource,$i,$pos,$key,$var,$nostyle='') print '</td>'; print '</tr>'; } - elseif ($key == 'none') + elseif ($key == 'none') // Empty line { print '<tr '.($nostyle?'':$bc[$var]).' height="20">'; print '<td class="nocellnopadding" width="16" style="font-weight: normal">'; @@ -1492,7 +1553,7 @@ function show_elem($fieldssource,$i,$pos,$key,$var,$nostyle='') print '</td>'; print '<td style="font-weight: normal">'; print $langs->trans("Field").' '.$pos; - if (! empty($fieldssource[$pos]['example1'])) print ' (<i>'.$fieldssource[$pos]['example1'].'</i>)'; + if (! empty($fieldssource[$pos]['example1'])) print ' (<i>'.htmlentities($fieldssource[$pos]['example1']).'</i>)'; print '</td>'; print '</tr>'; } diff --git a/htdocs/includes/modules/import/import_csv.modules.php b/htdocs/includes/modules/import/import_csv.modules.php index 83c878fa90ba3d27ea6009f631008e58900897c8..fa482c093dbbc07f8c4c5c0864c36341a6b7fab5 100644 --- a/htdocs/includes/modules/import/import_csv.modules.php +++ b/htdocs/includes/modules/import/import_csv.modules.php @@ -35,6 +35,9 @@ require_once(DOL_DOCUMENT_ROOT ."/includes/modules/import/modules_import.php"); class ImportCsv extends ModeleImports { var $id; + var $error; + var $errors=array(); + var $label; var $extension; var $version; @@ -192,6 +195,7 @@ class ImportCsv extends ModeleImports /** * \brief Return array of next record in input file. * \return Array Array of field values. Data are UTF8 encoded. + * [0]=>(['val']=>val,['type']=>-1=null,0=blank,1=string) */ function import_read_record() { @@ -216,13 +220,29 @@ class ImportCsv extends ModeleImports { if (! empty($conf->global->IMPORT_CSV_FORCE_CHARSET)) // Forced charset { - if (strtolower($conf->global->IMPORT_CSV_FORCE_CHARSET) == 'utf8') $newarrayres[$key]=$val; - else $newarrayres[$key]=utf8_encode($val); + if (strtolower($conf->global->IMPORT_CSV_FORCE_CHARSET) == 'utf8') + { + $newarrayres[$key]['val']=$val; + $newarrayres[$key]['type']=1; + } + else + { + $newarrayres[$key]['val']=utf8_encode($val); + $newarrayres[$key]['type']=1; + } } else // Autodetect format (UTF8 or ISO) { - if (utf8_check($val)) $newarrayres[$key]=$val; - else $newarrayres[$key]=utf8_encode($val); + if (utf8_check($val)) + { + $newarrayres[$key]['val']=$val; + $newarrayres[$key]['type']=1; + } + else + { + $newarrayres[$key]['val']=utf8_encode($val); + $newarrayres[$key]['type']=1; + } } } @@ -247,52 +267,120 @@ class ImportCsv extends ModeleImports * @param arrayrecord Array of field values * @param array_match_file_to_database * @param objimport + * @param maxfields Max number of fiels to use * @return int <0 if KO, >0 if OK */ - function import_insert($arrayrecord,$array_match_file_to_database,$objimport) + function import_insert($arrayrecord,$array_match_file_to_database,$objimport,$maxfields) { $error=0; - - // For each table to insert, me make a separate insert - foreach($objimport->array_import_tables[0] as $alias=>$tablename) + $warning=0; + $this->errors=array(); + $this->warnings=array(); + + dol_syslog("import_csv.modules maxfields=".$maxfields); + //print "X".$maxfields; + + var_dump($array_match_file_to_database); + var_dump($arrayrecord); + $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); + + if (sizeof($arrayrecord) == 0 || + (sizeof($arrayrecord) == 1 && empty($arrayrecord[0]['val']))) { - // Build sql request - $sql=''; - $listfields=''; - $listvalues=''; - foreach($array_match_file_to_database as $key => $val) - { - if ($listfields) { $listfields.=', '; $listvalues.=', '; } - $listfields.=$val; - $listvalues.='ee'; - } - if ($listfields) - { - $sql='INSERT INTO '.$tablename.'('.$listfields.') VALUES('.$listvalues.')'; - } - - //print '> '.join(',',$arrayrecord); - print 'sql='.$sql; - print '<br>'."\n"; - - // Run insert request - if ($sql) + print 'W'; + $this->warnings[$warning]['lib']='Empty line'; + $this->warnings[$warning]['type']='EMPTY'; + $warning++; + } + else + { + // For each table to insert, me make a separate insert + foreach($objimport->array_import_tables[0] as $alias=>$tablename) { - $resql=$this->db->query($sql); - if ($resql) + // Build sql request + $sql=''; + $listfields=''; + $listvalues=''; + $i=0; + $errorforthistable=0; + foreach($sort_array_match_file_to_database as $key => $val) { - print '.'; + if ($key <= $maxfields) + { + if ($listfields) { $listfields.=', '; $listvalues.=', '; } + $listfields.=$val; + $newval=''; + if ($arrayrecord[($key-1)]['type'] < 0) + { + $listvalues.="null"; + } + else if ($arrayrecord[($key-1)]['type'] == 0) + { + $listvalues.="''"; + } + else if ($arrayrecord[($key-1)]['type'] > 0) + { + $newval=$arrayrecord[($key-1)]['val']; + $listvalues.="'".$arrayrecord[($key-1)]['val']."'"; + } + + // Make some tests + + // Required field is ok + if (eregi('\*',$objimport->array_import_fields[0][$val]) && empty($newval)) + { + $this->errors[$error]['lib']='ErrorMissingMandatoryValue field nb '.$key.' target='.$val; + $this->errors[$error]['type']='NOTNULL'; + $errorforthistable++; + $error++; + } + // Test format + + // Other tests + // ... + + } + $i++; } - else + if (! $errorforthistable) { - print 'E'; - $this->error=$this->db->lasterror(); - $error++; + if ($listfields) + { + $sql='INSERT INTO '.$tablename.'('.$listfields.') VALUES('.$listvalues.')'; + dol_syslog("import_csv.modules sql=".$sql); + + //print '> '.join(',',$arrayrecord); + //print 'sql='.$sql; + //print '<br>'."\n"; + + // Run insert request + if ($sql) + { + $resql=$this->db->query($sql); + if ($resql) + { + print '.'; + } + else + { + print 'E'; + $this->errors[$error]['lib']='ErrorSQL '.$this->db->lasterror(); + $this->errors[$error]['type']='SQL'; + $error++; + } + } + } + else + { + dol_print_error('Ne doit pas arriver AAA'); + } } } } - - return $error?-$error:1; + + return 1; } } diff --git a/htdocs/langs/en_US/exports.lang b/htdocs/langs/en_US/exports.lang index 02b77f3d188e8977ad7db9d6b3cf99ef39a7bec6..f7a6d16e4c8c6120d862c516905b8641a0750343 100644 --- a/htdocs/langs/en_US/exports.lang +++ b/htdocs/langs/en_US/exports.lang @@ -9,7 +9,7 @@ ImportableDatas=Importable dataset SelectExportDataSet=Choose dataset you want to export... SelectImportDataSet=Choose dataset you want to import... SelectExportFields=Choose fields you want to export, or select a predefined export profil -SelectImportFields=Choose source file fields you want to import and their target field in database by moving them up and down with anchor %s,<br>or select a predefined import profil: +SelectImportFields=Choose source file fields you want to import and their target field in database by moving them up and down with anchor %s, or select a predefined import profil: NotImportedFields=Fields of source file not imported SaveExportModel=Save this export profile if you plan to reuse it later... SaveImportModel=Save this import profile if you plan to reuse it later... @@ -81,4 +81,8 @@ FieldNeedSource=This fiels in database require a data from source file SomeMandatoryFieldHaveNoSource=Some mandatory fields have no source from data file InformationOnSourceFile=Informations on source file InformationOnTargetTables=Informations on target fields -SelectAtLeastOneField=Switch at least one source field in the column of fields to export \ No newline at end of file +SelectAtLeastOneField=Switch at least one source field in the column of fields to export +SelectFormat=Choose this import file format +RunImportFile=Launch import file +NowClickToRunTheImport=Check result of import simulation. If everything is ok, launch the definitive import. +DataLoadedWithId=All data will be loaded with the following import id: <b>%s<b> diff --git a/htdocs/langs/fr_FR/exports.lang b/htdocs/langs/fr_FR/exports.lang index 8e94647a617b7e8c0e42ff3446cc610b7b1ebd57..4e3df02047d1c9afd64b7b0d24cac36f4563c484 100644 --- a/htdocs/langs/fr_FR/exports.lang +++ b/htdocs/langs/fr_FR/exports.lang @@ -81,4 +81,8 @@ FieldNeedSource=Ce champ en base requiert obligatoirement une donnée source SomeMandatoryFieldHaveNoSource=Certains champs obligatoires n'ont pas de champ source issus du fichier InformationOnSourceFile=Informations sur le fichier source InformationOnTargetTables=Informations sur les champs cibles -SelectAtLeastOneField=Basculer au moins un champ source dans la colonne des champs à exporter \ No newline at end of file +SelectAtLeastOneField=Basculer au moins un champ source dans la colonne des champs à exporter +SelectFormat=Choisir ce format de fichier import +RunImportFile=Lancer l'import en base +NowClickToRunTheImport=Vérifiez le résultat de la simulation. Si tout est ok, lancer l'import définitif en base. +DataLoadedWithId=Toutes les données seront importées avec l'id d'import suivant: <b>%s</b> \ No newline at end of file diff --git a/htdocs/lib/functions.lib.php b/htdocs/lib/functions.lib.php index cd176e324c6bc9fc33935afc29d94f01b372dd55..f72089e7144ca75b4086d9b21896fd8c6d7e7e41 100644 --- a/htdocs/lib/functions.lib.php +++ b/htdocs/lib/functions.lib.php @@ -2641,8 +2641,9 @@ function dol_nl2br($stringtoencode,$nl2brmode=0) } /** - * \brief This function is called to encode a string into a HTML string. - * All entities except &,<,> are converted. This permits to encode special chars to entities with no double encoded for already encoded HTML strings. + * \brief This function is called to encode a string into a HTML string but differs from htmlentities because + * all entities but &,<,> are converted. This permits to encode special chars to entities with no double + * encoding for already encoded HTML strings. * This function also remove last CR/BR. * \param stringtoencode String to encode * \param nl2brmode 0=Adding br before \n, 1=Replacing \n by br (for use with FPDF writeHTMLCell function for example)