diff --git a/importexport/inc/class.importexport_basic_import_csv.inc.php b/importexport/inc/class.importexport_basic_import_csv.inc.php index ead8962e03..28f7943556 100644 --- a/importexport/inc/class.importexport_basic_import_csv.inc.php +++ b/importexport/inc/class.importexport_basic_import_csv.inc.php @@ -109,6 +109,7 @@ abstract class importexport_basic_import_csv implements importexport_iface_impor public static $special_fields = array( 'contact' => array('label' => 'Link to Addressbook', 'title'=>'use nlast,nfirst[,org] or contact_id from addressbook, eg: Guy,Test,My organization'), 'link_search' => array('label' => 'Link by search', 'title'=>'appname:search terms the entry should be linked to, links to the first match eg: addressbook:My organization'), + 'link_custom' => array('label' => 'Link by custom field', 'title'=>'use ::|[] links to first entry where given custom field matches given row column'), 'link_0' => array('label' => 'Link to ID', 'title'=>'appname:appid the entry should be linked to, eg.: addressbook:123'), ); @@ -348,7 +349,11 @@ abstract class importexport_basic_import_csv implements importexport_iface_impor list($link, $type) = explode('_',$field); // Searching, take first result - if($type == 'search') + if($type == 'custom') + { + $app_id = $this->link_by_cf($record, $app, $app_id, $import_csv->get_current_position()); + } + else if($type == 'search') { $result = egw_link::query($app, $app_id); do @@ -503,6 +508,73 @@ abstract class importexport_basic_import_csv implements importexport_iface_impor return False; } + /** + * Get the primary key for an entry based on a custom field + * Returns key, so regular linking can take over + * + * @param int $record_number Row number, used for errors + * @param string $app Target application name + * @param string $value CSV value in the form of custom_field_name:value + */ + protected function link_by_cf(importexport_iface_egw_record &$record, $app, $value,$record_num) + { + $app_id = false; + + list($custom_field, $value) = explode(':',$value); + // Find matching entry + if($app && $custom_field && $value) + { + $cfs = config::get_customfields($app); + // Error if no custom fields, probably something wrong in definition + if(!$cfs[$custom_field]) + { + // Check for users specifing label instead of name + foreach($cfs as $name => $settings) + { + if(strtolower($settings['label']) == strtolower($custom_field)) + { + $custom_field = $name; + break; + } + } + } + + // Couldn't find field, give an error - something's wrong + if(!$cfs[$custom_field] && !$cfs[substr($custom_field,1)]) { + $this->errors[$record_num] .= lang('No custom field "%1" for %2.', + $custom_field, lang($app)); + return false; + } + if($custom_field[0] != '#') $custom_field = '#' . $custom_field; +error_log("Searching for $custom_field = $value"); + // Search + if(egw_link::get_registry($app, 'query')) + { + $options = array('filter' => array("$custom_field = " . $GLOBALS['egw']->db->quote($value))); + $result = egw_link::query($app, '', $options); + + // Only one allowed + if($record->get_identifier()) + { + while(key($result) == $record->get_identifier()) + { + array_shift($result); + } + } + if(count($result) != 1) + { + $this->warnings[$record_num] .= ($this->warnings[$record_num] ? "\n" : '') . + lang('Unable to link to %3 by custom field "%1": "%4". %2 matches.', + $custom_field, count($result), lang($app), $options['filter'][0] + ); + return false; + } + $app_id = key($result); + } + } + return $app_id; + } + /** * returns translated name of plugin * diff --git a/importexport/inc/class.importexport_schedule_ui.inc.php b/importexport/inc/class.importexport_schedule_ui.inc.php index 8f94ddf3e6..26d3518f95 100644 --- a/importexport/inc/class.importexport_schedule_ui.inc.php +++ b/importexport/inc/class.importexport_schedule_ui.inc.php @@ -111,7 +111,8 @@ $content ); if($result) { - $GLOBALS['egw']->js->set_onload('window.opener.location.reload(); self.close();'); + egw_framework::refresh_opener('', 'importexport'); + egw_framework::window_close(); } else { $data['message'] = lang('Unable to schedule'); unset($id); diff --git a/importexport/inc/class.importexport_wizard_basic_import_csv.inc.php b/importexport/inc/class.importexport_wizard_basic_import_csv.inc.php index 15467a7876..ad4953e535 100644 --- a/importexport/inc/class.importexport_wizard_basic_import_csv.inc.php +++ b/importexport/inc/class.importexport_wizard_basic_import_csv.inc.php @@ -305,19 +305,33 @@ class importexport_wizard_basic_import_csv if(array_key_exists('field_mapping', $content)) { $field = $content['field_mapping']; + $conversion = $content['field_conversion']; } else { $field = $content['plugin_options']['field_mapping']; + $conversion = $content['plugin_options']['field_conversion']; } + $empties = 1; foreach($content['csv_fields'] as $index => $title) { $content['mapping'][] = array( 'index' => $index, 'title' => $title, 'field' => $field[$index], - 'conversion' => $content['field_conversion'][$index] + 'conversion' => $conversion[$index] ); + if(strstr($title,lang('Extra %1'))) $empties++; + } + while($empties <= 3) + { + $content['mapping'][] = array( + 'index' => $index + $empties, + 'title' => lang('Extra %1', $empties), + 'field' => $field[$index+$empties], + 'conversion' => $conversion[$index+$empties] + ); + $empties++; } $preserv = $content; $sel_options['field'] = array('--NONE--' => lang('none')) + $this->mapping_fields; @@ -389,6 +403,16 @@ class importexport_wizard_basic_import_csv foreach($content['field_mapping'] as $field) { $sel_options['string'][$field] = $this->mapping_fields[$field]; + if(!$sel_options['string'][$field]) + { + foreach($this->mapping_fields as $fields) + { + if(is_array($fields) && $fields[$field]) + { + $sel_options['string'][$field] = $fields[$field]; + } + } + } } $sel_options['type'] = $this->conditions; $sel_options['action'] = $this->actions;