".$_REQUEST[", "".$mod_strings['LBL_MODULE_NAME']."", $mod_strings['LBL_STEP_3_TITLE'], ); } /** * @see SugarView::display() */ public function display() { global $mod_strings, $app_strings, $current_user, $sugar_config, $app_list_strings, $locale; $this->ss->assign("MOD", $mod_strings); $this->ss->assign("APP", $app_strings); $this->ss->assign("IMPORT_MODULE", $_REQUEST['import_module']); $has_header = ( isset( $_REQUEST['has_header']) ? 1 : 0 ); $sugar_config['import_max_records_per_file'] = ( empty($sugar_config['import_max_records_per_file']) ? 1000 : $sugar_config['import_max_records_per_file'] ); // load the bean for the import module $focus = loadImportBean($_REQUEST['import_module']); if ( !$focus ) { showImportError($mod_strings['LBL_ERROR_IMPORTS_NOT_SET_UP'],$_REQUEST['import_module']); return; } // Clear out this user's last import $seedUsersLastImport = new UsersLastImport(); $seedUsersLastImport->mark_deleted_by_user_id($current_user->id); ImportCacheFiles::clearCacheFiles(); // attempt to lookup a preexisting field map // use the custom one if specfied to do so in step 1 $field_map = array(); $default_values = array(); $ignored_fields = array(); if ( !empty( $_REQUEST['source_id'])) { $mapping_file = new ImportMap(); $mapping_file->retrieve( $_REQUEST['source_id'],false); $_REQUEST['source'] = $mapping_file->source; $has_header = $mapping_file->has_header; if (isset($mapping_file->delimiter)) $_REQUEST['custom_delimiter'] = $mapping_file->delimiter; if (isset($mapping_file->enclosure)) $_REQUEST['custom_enclosure'] = htmlentities($mapping_file->enclosure); $field_map = $mapping_file->getMapping(); $default_values = $mapping_file->getDefaultValues(); $this->ss->assign("MAPNAME",$mapping_file->name); $this->ss->assign("CHECKMAP",'checked="checked" value="on"'); } else { // Try to see if we have a custom mapping we can use // based upon the where the records are coming from // and what module we are importing into $classname = 'ImportMap' . ucfirst($_REQUEST['source']); require("modules/Import/{$classname}.php"); $mapping_file = new $classname; if (isset($mapping_file->delimiter)) $_REQUEST['custom_delimiter'] = $mapping_file->delimiter; if (isset($mapping_file->enclosure)) $_REQUEST['custom_enclosure'] = htmlentities($mapping_file->enclosure); $ignored_fields = $mapping_file->getIgnoredFields($_REQUEST['import_module']); $field_map = $mapping_file->getMapping($_REQUEST['import_module']); } $this->ss->assign("CUSTOM_DELIMITER", ( !empty($_REQUEST['custom_delimiter']) ? $_REQUEST['custom_delimiter'] : "," )); $this->ss->assign("CUSTOM_ENCLOSURE", ( !empty($_REQUEST['custom_enclosure']) ? $_REQUEST['custom_enclosure'] : "" )); // handle uploaded file $uploadFile = new UploadFile('userfile'); if (isset($_FILES['userfile']) && $uploadFile->confirm_upload()) { $uploadFile->final_move('IMPORT_'.$focus->object_name.'_'.$current_user->id); $uploadFileName = $uploadFile->get_upload_path('IMPORT_'.$focus->object_name.'_'.$current_user->id); } else { showImportError($mod_strings['LBL_IMPORT_MODULE_ERROR_NO_UPLOAD'],$_REQUEST['import_module'],'Step2'); return; } // split file into parts $splitter = new ImportFileSplitter( $uploadFileName, $sugar_config['import_max_records_per_file']); $splitter->splitSourceFile( $_REQUEST['custom_delimiter'], html_entity_decode($_REQUEST['custom_enclosure'],ENT_QUOTES), $has_header ); // Now parse the file and look for errors $importFile = new ImportFile( $uploadFileName, $_REQUEST['custom_delimiter'], html_entity_decode($_REQUEST['custom_enclosure'],ENT_QUOTES) ); if ( !$importFile->fileExists() ) { showImportError($mod_strings['LBL_CANNOT_OPEN'],$_REQUEST['import_module'],'Step2'); return; } // retrieve first 3 rows $rows = array(); $system_charset = $locale->default_export_charset; $user_charset = $locale->getExportCharset(); $other_charsets = 'UTF-8, UTF-7, ASCII, EUC-JP,SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP'; $charset_for_import = $user_charset; //We will set the default import charset option by user's preference. $able_to_detect = function_exists('mb_detect_encoding'); for ( $i = 0; $i < 3; $i++ ) { $rows[$i] = $importFile->getNextRow(); if(!empty($rows[$i]) && $able_to_detect) { foreach($rows[$i] as & $temp_value) { $current_charset = mb_detect_encoding($temp_value, "UTF-8, {$user_charset}, {$system_charset}, {$other_charsets}"); if(!empty($current_charset) && $current_charset != "UTF-8") { $temp_value = $locale->translateCharset($temp_value, $current_charset);// we will use utf-8 for displaying the data on the page. $charset_for_import = $current_charset; //set the default import charset option according to the current_charset. //If it is not utf-8, tt may be overwritten by the later one. So the uploaded file should not contain two types of charset($user_charset, $system_charset), and I think this situation will not occur. } } } } $ret_field_count = $importFile->getFieldCount(); // Bug 14689 - Parse the first data row to make sure it has non-empty data in it $isempty = true; if ( $rows[(int)$has_header] != false ) { foreach ( $rows[(int)$has_header] as $value ) { if ( strlen(trim($value)) > 0 ) { $isempty = false; break; } } } if ($isempty || $rows[(int)$has_header] == false) { showImportError($mod_strings['LBL_NO_LINES'],$_REQUEST['import_module'],'Step2'); return; } // save first row to send to step 4 $this->ss->assign("FIRSTROW", base64_encode(serialize($rows[0]))); // Now build template $this->ss->assign("TMP_FILE", $uploadFileName ); $this->ss->assign("FILECOUNT", $splitter->getFileCount() ); $this->ss->assign("RECORDCOUNT", $splitter->getRecordCount() ); $this->ss->assign("RECORDTHRESHOLD", $sugar_config['import_max_records_per_file']); $this->ss->assign("SOURCE", $_REQUEST['source'] ); $this->ss->assign("TYPE", $_REQUEST['type'] ); $this->ss->assign("DELETE_INLINE_PNG", SugarThemeRegistry::current()->getImage('basic_search','align="absmiddle" alt="'.$app_strings['LNK_DELETE'].'" border="0"')); $this->ss->assign("PUBLISH_INLINE_PNG", SugarThemeRegistry::current()->getImage('advanced_search','align="absmiddle" alt="'.$mod_strings['LBL_PUBLISH'].'" border="0"')); $this->ss->assign("MODULE_TITLE", $this->getModuleTitle()); $this->ss->assign("STEP4_TITLE", strip_tags(str_replace("\n","",get_module_title( $mod_strings['LBL_MODULE_NAME'], $mod_strings['LBL_MODULE_NAME']." ".$mod_strings['LBL_STEP_4_TITLE'], false ))) ); $this->ss->assign("HEADER", $app_strings['LBL_IMPORT']." ". $mod_strings['LBL_MODULE_NAME']); // we export it as email_address, but import as email1 $field_map['email_address'] = 'email1'; // build each row; row count is determined by the the number of fields in the import file $columns = array(); $mappedFields = array(); for($field_count = 0; $field_count < $ret_field_count; $field_count++) { // See if we have any field map matches $defaultValue = ""; // Bug 31260 - If the data rows have more columns than the header row, then just add a new header column if ( !isset($rows[0][$field_count]) ) $rows[0][$field_count] = ''; // See if we can match the import row to a field in the list of fields to import $firstrow_name = trim(str_replace(":","",$rows[0][$field_count])); if ($has_header && isset( $field_map[$firstrow_name] ) ) { $defaultValue = $field_map[$firstrow_name]; } elseif (isset($field_map[$field_count])) { $defaultValue = $field_map[$field_count]; } elseif (empty( $_REQUEST['source_id'])) { $defaultValue = trim($rows[0][$field_count]); } // build string of options $fields = $focus->get_importable_fields(); $options = array(); $defaultField = ''; foreach ( $fields as $fieldname => $properties ) { // get field name if (!empty ($properties['vname'])) $displayname = str_replace(":","",translate($properties['vname'] ,$focus->module_dir)); else $displayname = str_replace(":","",translate($properties['name'] ,$focus->module_dir)); // see if this is required $req_mark = ""; $req_class = ""; if ( array_key_exists($fieldname, $focus->get_import_required_fields()) ) { $req_mark = ' ' . $app_strings['LBL_REQUIRED_SYMBOL']; $req_class = ' class="required" '; } // see if we have a match $selected = ''; if ( !empty($defaultValue) && !in_array($fieldname,$mappedFields) && !in_array($fieldname,$ignored_fields) ) { if ( strtolower($fieldname) == strtolower($defaultValue) || strtolower($fieldname) == str_replace(" ","_",strtolower($defaultValue)) || strtolower($displayname) == strtolower($defaultValue) || strtolower($displayname) == str_replace(" ","_",strtolower($defaultValue)) ) { $selected = ' selected="selected" '; $defaultField = $fieldname; $mappedFields[] = $fieldname; } } // get field type information $fieldtype = ''; if ( isset($properties['type']) && isset($mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])]) ) $fieldtype = ' [' . $mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])] . '] '; if ( isset($properties['comment']) ) $fieldtype .= ' - ' . $properties['comment']; $options[$displayname.$fieldname] = '\n'; } // get default field value $defaultFieldHTML = ''; if ( !empty($defaultField) ) { $defaultFieldHTML = getControl( $_REQUEST['import_module'], $defaultField, $fields[$defaultField], ( isset($default_values[$defaultField]) ? $default_values[$defaultField] : '' ) ); } if ( isset($default_values[$defaultField]) ) unset($default_values[$defaultField]); // Bug 27046 - Sort the column name picker alphabetically ksort($options); $columns[] = array( 'field_choices' => implode('',$options), 'default_field' => $defaultFieldHTML, 'cell1' => str_replace(""",'',htmlspecialchars($rows[0][$field_count])), 'cell2' => str_replace(""",'',htmlspecialchars($rows[1][$field_count])), 'cell3' => str_replace(""",'',htmlspecialchars($rows[2][$field_count])), 'show_remove' => false, ); } // add in extra defaulted fields if they are in the mapping record if ( count($default_values) > 0 ) { foreach ( $default_values as $field_name => $default_value ) { // build string of options $fields = $focus->get_importable_fields(); $options = array(); $defaultField = ''; foreach ( $fields as $fieldname => $properties ) { // get field name if (!empty ($properties['vname'])) $displayname = str_replace(":","",translate($properties['vname'] ,$focus->module_dir)); else $displayname = str_replace(":","",translate($properties['name'] ,$focus->module_dir)); // see if this is required $req_mark = ""; $req_class = ""; if ( array_key_exists($fieldname, $focus->get_import_required_fields()) ) { $req_mark = ' ' . $app_strings['LBL_REQUIRED_SYMBOL']; $req_class = ' class="required" '; } // see if we have a match $selected = ''; if ( strtolower($fieldname) == strtolower($field_name) && !in_array($fieldname,$mappedFields) && !in_array($fieldname,$ignored_fields) ) { $selected = ' selected="selected" '; $defaultField = $fieldname; $mappedFields[] = $fieldname; } // get field type information $fieldtype = ''; if ( isset($properties['type']) && isset($mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])]) ) $fieldtype = ' [' . $mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])] . '] '; if ( isset($properties['comment']) ) $fieldtype .= ' - ' . $properties['comment']; $options[$displayname.$fieldname] = '\n'; } // get default field value $defaultFieldHTML = ''; if ( !empty($defaultField) ) { $defaultFieldHTML = getControl( $_REQUEST['import_module'], $defaultField, $fields[$defaultField], $default_value ); } // Bug 27046 - Sort the column name picker alphabetically ksort($options); $columns[] = array( 'field_choices' => implode('',$options), 'default_field' => $defaultFieldHTML, 'show_remove' => true, ); $ret_field_count++; } } $this->ss->assign("COLUMNCOUNT",$ret_field_count); $this->ss->assign("rows",$columns); // get list of valid date/time formats $timeFormat = $current_user->getUserDateTimePreferences(); $timeOptions = get_select_options_with_id($sugar_config['time_formats'], $timeFormat['time']); $dateOptions = get_select_options_with_id($sugar_config['date_formats'], $timeFormat['date']); $this->ss->assign('TIMEOPTIONS', $timeOptions); $this->ss->assign('DATEOPTIONS', $dateOptions); $this->ss->assign('datetimeformat', $GLOBALS['timedate']->get_cal_date_time_format()); // get list of valid timezones require_once('include/timezone/timezones.php'); global $timezones; $userTZ = $current_user->getPreference('timezone'); if(empty($userTZ)) $userTZ = lookupTimezone(); $timezoneOptions = ''; ksort($timezones); foreach($timezones as $key => $value) { $selected =($userTZ == $key) ? ' SELECTED="true"' : ''; $dst = !empty($value['dstOffset']) ? '(+DST)' : ''; $gmtOffset =($value['gmtOffset'] / 60); if(!strstr($gmtOffset,'-')) { $gmtOffset = '+'.$gmtOffset; } $timezoneOptions .= ""; } $this->ss->assign('TIMEZONEOPTIONS', $timezoneOptions); // get currency preference require_once('modules/Currencies/ListCurrency.php'); $currency = new ListCurrency(); $cur_id = $locale->getPrecedentPreference('currency', $current_user); if($cur_id) { $selectCurrency = $currency->getSelectOptions($cur_id); $this->ss->assign("CURRENCY", $selectCurrency); } else { $selectCurrency = $currency->getSelectOptions(); $this->ss->assign("CURRENCY", $selectCurrency); } $currenciesVars = ""; $i=0; foreach($locale->currencies as $id => $arrVal) { $currenciesVars .= "currencies[{$i}] = '{$arrVal['symbol']}';\n"; $i++; } $currencySymbolsJs = <<ss->assign('currencySymbolJs', $currencySymbolsJs); // fill significant digits dropdown $significantDigits = $locale->getPrecedentPreference('default_currency_significant_digits', $current_user); $sigDigits = ''; for($i=0; $i<=6; $i++) { if($significantDigits == $i) { $sigDigits .= ''; } else { $sigDigits .= ''; } } $this->ss->assign('sigDigits', $sigDigits); $num_grp_sep = $current_user->getPreference('num_grp_sep'); $dec_sep = $current_user->getPreference('dec_sep'); $this->ss->assign("NUM_GRP_SEP", ( empty($num_grp_sep) ? $sugar_config['default_number_grouping_seperator'] : $num_grp_sep )); $this->ss->assign("DEC_SEP", ( empty($dec_sep) ? $sugar_config['default_decimal_seperator'] : $dec_sep )); $this->ss->assign('getNumberJs', $locale->getNumberJs()); // Name display format $this->ss->assign('default_locale_name_format', $locale->getLocaleFormatMacro($current_user)); $this->ss->assign('getNameJs', $locale->getNameJs()); // Charset $charsetOptions = get_select_options_with_id( $locale->getCharsetSelect(), $charset_for_import);//wdong, bug 25927, here we should use the charset testing results from above. $this->ss->assign('CHARSETOPTIONS', $charsetOptions); // handle building index selector global $dictionary, $current_language; require_once("include/templates/TemplateGroupChooser.php"); $chooser_array = array(); $chooser_array[0] = array(); $idc = new ImportDuplicateCheck($focus); $chooser_array[1] = $idc->getDuplicateCheckIndexes(); $chooser = new TemplateGroupChooser(); $chooser->args['id'] = 'selected_indices'; $chooser->args['values_array'] = $chooser_array; $chooser->args['left_name'] = 'choose_index'; $chooser->args['right_name'] = 'ignore_index'; $chooser->args['left_label'] = $mod_strings['LBL_INDEX_USED']; $chooser->args['right_label'] = $mod_strings['LBL_INDEX_NOT_USED']; $this->ss->assign("TAB_CHOOSER", $chooser->display()); // show notes if ( $focus instanceof Person ) $module_key = "LBL_CONTACTS_NOTE_"; elseif ( $focus instanceof Company ) $module_key = "LBL_ACCOUNTS_NOTE_"; else $module_key = "LBL_".strtoupper($_REQUEST['import_module'])."_NOTE_"; $notetext = ''; for ($i = 1;isset($mod_strings[$module_key.$i]);$i++) { $notetext .= '
  • ' . $mod_strings[$module_key.$i] . '
  • '; } $this->ss->assign("NOTETEXT",$notetext); $this->ss->assign("HAS_HEADER",($has_header ? 'on' : 'off' )); // get list of required fields $required = array(); foreach ( array_keys($focus->get_import_required_fields()) as $name ) { $properties = $focus->getFieldDefinition($name); if (!empty ($properties['vname'])) $required[$name] = str_replace(":","",translate($properties['vname'] ,$focus->module_dir)); else $required[$name] = str_replace(":","",translate($properties['name'] ,$focus->module_dir)); } // include anything needed for quicksearch to work require_once("include/TemplateHandler/TemplateHandler.php"); $quicksearch_js = TemplateHandler::createQuickSearchCode($fields,$fields,'importstep3'); $this->ss->assign("JAVASCRIPT", $quicksearch_js . "\n" . $this->_getJS($required)); $this->ss->assign('required_fields',implode(', ',$required)); $this->ss->display('modules/Import/tpls/step3.tpl'); } /** * Returns JS used in this view */ private function _getJS($required) { global $mod_strings; $print_required_array = ""; foreach ($required as $name=>$display) { $print_required_array .= "required['$name'] = '". $display . "';\n"; } $sqsWaitImage = SugarThemeRegistry::current()->getImageURL('sqsWait.gif'); return << EOJAVASCRIPT; } }