<?php
/**
* APP消息推送類
* 默認爲極光推送
* @update 支持同時向多個app推送 sugang 2014-7-19
* @update 增加個推www.getui.com sugang 2015-1-5
* 增加多平臺推送,同時推送jpush和getui 2014-1-6
* @update 增加通知和消息的轉化和開關,如把個推通知轉到消息去,即用消息推送。如關閉個推通知。 sugang 2014-1-7
* @update 優化一些函數和調用方式 sugang 2015-3-28
* @update 增加appId,個推推送時需要指定 sugang 2015-7-25
**/
class AppPush {
private $appId; // App Id
private $appKey; // App Key
private $secretKey; // Secret Key
private $initParams; // 其它參數
private $pushType = ''; // 推送類型,通知或消息
private $pushPlatUse = 'jpush'; // 當前使用的api平臺
private $productCode = 'yl1001'; // 當前使用的產品
private $pushPlatArr = array('jpush','baidu','yl1001','getui'); // 使用的平臺
private $pushAppNum = 0; // 推送多個app時的當前推送
private $pushAppNumTotal = 0; // 推送多個app時的推送總次數
private $pushPlatNum = 0; // 當前推送的平臺編號
private $pushPlatNumTotal = 0; // 當前推送的平臺總數
private $pushPlatUses = ''; // pushPlateUse記錄當前使用的平臺,pushPlatUsers記錄需要推送的平臺
private $debug = false; // 是否開啓調試信息
// 個推平臺的參數
private $gt_host = 'http://sdk.open.api.igexin.com/apiex.htm';
private $gt_appId = ''; // 已使用appId替換,應爲個推推送多個app時,每個appId不同
// 不同平臺,使用不同的字符集
private $pushCharset = array(
'jpush' => 'utf-8',
'baidu' => 'utf-8',
'yl1001' => 'gbk',
'getui' => 'utf-8',
);
// 不同平臺,不同產品的key
private $keyArr = array(
'jpush' => array(
'yl1001' => array(
array(
'app_key' => '',
'secret_key'=> '',
),
array( // 只推送給ios
'app_key' => '',
'secret_key'=> '',
),
),
'moyuan' => array(
'app_key' => '',
'secret_key'=> '',
),
),
'baidu' => array(
'yl1001' => array(
'app_key' => '',
'secret_key'=> '',
),
),
'getui' => array(
'yl1001' => array(
array(
'app_id' => '', // AppID
'app_key' => '', // AppKey
'secret_key'=> '', // MasterSecret
),
// array( // 用於測試app,不用上傳到線上
// 'app_id' => '',
// 'app_key' => '',
// 'secret_key'=> '', // MasterSecret
// )
)
),
);
/**
* 構造函數,初始化傳入的參數、推送的key、推送類
* @param String $pushPlatUse
* @param String $appKey
* @param String $secretKey
* @param Array $initParams
*/
public function __construct($initParams = array()) {
// 參數設置
if ( $initParams['pushPlatUse'] ) {
$this->pushPlatUse = $initParams['pushPlatUse'];
}
if ( $initParams['productCode'] ) {
$this->productCode = $initParams['productCode'];
}
if ( $initParams['appId'] ) {
$this->appId = $initParams['appId'];
}
if ( $initParams['appKey'] ) {
$this->appKey = $initParams['appKey'];
}
if ( $initParams['secretKey'] ) {
$this->secretKey = $initParams['secretKey'];
}
// 調試
if( $_SESSION['dugabcd'] == 1 ){
$this->debug = true;
}
if ( isset($initParams['debug']) ) {
$this->debug = $initParams['debug'];
}
unset($initParams['pushPlatUse']);
unset($initParams['productCode']);
unset($initParams['appKey']);
unset($initParams['secretKey']);
// 其他參數
if ( $initParams ) {
$this->initParams = $initParams;
}
// 處理多平臺推送
if ( $this->pushPlatUse ) {
$this->pushPlatUses = explode(',', $this->pushPlatUse);
$this->pushPlatUses = array_unique($this->pushPlatUses);
// 設置當前使用的平臺,因爲傳進來的時候可能是多個平臺
$this->pushPlatUse = $this->pushPlatUses[0];
$this->pushPlatNumTotal = count($this->pushPlatUses);
}
// 初始化key
$this->initPushKey();
// 初始化推送類
$this->initPushClass();
}
/**
* 檢查當前使用的平臺是否合法
**/
public function checkPushPlat() {
if ( !array_key_exists($this->pushPlatUse, $this->pushPlatArr) ) {
return false;
}
return true;
}
/**
* 初始化key,key的定義見變量$keyArr
**/
public function initPushKey() {
if ( $this->pushPlatUse && $this->productCode ) {
// 是否存在定義的平臺
if ( array_key_exists($this->pushPlatUse, $this->keyArr) ) {
// 是否存在定義的產品
if ( array_key_exists($this->productCode, $this->keyArr[$this->pushPlatUse]) ) {
$keyArr = $this->keyArr[$this->pushPlatUse][$this->productCode];
// key可能是二維數組,表示需要推送給多個app
if ( !$keyArr['app_key'] && is_array($keyArr[$this->pushAppNum]) ) {
$this->pushAppNumTotal = count($keyArr);
// 初始化當前需要推送的app的key
$this->appId = $keyArr[$this->pushAppNum]['app_id'];
$this->appKey = $keyArr[$this->pushAppNum]['app_key'];
$this->secretKey= $keyArr[$this->pushAppNum]['secret_key'];
} else {
$this->appId = $keyArr['app_id'];
$this->appKey = $keyArr['app_key'];
$this->secretKey= $keyArr['secret_key'];
}
}
}
}
}
/**
* 加載不同平臺需要的類
* @notice 切換不同的平臺推送時需要調用
**/
public function initPushClass() {
switch( $this->pushPlatUse ) {
case 'jpush':
// 極光推送
include_once dirname(__FILE__) . '/lib/jpush/JPushClient.php';
break;
case 'baidu':
// 百度雲推送
include_once dirname(__FILE__) . '/lib/baidu/Channel.class.php';
break;
case 'yl1001':
// 一覽推送
include_once dirname(__FILE__) . '/lib/yl1001/Yl1001Push.php';
break;
case 'getui':
// 個推
include_once dirname(__FILE__) . '/lib/getui/IGt.Push.php';
break;
}
}
/**
* 初始化推送對象
* 處理initParams的其他參數,如離線時長、設備類型
* @notice 切換不同的平臺推送時需要調用
**/
public function initPushObject() {
switch( $this->pushPlatUse ) {
case 'jpush':
if ( !isset($this->initParams['time_to_live']) ) {
$this->initParams['time_to_live'] = 86400; // 離線時長:1天
}
if ( !isset($this->initParams['platform']) ) {
$this->initParams['platform'] = ''; // android,ios
}
if ( !isset($this->initParams['apns_production']) ) {
$this->initParams['apns_production']= false; // APNS 通知發送環境 false開發環境 true生產環境
}
$pushObj = new JPushClient($this->appKey,$this->secretKey, $this->initParams['time_to_live'], $this->initParams['platform'], $this->initParams['apns_production']);
break;
case 'baidu':
if ( !isset($this->initParams['arr_curlOpts']) ) {
$this->initParams['arr_curlOpts'] = array();
}
$pushObj = new Channel($this->appKey, $this->secretKey, $this->initParams['arr_curlOpts']);
break;
case 'yl1001':
if ( !isset($this->initParams['platform']) ) {
$this->initParams['platform'] = ''; // android,ios
}
$pushObj = new Yl1001Push($this->initParams);
break;
case 'getui':
if ( !isset($this->initParams['time_to_live']) ) {
$this->initParams['time_to_live'] = 86400 * 1000; // 離線時長:1天,個推使用的毫秒
}
if ( !isset($this->initParams['platform']) ) {
$this->initParams['platform'] = ''; // android,ios
}
$pushObj = new IGeTui($this->gt_host,$this->appKey,$this->secretKey);
break;
}
return $pushObj;
}
/**
* 初始化默認參數
* 默認爲廣播
* @params array 用戶參數參數
* @extras array 擴展參數列表
**/
public function initPushParam(&$params, &$extras) {
$default_params = array();
$default_extras = array();
$params = is_array($params) ? $params : array();
$extras = is_array($extras) ? $extras : array();
switch( $this->pushPlatUse ) {
case 'jpush':
// 極光推送
$default_params['receiver_type'] = 4; // 接收者類型:4廣播
$default_params['receiver_value'] = ' '; // 廣播不用填寫
$default_params['sendno'] = time(); // 發送編號(最大支持32位正整數(即 4294967295 ))
$default_params['send_description'] = ''; // 描述此次發送調用
$default_params['override_msg_id'] = ''; // 覆蓋的上一條消息的 ID
if( $this->initParams['platform']=='' || strpos($this->initParams['platform'], 'ios')!==false ){
// ios處理
$default_extras['ios']['badge'] = 1;
$default_extras['ios']['sound'] = 'default';
}
break;
case 'baidu':
// 百度雲推送
break;
case 'getui':
// 個推
if( $this->initParams['platform']=='' || strpos($this->initParams['platform'], 'ios')!==false ){
// ios處理
$default_extras['ios']['badge'] = 1;
$default_extras['ios']['sound'] = 'default';
}
break;
}
$params = $params + $default_params;
$extras = $extras + $default_extras;
}
/**
* 通過此方法判斷是否需要多平臺推送
* @notice 該方法判斷時必須保證當前平臺下面的多個app推送完成後,才能進行下一個平臺的推送
* @author sugang
* @date 2015-1-6
**/
public function multiPlatPush() {
// 當前平臺下的多個App推送是否完成,如果沒完成不能進入下一個平臺的推送
if ( $this->pushAppNum != ($this->pushAppNumTotal - 1) ) {
return false;
}
if ( $this->pushPlatNum < ($this->pushPlatNumTotal - 1) ) {
// 初始化不同平臺需要的東西(key,pushObj等)
$this->pushPlatNum++; // 切換下一個平臺
$this->pushAppNum = 0; // 切換平臺後,app推送從頭開始
// 定義當前使用的平臺
$this->pushPlatUse = $this->pushPlatUses[$this->pushPlatNum];
// class
$this->initPushClass();
// Key
$this->initPushKey();
// Object
$this->initPushObject();
return true;
}
return false;
}
/**
* 通過此方法判斷是否需要推送給多個app(重構之前的功能、之前沒有進行封裝)
* @author sugang
* @date 2015-1-7
**/
public function multiAppPush() {
if ( $this->pushAppNum < ($this->pushAppNumTotal - 1) ) {
$this->pushAppNum++; // 切換下一個app
// Key
$this->initPushKey(); // 同一平臺的不同app推送,只需重新初始化Key
return true;
}
return false;
}
/**
* 推送通知或消息時需要重置推送平臺,推送app
* @notice 當同時推送通知和消息時,通知推送完畢後,需要重置推送平臺和app(從頭開始再依次推送)
* @author sugang
* @date 2015-7-29
**/
public function multiTypePush() {
// 多平臺,多app推送完了,表示此事通知或者消息通知完畢了,要消息或通知了
if ( $this->pushAppNum == ($this->pushAppNumTotal - 1) && $this->pushPlatNum == ($this->pushPlatNumTotal - 1) ) {
$this->pushAppNum = 0;
$this->pushPlatNum = 0;
// 定義當前使用的平臺
$this->pushPlatUse = $this->pushPlatUses[$this->pushPlatNum];
// class
$this->initPushClass();
// Key
$this->initPushKey();
// Object
$this->initPushObject();
}
}
/**
* 輸出調試信息,方便調試
* @author sugang
* @date 2015-1-7
**/
public function debugInfo() {
if ( $this->debug ) {
echo '<br/>當前推送的信息---';
echo '<br/>推送類型:' . $this->pushType;
echo '<br/>推送平臺:' . $this->pushPlatUse;
echo '<br/>推送產品:' . $this->productCode;
echo '<br/>推送app序號(從0開始):' . $this->pushAppNum;
echo '<br/>當前使用的Key:' . $this->appId . ' / ' . $this->appKey . ' / ' . $this->secretKey;
echo '<br/><br/>';
}
}
/**
* 編碼轉換,默認輸入編碼爲gbk
**/
private function changeCode($param1,$param2) {
$argList = func_get_args();
$paramArr = array();
switch($this->pushCharset[$this->pushPlatUse]) {
case 'utf-8':
foreach($argList as $arg) {
$paramArr[] = iconv('gbk', 'utf-8', $arg);
}
break;
case 'gbk':
default:
foreach($argList as $arg) {
$paramArr[] = $arg;
}
break;
}
return $paramArr;
}
/**
* 某個時間段不進行推送
* @notice 注意,實際的推送方法中返回值需要做處理。直接在該方法中返回是可以避免推送,但是有些情況是:推送完後需要記錄在yl_app_push表中,該記錄的狀態是根據推送返回結果來判斷的,如果沒有返回結果,默認的推送記錄狀態爲“未推送”,在定時推送程序中還會進行推送。
* @author sugang
* @date 2015-4-25
**/
public function filterTimePush() {
$hour = date('H');
// 23點開始,早上8點結束
if ( $hour<8 || $hour>=23 ) {
return false;
}
return true;
}
/**
* 推送通知
* @param $title 推送通知的標題(客戶端接收的內容)
* @param $content 推送通知的內容(客戶端接收的內容)
* @param $params 推送的配置參數
* @param $extras 推送的擴展內容(客戶端接收的內容)
**/
public function sendNotice($title, $content, $params, $extras = array()) {
if ( !$this->filterTimePush() ) {
return array('status'=>'FORBID');
}
$this->pushType = 'notice';
/// 用於多次推送
$_title = $title;
$_content = $content;
$_params = $params;
$_extras = $extras;
/////////////////////
// 編碼轉換
list($title, $content) = $this->changeCode($title, $content);
$pushObj = $this->initPushObject();
$this->initPushParam($params, $extras);
switch( $this->pushPlatUse ) {
case 'jpush':
// 過濾特殊字符
$title = $this->filterSpecialChar($title);
$content= $this->filterSpecialChar($content);
$extras = $this->filterSpecialChar($extras);
// 獲取合適長度的內容
$content= $this->getAppropriateLen($title, $content, $params, $extras, '1');
if( $params['receiver_type'] == '4' ) {
// 廣播
$result_tmp = $pushObj->sendNotification($title, $content, $params, $extras);
$result = $this->formatResult($result_tmp);
} else {
if( $params['receiver_type']=='2' ) {
// 標籤tag,一次支持10個標籤
$len = 10;
} else if( $params['receiver_type']=='3' || $params['receiver_type']=='5' ){
// 別名alias和RegistrationID,一次支持1000個
$len = 1000;
}
$receiverStr = $params['receiver_value'];
$receiverArr = $this->getAliasStringByStr($receiverStr, $len);
$result = array(
'status' => 'FAIL',
'code' => 0,
'status_desc' => '',
'info' => '',
);
foreach( $receiverArr as $receiver ){
$params['receiver_value'] = $receiver;
$result_tmp = $pushObj->sendNotification($title, $content, $params, $extras);
$result_tmp = $this->formatResult($result_tmp);
if( $result_tmp['status']=='OK' && $result['status']=='FAIL' ){
$result['status'] = 'OK';
$result['code'] = 200;
}
$result['info'][] = $result_tmp;
}
}
break;
case 'baidu':
// 推送類型,取值範圍爲:1~3 1:單個人 2:一羣人 3:所有人
$push_type = 3;
// 設備類型,取值範圍爲:1~5 1:瀏覽器設備;2:PC設備;3:Andriod設備;4:iOS設備;5:Windows Phone設備;
$optional[Channel::DEVICE_TYPE] = 3;
// 消息類型0:消息 1:通知
$optional[Channel::MESSAGE_TYPE]= 1;
//通知類型的內容必須按指定內容發送,示例如下:
$message = '{
"title": "test_push",
"description": "open url",
"notification_basic_style":7,
"open_type":1,
"url":"http://www.baidu.com"
}';
// 消息標識
$message_key= time();
$result = $pushObj->pushMessage( $push_type, $message, $message_key, $optional );
$result = $this->formatResult($result);
break;
case 'yl1001':
$title = $this->filterSpecialChar($title); // 過濾特殊字符
$content = $this->filterSpecialChar($content);// 過濾特殊字符
$result_tmp = $pushObj->send_note_by_user_id($title, $content, $params, $extras);
$result_tmp = $pushObj->send_note_by_device_token($title, $content, $params, $extras);
$result = array(
'status' => 'FAIL',
'code' => 0,
'status_desc' => '',
'info' => '',
);
foreach($result_tmp as $result_device){
foreach($result_device as $val){
$re_tmp = $this->formatResult($val);
$result['info'][] = $re_tmp;
if( $re_tmp['status']=='OK' ){
$result['status'] = 'OK';
$result['code'] = 200;
}
}
}
break;
case 'getui':
// 從極光推送中獲取個推的參數(之前的程序使用極光)
$this->gtParamFromJpush($params, $extras);
$templateType = $this->gtPushStatus('notice');
if ( $templateType ) {
$result_tmp = $this->gtPushMessage($params['gt_target'], $templateType, array(
'title' => $title,
'content' => $content,
'extras' => $extras,
),$pushObj);
$result = $this->formatResult($result_tmp);
}
break;
}
// 輸出本次推送的調試信息
$this->debugInfo();
// 是否進入下一個app推送
if ( $this->multiAppPush() ) {
$this->sendNotice($_title, $_content, $_params, $_extras);
}
// 是否進入下一個平臺推送
if ( $this->multiPlatPush() ) {
$this->sendNotice($_title, $_content, $_params, $_extras);
}
// 所有平臺,所有app的通知是否推送完畢
$this->multiTypePush();
return $result;
}
/**
* 推送消息(僅Android設備支持)
* @param $title 推送通知的標題(客戶端接收的內容)
* @param $content 推送通知的內容(客戶端接收的內容)
* @param $params 推送的配置參數
* @param $extras 推送的擴展內容(客戶端接收的內容)
* @update sugang 2015-7-20 之前推送完後,沒有調用下次推送
**/
public function sendMessage($title, $content, $params, $extras = array()) {
if ( !$this->filterTimePush() ) {
return array('status'=>'FORBID');
}
$this->pushType = 'message';
////// 多次推送通知後,消息只推送一個
// $this->pushAppNum = 0;
// $this->initPushKey();
//////
/// 用於多次推送
$_title = $title;
$_content = $content;
$_params = $params;
$_extras = $extras;
// 編碼轉換
list($title, $content) = $this->changeCode($title, $content);
$pushObj = $this->initPushObject();
$this->initPushParam($params, $extras);
switch( $this->pushPlatUse ) {
case 'jpush':
// 過濾特殊字符
$title = $this->filterSpecialChar($title);
$content= $this->filterSpecialChar($content);
$extras = $this->filterSpecialChar($extras);
if( $params['receiver_type'] == '4' ){
// 廣播
$result_tmp = $pushObj->sendCustomMessage($title, $content, $params, $extras);
$result = $this->formatResult($result_tmp);
} else {
if( $params['receiver_type']=='2' ){
// 標籤tag,一次支持10個標籤
$len = 10;
} else if( $params['receiver_type']=='3' || $params['receiver_type']=='5' ){
// 別名alias和RegistrationID,一次支持1000個
$len = 1000;
}
$receiverStr = $params['receiver_value'];
$receiverArr = $this->getAliasStringByStr($receiverStr, $len);
$result = array(
'status' => 'FAIL',
'code' => 0,
'status_desc' => '',
'info' => '',
);
foreach( $receiverArr as $receiver ){
$params['receiver_value'] = $receiver;
$result_tmp = $pushObj->sendCustomMessage($title, $content, $params, $extras);
$result_tmp = $this->formatResult($result_tmp);
if( $result_tmp['status']=='OK' && $result['status']=='FAIL' ){
$result['status'] = 'OK';
$result['code'] = 200;
}
$result['info'][] = $result_tmp;
}
}
break;
case 'baidu':
break;
case 'getui':
// 從極光推送中獲取個推的參數(之前的程序使用極光)
$this->gtParamFromJpush($params, $extras);
$templateType = $this->gtPushStatus('message');
if ( $templateType ) {
$result_tmp = $this->gtPushMessage($params['gt_target'],$templateType, array(
'title' => $title,
'content' => $content,
'extras' => $extras,
), $pushObj);
$result = $this->formatResult($result_tmp);
}
break;
}
$this->debugInfo();
// 是否進入下一個app推送
if ( $this->multiAppPush() ) {
$this->sendMessage($_title, $_content, $_params, $_extras);
}
// 是否進入下一個平臺推送
if ( $this->multiPlatPush() ) {
$this->sendMessage($_title, $_content, $_params, $_extras);
}
// 所有平臺,所有app的通知是否推送完畢
$this->multiTypePush();
return $result;
}
/**
* 統一處理返回值
**/
public function formatResult($result) {
switch( $this->pushPlatUse ) {
case 'jpush':
$status = 'FAIL';
$code = $result->getCode();
$status_desc = $result->getMessage();
if ($code == 0) { // 正確
$status = 'OK';
$code = 200;
}
$info = array(
'msgId' => $result->getMesId(),
'sendno' => $result->getSendno(),
'code' => $result->getCode(),
'message' => $result->getMessage(),
'responseContent' => $result->getResponseContent(),
);
break;
case 'baidu':
$status = 'FAIL';
$status_desc = '';
if ( $result['request_id'] ) {
$status = 'OK';
$code = 200;
}
$info = $result;
break;
case 'yl1001':
$status = 'FAIL';
$status_desc = '';
$code = 0;
$info = array();
if( $result==1 ){
$status = 'OK';
$code = 200;
}
break;
case 'getui':
$status = 'FAIL';
$code = 0;
$status_desc = $result['status'];
$info = array();
if ($result['result'] == 'ok') { // 正確
$status = 'OK';
$code = 200;
if ( $result['taskId'] ) {
$info['taskId'] = $result['taskId'];
}
if ( $result['contentId'] ) {
$info['contentId'] = $result['contentId'];
}
} else {
$status_desc = $result['result'];
}
break;
}
$result = array(
'status' => $status,
'code' => $code,
'status_desc' => $status_desc,
'info' => $info,
);
return $result;
}
/**
* 過濾特殊字符
* @param $str string/array 需要過濾的字符
* @param $exclude string/array 不過濾的字符串
**/
public function filterSpecialChar($str, $exclude = null) {
if( empty($str) ){
return $str;
}
// 非必須去除的特殊字符
$search_char = array(' ', '&', '"', ''', '“', '”', '—', '<', '>', '·', '…');
$replace_char = array(' ', '&', '"', "'", '“', '”', '—', '<', '>', '·', '…');
if( $exclude ) {
// 不過濾字符
if ( !is_array($exclude) ) {
$exclude = explode(',', $exclude);
}
foreach( $exclude as $val ){
$search_key = array_search($val, $search_char);
if( $search_key !== false ){
unset( $search_char[$search_key] );
unset( $replace_char[$search_key] );
}
}
}
// 必須去掉的字符
$search_char_must = array("\r", "\n", "\r\n", ';', '&');
$replace_char_must = array('', '', '', ";", '');
$search_char = array_merge($search_char, $search_char_must);
$replace_char = array_merge($replace_char, $replace_char_must);
// 進行替換
if ( is_array($str) ) {
foreach($str as $k=>$v) {
$str[$k] = $this->filterSpecialChar($v,$exclude);
}
} else {
$str = str_replace($search_char, $replace_char, $str);
}
return $str;
}
/**
* 獲取合適長度的內容
* @notice $content和$extras內容過長時,對$content進行截取
**/
public function getAppropriateLen($title, $content, $params, $extras, $type){
switch( $this->pushPlatUse ) {
case 'jpush':
if( $type == '1' ){
// 通知類型, 長度不超過220字節($content和$extras的總和)
$content_len = strlen($content);// 內容的長度
$extras_len = strlen(json_encode($extras));// 擴展內容的長度
$cut_len = $extras_len + $content_len - 220; // 要剪切的字節長度
if( $cut_len > 0 ){
// 如果cut_len值大於0,則表示內容需要截取
$str = mb_strcut($content, 0, $content_len-$cut_len, 'utf-8');
} else {
$str = $content;
}
} else {
// 消息類型,不得超過1000個字節
}
break;
case 'baidu':
break;
case 'getui':
if ( $type = '3' ) { // apns 256限制
$str = mb_strcut($content, 0, 150, 'utf-8');
}
break;
}
return $str;
}
/**
* 截取extras和content
**/
public function getAppropriateExtras($title, &$content, $params, &$extras, $type, $cut_arr){
switch( $this->pushPlatUse ) {
case 'jpush':
if( $this->initParams['platform']=='' || strpos($this->initParams['platform'], 'ios')!==false ){
// ios處理
$extras['ios'] = array(
'badge' => 1,
'sound' => 'default'
);
}
if( $this->pushCharset['jpush']=='utf-8' ){
if( !$this->checkStringIsUtf8($content) ){
$content = iconv('gbk', 'utf-8', $content);
$content_to_gbk = true;
}
foreach ($extras as $key => $value) {
if( !$this->checkStringIsUtf8($value) ){
$extras[$key] = iconv('gbk', 'utf-8', $value);
$extras_to_gbk = true;
}
}
}
if( $type == '1' ){
// 通知類型, 長度不超過220字節
// 計算長度
$content_len = strlen($content);// 內容的長度
$extras_len = strlen(json_encode($extras));// 擴展內容的長度
$cut_len = $extras_len + $content_len - 220; // 要剪切的字節長度
if( $cut_len > 0 ){
// 如果cut_len值大於0,則表示內容需要截取
if( !empty($cut_arr) ){
$cut_arr_count = count($cut_arr);
$e_val_len_c = ceil( $cut_len/$cut_arr_count ); // 如果傳入多個可截取值,則平均截取
// $e_val_len_c = $cut_arr_count==1 ? ceil( $cut_len/5*4 ) : $e_val_len_c;
foreach ($cut_arr as $key => $value) {
if( $cut_len<=0 ){
break;
}
$e_val_len = strlen($extras[$value]);
$extras[$value] = mb_strcut($extras[$value], 0, abs($e_val_len-$e_val_len_c)-1, 'utf-8').'...';
$cut_len -= $e_val_len_c;// 剩餘要截取的長度
}
}
}
} else {
// 消息類型,
}
if( $this->pushCharset['jpush']=='utf-8' ){
if( $this->checkStringIsUtf8($content) && $content_to_gbk==true ){
$content = iconv('utf-8', 'gbk', $content);
}
foreach ($extras as $key => $value) {
if( $this->checkStringIsUtf8($value) && $extras_to_gbk==true){
$extras[$key] = iconv('utf-8', 'gbk', $value);
}
}
}
unset($extras['ios']);
break;
case 'baidu':
break;
}
}
/**
* 剪切alias數組長度,默認1000個alias爲一個長度。
*/
public function getAliasStringByStr($str, $len = 1000) {
if ( empty($str) ) {
return array();
}
if ( !is_array($str) ) {
$aliasArr = explode(',', $str);
}
$aliasArr = array_unique($aliasArr);
$aliasArr = array_filter($aliasArr);
$aliasArr = array_chunk($aliasArr, $len);
$strArr = array();
foreach( $aliasArr as $data ) {
$strArr[] = implode(',', $data);
}
return $strArr;
}
/**
* 判斷字符串是否是utf-8編碼
**/
public function checkStringIsUtf8($str) {
$len = strlen($str);
for($i = 0; $i < $len; $i++) {
$c = ord($str[$i]);
if ($c > 128) {
if (($c > 247)) return false;
elseif ($c > 239) $bytes = 4;
elseif ($c > 223) $bytes = 3;
elseif ($c > 191) $bytes = 2;
else return false;
if (($i + $bytes) > $len) return false;
while ($bytes > 1) {
$i++;
$b = ord($str[$i]);
if ($b < 128 || $b > 191) return false;
$bytes--;
}
}
}
return true;
}
/////Start 個推方法////////////////////////////////////////////////////////////
/**
* 根據接收者調用不同的推送方法
* @param $targets string/array 接收者
* @param $templateType string 模板的類型
* @param $templateParam array 生成模板時的參數
* @author sugang
* @date 2015-1-6
**/
public function gtPushMessage($targets, $templateType, $templateParam = array(), $pushObj) {
// 通過接收人判斷推送方式
if ( $targets == '0' ) {
// 廣播
$type = 'app';
} else {
if ( !is_array($targets) ) {
$targets = explode(',', $targets);
}
if ( count($targets) == 1 ) {
$type = 'single';
} else {
$type = 'list';
}
}
// 不同的推送方法
if ( $type == 'app' ) {
$message = new IGtAppMessage();
} else if ( $type == 'list' ) {
$message = new IGtListMessage();
} else if ( $type == 'single' ){
$message = new IGtSingleMessage();
}
$template = $this->gtTemplateGenerate($templateType, $templateParam);
$message->set_isOffline(true); //是否離線
$message->set_offlineExpireTime(3600*12*1000); //離線時間
$message->set_data($template); //設置推送消息類型
$message->set_PushNetWorkType(0); //設置是否根據WIFI推送消息,1爲wifi推送,0爲不限制推送
if ( is_null($pushObj) || !($pushObj instanceof IGeTui) ) {
$pushObj = new IGeTui($this->gt_host,$this->appKey,$this->secretKey);
}
if ( $type == 'single' ) {
$targetList = $this->gtTargetGenerate($targets);
$pushResult = $pushObj->pushMessageToSingle($message, $targetList[0]);
} else if ( $type == 'list' ) {
$targetList = $this->gtTargetGenerate($targets);
$contentId = $pushObj->getContentId($message);
$pushResult = $pushObj->pushMessageToList($contentId, $targetList);
} else if ( $type == 'app' ) {
$message->set_appIdList(array($this->appId));
// $message->set_phoneTypeList(array('ANDROID')); // 只有薪聞是廣播,暫時先禁用 sugang 2015-7-7
// $message->set_provinceList(array('浙江','北京','河南'));
// $message->set_tagList(array('開心'));
$pushResult = $pushObj->pushMessageToApp($message);
}
return $pushResult;
}
/**
* 生成對應的推送模板
* @param $type string 模板類型
* @param $params array 各個模板需要的參數(此處應該要考慮默認值)
* @author sugang
* @date 2015-1-6
**/
public function gtTemplateGenerate($type, $params = array()) {
$title = $params['title'];
$content = $params['content'];
$logo = $params['logo'];
$url = $params['url'];
// 透傳內容
$extras = array();
if ( $params['extras'] ) {
$extras = $params['extras'];
}
$extras['title'] = $title;
$extras['content'] = $content;
$extras_json = json_encode($extras);
switch( $type ) {
case 'notice':
$template = new IGtNotificationTemplate();
$template->set_appId($this->appId); //應用appid
$template->set_appkey($this->appKey); //應用appkey
$template->set_transmissionType(2); //透傳消息類型,1啓動應用2等待(不啓動應用)
$template->set_transmissionContent($extras_json); //透傳內容
$template->set_title($title); //通知欄標題
$template->set_text($content); //通知欄內容
$template->set_logo($logo); //通知欄logo
$template->set_isRing(true); //是否響鈴
$template->set_isVibrate(true); //是否震動
$template->set_isClearable(true); //通知欄是否可清除
break;
case 'link':
$template = new IGtLinkTemplate();
$template ->set_appId($this->appId);
$template ->set_appkey($this->appKey);
$template ->set_title($title);
$template ->set_text($content);
$template ->set_logo($logo);
$template ->set_isRing(true);
$template ->set_isVibrate(true);
$template ->set_isClearable(true);
$template ->set_url($url); //打開連接地址
break;
case 'download':
$template = new IGtNotyPopLoadTemplate();
$template ->set_appId($this->appId);
$template ->set_appkey($this->appKey);
//通知欄
$template ->set_notyTitle($title); //通知欄標題
$template ->set_notyContent($content); //通知欄內容
$template ->set_notyIcon($logo); //通知欄logo
$template ->set_isBelled(true); //是否響鈴
$template ->set_isVibrationed(true); //是否震動
$template ->set_isCleared(true); //通知欄是否可清除
//彈框
$template ->set_popTitle($params['pop_title']); //彈框標題
$template ->set_popContent($params['pop_content']); //彈框內容
$template ->set_popImage($params['pop_image']); //彈框圖片
$template ->set_popButton1("下載"); //左鍵
$template ->set_popButton2("取消"); //右鍵
//下載
$template ->set_loadIcon($params['load_icon']); //下載圖標
$template ->set_loadTitle($params['load_title']); //下載標題
$template ->set_loadUrl($params['load_url']); //下載地址
$template ->set_isAutoInstall(false); //是否自動安裝
$template ->set_isActived(true); //安裝完成後是否自動啓動應用程序
break;
case 'message':
$template = new IGtTransmissionTemplate();
$template->set_appId($this->appId);
$template->set_appkey($this->appKey);
$template->set_transmissionType(2);
$template->set_transmissionContent($extras_json); //透傳內容
// ios特殊處理
$payload = array('type'=>$extras['type']);
if ( $extras['ios']['payload'] && is_array($extras['ios']['payload']) ) {
$payload = array_merge($payload, $extras['ios']['payload']);
}
$payload = json_encode($payload);
$content = $this->getAppropriateLen($title, $content, $params, $extras, '3');
// ios聲音特殊處理
$sound = 'default';
if ( $extras['ios']['sound'] ) {
$sound = $extras['ios']['sound'];
}
$template->set_pushInfo("","1","",$sound,$payload,$content,"","");
// $template->set_pushInfo("actionLocKey","badge","message","sound","payload","locKey","locArgs","launchImage");
break;
}
return $template;
}
/**
* 生成接收方
* @param $targets string/array 接收者標識,可以是客戶端ID或者別名
* @type $type string $targets標識的類型,client表示傳的客戶端ID,alias表示傳的別名
* @author sugang
* @date 2015-1-6
**/
public function gtTargetGenerate($targets, $type = 'alias') {
$targetList = array();
if ( !is_array($targets) ) {
$targets = explode(',', $targets);
}
foreach( $targets as $data ) {
$target = new IGtTarget();
$target->set_appId($this->appId);
if ( $type == 'client' ) {
$target->set_clientId($data);
} else if ( $type == 'alias' ) {
$target->set_alias($data);
}
$targetList[] = $target;
}
return $targetList;
}
/**
* 通過極光推送的相關參數得到個推的參數
* @author sugang
* @date 2015-1-6
**/
public function gtParamFromJpush(&$param, &$extras) {
if ( isset($param['receiver_type']) ) {
// 2標籤 3別名 4廣播 5註冊ID
if ( $param['receiver_type'] == 4 ) {
$param['gt_target'] = '0';
} else if ( isset($param['receiver_value']) ) {
$param['gt_target'] = $param['receiver_value'];
}
}
}
/**
* 通過個推的相關參數得到極光推送的參數
* @author sugang
* @date 2015-1-7
**/
public function jpushParamFromGt() {
if ( isset($param['gt_target']) ) {
// 2標籤 3別名 4廣播 5註冊ID
if ( $param['gt_target'] == '0' ) {
$param['receiver_type'] = '4';
$param['receiver_value']= '';
} else {
$param['receiver_type'] = '3';
$param['receiver_value']= $param['gt_target'];
}
}
}
/**
* 對個推推送增加開關和轉化參數控制
* @param $template string 個推的模板類型,notice通知,message消息
* @notice 通過構造函數中的initParams參數控制
* $initParams['gt_notice_switch'] 是否推送通知,true推送,false不推送
* $initParams['gt_notice_change'] 只能傳message,表示通知將使用消息的方式推送
* $initParams['gt_message_switch'] 是否推送消息,true推送,false不推送
* $initParams['gt_message_change'] 只能傳notice,表示消息將使用通知的方式推送
* @author sugang
* @date 2015-1-7
**/
public function gtPushStatus($template) {
if ( $template == 'notice' ) {
if ( isset($this->initParams['gt_notice_switch']) && !$this->initParams['gt_notice_switch'] ) {
return false;
}
if ( $this->initParams['gt_notice_change'] == 'message' ) {
return 'message';
}
} else {
if ( isset($this->initParams['gt_message_switch']) && !$this->initParams['gt_message_switch'] ) {
return false;
}
if ( $this->initParams['gt_message_switch'] == 'notice' ) {
return 'notice';
}
}
return $template;
}
/////End 個推方法////////////////////////////////////////////////////////////
}
?>
App推送程序
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.