2009-03-25 22:26:15 +01:00
< ? php
/* Copyright ( C ) 2006 - 2009 Laurent Destailleur < eldy @ users . sourceforge . net >
2010-03-17 14:33:56 +01:00
* Copyright ( C ) 2009 - 2010 Regis Houssin < regis @ dolibarr . fr >
2009-03-25 22:26:15 +01:00
*
* 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 2 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 , write to the Free Software
* Foundation , Inc . , 59 Temple Place - Suite 330 , Boston , MA 02111 - 1307 , USA .
* or see http :// www . gnu . org /
*/
/**
2009-10-04 00:32:10 +02:00
* \file htdocs / includes / modules / import / import_csv . modules . php
* \ingroup import
* \brief File to load import files with CSV format
2009-03-25 22:26:15 +01:00
* \author Laurent Destailleur
* \version $Id $
*/
require_once ( DOL_DOCUMENT_ROOT . " /includes/modules/import/modules_import.php " );
/**
* \class ImportCsv
* \brief Classe permettant de lire les fichiers imports CSV
*/
class ImportCsv extends ModeleImports
{
var $id ;
2009-10-13 19:23:26 +02:00
var $error ;
var $errors = array ();
2009-10-13 23:46:09 +02:00
2009-03-25 22:26:15 +01:00
var $label ;
var $extension ;
var $version ;
var $label_lib ;
var $version_lib ;
var $separator ;
2009-05-19 02:14:27 +02:00
2009-03-25 22:26:15 +01:00
var $handle ; // Handle fichier
2010-10-02 01:37:36 +02:00
var $cachefieldtable = array (); // Array to cache list of value into fields@tables
2009-05-19 02:14:27 +02:00
2009-03-25 22:26:15 +01:00
/**
* \brief Constructeur
* \param db Handler acces base de donnee
*/
function ImportCsv ( $db )
{
2010-07-11 13:08:55 +02:00
global $conf , $langs ;
2009-03-25 22:26:15 +01:00
$this -> db = $db ;
2009-09-27 23:28:52 +02:00
$this -> separator = ',' ;
2009-10-26 08:13:24 +01:00
if ( ! empty ( $conf -> global -> IMPORT_CSV_SEPARATOR_TO_USE )) $this -> separator = $conf -> global -> IMPORT_CSV_SEPARATOR_TO_USE ;
2009-10-03 01:07:31 +02:00
$this -> enclosure = '"' ;
2009-09-28 22:06:15 +02:00
$this -> escape = '"' ;
2009-09-27 23:28:52 +02:00
2009-03-25 22:26:15 +01:00
$this -> id = 'csv' ; // Same value then xxx in file name export_xxx.modules.php
2009-09-28 22:06:15 +02:00
$this -> label = 'Csv' ; // Label of driver
2010-07-11 13:08:55 +02:00
$this -> desc = $langs -> trans ( " CSVFormatDesc " , $this -> separator , $this -> enclosure , $this -> escape );
2009-03-25 22:26:15 +01:00
$this -> extension = 'csv' ; // Extension for generated file by this driver
2009-05-19 02:14:27 +02:00
$this -> picto = 'mime/other' ; // Picto
2009-10-20 15:14:44 +02:00
$ver = explode ( ' ' , '$Revision$' );
2009-03-25 22:26:15 +01:00
$this -> version = $ver [ 2 ]; // Driver version
// If driver use an external library, put its name here
2009-05-19 02:14:27 +02:00
$this -> label_lib = 'Dolibarr' ;
2009-03-25 22:26:15 +01:00
$this -> version_lib = DOL_VERSION ;
}
function getDriverId ()
{
return $this -> id ;
}
function getDriverLabel ()
{
return $this -> label ;
}
2009-09-28 22:06:15 +02:00
function getDriverDesc ()
{
return $this -> desc ;
}
2009-03-25 22:26:15 +01:00
function getDriverExtension ()
{
return $this -> extension ;
}
function getDriverVersion ()
{
return $this -> version ;
}
function getLibLabel ()
{
return $this -> label_lib ;
}
function getLibVersion ()
{
return $this -> version_lib ;
}
2009-09-08 01:49:16 +02:00
/**
2011-05-28 13:50:51 +02:00
* Output header of an example file for this format
* @ param outputlangs Output language
2009-09-08 01:49:16 +02:00
*/
function write_header_example ( $outputlangs )
{
return '' ;
}
/**
2011-05-28 13:50:51 +02:00
* Output title line of an example file for this format
* @ param outputlangs Output language
2009-09-08 01:49:16 +02:00
*/
function write_title_example ( $outputlangs , $headerlinefields )
{
2011-05-28 13:50:51 +02:00
$func = function ( $value ) {
return str_replace ( $this -> separator , '/' , $value );
};
$s .= join ( $this -> separator , array_map ( $headerlinefields ));
2009-09-08 01:49:16 +02:00
return $s . " \n " ;
}
/**
2011-05-28 13:50:51 +02:00
* Output record of an example file for this format
* @ param outputlangs Output language
2009-09-08 01:49:16 +02:00
*/
function write_record_example ( $outputlangs , $contentlinevalues )
{
2011-05-28 13:50:51 +02:00
$func = function ( $value ) {
return str_replace ( $this -> separator , '/' , $value );
};
$s = join ( $this -> separator , array_map ( $contentlinevalues ));
2009-09-08 01:49:16 +02:00
return $s . " \n " ;
}
/**
2011-05-28 13:50:51 +02:00
* Output footer of an example file for this format
* @ param outputlangs Output language
2009-09-08 01:49:16 +02:00
*/
function write_footer_example ( $outputlangs )
{
return '' ;
}
2009-03-25 22:26:15 +01:00
/**
2011-05-28 13:50:51 +02:00
* Open input file
* @ param file Path of filename
* @ return int < 0 if KO , >= 0 if OK
2009-03-25 22:26:15 +01:00
*/
2009-10-02 00:17:18 +02:00
function import_open_file ( $file )
2009-03-25 22:26:15 +01:00
{
global $langs ;
2009-10-04 20:01:30 +02:00
$ret = 1 ;
2009-05-19 02:14:27 +02:00
2009-03-25 22:26:15 +01:00
dol_syslog ( " ImportCsv::open_file file= " . $file );
2009-10-28 17:34:05 +01:00
ini_set ( 'auto_detect_line_endings' , 1 ); // For MAC compatibility
2009-10-04 20:01:30 +02:00
$newfile = utf8_check ( $file ) ? utf8_decode ( $file ) : $file ; // fopen need ISO file name
$this -> handle = fopen ( $newfile , " r " );
2009-03-25 22:26:15 +01:00
if ( ! $this -> handle )
{
$langs -> load ( " errors " );
$this -> error = $langs -> trans ( " ErrorFailToOpenFile " , $file );
$ret =- 1 ;
}
2009-10-03 01:07:31 +02:00
else
{
$this -> file = $file ;
}
2009-05-19 02:14:27 +02:00
2009-03-25 22:26:15 +01:00
return $ret ;
}
/**
2009-10-02 00:17:18 +02:00
* \brief Input header line from file
2009-03-25 22:26:15 +01:00
*/
2009-10-02 00:17:18 +02:00
function import_read_header ()
2009-03-25 22:26:15 +01:00
{
return 0 ;
}
/**
2009-10-04 00:32:10 +02:00
* \brief Return array of next record in input file .
* \return Array Array of field values . Data are UTF8 encoded .
2010-01-15 01:02:52 +01:00
* [ 0 ] => ([ 'val' ] => val , [ 'type' ] =>- 1 = null , 0 = blank , 1 = string )
2009-03-25 22:26:15 +01:00
*/
2009-10-03 01:07:31 +02:00
function import_read_record ()
2009-03-25 22:26:15 +01:00
{
global $conf ;
2009-10-03 01:07:31 +02:00
$arrayres = array ();
if ( version_compare ( phpversion (), '5.3' ) < 0 )
{
$arrayres = fgetcsv ( $this -> handle , 100000 , $this -> separator , $this -> enclosure );
}
else
{
$arrayres = fgetcsv ( $this -> handle , 100000 , $this -> separator , $this -> enclosure , $this -> escape );
}
2009-10-04 00:32:10 +02:00
//var_dump($this->handle);
2009-10-03 01:07:31 +02:00
//var_dump($arrayres);exit;
2009-10-04 00:32:10 +02:00
$newarrayres = array ();
2009-10-03 01:07:31 +02:00
if ( $arrayres && is_array ( $arrayres ))
2009-03-25 22:26:15 +01:00
{
2009-10-04 00:32:10 +02:00
foreach ( $arrayres as $key => $val )
{
if ( ! empty ( $conf -> global -> IMPORT_CSV_FORCE_CHARSET )) // Forced charset
{
2009-10-13 23:46:09 +02:00
if ( strtolower ( $conf -> global -> IMPORT_CSV_FORCE_CHARSET ) == 'utf8' )
2009-10-13 19:23:26 +02:00
{
$newarrayres [ $key ][ 'val' ] = $val ;
2010-08-24 16:42:18 +02:00
$newarrayres [ $key ][ 'type' ] = ( dol_strlen ( $val ) ? 1 :- 1 ); // If empty we considere it's null
2009-10-13 19:23:26 +02:00
}
else
{
$newarrayres [ $key ][ 'val' ] = utf8_encode ( $val );
2010-08-24 16:42:18 +02:00
$newarrayres [ $key ][ 'type' ] = ( dol_strlen ( $val ) ? 1 :- 1 ); // If empty we considere it's null
2009-10-13 19:23:26 +02:00
}
2009-10-04 00:32:10 +02:00
}
else // Autodetect format (UTF8 or ISO)
{
2009-10-13 23:46:09 +02:00
if ( utf8_check ( $val ))
2009-10-13 19:23:26 +02:00
{
$newarrayres [ $key ][ 'val' ] = $val ;
2010-08-24 16:42:18 +02:00
$newarrayres [ $key ][ 'type' ] = ( dol_strlen ( $val ) ? 1 :- 1 ); // If empty we considere it's null
2009-10-13 19:23:26 +02:00
}
2009-10-13 23:46:09 +02:00
else
2009-10-13 19:23:26 +02:00
{
$newarrayres [ $key ][ 'val' ] = utf8_encode ( $val );
2010-08-24 16:42:18 +02:00
$newarrayres [ $key ][ 'type' ] = ( dol_strlen ( $val ) ? 1 :- 1 ); // If empty we considere it's null
2009-10-13 19:23:26 +02:00
}
2009-10-04 00:32:10 +02:00
}
}
$this -> col = sizeof ( $newarrayres );
2009-10-03 01:07:31 +02:00
}
2009-05-19 02:14:27 +02:00
2009-10-04 00:32:10 +02:00
return $newarrayres ;
2009-03-25 22:26:15 +01:00
}
/**
* \brief Close file handle
*/
2009-10-02 00:17:18 +02:00
function import_close_file ()
2009-03-25 22:26:15 +01:00
{
fclose ( $this -> handle );
return 0 ;
}
2009-10-02 00:17:18 +02:00
2009-03-25 22:26:15 +01:00
/**
2009-10-04 00:32:10 +02:00
* Insert a record into database
* @ param arrayrecord Array of field values
* @ param array_match_file_to_database
* @ param objimport
2009-10-13 19:23:26 +02:00
* @ param maxfields Max number of fiels to use
2009-10-04 00:32:10 +02:00
* @ return int < 0 if KO , > 0 if OK
2009-03-25 22:26:15 +01:00
*/
2009-10-13 23:46:09 +02:00
function import_insert ( $arrayrecord , $array_match_file_to_database , $objimport , $maxfields , $importid )
2009-03-25 22:26:15 +01:00
{
2009-10-17 15:12:55 +02:00
global $langs , $conf , $user ;
2009-10-15 17:15:38 +02:00
2009-10-04 00:32:10 +02:00
$error = 0 ;
2009-10-13 19:23:26 +02:00
$warning = 0 ;
$this -> errors = array ();
$this -> warnings = array ();
2009-10-13 23:46:09 +02:00
//dol_syslog("import_csv.modules maxfields=".$maxfields." importid=".$importid);
//var_dump($array_match_file_to_database);
//var_dump($arrayrecord);
2009-11-09 23:10:39 +01:00
$array_match_database_to_file = array_flip ( $array_match_file_to_database );
2009-10-13 19:23:26 +02:00
$sort_array_match_file_to_database = $array_match_file_to_database ;
ksort ( $sort_array_match_file_to_database );
2009-11-09 23:10:39 +01:00
2009-10-13 19:23:26 +02:00
//var_dump($sort_array_match_file_to_database);
if ( sizeof ( $arrayrecord ) == 0 ||
( sizeof ( $arrayrecord ) == 1 && empty ( $arrayrecord [ 0 ][ 'val' ])))
2009-03-25 22:26:15 +01:00
{
2009-10-15 01:44:25 +02:00
//print 'W';
$this -> warnings [ $warning ][ 'lib' ] = $langs -> trans ( 'EmptyLine' );
2009-10-13 19:23:26 +02:00
$this -> warnings [ $warning ][ 'type' ] = 'EMPTY' ;
$warning ++ ;
}
else
{
// For each table to insert, me make a separate insert
2009-10-17 15:12:55 +02:00
foreach ( $objimport -> array_import_tables [ 0 ] as $alias => $tablename )
2009-10-04 00:32:10 +02:00
{
2009-10-13 19:23:26 +02:00
// Build sql request
$sql = '' ;
$listfields = '' ;
$listvalues = '' ;
$i = 0 ;
$errorforthistable = 0 ;
2009-11-09 23:10:39 +01:00
// Loop on each fields in the match array ($key = 1..n, $val=alias of field)
2009-10-13 19:23:26 +02:00
foreach ( $sort_array_match_file_to_database as $key => $val )
2009-10-04 00:32:10 +02:00
{
2009-10-13 19:23:26 +02:00
if ( $key <= $maxfields )
{
if ( $listfields ) { $listfields .= ', ' ; $listvalues .= ', ' ; }
2009-10-21 15:09:42 +02:00
$listfields .= preg_replace ( '/^.*\./i' , '' , $val );
2009-10-13 19:23:26 +02:00
$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' ];
2010-10-02 01:37:36 +02:00
$listvalues .= " ' " . $this -> db -> escape ( $arrayrecord [( $key - 1 )][ 'val' ]) . " ' " ;
2009-10-13 19:23:26 +02:00
}
2009-10-13 23:46:09 +02:00
2009-10-13 19:23:26 +02:00
// Make some tests
2009-10-13 23:46:09 +02:00
2009-10-13 19:23:26 +02:00
// Required field is ok
2009-10-22 17:09:04 +02:00
if ( preg_match ( '/\*/' , $objimport -> array_import_fields [ 0 ][ $val ]) && ( $newval == '' ))
2009-10-13 19:23:26 +02:00
{
2009-10-15 01:44:25 +02:00
$this -> errors [ $error ][ 'lib' ] = $langs -> trans ( 'ErrorMissingMandatoryValue' , $key );
2009-10-13 19:23:26 +02:00
$this -> errors [ $error ][ 'type' ] = 'NOTNULL' ;
$errorforthistable ++ ;
$error ++ ;
}
2009-10-17 15:12:55 +02:00
// Test format only if field is not a missing mandatory field
else {
2010-10-02 01:37:36 +02:00
if ( ! empty ( $objimport -> array_import_regex [ 0 ][ $val ]))
2009-10-17 15:12:55 +02:00
{
2010-10-02 01:37:36 +02:00
// If test is "Must exist in a field@table"
if ( preg_match ( '/^(.*)@(.*)$/' , $objimport -> array_import_regex [ 0 ][ $val ], $reg ))
{
$field = $reg [ 1 ];
$table = $reg [ 2 ];
if ( ! is_array ( $this -> cachefieldtable [ $field . '@' . $table ])) // If content of field@table no already loaded into cache
{
$sql = " SELECT " . $field . " as aliasfield FROM " . $table ;
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
$num = $this -> db -> num_rows ( $resql );
$i = 0 ;
while ( $i < $num )
{
$obj = $this -> db -> fetch_object ( $resql );
if ( $obj ) $this -> cachefieldtable [ $field . '@' . $table ][] = $obj -> aliasfield ;
$i ++ ;
}
}
else
{
dol_print_error ( $this -> db );
}
}
// Now we check in cache
if ( ! in_array ( $newval , $this -> cachefieldtable [ $field . '@' . $table ]))
{
$this -> errors [ $error ][ 'lib' ] = $langs -> trans ( 'ErrorFieldValueNotIn' , $key , $newval , $field , $table );
$this -> errors [ $error ][ 'type' ] = 'FOREIGNKEY' ;
$error ++ ;
}
}
// If test is just a static regex
else if ( ! preg_match ( '/' . $objimport -> array_import_regex [ 0 ][ $val ] . '/i' , $newval ))
{
$this -> errors [ $error ][ 'lib' ] = $langs -> trans ( 'ErrorWrongValueForField' , $key , $newval , $objimport -> array_import_regex [ 0 ][ $val ]);
$this -> errors [ $error ][ 'type' ] = 'REGEX' ;
$errorforthistable ++ ;
$error ++ ;
}
2009-10-17 15:12:55 +02:00
}
2009-10-13 23:46:09 +02:00
2010-10-02 01:37:36 +02:00
// Other tests
// ...
2009-10-17 15:12:55 +02:00
}
2009-10-13 19:23:26 +02:00
}
$i ++ ;
2009-10-04 00:32:10 +02:00
}
2010-01-15 01:02:52 +01:00
//print $listvalues;
2009-11-09 23:10:39 +01:00
2009-10-13 19:23:26 +02:00
if ( ! $errorforthistable )
2009-10-04 00:32:10 +02:00
{
2009-10-13 19:23:26 +02:00
if ( $listfields )
{
2009-11-09 23:10:39 +01:00
// If some values need to be found somewhere else than in source file: Case we need a rowid found from a fetch on a reference.
2009-11-08 20:28:44 +01:00
// This is used when insert must be done when a parent row already exists
2009-11-09 09:48:05 +01:00
// $objimport->array_import_convertvalue=array('s.fk_soc'=>array('rule'=>'fetchfromref',file='/societe.class.php','class'=>'Societe','method'=>'fetch'));
2009-11-09 23:10:39 +01:00
foreach ( $objimport -> array_import_convertvalue as $alias => $rulearray )
{
if ( empty ( $rulearray [ 'rule' ]) || $rulearray [ 'rule' ] != 'fetchfromref' ) continue ;
dol_syslog ( " We need to get rowid from ref= " . $alias . " using value found in column " . $array_match_database_to_file . " in source file, so " . $arrayrecord [ $array_match_database_to_file ][ 'val' ]);
}
2009-11-08 20:28:44 +01:00
2009-11-09 23:10:39 +01:00
// If some values need to be found somewhere else than in source file: Case we need lastinsert id from previous insert
2009-11-08 20:28:44 +01:00
// This is used when insert must be done in several tables
2009-11-09 09:48:05 +01:00
// $objimport->array_import_convertvalue=array('s.fk_soc'=>array('rule'=>'lastrowid',table='t');
2009-11-08 20:28:44 +01:00
// TODO
2009-10-17 15:12:55 +02:00
// Build SQL request
$sql = 'INSERT INTO ' . $tablename . '(' . $listfields . ', import_key' ;
if ( ! empty ( $objimport -> array_import_tables_creator [ 0 ][ $alias ])) $sql .= ', ' . $objimport -> array_import_tables_creator [ 0 ][ $alias ];
$sql .= ') VALUES(' . $listvalues . " , ' " . $importid . " ' " ;
if ( ! empty ( $objimport -> array_import_tables_creator [ 0 ][ $alias ])) $sql .= ', ' . $user -> id ;
$sql .= ')' ;
2009-10-13 19:23:26 +02:00
dol_syslog ( " import_csv.modules sql= " . $sql );
2009-10-13 23:46:09 +02:00
2009-10-13 19:23:26 +02:00
//print '> '.join(',',$arrayrecord);
//print 'sql='.$sql;
//print '<br>'."\n";
2009-10-13 23:46:09 +02:00
2009-10-13 19:23:26 +02:00
// Run insert request
if ( $sql )
{
$resql = $this -> db -> query ( $sql );
if ( $resql )
{
2009-10-15 01:44:25 +02:00
//print '.';
2009-10-13 19:23:26 +02:00
}
else
{
2009-10-15 01:44:25 +02:00
//print 'E';
$this -> errors [ $error ][ 'lib' ] = $this -> db -> lasterror ();
2009-10-13 19:23:26 +02:00
$this -> errors [ $error ][ 'type' ] = 'SQL' ;
$error ++ ;
}
}
}
else
{
dol_print_error ( 'Ne doit pas arriver AAA' );
}
2009-10-04 00:32:10 +02:00
}
}
2009-03-25 22:26:15 +01:00
}
2009-10-13 23:46:09 +02:00
2009-10-13 19:23:26 +02:00
return 1 ;
2009-10-04 00:32:10 +02:00
}
2009-05-19 02:14:27 +02:00
2009-03-25 22:26:15 +01:00
}
?>