]> CyberLeo.Net >> Repos - Github/sugarcrm.git/blob - modules/DynamicFields/templates/Fields/TemplateField.php
Release 6.2.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
73         var $vardef_map = array(
74                 'name'=>'name',
75                 'label'=>'vname',
76         // bug 15801 - need to ALWAYS keep default and default_value consistent as some methods/classes use one, some use another...
77                 'default_value'=>'default',
78                 'default'=>'default_value',
79                 'display_default'=>'default_value',
80         //              'default_value'=>'default_value',
81         //              'default'=>'default_value',
82                 'len'=>'len',
83                 'required'=>'required',
84                 'type'=>'type',
85                 'audited'=>'audited',
86                 'massupdate'=>'massupdate',
87                 'options'=>'ext1',
88                 'help'=>'help',
89             'comments'=>'comment',
90             'importable'=>'importable',
91                 'duplicate_merge'=>'duplicate_merge',
92                 'duplicate_merge_dom_value'=>'duplicate_merge_dom_value', //bug #14897
93                 'merge_filter'=>'merge_filter',
94                 'reportable' => 'reportable',
95                 'min'=>'ext1',
96                 'max'=>'ext2',
97                 'ext2'=>'ext2',
98                 'ext4'=>'ext4',
99         //'disable_num_format'=>'ext3',
100             'ext3'=>'ext3',
101                 'label_value'=>'label_value',
102         );
103         /*
104                 HTML FUNCTIONS
105                 */
106         function get_html(){
107                 $view = $this->view;
108                 if(!empty($GLOBALS['studioReadOnlyFields'][$this->name]))$view = 'detail';
109                 switch($view){
110                         case 'search':return $this->get_html_search();
111                         case 'edit': return $this->get_html_edit();
112                         case 'list': return $this->get_html_list();
113                         case 'detail': return $this->get_html_detail();
114
115                 }
116         }
117         function set($values){
118                 foreach($values as $name=>$value){
119                         $this->$name = $value;
120                 }
121
122         }
123
124         function get_html_edit(){
125                 return 'not implemented';
126         }
127
128         function get_html_list(){
129                 return $this->get_html_detail();
130         }
131
132         function get_html_detail(){
133                 return 'not implemented';
134         }
135
136         function get_html_search(){
137                 return $this->get_html_edit();
138         }
139         function get_html_label(){
140
141                 $label =  "{MOD." .$this->vname . "}";
142                 if(!empty($GLOBALS['app_strings'][$this->vname])){
143                         $label = "{APP." .$this->label . "}";
144                 }
145                 if($this->view == 'edit' && $this->is_required()){
146                         $label .= '<span class="required">*</span>';
147                 }
148                 if($this->view == 'list'){
149                         if(isset($this->bean)){
150                                 if(!empty($this->id)){
151                                         $name = $this->bean->table_name . '_cstm.'. $this->name;
152                                         $arrow = $this->bean->table_name . '_cstm_'. $this->name;
153                                 }else{
154                                         $name = $this->bean->table_name . '.'. $this->name;
155                                         $arrow = $this->bean->table_name . '_'. $this->name;
156                                 }
157                         }else{
158                                 $name = $this->name;
159                                 $arrow = $name;
160                         }
161                         $label = "<a href='{ORDER_BY}$name' class='listViewThLinkS1'>{MOD.$this->label}{arrow_start}{".$arrow."_arrow}{arrow_end}</a>";
162                 }
163                 return $label;
164
165         }
166
167         /*
168                 XTPL FUNCTIONS
169                 */
170
171         function get_xtpl($bean = false){
172                 if($bean)
173                 $this->bean = $bean;
174                 $view = $this->view;
175                 if(!empty($GLOBALS['studioReadOnlyFields'][$this->name]))$view = 'detail';
176                 switch($view){
177                         case 'search':return $this->get_xtpl_search();
178                         case 'edit': return $this->get_xtpl_edit();
179                         case 'list': return $this->get_xtpl_list();
180                         case 'detail': return $this->get_xtpl_detail();
181
182                 }
183         }
184
185         function get_xtpl_edit(){
186                 return '/*not implemented*/';
187         }
188
189         function get_xtpl_list(){
190                 return get_xtpl_detail();
191         }
192
193         function get_xtpl_detail(){
194                 return '/*not implemented*/';
195         }
196
197         function get_xtpl_search(){
198                 //return get_xtpl_edit();
199         }
200
201         function is_required(){
202                 if($this->required){
203                         return true;
204                 }
205                 return false;
206
207         }
208
209
210
211
212         /*
213                 DB FUNCTIONS
214                 */
215
216         function get_db_type(){
217                 switch($GLOBALS['db']->dbType){
218                         case 'oci8': return " varchar2($this->len)";
219                         case 'mssql': return !empty($GLOBALS['db']->isFreeTDS) ? " nvarchar($this->len)" : " varchar($this->len)";
220                         default: return " varchar($this->len)";
221                 }
222         }
223
224         function get_db_default($modify=false){
225                 $GLOBALS['log']->debug('get_db_default(): default_value='.$this->default_value);
226                 if (!$modify or empty($this->new_field_definition['default_value']) or $this->new_field_definition['default_value'] != $this->default_value ) {
227                         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()
228                                 if(NULL == trim($this->default_value)){
229                                         return " DEFAULT NULL";
230                                 }
231                                 else {
232                                         return " DEFAULT '$this->default_value'";
233                                 }
234                         }else{
235                                 return '';
236                         }
237                 }
238         }
239
240         /*
241          * Return the required clause for this field
242          * Confusingly, when modifying an existing field ($modify=true) there are two exactly opposite cases:
243          * 1. if called by Studio, only $this->required is set. If set, we return "NOT NULL" otherwise we return "NULL"
244          * 2. if not called by Studio, $this->required holds the OLD value of required, and new_field_definition['required'] is the NEW
245          * So if not called by Studio we want to return NULL if required=true (because we are changing FROM this setting)
246          */
247
248         function get_db_required($modify=false){
249                 //              $GLOBALS['log']->debug('get_db_required required='.$this->required." and ".(($modify)?"true":"false")." and ".print_r($this->new_field_definition,true));
250                 $req = "";
251
252                 if ($modify) {
253                         if (!empty($this->new_field_definition['required'])) {
254                                 if ($this->required and $this->new_field_definition['required'] != $this->required) {
255                                         $req = " NULL ";
256                                 }
257                         }
258                         else
259                         {
260                                 $req = ($this->required) ? " NOT NULL " : ''; // bug 17184 tyoung - set required correctly when modifying custom field in Studio
261                         }
262                 }
263                 else
264                 {
265                         if (empty($this->new_field_definition['required']) or $this->new_field_definition['required'] != $this->required ) {
266                                 if(!empty($this->required) && $this->required){
267                                         $req = " NOT NULL";
268                                 }
269                         }
270                 }
271
272                 return $req;
273         }
274
275         /*      function get_db_required($modify=false){
276                 $GLOBALS['log']->debug('get_db_required required='.$this->required." and ".(($modify)?"true":"false")." and ".print_r($this->new_field_definition,true));
277                 if ($modify) {
278                 if (!empty($this->new_field_definition['required'])) {
279                 if ($this->required and $this->new_field_definition['required'] != $this->required) {
280                 return " null ";
281                 }
282                 return "";
283                 }
284                 }
285                 if (empty($this->new_field_definition['required']) or $this->new_field_definition['required'] != $this->required ) {
286                 if(!empty($this->required) && $this->required){
287                 return " NOT NULL";
288                 }
289                 }
290                 return '';
291                 }
292                 */
293         /**
294          * Oracle Support: do not set required constraint if no default value is supplied.
295          * In this case the default value will be handled by the application/sugarbean.
296          */
297         function get_db_add_alter_table($table)
298         {
299                 return $GLOBALS['db']->getHelper()->addColumnSQL($table, $this->get_field_def(), true);
300         }
301
302         function get_db_delete_alter_table($table)
303         {
304                 return $GLOBALS['db']->getHelper()->dropColumnSQL(
305                 $table,
306                 $this->get_field_def()
307                 );
308         }
309
310         /**
311          * mysql requires the datatype caluse in the alter statment.it will be no-op anyway.
312          */
313         function get_db_modify_alter_table($table){
314                 global $db;
315                 $db_default=$this->get_db_default(true);
316                 $db_required=$this->get_db_required(true);
317                 switch ($GLOBALS['db']->dbType) {
318
319                         case "mssql":
320                                 //Bug 21772: MSSQL handles alters in strange ways. Defer to DBHelpers guidance.
321                                 $query = $db->helper->alterColumnSQL($table, $this->get_field_def());
322                                 return $query;
323                                 break;
324
325                         case "mysql":
326                                 $query="ALTER TABLE $table MODIFY $this->name " .$this->get_db_type();
327                                 break;
328                         default:
329                                 $query="ALTER TABLE $table MODIFY $this->name " .$this->get_db_type();;
330                                 break;
331
332                 }
333                 if (!empty($db_default) && !empty($db_required)) {
334                         $query .= $db_default . $db_required ;
335                 } else if (!empty($db_default)) {
336                         $query .= $db_default;
337                 }
338                 return $query;
339         }
340
341
342         /*
343          * BEAN FUNCTIONS
344          *
345          */
346         function get_field_def(){
347                 $array =  array(
348                         'required'=>$this->convertBooleanValue($this->required),
349                         'source'=>'custom_fields',
350                         'name'=>$this->name,
351                         'vname'=>$this->vname,
352                         'type'=>$this->type,
353                         'massupdate'=>$this->massupdate,
354                         'default'=>$this->default,
355                         'comments'=> (isset($this->comments)) ? $this->comments : '',
356                     'help'=> (isset($this->help)) ?  $this->help : '',
357                     'importable'=>$this->importable,
358                         'duplicate_merge'=>$this->duplicate_merge,
359                         'duplicate_merge_dom_value'=> isset($this->duplicate_merge_dom_value) ? $this->duplicate_merge_dom_value : $this->duplicate_merge,
360                         'audited'=>$this->convertBooleanValue($this->audited),
361                         'reportable'=>$this->convertBooleanValue($this->reportable),
362                 );
363                 if(!empty($this->len)){
364                         $array['len'] = $this->len;
365                 }
366                 if(!empty($this->size)){
367                         $array['size'] = $this->size;
368                 }
369                 $this->get_dup_merge_def($array);
370                 return $array;
371         }
372
373         protected function convertBooleanValue($value)
374         {
375                 if ($value === 'true' || $value === '1' || $value === 1)
376                 return  true;
377                 else if ($value === 'false' || $value === '0' || $value === 0)
378                 return  false;
379                 else
380                 return $value;
381         }
382
383
384         /* if the field is duplicate merge enabled this function will return the vardef entry for the same.
385          */
386         function get_dup_merge_def(&$def) {
387
388                 switch ($def['duplicate_merge_dom_value']) {
389                         case 0:
390                                 $def['duplicate_merge']='disabled';
391                                 break;
392                         case 1:
393                                 $def['duplicate_merge']='enabled';
394                                 break;
395                         case 2:
396                                 $def['merge_filter']='enabled';
397                                 $def['duplicate_merge']='enabled';
398                                 break;
399                         case 3:
400                                 $def['merge_filter']='selected';
401                                 $def['duplicate_merge']='enabled';
402                                 break;
403                         case 4:
404                                 $def['merge_filter']='enabled';
405                                 $def['duplicate_merge']='disabled';
406                                 break;
407                 }
408
409         }
410
411         /*
412                 HELPER FUNCTIONS
413                 */
414
415
416         function prepare(){
417                 if(empty($this->id)){
418                         $this->id = $this->name;
419                 }
420         }
421
422         /**
423          * populateFromRow
424          * This function supports setting the values of all TemplateField instances.
425          * @param $row The Array key/value pairs from fields_meta_data table
426          */
427         function populateFromRow($row=array()) {
428                 $fmd_to_dyn_map = array('comments' => 'comment', 'require_option' => 'required', 'label' => 'vname',
429                                                             'mass_update' => 'massupdate', 'max_size' => 'len', 'default_value' => 'default', 'id_name' => 'ext3');
430                 if(!is_array($row)) {
431                         $GLOBALS['log']->error("Error: TemplateField->populateFromRow expecting Array");
432                 }
433                 //Bug 24189: Copy fields from FMD format to Field objects
434                 foreach ($fmd_to_dyn_map as $fmd_key => $dyn_key) {
435                         if (isset($row[$fmd_key])) {
436                                 $this->$dyn_key = $row[$fmd_key];
437                         }
438                 }
439                 foreach($row as $key=>$value) {
440                         $this->$key = $value;
441                 }
442         }
443
444         function populateFromPost(){
445                 foreach($this->vardef_map as $vardef=>$field){
446                         if(isset($_REQUEST[$vardef])){
447                                 $this->$vardef = $_REQUEST[$vardef];
448                                 if($vardef != $field){
449                                         $this->$field = $this->$vardef;
450                                 }
451                         }
452                 }
453                 $this->applyVardefRules();
454                 $GLOBALS['log']->debug('populate: '.print_r($this,true));
455
456         }
457
458         protected function applyVardefRules()
459         {
460         }
461
462         function get_additional_defs(){
463                 return array();
464         }
465
466         function delete($df){
467                 $df->deleteField($this);
468         }
469
470         function save($df){
471                 //          $GLOBALS['log']->debug('saving field: '.print_r($this,true));
472                 $df->addFieldObject($this);
473         }
474
475 }
476
477
478 ?>