]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/Import/views/view.step3.php
Release 6.2.0
[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 Community Edition 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($browserTitle = false)
97         {
98             global $mod_strings, $app_list_strings;
99             
100             $iconPath = $this->getModuleTitleIconPath($this->module);
101             $returnArray = array();
102             if (!empty($iconPath) && !$browserTitle) {
103                 $returnArray[] = "<a href='index.php?module={$_REQUEST['import_module']}&action=index'><img src='{$iconPath}' alt='{$app_list_strings['moduleList'][$_REQUEST['import_module']]}' title='{$app_list_strings['moduleList'][$_REQUEST['import_module']]}' align='absmiddle'></a>";
104         }
105         else {
106             $returnArray[] = $app_list_strings['moduleList'][$_REQUEST['import_module']];
107         }
108             $returnArray[] = "<a href='index.php?module=Import&action=Step1&import_module={$_REQUEST['import_module']}'>".$mod_strings['LBL_MODULE_NAME']."</a>";
109             $returnArray[] = $mod_strings['LBL_STEP_3_TITLE'];
110         
111             return $returnArray;
112     }
113
114         /**
115      * @see SugarView::display()
116      */
117         public function display()
118     {
119         global $mod_strings, $app_strings, $current_user, $sugar_config, $app_list_strings, $locale;
120         
121         $this->ss->assign("IMPORT_MODULE", $_REQUEST['import_module']);
122         $has_header = ( isset( $_REQUEST['has_header']) ? 1 : 0 );
123         $sugar_config['import_max_records_per_file'] =
124             ( empty($sugar_config['import_max_records_per_file'])
125                 ? 1000 : $sugar_config['import_max_records_per_file'] );
126         
127         // Clear out this user's last import
128         $seedUsersLastImport = new UsersLastImport();
129         $seedUsersLastImport->mark_deleted_by_user_id($current_user->id);
130         ImportCacheFiles::clearCacheFiles();
131
132         // attempt to lookup a preexisting field map
133         // use the custom one if specfied to do so in step 1
134         $field_map = array();
135         $default_values = array();
136                 $ignored_fields = array();
137         if ( !empty( $_REQUEST['source_id'])) {
138             $mapping_file = new ImportMap();
139             $mapping_file->retrieve( $_REQUEST['source_id'],false);
140             $_REQUEST['source'] = $mapping_file->source;
141             $has_header = $mapping_file->has_header;
142             if (isset($mapping_file->delimiter))
143                 $_REQUEST['custom_delimiter'] = $mapping_file->delimiter;
144             if (isset($mapping_file->enclosure))
145                 $_REQUEST['custom_enclosure'] = htmlentities($mapping_file->enclosure);
146             $field_map = $mapping_file->getMapping();
147                         $default_values = $mapping_file->getDefaultValues();
148             $this->ss->assign("MAPNAME",$mapping_file->name);
149             $this->ss->assign("CHECKMAP",'checked="checked" value="on"');
150         }
151         else {
152             // Try to see if we have a custom mapping we can use
153             // based upon the where the records are coming from
154             // and what module we are importing into
155             $classname = 'ImportMap' . ucfirst($_REQUEST['source']);
156             if ( file_exists("modules/Import/{$classname}.php") )
157                 require_once("modules/Import/{$classname}.php");
158             elseif ( file_exists("custom/modules/Import/{$classname}.php") )
159                 require_once("custom/modules/Import/{$classname}.php");
160             else {
161                 require_once("custom/modules/Import/ImportMapOther.php");
162                 $classname = 'ImportMapOther';
163                 $_REQUEST['source'] = 'other';
164             }
165             if ( class_exists($classname) ) {
166                 $mapping_file = new $classname;
167                 if (isset($mapping_file->delimiter)) 
168                     $_REQUEST['custom_delimiter'] = $mapping_file->delimiter;
169                 if (isset($mapping_file->enclosure)) 
170                     $_REQUEST['custom_enclosure'] = htmlentities($mapping_file->enclosure);
171                 $ignored_fields = $mapping_file->getIgnoredFields($_REQUEST['import_module']);
172                 $field_map = $mapping_file->getMapping($_REQUEST['import_module']);
173             }
174         }
175
176         $this->ss->assign("CUSTOM_DELIMITER",
177             ( !empty($_REQUEST['custom_delimiter']) ? $_REQUEST['custom_delimiter'] : "," ));
178         $this->ss->assign("CUSTOM_ENCLOSURE",
179             ( !empty($_REQUEST['custom_enclosure']) ? $_REQUEST['custom_enclosure'] : "" ));
180
181         // handle uploaded file
182         $uploadFile = new UploadFile('userfile');
183         if (isset($_FILES['userfile']) && $uploadFile->confirm_upload())
184         {
185             $uploadFile->final_move('IMPORT_'.$this->bean->object_name.'_'.$current_user->id);
186             $uploadFileName = $uploadFile->get_upload_path('IMPORT_'.$this->bean->object_name.'_'.$current_user->id);
187         }
188         else {
189             $this->_showImportError($mod_strings['LBL_IMPORT_MODULE_ERROR_NO_UPLOAD'],$_REQUEST['import_module'],'Step2');
190             return;
191         }
192
193         // split file into parts
194         $splitter = new ImportFileSplitter(
195                 $uploadFileName,
196                 $sugar_config['import_max_records_per_file']);
197         $splitter->splitSourceFile(
198                 $_REQUEST['custom_delimiter'],
199                 html_entity_decode($_REQUEST['custom_enclosure'],ENT_QUOTES),
200                 $has_header
201             );
202
203         // Now parse the file and look for errors
204         $importFile = new ImportFile(
205                 $uploadFileName,
206                 $_REQUEST['custom_delimiter'],
207                 html_entity_decode($_REQUEST['custom_enclosure'],ENT_QUOTES)
208             );
209
210         if ( !$importFile->fileExists() ) {
211             $this->_showImportError($mod_strings['LBL_CANNOT_OPEN'],$_REQUEST['import_module'],'Step2');
212             return;
213         }
214
215         // retrieve first 3 rows
216         $rows = array();
217         $system_charset = $locale->default_export_charset;
218         $user_charset = $locale->getExportCharset();
219         $other_charsets = 'UTF-8, UTF-7, ASCII, CP1252, EUC-JP, SJIS, eucJP-win, SJIS-win, JIS, ISO-2022-JP';
220         $detectable_charsets = "UTF-8, {$user_charset}, {$system_charset}, {$other_charsets}";
221         // Bug 26824 - mb_detect_encoding() thinks CP1252 is IS0-8859-1, so use that instead in the encoding list passed to the function
222         $detectable_charsets = str_replace('CP1252','ISO-8859-1',$detectable_charsets);
223         $charset_for_import = $user_charset; //We will set the default import charset option by user's preference.
224         $able_to_detect = function_exists('mb_detect_encoding');
225         for ( $i = 0; $i < 3; $i++ ) {
226             $rows[$i] = $importFile->getNextRow();
227             if(!empty($rows[$i]) && $able_to_detect) {
228                 foreach($rows[$i] as & $temp_value) {
229                     $current_charset = mb_detect_encoding($temp_value, $detectable_charsets);
230                     if(!empty($current_charset) && $current_charset != "UTF-8") {
231                         $temp_value = $locale->translateCharset($temp_value, $current_charset);// we will use utf-8 for displaying the data on the page.
232                         $charset_for_import = $current_charset;
233                         //set the default import charset option according to the current_charset.
234                         //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.
235                     }
236                 }
237             }
238         }
239         $ret_field_count = $importFile->getFieldCount();
240
241         // Bug 14689 - Parse the first data row to make sure it has non-empty data in it
242         $isempty = true;
243         if ( $rows[(int)$has_header] != false ) {
244             foreach ( $rows[(int)$has_header] as $value ) {
245                 if ( strlen(trim($value)) > 0 ) {
246                     $isempty = false;
247                     break;
248                 }
249             }
250         }
251
252         if ($isempty || $rows[(int)$has_header] == false) {
253             $this->_showImportError($mod_strings['LBL_NO_LINES'],$_REQUEST['import_module'],'Step2');
254             return;
255         }
256
257         // save first row to send to step 4
258         $this->ss->assign("FIRSTROW", base64_encode(serialize($rows[0])));
259
260         // Now build template
261         $this->ss->assign("TMP_FILE", $uploadFileName );
262         $this->ss->assign("FILECOUNT", $splitter->getFileCount() );
263         $this->ss->assign("RECORDCOUNT", $splitter->getRecordCount() );
264         $this->ss->assign("RECORDTHRESHOLD", $sugar_config['import_max_records_per_file']);
265         $this->ss->assign("SOURCE", $_REQUEST['source'] );
266         $this->ss->assign("TYPE", $_REQUEST['type'] );
267         $this->ss->assign("DELETE_INLINE_PNG",  SugarThemeRegistry::current()->getImage('basic_search','align="absmiddle" alt="'.$app_strings['LNK_DELETE'].'" border="0"'));
268         $this->ss->assign("PUBLISH_INLINE_PNG",  SugarThemeRegistry::current()->getImage('advanced_search','align="absmiddle" alt="'.$mod_strings['LBL_PUBLISH'].'" border="0"'));
269         $this->ss->assign("MODULE_TITLE", $this->getModuleTitle());
270         $this->ss->assign("STEP4_TITLE",
271             strip_tags(str_replace("\n","",getClassicModuleTitle(
272                 $mod_strings['LBL_MODULE_NAME'],
273                 array($mod_strings['LBL_MODULE_NAME'],$mod_strings['LBL_STEP_4_TITLE']),
274                 false
275                 )))
276             );
277         $this->ss->assign("HEADER", $app_strings['LBL_IMPORT']." ". $mod_strings['LBL_MODULE_NAME']);
278
279         // we export it as email_address, but import as email1
280         $field_map['email_address'] = 'email1';
281
282         // build each row; row count is determined by the the number of fields in the import file
283         $columns = array();
284         $mappedFields = array();
285
286         for($field_count = 0; $field_count < $ret_field_count; $field_count++) {
287             // See if we have any field map matches
288             $defaultValue = "";
289             // Bug 31260 - If the data rows have more columns than the header row, then just add a new header column
290             if ( !isset($rows[0][$field_count]) )
291                 $rows[0][$field_count] = '';
292             // See if we can match the import row to a field in the list of fields to import
293             $firstrow_name = trim(str_replace(":","",$rows[0][$field_count]));
294             if ($has_header && isset( $field_map[$firstrow_name] ) ) {
295                 $defaultValue = $field_map[$firstrow_name];
296             }
297             elseif (isset($field_map[$field_count])) {
298                 $defaultValue = $field_map[$field_count];
299             }
300             elseif (empty( $_REQUEST['source_id'])) {
301                 $defaultValue = trim($rows[0][$field_count]);
302             }
303
304             // build string of options
305             $fields  = $this->bean->get_importable_fields();
306             $options = array();
307             $defaultField = '';
308             foreach ( $fields as $fieldname => $properties ) {
309                 // get field name
310                 if (!empty ($properties['vname']))
311                                         $displayname = str_replace(":","",translate($properties['vname'] ,$this->bean->module_dir));
312                 else
313                                         $displayname = str_replace(":","",translate($properties['name'] ,$this->bean->module_dir));
314                 // see if this is required
315                 $req_mark  = "";
316                 $req_class = "";
317                 if ( array_key_exists($fieldname, $this->bean->get_import_required_fields()) ) {
318                     $req_mark  = ' ' . $app_strings['LBL_REQUIRED_SYMBOL'];
319                     $req_class = ' class="required" ';
320                 }
321                 // see if we have a match
322                 $selected = '';
323                 if ( !empty($defaultValue) && !in_array($fieldname,$mappedFields)
324                                                 && !in_array($fieldname,$ignored_fields) ) {
325                     if ( strtolower($fieldname) == strtolower($defaultValue)
326                         || strtolower($fieldname) == str_replace(" ","_",strtolower($defaultValue))
327                         || strtolower($displayname) == strtolower($defaultValue)
328                         || strtolower($displayname) == str_replace(" ","_",strtolower($defaultValue)) ) {
329                         $selected = ' selected="selected" ';
330                         $defaultField = $fieldname;
331                         $mappedFields[] = $fieldname;
332                     }
333                 }
334                 // get field type information
335                 $fieldtype = '';
336                 if ( isset($properties['type'])
337                         && isset($mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])]) )
338                     $fieldtype = ' [' . $mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])] . '] ';
339                 if ( isset($properties['comment']) )
340                     $fieldtype .= ' - ' . $properties['comment'];
341                 $options[$displayname.$fieldname] = '<option value="'.$fieldname.'" title="'. $displayname . htmlentities($fieldtype) . '"'
342                     . $selected . $req_class . '>' . $displayname . $req_mark . '</option>\n';
343             }
344
345             // get default field value
346             $defaultFieldHTML = '';
347             if ( !empty($defaultField) ) {
348                 $defaultFieldHTML = getControl(
349                     $_REQUEST['import_module'],
350                     $defaultField,
351                     $fields[$defaultField],
352                     ( isset($default_values[$defaultField]) ? $default_values[$defaultField] : '' )
353                     );
354             }
355
356             if ( isset($default_values[$defaultField]) )
357                 unset($default_values[$defaultField]);
358
359             // Bug 27046 - Sort the column name picker alphabetically
360             ksort($options);
361
362             $columns[] = array(
363                 'field_choices' => implode('',$options),
364                 'default_field' => $defaultFieldHTML,
365                 'cell1'         => str_replace("&quot;",'',htmlspecialchars($rows[0][$field_count])),
366                 'cell2'         => str_replace("&quot;",'',htmlspecialchars($rows[1][$field_count])),
367                 'cell3'         => str_replace("&quot;",'',htmlspecialchars($rows[2][$field_count])),
368                 'show_remove'   => false,
369                 );
370         }
371
372         // add in extra defaulted fields if they are in the mapping record
373         if ( count($default_values) > 0 ) {
374             foreach ( $default_values as $field_name => $default_value ) {
375                 // build string of options
376                 $fields  = $this->bean->get_importable_fields();
377                 $options = array();
378                 $defaultField = '';
379                 foreach ( $fields as $fieldname => $properties ) {
380                     // get field name
381                     if (!empty ($properties['vname']))
382                         $displayname = str_replace(":","",translate($properties['vname'] ,$this->bean->module_dir));
383                     else
384                         $displayname = str_replace(":","",translate($properties['name'] ,$this->bean->module_dir));
385                     // see if this is required
386                     $req_mark  = "";
387                     $req_class = "";
388                     if ( array_key_exists($fieldname, $this->bean->get_import_required_fields()) ) {
389                         $req_mark  = ' ' . $app_strings['LBL_REQUIRED_SYMBOL'];
390                         $req_class = ' class="required" ';
391                     }
392                     // see if we have a match
393                     $selected = '';
394                     if ( strtolower($fieldname) == strtolower($field_name)
395                                                         && !in_array($fieldname,$mappedFields)
396                                                         && !in_array($fieldname,$ignored_fields) ) {
397                         $selected = ' selected="selected" ';
398                         $defaultField = $fieldname;
399                         $mappedFields[] = $fieldname;
400                     }
401                     // get field type information
402                     $fieldtype = '';
403                     if ( isset($properties['type'])
404                             && isset($mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])]) )
405                         $fieldtype = ' [' . $mod_strings['LBL_IMPORT_FIELDDEF_' . strtoupper($properties['type'])] . '] ';
406                     if ( isset($properties['comment']) )
407                         $fieldtype .= ' - ' . $properties['comment'];
408                     $options[$displayname.$fieldname] = '<option value="'.$fieldname.'" title="'. $displayname . $fieldtype . '"' . $selected . $req_class . '>'
409                         . $displayname . $req_mark . '</option>\n';
410                 }
411
412                 // get default field value
413                 $defaultFieldHTML = '';
414                 if ( !empty($defaultField) ) {
415                     $defaultFieldHTML = getControl(
416                         $_REQUEST['import_module'],
417                         $defaultField,
418                         $fields[$defaultField],
419                         $default_value
420                         );
421                 }
422
423                 // Bug 27046 - Sort the column name picker alphabetically
424                 ksort($options);
425
426                 $columns[] = array(
427                     'field_choices' => implode('',$options),
428                     'default_field' => $defaultFieldHTML,
429                     'show_remove'   => true,
430                     );
431
432                 $ret_field_count++;
433             }
434         }
435
436         $this->ss->assign("COLUMNCOUNT",$ret_field_count);
437         $this->ss->assign("rows",$columns);
438
439         // get list of valid date/time formats
440         $timeFormat = $current_user->getUserDateTimePreferences();
441         $timeOptions = get_select_options_with_id($sugar_config['time_formats'], $timeFormat['time']);
442         $dateOptions = get_select_options_with_id($sugar_config['date_formats'], $timeFormat['date']);
443         $this->ss->assign('TIMEOPTIONS', $timeOptions);
444         $this->ss->assign('DATEOPTIONS', $dateOptions);
445         $this->ss->assign('datetimeformat', $GLOBALS['timedate']->get_cal_date_time_format());
446
447         // get list of valid timezones
448         $userTZ = $current_user->getPreference('timezone');
449         if(empty($userTZ))
450             $userTZ = TimeDate::userTimezone();
451
452         $this->ss->assign('TIMEZONE_CURRENT', $userTZ);
453         $this->ss->assign('TIMEZONEOPTIONS', TimeDate::getTimezoneList());
454
455         // get currency preference
456         require_once('modules/Currencies/ListCurrency.php');
457         $currency = new ListCurrency();
458         $cur_id = $locale->getPrecedentPreference('currency', $current_user);
459         if($cur_id) {
460             $selectCurrency = $currency->getSelectOptions($cur_id);
461             $this->ss->assign("CURRENCY", $selectCurrency);
462         } else {
463             $selectCurrency = $currency->getSelectOptions();
464             $this->ss->assign("CURRENCY", $selectCurrency);
465         }
466
467         $currenciesVars = "";
468         $i=0;
469         foreach($locale->currencies as $id => $arrVal) {
470             $currenciesVars .= "currencies[{$i}] = '{$arrVal['symbol']}';\n";
471             $i++;
472         }
473         $currencySymbolsJs = <<<eoq
474 var currencies = new Object;
475 {$currenciesVars}
476 function setSymbolValue(id) {
477     document.getElementById('symbol').value = currencies[id];
478 }
479 eoq;
480         $this->ss->assign('currencySymbolJs', $currencySymbolsJs);
481
482
483         // fill significant digits dropdown
484         $significantDigits = $locale->getPrecedentPreference('default_currency_significant_digits', $current_user);
485         $sigDigits = '';
486         for($i=0; $i<=6; $i++) {
487             if($significantDigits == $i) {
488                $sigDigits .= '<option value="'.$i.'" selected="true">'.$i.'</option>';
489             } else {
490                $sigDigits .= '<option value="'.$i.'">'.$i.'</option>';
491             }
492         }
493
494         $this->ss->assign('sigDigits', $sigDigits);
495
496         $num_grp_sep = $current_user->getPreference('num_grp_sep');
497         $dec_sep = $current_user->getPreference('dec_sep');
498         $this->ss->assign("NUM_GRP_SEP",
499             ( empty($num_grp_sep)
500                 ? $sugar_config['default_number_grouping_seperator'] : $num_grp_sep ));
501         $this->ss->assign("DEC_SEP",
502             ( empty($dec_sep)
503                 ? $sugar_config['default_decimal_seperator'] : $dec_sep ));
504         $this->ss->assign('getNumberJs', $locale->getNumberJs());
505
506         // Name display format
507         $this->ss->assign('default_locale_name_format', $locale->getLocaleFormatMacro($current_user));
508         $this->ss->assign('getNameJs', $locale->getNameJs());
509
510         // Charset
511         $charsetOptions = get_select_options_with_id(
512             $locale->getCharsetSelect(), $charset_for_import);//wdong,  bug 25927, here we should use the charset testing results from above.
513         $this->ss->assign('CHARSETOPTIONS', $charsetOptions);
514
515         // handle building index selector
516         global $dictionary, $current_language;
517
518         require_once("include/templates/TemplateGroupChooser.php");
519
520         $chooser_array = array();
521         $chooser_array[0] = array();
522         $idc = new ImportDuplicateCheck($this->bean);
523         $chooser_array[1] = $idc->getDuplicateCheckIndexes();
524
525         $chooser = new TemplateGroupChooser();
526         $chooser->args['id'] = 'selected_indices';
527         $chooser->args['values_array'] = $chooser_array;
528         $chooser->args['left_name'] = 'choose_index';
529         $chooser->args['right_name'] = 'ignore_index';
530         $chooser->args['left_label'] =  $mod_strings['LBL_INDEX_USED'];
531         $chooser->args['right_label'] =  $mod_strings['LBL_INDEX_NOT_USED'];
532         $this->ss->assign("TAB_CHOOSER", $chooser->display());
533
534         // show notes
535         if ( $this->bean instanceof Person )
536             $module_key = "LBL_CONTACTS_NOTE_";
537         elseif ( $this->bean instanceof Company )
538             $module_key = "LBL_ACCOUNTS_NOTE_";
539         else
540             $module_key = "LBL_".strtoupper($_REQUEST['import_module'])."_NOTE_";
541         $notetext = '';
542         for ($i = 1;isset($mod_strings[$module_key.$i]);$i++) {
543             $notetext .= '<li>' . $mod_strings[$module_key.$i] . '</li>';
544         }
545         $this->ss->assign("NOTETEXT",$notetext);
546         $this->ss->assign("HAS_HEADER",($has_header ? 'on' : 'off' ));
547
548         // get list of required fields
549         $required = array();
550         foreach ( array_keys($this->bean->get_import_required_fields()) as $name ) {
551             $properties = $this->bean->getFieldDefinition($name);
552             if (!empty ($properties['vname']))
553                 $required[$name] = str_replace(":","",translate($properties['vname'] ,$this->bean->module_dir));
554             else
555                 $required[$name] = str_replace(":","",translate($properties['name'] ,$this->bean->module_dir));
556         }
557         // include anything needed for quicksearch to work
558         require_once("include/TemplateHandler/TemplateHandler.php");
559         $quicksearch_js = TemplateHandler::createQuickSearchCode($fields,$fields,'importstep3');
560         $this->ss->assign("JAVASCRIPT", $quicksearch_js . "\n" . $this->_getJS($required));
561
562         $this->ss->assign('required_fields',implode(', ',$required));
563         $this->ss->display('modules/Import/tpls/step3.tpl');
564     }
565
566     /**
567      * Displays the Smarty template for an error
568      *
569      * @param string $message error message to show
570      * @param string $module what module we were importing into
571      * @param string $action what page we should go back to
572      */
573     protected function _showImportError(
574         $message, 
575         $module,
576         $action = 'Step1'
577         )
578     {
579         $ss = new Sugar_Smarty();
580         
581         $ss->assign("MESSAGE",$message);
582         $ss->assign("ACTION",$action);
583         $ss->assign("IMPORT_MODULE",$module);
584         $ss->assign("MOD", $GLOBALS['mod_strings']);
585         $ss->assign("SOURCE","");
586         if ( isset($_REQUEST['source']) )
587             $ss->assign("SOURCE", $_REQUEST['source']);
588         
589         echo $ss->fetch('modules/Import/tpls/error.tpl');
590     }
591     
592     /**
593      * Returns JS used in this view
594      *
595      * @param  array $required fields that are required for the import
596      * @return string HTML output with JS code
597      */
598     protected function _getJS($required)
599     {
600         global $mod_strings;
601
602         $print_required_array = "";
603         foreach ($required as $name=>$display) {
604             $print_required_array .= "required['$name'] = '". $display . "';\n";
605         }
606
607         $sqsWaitImage = SugarThemeRegistry::current()->getImageURL('sqsWait.gif');
608
609         return <<<EOJAVASCRIPT
610 <script type="text/javascript">
611 <!--
612 document.getElementById('goback').onclick = function(){
613     document.getElementById('importstep3').action.value = 'Step2';
614     document.getElementById('importstep3').to_pdf.value = '0';
615     return true;
616 }
617
618 document.getElementById('importnow').onclick = function(){
619     // get the list of indices chosen
620     var chosen_indices = '';
621     var selectedOptions = document.getElementById('choose_index_td').getElementsByTagName('select')[0].options.length;
622     for (i = 0; i < selectedOptions; i++)
623     {
624         chosen_indices += document.getElementById('choose_index_td').getElementsByTagName('select')[0].options[i].value;
625         if (i != (selectedOptions - 1))
626             chosen_indices += "&";
627     }
628     document.getElementById('importstep3').display_tabs_def.value = chosen_indices;
629
630     // validate form
631     clear_all_errors();
632     var form = document.getElementById('importstep3');
633     var hash = new Object();
634     var required = new Object();
635     $print_required_array
636     var isError = false;
637     for ( i = 0; i < form.length; i++ ) {
638                 if ( form.elements[i].name.indexOf("colnum",0) == 0) {
639             if ( form.elements[i].value == "-1") {
640                 continue;
641             }
642             if ( hash[ form.elements[i].value ] == 1) {
643                 isError = true;
644                 add_error_style('importstep3',form.elements[i].name,"{$mod_strings['ERR_MULTIPLE']}");
645             }
646             hash[form.elements[i].value] = 1;
647         }
648     }
649
650     // check for required fields
651         for(var field_name in required) {
652                 // contacts hack to bypass errors if full_name is set
653                 if (field_name == 'last_name' &&
654                                 hash['full_name'] == 1) {
655                         continue;
656                 }
657                 if ( hash[ field_name ] != 1 ) {
658             isError = true;
659             add_error_style('importstep3',form.colnum_0.name,
660                 "{$mod_strings['ERR_MISSING_REQUIRED_FIELDS']} " + required[field_name]);
661                 }
662         }
663
664     // return false if we got errors
665         if (isError == true) {
666                 return false;
667         }
668
669     // Move on to next step
670     document.getElementById('importstep3').action.value = 'Step4';
671     ProcessImport.begin();
672 }
673
674 // handle adding new row
675 document.getElementById('addrow').onclick = function(){
676     rownum = document.getElementById('importstep3').columncount.value;
677     newrow = document.createElement("tr");
678
679     column0 = document.getElementById('row_0_col_0').cloneNode(true);
680     column0.id = 'row_' + rownum + '_col_0';
681     for ( i = 0; i < column0.childNodes.length; i++ ) {
682         if ( column0.childNodes[i].name == 'colnum_0' ) {
683             column0.childNodes[i].name = 'colnum_' + rownum;
684             column0.childNodes[i].onchange = function(){
685                 var module    = document.getElementById('importstep3').import_module.value;
686                 var fieldname = this.value;
687                 var matches   = /colnum_([0-9]+)/i.exec(this.name);
688                 var fieldnum  = matches[1];
689                 if ( fieldname == -1 ) {
690                     document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '';
691                     return;
692                 }
693                 document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '<img src="{$sqsWaitImage}" />'
694                 YAHOO.util.Connect.asyncRequest('GET', 'index.php?module=Import&action=GetControl&import_module='+module+'&field_name='+fieldname,
695                     {
696                         success: function(o)
697                         {
698                                 document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = o.responseText;
699                             SUGAR.util.evalScript(o.responseText);
700                             enableQS(true);
701                         },
702                         failure: function(o) {/*failure handler code*/}
703                     });
704             }
705         }
706     }
707     newrow.appendChild(column0);
708
709     if ( document.getElementById('row_0_header') ) {
710         column1 = document.getElementById('row_0_header').cloneNode(true);
711         column1.innerHTML = '&nbsp;';
712         newrow.appendChild(column1);
713     }
714
715     column2 = document.getElementById('defaultvaluepicker_0').cloneNode(true);
716     column2.id = 'defaultvaluepicker_' + rownum;
717     newrow.appendChild(column2);
718
719     column3 = document.createElement('td');
720     column3.className = 'tabDetailViewDL';
721     if ( !document.getElementById('row_0_header') ) {
722         column3.colSpan = 2;
723     }
724     column3.innerHTML = '<input title="{$mod_strings['LBL_REMOVE_ROW']}" accessKey="" id="deleterow_' + rownum + '" class="button" type="button" value="  {$mod_strings['LBL_REMOVE_ROW']}  ">';
725     newrow.appendChild(column3);
726
727     document.getElementById('importstep3').columncount.value = parseInt(document.getElementById('importstep3').columncount.value) + 1;
728
729     document.getElementById('row_0_col_0').parentNode.parentNode.insertBefore(newrow,this.parentNode.parentNode);
730
731     document.getElementById('deleterow_' + rownum).onclick = function(){
732         this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
733     }
734 }
735
736 YAHOO.util.Event.onDOMReady(function(){
737     var selects = document.getElementsByTagName('select');
738     for (var i = 0; i < selects.length; ++i ){
739         if (selects[i].name.indexOf("colnum_") != -1 ) {
740             // fetch the field input control via ajax
741             selects[i].onchange = function(){
742                 var module    = document.getElementById('importstep3').import_module.value;
743                 var fieldname = this.value;
744                 var matches   = /colnum_([0-9]+)/i.exec(this.name);
745                 var fieldnum  = matches[1];
746                 if ( fieldname == -1 ) {
747                     document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '';
748                     return;
749                 }
750
751                 document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = '<img src="{$sqsWaitImage}" />'
752                 YAHOO.util.Connect.asyncRequest('GET', 'index.php?module=Import&action=GetControl&import_module='+module+'&field_name='+fieldname,
753                     {
754                         success: function(o)
755                         {
756                             document.getElementById('defaultvaluepicker_'+fieldnum).innerHTML = o.responseText;
757                             SUGAR.util.evalScript(o.responseText);
758                             enableQS(true);
759                         },
760                         failure: function(o) {/*failure handler code*/}
761                     });
762             }
763         }
764     }
765     var inputs = document.getElementsByTagName('input');
766     for (var i = 0; i < inputs.length; ++i ){
767         if (inputs[i].id.indexOf("deleterow_") != -1 ) {
768             inputs[i].onclick = function(){
769                 this.parentNode.parentNode.parentNode.removeChild(this.parentNode.parentNode);
770             }
771         }
772     }
773 });
774
775 document.getElementById('toggleImportOptions').onclick = function() {
776     if (document.getElementById('importOptions').style.display == 'none'){
777         document.getElementById('importOptions').style.display = '';
778         document.getElementById('toggleImportOptions').value='  {$mod_strings['LBL_HIDE_ADVANCED_OPTIONS']}  ';
779         document.getElementById('toggleImportOptions').title='{$mod_strings['LBL_HIDE_ADVANCED_OPTIONS']}';
780     }
781     else {
782         document.getElementById('importOptions').style.display = 'none';
783         document.getElementById('toggleImportOptions').value='  {$mod_strings['LBL_SHOW_ADVANCED_OPTIONS']}  ';
784         document.getElementById('toggleImportOptions').title='{$mod_strings['LBL_SHOW_ADVANCED_OPTIONS']}';
785     }
786 }
787
788 -->
789 </script>
790
791 EOJAVASCRIPT;
792     }
793 }