]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/EditView/EditView2.php
Release 6.2.4
[Github/sugarcrm.git] / include / EditView / EditView2.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM Community Edition is a customer relationship management program developed by
4  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
5  * 
6  * This program is free software; you can redistribute it and/or modify it under
7  * the terms of the GNU Affero General Public License version 3 as published by the
8  * Free Software Foundation with the addition of the following permission added
9  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
10  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
11  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
12  * 
13  * This program is distributed in the hope that it will be useful, but WITHOUT
14  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
15  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
16  * details.
17  * 
18  * You should have received a copy of the GNU Affero General Public License along with
19  * this program; if not, see http://www.gnu.org/licenses or write to the Free
20  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
21  * 02110-1301 USA.
22  * 
23  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
24  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
25  * 
26  * The interactive user interfaces in modified source and object code versions
27  * of this program must display Appropriate Legal Notices, as required under
28  * Section 5 of the GNU Affero General Public License version 3.
29  * 
30  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
31  * these Appropriate Legal Notices must retain the display of the "Powered by
32  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
33  * technical reasons, the Appropriate Legal Notices must display the words
34  * "Powered by SugarCRM".
35  ********************************************************************************/
36
37
38
39 require_once('include/TemplateHandler/TemplateHandler.php');
40 require_once('include/EditView/SugarVCR.php');
41
42 class EditView
43 {
44     public $th;
45     public $tpl;
46     public $notes;
47     public $id;
48     public $metadataFile;
49     public $headerTpl;
50     public $footerTpl;
51     public $returnAction;
52     public $returnModule;
53     public $returnId;
54     public $isDuplicate;
55     public $focus;
56     public $module;
57     public $fieldDefs;
58     public $sectionPanels;
59     public $view = 'EditView';
60     public $formatFields = true;
61     public $showDetailData = true;
62     public $showVCRControl = true;
63     public $showSectionPanelsTitles = true;
64     public $quickSearchCode;
65     public $ss;
66     public $offset = 0;
67     public $populateBean = true;
68     public $moduleTitleKey;
69     public $viewObject = null;
70     public $formName = '';
71
72     /**
73      * EditView constructor
74      * This is the EditView constructor responsible for processing the new
75      * Meta-Data framework
76      *
77      * @param $module String value of module this Edit view is for
78      * @param $focus An empty sugarbean object of module
79      * @param $id The record id to retrieve and populate data for
80      * @param $metadataFile String value of file location to use in overriding default metadata file
81      * @param tpl String value of file location to use in overriding default Smarty template
82      * @param createFocus bool value to tell whether to create a new bean if we do not have one with an id, this is used from ConvertLead
83      *
84      */
85     function setup($module, $focus = null, $metadataFile = null, $tpl = 'include/EditView/EditView.tpl', $createFocus = true)
86     {
87         $this->th = new TemplateHandler();
88         $this->th->ss =& $this->ss;
89         $this->tpl = $tpl;
90         $this->module = $module;
91         $this->focus = $focus;
92
93         //this logic checks if the focus has an id and if it does not then it will create a new instance of the focus bean
94         //but in convert lead we do not want to create a new instance and do not want to populate id.
95         if ($createFocus)
96         {
97             $this->createFocus();
98         }
99
100         if (empty($GLOBALS['sugar_config']['showDetailData']))
101         {
102             $this->showDetailData = false;
103         }
104         $this->metadataFile = $metadataFile;
105
106         if (isset($GLOBALS['sugar_config']['disable_vcr']))
107         {
108            $this->showVCRControl = !$GLOBALS['sugar_config']['disable_vcr'];
109         }
110
111         if (!empty($this->metadataFile) && file_exists($this->metadataFile))
112         {
113             include($this->metadataFile);
114         }
115         else
116         {
117             //If file doesn't exist we create a best guess
118             if (!file_exists("modules/$this->module/metadata/editviewdefs.php")
119                 && file_exists("modules/$this->module/EditView.html"))
120             {
121                 require_once('include/SugarFields/Parsers/EditViewMetaParser.php');
122
123                 global $dictionary;
124
125                 $htmlFile = "modules/" . $this->module . "/EditView.html";
126                 $parser = new EditViewMetaParser();
127                 if (!file_exists('modules/'.$this->module.'/metadata'))
128                 {
129                    sugar_mkdir('modules/'.$this->module.'/metadata');
130                 }
131
132                 $fp = sugar_fopen('modules/'.$this->module.'/metadata/editviewdefs.php', 'w');
133                 fwrite($fp, $parser->parse($htmlFile, $dictionary[$focus->object_name]['fields'], $this->module));
134                 fclose($fp);
135             }
136
137             //Flag an error... we couldn't create the best guess meta-data file
138             if (!file_exists("modules/$this->module/metadata/editviewdefs.php"))
139             {
140                 global $app_strings;
141
142                 $error = str_replace("[file]", "modules/$this->module/metadata/editviewdefs.php", $app_strings['ERR_CANNOT_CREATE_METADATA_FILE']);
143                 $GLOBALS['log']->fatal($error);
144                 echo $error;
145                 die();
146             }
147
148             require_once("modules/$this->module/metadata/editviewdefs.php");
149         }
150
151         $this->defs = $viewdefs[$this->module][$this->view];
152         $this->isDuplicate = isset($_REQUEST['isDuplicate']) && $_REQUEST['isDuplicate'] == 'true' && $this->focus->aclAccess('edit');
153     }
154
155     function createFocus()
156     {
157         global $beanList, $beanFiles;
158
159         if (empty($beanList[$this->module])) return;
160         if(!$this->focus )
161         {
162            $bean = $beanList[$this->module];
163            require_once($beanFiles[$bean]);
164            $obj = new $bean();
165            $this->focus = $obj;
166         }
167
168         //If there is no idea, assume we are creating a new instance
169         //and call the fill_in_additional_detail_fields where initialization
170         //code has been moved to
171         if (empty($this->focus->id))
172         {
173             global $current_user;
174
175             $this->focus->fill_in_additional_detail_fields();
176             $this->focus->assigned_user_id = $current_user->id;
177         }
178     }
179
180     function populateBean()
181     {
182         if (!empty($_REQUEST['record']) && $this->populateBean)
183         {
184            global $beanList;
185
186            $bean = $beanList[$this->module];
187            $obj = new $bean();
188            $this->focus = $obj->retrieve($_REQUEST['record']);
189         }
190         else
191         {
192            $GLOBALS['log']->debug("Unable to populate bean, no record parameter found");
193         }
194     }
195
196     /**
197      * enableFormatting
198      * This method is used to manually turn on/off the field formatting
199      * @param $format boolean value to turn on/off field formatting
200      */
201     function enableFormatting($format = true)
202     {
203         $this->formatFields = $format;
204     }
205
206     /**
207      * Enter description here ...
208      */
209     function requiredFirst()
210     {
211         $panels = array('required'=>array());
212         $reqCol = -1;
213         $reqRow = 0;
214         foreach($this->defs['panels'] as $key=>$p)
215         {
216             foreach ($p as $row=>$rowDef)
217             {
218                 foreach($rowDef as $col => $colDef)
219                 {
220                     $field = (is_array($p[$row][$col])) ? $p[$row][$col]['name'] : $p[$row][$col];
221                     if ((!empty($this->focus->field_defs[$field])
222                         && !empty($this->focus->field_defs[$field]['required']))
223                             || (!empty($p[$row][$col]['displayParams']['required'])))
224                     {
225                         $reqCol++;
226                         if ($reqCol == $this->defs['templateMeta']['maxColumns'])
227                         {
228                             $reqCol = -1;
229                             $reqRow++;
230                         }
231
232                         $panels['required'][$reqRow][$reqCol] = $p[$row][$col];
233                     }
234                     else
235                     {
236                         $panels[$key][$row][$col] = $p[$row][$col];
237                     }
238                 }
239             }
240         }
241
242         $this->defs['panels'] = $panels;
243     }
244
245     function render()
246     {
247         $totalWidth = 0;
248         foreach ($this->defs['templateMeta']['widths'] as $col => $def) {
249             foreach ($def as $k => $value) {
250                 $totalWidth += $value;
251             }
252         }
253
254         // calculate widths
255         foreach ($this->defs['templateMeta']['widths'] as $col => $def) {
256             foreach ($def as $k => $value) {
257                 $this->defs['templateMeta']['widths'][$col][$k] = round($value / ($totalWidth / 100), 2);
258             }
259         }
260
261         $this->sectionPanels = array();
262         $this->sectionLabels = array();
263         if (!empty($this->defs['panels']) && count($this->defs['panels']) > 0)
264         {
265            $keys = array_keys($this->defs['panels']);
266            if (is_numeric($keys[0]))
267            {
268                $defaultPanel = $this->defs['panels'];
269                unset($this->defs['panels']); //blow away current value
270                $this->defs['panels'][''] = $defaultPanel;
271            }
272         }
273
274         if ($this->view == 'EditView' && !empty($GLOBALS['sugar_config']['forms']['requireFirst'])){
275             $this->requiredFirst();
276         }
277
278         $maxColumns = isset($this->defs['templateMeta']['maxColumns']) ? $this->defs['templateMeta']['maxColumns'] : 2;
279         $panelCount = 0;
280         static $itemCount = 100; //Start the generated tab indexes at 100 so they don't step on custom ones.
281
282
283         /* loop all the panels */
284         foreach ($this->defs['panels'] as $key=>$p)
285         {
286             $panel = array();
287
288             if (!is_array($this->defs['panels'][$key])) {
289                $this->sectionPanels[strtoupper($key)] = $p;
290             }
291             else
292             {
293                                 foreach($p as $row=>$rowDef) {
294                                     $columnsInRows = count($rowDef);
295                                     $columnsUsed = 0;
296                                     foreach($rowDef as $col => $colDef) {
297                                         $panel[$row][$col] = is_array($p[$row][$col]) ? array('field' => $p[$row][$col]) : array('field' => array('name'=>$p[$row][$col]));
298                             $panel[$row][$col]['field']['tabindex'] = (isset($p[$row][$col]['tabindex']) && is_numeric($p[$row][$col]['tabindex'])) ? $p[$row][$col]['tabindex'] : $itemCount;
299
300                                         if($columnsInRows < $maxColumns) {
301                                             if($col == $columnsInRows - 1) {
302                                                 $panel[$row][$col]['colspan'] = 2 * $maxColumns - ($columnsUsed + 1);
303                                             } else {
304                                                 $panel[$row][$col]['colspan'] = floor(($maxColumns * 2 - $columnsInRows) / $columnsInRows);
305                                                 $columnsUsed = $panel[$row][$col]['colspan'];
306                                             }
307                                         }
308
309                                         //Set address types to have colspan value of 2 if colspan is not already defined
310                                         if(is_array($colDef) && !empty($colDef['hideLabel']) && !isset($panel[$row][$col]['colspan'])) {
311                                             $panel[$row][$col]['colspan'] = 2;
312                                         }
313
314                                         $itemCount++;
315
316                                     } //foreach
317                                 } //foreach
318
319                                         $panel = $this->getPanelWithFillers($panel);
320
321
322                                 $this->sectionPanels[strtoupper($key)] = $panel;
323                         }
324
325
326                 $panelCount++;
327                 } //foreach
328     }
329
330     /**
331      * Adds fillers to each row if required
332      *
333      * Panel alignment will be off if the panel doesn't have a row with the max column
334      * It will not be aligned to the other panels so we fill out the columns in the last row
335      *
336      * @param array $panel
337      * @return array
338      */
339     protected function getPanelWithFillers($panel)
340     {
341         $addFiller = true;
342         foreach($panel as $row)
343         {
344             if (count($row) == $this->defs['templateMeta']['maxColumns']
345                 || 1 == count($panel))
346             {
347                 $addFiller = false;
348                 break;
349             }
350         }
351
352         if ($addFiller)
353         {
354             $rowCount = count($panel);
355             $filler   = count($panel[$rowCount-1]);
356             while ($filler < $this->defs['templateMeta']['maxColumns'])
357             {
358                 $panel[$rowCount - 1][$filler++] = array('field' => array('name' => ''));
359             }
360         }
361
362         return $panel;
363     }    
364
365     function process($checkFormName = false, $formName = '')
366     {
367         global $mod_strings, $sugar_config, $app_strings, $app_list_strings;
368
369         //the retrieve already did this work;
370         //$this->focus->fill_in_relationship_fields();
371
372         if (!$this->th->checkTemplate($this->module, $this->view, $checkFormName, $formName))
373         {
374             $this->render();
375         }
376
377         if (isset($_REQUEST['offset']))
378         {
379             $this->offset = $_REQUEST['offset'] - 1;
380         }
381
382         if ($this->showVCRControl)
383         {
384             $this->th->ss->assign('PAGINATION', SugarVCR::menu($this->module, $this->offset, $this->focus->is_AuditEnabled(), ($this->view == 'EditView')));
385         }
386
387         if (isset($_REQUEST['return_module'])) $this->returnModule = $_REQUEST['return_module'];
388         if (isset($_REQUEST['return_action'])) $this->returnAction = $_REQUEST['return_action'];
389         if (isset($_REQUEST['return_id'])) $this->returnId = $_REQUEST['return_id'];
390         if (isset($_REQUEST['return_relationship'])) $this->returnRelationship = $_REQUEST['return_relationship'];
391         if (isset($_REQUEST['return_name'])) $this->returnName = $this->getValueFromRequest($_REQUEST, 'return_name' ) ;
392
393         // handle Create $module then Cancel
394         if (empty($this->returnId))
395         {
396             $this->returnAction = 'index';
397         }
398
399         $is_owner = $this->focus->isOwner($GLOBALS['current_user']->id);
400
401         $this->fieldDefs = array();
402         if ($this->focus)
403         {
404             global $current_user;
405
406             if (!empty($this->focus->assigned_user_id))
407             {
408                 $this->focus->assigned_user_name = get_assigned_user_name($this->focus->assigned_user_id);
409             }
410
411
412             foreach ($this->focus->toArray() as $name => $value)
413             {
414                 $valueFormatted = false;
415                 //if ($this->focus->field_defs[$name]['type']=='link')continue;
416
417                 $this->fieldDefs[$name] = (!empty($this->fieldDefs[$name]) && !empty($this->fieldDefs[$name]['value']))
418                     ? array_merge($this->focus->field_defs[$name], $this->fieldDefs[$name])
419                     : $this->focus->field_defs[$name];
420
421                 foreach (array("formula", "default", "comments", "help") as $toEscape)
422                 {
423                     if (!empty($this->fieldDefs[$name][$toEscape]))
424                     {
425                         $this->fieldDefs[$name][$toEscape] = htmlentities($this->fieldDefs[$name][$toEscape], ENT_QUOTES, 'UTF-8');
426                     }
427                 }
428
429                 if (isset($this->fieldDefs[$name]['options']) && isset($app_list_strings[$this->fieldDefs[$name]['options']]))
430                 {
431                     $this->fieldDefs[$name]['options'] = $app_list_strings[$this->fieldDefs[$name]['options']];
432                 }
433
434                 if (isset($this->fieldDefs[$name]['function']))
435                 {
436                     $function = $this->fieldDefs[$name]['function'];
437                     $function = (is_array($function) && isset($function['name']))
438                         ? $this->fieldDefs[$name]['function']['name']
439                         : $this->fieldDefs[$name]['function'];
440
441                     if (!empty($this->fieldDefs[$name]['function']['returns']) && $this->fieldDefs[$name]['function']['returns'] == 'html')
442                     {
443                         if (!empty($this->fieldDefs[$name]['function']['include']))
444                         {
445                             require_once($this->fieldDefs[$name]['function']['include']);
446                         }
447
448                         $value = $function($this->focus, $name, $value, $this->view);
449                         $valueFormatted = true;
450                     }
451                     else
452                     {
453                         $this->fieldDefs[$name]['options'] = $function($this->focus, $name, $value, $this->view);
454                     }
455                 }
456
457                 if (isset($this->fieldDefs[$name]['type']) && $this->fieldDefs[$name]['type'] == 'function' && isset($this->fieldDefs[$name]['function_name']))
458                 {
459                     $value = $this->callFunction($this->fieldDefs[$name]);
460                     $valueFormatted = true;
461                 }
462
463                 if (!$valueFormatted)
464                 {
465                     // $this->focus->format_field($this->focus->field_defs[$name]);
466                    $value = isset($this->focus->$name) ? $this->focus->$name : '';
467                 }
468
469                 if (empty($this->fieldDefs[$name]['value']))
470                 {
471                     $this->fieldDefs[$name]['value'] = $value;
472                 }
473
474
475                 //This code is used for QuickCreates that go to Full Form view
476                 if ($this->populateBean && empty($this->focus->id)
477                     && (isset($this->fieldDefs[$name]['function']['returns'])
478                         ? $this->fieldDefs[$name]['function']['returns'] != 'html'
479                         : true)
480                     && isset($_REQUEST[$name]))
481                 {
482                     $this->fieldDefs[$name]['value'] = $this->getValueFromRequest($_REQUEST, $name);
483                 }
484
485                /*
486                 * Populate any relate fields that are linked by a relationship to the calling module.
487                 * Clicking the create button on a subpanel for example will populate three values in the $_REQUEST:
488                 * 1. return_module => the name of the calling module
489                 * 2. return_id => the id of the record in the calling module that the user was viewing and that should be associated with this new record
490                 * 3. return_name => the display value of the return_id record - the value to show in any relate field in this EditView
491                 * Only do if this fieldDef does not already have a value; if it does it will have been explicitly set, and that should overrule this less specific mechanism
492                 */
493                 if (isset($this->returnModule) && isset($this->returnName)
494                     && empty($this->focus->id) && empty($this->fieldDefs['name']['value']) )
495                 {
496                    if (($this->focus->field_defs[$name]['type'] == 'relate')
497                        && isset($this->focus->field_defs[$name][ 'module' ])
498                        && $this->focus->field_defs[$name][ 'module' ] == $this->returnModule)
499                    {
500                        if (isset( $this->fieldDefs[$name]['id_name'])
501                            && !empty($this->returnRelationship)
502                            && isset($this->focus->field_defs[$this->fieldDefs[$name]['id_name']]['relationship'])
503                            && ($this->returnRelationship == $this->focus->field_defs[$this->fieldDefs[$name]['id_name']]['relationship']))
504                        {
505                            $this->fieldDefs[$name]['value'] =  $this->returnName ;
506                            // set the hidden id field for this relate field to the correct value i.e., return_id
507                            $this->fieldDefs[$this->fieldDefs[$name]['id_name']]['value'] = $this->returnId ;
508                        }
509                    }
510                 }
511             }
512         }
513
514         if (isset($this->focus->additional_meta_fields))
515         {
516             $this->fieldDefs = array_merge($this->fieldDefs, $this->focus->additional_meta_fields);
517         }
518
519         if ($this->isDuplicate)
520         {
521             foreach ($this->fieldDefs as $name=>$defs) {
522                 if (!empty($defs['auto_increment']))
523                 {
524                     $this->fieldDefs[$name]['value'] = '';
525                 }
526             }
527         }
528     }
529
530     /**
531      * display
532      * This method makes the Smarty variable assignments and then displays the
533      * generated view.
534      * @param $showTitle boolean value indicating whether or not to show a title on the resulting page
535      * @param $ajaxSave boolean value indicating whether or not the operation is an Ajax save request
536      * @return HTML display for view as String
537      */
538     function display($showTitle = true, $ajaxSave = false)
539     {
540         global $mod_strings, $sugar_config, $app_strings, $app_list_strings, $theme, $current_user;
541
542         if(isset($this->defs['templateMeta']['javascript']))
543         {
544             if(is_array($this->defs['templateMeta']['javascript']))
545             {
546                 //$this->th->ss->assign('externalJSFile', 'modules/' . $this->module . '/metadata/editvewdefs.js');
547                 $this->th->ss->assign('externalJSFile', $this->defs['templateMeta']['javascript']);
548             }
549             else
550             {
551                 $this->th->ss->assign('scriptBlocks', $this->defs['templateMeta']['javascript']);
552             }
553         }
554
555         $this->th->ss->assign('id', $this->fieldDefs['id']['value']);
556         $this->th->ss->assign('offset', $this->offset + 1);
557         $this->th->ss->assign('APP', $app_strings);
558         $this->th->ss->assign('MOD', $mod_strings);
559         $this->th->ss->assign('fields', $this->fieldDefs);
560         $this->th->ss->assign('sectionPanels', $this->sectionPanels);
561         $this->th->ss->assign('returnModule', $this->returnModule);
562         $this->th->ss->assign('returnAction', $this->returnAction);
563         $this->th->ss->assign('returnId', $this->returnId);
564         $this->th->ss->assign('isDuplicate', $this->isDuplicate);
565         $this->th->ss->assign('def', $this->defs);
566         $this->th->ss->assign('useTabs', isset($this->defs['templateMeta']['useTabs']) ? $this->defs['templateMeta']['useTabs'] : false);
567         $this->th->ss->assign('maxColumns', isset($this->defs['templateMeta']['maxColumns']) ? $this->defs['templateMeta']['maxColumns'] : 2);
568         $this->th->ss->assign('module', $this->module);
569         $this->th->ss->assign('headerTpl', isset($this->defs['templateMeta']['form']['headerTpl']) ? $this->defs['templateMeta']['form']['headerTpl'] : 'include/' . $this->view . '/header.tpl');
570         $this->th->ss->assign('footerTpl', isset($this->defs['templateMeta']['form']['footerTpl']) ? $this->defs['templateMeta']['form']['footerTpl'] : 'include/' . $this->view . '/footer.tpl');
571         $this->th->ss->assign('current_user', $current_user);
572         $this->th->ss->assign('bean', $this->focus);
573         $this->th->ss->assign('isAuditEnabled', $this->focus->is_AuditEnabled());
574         $this->th->ss->assign('gridline',$current_user->getPreference('gridline') == 'on' ? '1' : '0');
575
576         global $js_custom_version;
577         global $sugar_version;
578
579         $this->th->ss->assign('SUGAR_VERSION', $sugar_version);
580         $this->th->ss->assign('JS_CUSTOM_VERSION', $js_custom_version);
581
582         //this is used for multiple forms on one page
583         if (!empty($this->formName)) {
584             $form_id = $this->formName;
585             $form_name = $this->formName;
586         }
587         else
588         {
589             $form_id = $this->view;
590             $form_name = $this->view;
591         }
592
593         if ($ajaxSave && empty($this->formName))
594         {
595             $form_id = 'form_'.$this->view .'_'.$this->module;
596             $form_name = $form_id;
597             $this->view = $form_name;
598             //$this->defs['templateMeta']['form']['buttons'] = array();
599             //$this->defs['templateMeta']['form']['buttons']['ajax_save'] = array('id' => 'AjaxSave', 'customCode'=>'<input type="button" class="button" value="Save" onclick="this.form.action.value=\'AjaxFormSave\';return saveForm(\''.$form_name.'\', \'multiedit_form_{$module}\', \'Saving {$module}...\');"/>');
600         }
601
602         $form_name = $form_name == 'QuickCreate' ? "QuickCreate_{$this->module}" : $form_name;
603         $form_id = $form_id == 'QuickCreate' ? "QuickCreate_{$this->module}" : $form_id;
604
605         if (isset($this->defs['templateMeta']['preForm']))
606         {
607             $this->th->ss->assign('preForm', $this->defs['templateMeta']['preForm']);
608         }
609
610         if (isset($this->defs['templateMeta']['form']['closeFormBeforeCustomButtons']))
611         {
612             $this->th->ss->assign('closeFormBeforeCustomButtons', $this->defs['templateMeta']['form']['closeFormBeforeCustomButtons']);
613         }
614
615         if(isset($this->defs['templateMeta']['form']['enctype']))
616         {
617             $this->th->ss->assign('enctype', 'enctype="'.$this->defs['templateMeta']['form']['enctype'].'"');
618         }
619
620         //for SugarFieldImage, we must set form enctype to "multipart/form-data"
621         foreach ($this->fieldDefs as $field)
622         {
623             if (isset($field['type']) && $field['type'] == 'image')
624             {
625                 $this->th->ss->assign('enctype', 'enctype="multipart/form-data"');
626                 break;
627             }
628         }
629
630         $this->th->ss->assign('showDetailData', $this->showDetailData);
631         $this->th->ss->assign('showSectionPanelsTitles', $this->showSectionPanelsTitles);
632         $this->th->ss->assign('form_id', $form_id);
633         $this->th->ss->assign('form_name', $form_name);
634         $this->th->ss->assign('set_focus_block', get_set_focus_js());
635
636         $this->th->ss->assign('form', isset($this->defs['templateMeta']['form']) ? $this->defs['templateMeta']['form'] : null);
637         $this->th->ss->assign('includes', isset($this->defs['templateMeta']['includes']) ? $this->defs['templateMeta']['includes'] : null);
638         $this->th->ss->assign('view', $this->view);
639
640
641         //Calculate time & date formatting (may need to calculate this depending on a setting)
642         global $timedate;
643
644         $this->th->ss->assign('CALENDAR_DATEFORMAT', $timedate->get_cal_date_format());
645         $this->th->ss->assign('USER_DATEFORMAT', $timedate->get_user_date_format());
646         $time_format = $timedate->get_user_time_format();
647         $this->th->ss->assign('TIME_FORMAT', $time_format);
648
649         $date_format = $timedate->get_cal_date_format();
650         $time_separator = ':';
651         if (preg_match('/\d+([^\d])\d+([^\d]*)/s', $time_format, $match))
652         {
653             $time_separator = $match[1];
654         }
655
656         // Create Smarty variables for the Calendar picker widget
657         $t23 = strpos($time_format, '23') !== false ? '%H' : '%I';
658         if (!isset($match[2]) || $match[2] == '')
659         {
660             $this->th->ss->assign('CALENDAR_FORMAT', $date_format . ' ' . $t23 . $time_separator . '%M');
661         }
662         else
663         {
664             $pm = $match[2] == 'pm' ? '%P' : '%p';
665             $this->th->ss->assign('CALENDAR_FORMAT', $date_format . ' ' . $t23 . $time_separator . '%M' . $pm);
666         }
667
668         $this->th->ss->assign('TIME_SEPARATOR', $time_separator);
669
670         $seps = get_number_seperators();
671         $this->th->ss->assign('NUM_GRP_SEP', $seps[0]);
672         $this->th->ss->assign('DEC_SEP', $seps[1]);
673
674         if ($this->view == 'EditView')
675         {
676             $height = $current_user->getPreference('text_editor_height');
677             $width  = $current_user->getPreference('text_editor_width');
678
679             $height = isset($height) ? $height : '300px';
680             $width  = isset($width) ? $width : '95%';
681
682             $this->th->ss->assign('RICH_TEXT_EDITOR_HEIGHT', $height);
683             $this->th->ss->assign('RICH_TEXT_EDITOR_WIDTH', $width);
684         }
685         else
686         {
687             $this->th->ss->assign('RICH_TEXT_EDITOR_HEIGHT', '100px');
688             $this->th->ss->assign('RICH_TEXT_EDITOR_WIDTH', '95%');
689         }
690
691         $this->th->ss->assign('SHOW_VCR_CONTROL', $this->showVCRControl);
692
693         $str = $this->showTitle($showTitle);
694
695         //Use the output filter to trim the whitespace
696         $this->th->ss->load_filter('output', 'trimwhitespace');
697         $str .= $this->th->displayTemplate($this->module, $form_name, $this->tpl, $ajaxSave, $this->defs);
698
699         return $str;
700     }
701
702     function insertJavascript($javascript)
703     {
704         $this->ss->assign('javascript', $javascript);
705     }
706
707     function callFunction($vardef)
708     {
709         $can_execute = true;
710         $execute_function = array();
711         $execute_params = array();
712         if (!empty($vardef['function_class']))
713         {
714             $execute_function[] = $vardef['function_class'];
715             $execute_function[] = $vardef['function_name'];
716         }
717         else
718         {
719             $execute_function = $vardef['function_name'];
720         }
721
722         foreach ($vardef['function_params'] as $param )
723         {
724             if (empty($vardef['function_params_source']) or $vardef['function_params_source']=='parent')
725             {
726                 if (empty($this->focus->$param))
727                 {
728                     $can_execute = false;
729                 }
730                 else
731                 {
732                     $execute_params[] = $this->focus->$param;
733                 }
734             }
735             else if ($vardef['function_params_source']=='this')
736             {
737                 if (empty($this->focus->$param))
738                 {
739                     $can_execute = false;
740                 } else {
741                     $execute_params[] = $this->focus->$param;
742                 }
743             }
744             else
745             {
746                 $can_execute = false;
747             }
748         }
749
750         $value = '';
751         if ($can_execute)
752         {
753             if (!empty($vardef['function_require']))
754             {
755                 require_once($vardef['function_require']);
756             }
757
758             $value = call_user_func_array($execute_function, $execute_params);
759         }
760
761         return $value;
762     }
763
764     /**
765      * getValueFromRequest
766      * This is a helper method to extract a value from the request
767      * Array.  We do some special processing for fields that start
768      * with 'date_' by checking to see if they also include time
769      * and meridiem values
770      *
771      * @param request The request Array
772      * @param name The field name to extract value for
773      * @return String value for given name
774      */
775     function getValueFromRequest($request, $name)
776     {
777         //Special processing for date values (combine to one field)
778         if (preg_match('/^date_(.*)$/s', $name, $matches))
779         {
780             $d = $request[$name];
781
782             if (isset($request['time_' . $matches[1]]))
783             {
784                 $d .= ' ' . $request['time_' . $matches[1]];
785                 if (isset($request[$matches[1] . '_meridiem']))
786                 {
787                     $d .= $request[$matches[1] . '_meridiem'];
788                 }
789             }
790             else
791             {
792                 if (isset($request['time_hour_' . $matches[1]])
793                     && isset($request['time_minute_' . $matches[1]]))
794                 {
795                     $d .= sprintf(' %s:%s', $request['time_hour_' . $matches[1]], $request['time_minute_' . $matches[1]]);
796                 }
797
798                 if (isset($request['meridiem']))
799                 {
800                     $d .= $request['meridiem'];
801                 }
802            }
803
804            return $d;
805         }
806
807         if (empty($request[$name]) || !isset($this->fieldDefs[$name]))
808         {
809            return $request[$name];
810         }
811
812         //if it's a bean field - unformat it
813         require_once('include/SugarFields/SugarFieldHandler.php');
814
815         $sfh  = new SugarFieldHandler();
816         $type = !empty($this->fieldDefs[$name]['custom_type'])
817             ? $this->fieldDefs[$name]['custom_type']
818             : $this->fieldDefs[$name]['type'];
819         $sf   = $sfh->getSugarField($type);
820
821         return $sf ? $sf->unformatField($request[$name], $this->fieldDefs[$name]) : $request[$name];
822     }
823
824
825         /**
826          * Allow Subviews to overwrite this method to show custom titles.
827          * Examples: Projects & Project Templates.
828          * params: $showTitle: boolean for backwards compatibility.
829          */
830     public function showTitle($showTitle = false)
831     {
832         global $mod_strings, $app_strings;
833
834         if (is_null($this->viewObject))
835         {
836             $this->viewObject = (!empty($GLOBALS['current_view']))
837                 ? $GLOBALS['current_view']
838                 : new SugarView();
839         }
840
841         if ($showTitle)
842         {
843             return $this->viewObject->getModuleTitle();
844         }
845
846         return '';
847     }
848 }