CRMEB/backend/crmeb/services/notice/AbstractNoticeChannel.php
2026-09-23 15:15:02 +08:00

91 lines
3.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
// +----------------------------------------------------------------------
// | CRMEB [ CRMEB赋能开发者,助力企业发展 ]
// +----------------------------------------------------------------------
// | Copyright (c) 2016~2026 https://www.crmeb.com All rights reserved.
// +----------------------------------------------------------------------
// | Author: CRMEB Team <admin@crmeb.com>
// +----------------------------------------------------------------------
declare(strict_types=1);
namespace crmeb\services\notice;
/**
* 消息渠道适配器抽象基类
*
* 提供渠道声明(key/名称/额外字段/支持范围)与占位符渲染等通用能力,
* 具体渠道只需继承本类并实现 send(NoticeMessage):发送成功直接返回,
* 失败抛 NoticeSendException(由 Notice::deliver() 捕获记日志)。
*
* 依赖边界(架构铁律:crmeb/ 不可调用 app/):
* - 本类位于 crmeb/ 核心层,不依赖任何 app/ 层服务。
* - 所有渠道适配器统一放在 app/services/message/channel/ 下继承本类:
* 有 app 依赖的(System/Sms/Email)通过 app()->make() 调用 app 层服务;
* 纯调用 driver/ 的(DingTalk/EntWechat)直接调用 crmeb 层 Bot/Http。
*/
abstract class AbstractNoticeChannel implements NoticeChannelInterface
{
/**
* 渠道标识(对应 eb_notice_channel.channel_key)
* 子类必须覆盖此方法,返回如 'is_system'、'is_sms' 等
* @return string
*/
public static function channelKey(): string
{
return '';
}
/**
* 渠道显示名称(如 系统站内信、短信),子类覆写
* @return string
*/
public static function channelName(): string
{
return static::channelKey();
}
/**
* 本渠道需要额外存储的配置字段,格式 [字段名 => 默认值]。
* 通用字段 template_title / template_content / status 由框架统一处理,无需在此声明。
* @return array
*/
public static function getExtraFields(): array
{
return [];
}
/**
* 渠道支持的消息范围,默认用户端/平台端均支持。
* 仅平台通知的渠道(如钉钉/企业微信群机器人)覆写为仅平台端。
* @return array ['support_user' => 0|1, 'support_platform' => 0|1]
*/
public static function getSupportScope(): array
{
return ['support_user' => 1, 'support_platform' => 1];
}
/**
* 将扁平业务变量渲染进模板文本:替换全部 {key} 占位符
*
* 值统一转 string,避免 int 参数触发 str_replace TypeError;
* 非标量值(数组/对象)跳过不参与替换。
*
* @param string $text 模板文本(含 {key} 占位符)
* @param array $variables 扁平业务变量
* @return string
*/
protected function renderPlaceholders(string $text, array $variables): string
{
if ($text === '' || empty($variables)) {
return $text;
}
foreach ($variables as $key => $value) {
if (!is_scalar($value)) {
continue;
}
$text = str_replace('{' . $key . '}', (string)$value, $text);
}
return $text;
}
}