作者:James Zhu (fatindeed@hotmail.com)
创建日期:2018-08-31
1. customCode
例如,数据库中有一个的字段weight_c
,值为70
,期望输出70 kg
,则仅需修改相关view文件即可。
列表页面:custom/modules/module_name/metadata/listviewdefs.php
$listViewDefs[$module_name] = array(
// ...
'WEIGHT_C' => array(
'type' => 'int',
'default' => true,
'label' => 'LBL_WEIGHT',
'width' => '5%',
'customCode' => '{$WEIGHT_C} kg',
),
// ...
);
详情页面:custom/modules/module_name/metadata/detailviewdefs.php
$viewdefs[$module_name] = array(
// ...
array(
'name' => 'weight_c',
'label' => 'LBL_WEIGHT',
'customCode' => '{$fields.weight_c.value} kg',
),
// ...
);
子面板页面?不支持customCode。
2. 自定义function字段
例如,数据库中有一个的字段born_c
,值为1990-01-01
,期望输出计算后的年龄28
。
首先需要新建一个字段定义文件custom/Extension/modules/module_name/Ext/Vardefs/sugarfield_age_c.php
,内容如下:
$dictionary['module_name']['fields']['age_c'] = array(
'name' => 'age_c',
'vname' => 'LBL_AGE_C',
'type' => 'function',
'function_class' => 'module_name_util',
'function_name' => 'get_age',
'function_params' => array('born_c'),
'source' => 'function',
'reportable' => false,
'importable' => false,
);
module_name_util
可以随便放个地方,只要在module里require_once
就可以了。
class module_name_util {
public static function get_age($born_c) {
if(empty($born_c)) return '';
$interval = date_diff(date_create(), date_create($born_c));
return $interval->format('%y');
}
}
然后,运行 系统管理 > 修复 > 快速修复和重建 来重新生成字段定义缓存文件。
列表页面:无法直接使用自定义字段,需要通过 process_record 的 logic_hook 手动触发function后,才可在listviewdefs.php
中使用。custom/modules/module_name/logic_hooks.php
文件内容如下:
$hook_version = 1;
$hook_array = array();
$hook_array['process_record'] = array();
$hook_array['process_record'][] = array(1, 'process record', 'custom/modules/module_name/module_name_logic_hook.php','module_name_logic_hook', 'process_record');
custom/modules/module_name/module_name_logic_hook.php
文件内容如下:
class module_name_logic_hook {
public function process_record($bean, $event, $arguments) {
$bean->age_c = module_name_util::get_age($bean->born_c);
}
}
custom/modules/module_name/metadata/listviewdefs.php
文件内容如下:
$listViewDefs[$module_name] = array(
// ...
'AGE_C' => array(
'default' => true,
'label' => 'LBL_AGE',
'width' => '5%',
'sortable' => false, // 非数据库字段无法排序,否则会报错
'customCode' => '{$AGE_C} years old', // 仍可使用customCode定义输出内容
'related_fields' => array('born_c'), // 保证当列表也没有born_c时也能正常显示
),
// ...
);
详情页面:custom/modules/module_name/metadata/detailviewdefs.php
$viewdefs[$module_name] = array(
// ...
array(
'name' => 'age_c',
'label' => 'LBL_AGE',
'customCode' => '{$fields.age_c.value} years old', // 仍可使用customCode定义输出内容
),
// ...
);
子面板页面:与列表页面类似,也需触发 process_record 的 logic_hook,但是定义文件中无法使用related_fields,且无法使用customCode,实现方法如下:
custom/modules/module_name/metadata/subpanels/relation_name.php
$subpanel_layout[$module_name] = array(
// ...
'age_c' => array(
'default' => true,
'vname' => 'LBL_AGE',
'width' => '5%',
'sortable' => false, // 非数据库字段无法排序,否则会报错
),
'born_c' => array(
'usage'=>'query_only'
),
// ...
);
3. 字段function属性
仍然是born_c
字段,现在期望输出1990-01-01 (28)
,这种情况下有一个比较简单的方法。
直接修改born_c
的字段定义文件custom/Extension/modules/module_name/Ext/Vardefs/sugarfield_born_c.php
,加入如下配置:
$dictionary['module_name']['fields']['born_c']['function'] = array(
'name' => 'show_dob_with_age',
'include' => 'custom/modules/module_name/module_name_util.php', // 如果直接写在module文件里,可不用include
'returns' => 'html',
'onListView' => true,
);
show_dob_with_age
方法实现如下:
function show_dob_with_age($focus, $field, $value, $view = 'ListView') {
if(empty($value)) return '';
$interval = date_diff(date_create(), date_create($value));
return $value.' ('.$interval->format('%y').')';
}
列表页面、详情页面、子面板页面默认显示function处理后的结果。如支持customCode(列表页面、详情页面),则仍可自定义输出内容。
$listViewDefs[$module_name] = array(
// ...
'BORN_C' => array(
'default' => true,
'label' => 'LBL_BORN',
'width' => '10%',
'customCode' => '{$BORN_C}', // 使用customCode后显示原始内容
),
// ...
);
PS: 此方法会影响字段的正常编辑,显示虽然方便了,但是编辑不了了。
4. 自定义SugarField
以上两种方法都有局限性,有没有其它更好的方法呢?那就是自定义 SugarField 了。
我们新建一个类型为DateOfBirthWithAge
的 SugarField,需要创建以下3个文件:
custom/include/SugarFields/Fields/DateOfBirthWithAge/SugarFieldDateOfBirthWithAge.php
文件内容如下:
// 这里继承SugarFieldDatetime,在编辑页面即会出现日期选择器组件
require_once('include/SugarFields/Fields/Datetime/SugarFieldDatetime.php');
class SugarFieldDateOfBirthWithAge extends SugarFieldDatetime {
}
custom/include/SugarFields/Fields/DateOfBirthWithAge/ListView.tpl
文件内容如下:
{if $parentFieldArray.$col}
{$parentFieldArray.$col|date_format:"%b %e, %Y"} ({$parentFieldArray.$col|@show_dob_with_age})
{/if}
custom/include/SugarFields/Fields/DateOfBirthWithAge/DetailView.tpl
文件内容如下:
{assign var="born" value={{sugarvar key='value' string=true}} }
{if $born}
{$born|date_format:"%b %e, %Y"} ({$born|@show_dob_with_age})
{/if}
至此,SugarField创建完成,接着我们需要在使用的module中进行配置。
show_dob_with_age
方法仍可以直接写入module文件,再修改born_c
的字段定义文件custom/Extension/modules/module_name/Ext/Vardefs/sugarfield_born_c.php
,加入如下配置:
$dictionary['module_name']['fields']['born_c']['custom_type'] = 'DateOfBirthWithAge';
现在,不管是列表页面、详情页面、子面板页面,还是编辑页面,都可以正常显示。应该是一个比较完美的方案了。
总结
介绍了以上4种方法,在实际开发过程中,还需根据不同需求,使用相应的方法。