Skip to content

Commit

Permalink
fix mapping of gmail CSV files
Browse files Browse the repository at this point in the history
  • Loading branch information
johndoh committed Aug 8, 2020
1 parent 1bbe905 commit 87bddfb
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 21 deletions.
71 changes: 51 additions & 20 deletions program/lib/Roundcube/rcube_csv2vcard.php
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,7 @@ class rcube_csv2vcard
'group' => 'groups',

// GMail
'_auto_' => '_auto_',
'groups' => 'groups',
'group_membership' => 'groups',
'given_name' => 'firstname',
Expand Down Expand Up @@ -434,14 +435,21 @@ public function import($csv, $dry_run = false, $skip_head = true)
// Parse header
if (empty($this->map)) {
$this->parse_header($elements);
$this->map_gmail_fields($elements);
}
elseif ($n == 0) {
// import is running using predefined field map
// check import fiels for gamil fields and build the special gmail field map
// do not change the global field map
$this->map_gmail_fields($elements, false);
}

if ($dry_run) {
return array('source' => $elements, 'destination' => $this->map);
}
if ($dry_run) {
return array('source' => $elements, 'destination' => $this->map);
}

if (empty($this->map)) {
break;
}
if (empty($this->map)) {
break;
}

// first line is the headers so do not import unless explicitly set
Expand Down Expand Up @@ -481,6 +489,10 @@ public function get_fields()
// translate with the local map
$map = array();
foreach ($fields as $csv => $vcard) {
if ($vcard == '_auto_') {
continue;
}

$map[$vcard] = $local_field_names[$csv];
}

Expand Down Expand Up @@ -567,15 +579,29 @@ protected function parse_header($elements)
}

$this->map = count($map1) >= count($map2) ? $map1 : $map2;
}

// support special Gmail format
/**
* Parse CSV header line, special Gmail format
*
* @param array $elements Array of field names from a first line in CSV file
*/
protected function map_gmail_fields($elements, $update_map = true) {
foreach ($this->gmail_label_map as $key => $items) {
$num = 1;
while (($_key = "$key $num - Type") && ($found = array_search($_key, $elements)) !== false) {
if ($update_map) {
$this->map[$found] = '_auto_';
}

$this->gmail_map["$key:$num"] = array('_key' => $key, '_idx' => $found);
foreach (array_keys($items) as $item_key) {
$_key = "$key $num - $item_key";
if (($found = array_search($_key, $elements)) !== false) {
if ($update_map) {
$this->map[$found] = '_auto_';
}

$this->gmail_map["$key:$num"][$item_key] = $found;
}
}
Expand All @@ -594,6 +620,9 @@ protected function csv_to_vcard($data)
{
$contact = array();
foreach ($this->map as $idx => $name) {
if ($name == '_auto_')
continue;

$value = $data[$idx];
if ($value !== null && $value !== '') {
if (!empty($contact[$name])) {
Expand All @@ -614,20 +643,22 @@ protected function csv_to_vcard($data)
unset($item['_idx']);
unset($item['_key']);

foreach ($item as $item_key => $item_idx) {
$value = $data[$item_idx];
if ($value !== null && $value !== '') {
foreach (array($type, '*') as $_type) {
if ($data_idx = $this->gmail_label_map[$key][$item_key][$_type]) {
$value = explode(' ::: ', $value);

if (!empty($contact[$data_idx])) {
$contact[$data_idx] = array_merge((array) $contact[$data_idx], $value);
}
else {
$contact[$data_idx] = $value;
if ($this->map[$item['Value']] == '_auto_') {
foreach ($item as $item_key => $item_idx) {
$value = $data[$item_idx];
if ($value !== null && $value !== '') {
foreach (array($type, '*') as $_type) {
if ($data_idx = $this->gmail_label_map[$key][$item_key][$_type]) {
$value = explode(' ::: ', $value);

if (!empty($contact[$data_idx])) {
$contact[$data_idx] = array_merge((array) $contact[$data_idx], $value);
}
else {
$contact[$data_idx] = $value;
}
break;
}
break;
}
}
}
Expand Down
1 change: 1 addition & 0 deletions program/localization/en_US/labels.inc
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,7 @@ $labels['importgroupsexisting'] = 'Only for existing groups';
$labels['importdesc'] = 'You can upload contacts from an existing address book.<br/>We currently support importing addresses from the <a href="https://en.wikipedia.org/wiki/VCard">vCard</a> or CSV (comma-separated) data format.';
$labels['importmapdesc'] = 'Confirm the field mapping information below is correct before proceeding with CSV (comma-separated) data import.';
$labels['fieldnotmapped'] = 'Field not mapped (do not import)';
$labels['fieldautomapped'] = 'Automatically map field value into contact';
$labels['done'] = 'Done';

// settings
Expand Down
9 changes: 8 additions & 1 deletion program/steps/addressbook/import.inc
Original file line number Diff line number Diff line change
Expand Up @@ -378,7 +378,14 @@ function rcmail_import_map($attrib)
$map = $_SESSION['contactcsvimport']['map'];
foreach ($map['source'] as $i => $name) {
$field_table->add('title', html::label('rcmimportmap' . $i, rcube::Q($name)));
$field_table->add(null, $fieldlist->show(array_key_exists($i, $map['destination']) ? $map['destination'][$i] : '', array('id' => 'rcmimportmap' . $i)));

$curfield = $fieldlist;
// add auto mapping option for gmail CSV file imports
if ($map['destination'][$i] == '_auto_') {
$curfield->add($RCMAIL->gettext('fieldautomapped'), '_auto_');
}

$field_table->add(null, $curfield->show(array_key_exists($i, $map['destination']) ? $map['destination'][$i] : '', array('id' => 'rcmimportmap' . $i)));
}

$form = '';
Expand Down

0 comments on commit 87bddfb

Please sign in to comment.