diff --git a/addressbook/csv_import.php b/addressbook/csv_import.php index 4091409d94..c80c1dd77f 100644 --- a/addressbook/csv_import.php +++ b/addressbook/csv_import.php @@ -42,7 +42,7 @@ if (isset($_POST['charset'])) $GLOBALS['egw_info']['flags']['app_header'] = lang('Import CSV-File into Addressbook'); $GLOBALS['egw']->common->egw_header(); -$GLOBALS['egw']->contacts = new contacts(); +$bocontacts = new addressbook_bo(); //$GLOBALS['egw']->template->set_unknowns('keep'); $GLOBALS['egw']->template->set_file(array('import' => 'csv_import.tpl')); @@ -64,24 +64,30 @@ $VPre = '|#'; // Value-Prefix, is expanded to \ for ereg_replace $CPre = '|['; $CPreReg = '\|\['; // |{csv-fieldname} is expanded to the value of the csv-field $CPos = ']'; $CPosReg = '\]'; // if used together with @ (replacement is eval-ed) value gets autom. quoted -// find in Addressbook, at least n_family AND (n_given OR org_name) have to match +/** + * Find contact with at least n_family AND (n_given OR org_name) have to match + * + * @param string $n_family + * @param string $n_given + * @param string $org_name + * @return int|boolean contact id or false if no match + */ function addr_id($n_family,$n_given,$org_name) { - $addrs = $GLOBALS['egw']->contacts->search(array('n_family'=>$n_family,'n_given'=>$n_given,'org_name'=>$org_name)); + global $bocontacts; + $addrs = $bocontacts->search(array('n_family'=>$n_family,'n_given'=>$n_given,'org_name'=>$org_name)); if(!count($addrs)) { - $addrs = $GLOBALS['egw']->contacts->search(array('n_family'=>$n_family,'n_given'=>$n_given)); + $addrs = $bocontacts->search(array('n_family'=>$n_family,'n_given'=>$n_given)); } if(!count($addrs)) { - $addrs = $GLOBALS['egw']->contacts->search(array('n_family'=>$n_family,'org_name'=>$org_name)); + $addrs = $bocontacts->search(array('n_family'=>$n_family,'org_name'=>$org_name)); } - if(count($addrs)) { return $addrs[0]['id']; } - return False; } @@ -131,6 +137,8 @@ switch($_POST['action']) case 'continue': case 'download': $defaults = $GLOBALS['egw_info']['user']['preferences']['addressbook']['cvs_import']; + if (!($unique_id = $GLOBALS['egw_info']['user']['preferences']['addressbook']['cvs_import_unique_id'])) $unique_id = 'id'; + if (!($unique_id2 = $GLOBALS['egw_info']['user']['preferences']['addressbook']['cvs_import_unique_id2'])) $unique_id2 = 'uid'; if(!is_array($defaults)) { $defaults = array(); @@ -144,16 +152,17 @@ switch($_POST['action']) $GLOBALS['egw']->template->set_var('lang_debug',lang('Test Import (show importable records only in browser)')); $GLOBALS['egw']->template->parse('fheaderhandle','fheader'); - $addr_names = $GLOBALS['egw']->contacts->contact_fields; + $addr_names = $bocontacts->contact_fields; $addr_names['cat_id'] .= ': id or name, comma separated list'; $addr_names['private'] .= ': 0 = public, 1 = private'; $addr_names['owner'] .= ': id or account name of user or group, defaults to importing user'; $addr_names['bday'] .= ': YYYY-mm-dd'; + $addr_names['uid'] = lang('Unique ID (UID)'); unset($addr_names['jpegphoto']); // cant cvs import that - foreach($GLOBALS['egw']->contacts->customfields as $name => $data) + foreach($bocontacts->customfields as $name => $data) { - $addr_names['#'.$name] = $data['label']; + $cfs['#'.$name] = $addr_names['#'.$name] = $data['label']; } $addr_name_options = "none\n"; foreach($addr_names as $field => $name) @@ -182,6 +191,17 @@ switch($_POST['action']) } $GLOBALS['egw']->template->parse('fieldshandle','fields',True); } + $GLOBALS['egw']->template->set_var('lang_unique_id',lang('Unique ID(to update existing records)')); + $GLOBALS['egw']->template->set_var('unique_id',html::select('unique_id',$unique_id,array( + 'id' => $addr_names['id'], + 'uid' => $addr_names['uid'], + )+$cfs)."\n".html::select('unique_id2',$unique_id2,array( + '*none*' => lang('No fallback'), + 'id' => $addr_names['id'], + 'uid' => $addr_names['uid'], + 'addr_id' => lang('two of: %1',$addr_names['org_name'].', '.$addr_names['n_family'].', '.$addr_names['n_given']), + )+$cfs)); + $GLOBALS['egw']->template->set_var('lang_start',lang('Startrecord')); $GLOBALS['egw']->template->set_var('start',get_var('start',array('POST'),1)); $msg = ($safe_mode = ini_get('safe_mode') == 'On') ? lang('to many might exceed your execution-time-limit'): @@ -205,7 +225,7 @@ switch($_POST['action']) "usefull for the last pair, as they are worked from left to right.". "First example: 1${ASep}private${PSep}public". "This will translate a '1' in the CSV field to 'privat' and everything else to 'public'.". - "Patterns as well as the replacement can be regular expressions (the replacement is done via ereg_replace). ". + "Patterns as well as the replacement can be regular expressions (the replacement is done via preg_replace). ". "If, after all replacements, the value starts with an '@' the whole value is eval()'ed, so you ". "may use all php, phpgw plus your own functions. This is quiet powerfull, but circumvents all ACL. ". "Therefor this feature is only availible to Adminstrators.". @@ -243,7 +263,9 @@ switch($_POST['action']) 'max' => $_POST['max'], 'debug' => $_POST['debug'], 'addr_fields' => $_POST['addr_fields'], - 'trans' => $_POST['trans'] + 'trans' => $_POST['trans'], + 'unique_id' => $_POST['unique_id'], + 'unique_id2' => $_POST['unique_id2'], )); @set_time_limit(0); ini_set('auto_detect_line_endings',true); // to allow to import files created eg. on a mac @@ -267,10 +289,16 @@ switch($_POST['action']) } $GLOBALS['egw']->preferences->read_repository(); $GLOBALS['egw']->preferences->add('addressbook','cvs_import',$defaults); + $GLOBALS['egw']->preferences->add('addressbook','cvs_import_unique_id',$unique_id = $_POST['unique_id']); + $GLOBALS['egw']->preferences->add('addressbook','cvs_import_unique_id2',$unique_id2 = $_POST['unique_id2']); $GLOBALS['egw']->preferences->save_repository(True); $log = ''."\n\t#\n"; + if (!in_array('id',$addr_fields)) // autocreate public access if not set by user + { + $log .= "\t\tID\n"; + } if (!in_array('private',$addr_fields)) // autocreate public access if not set by user { $log .= "\t\tprivate\n"; @@ -328,14 +356,14 @@ switch($_POST['action']) $trans_csv = $_POST['trans'][$csv_idx]; while(list($pattern,$replace) = each($trans_csv)) { - if(ereg((string) $pattern,$val)) + if(preg_match('/'.(string) $pattern.'/',$val)) { // echo "csv_idx='$csv_idx',info='$addr',trans_csv=".print_r($trans_csv).",preg_replace('/$pattern/','$replace','$val') = "; $val = preg_replace('/'.(string) $pattern.'/',str_replace($VPre,'\\',$replace),(string) $val); // echo "'$val'"; $reg = $CPreReg.'([a-zA-Z_0-9]+)'.$CPosReg; - while(ereg($reg,$val,$vars)) + while(preg_match('/'.(string) $reg.'/',$val,$vars)) { // expand all CSV fields $val = str_replace($CPre . $vars[1] . $CPos, $val[0] == '@' ? "'" . addslashes($fields[array_search($vars[1], $csv_fields)]) @@ -374,19 +402,51 @@ switch($_POST['action']) // convert dates to timestamps foreach(array('created','modified') as $date) { - if (isset($values[$date]) && !is_numeric($date)) + if (isset($values[$date]) && !is_numeric($values[$date])) { // convert german DD.MM.YYYY format into ISO YYYY-MM-DD format $values[$date] = preg_replace('/([0-9]{1,2}).([0-9]{1,2}).([0-9]{4})/','\3-\2-\1',$values[$date]); // remove fractures of seconds if present at the end of the string - if (ereg('(.*)\.[0-9]+',$values[$date],$parts)) $values[$date] = $parts[1]; + if (preg_match('/(.*)\.[0-9]+/',$values[$date],$parts)) $values[$date] = $parts[1]; $values[$date] = strtotime($values[$date]); } } + // check unique ids + $existing = false; + if (!empty($values[$unique_id])) + { + if ($unique_id == 'id') + { + $existing = $bocontacts->read($values[$unique_id]); + } + else + { + list($existing) = $bocontacts->search(array($unique_id => $values[$unique_id]),false); + } + } + if (!$existing && (!empty($values[$unique_id2]) || + $unique_id2 == 'addr_id' && (!empty($values['org_name'])+!empty($values['n_family'])+!empty($values['n_given'])) >= 2)) + { + if ($unique_id2 == 'id' || $unique_id2 == 'addr_id' && + ($values[$unique_id2] = addr_id($values['n_family'],$values['n_given'],$values['org_name']))) + { + $existing = $bocontacts->read($values[$unique_id2]); + } + elseif ($unique_id2 != 'addr_id') + { + list($existing) = $bocontacts->search(array($unique_id2 => $values[$unique_id2]),false); + } + } + //echo "unique_id=$unique_id='{$values[$unique_id]}', unique_id2=$unique_id2='{$values[$unique_id2]}' --> ".array2string($existing)."\n"; + if ($existing) + { + unset($values['id']); // to NOT overrite the found one + $values = array_merge($existing,$values); + } // convert user-names to user-id's foreach(array('owner','modifier','creator') as $user) { - if (isset($values[$user]) && !is_numeric($user)) + if (isset($values[$user]) && !is_numeric($values[$user])) { if (preg_match('/\[([^\]]+)\]/',$values[$user],$matches)) $values[$user] = $matches[1]; $values[$user] = $GLOBALS['egw']->accounts->name2id($values[$user],'account_lid',$user=='owner'?null:'u'); @@ -396,6 +456,10 @@ switch($_POST['action']) { $values['owner'] = $GLOBALS['egw_info']['user']['account_id']; } + if (!in_array('id',$addr_fields)) + { + $log .= "\t\t".$values['id']."\n"; + } if (!in_array('private',$addr_fields)) { $values['private'] = 0; // public access if not set by user @@ -414,7 +478,7 @@ switch($_POST['action']) } if(!$_POST['debug'] && !$empty) // dont import empty contacts { - $rvalue=$GLOBALS['egw']->contacts->save($values); + $rvalue=$bocontacts->save($values); //echo "adding: ".print_r($values,true)."\n"; } // display read and interpreted results, so the user can check it diff --git a/addressbook/setup/egw_de.lang b/addressbook/setup/egw_de.lang index f3baa341e3..02030715ad 100644 --- a/addressbook/setup/egw_de.lang +++ b/addressbook/setup/egw_de.lang @@ -287,6 +287,7 @@ new contact submitted by %1 at %2 addressbook de Neuer Kontakt eingetragen von % new window opened to edit infolog for your selection addressbook de Es wird ein neues Fenster zum erstellen des Infolog Eintrags geöffnet next date addressbook de Nächster Termin no categories selected addressbook de keine Kategorien ausgewählt +no fallback addressbook de Kein Ausweichlösung no vcard addressbook de Keine VCard number addressbook de Nummer number of records to read (%1) addressbook de Anzahl der einzulesenden Datensätze (%1) @@ -382,7 +383,10 @@ to many might exceed your execution-time-limit addressbook de zu viel können ih today is %1's birthday! common de Heute ist der Geburtstag von %1! tomorrow is %1's birthday. common de Morgen ist der Geburtstag von %1. translation addressbook de Übersetzung +two of: %1 addressbook de Zwei von: %1 type addressbook de Typ +unique id (uid) addressbook de Eindeutige ID (UID) +unique id(to update existing records) addressbook de Eindeutige ID(um existierende Datensätze zu aktualisieren) update a single entry by passing the fields. addressbook de Aktualisiert einen einzelnen Eintrag durch Übergabe seiner Felder. update fields by edited organisations? admin de Welche Felder sollen beim Bearbeiten von Organisationen aktualisiert werden? updated addressbook de Aktualisiert diff --git a/addressbook/setup/egw_en.lang b/addressbook/setup/egw_en.lang index 68d487c7a3..8a0b0d5920 100644 --- a/addressbook/setup/egw_en.lang +++ b/addressbook/setup/egw_en.lang @@ -287,6 +287,7 @@ new contact submitted by %1 at %2 addressbook en New contact submitted by %1 at new window opened to edit infolog for your selection addressbook en New window opened to edit Infolog for your selection next date addressbook en Next date no categories selected addressbook en no categories selected +no fallback addressbook en No fallback no vcard addressbook en No VCard number addressbook en Number number of records to read (%1) addressbook en Number of records to read (%1) @@ -382,7 +383,10 @@ to many might exceed your execution-time-limit addressbook en to many might exce today is %1's birthday! common en Today is %1's birthday! tomorrow is %1's birthday. common en Tomorrow is %1's birthday. translation addressbook en Translation +two of: %1 addressbook en two of: %1 type addressbook en Type +unique id (uid) addressbook en Unique ID (UID) +unique id(to update existing records) addressbook en Unique ID(to update existing records) update a single entry by passing the fields. addressbook en Update a single entry by passing the fields. update fields by edited organisations? admin en Update Fields by edited organisations? updated addressbook en Updated diff --git a/addressbook/templates/default/csv_import.tpl b/addressbook/templates/default/csv_import.tpl index 11eb3785d4..341f90f990 100644 --- a/addressbook/templates/default/csv_import.tpl +++ b/addressbook/templates/default/csv_import.tpl @@ -1,17 +1,17 @@ - - + + - - {lang_csvfile} - + + {lang_csvfile} + {lang_fieldsep} - + {lang_charset} @@ -20,8 +20,8 @@ - - + + @@ -35,21 +35,25 @@ {csv_field} - {addr_fields} - + {addr_fields} + - {submit} - - {lang_start} - {lang_max} + {lang_unique_id} + {unique_id} - {lang_debug} - + {submit} + + {lang_start} + {lang_max} + + + {lang_debug} + {help_on_trans} @@ -61,11 +65,11 @@ {log} {anz_imported} - + - + {hiddenvars} - +
". "First example: 1${ASep}private${PSep}public". "This will translate a '1' in the CSV field to 'privat' and everything else to 'public'.
". - "Patterns as well as the replacement can be regular expressions (the replacement is done via ereg_replace). ". + "Patterns as well as the replacement can be regular expressions (the replacement is done via preg_replace). ". "If, after all replacements, the value starts with an '@' the whole value is eval()'ed, so you ". "may use all php, phpgw plus your own functions. This is quiet powerfull, but circumvents all ACL. ". "Therefor this feature is only availible to Adminstrators.
". @@ -243,7 +263,9 @@ switch($_POST['action']) 'max' => $_POST['max'], 'debug' => $_POST['debug'], 'addr_fields' => $_POST['addr_fields'], - 'trans' => $_POST['trans'] + 'trans' => $_POST['trans'], + 'unique_id' => $_POST['unique_id'], + 'unique_id2' => $_POST['unique_id2'], )); @set_time_limit(0); ini_set('auto_detect_line_endings',true); // to allow to import files created eg. on a mac @@ -267,10 +289,16 @@ switch($_POST['action']) } $GLOBALS['egw']->preferences->read_repository(); $GLOBALS['egw']->preferences->add('addressbook','cvs_import',$defaults); + $GLOBALS['egw']->preferences->add('addressbook','cvs_import_unique_id',$unique_id = $_POST['unique_id']); + $GLOBALS['egw']->preferences->add('addressbook','cvs_import_unique_id2',$unique_id2 = $_POST['unique_id2']); $GLOBALS['egw']->preferences->save_repository(True); $log = '
csv_idx='$csv_idx',info='$addr',trans_csv=".print_r($trans_csv).",preg_replace('/$pattern/','$replace','$val') = "; $val = preg_replace('/'.(string) $pattern.'/',str_replace($VPre,'\\',$replace),(string) $val); // echo "'$val'
unique_id=$unique_id='{$values[$unique_id]}', unique_id2=$unique_id2='{$values[$unique_id2]}' --> ".array2string($existing)."
adding: ".print_r($values,true)."
{help_on_trans}
{anz_imported} - + -