SugarCRM6.5中字段定制显示方法研究

作者: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_recordlogic_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_recordlogic_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 了。

我们新建一个类型为DateOfBirthWithAgeSugarField,需要创建以下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种方法,在实际开发过程中,还需根据不同需求,使用相应的方法。

Last updated