forked from extern/egroupware
Implemented configurable unique id's in addressbook cvs import:
- primary unique id: id (default), uid, or any custom field - fallback: id, uid(default), two from n_family, org_name or n_given, or any custom field - some bugfixes
This commit is contained in:
parent
aa1d033532
commit
dc813fd741
@ -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 <u>only</u> 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 = "<option value=\"\">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<br />(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.<p>".
|
||||
"First example: <b>1${ASep}private${PSep}public</b><br>".
|
||||
"This will translate a '1' in the CSV field to 'privat' and everything else to 'public'.<p>".
|
||||
"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 <u>circumvents all ACL</u>. ".
|
||||
"Therefor this feature is only availible to Adminstrators.<p>".
|
||||
@ -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 = '<table border="1" style="border: 1px dotted black; border-collapse: collapse;">'."\n\t<tr><td>#</td>\n";
|
||||
|
||||
if (!in_array('id',$addr_fields)) // autocreate public access if not set by user
|
||||
{
|
||||
$log .= "\t\t<td><b>ID</b></td>\n";
|
||||
}
|
||||
if (!in_array('private',$addr_fields)) // autocreate public access if not set by user
|
||||
{
|
||||
$log .= "\t\t<td><b>private</b></td>\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 "<p>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'</p>";
|
||||
|
||||
$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 "<p>unique_id=$unique_id='{$values[$unique_id]}', unique_id2=$unique_id2='{$values[$unique_id2]}' --> ".array2string($existing)."</p>\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<td>".$values['id']."</td>\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 "<p>adding: ".print_r($values,true)."</p>\n";
|
||||
}
|
||||
// display read and interpreted results, so the user can check it
|
||||
|
@ -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<br />(to update existing records) addressbook de Eindeutige ID<br />(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
|
||||
|
@ -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<br />(to update existing records) addressbook en Unique ID<br />(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
|
||||
|
@ -1,17 +1,17 @@
|
||||
|
||||
<br><center>
|
||||
|
||||
<FORM {enctype} action="{action_url}" method="post">
|
||||
<TABLE>
|
||||
<form {enctype} action="{action_url}" method="post">
|
||||
<table>
|
||||
|
||||
<!-- BEGIN filename -->
|
||||
<TR>
|
||||
<TD>{lang_csvfile}</td>
|
||||
<td><INPUT NAME="csvfile" SIZE=30 TYPE="file" VALUE="{csvfile}"></td>
|
||||
<tr>
|
||||
<td>{lang_csvfile}</td>
|
||||
<td><input NAME="csvfile" SIZE=30 TYPE="file" VALUE="{csvfile}" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{lang_fieldsep}</td>
|
||||
<td><input name="fieldsep" size=1 value="{fieldsep}"></td>
|
||||
<td><input name="fieldsep" size=1 value="{fieldsep}" /></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>{lang_charset}</td>
|
||||
@ -20,8 +20,8 @@
|
||||
</td>
|
||||
</tr>
|
||||
<tr><td> </td>
|
||||
<td><INPUT NAME="convert" TYPE="submit" VALUE="{submit}"></TD>
|
||||
</TR>
|
||||
<td><input NAME="convert" TYPE="submit" VALUE="{submit}" /></TD>
|
||||
</tr>
|
||||
<!-- END filename -->
|
||||
|
||||
<!-- BEGIN fheader -->
|
||||
@ -35,21 +35,25 @@
|
||||
<!-- BEGIN fields -->
|
||||
<tr>
|
||||
<td>{csv_field}</td>
|
||||
<td><SELECT name="addr_fields[{csv_idx}]">{addr_fields}</select></td>
|
||||
<td><input name="trans[{csv_idx}]" size=60 value="{trans}"></td>
|
||||
<td><select name="addr_fields[{csv_idx}]">{addr_fields}</select></td>
|
||||
<td><input name="trans[{csv_idx}]" size=60 value="{trans}" /></td>
|
||||
</tr>
|
||||
<!-- END fields -->
|
||||
|
||||
<!-- BEGIN ffooter -->
|
||||
<tr>
|
||||
<td rowspan="2" valign="middle"><br>{submit}</TD>
|
||||
<td colspan="2"><br>
|
||||
{lang_start} <INPUT name="start" type="text" size="5" value="{start}">
|
||||
{lang_max} <INPUT name="max" type="text" size="3" value="{max}"><td>
|
||||
<td>{lang_unique_id}</td>
|
||||
<td colspan="2">{unique_id}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><INPUT name="debug" type="checkbox" value="1" {debug}> {lang_debug}</td>
|
||||
</TR>
|
||||
<td rowspan="2" valign="middle"><br>{submit}</TD>
|
||||
<td colspan="2"><br>
|
||||
{lang_start} <input name="start" type="text" size="5" value="{start}" />
|
||||
{lang_max} <input name="max" type="text" size="3" value="{max}" /><td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td colspan="3"><input name="debug" type="checkbox" value="1" {debug}> {lang_debug}</td>
|
||||
</tr>
|
||||
<tr><td colspan="3"> <p>
|
||||
{help_on_trans}
|
||||
</td></tr>
|
||||
@ -61,11 +65,11 @@
|
||||
{log}<p>
|
||||
{anz_imported}
|
||||
</td>
|
||||
</TR>
|
||||
</tr>
|
||||
<!-- END imported -->
|
||||
|
||||
</TABLE>
|
||||
</table>
|
||||
{hiddenvars}
|
||||
</form>
|
||||
|
||||
</CENTER>
|
||||
</center>
|
||||
|
Loading…
Reference in New Issue
Block a user