]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/DynamicFields/templates/Fields/TemplateField.php
Release 6.4.0
[Github/sugarcrm.git] / modules / DynamicFields / templates / Fields / TemplateField.php
1 <?php
2 if(!defined('sugarEntry') || !sugarEntry) die('Not A Valid Entry Point');
3 /*********************************************************************************
4  * SugarCRM Community Edition is a customer relationship management program developed by
5  * SugarCRM, Inc. Copyright (C) 2004-2011 SugarCRM Inc.
6  * 
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU Affero General Public License version 3 as published by the
9  * Free Software Foundation with the addition of the following permission added
10  * to Section 15 as permitted in Section 7(a): FOR ANY PART OF THE COVERED WORK
11  * IN WHICH THE COPYRIGHT IS OWNED BY SUGARCRM, SUGARCRM DISCLAIMS THE WARRANTY
12  * OF NON INFRINGEMENT OF THIRD PARTY RIGHTS.
13  * 
14  * This program is distributed in the hope that it will be useful, but WITHOUT
15  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
16  * FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more
17  * details.
18  * 
19  * You should have received a copy of the GNU Affero General Public License along with
20  * this program; if not, see http://www.gnu.org/licenses or write to the Free
21  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
22  * 02110-1301 USA.
23  * 
24  * You can contact SugarCRM, Inc. headquarters at 10050 North Wolfe Road,
25  * SW2-130, Cupertino, CA 95014, USA. or at email address contact@sugarcrm.com.
26  * 
27  * The interactive user interfaces in modified source and object code versions
28  * of this program must display Appropriate Legal Notices, as required under
29  * Section 5 of the GNU Affero General Public License version 3.
30  * 
31  * In accordance with Section 7(b) of the GNU Affero General Public License version 3,
32  * these Appropriate Legal Notices must retain the display of the "Powered by
33  * SugarCRM" logo. If the display of the logo is not reasonably feasible for
34  * technical reasons, the Appropriate Legal Notices must display the words
35  * "Powered by SugarCRM".
36  ********************************************************************************/
37
38 $GLOBALS['studioReadOnlyFields'] = array('date_entered'=>1, 'date_modified'=>1, 'created_by'=>1, 'id'=>1, 'modified_user_id'=>1);
39 class TemplateField{
40         /*
41                 The view is the context this field will be used in
42                 -edit
43                 -list
44                 -detail
45                 -search
46                 */
47         var $view = 'edit';
48         var $name = '';
49         var $vname = '';
50         var $id = '';
51         var $size = '20';
52         var $len = '255';
53         var $required = false;
54         var $default = null;
55         var $default_value = null;
56         var $type = 'varchar';
57         var $comment = '';
58         var $bean;
59         var $ext1 = '';
60         var $ext2 = '';
61         var $ext3 = '';
62         var $ext4 = '';
63         var $audited= 0;
64         var $massupdate = 0;
65         var $importable = 'true' ;
66         var $duplicate_merge=0;
67         var $new_field_definition;
68         var $reportable = true;
69         var $label_value = '';
70         var $help = '';
71         var $formula = '';
72     var $unified_search = 0;
73     var $supports_unified_search = false;
74         var $vardef_map = array(
75                 'name'=>'name',
76                 'label'=>'vname',
77         // bug 15801 - need to ALWAYS keep default and default_value consistent as some methods/classes use one, some use another...
78                 'default_value'=>'default',
79                 'default'=>'default_value',
80                 'display_default'=>'default_value',
81         //              'default_value'=>'default_value',
82         //              'default'=>'default_value',
83                 'len'=>'len',
84                 'required'=>'required',
85                 'type'=>'type',
86                 'audited'=>'audited',
87                 'massupdate'=>'massupdate',
88                 'options'=>'ext1',
89                 'help'=>'help',
90             'comments'=>'comment',
91             'importable'=>'importable',
92                 'duplicate_merge'=>'duplicate_merge',
93                 'duplicate_merge_dom_value'=>'duplicate_merge_dom_value', //bug #14897
94                 'merge_filter'=>'merge_filter',
95                 'reportable' => 'reportable',
96                 'min'=>'ext1',
97                 'max'=>'ext2',
98                 'ext2'=>'ext2',
99                 'ext4'=>'ext4',
100         //'disable_num_format'=>'ext3',
101             'ext3'=>'ext3',
102                 'label_value'=>'label_value',
103                 'unified_search'=>'unified_search',
104         );
105         /*
106                 HTML FUNCTIONS
107                 */
108         function get_html(){
109                 $view = $this->view;
110                 if(!empty($GLOBALS['studioReadOnlyFields'][$this->name]))$view = 'detail';
111                 switch($view){
112                         case 'search':return $this->get_html_search();
113                         case 'edit': return $this->get_html_edit();
114                         case 'list': return $this->get_html_list();
115                         case 'detail': return $this->get_html_detail();
116
117                 }
118         }
119         function set($values){
120                 foreach($values as $name=>$value){
121                         $this->$name = $value;
122                 }
123
124         }
125
126         function get_html_edit(){
127                 return 'not implemented';
128         }
129
130         function get_html_list(){
131                 return $this->get_html_detail();
132         }
133
134         function get_html_detail(){
135                 return 'not implemented';
136         }
137
138         function get_html_search(){
139                 return $this->get_html_edit();
140         }
141         function get_html_label(){
142
143                 $label =  "{MOD." .$this->vname . "}";
144                 if(!empty($GLOBALS['app_strings'][$this->vname])){
145                         $label = "{APP." .$this->label . "}";
146                 }
147                 if($this->view == 'edit' && $this->is_required()){
148                         $label .= '<span class="required">*</span>';
149                 }
150                 if($this->view == 'list'){
151                         if(isset($this->bean)){
152                                 if(!empty($this->id)){
153                                         $name = $this->bean->table_name . '_cstm.'. $this->name;
154                                         $arrow = $this->bean->table_name . '_cstm_'. $this->name;
155                                 }else{
156                                         $name = $this->bean->table_name . '.'. $this->name;
157                                         $arrow = $this->bean->table_name . '_'. $this->name;
158                                 }
159                         }else{
160                                 $name = $this->name;
161                                 $arrow = $name;
162                         }
163                         $label = "<a href='{ORDER_BY}$name' class='listViewThLinkS1'>{MOD.$this->label}{arrow_start}{".$arrow."_arrow}{arrow_end}</a>";
164                 }
165                 return $label;
166
167         }
168
169         /*
170                 XTPL FUNCTIONS
171                 */
172
173         function get_xtpl($bean = false){
174                 if($bean)
175                 $this->bean = $bean;
176                 $view = $this->view;
177                 if(!empty($GLOBALS['studioReadOnlyFields'][$this->name]))$view = 'detail';
178                 switch($view){
179                         case 'search':return $this->get_xtpl_search();
180                         case 'edit': return $this->get_xtpl_edit();
181                         case 'list': return $this->get_xtpl_list();
182                         case 'detail': return $this->get_xtpl_detail();
183
184                 }
185         }
186
187         function get_xtpl_edit(){
188                 return '/*not implemented*/';
189         }
190
191         function get_xtpl_list(){
192                 return get_xtpl_detail();
193         }
194
195         function get_xtpl_detail(){
196                 return '/*not implemented*/';
197         }
198
199         function get_xtpl_search(){
200                 //return get_xtpl_edit();
201         }
202
203         function is_required(){
204                 if($this->required){
205                         return true;
206                 }
207                 return false;
208
209         }
210
211
212
213
214         /*
215                 DB FUNCTIONS
216                 */
217
218         function get_db_type(){
219             if(!empty($this->type)) {
220                 $type = $GLOBALS['db']->getColumnType($this->type);
221             }
222             if(!empty($type)) return " $type";
223             $type = $GLOBALS['db']->getColumnType("varchar");
224         return " $type({$this->len})";
225         }
226
227         function get_db_default($modify=false){
228                 $GLOBALS['log']->debug('get_db_default(): default_value='.$this->default_value);
229                 if (!$modify or empty($this->new_field_definition['default_value']) or $this->new_field_definition['default_value'] != $this->default_value ) {
230                         if(!is_null($this->default_value)){ // add a default value if it is not null - we want to set a default even if default_value is '0', which is not null, but which is empty()
231                                 if(NULL == trim($this->default_value)){
232                                         return " DEFAULT NULL";
233                                 }
234                                 else {
235                                         return " DEFAULT '$this->default_value'";
236                                 }
237                         }else{
238                                 return '';
239                         }
240                 }
241         }
242
243         /*
244          * Return the required clause for this field
245          * Confusingly, when modifying an existing field ($modify=true) there are two exactly opposite cases:
246          * 1. if called by Studio, only $this->required is set. If set, we return "NOT NULL" otherwise we return "NULL"
247          * 2. if not called by Studio, $this->required holds the OLD value of required, and new_field_definition['required'] is the NEW
248          * So if not called by Studio we want to return NULL if required=true (because we are changing FROM this setting)
249          */
250
251         function get_db_required($modify=false){
252                 //              $GLOBALS['log']->debug('get_db_required required='.$this->required." and ".(($modify)?"true":"false")." and ".print_r($this->new_field_definition,true));
253                 $req = "";
254
255                 if ($modify) {
256                         if (!empty($this->new_field_definition['required'])) {
257                                 if ($this->required and $this->new_field_definition['required'] != $this->required) {
258                                         $req = " NULL ";
259                                 }
260                         }
261                         else
262                         {
263                                 $req = ($this->required) ? " NOT NULL " : ''; // bug 17184 tyoung - set required correctly when modifying custom field in Studio
264                         }
265                 }
266                 else
267                 {
268                         if (empty($this->new_field_definition['required']) or $this->new_field_definition['required'] != $this->required ) {
269                                 if(!empty($this->required) && $this->required){
270                                         $req = " NOT NULL";
271                                 }
272                         }
273                 }
274
275                 return $req;
276         }
277
278         /*      function get_db_required($modify=false){
279                 $GLOBALS['log']->debug('get_db_required required='.$this->required." and ".(($modify)?"true":"false")." and ".print_r($this->new_field_definition,true));
280                 if ($modify) {
281                 if (!empty($this->new_field_definition['required'])) {
282                 if ($this->required and $this->new_field_definition['required'] != $this->required) {
283                 return " null ";
284                 }
285                 return "";
286                 }
287                 }
288                 if (empty($this->new_field_definition['required']) or $this->new_field_definition['required'] != $this->required ) {
289                 if(!empty($this->required) && $this->required){
290                 return " NOT NULL";
291                 }
292                 }
293                 return '';
294                 }
295                 */
296         /**
297          * Oracle Support: do not set required constraint if no default value is supplied.
298          * In this case the default value will be handled by the application/sugarbean.
299          */
300         function get_db_add_alter_table($table)
301         {
302                 return $GLOBALS['db']->getHelper()->addColumnSQL($table, $this->get_field_def(), true);
303         }
304
305         function get_db_delete_alter_table($table)
306         {
307                 return $GLOBALS['db']->getHelper()->dropColumnSQL(
308                 $table,
309                 $this->get_field_def()
310                 );
311         }
312
313         /**
314          * mysql requires the datatype caluse in the alter statment.it will be no-op anyway.
315          */
316         function get_db_modify_alter_table($table){
317                 return $GLOBALS['db']->alterColumnSQL($table, $this->get_field_def());
318         }
319
320
321         /*
322          * BEAN FUNCTIONS
323          *
324          */
325         function get_field_def(){
326                 $array =  array(
327                         'required'=>$this->convertBooleanValue($this->required),
328                         'source'=>'custom_fields',
329                         'name'=>$this->name,
330                         'vname'=>$this->vname,
331                         'type'=>$this->type,
332                         'massupdate'=>$this->massupdate,
333                         'default'=>$this->default,
334                         'comments'=> (isset($this->comments)) ? $this->comments : '',
335                     'help'=> (isset($this->help)) ?  $this->help : '',
336                     'importable'=>$this->importable,
337                         'duplicate_merge'=>$this->duplicate_merge,
338                         'duplicate_merge_dom_value'=> isset($this->duplicate_merge_dom_value) ? $this->duplicate_merge_dom_value : $this->duplicate_merge,
339                         'audited'=>$this->convertBooleanValue($this->audited),
340                         'reportable'=>$this->convertBooleanValue($this->reportable),
341             'unified_search'=>$this->convertBooleanValue($this->unified_search)
342                 );
343                 if(!empty($this->len)){
344                         $array['len'] = $this->len;
345                 }
346                 if(!empty($this->size)){
347                         $array['size'] = $this->size;
348                 }
349                 $this->get_dup_merge_def($array);
350
351                 return $array;
352         }
353
354         protected function convertBooleanValue($value)
355         {
356                 if ($value === 'true' || $value === '1' || $value === 1)
357                 return  true;
358                 else if ($value === 'false' || $value === '0' || $value === 0)
359                 return  false;
360                 else
361                 return $value;
362         }
363
364
365         /* if the field is duplicate merge enabled this function will return the vardef entry for the same.
366          */
367         function get_dup_merge_def(&$def) {
368
369                 switch ($def['duplicate_merge_dom_value']) {
370                         case 0:
371                                 $def['duplicate_merge']='disabled';
372                                 break;
373                         case 1:
374                                 $def['duplicate_merge']='enabled';
375                                 break;
376                         case 2:
377                                 $def['merge_filter']='enabled';
378                                 $def['duplicate_merge']='enabled';
379                                 break;
380                         case 3:
381                                 $def['merge_filter']='selected';
382                                 $def['duplicate_merge']='enabled';
383                                 break;
384                         case 4:
385                                 $def['merge_filter']='enabled';
386                                 $def['duplicate_merge']='disabled';
387                                 break;
388                 }
389
390         }
391
392         /*
393                 HELPER FUNCTIONS
394                 */
395
396
397         function prepare(){
398                 if(empty($this->id)){
399                         $this->id = $this->name;
400                 }
401         }
402
403         /**
404          * populateFromRow
405          * This function supports setting the values of all TemplateField instances.
406          * @param $row The Array key/value pairs from fields_meta_data table
407          */
408         function populateFromRow($row=array()) {
409                 $fmd_to_dyn_map = array('comments' => 'comment', 'require_option' => 'required', 'label' => 'vname',
410                                                             'mass_update' => 'massupdate', 'max_size' => 'len', 'default_value' => 'default', 'id_name' => 'ext3');
411                 if(!is_array($row)) {
412                         $GLOBALS['log']->error("Error: TemplateField->populateFromRow expecting Array");
413                 }
414                 //Bug 24189: Copy fields from FMD format to Field objects
415                 foreach ($fmd_to_dyn_map as $fmd_key => $dyn_key) {
416                         if (isset($row[$fmd_key])) {
417                                 $this->$dyn_key = $row[$fmd_key];
418                         }
419                 }
420                 foreach($row as $key=>$value) {
421                         $this->$key = $value;
422                 }
423         }
424
425         function populateFromPost(){
426                 foreach($this->vardef_map as $vardef=>$field){
427                         if(isset($_REQUEST[$vardef])){
428                                 $this->$vardef = $_REQUEST[$vardef];
429                                 if($vardef != $field){
430                                         $this->$field = $this->$vardef;
431                                 }
432                         }
433                 }
434                 $this->applyVardefRules();
435                 $GLOBALS['log']->debug('populate: '.print_r($this,true));
436
437         }
438
439         protected function applyVardefRules()
440         {
441         }
442
443         function get_additional_defs(){
444                 return array();
445         }
446
447         function delete($df){
448                 $df->deleteField($this);
449         }
450
451     /**
452      * get_field_name
453      * 
454      * This is a helper function to return a field's proper name.  It checks to see if an instance of the module can
455      * be created and then attempts to retrieve the field's name based on the name lookup skey supplied to the method.
456      *
457      * @param String $module The name of the module
458      * @param String $name The field name key
459      * @return The field name for the module
460      */
461     protected function get_field_name($module, $name)
462     {
463        $bean = loadBean($module);
464        if(empty($bean) || is_null($bean))
465        {
466           return $name;
467        }
468
469        $field_defs = $bean->field_defs;
470        return isset($field_defs[$name]['name']) ? $field_defs[$name]['name'] : $name;
471     }
472
473     /**
474      * save
475      *
476      * This function says the field template by calling the DynamicField addFieldObject function.  It then
477      * checks to see if updates are needed for the SearchFields.php file.  In the event that the unified_search
478      * member variable is set to true, a search field definition is updated/created to the SearchFields.php file.
479      *
480      * @param $df Instance of DynamicField
481      */
482         function save($df){
483                 //          $GLOBALS['log']->debug('saving field: '.print_r($this,true));
484                 $df->addFieldObject($this);
485
486         require_once('modules/ModuleBuilder/parsers/parser.searchfields.php');
487         $searchFieldParser = new ParserSearchFields( $df->getModuleName() , $df->getPackageName() ) ;
488             //If unified_search is enabled for this field, then create the SearchFields entry
489             $fieldName = $this->get_field_name($df->getModuleName(), $this->name);
490         if($this->unified_search && !isset($searchFieldParser->searchFields[$df->getModuleName()][$fieldName]))
491         {
492            $searchFieldParser->addSearchField($fieldName, array('query_type'=>'default'));
493            $searchFieldParser->saveSearchFields($searchFieldParser->searchFields);
494         }
495         }
496
497 }
498
499
500 ?>