├── .gitignore ├── .travis.yml ├── LICENSE ├── README.md ├── autoload.php ├── composer.json ├── doc ├── api.md ├── grouppush.md └── http2.md ├── examples ├── admin_example.php ├── batch_push_example.php ├── cid_example.php ├── config.php.example ├── devices │ ├── delete_alias_example.php │ ├── delete_tag_example.php │ ├── get_alias_devices_example.php │ ├── get_devices_example.php │ ├── get_devices_status_example.php │ ├── get_tags_example.php │ ├── update_device_example.php │ └── update_tag_example.php ├── grouppush_example.php ├── huawei_push_example.php ├── push_example.php ├── reports │ ├── messages_detail_example.php │ └── received_detail_example.php ├── schedule_example.php └── zone_examples.php ├── phpunit.xml.dist ├── src └── JPush │ ├── AdminClient.php │ ├── Client.php │ ├── Config.php │ ├── DevicePayload.php │ ├── Exceptions │ ├── APIConnectionException.php │ ├── APIRequestException.php │ ├── JPushException.php │ └── ServiceNotAvaliable.php │ ├── Http.php │ ├── PushPayload.php │ ├── ReportPayload.php │ ├── SchedulePayload.php │ └── version.php └── tests ├── JPush ├── DevicePayloadTest.php ├── PushPayloadTest.php ├── ReportPayloadTest.php └── SchedulePayloadTest.php └── bootstrap.php /.gitignore: -------------------------------------------------------------------------------- 1 | *.pyc 2 | log/ 3 | build/ 4 | bin/ 5 | .pydevproject 6 | .tar 7 | .zip 8 | .buildpath 9 | .project 10 | .settings/ 11 | .idea 12 | composer.lock 13 | vendor/ 14 | *.log 15 | vendor.tar.gz 16 | composer.phar 17 | vendor.zip 18 | examples/config.php 19 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: php 2 | 3 | php: 4 | - '5.3' 5 | - '5.4' 6 | - '5.5' 7 | - '5.6' 8 | - '7.0' 9 | 10 | before_script: 11 | - composer install 12 | script: 13 | - ./vendor/bin/phpunit tests 14 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2016 极光 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JPush API PHP Client 2 | 3 | 这是 JPush REST API 的 PHP 版本封装开发包,是由极光推送官方提供的,一般支持最新的 API 功能。 4 | 5 | 对应的 REST API 文档: https://docs.jiguang.cn/jpush/server/push/server_overview/ 6 | 7 | > 支持的 PHP 版本: 5.3.3 ~ 5.6.x, 7.x 8 | 9 | > 若需要兼容 PHP 5.3.3 以下版本,可以使用 [v3 分支的代码](https://github.com/jpush/jpush-api-php-client/tree/v3)。 10 | 因为运行 Composer 需要 PHP 5.3.2+ 以上版本,所以其不提供 Composer 支持, 11 | 也可以[点击链接](https://github.com/jpush/jpush-api-php-client/releases)下载 v3.4.x 版本源码。 12 | 13 | ## Installation 14 | 15 | #### 使用 Composer 安装 16 | 17 | - 执行 `$ php composer.phar install` 或 `$ composer install` 进行安装。 18 | 19 | #### 直接下载源码安装 20 | 21 | > 直接下载源代码也是一种安装 SDK 的方法,不过因为有版本更新的维护问题,所以这种安装方式**十分不推荐**,但由于种种原因导致无法使用 Composer,所以我们也提供了这种情况下的备选方案。 22 | 23 | - 下载源代码包,解压到项目中 24 | - 在项目中引入 autoload: 25 | 26 | ```php 27 | require 'path_to_sdk/autoload.php'; 28 | ``` 29 | 30 | ## Usage 31 | 32 | - [Init API](https://github.com/jpush/jpush-api-php-client/blob/master/doc/api.md#init-api) 33 | - [Push API](https://github.com/jpush/jpush-api-php-client/blob/master/doc/api.md#push-api) 34 | - [Report API](https://github.com/jpush/jpush-api-php-client/blob/master/doc/api.md#report-api) 35 | - [Device API](https://github.com/jpush/jpush-api-php-client/blob/master/doc/api.md#device-api) 36 | - [Schedule API](https://github.com/jpush/jpush-api-php-client/blob/master/doc/api.md#schedule-api) 37 | - [Exception Handle](https://github.com/jpush/jpush-api-php-client/blob/master/doc/api.md#schedule-api) 38 | - [HTTP/2 Support](https://github.com/jpush/jpush-api-php-client/blob/master/doc/http2.md) 39 | - [Group Push](https://github.com/jpush/jpush-api-php-client/blob/master/doc/grouppush.md) 40 | 41 | #### 初始化 42 | 43 | ```php 44 | use JPush\Client as JPush; 45 | ... 46 | ... 47 | 48 | $client = new JPush($app_key, $master_secret); 49 | 50 | ... 51 | ``` 52 | 53 | OR 54 | 55 | ```php 56 | $client = new \JPush\Client($app_key, $master_secret); 57 | ``` 58 | 59 | #### 简单推送 60 | 61 | ```php 62 | $client->push() 63 | ->setPlatform('all') 64 | ->addAllAudience() 65 | ->setNotificationAlert('Hello, JPush') 66 | ->send(); 67 | ``` 68 | 69 | #### 异常处理 70 | 71 | ```php 72 | $pusher = $client->push(); 73 | $pusher->setPlatform('all'); 74 | $pusher->addAllAudience(); 75 | $pusher->setNotificationAlert('Hello, JPush'); 76 | try { 77 | $pusher->send(); 78 | } catch (\JPush\Exceptions\JPushException $e) { 79 | // try something else here 80 | print $e; 81 | } 82 | ``` 83 | 84 | ## Examples 85 | 86 | **注意: 这只是使用样例, 不应该直接用于实际环境中!!** 87 | 88 | 在下载的中的 [examples](https://github.com/jpush/jpush-api-php-client/tree/master/examples) 文件夹有简单示例代码, 开发者可以参考其中的样例快速了解该库的使用方法。 89 | 90 | **简单使用方法** 91 | 92 | 先填写对应的appKey和masterSecret,可以额外设定Registration_id。 93 | 94 | 若要运行 push_example.php 中的示例代码: 95 | 96 | ``` bash 97 | # 假定当前目录为 JPush 源码所在的根目录 98 | $ php examples/push_example.php 99 | ``` 100 | > 同时也可编辑相关的示例文件,更改参数查看执行效果 101 | 102 | ## Testing 103 | 104 | ```bash 105 | # 编辑 tests/bootstrap.php 文件,填入必须的变量值 106 | # OR 设置相应的环境变量 107 | 108 | # 运行全部测试用例 109 | $ composer tests 110 | 111 | # 运行某一具体测试用例 112 | $ composer tests/JPush/xxTest.php 113 | ``` 114 | 115 | ## Contributing 116 | 117 | Bug reports and pull requests are welcome on GitHub at https://github.com/jpush/jpush-api-php-client. 118 | 119 | ## License 120 | 121 | The library is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT). 122 | -------------------------------------------------------------------------------- /autoload.php: -------------------------------------------------------------------------------- 1 | =5.3.3", 17 | "ext-curl": "*" 18 | }, 19 | "require-dev": { 20 | "phpunit/phpunit": "*" 21 | }, 22 | "autoload" : { 23 | "psr-4": {"JPush\\": "src/JPush/"} 24 | }, 25 | "autoload-dev": { 26 | "psr-4": { "JPush\\Tests\\": "tests/" } 27 | }, 28 | "scripts": { 29 | "test": "vendor/bin/phpunit" 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /doc/api.md: -------------------------------------------------------------------------------- 1 | # 目录 2 | 3 | - [Init API](#init-api) 4 | - [Push API](#push-api) 5 | - [Report API](#report-api) 6 | - [Device API](#device-api) 7 | - [Schedule API](#schedule-api) 8 | - [Exception Handle](#schedule-api) 9 | 10 | > **注:PHP SDK 全面支持 namespaces 但为方便表达,以下例子都不使用 use 语句** 11 | 12 | ## Init API 13 | 14 | 在调用推送之前,我们必须先初始化 JPushClient,调用以下代码可以进行快速初始化: 15 | 16 | ```php 17 | $client = new \JPush\Client($app_key, $master_secret); 18 | ``` 19 | 20 | 在初始化 JPushClient 的时候,可以指定**日志路径**: 21 | 22 | ```php 23 | $client = new \JPush\Client($app_key, $master_secret, $log_path); 24 | ``` 25 | > 默认日志路径为 `./jpush.log`,即保存在当前运行目录,如果想关闭日志,可以指定为 `null`。 26 | 27 | ## Push API 28 | 29 | 在初始化 JPushClient 后,调用以下代码将返回一个推送 Payload 构建器,它提供丰富的API来帮助你构建 PushPayload。 30 | 31 | ```php 32 | $push = $client->push(); 33 | ``` 34 | 35 | 通过 [JPush Push API](https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/) 我们知道,一个 PushPayload 是由以下几个部分构成的: 36 | 37 | - Cid 38 | - Platform 39 | - Audience 40 | - Notification 41 | - Message 42 | - SmsContent 43 | - Options 44 | 45 | #### Cid 46 | 47 | ```php 48 | $push->setCid($cid); 49 | ``` 50 | 51 | #### Platform 52 | 53 | ```php 54 | $push->setPlatform('all'); 55 | // OR 56 | $push->setPlatform('ios', 'android'); 57 | // OR 58 | $push->setPlatform(['ios', 'android']); 59 | ``` 60 | 61 | #### Audience 62 | 63 | ```php 64 | $push->addAllAudience(); 65 | ``` 66 | 67 | ```php 68 | $push->addTag('tag1'); 69 | // OR 70 | $push->addTag(['tag1', 'tag2']); 71 | ``` 72 | 73 | 其他诸如 `addAlias()`, `addRegistrationId()`, `addTagAnd()`, `addTagNot()`, `addSegmentId()`, `addAbtest()` 的使用方法与 `addTag()` 类似,在此不做赘述。 74 | 75 | #### Notification 76 | 77 | ```php 78 | // 简单地给所有平台推送相同的 alert 消息 79 | $push->setNotificationAlert('alert'); 80 | ``` 81 | 82 | **iOS Notification** 83 | 84 | ```php 85 | // iosNotification($alert = '', array $notification = array()) 86 | // 数组 $notification 的键支持 'sound', 'badge', 'content-available', 'mutable-content', category', 'extras', 'thread-id' 中的一个或多个 87 | 88 | // 调用示例 89 | $push->iosNotification(); 90 | // OR 91 | $push->iosNotification('hello'); 92 | // OR 93 | $push->iosNotification('hello', [ 94 | 'sound' => 'sound', 95 | 'badge' => '+1', 96 | 'extras' => [ 97 | 'key' => 'value' 98 | ] 99 | ]); 100 | ``` 101 | 102 | 参数说明: 103 | 104 | | 参数 | 说明 | 105 | | --- | --- | 106 | | alert |表示通知内容,会覆盖上级统一指定的 alert 信息;默认内容可以为空字符串,表示不展示到通知栏, 支持字符串和数组两种形式 | 107 | | sound | 表示通知提示声音,默认填充为空字符串 | 108 | | badge | 表示应用角标,把角标数字改为指定的数字;为 0 表示清除,支持 '+1','-1' 这样的字符串,表示在原有的 badge 基础上进行增减,默认填充为 '+1' | 109 | | content-available | 表示推送唤醒,仅接受 true 表示为 Background Remote Notification,若不填默认表示普通的 Remote Notification | 110 | | mutable-content | 表示通知扩展, 仅接受 true 表示支持 iOS10 的 UNNotificationServiceExtension, 若不填默认表示普通的 Remote Notification | 111 | | category | IOS8才支持。设置 APNs payload 中的 'category' 字段值 | 112 | | thread-id | 表示通知分组,ios 的远程通知通过该属性来对通知进行分组,同一个 thread-id 的通知归为一组 | 113 | | extras | 表示扩展字段,接受一个数组,自定义 Key/value 信息以供业务使用 | 114 | 115 | **Android Notification** 116 | 117 | ```php 118 | // androidNotification($alert = '', array $notification = array()) 119 | // 调用示例同 IOS,数组 $notification 的键支持 'title', 'builder_id', 'priority', 'category', 'style', 'alert_type', 'big_text', 'inbox', 'big_pic_path', 'large_icon', 'intent', 'extras' 中的一个或多个 120 | ``` 121 | 122 | 参数说明: 123 | 124 | | 参数 | 说明 | 125 | | --- | --- | 126 | | alert | 表示通知内容,会覆盖上级统一指定的 alert 信息;默认内容可以为空字符串,表示不展示到通知栏 | 127 | | title | 表示通知标题,会替换通知里原来展示 App 名称的地方 | 128 | | builder_id | 表示通知栏样式 ID | 129 | | priority | 表示通知栏展示优先级,默认为 0,范围为 -2~2 ,其他值将会被忽略而采用默认值 | 130 | | category | 表示通知栏条目过滤或排序,完全依赖 rom 厂商对 category 的处理策略 | 131 | | style | 表示通知栏样式类型,默认为 0,还有1,2,3可选,用来指定选择哪种通知栏样式,其他值无效。有三种可选分别为 bigText=1,Inbox=2,bigPicture=3 | 132 | | alert_type | 表示通知提醒方式, 可选范围为 -1~7 ,对应 Notification.DEFAULT_ALL = -1 或者 Notification.DEFAULT_SOUND = 1, Notification.DEFAULT_VIBRATE = 2, Notification.DEFAULT_LIGHTS = 4 的任意 “or” 组合。默认按照 -1 处理。 | 133 | | big_text | 表示大文本通知栏样式,当 style = 1 时可用,内容会被通知栏以大文本的形式展示出来,支持 api 16 以上的 rom | 134 | | inbox | 表示文本条目通知栏样式,接受一个数组,当 style = 2 时可用,数组的每个 key 对应的 value 会被当作文本条目逐条展示,支持 api 16 以上的 rom | 135 | | big_pic_path | 表示大图片通知栏样式,当 style = 3 时可用,可以是网络图片 url,或本地图片的 path,目前支持 .jpg 和 .png 后缀的图片。图片内容会被通知栏以大图片的形式展示出来。如果是 http/https 的 url,会自动下载;如果要指定开发者准备的本地图片就填 sdcard 的相对路径,支持 api 16 以上的 rom | 136 | | large_icon | 表示通知栏大图标,图标路径可以是以 http 或 https 开头的网络图片,如:"http:jiguang.cn/logo.png",图标大小不超过 30k; 也可以是位于 drawable 资源文件夹的图标路径,如:"R.drawable.lg_icon";| 137 | | intent | 表示扩展字段,接受一个数组,自定义 Key/value 信息以供业务使用 | 138 | | extras | 表示扩展字段,接受一个数组,自定义 Key/value 信息以供业务使用 | 139 | 140 | **hmos Notification** 141 | 142 | ```php 143 | // hmosNotification($alert = '', $category = '', array $notification = array()) 144 | // 数组 $notification 的键支持 'title', 'category', 'large_icon', 'intent', 'badge_add_num', 'test_message', 'receipt_id', 'extras' 中的一个或多个 145 | // 注意category为必填项,若$category为空字符串则会从$notification中取'category'的值 146 | ``` 147 | 148 | 参数说明: 149 | 150 | | 参数 | 说明 | 151 | | --- | --- | 152 | | alert | 表示通知内容,会覆盖上级统一指定的 alert 信息;默认内容可以为空字符串,表示不展示到通知栏 | 153 | | title | 表示通知标题,会替换通知里原来展示 App 名称的地方 | 154 | | category | 通知栏消息分类条目;对应官方「本地通知」category取值,开发者通过极光服务发起推送时如果传递了此字段值,请务必按照官方要求传递 | 155 | | badge_add_num | 设置角标数字累加值;不填则不改变角标数字,取值范围为1-99 | 156 | | test_message | 测试消息标识;false为正常消息(默认值),true为测试消息 | 157 | | receipt_id | 华为回执 ID;输入一个唯一的回执 ID 指定本次下行消息的回执地址及配置,该回执 ID 可以在鸿蒙回执参数配置中查看 | 158 | | large_icon | 表示通知栏大图标,图标路径可以是以 http 或 https 开头的网络图片,如:"http:jiguang.cn/logo.png",图标大小不超过 30k; 也可以是位于 drawable 资源文件夹的图标路径,如:"R.drawable.lg_icon";| 159 | | intent | 表示扩展字段,接受一个数组,自定义 Key/value 信息以供业务使用 | 160 | | extras | 表示扩展字段,接受一个数组,自定义 Key/value 信息以供业务使用 | 161 | 162 | **WinPhone Notification** 163 | 164 | ```php 165 | $push->addWinPhoneNotification($alert=null, $title=null, $_open_page=null, $extras=null) 166 | ``` 167 | 168 | 参数说明: 169 | 170 | | 参数 | 说明 | 171 | | --- | --- | 172 | | alert | 表示通知内容,会覆盖上级统一指定的 alert 信息;内容为空则不展示到通知栏 | 173 | | title | 通知标题,会填充到 toast 类型 text1 字段上 | 174 | | _open_page | 点击打开的页面名称 | 175 | 176 | #### Message 177 | 178 | ```php 179 | // message($msg_content, array $msg = array()) 180 | // 数组 $msg 的键支持 'title', 'content_type', 'extras' 中的一个或多个 181 | 182 | // 调用示例 183 | $push->message('Hello JPush'); 184 | // OR 185 | $push->message('Hello JPush', [ 186 | 'title' => 'Hello', 187 | 'content_type' => 'text', 188 | 'extras' => [ 189 | 'key' => 'value' 190 | ] 191 | ]); 192 | ``` 193 | 194 | 参数说明: 195 | 196 | | 参数 | 说明 | 197 | | --- | --- | 198 | | msg_content | 消息内容本身 | 199 | | title | 消息标题 | 200 | | content_type | 消息内容类型 | 201 | | extras | 表示扩展字段,接受一个数组,自定义 Key/value 信息以供业务使用 | 202 | 203 | #### Sms Message 204 | 205 | ```php 206 | $push->setSms($delay_time, $temp_id, array $temp_para = []) 207 | ``` 208 | 209 | 参数说明: 210 | * delay_time: 表示短信发送的延迟时间,单位为秒,不能超过 24 小时(即大于等于 0 小于等于 86400)。仅对 android 平台有效。 211 | * temp_id: 短信补充的内容模板 ID。没有填写该字段即表示不使用短信补充功能。 212 | * temp_para: 短信模板中的参数 213 | 214 | ##### 已弃用 215 | 216 | ```php 217 | $push->setSmsMessage($content, $delay_time) 218 | ``` 219 | 220 | 参数说明: 221 | * content: 短信文本,不超过 480 字符 222 | * delay_time: 表示短信发送的延迟时间,单位为秒,不能超过 24 小时(即大于等于 0 小于等于 86400)。仅对 android 平台有效。默认为 0,表示立即发送短信 223 | 224 | #### Options 225 | 226 | ```php 227 | // options(array $opts = array()) 228 | // 数组 $opts 的键支持 'sendno', 'time_to_live', 'override_msg_id', 'apns_production', 'big_push_duration', 'apns_collapse_id' 中的一个或多个 229 | ``` 230 | 231 | 参数说明: 232 | 233 | | 可选项 | 说明 | 234 | | --- | --- | 235 | | sendno | 表示推送序号,纯粹用来作为 API 调用标识,API 返回时被原样返回,以方便 API 调用方匹配请求与返回 | 236 | | time_to_live | 表示离线消息保留时长(秒),推送当前用户不在线时,为该用户保留多长时间的离线消息,以便其上线时再次推送。默认 86400 (1 天),最长 10 天。设置为 0 表示不保留离线消息,只有推送当前在线的用户可以收到 | 237 | | override_msg_id | 表示要覆盖的消息ID,如果当前的推送要覆盖之前的一条推送,这里填写前一条推送的 msg_id 就会产生覆盖效果 | 238 | | apns_production | 表示 APNs 是否生产环境,True 表示推送生产环境,False 表示要推送开发环境;如果不指定则默认为推送开发环境 | 239 | | apns_collapse_id | APNs 新通知如果匹配到当前通知中心有相同 apns-collapse-id 字段的通知,则会用新通知内容来更新它,并使其置于通知中心首位;collapse id 长度不可超过 64 bytes| 240 | | big_push_duration | 表示定速推送时长(分钟),又名缓慢推送,把原本尽可能快的推送速度,降低下来,给定的 n 分钟内,均匀地向这次推送的目标用户推送。最大值为1400.未设置则不是定速推送 | 241 | 242 | #### Common Method 243 | 244 | ```php 245 | // 发送推送 246 | // 该方法内部将自动调用构建方法获得当前构建对象,并转化为 JSON 向 JPush 服务器发送请求 247 | $push->send(); 248 | ``` 249 | 250 | > 构建 PushPayload 的 API 每一次都会返回自身的引用,所以我们可用使用链式调用的方法提高代码的简洁性,如: 251 | 252 | ```php 253 | $response = $push() 254 | ->setCid('xxxxxx') 255 | ->setPlatform(['ios', 'android']) 256 | ->addTag(['tag1', 'tag2']) 257 | ->setNotificationAlert('Hello, JPush') 258 | ->iosNotification('hello', [ 259 | 'sound' => 'sound', 260 | 'badge' => '+1', 261 | 'extras' => [ 262 | 'key' => 'value' 263 | ] 264 | ]) 265 | ->androidNotification('hello') 266 | ->message('Hello JPush', [ 267 | 'title' => 'Hello', 268 | 'content_type' => 'text', 269 | 'extras' => [ 270 | 'key' => 'value' 271 | ] 272 | ]) 273 | ->send(); 274 | 275 | // OR 也可以提前准备好所有的参数,然后链式调用,这样代码可读性更好一点 276 | $cid = 'xxxxxx'; 277 | $platform = array('ios', 'android'); 278 | $alert = 'Hello JPush'; 279 | $tag = array('tag1', 'tag2'); 280 | $regId = array('rid1', 'rid2'); 281 | $ios_notification = array( 282 | 'sound' => 'hello jpush', 283 | 'badge' => 2, 284 | 'content-available' => true, 285 | 'category' => 'jiguang', 286 | 'extras' => array( 287 | 'key' => 'value', 288 | 'jiguang' 289 | ), 290 | ); 291 | $android_notification = array( 292 | 'title' => 'hello jpush', 293 | 'builder_id' => 2, 294 | 'extras' => array( 295 | 'key' => 'value', 296 | 'jiguang' 297 | ), 298 | ); 299 | $content = 'Hello World'; 300 | $message = array( 301 | 'title' => 'hello jpush', 302 | 'content_type' => 'text', 303 | 'extras' => array( 304 | 'key' => 'value', 305 | 'jiguang' 306 | ), 307 | ); 308 | $options = array( 309 | 'sendno' => 100, 310 | 'time_to_live' => 100, 311 | 'override_msg_id' => 100, 312 | 'big_push_duration' => 100 313 | ); 314 | $response = $push->setCid($cid) 315 | ->setPlatform($platform) 316 | ->addTag($tag) 317 | ->addRegistrationId($regId) 318 | ->iosNotification($alert, $ios_notification) 319 | ->androidNotification($alert, $android_notification) 320 | ->message($content, $message) 321 | ->options($options) 322 | ->send(); 323 | ``` 324 | 325 | #### 获取 Cid 326 | 327 | ```php 328 | $push->getCid($count = 1, $type = 'push'); 329 | ``` 330 | 331 | ## Report API 332 | 333 | ```php 334 | $report = $client->report(); 335 | ``` 336 | 337 | #### 获取送达统计 338 | 339 | ```php 340 | $report->getReceived('msg_id'); 341 | // OR 342 | $report->getReceived(['msg_id1', 'msg_id2']); 343 | ``` 344 | 345 | #### 送达状态查询 346 | 347 | ```php 348 | $msg_id0 = 66666666666; 349 | $report->getMessageStatus($msg_id0, 'rid0'); 350 | # OR 351 | $report->getMessageStatus($msg_id0, ['rid0', 'rid1']); 352 | #OR 353 | $report->getMessageStatus($msg_id0, ['rid0', 'rid1'], '2017-12-21'); 354 | ``` 355 | 356 | #### 获取消息统计 357 | 358 | ```php 359 | // getMessages(getMessages($msgIds)); 360 | // 消息统计与送达统计一样,接受一个数组的参数,在这里不做赘述 361 | ``` 362 | 363 | #### 获取用户统计 364 | 365 | 调用一下代码可以获得用户统计 366 | 367 | ```php 368 | $report->getUsers($time_unit, $start, $duration) 369 | ``` 370 | 371 | 参数说明: 372 | 373 | - time_unit:`String` 时间单位, 可取值HOUR, DAY, MONTH 374 | - start:`String` 起始时间 375 | - 如果单位是小时,则起始时间是小时(包含天),格式例:2014-06-11 09 376 | - 如果单位是天,则起始时间是日期(天),格式例:2014-06-11 377 | - 如果单位是月,则起始时间是日期(月),格式例:2014-06 378 | - duration:`String` 持续时长 379 | - 如果单位是天,则是持续的天数。以此类推 380 | - 只支持查询60天以内的用户信息,对于time_unit为HOUR的,只支持输出当天的统计结果。 381 | 382 | ## Device API 383 | 384 | ```php 385 | $device = $client->device(); 386 | ``` 387 | 388 | #### 操作 Device(registration_id) 389 | 390 | ```php 391 | // 查询指定设备的别名与标签 392 | $device->getDevices($registration_id); 393 | 394 | 395 | // 更新指定设备的别名与标签 396 | 397 | // 更新 Alias 398 | $device->updateAlias($registration_id, 'alias'); 399 | // 添加 tag, 支持字符串和数组两种参数 400 | $device->addTags($registration_id, 'tag'); 401 | // OR 402 | $device->addTags($registration_id, ['tag1', 'tag2']); 403 | // 移除 tag,支持字符串和数组两种参数 404 | $device->removeTags($registration_id, 'tags'); 405 | // OR 406 | $device->removeTags($registration_id, ['tag1', 'tag2']); 407 | // 清空所有 tag 408 | $device->clearTags($registration_id); 409 | 410 | // 更新 mobile 411 | $device->updateMoblie($registration_id, '13800138000'); 412 | // 取消手机绑定 413 | $device->clearMobile($registration_id); 414 | 415 | // getDevicesStatus($registrationId) 416 | // 获取在线用户的登录状态(VIP专属接口),支持字符串和数组两种参数 417 | $device->getDevicesStatus('rid'); 418 | // OR 419 | $device->getDevicesStatus(['rid1', 'rid2']); 420 | ``` 421 | 422 | #### 操作标签 423 | 424 | ```php 425 | // 获取标签列表 426 | $device->getTags() 427 | 428 | // 判断指定设备是否在指定标签之下 429 | $device->isDeviceInTag($registrationId, $tag); 430 | 431 | 432 | // 更新标签 433 | 434 | // 为标签添加设备,支持字符串和数组两种参数 435 | $device->addDevicesToTag($tag, 'rid'); 436 | $device->addDevicesToTag($tag, ['rid1', 'rid2']); 437 | 438 | // 为标签移除设备,支持字符串和数组两种参数 439 | $device->removeDevicesFromTag($tag, 'rid'); 440 | $device->removeDevicesFromTag($tag, ['rid1', 'rid2']); 441 | 442 | 443 | // 删除标签 444 | $device->deleteTag('tag'); 445 | ``` 446 | 447 | #### 操作别名 448 | 449 | ```php 450 | // 获取指定别名下的设备 451 | $device->getAliasDevices('alias'); 452 | 453 | // 删除别名 454 | $device->deleteAlias('alias'); 455 | ``` 456 | 457 | ## Schedule API 458 | 459 | ```php 460 | $schedule = $client->schedule(); 461 | ``` 462 | 463 | #### 创建定时任务 464 | 465 | 定时任务分为Single与Periodical两种,可以通过调用以下方法创建定时任务 466 | 467 | ```php 468 | $schedule->createSingleSchedule($name, $push_payload, $trigger) 469 | $schedule->createPeriodicalSchedule($name, $push_payload, $trigger) 470 | ``` 471 | 472 | 参数说明: 473 | - name: `String` 定时任务的名称 474 | - push_payload: `PushPayload` Push的构建对象,通过Push模块的`build()`方法获得 475 | - trigger: `Array` 触发器对象 476 | 477 | #### 更新定时任务 478 | 479 | ```php 480 | $schedule->updateSingleSchedule($schedule_id, $name=null, $enabled=null, $push_payload=null, $trigger=null) 481 | $schedule->updatePeriodicalSchedule($schedule_id, $name=null, $enabled=null, $push_payload=null, $trigger=null) 482 | ``` 483 | 484 | #### 其他 485 | 486 | ```php 487 | // 获取定时任务列表 488 | $schedule->getSchedules($page=1); 489 | 490 | // 获取指定定时任务 491 | $schedule->getSchedule($schedule_id); 492 | 493 | // 删除指定定时任务 494 | $schedule->deleteSchedule($schedule_id); 495 | 496 | // 获取定时任务对应的所有 msg_id 497 | $schedule->getMsgIds($schedule_id); 498 | ``` 499 | 500 | ## Exception Handle 501 | 502 | 当 API 请求发生错误时,SDK 将抛出异常,Pushpayload 具体错误代码请参考[ API 错误代码表](https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/#_19)。 503 | PHP SDK 主要抛出两个异常 `\JPush\Exceptions\APIConnectionException` 和 `\JPush\Exceptions\APIRequestException` 分别对应请求连接产生的异常和请求响应的异常。 504 | 这两种异常都需要捕获,为简单起见,也可以捕获他们的父类异常 `JPush\Exceptions\JPushException`(见 README)。另外 APIRequestException 异常还提供其他方法供开发者调用。 505 | 506 | ```php 507 | try { 508 | $pusher->send(); 509 | } catch (\JPush\Exceptions\APIConnectionException $e) { 510 | // try something here 511 | print $e; 512 | } catch (\JPush\Exceptions\APIRequestException $e) { 513 | // try something here 514 | print $e; 515 | } 516 | ``` 517 | -------------------------------------------------------------------------------- /doc/grouppush.md: -------------------------------------------------------------------------------- 1 | # JPush Group Push 2 | 3 | ## 获取 Group Key 和 Group Master Secret 4 | 5 | ```php 6 | $group_key = 'xxxx'; 7 | $group_master_secret = 'xxxx'; 8 | ``` 9 | 10 | ## 初始化 11 | 12 | **注:Group Key 需拼接 'group-' 使用** 13 | 14 | ```php 15 | $client = new \JPush\Client('group-' . $group_key, $group_master_secret); 16 | ``` 17 | 18 | ## 简单群组推送 19 | 20 | ```php 21 | $client->push() 22 | ->setPlatform('all') 23 | ->addAllAudience() 24 | ->setNotificationAlert('Hello, JPush') 25 | ->send(); 26 | ``` 27 | 28 | > [Example](https://github.com/jpush/jpush-api-php-client/blob/master/examples/push_example.php) 29 | -------------------------------------------------------------------------------- /doc/http2.md: -------------------------------------------------------------------------------- 1 | # JPush API PHP Client With HTTP/2 Support 2 | 3 | > JPush API PHP Client 全面支持 HTTP/2, 4 | > **要求 PHP >= 5.5.24**, 5 | > 但由于 libcurl 对于 HTTP/2 的实现依赖于第三方库 [nghttp2](https://github.com/nghttp2/nghttp2) 所以如果要支持 HTTP/2 需要做一些其他的配置。 6 | 7 | ### 安装 nghttp2 8 | 9 | 系统依赖仅针对 Ubuntu 14.04 LTS (trusty) 和 Debian 7.0 (wheezy) 或以上版本,其他系统版本请按照 nghttp2 的文档来操作: 10 | 11 | > From Ubuntu 15.10, spdylay has been available as a package named libspdylay-dev. For the earlier Ubuntu release, you need to build it yourself: http://tatsuhiro-t.github.io/spdylay/ 12 | 13 | 详细情况请查看 [nghttp2 的文档](https://github.com/nghttp2/nghttp2#requirements)。 14 | 15 | ```bash 16 | # Get build requirements 17 | # Some of these are used for the Python bindings 18 | # this package also installs 19 | $ sudo apt-get install g++ make binutils autoconf automake autotools-dev libtool pkg-config \ 20 | zlib1g-dev libcunit1-dev libssl-dev libxml2-dev libev-dev libevent-dev libjansson-dev \ 21 | libjemalloc-dev cython python3-dev python-setuptools 22 | 23 | # Build nghttp2 from source 24 | $ git clone https://github.com/tatsuhiro-t/nghttp2.git 25 | $ cd nghttp2 26 | $ autoreconf -i 27 | $ automake 28 | $ autoconf 29 | $ ./configure 30 | $ make 31 | $ sudo make install 32 | ``` 33 | 34 | ### 升级 curl 至最新版本 35 | 36 | ```bash 37 | $ sudo apt-get build-dep curl 38 | # 请根据当前的 curl 官网中的最新版本(https://curl.haxx.se/download/)替换下面的相应位置 39 | $ wget https://curl.haxx.se/download/curl-7.x.x.tar.bz2 40 | $ tar -xvjf curl-7.x.x.tar.bz2 41 | $ cd curl-7.x.x 42 | $ ./configure --with-nghttp2=/usr/local --with-ssl 43 | $ make 44 | $ sudo make install 45 | ``` 46 | 47 | ### 测试 48 | 49 | ##### 命令行测试 50 | 命令行运行 `$ curl --version`,若输出中的 Features 栏中有 `HTTP2` 一项则证明配置成功。 51 | 52 | ##### 样例测试 53 | 运行样例 `$ php examples/devices/get_devices_example.php`,若输出中的 HTTP 版本是 HTTP/2 则证明已经在使用 HTTP2 发送请求和接受响应了。 54 | 55 | ##### 测试测试 56 | 运行测试 `$./vendor/bin/phpunit tests/JPush/DevicePayloadTest.php`,若打印出的 http headers 中的 HTTP 版本是 HTTP/2 则证明已经在使用 HTTP2 发送请求和接受响应了。 57 | -------------------------------------------------------------------------------- /examples/admin_example.php: -------------------------------------------------------------------------------- 1 | createApp('aaa', 'cn.jpush.app'); 10 | print_r($response); 11 | 12 | $appKey = $response['body']['app_key']; 13 | $response = $admin->deleteApp($appKey); 14 | print_r($response); 15 | -------------------------------------------------------------------------------- /examples/batch_push_example.php: -------------------------------------------------------------------------------- 1 | 'all', 9 | 'target' => 'regid1', 10 | 'notification' => array( 11 | 'alert' => 'NotificationAlert1' 12 | ) 13 | ), 14 | array( 15 | 'platform' => 'all', 16 | 'target' => 'regid2', 17 | 'notification' => array( 18 | 'alert' => 'NotificationAlert2' 19 | ) 20 | ) 21 | ); 22 | 23 | $push_payload = $client -> push(); 24 | try { 25 | $response = $push_payload -> batchPushByRegid($singlePayloads); 26 | print_r($response); 27 | $response = $push_payload -> batchPushByAlias($singlePayloads); 28 | print_r($response); 29 | } catch (\JPush\Exceptions\APIConnectionException $e) { 30 | // try something here 31 | print $e; 32 | } catch (\JPush\Exceptions\APIRequestException $e) { 33 | // try something here 34 | print $e; 35 | } -------------------------------------------------------------------------------- /examples/cid_example.php: -------------------------------------------------------------------------------- 1 | push()->getCid(); 6 | 7 | print_r($response); 8 | -------------------------------------------------------------------------------- /examples/config.php.example: -------------------------------------------------------------------------------- 1 | device()->deleteAlias('alias'); 5 | print_r($response); 6 | -------------------------------------------------------------------------------- /examples/devices/delete_tag_example.php: -------------------------------------------------------------------------------- 1 | device()->deleteTag('tag'); 5 | print_r($response); 6 | -------------------------------------------------------------------------------- /examples/devices/get_alias_devices_example.php: -------------------------------------------------------------------------------- 1 | device()->getAliasDevices('alias'); 6 | print_r($response); 7 | -------------------------------------------------------------------------------- /examples/devices/get_devices_example.php: -------------------------------------------------------------------------------- 1 | device()->getDevices($registration_id); 6 | print_r($response); -------------------------------------------------------------------------------- /examples/devices/get_devices_status_example.php: -------------------------------------------------------------------------------- 1 | device()->getDevicesStatus($registration_id); 7 | } catch(\JPush\Exceptions\APIRequestException $e) { 8 | print $e; 9 | print $e->getHttpCode(); 10 | print $e->getHeaders(); 11 | } 12 | 13 | print_r($response); 14 | -------------------------------------------------------------------------------- /examples/devices/get_tags_example.php: -------------------------------------------------------------------------------- 1 | device()->getDevices($registration_id); 6 | print_r($response); -------------------------------------------------------------------------------- /examples/devices/update_device_example.php: -------------------------------------------------------------------------------- 1 | device()->getDevices($registration_id); 6 | print "before update alias = " . $result['body']['alias'] . "\n"; 7 | 8 | print 'updating alias ... response = '; 9 | $response = $client->device()->updateAlias($registration_id, 'jpush_alias'); 10 | print_r($response); 11 | 12 | $result = $client->device()->getDevices($registration_id); 13 | print "after update alias = " . $result['body']['alias'] . "\n\n"; 14 | 15 | // 添加 tag 16 | $result = $client->device()->getDevices($registration_id); 17 | print "before add tags = [" . implode(',', $result['body']['tags']) . "]\n"; 18 | 19 | print 'add tag1 tag2 ... response = '; 20 | 21 | $response = $client->device()->addTags($registration_id, 'tag0'); 22 | print_r($response); 23 | 24 | $response = $client->device()->addTags($registration_id, ['tag1', 'tag2']); 25 | print_r($response); 26 | 27 | $result = $client->device()->getDevices($registration_id); 28 | print "after add tags = [" . implode(',', $result['body']['tags']) . "]\n\n"; 29 | 30 | 31 | // 移除 tag 32 | $result = $client->device()->getDevices($registration_id); 33 | print "before remove tags = [" . implode(',', $result['body']['tags']) . "]\n"; 34 | 35 | print 'removing tag1 tag2 ... response = '; 36 | 37 | $response = $client->device()->removeTags($registration_id, 'tag0'); 38 | print_r($response); 39 | 40 | $response = $client->device()->removeTags($registration_id, ['tag1', 'tag2']); 41 | print_r($response); 42 | 43 | $result = $client->device()->getDevices($registration_id); 44 | print "after remove tags = [" . implode(',', $result['body']['tags']) . "]\n\n"; 45 | 46 | 47 | // 更新 mobile 48 | $result = $client->device()->getDevices($registration_id); 49 | print "before update mobile = " . $result['body']['mobile'] . "\n"; 50 | 51 | print 'updating mobile ... response = '; 52 | $response = $client->device()->updateMoblie($registration_id, '13800138000'); 53 | print_r($response); 54 | 55 | $result = $client->device()->getDevices($registration_id); 56 | print "after update mobile = " . $result['body']['mobile'] . "\n\n"; -------------------------------------------------------------------------------- /examples/devices/update_tag_example.php: -------------------------------------------------------------------------------- 1 | device()->isDeviceInTag($registration_id, 'tag'); 6 | $r = $result['body']['result'] ? 'true' : 'false'; 7 | print "before add device = " . $r . "\n"; 8 | 9 | print 'adding device ... response = '; 10 | $response = $client->device()->addDevicesToTag('tag', $registration_id); 11 | print_r($response); 12 | 13 | $result = $client->device()->isDeviceInTag($registration_id, 'tag'); 14 | $r = $result['body']['result'] ? 'true' : 'false'; 15 | print "after add tags = " . $r . "\n\n"; 16 | 17 | // 为一个标签删除设备 18 | $result = $client->device()->isDeviceInTag($registration_id, 'tag'); 19 | $r = $result['body']['result'] ? 'true' : 'false'; 20 | print "before remove device = " . $r . "\n"; 21 | 22 | print 'removing device ... response = '; 23 | $response = $client->device()->removeDevicesFromTag('tag', $registration_id); 24 | print_r($response); 25 | 26 | $result = $client->device()->isDeviceInTag($registration_id, 'tag'); 27 | $r = $result['body']['result'] ? 'true' : 'false'; 28 | print "after remove device = " . $r . "\n\n"; 29 | 30 | -------------------------------------------------------------------------------- /examples/grouppush_example.php: -------------------------------------------------------------------------------- 1 | push() 12 | ->setPlatform('all') 13 | ->addAllAudience() 14 | ->setNotificationAlert('Hi, JPush'); 15 | try { 16 | $response = $push_payload->send(); 17 | print_r($response); 18 | } catch (\JPush\Exceptions\APIConnectionException $e) { 19 | // try something here 20 | print $e; 21 | } catch (\JPush\Exceptions\APIRequestException $e) { 22 | // try something here 23 | print $e; 24 | } 25 | -------------------------------------------------------------------------------- /examples/huawei_push_example.php: -------------------------------------------------------------------------------- 1 | push() 8 | ->setPlatform(array('ios', 'android')) 9 | // ->addAlias('alias') 10 | ->addTag(array('tag1', 'tag2')) 11 | // ->addRegistrationId($registration_id) 12 | ->setNotificationAlert('Hi, JPush') 13 | ->androidNotification('Hello HUAWEI', array( 14 | 'title' => 'huawei demo', 15 | 16 | // --------------------------------------------------- 17 | // `uri_activity` 字段用于指定想要打开的 activity. 18 | // 值为 activity 节点的 “android:name” 属性值。 19 | 'uri_activity' => 'cn.jpush.android.ui.OpenClickActivity', 20 | // --------------------------------------------------- 21 | 22 | 'extras' => array( 23 | 'key' => 'value', 24 | 'jiguang' 25 | ), 26 | )); 27 | // ->send(); 28 | print_r($payload->build()); 29 | 30 | } catch (\JPush\Exceptions\APIConnectionException $e) { 31 | // try something here 32 | print $e; 33 | } catch (\JPush\Exceptions\APIRequestException $e) { 34 | // try something here 35 | print $e; 36 | } 37 | -------------------------------------------------------------------------------- /examples/push_example.php: -------------------------------------------------------------------------------- 1 | push() 19 | // ->setPlatform('all') 20 | // ->addAllAudience() 21 | // ->setNotificationAlert('Hi, JPush'); 22 | // try { 23 | // $response = $push_payload->send(); 24 | // print_r($response); 25 | // } catch (\JPush\Exceptions\APIConnectionException $e) { 26 | // // try something here 27 | // print $e; 28 | // } catch (\JPush\Exceptions\APIRequestException $e) { 29 | // // try something here 30 | // print $e; 31 | // } 32 | 33 | // 完整的推送示例 34 | // 这只是使用样例,不应该直接用于实际生产环境中 !! 35 | try { 36 | $response = $client->push() 37 | ->setPlatform(array('ios', 'android')) 38 | // 一般情况下,关于 audience 的设置只需要调用 addAlias、addTag、addTagAnd 或 addRegistrationId 39 | // 这四个方法中的某一个即可,这里仅作为示例,当然全部调用也可以,多项 audience 调用表示其结果的交集 40 | // 即是说一般情况下,下面三个方法和没有列出的 addTagAnd 一共四个,只适用一个便可满足大多数的场景需求 41 | 42 | // ->addAlias('alias') 43 | // ->addTag(array('tag1', 'tag2')) 44 | // ->addRegistrationId($registration_id) 45 | ->addAllAudience() 46 | 47 | ->setNotificationAlert('Test custom') 48 | ->iosNotification('Hello IOS', array( 49 | 'sound' => 'sound.caf', 50 | // 'badge' => '+1', 51 | // 'content-available' => true, 52 | // 'mutable-content' => true, 53 | 'category' => 'jiguang', 54 | 'extras' => array( 55 | 'key' => 'value', 56 | 'jiguang' 57 | ), 58 | )) 59 | ->androidNotification('Hello Android', array( 60 | 'title' => 'hello jpush', 61 | // 'builder_id' => 2, 62 | 'extras' => array( 63 | 'key' => 'value', 64 | 'jiguang' 65 | ), 66 | )) 67 | // voip可以传输任意键值对,可用作自定义 68 | ->voip(array( 69 | 'test123' => 'val1', 70 | 'jsontest' => 2, 71 | 'booleantest' => true 72 | )) 73 | ->message('message content', array( 74 | 'title' => 'hello jpush', 75 | // 'content_type' => 'text', 76 | 'extras' => array( 77 | 'key' => 'value', 78 | 'jiguang' 79 | ), 80 | )) 81 | ->options(array( 82 | // sendno: 表示推送序号,纯粹用来作为 API 调用标识, 83 | // API 返回时被原样返回,以方便 API 调用方匹配请求与返回 84 | // 这里设置为 100 仅作为示例 85 | 86 | // 'sendno' => 100, 87 | 88 | // time_to_live: 表示离线消息保留时长(秒), 89 | // 推送当前用户不在线时,为该用户保留多长时间的离线消息,以便其上线时再次推送。 90 | // 默认 86400 (1 天),最长 10 天。设置为 0 表示不保留离线消息,只有推送当前在线的用户可以收到 91 | // 这里设置为 1 仅作为示例 92 | 93 | 'time_to_live' => 1, 94 | 95 | // apns_production: 表示APNs是否生产环境, 96 | // True 表示推送生产环境,False 表示要推送开发环境;如果不指定则默认为推送开发环境 97 | 98 | // 'apns_production' => false, 99 | 100 | // big_push_duration: 表示定速推送时长(分钟),又名缓慢推送,把原本尽可能快的推送速度,降低下来, 101 | // 给定的 n 分钟内,均匀地向这次推送的目标用户推送。最大值为1400.未设置则不是定速推送 102 | // 这里设置为 1 仅作为示例 103 | 104 | // 'big_push_duration' => 1 105 | )) 106 | ->setSmsMessage(array( 107 | 'delay_time' => 60, 108 | 'signid' => 154, 109 | 'temp_id' => 1, 110 | 'temp_para' => array( 111 | 'code' => 357 112 | ), 113 | 'active_filter' => false 114 | )) 115 | // custom可自定义最外层参数,如skd未支持部分文档功能,用户可自行写入 116 | // 这里仅作为例子展示 117 | // ->custom(array( 118 | // 'sms_message' => array( 119 | // 'active_filter' => false, 120 | // 'delay_time' => 60, 121 | // 'signid' => 154, 122 | // 'temp_id' => 1, 123 | // 'temp_para' => array( 124 | // 'code' => 357 125 | // )), 126 | // 'options' => array( 127 | // 'apns_production' => false, 128 | // 'time_to_live' => 62000, 129 | // ) 130 | // )) 131 | ->send(); 132 | print_r($response); 133 | 134 | } catch (\JPush\Exceptions\APIConnectionException $e) { 135 | // try something here 136 | print $e; 137 | } catch (\JPush\Exceptions\APIRequestException $e) { 138 | // try something here 139 | print $e; 140 | } 141 | -------------------------------------------------------------------------------- /examples/reports/messages_detail_example.php: -------------------------------------------------------------------------------- 1 | report()->getMessagesDetail('149646415212'); 5 | print_r($result); -------------------------------------------------------------------------------- /examples/reports/received_detail_example.php: -------------------------------------------------------------------------------- 1 | report()->getReceivedDetail('149646415212'); 5 | print_r($result); -------------------------------------------------------------------------------- /examples/schedule_example.php: -------------------------------------------------------------------------------- 1 | push() 7 | ->setPlatform("all") 8 | ->addAllAudience() 9 | ->setNotificationAlert("Hi, 这是一条定时发送的消息") 10 | ->build(); 11 | 12 | // 创建一个2016-12-22 13:45:00触发的定时任务 13 | $response = $client->schedule()->createSingleSchedule("每天14点发送的定时任务", $payload, array("time"=>"2016-12-22 13:45:00")); 14 | print_r($response); 15 | 16 | // 创建一个每天14点发送的定时任务 17 | $response = $client->schedule()->createPeriodicalSchedule("每天14点发送的定时任务", $payload, 18 | array( 19 | "start"=>"2016-12-22 13:45:00", 20 | "end"=>"2016-12-25 13:45:00", 21 | "time"=>"14:00:00", 22 | "time_unit"=>"DAY", 23 | "frequency"=>1 24 | )); 25 | print_r($response); 26 | 27 | -------------------------------------------------------------------------------- /examples/zone_examples.php: -------------------------------------------------------------------------------- 1 | push() 12 | ->setPlatform('all') 13 | ->addAllAudience() 14 | ->setNotificationAlert('Hi, JPush'); 15 | try { 16 | $response = $push_payload->send(); 17 | print_r($response); 18 | } catch (\JPush\Exceptions\APIConnectionException $e) { 19 | // try something here 20 | print $e; 21 | } catch (\JPush\Exceptions\APIRequestException $e) { 22 | // try something here 23 | print $e; 24 | } -------------------------------------------------------------------------------- /phpunit.xml.dist: -------------------------------------------------------------------------------- 1 | 2 | 10 | 11 | 12 | tests/JPush 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /src/JPush/AdminClient.php: -------------------------------------------------------------------------------- 1 | devKey = $devKey; 18 | $this->devSecret = $devSecret; 19 | $this->retryTimes = 1; 20 | $this->logFile = null; 21 | } 22 | 23 | public function getAuthStr() { return $this->devKey . ":" . $this->devSecret; } 24 | public function getRetryTimes() { return $this->retryTimes; } 25 | public function getLogFile() { return $this->logFile; } 26 | 27 | public function createApp($appName, $androidPackage, $groupName=null) { 28 | $url = AdminClient::ADMIN_URL; 29 | $body = [ 30 | 'app_name' => $appName, 31 | 'android_package'=> $androidPackage, 32 | 'group_name' => $groupName 33 | 34 | ]; 35 | return Http::post($this, $url, $body); 36 | } 37 | 38 | public function deleteApp($appKey) { 39 | $url = AdminClient::ADMIN_URL . $appKey . '/delete'; 40 | return Http::post($this, $url, []); 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/JPush/Client.php: -------------------------------------------------------------------------------- 1 | [ 14 | 'push' => 'https://api.jpush.cn/v3/', 15 | 'report' => 'https://report.jpush.cn/v3/', 16 | 'device' => 'https://device.jpush.cn/v3/devices/', 17 | 'alias' => 'https://device.jpush.cn/v3/aliases/', 18 | 'tag' => 'https://device.jpush.cn/v3/tags/', 19 | 'schedule' => 'https://api.jpush.cn/v3/schedules' 20 | ], 21 | 'BJ' => [ 22 | 'push' => 'https://bjapi.push.jiguang.cn/v3/', 23 | 'report' => 'https://bjapi.push.jiguang.cn/v3/report/', 24 | 'device' => 'https://bjapi.push.jiguang.cn/v3/device/', 25 | 'alias' => 'https://bjapi.push.jiguang.cn/v3/device/aliases/', 26 | 'tag' => 'https://bjapi.push.jiguang.cn/v3/device/tags/', 27 | 'schedules' => 'https://bjapi.push.jiguang.cn/v3/push/schedules' 28 | ] 29 | ]; 30 | 31 | public function __construct($appKey, $masterSecret, $logFile=Config::DEFAULT_LOG_FILE, $retryTimes=Config::DEFAULT_MAX_RETRY_TIMES, $zone = null) { 32 | if (!is_string($appKey) || !is_string($masterSecret)) { 33 | throw new InvalidArgumentException("Invalid appKey or masterSecret"); 34 | } 35 | $this->appKey = $appKey; 36 | $this->masterSecret = $masterSecret; 37 | if (!is_null($retryTimes)) { 38 | $this->retryTimes = $retryTimes; 39 | } else { 40 | $this->retryTimes = 1; 41 | } 42 | $this->logFile = $logFile; 43 | if (!is_null($zone) && in_array(strtoupper($zone), array_keys(self::$zones))) { 44 | $this->zone = strtoupper($zone); 45 | } else { 46 | $this->zone = null; 47 | } 48 | } 49 | 50 | public function push() { return new PushPayload($this); } 51 | public function report() { return new ReportPayload($this); } 52 | public function device() { return new DevicePayload($this); } 53 | public function schedule() { return new SchedulePayload($this);} 54 | 55 | public function getAuthStr() { return $this->appKey . ":" . $this->masterSecret; } 56 | public function getRetryTimes() { return $this->retryTimes; } 57 | public function getLogFile() { return $this->logFile; } 58 | 59 | public function is_group() { 60 | $str = substr($this->appKey, 0, 6); 61 | return $str === 'group-'; 62 | } 63 | 64 | public function makeURL($key) { 65 | if (is_null($this->zone)) { 66 | return self::$zones['DEFAULT'][$key]; 67 | } else { 68 | return self::$zones[$this->zone][$key]; 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/JPush/Config.php: -------------------------------------------------------------------------------- 1 | client = $client; 15 | } 16 | 17 | public function getDevices($registrationId) { 18 | $url = $this->client->makeURL('device') . $registrationId; 19 | return Http::get($this->client, $url); 20 | } 21 | 22 | public function updateAlias($registration_id, $alias) { 23 | return $this->updateDevice($registration_id, $alias); 24 | } 25 | public function addTags($registration_id, $tags) { 26 | $tags = is_array($tags) ? $tags : array($tags); 27 | return $this->updateDevice($registration_id, null, null, $tags); 28 | } 29 | public function removeTags($registration_id, $tags) { 30 | $tags = is_array($tags) ? $tags : array($tags); 31 | return $this->updateDevice($registration_id, null, null, null, $tags); 32 | } 33 | public function updateMoblie($registration_id, $mobile) { 34 | return $this->updateDevice($registration_id, null, $mobile); 35 | } 36 | 37 | public function clearMobile($registrationId) { 38 | $url = $this->client->makeURL('device') . $registrationId; 39 | return Http::post($this->client, $url, ['mobile' => '']); 40 | } 41 | 42 | public function clearTags($registrationId) { 43 | $url = $this->client->makeURL('device') . $registrationId; 44 | return Http::post($this->client, $url, ['tags' => '']); 45 | } 46 | 47 | public function updateDevice($registrationId, $alias = null, $mobile = null, $addTags = null, $removeTags = null) { 48 | $payload = array(); 49 | if (!is_string($registrationId)) { 50 | throw new InvalidArgumentException('Invalid registration_id'); 51 | } 52 | 53 | $aliasIsNull = is_null($alias); 54 | $mobileIsNull = is_null($mobile); 55 | $addTagsIsNull = is_null($addTags); 56 | $removeTagsIsNull = is_null($removeTags); 57 | 58 | if ($aliasIsNull && $addTagsIsNull && $removeTagsIsNull && $mobileIsNull) { 59 | throw new InvalidArgumentException("alias, addTags, removeTags not all null"); 60 | } 61 | 62 | if (!$aliasIsNull) { 63 | if (is_string($alias)) { 64 | $payload['alias'] = $alias; 65 | } else { 66 | throw new InvalidArgumentException("Invalid alias string"); 67 | } 68 | } 69 | 70 | if (!$mobileIsNull) { 71 | if (is_string($mobile)) { 72 | $payload['mobile'] = $mobile; 73 | } else { 74 | throw new InvalidArgumentException("Invalid mobile string"); 75 | } 76 | } 77 | 78 | $tags = array(); 79 | 80 | if (!$addTagsIsNull) { 81 | if (is_array($addTags)) { 82 | $tags['add'] = $addTags; 83 | } else { 84 | throw new InvalidArgumentException("Invalid addTags array"); 85 | } 86 | } 87 | 88 | if (!$removeTagsIsNull) { 89 | if (is_array($removeTags)) { 90 | $tags['remove'] = $removeTags; 91 | } else { 92 | throw new InvalidArgumentException("Invalid removeTags array"); 93 | } 94 | } 95 | 96 | if (count($tags) > 0) { 97 | $payload['tags'] = $tags; 98 | } 99 | 100 | $url = $this->client->makeURL('device') . $registrationId; 101 | return Http::post($this->client, $url, $payload); 102 | } 103 | 104 | public function getTags() { 105 | $url = $this->client->makeURL('tag'); 106 | return Http::get($this->client, $url); 107 | } 108 | 109 | public function isDeviceInTag($registrationId, $tag) { 110 | if (!is_string($registrationId)) { 111 | throw new InvalidArgumentException("Invalid registration_id"); 112 | } 113 | 114 | if (!is_string($tag)) { 115 | throw new InvalidArgumentException("Invalid tag"); 116 | } 117 | $url = $this->client->makeURL('tag') . $tag . '/registration_ids/' . $registrationId; 118 | return Http::get($this->client, $url); 119 | } 120 | 121 | public function addDevicesToTag($tag, $addDevices) { 122 | $device = is_array($addDevices) ? $addDevices : array($addDevices); 123 | return $this->updateTag($tag, $device, null); 124 | } 125 | public function removeDevicesFromTag($tag, $removeDevices) { 126 | $device = is_array($removeDevices) ? $removeDevices : array($removeDevices); 127 | return $this->updateTag($tag, null, $device); 128 | } 129 | public function updateTag($tag, $addDevices = null, $removeDevices = null) { 130 | if (!is_string($tag)) { 131 | throw new InvalidArgumentException("Invalid tag"); 132 | } 133 | 134 | $addDevicesIsNull = is_null($addDevices); 135 | $removeDevicesIsNull = is_null($removeDevices); 136 | 137 | if ($addDevicesIsNull && $removeDevicesIsNull) { 138 | throw new InvalidArgumentException("Either or both addDevices and removeDevices must be set."); 139 | } 140 | 141 | $registrationId = array(); 142 | 143 | if (!$addDevicesIsNull) { 144 | if (is_array($addDevices)) { 145 | $registrationId['add'] = $addDevices; 146 | } else { 147 | throw new InvalidArgumentException("Invalid addDevices"); 148 | } 149 | } 150 | 151 | if (!$removeDevicesIsNull) { 152 | if (is_array($removeDevices)) { 153 | $registrationId['remove'] = $removeDevices; 154 | } else { 155 | throw new InvalidArgumentException("Invalid removeDevices"); 156 | } 157 | } 158 | 159 | $url = $this->client->makeURL('tag') . $tag; 160 | $payload = array('registration_ids'=>$registrationId); 161 | return Http::post($this->client, $url, $payload); 162 | } 163 | 164 | public function deleteTag($tag) { 165 | if (!is_string($tag)) { 166 | throw new InvalidArgumentException("Invalid tag"); 167 | } 168 | $url = $this->client->makeURL('tag') . $tag; 169 | return Http::delete($this->client, $url); 170 | } 171 | 172 | public function getAliasDevices($alias, $platform = null) { 173 | if (!is_string($alias)) { 174 | throw new InvalidArgumentException("Invalid alias"); 175 | } 176 | 177 | $url = $this->client->makeURL('alias') . $alias; 178 | 179 | if (!is_null($platform)) { 180 | if (is_array($platform)) { 181 | $isFirst = true; 182 | foreach($platform as $item) { 183 | if ($isFirst) { 184 | $url = $url . '?platform=' . $item; 185 | $isFirst = false; 186 | } else { 187 | $url = $url . ',' . $item; 188 | } 189 | } 190 | } else if (is_string($platform)) { 191 | $url = $url . '?platform=' . $platform; 192 | } else { 193 | throw new InvalidArgumentException("Invalid platform"); 194 | } 195 | } 196 | return Http::get($this->client, $url); 197 | } 198 | 199 | public function deleteAlias($alias) { 200 | if (!is_string($alias)) { 201 | throw new InvalidArgumentException("Invalid alias"); 202 | } 203 | $url = $this->client->makeURL('alias') . $alias; 204 | return Http::delete($this->client, $url); 205 | } 206 | 207 | public function getDevicesStatus($registrationId) { 208 | if (!is_array($registrationId) && !is_string($registrationId)) { 209 | throw new InvalidArgumentException('Invalid registration_id'); 210 | } 211 | 212 | if (is_string($registrationId)) { 213 | $registrationId = explode(',', $registrationId); 214 | } 215 | 216 | $payload = array(); 217 | if (count($registrationId) <= 0) { 218 | throw new InvalidArgumentException('Invalid registration_id'); 219 | } 220 | $payload['registration_ids'] = $registrationId; 221 | $url = $this->client->makeURL('device') . 'status'; 222 | return Http::post($this->client, $url, $payload); 223 | } 224 | } 225 | -------------------------------------------------------------------------------- /src/JPush/Exceptions/APIConnectionException.php: -------------------------------------------------------------------------------- 1 | message} \n"; 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /src/JPush/Exceptions/APIRequestException.php: -------------------------------------------------------------------------------- 1 | http_code = $response['http_code']; 12 | $this->headers = $response['headers']; 13 | 14 | $body = json_decode($response['body'], true); 15 | 16 | if (key_exists('error', $body)) { 17 | $this->code = $body['error']['code']; 18 | $this->message = $body['error']['message']; 19 | } else { 20 | $this->code = $body['code']; 21 | $this->message = $body['message']; 22 | } 23 | } 24 | 25 | public function __toString() { 26 | return "\n" . __CLASS__ . " -- [{$this->code}]: {$this->message} \n"; 27 | } 28 | 29 | public function getHttpCode() { 30 | return $this->http_code; 31 | } 32 | public function getHeaders() { 33 | return $this->headers; 34 | } 35 | 36 | } 37 | -------------------------------------------------------------------------------- /src/JPush/Exceptions/JPushException.php: -------------------------------------------------------------------------------- 1 | http_code = $response['http_code']; 11 | $this->headers = $response['headers']; 12 | $this->message = $response['body']; 13 | } 14 | 15 | function __toString() { 16 | return "\n" . __CLASS__ . " -- [{$this->http_code}]: {$this->message} \n"; 17 | } 18 | 19 | public function getHttpCode() { 20 | return $this->http_code; 21 | } 22 | public function getHeaders() { 23 | return $this->headers; 24 | } 25 | } 26 | -------------------------------------------------------------------------------- /src/JPush/Http.php: -------------------------------------------------------------------------------- 1 | getAuthStr()); 46 | curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); 47 | 48 | // 设置Post参数 49 | if ($method === Config::HTTP_POST) { 50 | curl_setopt($ch, CURLOPT_POST, true); 51 | } else if ($method === Config::HTTP_DELETE || $method === Config::HTTP_PUT) { 52 | curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method); 53 | } 54 | if (!is_null($body)) { 55 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($body)); 56 | } 57 | 58 | curl_setopt($ch, CURLOPT_HTTPHEADER, array( 59 | 'Content-Type: application/json', 60 | 'Connection: Keep-Alive' 61 | )); 62 | 63 | $output = curl_exec($ch); 64 | $response = array(); 65 | $errorCode = curl_errno($ch); 66 | 67 | // $msg = ''; 68 | // $data = json_decode($body, true); 69 | // if (isset($data['options']['sendno'])) { 70 | // $sendno = $data['options']['sendno']; 71 | // $msg = 'sendno: ' . $sendno; 72 | // } 73 | 74 | $msg = ''; 75 | if (isset($body['options']['sendno'])) { 76 | $sendno = $body['options']['sendno']; 77 | $msg = 'sendno: ' . $sendno; 78 | } 79 | 80 | 81 | if ($errorCode) { 82 | $retries = $client->getRetryTimes(); 83 | if ($times < $retries) { 84 | return self::sendRequest($client, $url, $method, $body, ++$times); 85 | } else { 86 | if ($errorCode === 28) { 87 | throw new APIConnectionException($msg . "Response timeout. Your request has probably be received by JPush Server,please check that whether need to be pushed again." ); 88 | } elseif ($errorCode === 56) { 89 | // resolve error[56 Problem (2) in the Chunked-Encoded data] 90 | throw new APIConnectionException($msg . "Response timeout, maybe cause by old CURL version. Your request has probably be received by JPush Server, please check that whether need to be pushed again."); 91 | } else { 92 | throw new APIConnectionException("$msg . Connect timeout. Please retry later. Error:" . $errorCode . " " . curl_error($ch)); 93 | } 94 | } 95 | } else { 96 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 97 | $header_size = curl_getinfo($ch, CURLINFO_HEADER_SIZE); 98 | $header_text = substr($output, 0, $header_size); 99 | $body = substr($output, $header_size); 100 | $headers = array(); 101 | foreach (explode("\r\n", $header_text) as $i => $line) { 102 | if (!empty($line)) { 103 | if ($i === 0) { 104 | $headers[0] = $line; 105 | } else if (strpos($line, ": ")) { 106 | list ($key, $value) = explode(': ', $line); 107 | $headers[$key] = $value; 108 | } 109 | } 110 | } 111 | $response['headers'] = $headers; 112 | $response['body'] = $body; 113 | $response['http_code'] = $httpCode; 114 | } 115 | curl_close($ch); 116 | return $response; 117 | } 118 | 119 | public static function processResp($response) { 120 | $data = json_decode($response['body'], true); 121 | if ($response['http_code'] === 200) { 122 | $result = array(); 123 | $result['body'] = $data; 124 | $result['http_code'] = $response['http_code']; 125 | $result['headers'] = $response['headers']; 126 | return $result; 127 | } elseif (is_null($data)) { 128 | throw new ServiceNotAvaliable($response); 129 | } else { 130 | throw new APIRequestException($response); 131 | } 132 | } 133 | 134 | public static function log($client, $content) { 135 | if (!is_null($client->getLogFile())) { 136 | error_log($content . "\r\n", 3, $client->getLogFile()); 137 | } 138 | } 139 | } 140 | -------------------------------------------------------------------------------- /src/JPush/PushPayload.php: -------------------------------------------------------------------------------- 1 | client = $client; 41 | $url = $this->client->is_group() ? 'grouppush' : 'push'; 42 | $this->url = $this->client->makeURL('push') . $url; 43 | } 44 | 45 | public function getCid($count = 1, $type = 'push') { 46 | $url = $this->client->makeURL('push') . 'push/cid?count=' . $count . '&type=' . $type; 47 | return Http::get($this->client, $url); 48 | } 49 | 50 | public function setCid($cid) { 51 | $this->cid = trim($cid); 52 | return $this; 53 | } 54 | 55 | public function setPlatform($platform) { 56 | # $required_keys = array('all', 'android', 'ios', 'winphone', 'hmos'); 57 | if (is_string($platform)) { 58 | $ptf = strtolower($platform); 59 | if ('all' === $ptf) { 60 | $this->platform = 'all'; 61 | } elseif (in_array($ptf, self::$EFFECTIVE_DEVICE_TYPES)) { 62 | $this->platform = array($ptf); 63 | } 64 | } elseif (is_array($platform)) { 65 | $ptf = array_map('strtolower', $platform); 66 | $this->platform = array_intersect($ptf, self::$EFFECTIVE_DEVICE_TYPES); 67 | } 68 | return $this; 69 | } 70 | 71 | public function setAudience($all) { 72 | if (strtolower($all) === 'all') { 73 | $this->addAllAudience(); 74 | return $this; 75 | } else { 76 | throw new InvalidArgumentException('Invalid audience value'); 77 | } 78 | } 79 | 80 | public function addAllAudience() { 81 | $this->audience = "all"; 82 | return $this; 83 | } 84 | 85 | public function addTag($tag) { 86 | return $this->updateAudience('tags', $tag, 'tag'); 87 | } 88 | 89 | public function addTagAnd($tag) { 90 | return $this->updateAudience('tagAnds', $tag, 'tag_and'); 91 | } 92 | 93 | public function addTagNot($tag) { 94 | return $this->updateAudience('tagNots', $tag, 'tag_not'); 95 | } 96 | 97 | public function addAlias($alias) { 98 | return $this->updateAudience('alias', $alias, 'alias'); 99 | } 100 | 101 | public function addRegistrationId($registrationId) { 102 | return $this->updateAudience('registrationIds', $registrationId, 'registration_id'); 103 | } 104 | 105 | public function addSegmentId($segmentId) { 106 | return $this->updateAudience('segmentIds', $segmentId, 'segment'); 107 | } 108 | 109 | public function addAbtest($abtest) { 110 | return $this->updateAudience('abtests', $abtest, 'abtest'); 111 | } 112 | 113 | private function updateAudience($key, $value, $name) { 114 | if (is_null($this->$key)) { 115 | $this->$key = array(); 116 | } 117 | 118 | if (is_array($value)) { 119 | foreach($value as $v) { 120 | if (!is_string($v)) { 121 | throw new InvalidArgumentException("Invalid $name value"); 122 | } 123 | if (!in_array($v, $this->$key)) { 124 | array_push($this->$key, $v); 125 | } 126 | } 127 | } else if (is_string($value)) { 128 | if (!in_array($value, $this->$key)) { 129 | array_push($this->$key, $value); 130 | } 131 | } else { 132 | throw new InvalidArgumentException("Invalid $name value"); 133 | } 134 | 135 | return $this; 136 | } 137 | 138 | public function setNotificationAlert($alert) { 139 | if (!is_string($alert)) { 140 | throw new InvalidArgumentException("Invalid alert value"); 141 | } 142 | $this->notificationAlert = $alert; 143 | return $this; 144 | } 145 | 146 | public function addWinPhoneNotification($alert=null, $title=null, $_open_page=null, $extras=null) { 147 | $winPhone = array(); 148 | 149 | if (!is_null($alert)) { 150 | if (!is_string($alert)) { 151 | throw new InvalidArgumentException("Invalid winphone notification"); 152 | } 153 | $winPhone['alert'] = $alert; 154 | } 155 | 156 | if (!is_null($title)) { 157 | if (!is_string($title)) { 158 | throw new InvalidArgumentException("Invalid winphone title notification"); 159 | } 160 | if(strlen($title) > 0) { 161 | $winPhone['title'] = $title; 162 | } 163 | } 164 | 165 | if (!is_null($_open_page)) { 166 | if (!is_string($_open_page)) { 167 | throw new InvalidArgumentException("Invalid winphone _open_page notification"); 168 | } 169 | if (strlen($_open_page) > 0) { 170 | $winPhone['_open_page'] = $_open_page; 171 | } 172 | } 173 | 174 | if (!is_null($extras)) { 175 | if (!is_array($extras)) { 176 | throw new InvalidArgumentException("Invalid winphone extras notification"); 177 | } 178 | if (count($extras) > 0) { 179 | $winPhone['extras'] = $extras; 180 | } 181 | } 182 | 183 | if (count($winPhone) <= 0) { 184 | throw new InvalidArgumentException("Invalid winphone notification"); 185 | } 186 | 187 | $this->winPhoneNotification = $winPhone; 188 | return $this; 189 | } 190 | 191 | public function setSms($delay_time, $temp_id, array $temp_para = []) { 192 | $sms = array(); 193 | $sms['temp_id'] = $temp_id; 194 | $sms['delay_time'] = ($delay_time === 0 || (is_int($delay_time) && $delay_time > 0 && $delay_time <= 86400)) ? $delay_time : 0; 195 | 196 | if (!empty($temp_para)) { 197 | $sms['temp_para'] = $temp_para; 198 | } 199 | 200 | $this->smsMessage = $sms; 201 | return $this; 202 | } 203 | 204 | public function build() { 205 | $payload = array(); 206 | 207 | // validate platform 208 | if (is_null($this->platform)) { 209 | throw new InvalidArgumentException("platform must be set"); 210 | } 211 | $payload["platform"] = $this->platform; 212 | 213 | if (!is_null($this->cid)) { 214 | $payload['cid'] = $this->cid; 215 | } 216 | 217 | // validate audience 218 | $audience = array(); 219 | if (!is_null($this->tags)) { 220 | $audience["tag"] = $this->tags; 221 | } 222 | if (!is_null($this->tagAnds)) { 223 | $audience["tag_and"] = $this->tagAnds; 224 | } 225 | if (!is_null($this->tagNots)) { 226 | $audience["tag_not"] = $this->tagNots; 227 | } 228 | if (!is_null($this->alias)) { 229 | $audience["alias"] = $this->alias; 230 | } 231 | if (!is_null($this->registrationIds)) { 232 | $audience["registration_id"] = $this->registrationIds; 233 | } 234 | if (!is_null($this->segmentIds)) { 235 | $audience["segment"] = $this->segmentIds; 236 | } 237 | if (!is_null($this->abtests)) { 238 | $audience["abtest"] = $this->abtests; 239 | } 240 | if (is_null($this->audience) && count($audience) <= 0) { 241 | throw new InvalidArgumentException("audience must be set"); 242 | } else if (!is_null($this->audience) && count($audience) > 0) { 243 | throw new InvalidArgumentException("you can't add tags/alias/registration_id/tag_and when audience='all'"); 244 | } else if (is_null($this->audience)) { 245 | $payload["audience"] = $audience; 246 | } else { 247 | $payload["audience"] = $this->audience; 248 | } 249 | 250 | 251 | // validate notification 252 | $notification = array(); 253 | 254 | if (!is_null($this->notificationAlert)) { 255 | $notification['alert'] = $this->notificationAlert; 256 | } 257 | 258 | if (!is_null($this->androidNotification)) { 259 | $notification['android'] = $this->androidNotification; 260 | if (is_null($this->androidNotification['alert'])) { 261 | if (is_null($this->notificationAlert)) { 262 | throw new InvalidArgumentException("Android alert can not be null"); 263 | } else { 264 | $notification['android']['alert'] = $this->notificationAlert; 265 | } 266 | } 267 | } 268 | 269 | if (!is_null($this->iosNotification)) { 270 | $notification['ios'] = $this->iosNotification; 271 | if (is_null($this->iosNotification['alert'])) { 272 | if (is_null($this->notificationAlert)) { 273 | throw new InvalidArgumentException("iOS alert can not be null"); 274 | } else { 275 | $notification['ios']['alert'] = $this->notificationAlert; 276 | } 277 | } 278 | } 279 | 280 | if (!is_null($this->winPhoneNotification)) { 281 | $notification['winphone'] = $this->winPhoneNotification; 282 | if (is_null($this->winPhoneNotification['alert'])) { 283 | if (is_null($this->winPhoneNotification)) { 284 | throw new InvalidArgumentException("WinPhone alert can not be null"); 285 | } else { 286 | $notification['winphone']['alert'] = $this->notificationAlert; 287 | } 288 | } 289 | } 290 | 291 | if (!is_null($this->hmosNotification)) { 292 | $notification['hmos'] = $this->hmosNotification; 293 | if (is_null($this->hmosNotification['alert'])) { 294 | if (is_null($this->hmosNotification)) { 295 | throw new InvalidArgumentException("hmos alert can not be null"); 296 | } else { 297 | $notification['hmos']['alert'] = $this->notificationAlert; 298 | } 299 | } 300 | if (is_null($this->hmosNotification['category'])) { 301 | throw new InvalidArgumentException("hmos category can not be null"); 302 | } 303 | } 304 | 305 | if (!is_null($this->voip)) { 306 | $notification['voip'] = $this->voip; 307 | } 308 | 309 | if (count($notification) > 0) { 310 | $payload['notification'] = $notification; 311 | } 312 | 313 | if (!is_null($this->message)) { 314 | $payload['message'] = $this->message; 315 | } 316 | if (!array_key_exists('notification', $payload) && !array_key_exists('message', $payload)) { 317 | throw new InvalidArgumentException('notification and message can not all be null'); 318 | } 319 | 320 | if (!is_null($this->smsMessage)) { 321 | $payload['sms_message'] = $this->smsMessage; 322 | } 323 | 324 | if (is_null($this->options)) { 325 | $this->options(); 326 | } 327 | 328 | $payload['options'] = $this->options; 329 | 330 | if (!is_null($this->custom)) { 331 | foreach($this->custom as $key=>$val) { 332 | $payload[$key] = $val; 333 | } 334 | } 335 | 336 | return $payload; 337 | } 338 | 339 | public function toJSON() { 340 | $payload = $this->build(); 341 | return json_encode($payload); 342 | } 343 | 344 | public function printJSON() { 345 | echo $this->toJSON(); 346 | return $this; 347 | } 348 | 349 | public function send() { 350 | return Http::post($this->client, $this->url, $this->build()); 351 | } 352 | 353 | public function validate() { 354 | $url = $this->client->makeURL('push') . '/push/validate'; 355 | return Http::post($this->client, $url, $this->build()); 356 | } 357 | 358 | private function generateSendno() { 359 | return rand(100000, getrandmax()); 360 | } 361 | 362 | # new methods 363 | public function iosNotification($alert = '', array $notification = array()) { 364 | $ios = array(); 365 | $ios['alert'] = (is_string($alert) || is_array($alert)) ? $alert : ''; 366 | if (!empty($notification)) { 367 | if (isset($notification['sound'])) { 368 | if (is_string($notification['sound']) || is_array($notification['sound'])) { 369 | $ios['sound'] = $notification['sound']; 370 | } else { 371 | unset($notification['sound']); 372 | } 373 | } 374 | if (isset($notification['content-available'])) { 375 | if (is_bool($notification['content-available'])) { 376 | $ios['content-available'] = $notification['content-available']; 377 | } else { 378 | unset($notification['content-available']); 379 | } 380 | } 381 | if (isset($notification['mutable-content'])) { 382 | if (is_bool($notification['mutable-content'])) { 383 | $ios['mutable-content'] = $notification['mutable-content']; 384 | } else { 385 | unset($notification['mutable-content']); 386 | } 387 | } 388 | if (isset($notification['extras'])) { 389 | if (is_array($notification['extras']) && !empty($notification['extras'])) { 390 | $ios['extras'] = $notification['extras']; 391 | } else { 392 | unset($notification['extras']); 393 | } 394 | } 395 | $ios = array_merge($notification, $ios); 396 | } 397 | if (!isset($ios['sound'])) { 398 | $ios['sound'] = ''; 399 | } 400 | if (!isset($ios['badge'])) { 401 | $ios['badge'] = '+1'; 402 | } 403 | $this->iosNotification = $ios; 404 | return $this; 405 | } 406 | 407 | public function androidNotification($alert = '', array $notification = array()) { 408 | $android = array(); 409 | $android['alert'] = is_string($alert) ? $alert : ''; 410 | if (!empty($notification)) { 411 | if (isset($notification['builder_id'])) { 412 | if (is_int($notification['builder_id'])) { 413 | $android['builder_id'] = $notification['builder_id']; 414 | } else { 415 | unset($notification['builder_id']); 416 | } 417 | } 418 | if (isset($notification['priority'])) { 419 | if (is_int($notification['priority'])) { 420 | $android['priority'] = $notification['priority']; 421 | } else { 422 | unset($notification['priority']); 423 | } 424 | } 425 | if (isset($notification['style'])) { 426 | if (is_int($notification['style'])) { 427 | $android['style'] = $notification['style']; 428 | } else { 429 | unset($notification['style']); 430 | } 431 | } 432 | if (isset($notification['alert_type'])) { 433 | if (is_int($notification['alert_type'])) { 434 | $android['alert_type'] = $notification['alert_type']; 435 | } else { 436 | unset($notification['alert_type']); 437 | } 438 | } 439 | if (isset($notification['inbox'])) { 440 | if (is_array($notification['inbox']) && !empty($notification['inbox'])) { 441 | $android['inbox'] = $notification['inbox']; 442 | } else { 443 | unset($notification['inbox']); 444 | } 445 | } 446 | if (isset($notification['intent'])) { 447 | if (is_array($notification['intent']) && !empty($notification['intent'])) { 448 | $android['intent'] = $notification['intent']; 449 | } else { 450 | unset($notification['intent']); 451 | } 452 | } 453 | if (isset($notification['extras'])) { 454 | if (is_array($notification['extras']) && !empty($notification['extras'])) { 455 | $android['extras'] = $notification['extras']; 456 | } else { 457 | unset($notification['extras']); 458 | } 459 | } 460 | $android = array_merge($notification, $android); 461 | } 462 | $this->androidNotification = $android; 463 | return $this; 464 | } 465 | 466 | public function hmosNotification($alert = '', $category='', array $notification = array()) { 467 | $hmos = array(); 468 | $hmos['alert'] = is_string($alert) ? $alert : ''; 469 | $hmos['category'] = is_string($category) ? $category : ''; 470 | if (!empty($notification)) { 471 | if (isset($notification['badge_add_num'])) { 472 | if (is_int($notification['badge_add_num']) && $notification['badge_add_num'] >= 1 && $notification['badge_add_num']<=99) { 473 | $hmos['badge_add_num'] = $notification['badge_add_num']; 474 | } else { 475 | unset($notification['badge_add_num']); 476 | } 477 | } 478 | if (isset($notification['test_message'])) { 479 | if (is_bool($notification['test_message'])) { 480 | $hmos['test_message'] = $notification['test_message']; 481 | } else { 482 | unset($notification['test_message']); 483 | } 484 | } 485 | if (isset($notification['intent'])) { 486 | if (is_array($notification['intent']) && !empty($notification['intent'])) { 487 | $hmos['intent'] = $notification['intent']; 488 | } else { 489 | unset($notification['intent']); 490 | } 491 | } 492 | if (isset($notification['extras'])) { 493 | if (is_array($notification['extras']) && !empty($notification['extras'])) { 494 | $hmos['extras'] = $notification['extras']; 495 | } else { 496 | unset($notification['extras']); 497 | } 498 | } 499 | if ($hmos['category'] === '' && isset($notification['category'])) { 500 | if (is_string($notification['category']) && $notification['category'] !== '') { 501 | $hmos['category'] = $notification['category']; 502 | } 503 | } 504 | $hmos = array_merge($notification, $hmos); 505 | } 506 | $this->hmosNotification = $hmos; 507 | return $this; 508 | } 509 | 510 | /** 511 | * Voip in notification 512 | * could add any custom key/value into it 513 | */ 514 | public function voip (array $extras = array()) { 515 | $voip = array(); 516 | if(!empty($extras)) { 517 | foreach($extras as $key=>$val) { 518 | $voip[$key] = $val; 519 | } 520 | } 521 | $voip = array_merge($extras, $voip); 522 | $this->voip=$voip; 523 | return $this; 524 | } 525 | 526 | public function message($msg_content, array $msg = array()) { 527 | # $required_keys = array('title', 'content_type', 'extras'); 528 | if (is_string($msg_content)) { 529 | $message = array(); 530 | $message['msg_content'] = $msg_content; 531 | if (!empty($msg)) { 532 | if (isset($msg['title']) && is_string($msg['title'])) { 533 | $message['title'] = $msg['title']; 534 | } 535 | if (isset($msg['content_type']) && is_string($msg['content_type'])) { 536 | $message['content_type'] = $msg['content_type']; 537 | } 538 | if (isset($msg['extras']) && is_array($msg['extras']) && !empty($msg['extras'])) { 539 | $message['extras'] = $msg['extras']; 540 | } 541 | } 542 | $this->message = $message; 543 | } 544 | return $this; 545 | } 546 | 547 | public function options(array $opts = array()) { 548 | # $required_keys = array('sendno', 'time_to_live', 'override_msg_id', 'apns_production', 'apns_collapse_id', 'big_push_duration'); 549 | $options = array(); 550 | if (isset($opts['sendno'])) { 551 | $options['sendno'] = $opts['sendno']; 552 | } else { 553 | $options['sendno'] = $this->generateSendno(); 554 | } 555 | if (isset($opts['time_to_live']) && $opts['time_to_live'] <= 864000 && $opts['time_to_live'] >= 0) { 556 | $options['time_to_live'] = $opts['time_to_live']; 557 | } 558 | if (isset($opts['override_msg_id'])) { 559 | $options['override_msg_id'] = $opts['override_msg_id']; 560 | } 561 | if (isset($opts['apns_production'])) { 562 | $options['apns_production'] = (bool)$opts['apns_production']; 563 | } else { 564 | $options['apns_production'] = false; 565 | } 566 | if (isset($opts['apns_collapse_id'])) { 567 | $options['apns_collapse_id'] = $opts['apns_collapse_id']; 568 | } 569 | if (isset($opts['big_push_duration']) && $opts['big_push_duration'] <= 1400 && $opts['big_push_duration'] >= 0) { 570 | $options['big_push_duration'] = $opts['big_push_duration']; 571 | } 572 | $options = array_merge($opts, $options); 573 | $this->options = $options; 574 | 575 | return $this; 576 | } 577 | 578 | public function custom (array $extras = array()) { 579 | if(!empty($extras)) { 580 | $this->custom=$extras; 581 | } 582 | return $this; 583 | } 584 | 585 | ############################################################################### 586 | ############# 以下函数已过期,不推荐使用,仅作为兼容接口存在 ######################### 587 | ############################################################################### 588 | public function addIosNotification($alert=null, $sound=null, $badge=null, $content_available=null, $category=null, $extras=null) { 589 | $ios = array(); 590 | 591 | if (!is_null($alert)) { 592 | if (!is_string($alert) && !is_array($alert)) { 593 | throw new InvalidArgumentException("Invalid ios alert value"); 594 | } 595 | $ios['alert'] = $alert; 596 | } 597 | 598 | if (!is_null($sound)) { 599 | if (!is_string($sound)) { 600 | throw new InvalidArgumentException("Invalid ios sound value"); 601 | } 602 | if ($sound !== Config::DISABLE_SOUND) { 603 | $ios['sound'] = $sound; 604 | } 605 | } else { 606 | // 默认sound为'' 607 | $ios['sound'] = ''; 608 | } 609 | 610 | if (!is_null($badge)) { 611 | if (is_string($badge) && !preg_match("/^[+-]{1}[0-9]{1,3}$/", $badge)) { 612 | if (!is_int($badge)) { 613 | throw new InvalidArgumentException("Invalid ios badge value"); 614 | } 615 | } 616 | if ($badge != Config::DISABLE_BADGE) { 617 | $ios['badge'] = $badge; 618 | } 619 | } else { 620 | // 默认badge为'+1' 621 | $ios['badge'] = '+1'; 622 | } 623 | 624 | if (!is_null($content_available)) { 625 | if (!is_bool($content_available)) { 626 | throw new InvalidArgumentException("Invalid ios content-available value"); 627 | } 628 | $ios['content-available'] = $content_available; 629 | } 630 | 631 | if (!is_null($category)) { 632 | if (!is_string($category)) { 633 | throw new InvalidArgumentException("Invalid ios category value"); 634 | } 635 | if (strlen($category)) { 636 | $ios['category'] = $category; 637 | } 638 | } 639 | 640 | if (!is_null($extras)) { 641 | if (!is_array($extras)) { 642 | throw new InvalidArgumentException("Invalid ios extras value"); 643 | } 644 | if (count($extras) > 0) { 645 | $ios['extras'] = $extras; 646 | } 647 | } 648 | 649 | if (count($ios) <= 0) { 650 | throw new InvalidArgumentException("Invalid iOS notification"); 651 | } 652 | 653 | $this->iosNotification = $ios; 654 | return $this; 655 | } 656 | 657 | public function addAndroidNotification($alert=null, $title=null, $builderId=null, $extras=null) { 658 | $android = array(); 659 | 660 | if (!is_null($alert)) { 661 | if (!is_string($alert)) { 662 | throw new InvalidArgumentException("Invalid android alert value"); 663 | } 664 | $android['alert'] = $alert; 665 | } 666 | 667 | if (!is_null($title)) { 668 | if(!is_string($title)) { 669 | throw new InvalidArgumentException("Invalid android title value"); 670 | } 671 | if(strlen($title) > 0) { 672 | $android['title'] = $title; 673 | } 674 | } 675 | 676 | if (!is_null($builderId)) { 677 | if (!is_int($builderId)) { 678 | throw new InvalidArgumentException("Invalid android builder_id value"); 679 | } 680 | $android['builder_id'] = $builderId; 681 | } 682 | 683 | if (!is_null($extras)) { 684 | if (!is_array($extras)) { 685 | throw new InvalidArgumentException("Invalid android extras value"); 686 | } 687 | if (count($extras) > 0) { 688 | $android['extras'] = $extras; 689 | } 690 | } 691 | 692 | if (count($android) <= 0) { 693 | throw new InvalidArgumentException("Invalid android notification"); 694 | } 695 | 696 | $this->androidNotification = $android; 697 | return $this; 698 | } 699 | 700 | public function setMessage($msg_content, $title=null, $content_type=null, $extras=null) { 701 | $message = array(); 702 | 703 | if (is_null($msg_content) || !is_string($msg_content)) { 704 | throw new InvalidArgumentException("Invalid message content"); 705 | } else { 706 | $message['msg_content'] = $msg_content; 707 | } 708 | 709 | if (!is_null($title)) { 710 | if (!is_string($title)) { 711 | throw new InvalidArgumentException("Invalid message title"); 712 | } 713 | $message['title'] = $title; 714 | } 715 | 716 | if (!is_null($content_type)) { 717 | if (!is_string($content_type)) { 718 | throw new InvalidArgumentException("Invalid message content type"); 719 | } 720 | $message["content_type"] = $content_type; 721 | } 722 | 723 | if (!is_null($extras)) { 724 | if (!is_array($extras)) { 725 | throw new InvalidArgumentException("Invalid message extras"); 726 | } 727 | if (count($extras) > 0) { 728 | $message['extras'] = $extras; 729 | } 730 | } 731 | 732 | $this->message = $message; 733 | return $this; 734 | } 735 | 736 | public function setSmsMessage($smsMessage) { 737 | $this->smsMessage = $smsMessage; 738 | return $this; 739 | } 740 | 741 | public function setOptions($sendno=null, $time_to_live=null, $override_msg_id=null, $apns_production=null, $big_push_duration=null) { 742 | $options = array(); 743 | 744 | if (!is_null($sendno)) { 745 | if (!is_int($sendno)) { 746 | throw new InvalidArgumentException('Invalid option sendno'); 747 | } 748 | $options['sendno'] = $sendno; 749 | } else { 750 | $options['sendno'] = $this->generateSendno(); 751 | } 752 | 753 | if (!is_null($time_to_live)) { 754 | if (!is_int($time_to_live) || $time_to_live < 0 || $time_to_live > 864000) { 755 | throw new InvalidArgumentException('Invalid option time to live, it must be a int and in [0, 864000]'); 756 | } 757 | $options['time_to_live'] = $time_to_live; 758 | } 759 | 760 | if (!is_null($override_msg_id)) { 761 | if (!is_long($override_msg_id)) { 762 | throw new InvalidArgumentException('Invalid option override msg id'); 763 | } 764 | $options['override_msg_id'] = $override_msg_id; 765 | } 766 | 767 | if (!is_null($apns_production)) { 768 | if (!is_bool($apns_production)) { 769 | throw new InvalidArgumentException('Invalid option apns production'); 770 | } 771 | $options['apns_production'] = $apns_production; 772 | } else { 773 | $options['apns_production'] = false; 774 | } 775 | 776 | if (!is_null($big_push_duration)) { 777 | if (!is_int($big_push_duration) || $big_push_duration < 0 || $big_push_duration > 1440) { 778 | throw new InvalidArgumentException('Invalid option big push duration, it must be a int and in [0, 1440]'); 779 | } 780 | $options['big_push_duration'] = $big_push_duration; 781 | } 782 | 783 | $this->options = $options; 784 | return $this; 785 | } 786 | 787 | /* 788 | 针对RegID方式批量单推 789 | https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/#vip 790 | */ 791 | public function batchPushByRegid(array $singlePayloads) { 792 | $body = array( 793 | "pushlist"=>array() 794 | ); 795 | $response = $this -> getCid(count($singlePayloads), 'push'); 796 | $cidlist = $response['body']['cidlist']; 797 | foreach ($cidlist as $i => $cid) { 798 | $body["pushlist"][$cid] = $singlePayloads[$i]; 799 | } 800 | $url = $this->client->makeURL('push') . 'push/batch/regid/single'; 801 | return Http::post($this->client, $url, $body); 802 | } 803 | 804 | /* 805 | 针对Alias方式批量单推 806 | https://docs.jiguang.cn/jpush/server/push/rest_api_v3_push/#vip 807 | */ 808 | public function batchPushByAlias(array $singlePayloads) { 809 | $body = array( 810 | "pushlist"=>array() 811 | ); 812 | $response = $this -> getCid(count($singlePayloads), 'push'); 813 | $cidlist = $response['body']['cidlist']; 814 | foreach ($cidlist as $i => $cid) { 815 | $body["pushlist"][$cid] = $singlePayloads[$i]; 816 | } 817 | $url = $this->client->makeURL('push') . 'push/batch/alias/single'; 818 | return Http::post($this->client, $url, $body); 819 | } 820 | } 821 | -------------------------------------------------------------------------------- /src/JPush/ReportPayload.php: -------------------------------------------------------------------------------- 1 | client = $client; 17 | } 18 | 19 | public function getReceived($msgIds) { 20 | $queryParams = '?msg_ids='; 21 | if (is_array($msgIds) && !empty($msgIds)) { 22 | $msgIdsStr = implode(',', $msgIds); 23 | $queryParams .= $msgIdsStr; 24 | } elseif (is_string($msgIds)) { 25 | $queryParams .= $msgIds; 26 | } else { 27 | throw new InvalidArgumentException("Invalid msg_ids"); 28 | } 29 | 30 | $url = $this->client->makeURL('report') . 'received' . $queryParams; 31 | return Http::get($this->client, $url); 32 | } 33 | 34 | /* 35 | 送达统计详情(新) 36 | https://docs.jiguang.cn/jpush/server/push/rest_api_v3_report/#_7 37 | */ 38 | public function getReceivedDetail($msgIds) { 39 | $queryParams = '?msg_ids='; 40 | if (is_array($msgIds) && !empty($msgIds)) { 41 | $msgIdsStr = implode(',', $msgIds); 42 | $queryParams .= $msgIdsStr; 43 | } elseif (is_string($msgIds)) { 44 | $queryParams .= $msgIds; 45 | } else { 46 | throw new InvalidArgumentException("Invalid msg_ids"); 47 | } 48 | 49 | $url = $this->client->makeURL('report') . 'received/detail' . $queryParams; 50 | return Http::get($this->client, $url); 51 | } 52 | 53 | public function getMessageStatus($msgId, $rids, $data = null) { 54 | $url = $this->client->makeURL('report') . 'status/message'; 55 | $registrationIds = is_array($rids) ? $rids : array($rids); 56 | $body = [ 57 | 'msg_id' => $msgId, 58 | 'registration_ids' => $registrationIds 59 | ]; 60 | if (!is_null($data)) { 61 | $body['data'] = $data; 62 | } 63 | return Http::post($this->client, $url, $body); 64 | } 65 | 66 | public function getMessages($msgIds) { 67 | $queryParams = '?msg_ids='; 68 | if (is_array($msgIds) && !empty($msgIds)) { 69 | $msgIdsStr = implode(',', $msgIds); 70 | $queryParams .= $msgIdsStr; 71 | } elseif (is_string($msgIds)) { 72 | $queryParams .= $msgIds; 73 | } else { 74 | throw new InvalidArgumentException("Invalid msg_ids"); 75 | } 76 | 77 | $url = $this->client->makeURL('report') . 'messages/' .$queryParams; 78 | return Http::get($this->client, $url); 79 | } 80 | 81 | /* 82 | 消息统计详情(VIP 专属接口,新) 83 | https://docs.jiguang.cn/jpush/server/push/rest_api_v3_report/#vip_1 84 | */ 85 | public function getMessagesDetail($msgIds) { 86 | $queryParams = '?msg_ids='; 87 | if (is_array($msgIds) && !empty($msgIds)) { 88 | $msgIdsStr = implode(',', $msgIds); 89 | $queryParams .= $msgIdsStr; 90 | } elseif (is_string($msgIds)) { 91 | $queryParams .= $msgIds; 92 | } else { 93 | throw new InvalidArgumentException("Invalid msg_ids"); 94 | } 95 | 96 | $url = $this->client->makeURL('report') . 'messages/detail' .$queryParams; 97 | return Http::get($this->client, $url); 98 | } 99 | 100 | public function getUsers($time_unit, $start, $duration) { 101 | $time_unit = strtoupper($time_unit); 102 | if (!in_array($time_unit, self::$EFFECTIVE_TIME_UNIT)) { 103 | throw new InvalidArgumentException('Invalid time unit'); 104 | } 105 | 106 | $url = $this->client->makeURL('report') . 'users/?time_unit=' . $time_unit . '&start=' . $start . '&duration=' . $duration; 107 | return Http::get($this->client, $url); 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /src/JPush/SchedulePayload.php: -------------------------------------------------------------------------------- 1 | client = $client; 15 | } 16 | 17 | public function createSingleSchedule($name, $push_payload, $trigger) { 18 | if (!is_string($name)) { 19 | throw new InvalidArgumentException('Invalid schedule name'); 20 | } 21 | if (!is_array($push_payload)) { 22 | throw new InvalidArgumentException('Invalid schedule push payload'); 23 | } 24 | if (!is_array($trigger)) { 25 | throw new InvalidArgumentException('Invalid schedule trigger'); 26 | } 27 | $payload = array(); 28 | $payload['name'] = $name; 29 | $payload['enabled'] = true; 30 | $payload['trigger'] = array("single"=>$trigger); 31 | $payload['push'] = $push_payload; 32 | 33 | $url = $this->client->makeURL('schedule'); 34 | return Http::post($this->client, $url, $payload); 35 | } 36 | 37 | public function createPeriodicalSchedule($name, $push_payload, $trigger) { 38 | if (!is_string($name)) { 39 | throw new InvalidArgumentException('Invalid schedule name'); 40 | } 41 | if (!is_array($push_payload)) { 42 | throw new InvalidArgumentException('Invalid schedule push payload'); 43 | } 44 | if (!is_array($trigger)) { 45 | throw new InvalidArgumentException('Invalid schedule trigger'); 46 | } 47 | $payload = array(); 48 | $payload['name'] = $name; 49 | $payload['enabled'] = true; 50 | $payload['trigger'] = array("periodical"=>$trigger); 51 | $payload['push'] = $push_payload; 52 | 53 | $url = $this->client->makeURL('schedule'); 54 | return Http::post($this->client, $url, $payload); 55 | } 56 | 57 | public function updateSingleSchedule($schedule_id, $name=null, $enabled=null, $push_payload=null, $trigger=null) { 58 | if (!is_string($schedule_id)) { 59 | throw new InvalidArgumentException('Invalid schedule id'); 60 | } 61 | $payload = array(); 62 | if (!is_null($name)) { 63 | if (!is_string($name)) { 64 | throw new InvalidArgumentException('Invalid schedule name'); 65 | } else { 66 | $payload['name'] = $name; 67 | } 68 | } 69 | 70 | if (!is_null($enabled)) { 71 | if (!is_bool($enabled)) { 72 | throw new InvalidArgumentException('Invalid schedule enable'); 73 | } else { 74 | $payload['enabled'] = $enabled; 75 | } 76 | } 77 | 78 | if (!is_null($push_payload)) { 79 | if (!is_array($push_payload)) { 80 | throw new InvalidArgumentException('Invalid schedule push payload'); 81 | } else { 82 | $payload['push'] = $push_payload; 83 | } 84 | } 85 | 86 | if (!is_null($trigger)) { 87 | if (!is_array($trigger)) { 88 | throw new InvalidArgumentException('Invalid schedule trigger'); 89 | } else { 90 | $payload['trigger'] = array("single"=>$trigger); 91 | } 92 | } 93 | 94 | if (count($payload) <= 0) { 95 | throw new InvalidArgumentException('Invalid schedule, name, enabled, trigger, push can not all be null'); 96 | } 97 | 98 | $url = $this->client->makeURL('schedule') . "/" . $schedule_id; 99 | 100 | return Http::put($this->client, $url, $payload); 101 | 102 | } 103 | 104 | public function updatePeriodicalSchedule($schedule_id, $name=null, $enabled=null, $push_payload=null, $trigger=null) { 105 | if (!is_string($schedule_id)) { 106 | throw new InvalidArgumentException('Invalid schedule id'); 107 | } 108 | $payload = array(); 109 | if (!is_null($name)) { 110 | if (!is_string($name)) { 111 | throw new InvalidArgumentException('Invalid schedule name'); 112 | } else { 113 | $payload['name'] = $name; 114 | } 115 | } 116 | 117 | if (!is_null($enabled)) { 118 | if (!is_bool($enabled)) { 119 | throw new InvalidArgumentException('Invalid schedule enable'); 120 | } else { 121 | $payload['enabled'] = $enabled; 122 | } 123 | } 124 | 125 | if (!is_null($push_payload)) { 126 | if (!is_array($push_payload)) { 127 | throw new InvalidArgumentException('Invalid schedule push payload'); 128 | } else { 129 | $payload['push'] = $push_payload; 130 | } 131 | } 132 | 133 | if (!is_null($trigger)) { 134 | if (!is_array($trigger)) { 135 | throw new InvalidArgumentException('Invalid schedule trigger'); 136 | } else { 137 | $payload['trigger'] = array("periodical"=>$trigger); 138 | } 139 | } 140 | 141 | if (count($payload) <= 0) { 142 | throw new InvalidArgumentException('Invalid schedule, name, enabled, trigger, push can not all be null'); 143 | } 144 | 145 | $url = $this->client->makeURL('schedule') . "/" . $schedule_id; 146 | return Http::put($this->client, $url, $payload); 147 | } 148 | 149 | public function getSchedules($page = 1) { 150 | if (!is_int($page)) { 151 | $page = 1; 152 | } 153 | $url = $this->client->makeURL('schedule') . "?page=" . $page; 154 | return Http::get($this->client, $url); 155 | } 156 | 157 | public function getSchedule($schedule_id) { 158 | if (!is_string($schedule_id)) { 159 | throw new InvalidArgumentException('Invalid schedule id'); 160 | } 161 | $url = $this->client->makeURL('schedule') . "/" . $schedule_id; 162 | return Http::get($this->client, $url); 163 | } 164 | 165 | public function deleteSchedule($schedule_id) { 166 | if (!is_string($schedule_id)) { 167 | throw new InvalidArgumentException('Invalid schedule id'); 168 | } 169 | $url = $this->client->makeURL('schedule') . "/" . $schedule_id; 170 | return Http::delete($this->client, $url); 171 | } 172 | 173 | public function getMsgIds($schedule_id) { 174 | if (!is_string($schedule_id)) { 175 | throw new InvalidArgumentException('Invalid schedule id'); 176 | } 177 | $url = $this->client->makeURL('schedule') . '/' . $schedule_id . '/msg_ids'; 178 | return Http::get($this->client, $url); 179 | } 180 | 181 | } 182 | 183 | -------------------------------------------------------------------------------- /src/JPush/version.php: -------------------------------------------------------------------------------- 1 | device = $client->device(); 10 | $this->test_tag = 'jpush_tag'; 11 | } 12 | 13 | function testGetDevices() { 14 | global $registration_id; 15 | $response = $this->device->getDevices($registration_id); 16 | $this->assertEquals('200', $response['http_code']); 17 | 18 | echo "HTTP HEADERS ARE: "; 19 | print_r($response['headers']); 20 | 21 | $body = $response['body']; 22 | $this->assertTrue(is_array($body)); 23 | $this->assertEquals(3, count($body)); 24 | $this->assertArrayHasKey('tags', $body); 25 | $this->assertArrayHasKey('alias', $body); 26 | $this->assertArrayHasKey('mobile', $body); 27 | $this->assertTrue(is_array($body['tags'])); 28 | } 29 | 30 | /** 31 | * @expectedException \JPush\Exceptions\APIRequestException 32 | * @expectedExceptionCode 7002 33 | */ 34 | function testGetDevicesWithInvalidRid() { 35 | $response = $this->device->getDevices('INVALID_REGISTRATION_ID'); 36 | } 37 | 38 | function testUpdateDevicesAlias() { 39 | global $registration_id; 40 | $result = $this->device->getDevices($registration_id); 41 | $old_alias = $result['body']['alias']; 42 | if ($old_alias == null) { 43 | $old_alias = ''; 44 | } 45 | $new_alias = 'jpush_alias'; 46 | if ($old_alias == $new_alias) { 47 | $new_alias = $new_alias . time(); 48 | } 49 | $response = $this->device->updateAlias($registration_id, $new_alias); 50 | $this->assertEquals('200', $response['http_code']); 51 | 52 | $response = $this->device->updateAlias($registration_id, $old_alias); 53 | $this->assertEquals('200', $response['http_code']); 54 | } 55 | 56 | function testUpdateDevicesTags() { 57 | global $registration_id; 58 | $new_tag = $this->test_tag; 59 | 60 | $response = $this->device->addTags($registration_id, array($new_tag)); 61 | $this->assertEquals('200', $response['http_code']); 62 | 63 | $response = $this->device->removeTags($registration_id, array($new_tag)); 64 | $this->assertEquals('200', $response['http_code']); 65 | } 66 | 67 | function testGetTags() { 68 | $response = $this->device->getTags(); 69 | $this->assertEquals('200', $response['http_code']); 70 | 71 | $body = $response['body']; 72 | $this->assertTrue(is_array($body)); 73 | $this->assertEquals(1, count($body)); 74 | $this->assertArrayHasKey('tags', $body); 75 | } 76 | 77 | function testIsDeviceInTag() { 78 | global $registration_id; 79 | $test_tag = $this->test_tag; 80 | 81 | $this->device->addTags($registration_id, array($test_tag)); 82 | $response = $this->device->isDeviceInTag($registration_id, $test_tag); 83 | $this->assertEquals('200', $response['http_code']); 84 | $body = $response['body']; 85 | $this->assertTrue(is_array($body)); 86 | $this->assertTrue($body['result']); 87 | 88 | $this->device->removeTags($registration_id, array($test_tag)); 89 | $response = $this->device->isDeviceInTag($registration_id, $test_tag); 90 | $this->assertEquals('200', $response['http_code']); 91 | $body = $response['body']; 92 | $this->assertTrue(is_array($body)); 93 | $this->assertFalse($body['result']); 94 | } 95 | 96 | function testUpdateTag() { 97 | global $registration_id; 98 | $test_tag = $this->test_tag; 99 | 100 | $response = $this->device->addDevicesToTag($test_tag, array($registration_id)); 101 | $this->assertEquals('200', $response['http_code']); 102 | 103 | $response = $this->device->removeDevicesFromTag($test_tag, array($registration_id)); 104 | $this->assertEquals('200', $response['http_code']); 105 | } 106 | 107 | function testDeleteTag() {} 108 | 109 | function testGetAliasDevices() { 110 | $test_tag = $this->test_tag; 111 | 112 | $response = $this->device->getAliasDevices($test_tag); 113 | $this->assertEquals('200', $response['http_code']); 114 | $body = $response['body']; 115 | $this->assertTrue(is_array($body)); 116 | $this->assertEquals(1, count($body)); 117 | $this->assertArrayHasKey('registration_ids', $body); 118 | } 119 | 120 | function testDeleteAlias() {} 121 | 122 | function testGetDevicesStatus() { 123 | global $registration_id; 124 | $response = $this->device->getDevicesStatus($registration_id); 125 | $this->assertEquals('200', $response['http_code']); 126 | $body = $response['body']; 127 | $this->assertTrue(is_array($body)); 128 | $this->assertEquals(1, count($body)); 129 | } 130 | 131 | } 132 | -------------------------------------------------------------------------------- /tests/JPush/PushPayloadTest.php: -------------------------------------------------------------------------------- 1 | payload = $client->push() 10 | ->setPlatform('all') 11 | ->addAllAudience() 12 | ->setNotificationAlert('Hello JPush'); 13 | 14 | $this->payload_without_audience = $client->push() 15 | ->setPlatform('all') 16 | ->setNotificationAlert('Hello JPush'); 17 | } 18 | 19 | public function testSimplePushToAll() { 20 | $payload = $this->payload; 21 | $result = $payload->build(); 22 | 23 | $this->assertTrue(is_array($result)); 24 | $this->assertEquals(4, count($result)); 25 | $this->assertArrayHasKey('platform', $result); 26 | $this->assertArrayHasKey('audience', $result); 27 | $this->assertArrayHasKey('notification', $result); 28 | $this->assertArrayHasKey('options', $result); 29 | } 30 | 31 | public function testSetPlatform() { 32 | $payload = $this->payload; 33 | 34 | $result = $payload->build(); 35 | $this->assertEquals('all', $result['platform']); 36 | 37 | $result = $payload->setPlatform('ios')->build(); 38 | $this->assertTrue(is_array($result['platform'])); 39 | $this->assertEquals(1, count($result['platform'])); 40 | $this->assertTrue(in_array('ios', $result['platform'])); 41 | 42 | $result = $payload->setPlatform(array('ios', 'android', 'blackberry'))->build(); 43 | $this->assertTrue(is_array($result['platform'])); 44 | $this->assertEquals(2, count($result['platform'])); 45 | $this->assertFalse(in_array('blackberry', $result['platform'])); 46 | } 47 | 48 | public function testSetAudience() { 49 | $result = $this->payload->build(); 50 | $this->assertEquals('all', $result['audience']); 51 | } 52 | 53 | public function testAddTag() { 54 | $payload = $this->payload_without_audience; 55 | $result = $payload->addTag('hello')->build(); 56 | $audience = $result['audience']; 57 | $this->assertTrue(is_array($audience['tag'])); 58 | $this->assertEquals(1, count($audience['tag'])); 59 | 60 | $result = $payload->addTag(array('jpush', 'jiguang'))->build(); 61 | $this->assertEquals(3, count($result['audience']['tag'])); 62 | } 63 | public function testAddTag2() { 64 | $payload = $this->payload_without_audience; 65 | $result = $payload->addTagAnd(array('jpush', 'jiguang'))->build(); 66 | $audience = $result['audience']; 67 | $this->assertTrue(is_array($audience['tag_and'])); 68 | $this->assertEquals(2, count($audience['tag_and'])); 69 | 70 | $result = $payload->addTagAnd('hello')->build(); 71 | $this->assertEquals(3, count($result['audience']['tag_and'])); 72 | } 73 | 74 | public function testAddTagAnd1() { 75 | $payload = $this->payload_without_audience; 76 | $result = $payload->addTagAnd('hello')->build(); 77 | $audience = $result['audience']; 78 | $this->assertTrue(is_array($audience['tag_and'])); 79 | $this->assertEquals(1, count($audience['tag_and'])); 80 | 81 | $result = $payload->addTagAnd(array('jpush', 'jiguang'))->build(); 82 | $this->assertEquals(3, count($result['audience']['tag_and'])); 83 | } 84 | public function testAddTagAnd2() { 85 | $payload = $this->payload_without_audience; 86 | $result = $payload->addTagAnd(array('jpush', 'jiguang'))->build(); 87 | $audience = $result['audience']; 88 | $this->assertTrue(is_array($audience['tag_and'])); 89 | $this->assertEquals(2, count($audience['tag_and'])); 90 | 91 | $result = $payload->addTagAnd('hello')->build(); 92 | $this->assertEquals(3, count($result['audience']['tag_and'])); 93 | } 94 | 95 | public function testAddRegistrationId1() { 96 | $payload = $this->payload_without_audience; 97 | $result = $payload->addRegistrationId('hello')->build(); 98 | $audience = $result['audience']; 99 | $this->assertTrue(is_array($audience['registration_id'])); 100 | $this->assertEquals(1, count($audience['registration_id'])); 101 | 102 | $result = $payload->addRegistrationId(array('jpush', 'jiguang'))->build(); 103 | $this->assertEquals(3, count($result['audience']['registration_id'])); 104 | } 105 | public function testAddRegistrationId2() { 106 | $payload = $this->payload_without_audience; 107 | $result = $payload->addRegistrationId(array('jpush', 'jiguang'))->build(); 108 | $audience = $result['audience']; 109 | $this->assertTrue(is_array($audience['registration_id'])); 110 | $this->assertEquals(2, count($audience['registration_id'])); 111 | 112 | $result = $payload->addRegistrationId('hello')->build(); 113 | $this->assertEquals(3, count($result['audience']['registration_id'])); 114 | } 115 | 116 | public function testSetNotificationAlert() { 117 | $result = $this->payload->build(); 118 | $notification = $result['notification']; 119 | $this->assertTrue(is_array($notification)); 120 | $this->assertEquals(1, count($notification)); 121 | $this->assertEquals('Hello JPush', $result['notification']['alert']); 122 | } 123 | 124 | public function testIosNotification() { 125 | $payload = $this->payload; 126 | $result = $payload->iosNotification()->build(); 127 | $ios = $result['notification']['ios']; 128 | $this->assertTrue(is_array($ios)); 129 | $this->assertEquals(3, count($ios)); 130 | $this->assertArrayHasKey('alert', $ios); 131 | $this->assertArrayHasKey('sound', $ios); 132 | $this->assertArrayHasKey('badge', $ios); 133 | $this->assertEquals('', $ios['alert']); 134 | $this->assertEquals('', $ios['sound']); 135 | $this->assertEquals('+1', $ios['badge']); 136 | 137 | $result = $payload->iosNotification('hello')->build(); 138 | $ios = $result['notification']['ios']; 139 | $this->assertEquals('hello', $result['notification']['ios']['alert']); 140 | } 141 | public function testIosNotificationWithArray() { 142 | $payload = $this->payload; 143 | $alert_array = array( 144 | 'alert_k1' => 'alert_v1', 145 | 'alert_k2' => 'alert_v2', 146 | 'alert_k3' => 'alert_v3', 147 | 'alert_k4' => 'alert_v4' 148 | ); 149 | $array = array( 150 | 'sound' => 'jpush.caf', 151 | 'badge' => 2, 152 | 'content-available' => true, 153 | 'category' => 'jiguang', 154 | 'extras' => array( 155 | 'key' => 'value', 156 | 'jiguang' 157 | ), 158 | 'invalid_key' => 'invalid_value' 159 | ); 160 | $result = $payload->iosNotification($alert_array, $array)->build(); 161 | $ios = $result['notification']['ios']; 162 | $this->assertTrue(is_array($ios['alert'])); 163 | $this->assertEquals(6, count($ios)); 164 | $this->assertFalse(array_key_exists('invalid_key', $ios)); 165 | } 166 | 167 | public function testAndroidNotification() { 168 | $payload = $this->payload; 169 | $result = $payload->androidNotification()->build(); 170 | $android = $result['notification']['android']; 171 | $this->assertTrue(is_array($android)); 172 | $this->assertEquals(1, count($android)); 173 | $this->assertArrayHasKey('alert', $android); 174 | $this->assertEquals('', $android['alert']); 175 | 176 | $result = $payload->androidNotification('hello')->build(); 177 | $android = $result['notification']['android']; 178 | $this->assertEquals('hello', $result['notification']['android']['alert']); 179 | } 180 | public function testAndroidNotificationWithArray() { 181 | $payload = $this->payload; 182 | $array = array( 183 | 'title' => 'hello jpush', 184 | 'builder_id' => 2, 185 | 'extras' => array( 186 | 'key' => 'value', 187 | 'jiguang' 188 | ), 189 | 'invalid_key' => 'invalid_value' 190 | ); 191 | $result = $payload->androidNotification('', $array)->build(); 192 | $android = $result['notification']['android']; 193 | $this->assertEquals(4, count($android)); 194 | $this->assertFalse(array_key_exists('invalid_key', $android)); 195 | } 196 | 197 | public function testSetSmsMessage() { 198 | $payload = $this->payload; 199 | $smsMessage = array( 200 | 'delay_time' => 60, 201 | 'signid' => 154, 202 | 'temp_id' => 1, 203 | 'temp_para' => array( 204 | 'code' => 357 205 | ), 206 | 'active_filter' => false 207 | ); 208 | $result = $payload->setSmsMessage($smsMessage)->build(); 209 | $sms = $result['sms_message']; 210 | $this->assertTrue(is_array($sms)); 211 | $this->assertEquals(5, count($sms)); 212 | $this->assertEquals(60, $sms['delay_time']); 213 | $this->assertEquals(154, $sms['signid']); 214 | $this->assertEquals(1, $sms['temp_id']); 215 | } 216 | 217 | public function testMessage() { 218 | $payload = $this->payload; 219 | $result = $payload->message('Hello JPush')->build(); 220 | $message = $result['message']; 221 | $this->assertTrue(is_array($message)); 222 | $this->assertEquals(1, count($message)); 223 | $this->assertEquals('Hello JPush', $message['msg_content']); 224 | 225 | $array = array( 226 | 'title' => 'hello jpush', 227 | 'content_type' => '', 228 | 'extras' => array( 229 | 'key' => 'value', 230 | 'jiguang' 231 | ), 232 | 'invalid_key' => 'invalid_value' 233 | ); 234 | $result = $payload->message('Hello JPush', $array)->build(); 235 | } 236 | 237 | public function testOptions() { 238 | $payload = $this->payload; 239 | $result = $payload->options()->build(); 240 | $this->assertTrue(array_key_exists('options', $result)); 241 | $this->assertEquals(false, $result['options']['apns_production']); 242 | $this->assertTrue(array_key_exists('sendno', $result['options'])); 243 | 244 | $array = array( 245 | 'sendno' => 100, 246 | 'time_to_live' => 100, 247 | 'apns_production' => true, 248 | 'override_msg_id' => 100, 249 | 'big_push_duration' => 100 250 | ); 251 | $result = $payload->options($array)->build(); 252 | $options = $result['options']; 253 | $this->assertEquals(5, count($options)); 254 | $this->assertArrayHasKey('apns_production', $options); 255 | $this->assertEquals(true, $options['apns_production']); 256 | } 257 | 258 | public function testPushToAll() { 259 | $payload = $this->payload; 260 | $platform = array('ios', 'android', 'blackberry'); 261 | $ios_alert = array( 262 | 'k1' => 'v1', 263 | 'k2' => 'v2', 264 | 'k3' => 'v3', 265 | 'k4' => 'v4' 266 | ); 267 | $ios_notification = array( 268 | 'sound' => 'jpush.caf', 269 | 'badge' => 2, 270 | 'content-available' => true, 271 | 'category' => 'jiguang', 272 | 'extras' => array( 273 | 'key' => 'value', 274 | 'jiguang' 275 | ), 276 | 'invalid_key' => 'invalid_value' 277 | ); 278 | $android_notification = array( 279 | 'title' => 'hello jpush', 280 | 'builder_id' => 2, 281 | 'extras' => array( 282 | 'key' => 'value', 283 | 'jiguang' 284 | ), 285 | 'invalid_key' => 'invalid_value' 286 | ); 287 | $message = array( 288 | 'title' => 'hello jpush', 289 | 'content_type' => '', 290 | 'extras' => array( 291 | 'key' => 'value', 292 | 'jiguang' 293 | ), 294 | 'invalid_key' => 'invalid_value' 295 | ); 296 | 297 | $result = $payload->setPlatform($platform) 298 | ->iosNotification($ios_alert, $ios_notification) 299 | ->androidNotification('Hello Android', $android_notification) 300 | ->message('Hello JPush', $message) 301 | ->build(); 302 | 303 | $response = $payload->send(); 304 | $this->assertEquals('200', $response['http_code']); 305 | 306 | echo "HTTP HEADERS ARE: "; 307 | print_r($response['headers']); 308 | 309 | $body = $response['body']; 310 | $this->assertTrue(is_array($body)); 311 | $this->assertEquals(2, count($body)); 312 | $this->assertArrayHasKey('sendno', $body); 313 | $this->assertArrayHasKey('msg_id', $body); 314 | } 315 | } 316 | -------------------------------------------------------------------------------- /tests/JPush/ReportPayloadTest.php: -------------------------------------------------------------------------------- 1 | payload = $client->push() 10 | ->setPlatform('all') 11 | ->addAllAudience() 12 | ->setNotificationAlert('Hello JPush'); 13 | $this->reporter = $client->report(); 14 | } 15 | 16 | public function testPusher0() { 17 | $payload = $this->payload; 18 | $response = $payload->send(); 19 | 20 | $this->assertEquals('200', $response['http_code']); 21 | $body = $response['body']; 22 | $this->assertTrue(is_array($body)); 23 | $this->assertEquals(2, count($body)); 24 | $this->assertArrayHasKey('sendno', $body); 25 | $this->assertArrayHasKey('msg_id', $body); 26 | sleep(10); 27 | return $body['msg_id']; 28 | } 29 | public function testPusher1() { 30 | $payload = $this->payload; 31 | $response = $payload->send(); 32 | $this->assertEquals('200', $response['http_code']); 33 | sleep(10); 34 | return $response['body']['msg_id']; 35 | } 36 | 37 | /** 38 | * @depends testPusher0 39 | * @depends testPusher1 40 | */ 41 | public function testGetReceived($msg_id_0, $msg_id_1) { 42 | $response = $this->reporter->getReceived($msg_id_0); 43 | $this->assertEquals('200', $response['http_code']); 44 | $body = $response['body']; 45 | $this->assertTrue(is_array($body)); 46 | $this->assertEquals(1, count($body)); 47 | $this->assertTrue(is_array($body[0])); 48 | $this->assertArrayHasKey('msg_id', $body[0]); 49 | 50 | $response = $this->reporter->getReceived(array($msg_id_0, $msg_id_1)); 51 | $this->assertEquals('200', $response['http_code']); 52 | $body = $response['body']; 53 | $this->assertTrue(is_array($body)); 54 | $this->assertEquals(2, count($body)); 55 | } 56 | 57 | /** 58 | * @depends testPusher0 59 | * @depends testPusher1 60 | */ 61 | public function testGetMessages($msg_id_0, $msg_id_1) { 62 | $response = $this->reporter->getMessages($msg_id_0); 63 | $this->assertEquals('200', $response['http_code']); 64 | $body = $response['body']; 65 | $this->assertTrue(is_array($body)); 66 | $this->assertEquals(1, count($body)); 67 | $this->assertTrue(is_array($body[0])); 68 | $this->assertEquals(4, count($body[0])); 69 | $this->assertArrayHasKey('msg_id', $body[0]); 70 | 71 | $response = $this->reporter->getMessages(array($msg_id_0, $msg_id_1)); 72 | $this->assertEquals('200', $response['http_code']); 73 | $body = $response['body']; 74 | $this->assertTrue(is_array($body)); 75 | $this->assertEquals(2, count($body)); 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /tests/JPush/SchedulePayloadTest.php: -------------------------------------------------------------------------------- 1 | schedule = $client->schedule(); 10 | } 11 | 12 | public function testGetSchedules() { 13 | $schedule = $this->schedule; 14 | $response = $schedule->getSchedules(); 15 | $this->assertEquals('200', $response['http_code']); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /tests/bootstrap.php: -------------------------------------------------------------------------------- 1 |