在客户关系管理(CRM)系统中,客户门户是一个重要的组成部分,它允许用户直接在门户上更新他们的工单或案例。然而,SuiteCRM的API在这方面存在一个明显的弱点,即没有提供用于获取或设置案例更新的REST API方法。本文将指导如何为SuiteCRM添加两个新的API方法,以支持客户门户中案例更新的功能。
SuiteCRM API的核心是服务端点,它包含了多个版本的API。目前最新的版本是4.2。可以通过访问SugarCRM的官方网站来查看每个版本的具体特性。在SuiteCRM的根目录下打开'service'文件夹,可以看到以'v'开头的文件夹,这些文件夹代表了不同版本的API。每个版本的API都包含了之前版本的所有功能,并且扩展了上一个版本的类。
要创建自己的API版本,应该从最新版本的API(例如v4.1)开始。首先,克隆v4.1文件夹并将其重命名为版本名称,例如fcc。然后,重命名SugarWebServiceImplv4_1.php和SugarWebServiceUtilv4_1.php这两个文件,并将其中的'v4_1'替换为版本名称。例如,将它们重命名为SugarWebServiceImplfcc.php和SugarWebServiceUtilfcc.php。
打开rest.php文件,需要在这里注册并包含API版本。例如,API名称是fcc。以下是fcc的rest.php文件的代码示例:
require_once('SugarWebServiceImplfcc.php');
$webservice_class = 'SugarRestService';
$webservice_path = 'service/core/SugarRestService.php';
$webservice_impl_class = 'SugarWebServiceImplfcc';
$registry_class = 'registry';
$location = '/service/fcc/rest.php';
$registry_path = 'service/fcc/registry.php';
require_once('service/core/webservice.php');
同样,也需要对soap.php文件执行相同的步骤。
SugarWebServiceUtilfcc.php文件包含了在主API方法中使用的所有实用工具和辅助函数。这个文件中的类是从最新版本的SuiteCRM API服务扩展而来的。以下是如何编写这个类的例子:
require_once('service/v4_1/SugarWebServiceUtilv4_1.php');
class SugarWebServiceUtilfcc extends SugarWebServiceUtilv4_1 {
// Your functions
}
根据API函数需求,可以在这个类中编写自己的函数。同时,需要包含扩展API的版本文件,例如SugarWebServicecUtilv4_1.php。
主要的API方法和函数是在SugarWebServiceImplfcc.php文件中编写的。想要添加两个新的API方法:set_case_update和get_case_updates。首先,编写这两个新函数的原型:
function get_case_updates($session, $module_name, $name_value_list) {
// API code
}
function set_case_update($session, $module_name, $name_value_list) {
// API code
}
这两个新函数具有相同的参数:$session是所有SuiteCRM API方法的通用参数,它包含了登录函数返回的会话ID,表明请求具有足够的凭据。$module_name参数属于那些为所有模块工作的方法,如get_entry_list、set_entry等。在案例中,这个参数不是必需的,因为这两种方法都在Case_Updates模块上工作。但是,没有从方法原型中移除这个参数。$name_value_list参数是一个数组,包含了客户端发送的所有数据,如查询、字段值等。
set_case_update方法负责在案例记录上插入或更新case_update。以下是该方法的实现:
$case_update = new AOP_Case_Updates();
$GLOBALS['log']->info('Begin: SugarWebServiceImpl->set_case_update');
if (!self::$helperObject->checkSessionAndModuleAccess($session, 'invalid_session', "AOP_Case_Updates", 'read', 'no_access', $error)) {
return;
}
foreach ($name_value_list as &$value) {
$name = $value['name'];
$case_update->$name = $value['value'];
}
$case_update->save();
$GLOBALS['log']->info('End: SugarWebServiceImpl->set_case_update');
return array('id' => $case_update->id);
在第一行,创建了AOP_Case_Update的一个新的实例。在SuiteCRM中,要插入或更新一个新的记录,只需要从模块类中获取一个新的实例。当调用Save方法时,如果id字段为空,则会创建一个新的记录;如果id字段已经填写,则该方法会更新id所属的记录。接下来的代码行在SuiteCRM日志文件中写入了新的一行。接下来的条件语句用于检查凭据和用户访问权限。如果会话ID为空或有错误的值,则该方法返回。在下一个语句中,有一个foreach循环,它遍历$name_value_list数组并填充$case_update参数。最后一条语句调用了case_update实例的save方法。正如下面所说的,这个方法根据Id属性的值工作。如果Id为空,该方法将添加一个新的记录;如果id属性有一个正确的id值,该方法将更新该记录。方法的最后一行返回新记录或更新记录的Id。这是所有插入或更新方法返回id值的必要部分。
get_case_updates方法获取一个案例ID,并返回其所有的case_updates。以下是该方法的实现:
function get_case_updates($session, $module_name, $name_value_list){
$caseUpdateBean = BeanFactory::getBean('AOP_Case_Updates');
$caseUpdate = $caseUpdateBean->get_full_list('date_entered desc', "case_id = '" . $name_value_list[0]['value'] . "'");
$counter = 0;
foreach ($caseUpdate as &$value) {
$item = array();
$i = 1;
foreach ($value as $key => $val) {
try {
if ($i < 22) {
array_push($item, array('name' => $key, 'value' => $val));
}
} catch (Exception $e) {
}
$i++;
}
if ($counter == 0)
$items = array($item);
else
array_push($items, $item);
$counter++;
}
$result = array('count' => $i, 'items' => $items);
return array('entry_list' => $result);
}
在第一行,创建了Case_Update的一个新实例。这是通过BeanFactory::getBean方法完成的。接下来一行,调用get_full_list方法。这个方法接受两个字符串参数,排序顺序和查询语句,并返回与查询匹配的记录列表。接下来的循环步骤根据适合的返回值填充一个新数组,客户端可以处理这个数组。最后一条语句将数组返回给客户端。
$this->serviceClass->registerFunction(
'set_case_update',
array(
'session' => 'xsd:string',
'module_name' => 'xsd:string',
'name_value_list' => 'tns:name_value_list'
),
array(
'return' => 'tns:new_set_entry_result'
)
);