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