]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Import/views/view.step3.php
Release 6.1.4
[Github/sugarcrm.git] / modules / Import / views / view.step3.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38 /*********************************************************************************
39
40  * Description: view handler for step 3 of the import process
41  * Portions created by SugarCRM are Copyright (C) SugarCRM, Inc.
42  * All Rights Reserved.
43  ********************************************************************************/
44 require_once('include/MVC/View/SugarView.php');
45 require_once('modules/Import/ImportFile.php');
46 require_once('modules/Import/ImportFileSplitter.php');
47 require_once('modules/Import/ImportCacheFiles.php');
48 require_once('modules/Import/ImportDuplicateCheck.php');
49
50 require_once('include/upload_file.php');    
51
52 class ImportViewStep3 extends SugarView 
53 {       
54     /**
55      * @see SugarView::getMenu()
56      */
57     public function getMenu(
58         $module = null
59         )
60     {
61         global $mod_strings, $current_language;
62         
63         if ( empty($module) )
64             $module = $_REQUEST['import_module'];
65         
66         $old_mod_strings = $mod_strings;
67         $mod_strings = return_module_language($current_language, $module);
68         $returnMenu = parent::getMenu($module);
69         $mod_strings = $old_mod_strings;
70         
71         return $returnMenu;
72     }
73     
74         /**
75      * @see SugarView::_getModuleTab()
76      */
77         protected function _getModuleTab()
78     {
79         global $app_list_strings, $moduleTabMap;
80         
81                 // Need to figure out what tab this module belongs to, most modules have their own tabs, but there are exceptions.
82         if ( !empty($_REQUEST['module_tab']) )
83             return $_REQUEST['module_tab'];
84         elseif ( isset($moduleTabMap[$_REQUEST['import_module']]) )
85             return $moduleTabMap[$_REQUEST['import_module']];
86         // Default anonymous pages to be under Home
87         elseif ( !isset($app_list_strings['moduleList'][$_REQUEST['import_module']]) )
88             return 'Home';
89         else
90             return $_REQUEST['import_module'];
91         }
92         
93         /**
94          * @see SugarView::_getModuleTitleParams()
95          */
96         protected function _getModuleTitleParams()
97         {
98             global $mod_strings;
99             
100         return array(
101            "<a href='index.php?module={$_REQUEST['import_module']}&action=index'><img src='".SugarThemeRegistry::current()->getImageURL('icon_'.$_REQUEST['import_module'].'_32.png')."' alt='".$_REQUEST['import_module']."' title='".$_REQUEST['import_module']."' align='absmiddle'></a>",
102            "<a href='index.php?module=Import&action=Step1&import_module={$_REQUEST['import_module']}'>".$mod_strings['LBL_MODULE_NAME']."</a>",
103            $mod_strings['LBL_STEP_3_TITLE'],
104            );
105     }
106     
107         /** 
108      * @see SugarView::display()
109      */
110         public function display()
111     {
112         global $mod_strings, $app_strings, $current_user, $sugar_config, $app_list_strings, $locale;
113         $this->ss->assign("MOD", $mod_strings);
114         $this->ss->assign("APP", $app_strings);
115         $this->ss->assign("IMPORT_MODULE", $_REQUEST['import_module']);
116         $has_header = ( isset( $_REQUEST['has_header']) ? 1 : 0 );
117         $sugar_config['import_max_records_per_file'] =  
118             ( empty($sugar_config['import_max_records_per_file']) 
119                 ? 1000 : $sugar_config['import_max_records_per_file'] );
120         
121         // load the bean for the import module
122         $focus = loadImportBean($_REQUEST['import_module']);
123         if ( !$focus ) {
124             showImportError($mod_strings['LBL_ERROR_IMPORTS_NOT_SET_UP'],$_REQUEST['import_module']);
125             return;
126         }
127         
128         // Clear out this user's last import
129         $seedUsersLastImport = new UsersLastImport();
130         $seedUsersLastImport->mark_deleted_by_user_id($current_user->id);
131         ImportCacheFiles::clearCacheFiles();
132         
133         // attempt to lookup a preexisting field map
134         // use the custom one if specfied to do so in step 1
135         $field_map = array();
136         $default_values = array();
137                 $ignored_fields = array();
138         if ( !empty( $_REQUEST['source_id'])) {
139             $mapping_file = new ImportMap();
140             $mapping_file->retrieve( $_REQUEST['source_id'],false);
141             $_REQUEST['source'] = $mapping_file->source;
142             $has_header = $mapping_file->has_header;
143             if (isset($mapping_file->delimiter)) 
144                 $_REQUEST['custom_delimiter'] = $mapping_file->delimiter;
145             if (isset($mapping_file->enclosure)) 
146                 $_REQUEST['custom_enclosure'] = htmlentities($mapping_file->enclosure);
147             $field_map = $mapping_file->getMapping();
148                         $default_values = $mapping_file->getDefaultValues();
149             $this->ss->assign("MAPNAME",$mapping_file->name);
150             $this->ss->assign("CHECKMAP",'checked="checked" value="on"');
151         }
152         else {
153             // Try to see if we have a custom mapping we can use
154             // based upon the where the records are coming from 
155             // and what module we are importing into
156             $classname = 'ImportMap' . ucfirst($_REQUEST['source']);
157             require("modules/Import/{$classname}.php");
158             $mapping_file = new $classname;
159             if (isset($mapping_file->delimiter)) 
160                 $_REQUEST['custom_delimiter'] = $mapping_file->delimiter;
161             if (isset($mapping_file->enclosure)) 
162                 $_REQUEST['custom_enclosure'] = htmlentities($mapping_file->enclosure);
163             $ignored_fields = $mapping_file->getIgnoredFields($_REQUEST['import_module']);
164             $field_map = $mapping_file->getMapping($_REQUEST['import_module']);
165         }
166         
167         $this->ss->assign("CUSTOM_DELIMITER",
168             ( !empty($_REQUEST['custom_delimiter']) ? $_REQUEST['custom_delimiter'] : "," ));
169         $this->ss->assign("CUSTOM_ENCLOSURE",
170             ( !empty($_REQUEST['custom_enclosure']) ? $_REQUEST['custom_enclosure'] : "" ));
171         
172         // handle uploaded file
173         $uploadFile = new UploadFile('userfile');
174         if (isset($_FILES['userfile']) && $uploadFile->confirm_upload())
175         {
176             $uploadFile->final_move('IMPORT_'.$focus->object_name.'_'.$current_user->id);
177             $uploadFileName = $uploadFile->get_upload_path('IMPORT_'.$focus->object_name.'_'.$current_user->id);
178         }
179         else {
180             showImportError($mod_strings['LBL_IMPORT_MODULE_ERROR_NO_UPLOAD'],$_REQUEST['import_module'],'Step2');
181             return;
182         }
183         
184         // split file into parts
185         $splitter = new ImportFileSplitter(
186                 $uploadFileName,
187                 $sugar_config['import_max_records_per_file']);
188         $splitter->splitSourceFile(
189                 $_REQUEST['custom_delimiter'],
190                 html_entity_decode($_REQUEST['custom_enclosure'],ENT_QUOTES),
191                 $has_header
192             );
193         
194         // Now parse the file and look for errors
195         $importFile = new ImportFile(
196                 $uploadFileName,
197                 $_REQUEST['custom_delimiter'],
198                 html_entity_decode($_REQUEST['custom_enclosure'],ENT_QUOTES)
199             );
200         
201         if ( !$importFile->fileExists() ) {
202             showImportError($mod_strings['LBL_CANNOT_OPEN'],$_REQUEST['import_module'],'Step2');
203             return;
204         }
205         
206         // retrieve first 3 rows
207         $rows = array();
208         $system_charset = $locale->default_export_charset;
209         $user_charset = $locale->getExportCharset();
210         $other_charsets = 'UTF-8, UTF-7, ASCII, EUC-JP,SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP';
211         $charset_for_import = $user_charset; //We will set the default import charset option by user's preference.
212         $able_to_detect = function_exists('mb_detect_encoding');
213         for ( $i = 0; $i < 3; $i++ ) {
214             $rows[$i] = $importFile->getNextRow();
215             if(!empty($rows[$i]) && $able_to_detect) {
216                 foreach($rows[$i] as & $temp_value) {
217                     $current_charset = mb_detect_encoding($temp_value, "UTF-8, {$user_charset}, {$system_charset}, {$other_charsets}");
218                     if(!empty($current_charset) && $current_charset != "UTF-8") {
219                         $temp_value = $locale->translateCharset($temp_value, $current_charset);// we will use utf-8 for displaying the data on the page.
220                         $charset_for_import = $current_charset;
221                         //set the default import charset option according to the current_charset.
222                         //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.
223                     }
224                 }
225             }
226         }
227         $ret_field_count = $importFile->getFieldCount();
228         
229         // Bug 14689 - Parse the first data row to make sure it has non-empty data in it
230         $isempty = true;
231         if ( $rows[(int)$has_header] != false ) {
232             foreach ( $rows[(int)$has_header] as $value ) {
233                 if ( strlen(trim($value)) > 0 ) {
234                     $isempty = false;
235                     break;
236                 }
237             }
238         }
239         
240         if ($isempty || $rows[(int)$has_header] == false) {
241             showImportError($mod_strings['LBL_NO_LINES'],$_REQUEST['import_module'],'Step2');
242             return;
243         }
244         
245         // save first row to send to step 4
246         $this->ss->assign("FIRSTROW", base64_encode(serialize($rows[0])));
247         
248         // Now build template
249         $this->ss->assign("TMP_FILE", $uploadFileName );
250         $this->ss->assign("FILECOUNT", $splitter->getFileCount() );
251         $this->ss->assign("RECORDCOUNT", $splitter->getRecordCount() );
252         $this->ss->assign("RECORDTHRESHOLD", $sugar_config['import_max_records_per_file']);
253         $this->ss->assign("SOURCE", $_REQUEST['source'] );
254         $this->ss->assign("TYPE", $_REQUEST['type'] );
255         $this->ss->assign("DELETE_INLINE_PNG",  SugarThemeRegistry::current()->getImage('basic_search','align="absmiddle" alt="'.$app_strings['LNK_DELETE'].'" border="0"'));
256         $this->ss->assign("PUBLISH_INLINE_PNG",  SugarThemeRegistry::current()->getImage('advanced_search','align="absmiddle" alt="'.$mod_strings['LBL_PUBLISH'].'" border="0"'));
257         $this->ss->assign("MODULE_TITLE", $this->getModuleTitle());
258         $this->ss->assign("STEP4_TITLE", 
259             strip_tags(str_replace("\n","",get_module_title(
260                 $mod_strings['LBL_MODULE_NAME'], 
261                 $mod_strings['LBL_MODULE_NAME']." ".$mod_strings['LBL_STEP_4_TITLE'], 
262                 false
263                 )))
264             );
265         $this->ss->assign("HEADER", $app_strings['LBL_IMPORT']." ". $mod_strings['LBL_MODULE_NAME']);
266         
267         // we export it as email_address, but import as email1
268         $field_map['email_address'] = 'email1';
269         
270         // build each row; row count is determined by the the number of fields in the import file
271         $columns = array();
272         $mappedFields = array();
273
274         for($field_count = 0; $field_count < $ret_field_count; $field_count++) {
275             // See if we have any field map matches
276             $defaultValue = "";
277             // Bug 31260 - If the data rows have more columns than the header row, then just add a new header column
278             if ( !isset($rows[0][$field_count]) )
279                 $rows[0][$field_count] = '';
280             // See if we can match the import row to a field in the list of fields to import
281             $firstrow_name = trim(str_replace(":","",$rows[0][$field_count]));
282             if ($has_header && isset( $field_map[$firstrow_name] ) ) {
283                 $defaultValue = $field_map[$firstrow_name];
284             }
285             elseif (isset($field_map[$field_count])) {
286                 $defaultValue = $field_map[$field_count];
287             }
288             elseif (empty( $_REQUEST['source_id'])) {
289                 $defaultValue = trim($rows[0][$field_count]);
290             }
291         
292             // build string of options
293             $fields  = $focus->get_importable_fields();
294             $options = array();
295             $defaultField = '';
296             foreach ( $fields as $fieldname => $properties ) {
297                 // get field name
298                 if (!empty ($properties['vname']))
299                                         $displayname = str_replace(":","",translate($properties['vname'] ,$focus->module_dir));
300                 else
301                                         $displayname = str_replace(":","",translate($properties['name'] ,$focus->module_dir));
302                 // see if this is required
303                 $req_mark  = "";
304                 $req_class = "";
305                 if ( array_key_exists($fieldname, $focus->get_import_required_fields()) ) {
306                     $req_mark  = ' ' . $app_strings['LBL_REQUIRED_SYMBOL'];
307                     $req_class = ' class="required" ';
308                 }
309                 // see if we have a match
310                 $selected = '';
311                 if ( !empty($defaultValue) && !in_array($fieldname,$mappedFields) 
312                                                 && !in_array($fieldname,$ignored_fields) ) {
313                     if ( strtolower($fieldname) == strtolower($defaultValue)
314                         || strtolower($fieldname) == str_replace(" ","_",strtolower($defaultValue))
315                         || strtolower($displayname) == strtolower($defaultValue)
316                         || strtolower($displayname) == str_replace(" ","_",strtolower($defaultValue)) ) {
317                         $selected = ' selected="selected" ';
318                         $defaultField = $fieldname;
319                         $mappedFields[] = $fieldname;
320                     }
321                 }
322                 // get field type information
323                 $fieldtype = '';
324                 if ( isset($properties['type']) 
325                         && isset($mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])]) )
326                     $fieldtype = ' [' . $mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])] . '] ';
327                 if ( isset($properties['comment']) )
328                     $fieldtype .= ' - ' . $properties['comment'];
329                 $options[$displayname.$fieldname] = '<option value="'.$fieldname.'" title="'. $displayname . htmlentities($fieldtype) . '"'
330                     . $selected . $req_class . '>' . $displayname . $req_mark . '</option>\n';
331             }
332             
333             // get default field value
334             $defaultFieldHTML = '';
335             if ( !empty($defaultField) ) {
336                 $defaultFieldHTML = getControl(
337                     $_REQUEST['import_module'],
338                     $defaultField,
339                     $fields[$defaultField],
340                     ( isset($default_values[$defaultField]) ? $default_values[$defaultField] : '' )
341                     );
342             }
343             
344             if ( isset($default_values[$defaultField]) )
345                 unset($default_values[$defaultField]);
346             
347             // Bug 27046 - Sort the column name picker alphabetically
348             ksort($options);
349             
350             $columns[] = array(
351                 'field_choices' => implode('',$options),
352                 'default_field' => $defaultFieldHTML,
353                 'cell1'         => str_replace("&quot;",'',htmlspecialchars($rows[0][$field_count])),
354                 'cell2'         => str_replace("&quot;",'',htmlspecialchars($rows[1][$field_count])),
355                 'cell3'         => str_replace("&quot;",'',htmlspecialchars($rows[2][$field_count])),
356                 'show_remove'   => false,
357                 );
358         }
359
360         // add in extra defaulted fields if they are in the mapping record
361         if ( count($default_values) > 0 ) {
362             foreach ( $default_values as $field_name => $default_value ) {
363                 // build string of options
364                 $fields  = $focus->get_importable_fields();
365                 $options = array();
366                 $defaultField = '';
367                 foreach ( $fields as $fieldname => $properties ) {
368                     // get field name
369                     if (!empty ($properties['vname']))
370                         $displayname = str_replace(":","",translate($properties['vname'] ,$focus->module_dir));
371                     else
372                         $displayname = str_replace(":","",translate($properties['name'] ,$focus->module_dir));
373                     // see if this is required
374                     $req_mark  = "";
375                     $req_class = "";
376                     if ( array_key_exists($fieldname, $focus->get_import_required_fields()) ) {
377                         $req_mark  = ' ' . $app_strings['LBL_REQUIRED_SYMBOL'];
378                         $req_class = ' class="required" ';
379                     }
380                     // see if we have a match
381                     $selected = '';
382                     if ( strtolower($fieldname) == strtolower($field_name) 
383                                                         && !in_array($fieldname,$mappedFields) 
384                                                         && !in_array($fieldname,$ignored_fields) ) {
385                         $selected = ' selected="selected" ';
386                         $defaultField = $fieldname;
387                         $mappedFields[] = $fieldname;
388                     }
389                     // get field type information
390                     $fieldtype = '';
391                     if ( isset($properties['type']) 
392                             && isset($mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])]) )
393                         $fieldtype = ' [' . $mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])] . '] ';
394                     if ( isset($properties['comment']) )
395                         $fieldtype .= ' - ' . $properties['comment'];
396                     $options[$displayname.$fieldname] = '<option value="'.$fieldname.'" title="'. $displayname . $fieldtype . '"' . $selected . $req_class . '>' 
397                         . $displayname . $req_mark . '</option>\n';
398                 }
399                 
400                 // get default field value
401                 $defaultFieldHTML = '';
402                 if ( !empty($defaultField) ) {
403                     $defaultFieldHTML = getControl(
404                         $_REQUEST['import_module'],
405                         $defaultField,
406                         $fields[$defaultField],
407                         $default_value
408                         );
409                 }
410                 
411                 // Bug 27046 - Sort the column name picker alphabetically
412                 ksort($options);
413             
414                 $columns[] = array(
415                     'field_choices' => implode('',$options),
416                     'default_field' => $defaultFieldHTML,
417                     'show_remove'   => true,
418                     );
419                 
420                 $ret_field_count++;
421             }
422         }
423         
424         $this->ss->assign("COLUMNCOUNT",$ret_field_count);
425         $this->ss->assign("rows",$columns);
426         
427         // get list of valid date/time formats
428         $timeFormat = $current_user->getUserDateTimePreferences();
429         $timeOptions = get_select_options_with_id($sugar_config['time_formats'], $timeFormat['time']);
430         $dateOptions = get_select_options_with_id($sugar_config['date_formats'], $timeFormat['date']);
431         $this->ss->assign('TIMEOPTIONS', $timeOptions);
432         $this->ss->assign('DATEOPTIONS', $dateOptions);
433         $this->ss->assign('datetimeformat', $GLOBALS['timedate']->get_cal_date_time_format());
434         
435         // get list of valid timezones
436         require_once('include/timezone/timezones.php');
437         global $timezones;
438         
439         $userTZ = $current_user->getPreference('timezone');
440         if(empty($userTZ))
441             $userTZ = lookupTimezone();
442         
443         $timezoneOptions = '';
444         ksort($timezones);
445         foreach($timezones as $key => $value) {
446             $selected =($userTZ == $key) ? ' SELECTED="true"' : '';
447             $dst = !empty($value['dstOffset']) ? '(+DST)' : '';
448             $gmtOffset =($value['gmtOffset'] / 60);
449         
450             if(!strstr($gmtOffset,'-')) {
451                 $gmtOffset = '+'.$gmtOffset;
452             }
453                         $timezoneOptions .= "<option value='$key'".$selected.">".str_replace(array('_','North'), array(' ', 'N.'),translate('timezone_dom','',$key)). "(GMT".$gmtOffset.") ".$dst."</option>";
454         }
455         $this->ss->assign('TIMEZONEOPTIONS', $timezoneOptions);
456
457         // get currency preference
458         require_once('modules/Currencies/ListCurrency.php');
459         $currency = new ListCurrency(); 
460         $cur_id = $locale->getPrecedentPreference('currency', $current_user);
461         if($cur_id) {
462             $selectCurrency = $currency->getSelectOptions($cur_id);
463             $this->ss->assign("CURRENCY", $selectCurrency);
464         } else {
465             $selectCurrency = $currency->getSelectOptions();
466             $this->ss->assign("CURRENCY", $selectCurrency);
467         }
468         
469         $currenciesVars = "";
470         $i=0;
471         foreach($locale->currencies as $id => $arrVal) {
472             $currenciesVars .= "currencies[{$i}] = '{$arrVal['symbol']}';\n";
473             $i++;
474         }
475         $currencySymbolsJs = <<<eoq
476 var currencies = new Object;
477 {$currenciesVars}
478 function setSymbolValue(id) {
479     document.getElementById('symbol').value = currencies[id];
480 }
481 eoq;
482         $this->ss->assign('currencySymbolJs', $currencySymbolsJs);
483         
484         
485         // fill significant digits dropdown
486         $significantDigits = $locale->getPrecedentPreference('default_currency_significant_digits', $current_user);
487         $sigDigits = '';
488         for($i=0; $i<=6; $i++) {
489             if($significantDigits == $i) {
490                $sigDigits .= '<option value="'.$i.'" selected="true">'.$i.'</option>';
491             } else {
492                $sigDigits .= '<option value="'.$i.'">'.$i.'</option>';
493             }
494         }
495         
496         $this->ss->assign('sigDigits', $sigDigits);
497         
498         $num_grp_sep = $current_user->getPreference('num_grp_sep');
499         $dec_sep = $current_user->getPreference('dec_sep');
500         $this->ss->assign("NUM_GRP_SEP",
501             ( empty($num_grp_sep) 
502                 ? $sugar_config['default_number_grouping_seperator'] : $num_grp_sep ));
503         $this->ss->assign("DEC_SEP",
504             ( empty($dec_sep) 
505                 ? $sugar_config['default_decimal_seperator'] : $dec_sep ));
506         $this->ss->assign('getNumberJs', $locale->getNumberJs());
507         
508         // Name display format
509         $this->ss->assign('default_locale_name_format', $locale->getLocaleFormatMacro($current_user));
510         $this->ss->assign('getNameJs', $locale->getNameJs());
511         
512         // Charset
513         $charsetOptions = get_select_options_with_id(
514             $locale->getCharsetSelect(), $charset_for_import);//wdong,  bug 25927, here we should use the charset testing results from above.
515         $this->ss->assign('CHARSETOPTIONS', $charsetOptions);
516         
517         // handle building index selector
518         global $dictionary, $current_language;
519         
520         require_once("include/templates/TemplateGroupChooser.php");
521         
522         $chooser_array = array();
523         $chooser_array[0] = array();
524         $idc = new ImportDuplicateCheck($focus);
525         $chooser_array[1] = $idc->getDuplicateCheckIndexes();
526         
527         $chooser = new TemplateGroupChooser();
528         $chooser->args['id'] = 'selected_indices';
529         $chooser->args['values_array'] = $chooser_array;
530         $chooser->args['left_name'] = 'choose_index';
531         $chooser->args['right_name'] = 'ignore_index';
532         $chooser->args['left_label'] =  $mod_strings['LBL_INDEX_USED'];
533         $chooser->args['right_label'] =  $mod_strings['LBL_INDEX_NOT_USED'];
534         $this->ss->assign("TAB_CHOOSER", $chooser->display());
535         
536         // show notes
537         if ( $focus instanceof Person )
538             $module_key = "LBL_CONTACTS_NOTE_";
539         elseif ( $focus instanceof Company )
540             $module_key = "LBL_ACCOUNTS_NOTE_";
541         else
542             $module_key = "LBL_".strtoupper($_REQUEST['import_module'])."_NOTE_";
543         $notetext = '';
544         for ($i = 1;isset($mod_strings[$module_key.$i]);$i++) {
545             $notetext .= '<li>' . $mod_strings[$module_key.$i] . '</li>';
546         }
547         $this->ss->assign("NOTETEXT",$notetext);
548         $this->ss->assign("HAS_HEADER",($has_header ? 'on' : 'off' ));
549         
550         // get list of required fields
551         $required = array();
552         foreach ( array_keys($focus->get_import_required_fields()) as $name ) {
553             $properties = $focus->getFieldDefinition($name);
554             if (!empty ($properties['vname']))
555                 $required[$name] = str_replace(":","",translate($properties['vname'] ,$focus->module_dir));
556             else
557                 $required[$name] = str_replace(":","",translate($properties['name'] ,$focus->module_dir));
558         }
559         // include anything needed for quicksearch to work
560         require_once("include/TemplateHandler/TemplateHandler.php");
561         $quicksearch_js = TemplateHandler::createQuickSearchCode($fields,$fields,'importstep3');
562         $this->ss->assign("JAVASCRIPT", $quicksearch_js . "\n" . $this->_getJS($required));
563         
564         $this->ss->assign('required_fields',implode(', ',$required));
565         $this->ss->display('modules/Import/tpls/step3.tpl');
566     }
567     
568     /**
569      * Returns JS used in this view
570      */
571     private function _getJS($required)
572     {
573         global $mod_strings;
574         
575         $print_required_array = "";
576         foreach ($required as $name=>$display) {
577             $print_required_array .= "required['$name'] = '". $display . "';\n";
578         }
579         
580         $sqsWaitImage = SugarThemeRegistry::current()->getImageURL('sqsWait.gif');
581         
582         return <<<EOJAVASCRIPT
583 <script type="text/javascript">
584 <!--
585 document.getElementById('goback').onclick = function(){
586     document.getElementById('importstep3').action.value = 'Step2';
587     document.getElementById('importstep3').to_pdf.value = '0';
588     return true;
589 }
590
591 document.getElementById('importnow').onclick = function(){
592     // get the list of indices chosen
593     var chosen_indices = '';
594     var selectedOptions = document.getElementById('choose_index_td').getElementsByTagName('select')[0].options.length;
595     for (i = 0; i < selectedOptions; i++)
596     {
597         chosen_indices += document.getElementById('choose_index_td').getElementsByTagName('select')[0].options[i].value;
598         if (i != (selectedOptions - 1))
599             chosen_indices += "&";
600     }
601     document.getElementById('importstep3').display_tabs_def.value = chosen_indices;
602     
603     // validate form
604     clear_all_errors();
605     var form = document.getElementById('importstep3');
606     var hash = new Object();
607     var required = new Object();
608     $print_required_array
609     var isError = false;
610     for ( i = 0; i < form.length; i++ ) {
611                 if ( form.elements[i].name.indexOf("colnum",0) == 0) {
612             if ( form.elements[i].value == "-1") {
613                 continue;
614             }
615             if ( hash[ form.elements[i].value ] == 1) {
616                 isError = true;
617                 add_error_style('importstep3',form.elements[i].name,"{$mod_strings['ERR_MULTIPLE']}");
618             }
619             hash[form.elements[i].value] = 1;
620         }
621     }
622
623     // check for required fields
624         for(var field_name in required) {
625                 // contacts hack to bypass errors if full_name is set
626                 if (field_name == 'last_name' &&
627                                 hash['full_name'] == 1) {
628                         continue;
629                 }
630                 if ( hash[ field_name ] != 1 ) {
631             isError = true;
632             add_error_style('importstep3',form.colnum_0.name,
633                 "{$mod_strings['ERR_MISSING_REQUIRED_FIELDS']} " + required[field_name]);
634                 }
635         }
636
637     // return false if we got errors
638         if (isError == true) {
639                 return false;
640         }
641     
642     // Move on to next step
643     document.getElementById('importstep3').action.value = 'Step4';
644     ProcessImport.begin();
645 }
646
647 // handle adding new row
648 document.getElementById('addrow').onclick = function(){
649     rownum = document.getElementById('importstep3').columncount.value;
650     newrow = document.createElement("tr");
651     
652     column0 = document.getElementById('row_0_col_0').cloneNode(true);
653     column0.id = 'row_' + rownum + '_col_0';
654     for ( i = 0; i < column0.childNodes.length; i++ ) {
655         if ( column0.childNodes[i].name == 'colnum_0' ) {
656             column0.childNodes[i].name = 'colnum_' + rownum;
657             column0.childNodes[i].onchange = function(){
658                 var module    = document.getElementById('importstep3').import_module.value;
659                 var fieldname = this.value;
660                 var matches   = /colnum_([0-9]+)/i.exec(this.name);
661                 var fieldnum  = matches[1];
662                 if ( fieldname == -1 ) {
663                     document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '';
664                     return;
665                 }
666                 document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '<img src="{$sqsWaitImage}" />'            
667                 YAHOO.util.Connect.asyncRequest('GET', 'index.php?module=Import&action=GetControl&import_module='+module+'&field_name='+fieldname,
668                     {
669                         success: function(o) 
670                         {  
671                                 document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = o.responseText;
672                             SUGAR.util.evalScript(o.responseText);
673                             enableQS(true);
674                         },
675                         failure: function(o) {/*failure handler code*/}
676                     });
677             }
678         }
679     }
680     newrow.appendChild(column0);
681     
682     if ( document.getElementById('row_0_header') ) {
683         column1 = document.getElementById('row_0_header').cloneNode(true);
684         column1.innerHTML = '&nbsp;';
685         newrow.appendChild(column1);
686     }
687     
688     column2 = document.getElementById('defaultvaluepicker_0').cloneNode(true);
689     column2.id = 'defaultvaluepicker_' + rownum;
690     newrow.appendChild(column2);
691     
692     column3 = document.createElement('td');
693     column3.className = 'tabDetailViewDL';
694     if ( !document.getElementById('row_0_header') ) {
695         column3.colSpan = 2;
696     }
697     column3.innerHTML = '<input title="{$mod_strings['LBL_REMOVE_ROW']}" accessKey="" id="deleterow_' + rownum + '" class="button" type="button" value="  {$mod_strings['LBL_REMOVE_ROW']}  ">';
698     newrow.appendChild(column3);
699     
700     document.getElementById('importstep3').columncount.value = parseInt(document.getElementById('importstep3').columncount.value) + 1;
701     
702     document.getElementById('row_0_col_0').parentNode.parentNode.insertBefore(newrow,this.parentNode.parentNode);
703     
704     document.getElementById('deleterow_' + rownum).onclick = function(){
705         this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
706     }
707 }
708
709 YAHOO.util.Event.onDOMReady(function(){ 
710     var selects = document.getElementsByTagName('select');
711     for (var i = 0; i < selects.length; ++i ){ 
712         if (selects[i].name.indexOf("colnum_") != -1 ) {
713             // fetch the field input control via ajax
714             selects[i].onchange = function(){
715                 var module    = document.getElementById('importstep3').import_module.value;
716                 var fieldname = this.value;
717                 var matches   = /colnum_([0-9]+)/i.exec(this.name);
718                 var fieldnum  = matches[1];
719                 if ( fieldname == -1 ) {
720                     document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '';
721                     return;
722                 }
723               
724                 document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '<img src="{$sqsWaitImage}" />'
725                 YAHOO.util.Connect.asyncRequest('GET', 'index.php?module=Import&action=GetControl&import_module='+module+'&field_name='+fieldname,
726                     {
727                         success: function(o) 
728                         { 
729                             document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = o.responseText;
730                             SUGAR.util.evalScript(o.responseText);
731                             enableQS(true);
732                         },
733                         failure: function(o) {/*failure handler code*/}
734                     });
735             }
736         }
737     }
738     var inputs = document.getElementsByTagName('input');
739     for (var i = 0; i < inputs.length; ++i ){ 
740         if (inputs[i].id.indexOf("deleterow_") != -1 ) {
741             inputs[i].onclick = function(){
742                 this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
743             }
744         }
745     }
746 });
747
748 document.getElementById('toggleImportOptions').onclick = function() {
749     if (document.getElementById('importOptions').style.display == 'none'){
750         document.getElementById('importOptions').style.display = '';
751         document.getElementById('toggleImportOptions').value='  {$mod_strings['LBL_HIDE_ADVANCED_OPTIONS']}  ';
752         document.getElementById('toggleImportOptions').title='{$mod_strings['LBL_HIDE_ADVANCED_OPTIONS']}';
753     }
754     else {
755         document.getElementById('importOptions').style.display = 'none';
756         document.getElementById('toggleImportOptions').value='  {$mod_strings['LBL_SHOW_ADVANCED_OPTIONS']}  ';
757         document.getElementById('toggleImportOptions').title='{$mod_strings['LBL_SHOW_ADVANCED_OPTIONS']}';
758     }
759 }
760
761 -->
762 </script>
763
764 EOJAVASCRIPT;
765     }
766 }