diff --git a/README.md b/README.md index ea2d8d7..9108062 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ [![Latest Stable Version](https://img.shields.io/packagist/v/toplan/phpsms.svg)](https://packagist.org/packages/toplan/phpsms) [![Total Downloads](https://img.shields.io/packagist/dt/toplan/phpsms.svg)](https://packagist.org/packages/toplan/phpsms) -可能是目前最聪明、优雅的php短信发送库了。从此不再为各种原因造成的个别短信发送失败而烦忧! +可能是目前最聪明、优雅的 php 短信发送库了。 > phpsms的任务均衡调度功能由[toplan/task-balancer](https://github.com/toplan/task-balancer)提供。 @@ -34,16 +34,25 @@ | [聚合数据](https://www.juhe.cn/) | √ | × | √ | -- | ¥0.035/条 | [资费标准](https://www.juhe.cn/docs/api/id/54) | [阿里大鱼](https://www.alidayu.com/) | √ | × | √ | -- | ¥0.045/条 | [资费标准](https://www.alidayu.com/service/price) | [SendCloud](https://sendcloud.sohu.com/) | √ | × | √ | -- | ¥0.048/条 | [资费标准](https://sendcloud.sohu.com/price.html) -| [短信宝](http://www.smsbao.com/) | × | √ | √ | ¥5(50条) | ¥0.040/条(100万条) | [资费标准](http://www.smsbao.com/fee/) +| [短信宝](http://www.smsbao.com/) | × | √ | √ | ¥5(50条) | ¥0.040/条(100万条) | [资费标准](http://www.smsbao.com/fee/) +| [腾讯云](https://www.qcloud.com/product/sms) | √ | √ | √ | -- | ¥0.045/条 | [资费标准](https://www.qcloud.com/product/sms#price) +| [阿里云](https://www.aliyun.com/product/sms) | √ | × | × | -- | ¥0.045/条 | [资费标准](https://cn.aliyun.com/price/product#/mns/detail) +> 腾讯云和阿里云目前仅在**公测版**支持,欢迎使用并反馈测试结果和意见。 # 安装 +稳定版 ```php composer require toplan/phpsms:~1.7 ``` -安装开发中版本: +公测版 +```php +composer require toplan/phpsms:~1.8.0-beta +``` + +开发中版本 ```php composer require toplan/phpsms:dev-master ``` @@ -60,19 +69,14 @@ composer require toplan/phpsms:dev-master //example: Sms::config([ 'Luosimao' => [ - //短信API key 'apikey' => 'your api key', - //语音验证API key 'voiceApikey' => 'your voice api key', ], 'YunPian' => [ - //用户唯一标识,必须 'apikey' => 'your api key', ], 'SmsBao' => [ - //在短信宝注册的用户名,必须 'username' => 'your username', - //在短信宝网站注册的密码(明文),必须 'password' => 'your password' ] ]); @@ -124,7 +128,7 @@ $content = '【签名】这是短信内容...'; // 只希望使用模板方式发送短信,可以不设置content(如:云通讯、Submail、Ucpaas) Sms::make()->to($to)->template($templates)->data($tempData)->send(); -// 只希望使用内容方式放送,可以不设置模板id和模板data(如:短信宝、云片、luosimao) +// 只希望使用内容方式发送,可以不设置模板id和模板data(如:短信宝、云片、luosimao) Sms::make()->to($to)->content($content)->send(); // 同时确保能通过模板和内容方式发送,这样做的好处是,可以兼顾到各种类型服务商 @@ -146,10 +150,9 @@ Sms::voice('02343') ### 3. 在laravel中使用 -如果你只想单纯的在laravel中使用phpsms的功能可以按如下步骤操作, -当然也为你准备了基于phpsms开发的[laravel-sms](https://github.com/toplan/laravel-sms) +如果你只想单纯的在 laravel 中使用 phpsms 的功能可以按如下步骤操作。 -* 在config/app.php中引入服务提供器 +* 服务提供器 ```php //服务提供器 @@ -187,7 +190,7 @@ PhpSms::make()->to($to)->content($content)->send(); 设置/获取代理器的调度方案。 -> 调度配置在调度系统启动后(创建`Sms`实例时会自动启动)就不能修改。 +> 调度配置在应用系统的整个运行过程中都能修改。 - 设置 @@ -218,7 +221,7 @@ $scheme['SmsBao'] = Sms::scheme('SmsBao'); 设置/获取代理器的配置数据。 -> 代理器参数配置在应用系统的整个运行过程中都是能修改的,这点和调度配置有所不同。 +> 代理器参数配置在应用系统的整个运行过程中都能修改。 - 设置 @@ -251,7 +254,7 @@ $config['SmsBao'] = Sms::config('SmsBao'); 发送前钩子,示例: ```php -Sms::beforeSend(function($task, $prev, $index, $handlers){ +Sms::beforeSend(function($task, $index, $handlers, $prevReturn){ //获取短信数据 $smsData = $task->data; ... @@ -259,13 +262,13 @@ Sms::beforeSend(function($task, $prev, $index, $handlers){ return true; }); ``` -> 更多细节请查看[task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle)的“beforeRun”钩子 +> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `beforeRun` 钩子 ### Sms::beforeAgentSend($handler[, $override]); 代理器发送前钩子,示例: ```php -Sms::beforeAgentSend(function($task, $driver, $prev, $index, $handlers){ +Sms::beforeAgentSend(function($task, $driver, $index, $handlers, $prevReturn){ //短信数据: $smsData = $task->data; //当前使用的代理器名称: @@ -274,33 +277,33 @@ Sms::beforeAgentSend(function($task, $driver, $prev, $index, $handlers){ return true; }); ``` -> 更多细节请查看[task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle)的“beforeDriverRun”钩子 +> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `beforeDriverRun` 钩子 ### Sms::afterAgentSend($handler[, $override]); 代理器发送后钩子,示例: ```php -Sms::afterAgentSend(function($task, $result, $prev, $index, $handlers){ +Sms::afterAgentSend(function($task, $agentResult, $index, $handlers, $prevReturn){ //$result为代理器的发送结果数据 - $agentName = $result['driver']; + $agentName = $agentResult['driver']; ... }); ``` -> 更多细节请查看[task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle)的“afterDriverRun”钩子 +> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `afterDriverRun` 钩子 -### Sms::afterSend($handler [, $override]); +### Sms::afterSend($handler[, $override]); 发送后钩子,示例: ```php -Sms::afterSend(function($task, $result, $prev, $index, $handlers){ +Sms::afterSend(function($task, $taskResult, $index, $handlers, $prevReturn){ //$result为发送后获得的结果数组 - $success = $result['success']; + $success = $taskResult['success']; ... }); ``` -> 更多细节请查看[task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle)的“afterRun”钩子 +> 更多细节请查看 [task-balancer](https://github.com/toplan/task-balancer#2-task-lifecycle) 的 `afterRun` 钩子 -### Sms::queue($enable, $handler) +### Sms::queue([$enable[, $handler]]) 该方法可以设置是否启用队列以及定义如何推送到队列。 @@ -369,7 +372,7 @@ $sms = Sms::make([ ```php $sms = Sms::voice(); -//创建实例的同时设置验证码/语音文件ID +//创建实例的同时设置验证码 $sms = Sms::voice($code); ``` @@ -377,16 +380,20 @@ $sms = Sms::voice($code); > - **语音文件ID**即是在服务商配置的语音文件的唯一编号,比如阿里大鱼[语音通知](http://open.taobao.com/doc2/apiDetail.htm?spm=a219a.7395905.0.0.oORhh9&apiId=25445)的`voice_code`。 > - **模版语音**是另一种语音请求方式,它是通过模版ID和模版数据进行的语音请求,比如阿里大鱼的[文本转语音通知](http://open.taobao.com/doc2/apiDetail.htm?spm=a219a.7395905.0.0.f04PJ3&apiId=25444)。 -### $sms->to($mobile) +### type($type) + +设置实例类型,可选值有`Sms::TYPE_SMS`和`Sms::TYPE_VOICE`,返回实例对象。 + +### to($mobile) 设置发送给谁,并返回实例。 ```php $sms->to('1828*******'); ``` -### $sms->template($templates) +### template($templates) -指定代理器设置模版id或批量设置,并返回实例。 +指定代理器设置模版或批量设置,并返回实例。 ```php //设置指定服务商的模板id $sms->template('YunTongXun', 'your_temp_id') @@ -400,10 +407,14 @@ $sms->template([ ]); ``` -### $sms->data($data) +### data($data) 设置模板短信的模板数据,并返回实例对象。 ```php +//单个数据 +$sms->data('code', $code); + +//同时设置多个数据 $sms->data([ 'code' => $code, 'minutes' => $minutes @@ -412,28 +423,67 @@ $sms->data([ > 通过`template`和`data`方法的组合除了可以实现模版短信的数据填充,还可以实现模版语音的数据填充。 -### $sms->content($text) +### content($text) 设置内容短信的内容,并返回实例对象。一些内置的代理器(如SmsBao、YunPian、Luosimao)使用的是内容短信(即直接发送短信内容),那么就需要为它们设置短信内容。 ```php $sms->content('【签名】这是短信内容...'); ``` -### $sms->all([$key]) +### code($code) + +设置语音验证码,并返回实例对象。 + +### files($files) + +设置语音文件,并返回实例对象。 +```php +$sms->files('Agent1', 'agent1_file_id') + ->files('Agent2', 'agent2_file_id'); + +$sms->files([ + 'Agent1' => 'agent1_file_id', + 'Agent2' => 'agent2_fiile_id', +]); +``` + +### params($params) + +设置代理器参数,并返回实例对象。 +```php +$sms->params('Agent1', [ + 'callbackUrl' => ..., + 'userData' => ..., +]); + +$sms->params([ + 'Agent1' => [ + 'callbackUrl' => ..., + 'userData' => ..., + ], + 'Agent2' => [ + ... + ], +]); +``` + +### all([$key]) 获取Sms实例中的短信数据,不带参数时返回所有数据,其结构如下: ```php [ - 'type' => ..., - 'to' => ..., - 'templates' => [...], - 'content' => ..., - 'templateData' => [...], - 'voiceCode' => ..., + 'type' => ..., + 'to' => ..., + 'templates' => [...], + 'data' => [...], // template data + 'content' => ..., + 'code' => ..., // voice code + 'files' => [...], // voice files + 'params' => [...], ] ``` -### $sms->agent($name) +### agent($name) 临时设置发送时使用的代理器(不会影响备用代理器的正常使用),并返回实例,`$name`为代理器名称。 ```php @@ -441,14 +491,14 @@ $sms->agent('SmsBao'); ``` > 通过该方法设置的代理器将获得绝对优先权,但只对当前短信实例有效。 -### $sms->send() +### send() 请求发送短信/语音验证码。 ```php -//会遵循是否使用队列: +//会遵循是否使用队列 $result = $sms->send(); -//忽略是否使用队列: +//忽略是否使用队列 $result = $sms->send(true); ``` @@ -481,27 +531,37 @@ Sms::scheme('agentName', [ * 配置方式: -通过配置值中`sendSms`和`voiceVerify`键来设置发送短信和语音验证码的方式。 +可以配置的发送过程有: + +| Send Process | Arguments | +| ----------------- | :---------------------------: | +| sendContentSms | $agent, $to, $content | +| sendTemplateSms | $agent, $to, $tmpId, $tmpData | +| sendVoiceCode | $agent, $to, $code | +| sendContentVoice | $agent, $to, $content | +| sendTemplateVoice | $agent, $to, $tmpId, $tmpData | +| sendFileVoice | $agent, $to, $fileId | * 示例: ```php Sms::scheme([ 'agentName' => [ '20 backup', - 'sendSms' => function($agent, $to, $content, $tempId, $tempData){ - //获取配置(如果设置了的话): + 'sendContentSms' => function($agent, $to, $content){ + // 获取配置(如果设置了的话): $key = $agent->key; ... - //可使用的内置方法: - Agent::curl(...); + // 可使用的内置方法: + $agent->curlGet($url, $params); //get + $agent->curlPost($url, $params); //post ... - //更新发送结果: + // 更新发送结果: $agent->result(Agent::SUCCESS, true); $agent->result(Agent::INFO, 'some info'); $agent->result(Agent::CODE, 'your code'); }, - 'voiceVerify' => function($agent, $to, $code, $tempId, $tempData){ - //发送语音验证码,同上 + 'sendVoiceCode' => function($agent, $to, $code){ + // 发送语音验证码,同上 } ] ]); @@ -525,14 +585,6 @@ Sms::scheme([ 新建一个继承`Toplan\PhpSms\Agent`抽象类的代理器类,建议代理器类名为`FooAgent`,建议命名空间为`Toplan\PhpSms`。 如果类名不为`FooAgent`或者命名空间不为`Toplan\PhpSms`,在使用该代理器时则需要指定代理器类,详见[高级调度配置](#高级调度配置)。 -# Todo list - -- [ ] 可用代理器分组配置功能;短信发送时选择分组进行发送的功能。 - -# Encourage - -hi, guys! 如果喜欢或者要收藏,欢迎star。如果要提供意见和bug,欢迎issue或提交pr。 - # License MIT diff --git a/composer.json b/composer.json index cd2666b..0aa93f6 100644 --- a/composer.json +++ b/composer.json @@ -11,7 +11,7 @@ ], "require": { "php": ">=5.4.0", - "toplan/task-balancer": "~0.4", + "toplan/task-balancer": "~0.5.0-beta", "jeremeamia/SuperClosure": "~2.2" }, "require-dev": { diff --git a/src/config/phpsms.php b/src/config/phpsms.php index 447f796..9a691f5 100644 --- a/src/config/phpsms.php +++ b/src/config/phpsms.php @@ -1,34 +1,38 @@ scheme * - * The scheme value include: - * 1. weight (must be a positive integer) - * 2. 'backup' (ignore upper/lower case) + * The key-value paris: {name} => {value} + * + * Examples: + * 'Log' => '10 backup' + * 'SmsBao' => '100' + * 'CustomAgent' => [ + * '5 backup', + * 'agentClass' => '/Namespace/ClassName' + * ] + * + * Supported agents: + * 'Log', 'YunPian', 'YunTongXun', 'SubMail', 'Luosimao', + * 'Ucpaas', 'JuHe', 'Alidayu', 'SendCloud', 'SmsBao', + * 'Qcloud', 'Aliyun' * - * supported agents: - * 'Log', 'SmsBao', 'Luosimao', 'YunTongXun', 'YunPian', 'SubMail', 'Ucpaas', 'JuHe', 'Alidayu', 'SendCloud' */ 'scheme' => [ 'Log', ], /* - * agents config + * The configuration * ------------------------------------------------------------------- - * Note: agent name must be string. + * + * Expected the name of agent to be a string. * */ 'agents' => [ - /* * ----------------------------------- * YunPian @@ -51,30 +55,24 @@ * support template sms. */ 'YunTongXun' => [ - //主帐号,对应开官网发者主账号下的 ACCOUNT SID + //主帐号 'accountSid' => 'your account sid', - //主帐号令牌,对应官网开发者主账号下的 AUTH TOKEN + //主帐号令牌 'accountToken' => 'your account token', - //应用Id,在官网应用列表中点击应用,对应应用详情中的APP ID - //在开发调试的时候,可以使用官网自动为您分配的测试Demo的APP ID + //应用Id 'appId' => 'your app id', //请求地址 - //沙盒环境(用于应用开发调试):sandboxapp.cloopen.com - //生产环境(用户应用上线使用):app.cloopen.com 'serverIP' => 'app.cloopen.com', - //请求端口,生产环境和沙盒环境一致 + //请求端口 'serverPort' => '8883', //被叫号显 'displayNum' => null, - //语音验证码使用的语言类型 - 'voiceLang' => 'zh', - //语音验证码播放次数 'playTimes' => 3, ], @@ -190,21 +188,49 @@ * SmsBao * ----------------------------------- * website: http://www.smsbao.com - * not support template sms. - * 不支持模板变量短信 * support content sms. - * 支持内容短信 - * support voice sms. - * 支持语音验证码 - * 支持自定义短信签名 - * 最低消费5元(50条) 最低消费单价0.04元(100万条) */ 'SmsBao' => [ - //username + //注册账号 'username' => 'your username', - //password + //账号密码(明文) 'password' => 'your password', ], + + /* + * ----------------------------------- + * Qcloud + * 腾讯云 + * ----------------------------------- + * website:http://www.qcloud.com + * support template sms. + */ + 'Qcloud' => [ + //App ID + 'appId' => 'your app id', + + //App KEY + 'appKey' => 'your app key', + ], + + /* + * ----------------------------------- + * Aliyun + * 阿里云 + * ----------------------------------- + * website:https://www.aliyun.com/product/sms + * support template sms. + */ + 'AliyunSms' => [ + //阿里云颁发给用户的访问服务所用的密钥ID + 'accessKeyId' => 'your access key id', + + //阿里云颁发给用户的,用于加密签名字符串和服务器端验证签名字符串的密钥 + 'accessKeySecret' => 'your access key secret', + + //阿里云管理控制台中配置的短信签名(状态必须是验证通过) + 'signName' => 'your sms sign name', + ], ], ]; diff --git a/src/phpsms/Sms.php b/src/phpsms/Sms.php index b422387..d1c1676 100644 --- a/src/phpsms/Sms.php +++ b/src/phpsms/Sms.php @@ -2,8 +2,7 @@ namespace Toplan\PhpSms; -use SuperClosure\Serializer; -use Toplan\TaskBalance\Balancer; +use Toplan\TaskBalance\Driver; use Toplan\TaskBalance\Task; /** @@ -13,33 +12,39 @@ */ class Sms { - const TASK_NAME = 'PhpSms'; const TYPE_SMS = 1; const TYPE_VOICE = 2; + /** + * Task instance. + * + * @var Task + */ + protected static $task = null; + /** * Agent instances. * - * @var array + * @var Agent[] */ protected static $agents = []; /** - * The dispatch scheme of agents. + * Dispatch scheme of agents. * * @var array */ protected static $scheme = []; /** - * The configuration information of agents. + * Configuration information of agents. * * @var array */ protected static $agentsConfig = []; /** - * Whether to use the queue. + * Whether to use the queue system. * * @var bool */ @@ -55,7 +60,7 @@ class Sms /** * Available hooks. * - * @var array + * @var string[] */ protected static $availableHooks = [ 'beforeRun', @@ -64,31 +69,26 @@ class Sms 'afterRun', ]; - /** - * Closure serializer. - * - * @var Serializer - */ - protected static $serializer = null; - /** * Data container. * * @var array */ protected $smsData = [ - 'type' => self::TYPE_SMS, - 'to' => null, - 'templates' => [], - 'templateData' => [], - 'content' => null, - 'voiceCode' => null, + 'type' => self::TYPE_SMS, + 'to' => null, + 'templates' => [], + 'data' => [], + 'content' => null, + 'code' => null, + 'files' => [], + 'params' => [], ]; /** * The name of first agent. * - * @var string|null + * @var string */ protected $firstAgent = null; @@ -114,34 +114,31 @@ class Sms public function __construct($autoBoot = true) { if ($autoBoot) { - self::bootstrap(); + self::bootTask(); } } /** * Bootstrap the task. */ - public static function bootstrap() + public static function bootTask() { - if (!self::taskInitialized()) { - self::configuration(); - self::initTask(); + if (!self::isTaskBooted()) { + self::configure(); + foreach (self::scheme() as $name => $scheme) { + self::registerDriver($name, $scheme); + } } } /** - * Whether the task initialized. - * - * Note: 判断drivers是否为空不能用'empty',因为在TaskBalance库的中Task类的drivers属性是受保护的(不可访问), - * 虽然通过魔术方法可以获取到其值,但在其目前版本(v0.4.2)其内部却并没有使用'__isset'魔术方法对'empty'或'isset'函数进行逻辑补救. + * Is task has been booted. * * @return bool */ - protected static function taskInitialized() + protected static function isTaskBooted() { - $task = self::getTask(); - - return (bool) count($task->drivers); + return !empty(self::getTask()->drivers); } /** @@ -151,17 +148,19 @@ protected static function taskInitialized() */ public static function getTask() { - if (!Balancer::hasTask(self::TASK_NAME)) { - Balancer::task(self::TASK_NAME); + if (empty(self::$task)) { + self::$task = new Task(); } - return Balancer::getTask(self::TASK_NAME); + return self::$task; } /** - * Configuration. + * Configure. + * + * @throws PhpSmsException */ - protected static function configuration() + protected static function configure() { $config = []; if (!count(self::scheme())) { @@ -169,7 +168,9 @@ protected static function configuration() } $diff = array_diff_key(self::scheme(), self::$agentsConfig); self::initAgentsConfig(array_keys($diff), $config); - self::validateConfig(); + if (!count(self::scheme())) { + throw new PhpSmsException('Expected at least one agent in scheme.'); + } } /** @@ -204,49 +205,39 @@ protected static function initAgentsConfig(array $agents, array &$config) } /** - * Validate the configuration. + * register driver. * - * @throws PhpSmsException + * @param string $name + * @param string|array $scheme */ - protected static function validateConfig() + protected static function registerDriver($name, $scheme) { - if (!count(self::scheme())) { - throw new PhpSmsException('Please configure at least one agent.'); + // parse higher-order scheme + $settings = []; + if (is_array($scheme)) { + $settings = self::parseScheme($scheme); + $scheme = $settings['scheme']; } - } - - /** - * Initialize the task. - */ - protected static function initTask() - { - foreach (self::scheme() as $name => $scheme) { - // parse higher-order scheme - $settings = []; - if (is_array($scheme)) { - $settings = self::parseScheme($scheme); - $scheme = $settings['scheme']; + // register + self::getTask()->driver("$name $scheme")->work(function (Driver $driver) use ($settings) { + $agent = self::getAgent($driver->name, $settings); + extract($driver->getTaskData()); + $template = isset($templates[$driver->name]) ? $templates[$driver->name] : null; + $file = isset($files[$driver->name]) ? $files[$driver->name] : null; + $params = isset($params[$driver->name]) ? $params[$driver->name] : []; + if ($type === self::TYPE_VOICE) { + $agent->sendVoice($to, $content, $template, $data, $code, $file, $params); + } elseif ($type === self::TYPE_SMS) { + $agent->sendSms($to, $content, $template, $data, $params); } - // create driver - self::getTask()->driver("$name $scheme")->work(function ($driver) use ($settings) { - $agent = self::getAgent($driver->name, $settings); - $smsData = $driver->getTaskData(); - extract($smsData); - $template = isset($templates[$driver->name]) ? $templates[$driver->name] : 0; - if ($type === self::TYPE_VOICE) { - $agent->voiceVerify($to, $voiceCode, $template, $templateData); - } elseif ($type === self::TYPE_SMS) { - $agent->sendSms($to, $content, $template, $templateData); - } - $result = $agent->result(); - if ($result['success']) { - $driver->success(); - } - unset($result['success']); + $result = $agent->result(); + if ($result['success']) { + $driver->success(); + } + unset($result['success']); - return $result; - }); - } + return $result; + }); } /** @@ -258,13 +249,15 @@ protected static function initTask() */ protected static function parseScheme(array $options) { - $agentClass = Util::pullFromArrayByKey($options, 'agentClass'); - $sendSms = Util::pullFromArrayByKey($options, 'sendSms'); - $voiceVerify = Util::pullFromArrayByKey($options, 'voiceVerify'); - $backup = Util::pullFromArrayByKey($options, 'backup') ? 'backup' : ''; - $scheme = implode(' ', array_values($options)) . " $backup"; + $weight = Util::pullFromArray($options, 'weight'); + $backup = Util::pullFromArray($options, 'backup') ? 'backup' : ''; + $props = array_filter(array_values($options), function ($prop) { + return is_numeric($prop) || is_string($prop); + }); - return compact('agentClass', 'sendSms', 'voiceVerify', 'scheme'); + $options['scheme'] = implode(' ', $props) . " $weight $backup"; + + return $options; } /** @@ -275,7 +268,7 @@ protected static function parseScheme(array $options) * * @throws PhpSmsException * - * @return mixed + * @return Agent */ public static function getAgent($name, array $options = []) { @@ -293,13 +286,12 @@ public static function getAgent($name, array $options = []) $className = $options['agentClass']; unset($options['agentClass']); } - if (isset($options['sendSms']) || isset($options['voiceVerify'])) { - $config = array_merge($config, $options); - self::$agents[$name] = new ParasiticAgent($config); + if (!empty($options)) { + self::$agents[$name] = new ParasiticAgent($config, $options); } elseif (class_exists($className)) { self::$agents[$name] = new $className($config); } else { - throw new PhpSmsException("Do not support `$name` agent."); + throw new PhpSmsException("Not support agent `$name`."); } } @@ -321,45 +313,65 @@ public static function hasAgent($name) /** * Set or get the dispatch scheme. * - * @param mixed $name - * @param mixed $scheme + * @param string|array|null $name + * @param string|array|bool|null $scheme + * @param bool $override * * @return mixed */ - public static function scheme($name = null, $scheme = null) + public static function scheme($name = null, $scheme = null, $override = false) { + if (is_array($name) && is_bool($scheme)) { + $override = $scheme; + } + return Util::operateArray(self::$scheme, $name, $scheme, null, function ($key, $value) { if (is_string($key)) { self::modifyScheme($key, is_array($value) ? $value : "$value"); } elseif (is_int($key)) { self::modifyScheme($value, ''); } + }, $override, function (array $origin) { + if (self::isTaskBooted()) { + foreach (array_keys($origin) as $name) { + self::getTask()->removeDriver($name); + } + } }); } /** * Modify the dispatch scheme of agent. * - * @param $key - * @param $value + * @param string $name + * @param string|array $scheme * * @throws PhpSmsException */ - protected static function modifyScheme($key, $value) + protected static function modifyScheme($name, $scheme) { - if (self::taskInitialized()) { - throw new PhpSmsException("Modify the dispatch scheme of `$key` agent failed, because the task system has already started."); + self::validateAgentName($name); + self::$scheme[$name] = $scheme; + if (self::isTaskBooted()) { + $driver = self::getTask()->getDriver($name); + if ($driver) { + if (is_array($scheme)) { + $higherOrderScheme = self::parseScheme($scheme); + $scheme = $higherOrderScheme['scheme']; + } + $driver->reset($scheme); + } else { + self::registerDriver($name, $scheme); + } } - self::validateAgentName($key); - self::$scheme[$key] = $value; } /** * Set or get the configuration information. * - * @param mixed $name - * @param mixed $config - * @param bool $override + * @param string|array|null $name + * @param array|bool|null $config + * @param bool $override * * @throws PhpSmsException * @@ -367,17 +379,12 @@ protected static function modifyScheme($key, $value) */ public static function config($name = null, $config = null, $override = false) { - if (is_array($name) && is_bool($config)) { - $override = $config; - } + $overrideAll = (is_array($name) && is_bool($config)) ? $config : false; - return Util::operateArray(self::$agentsConfig, $name, $config, [], function ($key, $value) { - if (is_array($value)) { - self::modifyConfig($key, $value); - } - }, $override, function (array $origin) { - $nameList = array_keys($origin); - foreach ($nameList as $name) { + return Util::operateArray(self::$agentsConfig, $name, $config, [], function ($name, array $config) use ($override) { + self::modifyConfig($name, $config, $override); + }, $overrideAll, function (array $origin) { + foreach (array_keys($origin) as $name) { if (self::hasAgent("$name")) { self::getAgent("$name")->config([], true); } @@ -388,17 +395,26 @@ public static function config($name = null, $config = null, $override = false) /** * Modify the configuration information. * - * @param string $key - * @param array $value + * @param string $name + * @param array $config + * @param bool $override * * @throws PhpSmsException */ - protected static function modifyConfig($key, array $value) + protected static function modifyConfig($name, array $config, $override = false) { - self::validateAgentName($key); - self::$agentsConfig[$key] = $value; - if (self::hasAgent($key)) { - self::getAgent($key)->config($value); + self::validateAgentName($name); + if (!isset(self::$agentsConfig[$name])) { + self::$agentsConfig[$name] = []; + } + $target = &self::$agentsConfig[$name]; + if ($override) { + $target = $config; + } else { + $target = array_merge($target, $config); + } + if (self::hasAgent($name)) { + self::getAgent($name)->config($target); } } @@ -412,23 +428,21 @@ protected static function modifyConfig($key, array $value) */ protected static function validateAgentName($name) { - if (!$name || !is_string($name) || preg_match('/^[0-9]+$/', $name)) { - throw new PhpSmsException("Expected the agent name `$name` to be a string, witch except the string of number."); + if (empty($name) || !is_string($name) || preg_match('/^[0-9]+$/', $name)) { + throw new PhpSmsException('Expected the parameter to be string which except the string of number.'); } } /** - * Tear down agent use scheme and prepare to create and start a new task, - * so before do it must destroy old task instance. + * Tear down scheme. */ public static function cleanScheme() { - Balancer::destroy(self::TASK_NAME); - self::$scheme = []; + self::scheme([], true); } /** - * Tear down all the configuration information of agent. + * Tear down config information. */ public static function cleanConfig() { @@ -436,8 +450,7 @@ public static function cleanConfig() } /** - * Create a instance for send sms, - * you can also set templates or content at the same time. + * Create a instance for send sms. * * @param mixed $agentName * @param mixed $tempId @@ -447,7 +460,7 @@ public static function cleanConfig() public static function make($agentName = null, $tempId = null) { $sms = new self(); - $sms->smsData['type'] = self::TYPE_SMS; + $sms->type(self::TYPE_SMS); if (is_array($agentName)) { $sms->template($agentName); } elseif ($agentName && is_string($agentName)) { @@ -462,8 +475,7 @@ public static function make($agentName = null, $tempId = null) } /** - * Create a instance for send voice verify code, - * you can also set verify code at the same time. + * Create a instance for send voice. * * @param int|string|null $code * @@ -472,8 +484,8 @@ public static function make($agentName = null, $tempId = null) public static function voice($code = null) { $sms = new self(); - $sms->smsData['type'] = self::TYPE_VOICE; - $sms->smsData['voiceCode'] = $code; + $sms->type(self::TYPE_VOICE); + $sms->code($code); return $sms; } @@ -482,8 +494,8 @@ public static function voice($code = null) * Set whether to use the queue system, * and define how to use it. * - * @param mixed $enable - * @param mixed $handler + * @param bool|\Closure|null $enable + * @param \Closure|null $handler * * @return bool */ @@ -504,6 +516,25 @@ public static function queue($enable = null, $handler = null) return self::$enableQueue; } + /** + * Set the type of Sms instance. + * + * @param $type + * + * @throws PhpSmsException + * + * @return $this + */ + public function type($type) + { + if ($type !== self::TYPE_SMS && $type !== self::TYPE_VOICE) { + throw new PhpSmsException('Expected the parameter equals to `Sms::TYPE_SMS` or `Sms::TYPE_VOICE`.'); + } + $this->smsData['type'] = $type; + + return $this; + } + /** * Set the recipient`s mobile number. * @@ -550,14 +581,70 @@ public function template($name, $tempId = null) /** * Set the template data. * - * @param mixed $name + * @param mixed $key * @param mixed $value * * @return $this */ - public function data($name, $value = null) + public function data($key, $value = null) + { + Util::operateArray($this->smsData['data'], $key, $value); + + return $this; + } + + /** + * Set the voice code. + * + * @param string|int $code + * + * @return $this + */ + public function code($code) + { + $this->smsData['code'] = $code; + + return $this; + } + + /** + * Set voice files. + * + * @param string|array $name + * @param string|int $id + * + * @return $this + */ + public function files($name, $id = null) + { + Util::operateArray($this->smsData['files'], $name, $id); + + return $this; + } + + /** + * Set params of agent. + * + * @param string|array $name + * @param array|bool|null $params + * @param bool $override + * + * @return $this + */ + public function params($name, $params = null, $override = false) { - Util::operateArray($this->smsData['templateData'], $name, $value); + $overrideAll = (is_array($name) && is_bool($params)) ? $params : false; + Util::operateArray($this->smsData['params'], $name, $params, [], function ($name, array $params) use ($override) { + if (!isset($this->smsData['params'][$name])) { + $this->smsData['params'][$name] = []; + } + $target = &$this->smsData['params'][$name]; + if ($override) { + $target = $params; + } else { + $target = array_merge($target, $params); + } + }, $overrideAll); return $this; } @@ -567,11 +654,16 @@ public function data($name, $value = null) * * @param string $name * + * @throws PhpSmsException + * * @return $this */ public function agent($name) { - $this->firstAgent = (string) $name; + if (!is_string($name) || empty($name)) { + throw new PhpSmsException('Expected the parameter to be non-empty string.'); + } + $this->firstAgent = $name; return $this; } @@ -593,10 +685,7 @@ public function send($immediately = false) $immediately = true; } if ($immediately) { - return Balancer::run(self::TASK_NAME, [ - 'data' => $this->getData(), - 'driver' => $this->firstAgent, - ]); + return self::$task->data($this->all())->run($this->firstAgent); } return $this->push(); @@ -612,12 +701,12 @@ public function send($immediately = false) public function push() { if (!is_callable(self::$howToUseQueue)) { - throw new PhpSmsException('Please define how to use the queue system by the `queue` method.'); + throw new PhpSmsException('Expected define how to use the queue system by methods `queue`.'); } try { $this->pushedToQueue = true; - return call_user_func_array(self::$howToUseQueue, [$this, $this->getData()]); + return call_user_func_array(self::$howToUseQueue, [$this, $this->all()]); } catch (\Exception $e) { $this->pushedToQueue = false; throw $e; @@ -633,25 +722,13 @@ public function push() */ public function all($key = null) { - if (is_string($key) && isset($this->smsData["$key"])) { - return $this->smsData[$key]; + if ($key !== null) { + return isset($this->smsData[$key]) ? $this->smsData[$key] : null; } return $this->smsData; } - /** - * The alias of `all` method. - * - * @param null|string $key - * - * @return mixed - */ - public function getData($key = null) - { - return $this->all($key); - } - /** * Define the static hook methods by overload static method. * @@ -667,15 +744,11 @@ public static function __callStatic($name, $args) $name = $name === 'beforeAgentSend' ? 'beforeDriverRun' : $name; $name = $name === 'afterAgentSend' ? 'afterDriverRun' : $name; if (!in_array($name, self::$availableHooks)) { - throw new PhpSmsException("Do not find method `$name`."); + throw new PhpSmsException("Not found methods `$name`."); } $handler = $args[0]; $override = isset($args[1]) ? (bool) $args[1] : false; - if (!is_callable($handler)) { - throw new PhpSmsException("Please call method `$name` with a callable parameter."); - } - $task = self::getTask(); - $task->hook($name, $handler, $override); + self::getTask()->hook($name, $handler, $override); } /** @@ -704,7 +777,7 @@ public function __call($name, $args) public function __sleep() { try { - $this->state['scheme'] = self::serializeOrDeserializeScheme(self::scheme()); + $this->state['scheme'] = self::toggleSerializeScheme(self::scheme()); $this->state['agentsConfig'] = self::config(); $this->state['handlers'] = self::serializeHandlers(); } catch (\Exception $e) { @@ -722,27 +795,11 @@ public function __wakeup() if (empty($this->state)) { return; } - self::$scheme = self::serializeOrDeserializeScheme($this->state['scheme']); + self::$scheme = self::toggleSerializeScheme($this->state['scheme']); self::$agentsConfig = $this->state['agentsConfig']; - Balancer::destroy(self::TASK_NAME); - self::bootstrap(); self::reinstallHandlers($this->state['handlers']); } - /** - * Get a closure serializer. - * - * @return Serializer - */ - protected static function getSerializer() - { - if (!self::$serializer) { - self::$serializer = new Serializer(); - } - - return self::$serializer; - } - /** * Serialize or deserialize the scheme. * @@ -750,12 +807,13 @@ protected static function getSerializer() * * @return array */ - protected static function serializeOrDeserializeScheme(array $scheme) + protected static function toggleSerializeScheme(array $scheme) { foreach ($scheme as $name => &$options) { if (is_array($options)) { - self::serializeOrDeserializeClosureAndReplace($options, 'sendSms'); - self::serializeOrDeserializeClosureAndReplace($options, 'voiceVerify'); + foreach (ParasiticAgent::methods() as $method) { + self::toggleSerializeClosure($options, $method); + } } } @@ -763,17 +821,16 @@ protected static function serializeOrDeserializeScheme(array $scheme) } /** - * Serialize the hooks` handlers. + * Serialize the hooks' handlers. * * @return array */ protected static function serializeHandlers() { - $task = self::getTask(); - $hooks = (array) $task->handlers; + $hooks = (array) self::getTask()->handlers; foreach ($hooks as &$handlers) { foreach (array_keys($handlers) as $key) { - self::serializeOrDeserializeClosureAndReplace($handlers, $key); + self::toggleSerializeClosure($handlers, $key); } } @@ -781,13 +838,13 @@ protected static function serializeHandlers() } /** - * Reinstall hooks` handlers. + * Reinstall hooks' handlers. * * @param array $handlers */ protected static function reinstallHandlers(array $handlers) { - $serializer = self::getSerializer(); + $serializer = Util::getClosureSerializer(); foreach ($handlers as $hookName => $serializedHandlers) { foreach ($serializedHandlers as $index => $handler) { if (is_string($handler)) { @@ -804,12 +861,12 @@ protected static function reinstallHandlers(array $handlers) * @param array $options * @param int|string $key */ - protected static function serializeOrDeserializeClosureAndReplace(array &$options, $key) + protected static function toggleSerializeClosure(array &$options, $key) { if (!isset($options[$key])) { return; } - $serializer = self::getSerializer(); + $serializer = Util::getClosureSerializer(); if (is_callable($options[$key])) { $options[$key] = (string) $serializer->serialize($options[$key]); } elseif (is_string($options[$key])) { diff --git a/src/phpsms/Util.php b/src/phpsms/Util.php index 5b92316..987b639 100644 --- a/src/phpsms/Util.php +++ b/src/phpsms/Util.php @@ -2,22 +2,12 @@ namespace Toplan\PhpSms; +use SuperClosure\Serializer; + class Util { - /** - * 对数组进行赋值/取值操作 - * - * @param array $array - * @param mixed $key - * @param mixed $value - * @param mixed $default - * @param \Closure|null $setter - * @param bool $override - * @param \Closure|null $willOverride - * @param bool $isSet - * - * @return mixed - */ + protected static $closureSerializer = null; + public static function operateArray(array &$array, $key, $value = null, $default = null, \Closure $setter = null, $override = false, $willOverride = null, $isSet = false) { if (!$isSet && ($key === null || is_string($key) || is_int($key)) && $value === null) { @@ -43,22 +33,24 @@ public static function operateArray(array &$array, $key, $value = null, $default return $array; } - /** - * 从数组中根据指定键名拉取数据 - * - * @param array $options - * @param int|string $key - * - * @return mixed - */ - public static function pullFromArrayByKey(array &$options, $key) + public static function pullFromArray(array &$options, $key) { + $value = null; if (!isset($options[$key])) { - return; + return $value; } $value = $options[$key]; unset($options[$key]); return $value; } + + public static function getClosureSerializer() + { + if (empty(self::$closureSerializer)) { + self::$closureSerializer = new Serializer(); + } + + return self::$closureSerializer; + } } diff --git a/src/phpsms/agents/Agent.php b/src/phpsms/agents/Agent.php index 56901b2..a3b7cbc 100644 --- a/src/phpsms/agents/Agent.php +++ b/src/phpsms/agents/Agent.php @@ -15,16 +15,19 @@ abstract class Agent */ protected $config = []; + /** + * The custom params of request. + * + * @var array + */ + protected $params = []; + /** * The result data. * * @var array */ - protected $result = [ - self::SUCCESS => false, - self::INFO => null, - self::CODE => 0, - ]; + protected $result = []; /** * Constructor. @@ -33,15 +36,28 @@ abstract class Agent */ public function __construct(array $config = []) { + $this->reset(); $this->config($config); } /** - * Get or set the configuration information of agent. + * Reset states. + */ + public function reset() + { + $this->result = [ + self::SUCCESS => false, + self::INFO => null, + self::CODE => 0, + ]; + } + + /** + * Get or set the configuration information. * - * @param mixed $key - * @param mixed $value - * @param bool $override + * @param string|array $key + * @param mixed $value + * @param bool $override * * @return mixed */ @@ -54,51 +70,126 @@ public function config($key = null, $value = null, $override = false) return Util::operateArray($this->config, $key, $value, null, null, $override); } + /** + * Get or set the custom params. + * + * @param string|array $key + * @param mixed $value + * @param bool $override + * + * @return mixed + */ + public function params($key = null, $value = null, $override = false) + { + if (is_array($key) && is_bool($value)) { + $override = $value; + } + + return Util::operateArray($this->params, $key, $value, null, null, $override); + } + /** * SMS send process. * * @param $to * @param $content * @param $tempId - * @param array $tempData + * @param array $data + * @param array $params */ - abstract public function sendSms($to, $content, $tempId, array $tempData); + public function sendSms($to, $content = null, $tempId = null, array $data = [], array $params = []) + { + $this->reset(); + $this->params($params, true); + if ($tempId && $this instanceof TemplateSms) { + $this->sendTemplateSms($to, $tempId, $data); + } elseif ($content && $this instanceof ContentSms) { + $this->sendContentSms($to, $content); + } + } /** - * Voice verify send process. + * Voice send process. * * @param $to - * @param $code + * @param $content * @param $tempId - * @param array $tempData + * @param array $data + * @param $code + * @param $fileId + * @param array $params */ - abstract public function voiceVerify($to, $code, $tempId, array $tempData); + public function sendVoice($to, $content = null, $tempId = null, array $data = [], $code = null, $fileId = null, array $params = []) + { + $this->reset(); + $this->params($params, true); + if ($tempId && $this instanceof TemplateVoice) { + $this->sendTemplateVoice($to, $tempId, $data); + } elseif ($fileId && $this instanceof FileVoice) { + $this->sendFileVoice($to, $fileId); + } elseif ($code && $this instanceof VoiceCode) { + $this->sendVoiceCode($to, $code); + } elseif ($content && $this instanceof ContentVoice) { + $this->sendContentVoice($to, $content); + } + } + + /** + * @codeCoverageIgnore + * + * @param $url + * @param array $params + * @param array $opts + * + * @return array + */ + public function curlPost($url, array $params = [], array $opts = []) + { + $params = $this->params($params); + $opts = array_merge([ + CURLOPT_POSTFIELDS => $params, + ], $opts, [ + CURLOPT_POST => true, + CURLOPT_URL => $url, + ]); + + return self::curl($opts); + } + + /** + * @codeCoverageIgnore + * + * @param $url + * @param array $params + * @param array $opts + * + * @return array + */ + public function curlGet($url, array $params = [], array $opts = []) + { + $params = $this->params($params); + $queryStr = http_build_query($params); + $opts = array_merge($opts, [ + CURLOPT_POST => false, + CURLOPT_URL => $queryStr ? "$url?$queryStr" : $url, + ]); + + return self::curl($opts); + } /** * cURl * * @codeCoverageIgnore * - * @param string $url [请求地址] - * @param array $params [请求参数] - * @param bool $post [是否post] - * @param array $opts [curl设置项] + * @param array $opts curl options * * @return array ['request', 'response'] - * request:是否请求成功 - * response:响应数据 + * request: Whether request success. + * response: Response data. */ - public static function curl($url, $params = [], $post = false, array $opts = []) + public static function curl(array $opts = []) { - if (is_array($post)) { - $opts = $post; - $post = false; - } - if (is_bool($params)) { - $post = $params; - $params = []; - } - $ch = curl_init(); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_HEADER, false); @@ -107,19 +198,11 @@ public static function curl($url, $params = [], $post = false, array $opts = []) curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); - if ($post) { - curl_setopt($ch, CURLOPT_POST, true); - curl_setopt($ch, CURLOPT_POSTFIELDS, $params); - curl_setopt($ch, CURLOPT_URL, $url); - } else { - $params = http_build_query($params); - curl_setopt($ch, CURLOPT_URL, $params ? "$url?$params" : $url); - } foreach ($opts as $key => $value) { curl_setopt($ch, $key, $value); } - $response = curl_exec($ch); + $response = curl_exec($ch); $request = $response !== false; if (!$request) { $response = curl_getinfo($ch); @@ -144,9 +227,9 @@ public function result($name = null, $value = null) } if (array_key_exists($name, $this->result)) { if ($value === null) { - return $this->result["$name"]; + return $this->result[$name]; } - $this->result["$name"] = $value; + $this->result[$name] = $value; } } diff --git a/src/phpsms/agents/AlidayuAgent.php b/src/phpsms/agents/AlidayuAgent.php index 026adc1..5207bd5 100644 --- a/src/phpsms/agents/AlidayuAgent.php +++ b/src/phpsms/agents/AlidayuAgent.php @@ -11,64 +11,82 @@ * @property string $smsFreeSignName * @property string $calledShowNum */ -class AlidayuAgent extends Agent implements TemplateSms +class AlidayuAgent extends Agent implements TemplateSms, VoiceCode, TemplateVoice { - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendTemplateSms($to, $tempId, $data); - } - - public function sendTemplateSms($to, $tempId, array $data) + /** + * Template SMS send process. + * + * @param string|array $to + * @param int|string $tempId + * @param array $tempData + */ + public function sendTemplateSms($to, $tempId, array $tempData) { $params = [ 'method' => 'alibaba.aliqin.fc.sms.num.send', 'sms_type' => 'normal', 'sms_free_sign_name' => $this->smsFreeSignName, - 'sms_param' => $this->getTempDataString($data), + 'sms_param' => $this->getTempDataString($tempData), 'rec_num' => $to, 'sms_template_code' => $tempId, ]; $this->request($params); } - public function voiceVerify($to, $code, $tempId, array $data) + /** + * Template voice send process. + * + * @param string|array $to + * @param int|string $tempId + * @param array $tempData + */ + public function sendTemplateVoice($to, $tempId, array $tempData) { $params = [ - 'called_num' => $to, - 'called_show_num' => $this->calledShowNum, + 'called_num' => $to, + 'called_show_num' => $this->calledShowNum, + 'method' => 'alibaba.aliqin.fc.tts.num.singlecall', + 'tts_code' => $tempId, + 'tts_param' => $this->getTempDataString($tempData), + ]; + $this->request($params); + } + + /** + * Voice code send process. + * + * @param string|array $to + * @param int|string $code + */ + public function sendVoiceCode($to, $code) + { + $params = [ + 'called_num' => $to, + 'called_show_num' => $this->calledShowNum, + 'method' => 'alibaba.aliqin.fc.voice.num.singlecall', + 'voice_code' => $code, ]; - if ($tempId) { - //文本转语音通知 - $params['method'] = 'alibaba.aliqin.fc.tts.num.singlecall'; - $params['tts_code'] = $tempId; - $params['tts_param'] = $this->getTempDataString($data); - } elseif ($code) { - //语音通知 - $params['method'] = 'alibaba.aliqin.fc.voice.num.singlecall'; - $params['voice_code'] = $code; - } $this->request($params); } protected function request(array $params) { $params = $this->createParams($params); - $result = $this->curl($this->sendUrl, $params, true); + $result = $this->curlPost($this->sendUrl, $params); $this->setResult($result, $this->genResponseName($params['method'])); } protected function createParams(array $params) { - $params = array_merge([ + return array_merge([ 'app_key' => $this->appKey, 'v' => '2.0', 'format' => 'json', 'sign_method' => 'md5', 'timestamp' => date('Y-m-d H:i:s'), - ], $params); - $params['sign'] = $this->genSign($params); - - return $params; + ], $params, [ + 'sign' => $this->genSign($params), + ]); } protected function genSign($params) diff --git a/src/phpsms/agents/AliyunAgent.php b/src/phpsms/agents/AliyunAgent.php new file mode 100644 index 0000000..d0a1108 --- /dev/null +++ b/src/phpsms/agents/AliyunAgent.php @@ -0,0 +1,95 @@ + 'SingleSendSms', + 'SignName' => $this->signName, + 'ParamString' => $this->getTempDataString($data), + 'RecNum' => $to, + 'TemplateCode' => $tempId, + ]; + $this->request($params); + } + + protected function request(array $params) + { + $params = $this->createParams($params); + $result = $this->curlPost(self::$sendUrl, $params); + $this->setResult($result); + } + + protected function createParams(array $params) + { + return array_merge([ + 'Format' => 'JSON', + 'Version' => '2016-09-27', + 'AccessKeyId' => $this->accessKeyId, + 'SignatureMethod' => 'HMAC-SHA1', + 'Timestamp' => date('Y-m-d\TH:i:s\Z'), + 'SignatureVersion' => '1.0', + 'SignatureNonce' => uniqid(), + ], $params, [ + 'Signature' => $this->computeSignature($params), + ]); + } + + private function computeSignature($parameters) + { + ksort($parameters); + $canonicalizedQueryString = ''; + foreach ($parameters as $key => $value) { + $canonicalizedQueryString .= '&' . $this->percentEncode($key) . '=' . $this->percentEncode($value); + } + $stringToSign = 'POST&%2F&' . $this->percentencode(substr($canonicalizedQueryString, 1)); + + return base64_encode(hash_hmac('sha1', $stringToSign, $this->accessKeySecret . '&', true)); + } + + protected function percentEncode($str) + { + $res = urlencode($str); + $res = preg_replace('/\+/', '%20', $res); + $res = preg_replace('/\*/', '%2A', $res); + $res = preg_replace('/%7E/', '~', $res); + + return $res; + } + + protected function setResult($result) + { + if ($result['request']) { + $this->result(Agent::INFO, $result['response']); + $result = json_decode($result['response'], true); + if (isset($result['Message'])) { + $this->result(Agent::CODE, $result['Code']); + } else { + $this->result(Agent::SUCCESS, true); + } + } else { + $this->result(Agent::INFO, 'request failed'); + } + } + + protected function getTempDataString(array $data) + { + $data = array_map(function ($value) { + return (string) $value; + }, $data); + + return json_encode($data); + } +} diff --git a/src/phpsms/agents/JuHeAgent.php b/src/phpsms/agents/JuHeAgent.php index f34edf1..f5241f7 100644 --- a/src/phpsms/agents/JuHeAgent.php +++ b/src/phpsms/agents/JuHeAgent.php @@ -8,13 +8,8 @@ * @property string $key * @property string $times */ -class JuHeAgent extends Agent implements TemplateSms +class JuHeAgent extends Agent implements TemplateSms, VoiceCode { - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendTemplateSms($to, $tempId, $data); - } - public function sendTemplateSms($to, $tempId, array $data) { $sendUrl = 'http://v.juhe.cn/sms/send'; @@ -26,19 +21,18 @@ public function sendTemplateSms($to, $tempId, array $data) $split = !$tplValue ? '' : '&'; $tplValue .= "$split#$key#=$value"; } - $tplValue = !$tplValue ?: urlencode($tplValue); - $smsConf = [ + $params = [ 'key' => $this->key, 'mobile' => $to, 'tpl_id' => $tempId, - 'tpl_value' => $tplValue, + 'tpl_value' => urlencode($tplValue), 'dtype' => 'json', ]; - $result = $this->curl($sendUrl, $smsConf); + $result = $this->curlGet($sendUrl, $params); $this->setResult($result); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $url = 'http://op.juhe.cn/yuntongxun/voice'; $params = [ @@ -48,7 +42,7 @@ public function voiceVerify($to, $code, $tempId, array $data) 'key' => $this->key, 'dtype' => 'json', ]; - $result = $this->curl($url, $params); + $result = $this->curlGet($url, $params); $this->setResult($result); } diff --git a/src/phpsms/agents/LogAgent.php b/src/phpsms/agents/LogAgent.php index 931f926..07edb22 100644 --- a/src/phpsms/agents/LogAgent.php +++ b/src/phpsms/agents/LogAgent.php @@ -5,17 +5,8 @@ /** * Class LogAgent */ -class LogAgent extends Agent implements TemplateSms, ContentSms +class LogAgent extends Agent implements TemplateSms, ContentSms, VoiceCode { - public function sendSms($to, $content, $tempId, array $data) - { - if ($content) { - $this->sendContentSms($to, $content); - } else { - $this->sendTemplateSms($to, $tempId, $data); - } - } - public function sendContentSms($to, $content) { $this->result(Agent::SUCCESS, true); @@ -28,7 +19,7 @@ public function sendTemplateSms($to, $tempId, array $data) $this->result(Agent::INFO, 'send template sms success'); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $this->result(Agent::SUCCESS, true); $this->result(Agent::INFO, 'send voice verify success'); diff --git a/src/phpsms/agents/LuosimaoAgent.php b/src/phpsms/agents/LuosimaoAgent.php index 8d11db9..d46f3d8 100644 --- a/src/phpsms/agents/LuosimaoAgent.php +++ b/src/phpsms/agents/LuosimaoAgent.php @@ -8,9 +8,9 @@ * @property string $apikey * @property string $voiceApikey */ -class LuosimaoAgent extends Agent implements ContentSms +class LuosimaoAgent extends Agent implements ContentSms, VoiceCode { - public function sendSms($to, $content, $tempId, array $data) + public function sendContentSms($to, $content) { // 签名必须在最后面 if ($content && !preg_match('/】$/', $content)) { @@ -19,31 +19,24 @@ public function sendSms($to, $content, $tempId, array $data) $content = str_replace($matches[0], '', $content) . $matches[0]; } } - $this->sendContentSms($to, $content); - } - - public function sendContentSms($to, $content) - { $url = 'http://sms-api.luosimao.com/v1/send.json'; - $optData = [ + $result = $this->curlPost($url, [ 'mobile' => $to, 'message' => $content, - ]; - $result = $this->curl($url, $optData, true, [ + ], [ CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "api:key-$this->apikey", ]); $this->setResult($result); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $url = 'http://voice-api.luosimao.com/v1/verify.json'; - $optData = [ + $result = $this->curlPost($url, [ 'mobile' => $to, 'code' => $code, - ]; - $result = $this->curl($url, $optData, true, [ + ], [ CURLOPT_HTTPAUTH => CURLAUTH_BASIC, CURLOPT_USERPWD => "api:key-$this->voiceApikey", ]); diff --git a/src/phpsms/agents/ParasiticAgent.php b/src/phpsms/agents/ParasiticAgent.php index 5f9d83b..d0c0d8f 100644 --- a/src/phpsms/agents/ParasiticAgent.php +++ b/src/phpsms/agents/ParasiticAgent.php @@ -5,51 +5,117 @@ /** * Class ParasiticAgent * 寄生代理器 - * - * @property \Closure $sendSms - * @property \Closure $voiceVerify */ -class ParasiticAgent extends Agent +class ParasiticAgent extends Agent implements ContentSms, TemplateSms, VoiceCode, ContentVoice, TemplateVoice, FileVoice { - protected $sendSmsRunning = false; + protected static $methods; - protected $voiceVerifyRunning = false; + protected $handlers = []; - public function sendSms($to, $content, $tempId, array $data) + public function __construct(array $config = [], array $handlers = []) { - if (!is_callable($this->sendSms)) { - throw new PhpSmsException('Expected the higher-order scheme option `sendSms` to be a closure.'); - } - if ($this->sendSmsRunning) { - throw new PhpSmsException('Do not call `$agent->sendSms()` in the closure.'); - } - $this->sendSmsRunning = true; - try { - call_user_func_array($this->sendSms, [$this, $to, $content, $tempId, $data]); - $this->sendSmsRunning = false; - } catch (\Exception $e) { - $this->sendSmsRunning = false; - - throw $e; - } + parent::__construct($config); + + $this->handlers = $handlers; } - public function voiceVerify($to, $code, $tempId, array $data) + /** + * Content SMS send process. + * + * @param string|array $to + * @param string $content + */ + public function sendContentSms($to, $content) { - if (!is_callable($this->voiceVerify)) { - throw new PhpSmsException('Expected the higher-order scheme option `voiceVerify` to be a closure.'); - } - if ($this->voiceVerifyRunning) { - throw new PhpSmsException('Do not call `$agent->voiceVerify()` in the closure.'); + $this->handle(__FUNCTION__, func_get_args()); + } + + /** + * Content voice send process. + * + * @param string|array $to + * @param string $content + */ + public function sendContentVoice($to, $content) + { + $this->handle(__FUNCTION__, func_get_args()); + } + + /** + * File voice send process. + * + * @param string|array $to + * @param int|string $fileId + */ + public function sendFileVoice($to, $fileId) + { + $this->handle(__FUNCTION__, func_get_args()); + } + + /** + * Template SMS send process. + * + * @param string|array $to + * @param int|string $tempId + * @param array $tempData + */ + public function sendTemplateSms($to, $tempId, array $tempData) + { + $this->handle(__FUNCTION__, func_get_args()); + } + + /** + * Template voice send process. + * + * @param string|array $to + * @param int|string $tempId + * @param array $tempData + */ + public function sendTemplateVoice($to, $tempId, array $tempData) + { + $this->handle(__FUNCTION__, func_get_args()); + } + + /** + * Voice code send process. + * + * @param string|array $to + * @param int|string $code + */ + public function sendVoiceCode($to, $code) + { + $this->handle(__FUNCTION__, func_get_args()); + } + + /** + * Handle send process by closure. + * + * @param $name + * @param array $args + */ + protected function handle($name, array $args = []) + { + if (isset($this->handlers[$name]) && is_callable($this->handlers[$name])) { + array_unshift($args, $this); + call_user_func_array($this->handlers[$name], $args); } - $this->voiceVerifyRunning = true; - try { - call_user_func_array($this->voiceVerify, [$this, $to, $code, $tempId, $data]); - $this->voiceVerifyRunning = false; - } catch (\Exception $e) { - $this->voiceVerifyRunning = false; - - throw $e; + } + + /** + * Get methods name which inherit from interfaces. + * + * @return array + */ + public static function methods() + { + if (!is_array(self::$methods)) { + self::$methods = []; + $interfaces = class_implements('Toplan\\PhpSms\\ParasiticAgent'); + foreach ($interfaces as $interface) { + self::$methods = array_merge(self::$methods, get_class_methods($interface)); + } } + + return self::$methods; } } diff --git a/src/phpsms/agents/QcloudAgent.php b/src/phpsms/agents/QcloudAgent.php new file mode 100644 index 0000000..9fa13ad --- /dev/null +++ b/src/phpsms/agents/QcloudAgent.php @@ -0,0 +1,102 @@ + 0, // 0:普通短信 1:营销短信 + 'msg' => $content, + 'tel' => $to, + 'time' => time(), + ]; + $this->random = $this->getRandom(); + $sendUrl = "{$this->sendSms}?sdkappid={$this->appId}&random={$this->random}"; + $this->request($sendUrl, $params); + } + + public function sendTemplateSms($to, $tempId, array $data) + { + $params = [ + 'tel' => $to, + 'tpl_id' => $tempId, + 'params' => array_values($data), + 'time' => time(), + ]; + $this->random = $this->getRandom(); + $sendUrl = "{$this->sendSms}?sdkappid={$this->appId}&random={$this->random}"; + $this->request($sendUrl, $params); + } + + public function sendVoiceCode($to, $code) + { + $params = [ + 'tel' => $to, + 'msg' => $code, + ]; + $sendUrl = "{$this->sendVoiceCode}?sdkappid={$this->appId}&random={$this->random}"; + $this->request($sendUrl, $params); + } + + public function sendContentVoice($to, $content) + { + $params = [ + 'tel' => $to, + 'prompttype' => 2, + 'promptfile' => $content, + ]; + $sendUrl = "{$this->sendVoicePrompt}?sdkappid={$this->appId}&random={$this->random}"; + $this->request($sendUrl, $params); + } + + protected function request($sendUrl, array $params) + { + $params['sig'] = $this->genSign($params); + $params = $this->params($params); + $result = $this->curlPost($sendUrl, [], [ + CURLOPT_POSTFIELDS => json_encode($params), + ]); + $this->setResult($result); + } + + protected function genSign($params) + { + $phone = $params['tel']['mobile']; + $signature = "appkey={$this->appKey}&random={$this->random}&time={$params['time']}&mobile={$phone}"; + + return hash('sha256', $signature, false); + } + + protected function setResult($result) + { + if ($result['request']) { + $this->result(Agent::INFO, $result['response']); + $result = json_decode($result['response'], true); + if (isset($result['result'])) { + $this->result(Agent::SUCCESS, $result['result'] === 0); + $this->result(Agent::CODE, $result['result']); + } + } else { + $this->result(Agent::INFO, 'request failed'); + } + } + + protected function getRandom() + { + return rand(100000, 999999); + } +} diff --git a/src/phpsms/agents/SendCloudAgent.php b/src/phpsms/agents/SendCloudAgent.php index 2cb29ac..d55fd67 100755 --- a/src/phpsms/agents/SendCloudAgent.php +++ b/src/phpsms/agents/SendCloudAgent.php @@ -8,13 +8,8 @@ * @property string $smsUser * @property string $smsKey */ -class SendCloudAgent extends Agent implements TemplateSms +class SendCloudAgent extends Agent implements TemplateSms, VoiceCode { - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendTemplateSms($to, $tempId, $data); - } - public function sendTemplateSms($to, $tempId, array $data) { $params = [ @@ -26,7 +21,7 @@ public function sendTemplateSms($to, $tempId, array $data) $this->request('http://sendcloud.sohu.com/smsapi/send', $params); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $params = [ 'phone' => $to, @@ -37,19 +32,10 @@ public function voiceVerify($to, $code, $tempId, array $data) protected function request($sendUrl, array $params) { - $params = $this->createParams($params); - $result = $this->curl($sendUrl, $params, true); - $this->setResult($result); - } - - protected function createParams(array $params) - { - $params = array_merge([ - 'smsUser' => $this->smsUser, - ], $params); + $params['smsUser'] = $this->smsUser; $params['signature'] = $this->genSign($params); - - return $params; + $result = $this->curlPost($sendUrl, $params); + $this->setResult($result); } protected function genSign($params) diff --git a/src/phpsms/agents/SmsBaoAgent.php b/src/phpsms/agents/SmsBaoAgent.php index fb8ef0f..4cc9e30 100644 --- a/src/phpsms/agents/SmsBaoAgent.php +++ b/src/phpsms/agents/SmsBaoAgent.php @@ -8,7 +8,7 @@ * @property string $username * @property string $password */ -class SmsBaoAgent extends Agent implements ContentSms +class SmsBaoAgent extends Agent implements ContentSms, VoiceCode { protected $resultArr = [ '0' => '发送成功', @@ -22,11 +22,6 @@ class SmsBaoAgent extends Agent implements ContentSms '51' => '手机号码不正确', ]; - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendContentSms($to, $content); - } - public function sendContentSms($to, $content) { $url = 'http://api.smsbao.com/sms'; @@ -36,11 +31,11 @@ public function sendContentSms($to, $content) 'm' => $to, 'c' => $content, ]; - $result = $this->curl($url, $params); + $result = $this->curlGet($url, $params); $this->setResult($result); } - public function voiceVerify($to, $code, $tempId, array $tempData) + public function sendVoiceCode($to, $code) { $url = 'http://api.smsbao.com/voice'; $params = [ @@ -49,7 +44,7 @@ public function voiceVerify($to, $code, $tempId, array $tempData) 'm' => $to, 'c' => $code, ]; - $result = $this->curl($url, $params); + $result = $this->curlGet($url, $params); $this->setResult($result); } diff --git a/src/phpsms/agents/SubMailAgent.php b/src/phpsms/agents/SubMailAgent.php index 81d07fc..7ed639a 100644 --- a/src/phpsms/agents/SubMailAgent.php +++ b/src/phpsms/agents/SubMailAgent.php @@ -8,13 +8,8 @@ * @property string $appid * @property string $signature */ -class SubMailAgent extends Agent implements TemplateSms +class SubMailAgent extends Agent implements TemplateSms, VoiceCode { - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendTemplateSms($to, $tempId, $data); - } - public function sendTemplateSms($to, $tempId, array $data) { $url = 'https://api.mysubmail.com/message/xsend.json'; @@ -25,11 +20,11 @@ public function sendTemplateSms($to, $tempId, array $data) 'signature' => $this->signature, 'vars' => json_encode($data), ]; - $result = $this->curl($url, $params, true); + $result = $this->curlPost($url, $params); $this->setResult($result); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $url = 'https://api.mysubmail.com/voice/verify.json'; $params = [ @@ -38,7 +33,7 @@ public function voiceVerify($to, $code, $tempId, array $data) 'code' => $code, 'signature' => $this->signature, ]; - $result = $this->curl($url, $params, true); + $result = $this->curlPost($url, $params); $this->setResult($result); } diff --git a/src/phpsms/agents/UcpaasAgent.php b/src/phpsms/agents/UcpaasAgent.php index ba4c407..1c20857 100644 --- a/src/phpsms/agents/UcpaasAgent.php +++ b/src/phpsms/agents/UcpaasAgent.php @@ -9,20 +9,15 @@ * @property string $accountToken * @property string $appId */ -class UcpaasAgent extends Agent implements TemplateSms +class UcpaasAgent extends Agent implements TemplateSms, VoiceCode { - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendTemplateSms($to, $tempId, $data); - } - public function sendTemplateSms($to, $tempId, array $data) { $response = $this->ucpass()->templateSMS($this->appId, $to, $tempId, implode(',', $data)); $this->setResult($response); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $response = $this->ucpass()->voiceCode($this->appId, $code, $to); $this->result($response); @@ -30,12 +25,10 @@ public function voiceVerify($to, $code, $tempId, array $data) protected function ucpass() { - $config = [ + return new \Ucpaas([ 'accountsid' => $this->accountSid, 'token' => $this->accountToken, - ]; - - return new \Ucpaas($config); + ]); } protected function setResult($result) diff --git a/src/phpsms/agents/YunPianAgent.php b/src/phpsms/agents/YunPianAgent.php index 9a06275..c0cd0a0 100644 --- a/src/phpsms/agents/YunPianAgent.php +++ b/src/phpsms/agents/YunPianAgent.php @@ -7,42 +7,37 @@ * * @property string $apikey */ -class YunPianAgent extends Agent implements ContentSms +class YunPianAgent extends Agent implements ContentSms, VoiceCode { protected $headers = [ 'Accept:application/json;charset=utf-8', 'Content-Type:application/x-www-form-urlencoded;charset=utf-8', ]; - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendContentSms($to, $content); - } - public function sendContentSms($to, $content) { $url = 'https://sms.yunpian.com/v1/sms/send.json'; - $params = [ + $params = $this->params([ 'apikey' => $this->apikey, 'mobile' => $to, 'text' => $content, - ]; - $result = $this->curl($url, true, [ + ]); + $result = $this->curlPost($url, [], [ CURLOPT_HTTPHEADER => $this->headers, CURLOPT_POSTFIELDS => http_build_query($params), ]); $this->setResult($result); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $url = 'https://voice.yunpian.com/v1/voice/send.json'; - $params = [ + $params = $this->params([ 'apikey' => $this->apikey, 'mobile' => $to, 'code' => $code, - ]; - $result = $this->curl($url, true, [ + ]); + $result = $this->curlPost($url, [], [ CURLOPT_HTTPHEADER => $this->headers, CURLOPT_POSTFIELDS => http_build_query($params), ]); diff --git a/src/phpsms/agents/YunTongXunAgent.php b/src/phpsms/agents/YunTongXunAgent.php index d2dfc1b..c6889c1 100644 --- a/src/phpsms/agents/YunTongXunAgent.php +++ b/src/phpsms/agents/YunTongXunAgent.php @@ -13,16 +13,10 @@ * @property string $accountToken * @property string $appId * @property int $playTimes - * @property string $voiceLang * @property string $displayNum */ -class YunTongXunAgent extends Agent implements TemplateSms +class YunTongXunAgent extends Agent implements TemplateSms, VoiceCode { - public function sendSms($to, $content, $tempId, array $data) - { - $this->sendTemplateSms($to, $tempId, $data); - } - public function sendTemplateSms($to, $tempId, array $data) { $data = array_values($data); @@ -30,12 +24,15 @@ public function sendTemplateSms($to, $tempId, array $data) $this->setResult($result); } - public function voiceVerify($to, $code, $tempId, array $data) + public function sendVoiceCode($to, $code) { $playTimes = intval($this->playTimes ?: 3); $displayNum = $this->displayNum ?: null; - $lang = $this->voiceLang ?: 'zh'; - $result = $this->rest()->voiceVerify($code, $playTimes, $to, $displayNum, null, $lang); + $lang = $this->params('lang') ?: 'zh'; + $respUrl = $this->params('respUrl'); + $userData = $this->params('userData'); + $welcomePrompt = $this->params('welcomePrompt'); + $result = $this->rest()->voiceVerify($code, $playTimes, $to, $displayNum, $respUrl, $lang, $userData, $welcomePrompt); $this->setResult($result); } diff --git a/src/phpsms/interfaces/ContentSms.php b/src/phpsms/interfaces/ContentSms.php index 020d50e..532492c 100644 --- a/src/phpsms/interfaces/ContentSms.php +++ b/src/phpsms/interfaces/ContentSms.php @@ -7,8 +7,8 @@ interface ContentSms /** * Content SMS send process. * - * @param $to - * @param $content + * @param string|array $to + * @param string $content */ public function sendContentSms($to, $content); } diff --git a/src/phpsms/interfaces/ContentVoice.php b/src/phpsms/interfaces/ContentVoice.php new file mode 100644 index 0000000..dabdcc9 --- /dev/null +++ b/src/phpsms/interfaces/ContentVoice.php @@ -0,0 +1,14 @@ +assertEquals('send content sms success', $r['info']); } - public function testSendVoiceVerify() + public function testSendVoice() { - $this->agent->voiceVerify('18280111111', '1111', 0, []); + $this->agent->sendVoice('18280111111', null, 0, [], '1111'); $r = $this->agent->result(); $this->assertTrue($r['success']); } public function testParasitic() { - $parasiticAgent = new ParasiticAgent([ - 'sendSms' => function ($agent, $to, $content, $tempId, $tempData) { - $agent->result('info', 'parasitic_sms'); - $agent->result('code', $to); + $parasiticAgent = new ParasiticAgent([], [ + 'sendContentSms' => function ($agent, $to, $content) { + $agent->result(Agent::INFO, $content); + $agent->result(Agent::CODE, $to); + $agent->result(Agent::SUCCESS, true); }, - 'voiceVerify' => function ($agent, $to, $code, $tempId, $tempData) { - $agent->result('info', 'parasitic_voice_verify'); - $agent->result('code', $code); + 'sendVoiceCode' => function ($agent, $to, $code) { + $agent->result(Agent::INFO, 'parasitic_voice_verify'); + $agent->result(Agent::CODE, $code); }, ]); - $parasiticAgent->sendSms('18280111111', 'content', 'template_id', []); - $this->assertEquals('parasitic_sms', $parasiticAgent->result('info')); + $parasiticAgent->sendSms('18280111111', 'parasitic_sms_content'); + $this->assertEquals('parasitic_sms_content', $parasiticAgent->result('info')); $this->assertEquals('18280111111', $parasiticAgent->result('code')); - $parasiticAgent->voiceVerify('18280111111', '2222', 'template_id', []); + $parasiticAgent->sendVoice('18280111111', null, null, [], '2222'); $this->assertEquals('parasitic_voice_verify', $parasiticAgent->result('info')); $this->assertEquals('2222', $parasiticAgent->result('code')); } diff --git a/tests/ProtectedTest.php b/tests/ProtectedTest.php index b2a76a7..b22a707 100644 --- a/tests/ProtectedTest.php +++ b/tests/ProtectedTest.php @@ -16,7 +16,7 @@ public static function getPrivateMethod($name) public function testConfiguration() { - $method = self::getPrivateMethod('configuration'); + $method = self::getPrivateMethod('configure'); $obj = new Sms(false); $method->invokeArgs($obj, []); $config = include __DIR__ . '/../src/config/phpsms.php'; diff --git a/tests/SerializeTest.php b/tests/SerializeTest.php index bcae0e1..21f0049 100644 --- a/tests/SerializeTest.php +++ b/tests/SerializeTest.php @@ -13,7 +13,7 @@ public static function setUpBeforeClass() Sms::cleanScheme(); Sms::scheme('TestAgent', [ '100 backup', - 'sendSms' => function ($agent) { + 'sendContentSms' => function ($agent) { $agent->result(Agent::SUCCESS, true); $agent->result(Agent::INFO, 'some_info'); }, diff --git a/tests/SmsTest.php b/tests/SmsTest.php index 02d62dc..b0955a9 100644 --- a/tests/SmsTest.php +++ b/tests/SmsTest.php @@ -46,32 +46,28 @@ public function testGetTask() public function testGetSmsData() { - $data = self::$sms->getData(); + $data = self::$sms->all(); $this->assertArrayHasKey('to', $data); $this->assertArrayHasKey('templates', $data); - $this->assertArrayHasKey('templateData', $data); + $this->assertArrayHasKey('data', $data); $this->assertArrayHasKey('content', $data); - $this->assertArrayHasKey('voiceCode', $data); + $this->assertArrayHasKey('code', $data); + $this->assertArrayHasKey('files', $data); + $this->assertArrayHasKey('params', $data); self::$sms->to('...'); - $this->assertEquals('...', self::$sms->getData('to')); - } - - public function smsData() - { - return self::$sms->getData(); + $this->assertEquals('...', self::$sms->all('to')); } public function testSetTo() { self::$sms->to('18280345...'); - $smsData = $this->smsData(); - $this->assertEquals('18280345...', $smsData['to']); + $this->assertEquals('18280345...', self::$sms->all('to')); } public function testSetTemplate() { self::$sms->template('Luosimao', '123'); - $smsData = $this->smsData(); + $smsData = self::$sms->all(); $this->assertEquals([ 'Luosimao' => '123', ], $smsData['templates']); @@ -79,7 +75,7 @@ public function testSetTemplate() 'Luosimao' => '1234', 'YunTongXun' => '6789', ]); - $smsData = $this->smsData(); + $smsData = self::$sms->all(); $this->assertEquals([ 'Luosimao' => '1234', 'YunTongXun' => '6789', @@ -92,17 +88,17 @@ public function testSetData() 'code' => '1', 'msg' => 'msg', ]); - $smsData = $this->smsData(); + $smsData = self::$sms->all(); $this->assertEquals([ - 'code' => '1', - 'msg' => 'msg', - ], $smsData['templateData']); + 'code' => '1', + 'msg' => 'msg', + ], $smsData['data']); } public function testSetContent() { self::$sms->content('this is content'); - $smsData = $this->smsData(); + $smsData = self::$sms->all(); $this->assertEquals('this is content', $smsData['content']); } @@ -143,8 +139,8 @@ public function testSetAgent() public function testVoice() { $sms = Sms::voice('code'); - $data = $sms->getData(); - $this->assertEquals('code', $data['voiceCode']); + $data = $sms->all(); + $this->assertEquals('code', $data['code']); } public function testUseQueue()