
本文详解如何修正 controller.php 中的 sql 查询逻辑,确保“need further assistance”功能能正确继承原始工单所属的支持团队(如 parts distribution center),避免所有新工单错误归入默认团队(parts help desk)。
本文详解如何修正 controller.php 中的 sql 查询逻辑,确保“need further assistance”功能能正确继承原始工单所属的支持团队(如 parts distribution center),避免所有新工单错误归入默认团队(parts help desk)。
在 Zendesk Connect(原 RightNow CX)定制开发中,SolveCaseCreateNew 小部件用于在客户门户(CP)中基于已关闭工单快速创建关联新工单。但当前行为异常:无论原始工单归属 Parts Help Desk 还是 Parts Distribution Center,点击 “Need Further Assistance” 按钮后,新工单始终被路由至 Parts Help Desk。问题根源在于 controller.php 中用于获取原始工单团队信息的 SQL 查询不完整且存在安全隐患。
? 核心问题分析
查看提供的查询语句:
$incidentQuery = "SELECT I.ReferenceNumber, I.StatusWithType.StatusType.LookupName, I.CustomFields.c.support_team FROM Incident AS I WHERE I.ID = " . $i_id;
该语句存在三处关键缺陷:
- 字段路径错误:I.CustomFields.c.support_team 是典型的 Oracle Service Cloud(OSC)元数据路径写法,但在标准 SQL 查询中无法直接解析;实际需通过 CustomField 关联表或使用 OSC 内置函数(如 GetCustomField)访问自定义字段;
- SQL 注入风险:直接拼接未过滤的 $i_id 变量,若传入非数字值(如 '1 OR 1=1'),将导致严重安全漏洞;
- 缺少空值/默认值处理:当 support_team 字段为空或查询失败时,控制器未提供 fallback 逻辑,导致 view.php 中 = $this->data['Team'] ?> 渲染为空,进而使前端路由逻辑失效。
✅ 正确解决方案
1. 使用安全参数化查询(推荐 OSC 原生方式)
在 Zendesk Connect 中,应优先使用 RNCPHP\ROQL 或平台封装的 RNCPHP\Incident::fetch() 方法,而非裸 SQL:
try {
$incident = RNCPHP\Incident::fetch($i_id);
if ($incident && $incident->CustomFields->c->support_team) {
$team = (string) $incident->CustomFields->c->support_team;
} else {
// 回退到工单队列(Queue)或业务规则推导的默认团队
$team = $incident->Queue ? $incident->Queue->LookupName : 'Parts Help Desk';
}
// 将 team 注入视图上下文
$this->data['Team'] = $team;
} catch (Exception $e) {
error_log("Failed to fetch incident {$i_id}: " . $e->getMessage());
$this->data['Team'] = 'Parts Help Desk'; // 安全兜底
}2. 若必须使用 ROQL(只读查询语言),请规范书写:
$roql = "SELECT I.ReferenceNumber, I.StatusWithType.StatusType.LookupName, I.CustomFields.c.support_team
FROM Incident I
WHERE I.ID = :id";
$stmt = RNCPHP\ROQL::query($roql)->bind('id', $i_id)->execute();
if ($row = $stmt->next()) {
$this->data['Team'] = $row['I.CustomFields.c.support_team'] ?: 'Parts Help Desk';
}3. 在 view.php 中增强健壮性显示:
<p><b>Case # <?= htmlspecialchars($this->data['ReferenceNumber']) ?> has been closed.</b> If you need further assistance on this case, click the button below.</p> <p><b>Team: <?= htmlspecialchars($this->data['Team'] ?: 'Unknown Team') ?></b></p>
⚠️ 注意事项与最佳实践
- 永远不要拼接用户输入到 SQL:$i_id 必须经 filter_var($i_id, FILTER_VALIDATE_INT) 验证,或直接使用平台 API 的类型安全方法;
- 自定义字段名需与后台配置完全一致:检查 OSC 管理界面中 support_team 字段的 API Name(区分大小写、下划线),常见错误包括 support_team vs supportTeam;
- 测试边界场景:模拟 support_team = null、Queue = null、ID 不存在 等情况,验证兜底逻辑是否生效;
- 日志驱动调试:在生产环境开启 error_log() 记录查询失败详情,避免静默降级。
✅ 总结
该问题本质是 数据获取层逻辑缺失 + 安全防护缺位。修复重点不在“改查询”,而在于:
① 放弃裸 SQL,拥抱平台安全 API;
② 显式处理空值与异常;
③ 前后端协同校验字段渲染。
完成上述调整后,“Need Further Assistance” 将准确继承原始工单的 support_team 值,确保新工单自动进入对应支持路径(Parts Distribution Center 或 Parts Help Desk),提升客户自助服务准确性与一致性。










