]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - include/EditView/EditView2.php
Release 6.1.4
[Github/sugarcrm.git] / include / EditView / EditView2.php
1 <?php
2 /*********************************************************************************
3  * SugarCRM 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     var $th;
45     var $tpl;
46     var $notes;
47     var $id;
48     var $metadataFile;
49     var $headerTpl;
50     var $footerTpl;
51     var $returnAction;
52     var $returnModule;
53     var $returnId;
54     var $isDuplicate;
55     var $focus;
56     var $module;
57     var $fieldDefs;
58     var $sectionPanels;
59     var $view = 'EditView';
60     var $formatFields = true;
61     var $showDetailData = true;
62     var $showVCRControl = true;
63     var $showSectionPanelsTitles = true;
64     var $quickSearchCode;
65     var $ss;
66     var $offset = 0;
67     var $populateBean = true;
68     var $moduleTitleKey;
69     var $viewObject = null;
70     var $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         if(empty($GLOBALS['sugar_config']['showDetailData'])) {
100                 $this->showDetailData = false;
101         }
102         $this->metadataFile = $metadataFile;
103
104         if(isset($GLOBALS['sugar_config']['disable_vcr'])) {
105            $this->showVCRControl = !$GLOBALS['sugar_config']['disable_vcr'];
106         }
107         if(!empty($this->metadataFile) && file_exists($this->metadataFile)){
108                 include($this->metadataFile);
109         }else {
110                 //If file doesn't exist we create a best guess
111                 if(!file_exists("modules/$this->module/metadata/editviewdefs.php") &&
112                     file_exists("modules/$this->module/EditView.html")) {
113                     require_once('include/SugarFields/Parsers/EditViewMetaParser.php');
114                 global $dictionary;
115                     $htmlFile = "modules/" . $this->module . "/EditView.html";
116                     $parser = new EditViewMetaParser();
117                     if(!file_exists('modules/'.$this->module.'/metadata')) {
118                        sugar_mkdir('modules/'.$this->module.'/metadata');
119                     }
120                         $fp = sugar_fopen('modules/'.$this->module.'/metadata/editviewdefs.php', 'w');
121                     fwrite($fp, $parser->parse($htmlFile, $dictionary[$focus->object_name]['fields'], $this->module));
122                     fclose($fp);
123                 }
124
125                 //Flag an error... we couldn't create the best guess meta-data file
126                 if(!file_exists("modules/$this->module/metadata/editviewdefs.php")) {
127                    global $app_strings;
128                    $error = str_replace("[file]", "modules/$this->module/metadata/editviewdefs.php", $app_strings['ERR_CANNOT_CREATE_METADATA_FILE']);
129                    $GLOBALS['log']->fatal($error);
130                    echo $error;
131                    die();
132                 }
133             require_once("modules/$this->module/metadata/editviewdefs.php");
134         }
135
136         $this->defs = $viewdefs[$this->module][$this->view];
137         $this->isDuplicate = isset($_REQUEST['isDuplicate']) && $_REQUEST['isDuplicate'] == 'true' && $this->focus->aclAccess('edit');
138     }
139
140     function createFocus()
141     {
142         global $beanList, $beanFiles;
143         
144         if(empty($beanList[$this->module]))return;
145         if(!$this->focus ){
146            $bean = $beanList[$this->module];
147             require_once($beanFiles[$bean]);
148            $obj = new $bean();
149            $this->focus = $obj;
150         }
151
152         //If there is no idea, assume we are creating a new instance
153         //and call the fill_in_additional_detail_fields where initialization
154         //code has been moved to
155         if(empty($this->focus->id)) {
156            global $current_user;
157            $this->focus->fill_in_additional_detail_fields();
158            $this->focus->assigned_user_id = $current_user->id;
159         }
160     }
161
162     function populateBean() 
163     {
164         if(!empty($_REQUEST['record']) && $this->populateBean) {
165            global $beanList;
166            $bean = $beanList[$this->module];
167            $obj = new $bean();
168            $this->focus = $obj->retrieve($_REQUEST['record']);
169         } else {
170            $GLOBALS['log']->debug("Unable to populate bean, no record parameter found");
171         }
172     }
173
174     /**
175      * enableFormatting
176      * This method is used to manually turn on/off the field formatting
177      * @param $format boolean value to turn on/off field formatting
178      */
179     function enableFormatting(
180         $format = true
181         ) 
182     {
183         $this->formatFields = $format;
184     }
185
186
187     function requiredFirst()
188     {
189          $panels = array('required'=>array());
190          $reqCol = -1;
191          $reqRow = 0;
192         foreach($this->defs['panels'] as $key=>$p){
193
194                         foreach($p as $row=>$rowDef) {
195                             foreach($rowDef as $col => $colDef) {
196                                 $field = (is_array($p[$row][$col])) ? $p[$row][$col]['name'] : $p[$row][$col];
197                                 if((!empty($this->focus->field_defs[$field]) 
198                                         && !empty($this->focus->field_defs[$field]['required'])) 
199                                     || ( !empty($p[$row][$col]['displayParams']['required']) 
200                                         && ( isset($this->focus->field_defs[$field]) ? $this->focus->field_defs[$field]['required'] !== false : false ) ) ) {
201                                         $reqCol++;
202                                         if($reqCol == $this->defs['templateMeta']['maxColumns']) {
203                                                 $reqCol = -1;
204                                                 $reqRow++;
205                                         }
206                                     $panels['required'][$reqRow][$reqCol] = $p[$row][$col];
207                                 }else{
208                                         $panels[$key][$row][$col] = $p[$row][$col];
209                                 }
210
211                             } //foreach
212                         } //foreach
213
214
215                 } //foreach
216          $this->defs['panels'] = $panels;
217     }
218
219     function render()
220     {
221         $totalWidth = 0;
222         foreach($this->defs['templateMeta']['widths'] as $col => $def) {
223             foreach($def as $k => $value) $totalWidth += $value;
224         }
225         // calculate widths
226         foreach($this->defs['templateMeta']['widths'] as $col => $def) {
227             foreach($def as $k => $value)
228                 $this->defs['templateMeta']['widths'][$col][$k] = round($value / ($totalWidth / 100), 2);
229         }
230
231         $this->sectionPanels = array();
232         $this->sectionLabels = array();
233         if(!empty($this->defs['panels']) && count($this->defs['panels']) > 0) {
234            $keys = array_keys($this->defs['panels']);
235            if(is_numeric($keys[0])) {
236                   $defaultPanel = $this->defs['panels'];
237                   unset($this->defs['panels']); //blow away current value
238               $this->defs['panels'][''] = $defaultPanel;
239            }
240         }
241         if($this->view == 'EditView' && !empty($GLOBALS['sugar_config']['forms']['requireFirst'])){
242                 $this->requiredFirst();
243         }
244
245         $maxColumns = isset($this->defs['templateMeta']['maxColumns']) ? $this->defs['templateMeta']['maxColumns'] : 2;
246         $panelCount = 0;
247                 static $itemCount = 100; //Start the generated tab indexes at 100 so they don't step on custom ones.
248         
249                 /* loop all the panels */
250                 foreach($this->defs['panels'] as $key=>$p)
251                 {
252                         $panel = array();
253
254                 if(!is_array($this->defs['panels'][$key])) {
255                    $this->sectionPanels[strtoupper($key)] = $p;
256                 } else {
257
258                                 foreach($p as $row=>$rowDef) {
259                                     $columnsInRows = count($rowDef);
260                                     $columnsUsed = 0;
261                                     foreach($rowDef as $col => $colDef) {
262                                         $panel[$row][$col] = is_array($p[$row][$col]) ? array('field' => $p[$row][$col]) : array('field' => array('name'=>$p[$row][$col]));
263                             $panel[$row][$col]['field']['tabindex'] = (isset($p[$row][$col]['tabindex']) && is_numeric($p[$row][$col]['tabindex'])) ? $p[$row][$col]['tabindex'] : $itemCount;
264                                         
265                                         if($columnsInRows < $maxColumns) {
266                                             if($col == $columnsInRows - 1) {
267                                                 $panel[$row][$col]['colspan'] = 2 * $maxColumns - ($columnsUsed + 1);
268                                             } else {
269                                                 $panel[$row][$col]['colspan'] = floor(($maxColumns * 2 - $columnsInRows) / $columnsInRows);
270                                                 $columnsUsed = $panel[$row][$col]['colspan'];
271                                             }
272                                         }
273
274                                         
275                                         //Set address types to have colspan value of 2 if colspan is not already defined
276                                         if(isset($colDef['type']) && $colDef['type'] == 'address' && $this->view == 'EditView' && !isset($panel[$row][$col]['colspan'])) {
277                                            $panel[$row][$col]['colspan'] = 2;   
278                                         }
279
280                             
281                           
282                                         $itemCount++;
283
284                                     } //foreach
285                                 } //foreach
286
287                                 // Panel alignment will be off if the panel doesn't have a row with the max columns
288                                 // It will not be aligned to the other panels so we fill out the columns in the last row
289                                 $addFiller = true;
290                                 foreach($panel as $row) {
291                                         if(count($row) == $this->defs['templateMeta']['maxColumns']) {
292                                            $addFiller = false;
293                                            break;
294                                         }
295                                 }
296
297                                 if($addFiller) {
298                                    $rowCount = count($panel);
299                                    $filler = count($panel[$rowCount-1]);
300                                    while($filler < $this->defs['templateMeta']['maxColumns']) {
301                                       $panel[$rowCount - 1][$filler++] = array('field'=>array('name'=>''));
302                                    } //while
303                                 }
304                                                 
305
306                                 $this->sectionPanels[strtoupper($key)] = $panel;
307                         }
308                         
309
310                 $panelCount++;
311                 } //foreach
312     }
313
314     function process(
315         $checkFormName = false, 
316         $formName = ''
317         ) 
318     {
319         global $mod_strings, $sugar_config, $app_strings, $app_list_strings;
320
321                 //the retrieve already did this work;
322         //$this->focus->fill_in_relationship_fields();
323
324         if(!$this->th->checkTemplate($this->module, $this->view, $checkFormName, $formName)){
325                 $this->render();
326         }
327                 if(isset($_REQUEST['offset'])) {
328                         $this->offset = $_REQUEST['offset'] - 1;
329                 } //if
330         if($this->showVCRControl) {
331                 $this->th->ss->assign('PAGINATION', SugarVCR::menu($this->module, $this->offset, $this->focus->is_AuditEnabled(), ($this->view == 'EditView')));
332         } //if
333         if(isset($_REQUEST['return_module'])) $this->returnModule = $_REQUEST['return_module'];
334                 if(isset($_REQUEST['return_action'])) $this->returnAction = $_REQUEST['return_action'];
335                 if(isset($_REQUEST['return_id'])) $this->returnId = $_REQUEST['return_id'];
336                 if(isset($_REQUEST['return_relationship'])) $this->returnRelationship = $_REQUEST['return_relationship'];
337                 if(isset($_REQUEST['return_name'])) $this->returnName = $this->getValueFromRequest($_REQUEST, 'return_name' ) ;
338
339                 // handle Create $module then Cancel
340                 if (empty($this->returnId)) {
341                         $this->returnAction = 'index';
342                 }
343
344         $is_owner = $this->focus->isOwner($GLOBALS['current_user']->id);
345
346         $this->fieldDefs = array();
347                 if($this->focus){
348
349                         global $current_user;
350
351                         /*if(empty($this->focus->assigned_user_id) ){
352                                 $this->focus->assigned_user_id = $current_user->id;
353                         }*/
354
355                         if(!empty($this->focus->assigned_user_id)) {
356
357                            $this->focus->assigned_user_name = get_assigned_user_name($this->focus->assigned_user_id);
358                         }
359                 foreach($this->focus->toArray() as $name => $value) {
360
361                 $valueFormatted = false;
362                         //if($this->focus->field_defs[$name]['type']=='link')continue;
363
364                         if (!empty($this->fieldDefs[$name]) && !empty($this->fieldDefs[$name]['value']))
365                        $this->fieldDefs[$name] = array_merge($this->focus->field_defs[$name] , $this->fieldDefs[$name] ) ;
366                     else
367                    $this->fieldDefs[$name] = $this->focus->field_defs[$name];
368                                 
369                                 
370                                 foreach(array("formula", "default", "comments", "help") as $toEscape)
371                         {
372                             if (!empty($this->fieldDefs[$name][$toEscape])) {
373                                 $this->fieldDefs[$name][$toEscape] = htmlentities($this->fieldDefs[$name][$toEscape], ENT_QUOTES, 'UTF-8');
374                             }
375                         }
376
377                     if(isset($this->fieldDefs[$name]['options']) && isset($app_list_strings[$this->fieldDefs[$name]['options']])) {
378                         $this->fieldDefs[$name]['options'] = $app_list_strings[$this->fieldDefs[$name]['options']]; // fill in enums
379                     } //if
380
381                         if(isset($this->fieldDefs[$name]['function'])) {
382                                 $function = $this->fieldDefs[$name]['function'];
383                                 if(is_array($function) && isset($function['name'])){
384                                         $function = $this->fieldDefs[$name]['function']['name'];
385                                 }else{
386                                         $function = $this->fieldDefs[$name]['function'];
387                                 }
388                                 if(!empty($this->fieldDefs[$name]['function']['returns']) && $this->fieldDefs[$name]['function']['returns'] == 'html'){
389                                                 if(!empty($this->fieldDefs[$name]['function']['include'])){
390                                                                 require_once($this->fieldDefs[$name]['function']['include']);
391                                                 }
392                                                 $value = $function($this->focus, $name, $value, $this->view);
393                                                 $valueFormatted = true;
394                                         }else{
395                                                 $this->fieldDefs[$name]['options'] = $function($this->focus, $name, $value, $this->view);
396                                         }
397                         }
398
399                         if(isset($this->fieldDefs[$name]['type']) && $this->fieldDefs[$name]['type'] == 'function' && isset($this->fieldDefs[$name]['function_name'])){
400                                 $value = $this->callFunction($this->fieldDefs[$name]);
401                                 $valueFormatted = true;
402                         }
403
404                         if(!$valueFormatted) {
405                     // $this->focus->format_field($this->focus->field_defs[$name]);     
406                    $value = isset($this->focus->$name) ? $this->focus->$name : '';
407                         }
408
409                         if (empty($this->fieldDefs[$name]['value']))
410                         {
411                        $this->fieldDefs[$name]['value'] = $value;
412                         }
413                         
414
415                     //This code is used for QuickCreates that go to Full Form view
416                         if($this->populateBean && empty($this->focus->id) && (isset($this->fieldDefs[$name]['function']['returns']) ? $this->fieldDefs[$name]['function']['returns'] != 'html' : true) && isset($_REQUEST[$name])) {
417                        $this->fieldDefs[$name]['value'] = $this->getValueFromRequest($_REQUEST, $name);
418                     } //if
419
420                     /*
421                 * Populate any relate fields that are linked by a relationship to the calling module.
422                 * Clicking the create button on a subpanel for example will populate three values in the $_REQUEST:
423                 * 1. return_module => the name of the calling module
424                 * 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
425                 * 3. return_name => the display value of the return_id record - the value to show in any relate field in this EditView
426                 * 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
427                 */
428                     if (isset($this->returnModule) && isset($this->returnName) && empty($this->focus->id) && empty($this->fieldDefs['name']['value']) )
429                 {
430                        if ( ($this->focus->field_defs[$name]['type'] == 'relate') && isset($this->focus->field_defs[$name][ 'module' ]) && $this->focus->field_defs[$name][ 'module' ] == $this->returnModule )
431                        {
432                        if (isset( $this->fieldDefs[$name]['id_name'])
433                            && !empty($this->returnRelationship)
434                            && isset($this->focus->field_defs[$this->fieldDefs[$name]['id_name']]['relationship'])
435                            && ($this->returnRelationship == $this->focus->field_defs[$this->fieldDefs[$name]['id_name']]['relationship']))
436                            {
437                                $this->fieldDefs[$name]['value'] =  $this->returnName ;
438                                // set the hidden id field for this relate field to the correct value i.e., return_id
439                                $this->fieldDefs[$this->fieldDefs[$name]['id_name']]['value'] = $this->returnId ;
440                            }
441                        }
442                 }
443
444                 } //foreach
445
446                 } //if
447
448                 if(isset($this->focus->additional_meta_fields)) {
449                     $this->fieldDefs = array_merge($this->fieldDefs, $this->focus->additional_meta_fields);
450                 }
451                 
452         if($this->isDuplicate) {
453                    foreach($this->fieldDefs as $name=>$defs) {
454                                 if(!empty($defs['auto_increment'])) {
455                                    $this->fieldDefs[$name]['value'] = '';
456                                 }
457                    }
458         }               
459     }
460
461     /**
462      * display
463      * This method makes the Smarty variable assignments and then displays the
464      * generated view.
465      * @param $showTitle boolean value indicating whether or not to show a title on the resulting page
466      * @param $ajaxSave boolean value indicating whether or not the operation is an Ajax save request
467      * @return HTML display for view as String
468      */
469     function display(
470         $showTitle = true, 
471         $ajaxSave = false
472         ) 
473     {
474         global $mod_strings, $sugar_config, $app_strings, $app_list_strings, $theme, $current_user;
475
476
477         if(isset($this->defs['templateMeta']['javascript'])) {
478            if(is_array($this->defs['templateMeta']['javascript'])) {
479                  $this->th->ss->assign('externalJSFile', 'modules/' . $this->module . '/metadata/editvewdefs.js');
480            } else {
481              $this->th->ss->assign('scriptBlocks', $this->defs['templateMeta']['javascript']);
482            }
483         }
484
485         $this->th->ss->assign('id', $this->fieldDefs['id']['value']);
486         $this->th->ss->assign('offset', $this->offset + 1);
487         $this->th->ss->assign('APP', $app_strings);
488         $this->th->ss->assign('MOD', $mod_strings);
489         $this->th->ss->assign('fields', $this->fieldDefs);
490         $this->th->ss->assign('sectionPanels', $this->sectionPanels);
491         $this->th->ss->assign('returnModule', $this->returnModule);
492         $this->th->ss->assign('returnAction', $this->returnAction);
493         $this->th->ss->assign('returnId', $this->returnId);
494         $this->th->ss->assign('isDuplicate', $this->isDuplicate);
495         $this->th->ss->assign('def', $this->defs);
496         $this->th->ss->assign('useTabs', isset($this->defs['templateMeta']['useTabs']) ? $this->defs['templateMeta']['useTabs'] : false);
497         $this->th->ss->assign('maxColumns', isset($this->defs['templateMeta']['maxColumns']) ? $this->defs['templateMeta']['maxColumns'] : 2);
498         $this->th->ss->assign('module', $this->module);
499         $this->th->ss->assign('headerTpl', isset($this->defs['templateMeta']['form']['headerTpl']) ? $this->defs['templateMeta']['form']['headerTpl'] : 'include/' . $this->view . '/header.tpl');
500         $this->th->ss->assign('footerTpl', isset($this->defs['templateMeta']['form']['footerTpl']) ? $this->defs['templateMeta']['form']['footerTpl'] : 'include/' . $this->view . '/footer.tpl');
501         $this->th->ss->assign('current_user', $current_user);
502         $this->th->ss->assign('bean', $this->focus);
503         $this->th->ss->assign('isAuditEnabled', $this->focus->is_AuditEnabled());
504         $this->th->ss->assign('gridline',$current_user->getPreference('gridline') == 'on' ? '1' : '0');
505
506         global $js_custom_version;
507         global $sugar_version;
508         $this->th->ss->assign('SUGAR_VERSION', $sugar_version);
509         $this->th->ss->assign('JS_CUSTOM_VERSION', $js_custom_version);
510
511         //this is used for multiple forms on one page
512         if ( !empty($this->formName) ) {
513             $form_id = $this->formName;
514             $form_name = $this->formName;
515         }
516         else {
517             $form_id = $this->view;
518             $form_name = $this->view;
519         }
520         if($ajaxSave && empty($this->formName)){
521                 $form_id = 'form_'.$this->view .'_'.$this->module;
522                 $form_name = $form_id;
523                 $this->view = $form_name;
524                 //$this->defs['templateMeta']['form']['buttons'] = array();
525                 //$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}...\');"/>');
526         }
527         
528                 $form_name = $form_name == "QuickCreate" ? "QuickCreate_{$this->module}" : $form_name;        
529         $form_id = $form_id == "QuickCreate" ? "QuickCreate_{$this->module}" : $form_id;
530                 
531         if(isset($this->defs['templateMeta']['preForm'])) {
532           $this->th->ss->assign('preForm', $this->defs['templateMeta']['preForm']);
533         } //if
534         if(isset($this->defs['templateMeta']['form']['closeFormBeforeCustomButtons'])) {
535           $this->th->ss->assign('closeFormBeforeCustomButtons', $this->defs['templateMeta']['form']['closeFormBeforeCustomButtons']);
536         }
537         if(isset($this->defs['templateMeta']['form']['enctype'])) {
538           $this->th->ss->assign('enctype', 'enctype="'.$this->defs['templateMeta']['form']['enctype'].'"');
539         }
540         //for SugarFieldImage, we must set form enctype to "multipart/form-data"
541         foreach($this->fieldDefs as $field){
542                 if(isset($field['type']) && $field['type'] == 'image'){
543                         $this->th->ss->assign('enctype', 'enctype="multipart/form-data"');
544                         break;
545                 }
546         }
547         $this->th->ss->assign('showDetailData', $this->showDetailData);
548         $this->th->ss->assign('showSectionPanelsTitles', $this->showSectionPanelsTitles);
549         $this->th->ss->assign('form_id', $form_id);
550         $this->th->ss->assign('form_name', $form_name);
551                 $this->th->ss->assign('set_focus_block', get_set_focus_js());
552                 
553         $this->th->ss->assign('form', isset($this->defs['templateMeta']['form']) ? $this->defs['templateMeta']['form'] : null);
554         $this->th->ss->assign('includes', isset($this->defs['templateMeta']['includes']) ? $this->defs['templateMeta']['includes'] : null);
555                 $this->th->ss->assign('view', $this->view);
556
557         //Calculate time & date formatting (may need to calculate this depending on a setting)
558         global $timedate;
559         $this->th->ss->assign('CALENDAR_DATEFORMAT', $timedate->get_cal_date_format());
560         $this->th->ss->assign('USER_DATEFORMAT', $timedate->get_user_date_format());
561         $time_format = $timedate->get_user_time_format();
562         $this->th->ss->assign('TIME_FORMAT', $time_format);
563
564         $date_format = $timedate->get_cal_date_format();
565         $time_separator = ":";
566         if(preg_match('/\d+([^\d])\d+([^\d]*)/s', $time_format, $match)) {
567            $time_separator = $match[1];
568         }
569
570         // Create Smarty variables for the Calendar picker widget
571         $t23 = strpos($time_format, '23') !== false ? '%H' : '%I';
572         if(!isset($match[2]) || $match[2] == '') {
573           $this->th->ss->assign('CALENDAR_FORMAT', $date_format . ' ' . $t23 . $time_separator . "%M");
574         } else {
575           $pm = $match[2] == "pm" ? "%P" : "%p";
576           $this->th->ss->assign('CALENDAR_FORMAT', $date_format . ' ' . $t23 . $time_separator . "%M" . $pm);
577         }
578
579         $this->th->ss->assign('TIME_SEPARATOR', $time_separator);
580
581                 $seps = get_number_seperators();
582                 $this->th->ss->assign('NUM_GRP_SEP', $seps[0]);
583                 $this->th->ss->assign('DEC_SEP', $seps[1]);
584                 
585                 if($this->view == 'EditView') {
586                         $height = $current_user->getPreference('text_editor_height');
587                         $width = $current_user->getPreference('text_editor_width');
588                         $height = isset($height) ? $height : '300px';
589                 $width = isset($width) ? $width : '95%';
590                         $this->th->ss->assign('RICH_TEXT_EDITOR_HEIGHT', $height);
591                         $this->th->ss->assign('RICH_TEXT_EDITOR_WIDTH', $width);
592                 } else {
593                         $this->th->ss->assign('RICH_TEXT_EDITOR_HEIGHT', '100px');
594                         $this->th->ss->assign('RICH_TEXT_EDITOR_WIDTH', '95%');                 
595                 }
596
597                 
598                 $this->th->ss->assign('SHOW_VCR_CONTROL', $this->showVCRControl);
599
600         //$str='';
601
602         $str = $this->showTitle($showTitle);
603
604         //Use the output filter to trim the whitespace
605         $this->th->ss->load_filter('output', 'trimwhitespace');
606         $str .= $this->th->displayTemplate($this->module, $form_name, $this->tpl, $ajaxSave, $this->defs);
607                 return $str;
608     }
609
610     function insertJavascript(
611         $javascript
612         )
613     {
614         $this->ss->assign('javascript', $javascript);
615     }
616
617     function callFunction(
618         $vardef
619         )
620     {
621                 $can_execute = true;
622                 $execute_function = array();
623                 $execute_params = array();
624                 if(!empty($vardef['function_class'])){
625                         $execute_function[] =   $vardef['function_class'];
626                         $execute_function[] =   $vardef['function_name'];
627                 }else{
628                         $execute_function       = $vardef['function_name'];
629                 }
630                 foreach($vardef['function_params'] as $param ){
631                         if (empty($vardef['function_params_source']) or $vardef['function_params_source']=='parent'){
632                                 if(empty($this->focus->$param)){
633                                         $can_execute = false;
634                                 }else{
635                                         $execute_params[] = $this->focus->$param;
636                                 }
637                         }else if ($vardef['function_params_source']=='this'){
638                                 if(empty($this->focus->$param)){
639                                         $can_execute = false;
640                                 }else{
641                                         $execute_params[] = $this->focus->$param;
642                                 }
643                         }else{
644                                 $can_execute = false;
645                         }
646
647                 }
648                 $value = '';
649                 if($can_execute){
650                         if(!empty($vardef['function_require'])){
651                                 require_once($vardef['function_require']);
652                         }
653                         $value = call_user_func_array($execute_function, $execute_params);
654                 }
655                 return $value;
656     }
657
658     /**
659      * getValueFromRequest
660      * This is a helper method to extract a value from the request
661      * Array.  We do some special processing for fields that start
662      * with 'date_' by checking to see if they also include time
663      * and meridiem values
664      *
665      * @param request The request Array
666      * @param name The field name to extract value for
667      * @return String value for given name
668      */
669     function getValueFromRequest(
670         $request, 
671         $name
672         ) 
673     {
674         //Special processing for date values (combine to one field)
675         if(preg_match('/^date_(.*)$/s', $name, $matches)) {
676            $d = $request[$name];
677
678            if(isset($request['time_' . $matches[1]])) {
679                    $d .= ' ' . $request['time_' . $matches[1]];
680                    if(isset($request[$matches[1] . '_meridiem'])) {
681                           $d .= $request[$matches[1] . '_meridiem'];
682                    }
683            } else {
684                    if(isset($request['time_hour_' . $matches[1]]) &&
685                       isset($request['time_minute_' . $matches[1]])) {
686                           $d .= ' ' . $request['time_hour_' . $matches[1]] . ':' . $request['time_minute_' . $matches[1]];
687                    }
688                    if(isset($request['meridiem'])) {
689                           $d .= $request['meridiem'];
690                    }
691            }
692            return $d;
693         }
694
695         return $request[$name];
696     }
697
698         /**
699          * Allow Subviews to overwrite this method to show custom titles.
700          * Examples: Projects & Project Templates.
701          * params: $showTitle: boolean for backwards compatibility.
702          */
703     public function showTitle(
704         $showTitle = false
705         )
706     {
707         global $mod_strings, $app_strings;
708         
709         if (is_null($this->viewObject))
710                 if (!empty($GLOBALS['current_view']))
711                         $this->viewObject = $GLOBALS['current_view'];
712                 else
713                         $this->viewObject = new SugarView();
714         
715         if ($showTitle)
716                 return $this->viewObject->getModuleTitle();
717         
718         return '';
719     }
720 }