├── .gitignore ├── README.md ├── autoload.php ├── composer.json ├── example ├── android_test.php └── ios_test.php └── src ├── Android ├── AndroidBroadcast.php ├── AndroidCustomizedcast.php ├── AndroidFilecast.php ├── AndroidGroupcast.php └── AndroidUnicast.php ├── AndroidNotification.php ├── Autoloader.php ├── IOSNotification.php ├── Ios ├── IOSBroadcast.php ├── IOSCustomizedcast.php ├── IOSFilecast.php ├── IOSGroupcast.php └── IOSUnicast.php ├── NotificationConfig.php ├── UmengNotification.php └── UmengNotifyApi.php /.gitignore: -------------------------------------------------------------------------------- 1 | .buildpath 2 | .settings/org.eclipse.php.debug.core.Debug_Process_Preferences.prefs 3 | .project 4 | .settings/org.eclipse.php.core.prefs -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # php-umeng-notification 2 | 3 | 友盟消息推送sdk,php-composer版,支持动态传参和链式操作,对官方的php包v1.4进行封装修改。代码格式基于psr2,autoload加载方式基于psr4。 4 | 5 | ## 使用方式 6 | 7 | 1. 下载源文件,通过require autoload.php引入 8 | 9 | 2. composer 方式加载,composer require "hacklee/umeng-notification" 10 | 11 | ## 具体使用参考example目录下的android_test.php和ios_test.php -------------------------------------------------------------------------------- /autoload.php: -------------------------------------------------------------------------------- 1 | 6 | * 7 | * For the full copyright and license information, please view the LICENSE 8 | * file that was distributed with this source code. 9 | */ 10 | require __DIR__ . '/src/Autoloader.php'; 11 | Hacklee\Umeng\Autoloader::register(); -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "hacklee/umeng-notification", 3 | "description": "umeng-notification,友盟推送,消息推送,php-notification", 4 | "license": "MIT", 5 | "homepage": "https://github.com/hacklee/php-umeng-notification", 6 | "type": "library", 7 | "authors": [ 8 | { 9 | "name": "hacklee", 10 | "email": "517184100@qq.com", 11 | "homepage": "http://lgy168.xyz" 12 | } 13 | ], 14 | "require": { 15 | "php": ">=5.5" 16 | }, 17 | "autoload": { 18 | "psr-4": { 19 | "Hacklee\\Umeng\\": "src/" 20 | } 21 | }, 22 | "minimum-stability": "dev", 23 | "prefer-stable": true 24 | } 25 | -------------------------------------------------------------------------------- /example/android_test.php: -------------------------------------------------------------------------------- 1 | setAndroidAfterOpen() 11 | ->setAndroidText('安卓自定义别名测试-text') 12 | ->setAndroidTitle('安卓自定义别名测试-title') 13 | ->setAndroidTicker('安卓自定义别名测试-ticker') 14 | ->setAlias('alias') 15 | ->setAliasType('aliasType') 16 | ->sendAndroidCustomizedcast(); 17 | 18 | // 广播,直接传数组方式调用 19 | $api->sendAndroidBroadcast([ 20 | 'ticker' => '安卓广播测试-ticker', 21 | 'title' => '安卓广播测试-title', 22 | 'text' => '安卓广播测试-text', 23 | 'after_open' => 'go_app' 24 | ], [ 25 | 'ext' => '扩展参数' 26 | ]); 27 | 28 | // 自定义传配置,new 对象 29 | $customizeApi = new UmengNotifyApi('android', 'app_key', 'app_secret', true); 30 | 31 | $customizeApi->setAndroidAfterOpen() 32 | ->setAndroidText('安卓单播测试-text') 33 | ->setAndroidTitle('安卓单播测试-title') 34 | ->setAndroidTicker('安卓单播测试-ticker') 35 | ->setDeviceTokens('tokens') 36 | ->sendAndroidUnicast(); 37 | 38 | // 组播 是利用filter条件进行刷选 39 | $filter = [ 40 | "where" => [ 41 | "and" => [ 42 | [ 43 | "tag" => "test" 44 | ] 45 | ] 46 | ] 47 | ]; 48 | $customizeApi->setOs('android') 49 | ->setAppKey('app_key') 50 | ->setAppMasterSecret('app_secret') 51 | ->sendAndroidGroupcast([ 52 | 'ticker' => '安卓组播测试-ticker', 53 | 'title' => '安卓组播测试-title', 54 | 'text' => '安卓组播测试-text', 55 | 'after_open' => 'go_app', 56 | 'filter' => $filter 57 | ]); 58 | 59 | // 文件播 60 | $api->setFileContent("test\ntest") 61 | ->setAndroidAfterOpen() 62 | ->setAndroidText('安卓文件播测试-text') 63 | ->setAndroidTitle('安卓文件播测试-title') 64 | ->setAndroidTicker('安卓文件播测试-ticker') 65 | ->sendAndroidFilecast(); -------------------------------------------------------------------------------- /example/ios_test.php: -------------------------------------------------------------------------------- 1 | setIosAlert('ios自定义别名测试-text') 11 | ->setIosBadge(0) 12 | ->setIosSound('chime') 13 | ->setAlias('alias') 14 | ->setAliasType('aliasType') 15 | ->sendIOSCustomizedcast(); 16 | 17 | // 广播,直接传数组方式调用 18 | $api->sendIOSBroadcast([ 19 | 'alert' => 'IOS广播测试-alert' 20 | ], [ 21 | 'ext' => '扩展参数' 22 | ]); 23 | 24 | // 自定义传配置,new 对象 25 | $customizeApi = new UmengNotifyApi('ios', 'app_key', 'app_secret', true); 26 | 27 | $customizeApi->setDeviceTokens('tokens') 28 | ->setIosAlert('IOS单播测试-alert') 29 | ->sendIOSUnicast(); 30 | 31 | // 组播 是利用filter条件进行刷选 32 | $filter = [ 33 | "where" => [ 34 | "and" => [ 35 | [ 36 | "tag" => "test" 37 | ] 38 | ] 39 | ] 40 | ]; 41 | $customizeApi->setOs('ios') 42 | ->setAppKey('app_key') 43 | ->setAppMasterSecret('app_secret') 44 | ->setFilter($filter) 45 | ->sendIOSGroupcast([ 46 | 'alert' => '安卓组播测试-ticker' 47 | ]); 48 | 49 | // 文件播 50 | $api->setFileContent("ios_file_content")->sendIOSFilecast([ 51 | 'alert' => 'IOS文件播测试-alert', 52 | 'badge' => 0, 53 | 'sound' => 'chime' 54 | ]); -------------------------------------------------------------------------------- /src/Android/AndroidBroadcast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "broadcast"; 14 | } 15 | } -------------------------------------------------------------------------------- /src/Android/AndroidCustomizedcast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "customizedcast"; 15 | $this->data["alias_type"] = NULL; 16 | } 17 | 18 | public function isComplete() 19 | { 20 | parent::isComplete(); 21 | if (! array_key_exists("alias", $this->data) && ! array_key_exists("file_id", $this->data)) 22 | throw new Exception("You need to set alias or upload file for customizedcast!"); 23 | } 24 | 25 | // Upload file with device_tokens or alias to Umeng 26 | public function uploadContents($content) 27 | { 28 | if ($this->data["appkey"] == NULL) 29 | throw new Exception("appkey should not be NULL!"); 30 | if ($this->data["timestamp"] == NULL) 31 | throw new Exception("timestamp should not be NULL!"); 32 | if (! is_string($content)) 33 | throw new Exception("content should be a string!"); 34 | 35 | $post = array( 36 | "appkey" => $this->data["appkey"], 37 | "timestamp" => $this->data["timestamp"], 38 | "content" => $content 39 | ); 40 | 41 | $postBody = json_encode($post); 42 | $url = $this->host . $this->uploadPath; 43 | $sign = md5("POST" . $url . $postBody . $this->appMasterSecret); 44 | $url = $url . "?sign=" . $sign; 45 | 46 | $ch = curl_init($url); 47 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 48 | curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 49 | curl_setopt($ch, CURLOPT_POST, 1); 50 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); 51 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 52 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post)); 53 | $result = curl_exec($ch); 54 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 55 | $curlErrNo = curl_errno($ch); 56 | $curlErr = curl_error($ch); 57 | curl_close($ch); 58 | 59 | if ($httpCode == "0") // time out 60 | throw new Exception("Curl error number:" . $curlErrNo . " , Curl error details:" . $curlErr . "\r\n"); 61 | else if ($httpCode != "200") // we did send the notifition out and got a non-200 response 62 | throw new Exception("http code:" . $httpCode . "\r\n" . "details:" . $result . "\r\n"); 63 | 64 | $returnData = json_decode($result, true); 65 | if ($returnData["ret"] == "FAIL") 66 | throw new Exception("Failed to upload file, details:" . $result . "\r\n"); 67 | else 68 | $this->data["file_id"] = $returnData["data"]["file_id"]; 69 | } 70 | 71 | public function getFileId() 72 | { 73 | if (array_key_exists("file_id", $this->data)) 74 | return $this->data["file_id"]; 75 | return NULL; 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /src/Android/AndroidFilecast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "filecast"; 15 | $this->data["file_id"] = NULL; 16 | } 17 | 18 | // return file_id if SUCCESS, else throw Exception with details. 19 | public function uploadContents($content) 20 | { 21 | if ($this->data["appkey"] == NULL) 22 | throw new Exception("appkey should not be NULL!"); 23 | if ($this->data["timestamp"] == NULL) 24 | throw new Exception("timestamp should not be NULL!"); 25 | if (! is_string($content)) 26 | throw new Exception("content should be a string!"); 27 | 28 | $post = array( 29 | "appkey" => $this->data["appkey"], 30 | "timestamp" => $this->data["timestamp"], 31 | "content" => $content 32 | ); 33 | $url = $this->host . $this->uploadPath; 34 | $postBody = json_encode($post); 35 | $sign = md5("POST" . $url . $postBody . $this->appMasterSecret); 36 | $url = $url . "?sign=" . $sign; 37 | $ch = curl_init($url); 38 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 39 | curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 40 | curl_setopt($ch, CURLOPT_POST, 1); 41 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); 42 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 43 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody); 44 | $result = curl_exec($ch); 45 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 46 | $curlErrNo = curl_errno($ch); 47 | $curlErr = curl_error($ch); 48 | curl_close($ch); 49 | //print($result . "\r\n"); 50 | if ($httpCode == "0") // time out 51 | throw new Exception("Curl error number:" . $curlErrNo . " , Curl error details:" . $curlErr . "\r\n"); 52 | else if ($httpCode != "200") // we did send the notifition out and got a non-200 response 53 | throw new Exception("http code:" . $httpCode . " details:" . $result . "\r\n"); 54 | $returnData = json_decode($result, TRUE); 55 | if ($returnData["ret"] == "FAIL") 56 | throw new Exception("Failed to upload file, details:" . $result . "\r\n"); 57 | else 58 | $this->data["file_id"] = $returnData["data"]["file_id"]; 59 | } 60 | 61 | public function getFileId() 62 | { 63 | if (array_key_exists("file_id", $this->data)) 64 | return $this->data["file_id"]; 65 | return NULL; 66 | } 67 | } -------------------------------------------------------------------------------- /src/Android/AndroidGroupcast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "groupcast"; 14 | $this->data["filter"] = NULL; 15 | } 16 | } -------------------------------------------------------------------------------- /src/Android/AndroidUnicast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "unicast"; 14 | $this->data["device_tokens"] = NULL; 15 | } 16 | } -------------------------------------------------------------------------------- /src/AndroidNotification.php: -------------------------------------------------------------------------------- 1 | "notification", 12 | "body" => [ 13 | "ticker" => NULL, 14 | "title" => NULL, 15 | "text" => NULL, 16 | "play_vibrate" => "true", 17 | "play_lights" => "true", 18 | "play_sound" => "true", 19 | "after_open" => NULL 20 | ] 21 | ]; 22 | // "extra" => array("key1" => "value1", "key2" => "value2") 23 | 24 | // Keys can be set in the payload level 25 | protected $PAYLOAD_KEYS = [ 26 | "display_type" 27 | ]; 28 | 29 | // Keys can be set in the body level 30 | protected $BODY_KEYS = [ 31 | "ticker", 32 | "title", 33 | "text", 34 | "builder_id", 35 | "icon", 36 | "largeIcon", 37 | "img", 38 | "play_vibrate", 39 | "play_lights", 40 | "play_sound", 41 | "after_open", 42 | "url", 43 | "activity", 44 | "custom" 45 | ]; 46 | 47 | public function __construct() 48 | { 49 | parent::__construct(); 50 | $this->data["payload"] = $this->androidPayload; 51 | } 52 | 53 | // Set key/value for $data array, for the keys which can be set please see $DATA_KEYS, $PAYLOAD_KEYS, $BODY_KEYS, $POLICY_KEYS 54 | public function setPredefinedKeyValue($key, $value) 55 | { 56 | if (! is_string($key)) 57 | throw new Exception("key should be a string!"); 58 | 59 | if (in_array($key, $this->DATA_KEYS)) { 60 | $this->data[$key] = $value; 61 | } else if (in_array($key, $this->PAYLOAD_KEYS)) { 62 | $this->data["payload"][$key] = $value; 63 | if ($key == "display_type" && $value == "message") { 64 | $this->data["payload"]["body"]["ticker"] = ""; 65 | $this->data["payload"]["body"]["title"] = ""; 66 | $this->data["payload"]["body"]["text"] = ""; 67 | $this->data["payload"]["body"]["after_open"] = ""; 68 | if (! array_key_exists("custom", $this->data["payload"]["body"])) { 69 | $this->data["payload"]["body"]["custom"] = NULL; 70 | } 71 | } 72 | } else if (in_array($key, $this->BODY_KEYS)) { 73 | $this->data["payload"]["body"][$key] = $value; 74 | if ($key == "after_open" && $value == "go_custom" && ! array_key_exists("custom", $this->data["payload"]["body"])) { 75 | $this->data["payload"]["body"]["custom"] = NULL; 76 | } 77 | } else if (in_array($key, $this->POLICY_KEYS)) { 78 | $this->data["policy"][$key] = $value; 79 | } else { 80 | if ($key == "payload" || $key == "body" || $key == "policy" || $key == "extra") { 81 | throw new Exception("You don't need to set value for ${key} , just set values for the sub keys in it."); 82 | } else { 83 | throw new Exception("Unknown key: ${key}"); 84 | } 85 | } 86 | } 87 | 88 | // Set extra key/value for Android notification 89 | public function setExtraField($key, $value) 90 | { 91 | if (! is_string($key)) 92 | throw new Exception("key should be a string!"); 93 | $this->data["payload"]["extra"][$key] = $value; 94 | } 95 | } -------------------------------------------------------------------------------- /src/Autoloader.php: -------------------------------------------------------------------------------- 1 | directory = $baseDirectory; 17 | $this->prefix = __NAMESPACE__ . '\\'; 18 | $this->prefixLength = strlen($this->prefix); 19 | } 20 | 21 | /** 22 | * Registers the autoloader class with the PHP SPL autoloader. 23 | * 24 | * @param bool $prepend Prepend the autoloader on the stack instead of appending it. 25 | */ 26 | public static function register($prepend = false) 27 | { 28 | spl_autoload_register(array(new self(), 'autoload'), true, $prepend); 29 | } 30 | 31 | /** 32 | * Loads a class from a file using its fully qualified name. 33 | * 34 | * @param string $className Fully qualified name of a class. 35 | */ 36 | public function autoload($className) 37 | { 38 | if (0 === strpos($className, $this->prefix)) { 39 | $parts = explode('\\', substr($className, $this->prefixLength)); 40 | $filepath = $this->directory . DIRECTORY_SEPARATOR . implode(DIRECTORY_SEPARATOR, $parts) . '.php'; 41 | if (is_file($filepath)) { 42 | require $filepath; 43 | } 44 | } 45 | } 46 | } -------------------------------------------------------------------------------- /src/IOSNotification.php: -------------------------------------------------------------------------------- 1 | [ 11 | "alert" => NULL 12 | ] 13 | ]; 14 | protected $APS_KEYS = [ 15 | "alert", 16 | "badge", 17 | "sound", 18 | "content-available" 19 | ]; 20 | 21 | public function __construct() 22 | { 23 | parent::__construct(); 24 | $this->data["payload"] = $this->iosPayload; 25 | } 26 | 27 | // Set key/value for $data array, for the keys which can be set please see $DATA_KEYS, $PAYLOAD_KEYS, $BODY_KEYS, $POLICY_KEYS 28 | public function setPredefinedKeyValue($key, $value) 29 | { 30 | if (! is_string($key)) 31 | throw new Exception("key should be a string!"); 32 | 33 | if (in_array($key, $this->DATA_KEYS)) { 34 | $this->data[$key] = $value; 35 | } else if (in_array($key, $this->APS_KEYS)) { 36 | $this->data["payload"]["aps"][$key] = $value; 37 | } else if (in_array($key, $this->POLICY_KEYS)) { 38 | $this->data["policy"][$key] = $value; 39 | } else { 40 | if ($key == "payload" || $key == "policy" || $key == "aps") { 41 | throw new Exception("You don't need to set value for ${key} , just set values for the sub keys in it."); 42 | } else { 43 | throw new Exception("Unknown key: ${key}"); 44 | } 45 | } 46 | } 47 | 48 | // Set extra key/value for Android notification 49 | public function setCustomizedField($key, $value) 50 | { 51 | if (! is_string($key)) 52 | throw new Exception("key should be a string!"); 53 | $this->data["payload"][$key] = $value; 54 | } 55 | } -------------------------------------------------------------------------------- /src/Ios/IOSBroadcast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "broadcast"; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/Ios/IOSCustomizedcast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "customizedcast"; 15 | $this->data["alias_type"] = null; 16 | } 17 | 18 | public function isComplete() 19 | { 20 | parent::isComplete(); 21 | if (!array_key_exists("alias", $this->data) && !array_key_exists("file_id", $this->data)) { 22 | throw new Exception("You need to set alias or upload file for customizedcast!"); 23 | } 24 | 25 | } 26 | 27 | // Upload file with device_tokens or alias to Umeng 28 | public function uploadContents($content) 29 | { 30 | if ($this->data["appkey"] == null) { 31 | throw new Exception("appkey should not be NULL!"); 32 | } 33 | 34 | if ($this->data["timestamp"] == null) { 35 | throw new Exception("timestamp should not be NULL!"); 36 | } 37 | 38 | if (!is_string($content)) { 39 | throw new Exception("content should be a string!"); 40 | } 41 | 42 | $post = array( 43 | "appkey" => $this->data["appkey"], 44 | "timestamp" => $this->data["timestamp"], 45 | "content" => $content, 46 | ); 47 | 48 | $postBody = json_encode($post); 49 | $url = $this->host . $this->uploadPath; 50 | $sign = md5("POST" . $url . $postBody . $this->appMasterSecret); 51 | $url = $url . "?sign=" . $sign; 52 | 53 | $ch = curl_init($url); 54 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 55 | curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 56 | curl_setopt($ch, CURLOPT_POST, 1); 57 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); 58 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 59 | curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post)); 60 | $result = curl_exec($ch); 61 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 62 | $curlErrNo = curl_errno($ch); 63 | $curlErr = curl_error($ch); 64 | curl_close($ch); 65 | //print($result . "\r\n"); 66 | if ($httpCode == "0") // time out 67 | { 68 | throw new Exception("Curl error number:" . $curlErrNo . " , Curl error details:" . $curlErr . "\r\n"); 69 | } else if ($httpCode != "200") // we did send the notifition out and got a non-200 response 70 | { 71 | throw new Exception("http code:" . $httpCode . "\r\n" . "details:" . $result . "\r\n"); 72 | } 73 | 74 | $returnData = json_decode($result, true); 75 | if ($returnData["ret"] == "FAIL") { 76 | throw new Exception("Failed to upload file, details:" . $result . "\r\n"); 77 | } else { 78 | $this->data["file_id"] = $returnData["data"]["file_id"]; 79 | } 80 | 81 | } 82 | 83 | public function getFileId() 84 | { 85 | if (array_key_exists("file_id", $this->data)) { 86 | return $this->data["file_id"]; 87 | } 88 | 89 | return null; 90 | } 91 | } 92 | -------------------------------------------------------------------------------- /src/Ios/IOSFilecast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "filecast"; 15 | $this->data["file_id"] = null; 16 | } 17 | 18 | // return file_id if SUCCESS, else throw Exception with details. 19 | public function uploadContents($content) 20 | { 21 | if ($this->data["appkey"] == null) { 22 | throw new Exception("appkey should not be NULL!"); 23 | } 24 | 25 | if ($this->data["timestamp"] == null) { 26 | throw new Exception("timestamp should not be NULL!"); 27 | } 28 | 29 | if (!is_string($content)) { 30 | throw new Exception("content should be a string!"); 31 | } 32 | 33 | $post = array( 34 | "appkey" => $this->data["appkey"], 35 | "timestamp" => $this->data["timestamp"], 36 | "content" => $content, 37 | ); 38 | $url = $this->host . $this->uploadPath; 39 | $postBody = json_encode($post); 40 | $sign = md5("POST" . $url . $postBody . $this->appMasterSecret); 41 | $url = $url . "?sign=" . $sign; 42 | $ch = curl_init($url); 43 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 44 | curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 45 | curl_setopt($ch, CURLOPT_POST, 1); 46 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); 47 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 48 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody); 49 | $result = curl_exec($ch); 50 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 51 | $curlErrNo = curl_errno($ch); 52 | $curlErr = curl_error($ch); 53 | curl_close($ch); 54 | //print($result . "\r\n"); 55 | if ($httpCode == "0") // time out 56 | { 57 | throw new Exception("Curl error number:" . $curlErrNo . " , Curl error details:" . $curlErr . "\r\n"); 58 | } else if ($httpCode != "200") // we did send the notifition out and got a non-200 response 59 | { 60 | throw new Exception("http code:" . $httpCode . " details:" . $result . "\r\n"); 61 | } 62 | 63 | $returnData = json_decode($result, true); 64 | if ($returnData["ret"] == "FAIL") { 65 | throw new Exception("Failed to upload file, details:" . $result . "\r\n"); 66 | } else { 67 | $this->data["file_id"] = $returnData["data"]["file_id"]; 68 | } 69 | 70 | } 71 | 72 | public function getFileId() 73 | { 74 | if (array_key_exists("file_id", $this->data)) { 75 | return $this->data["file_id"]; 76 | } 77 | 78 | return null; 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /src/Ios/IOSGroupcast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "groupcast"; 14 | $this->data["filter"] = null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/Ios/IOSUnicast.php: -------------------------------------------------------------------------------- 1 | data["type"] = "unicast"; 14 | $this->data["device_tokens"] = null; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/NotificationConfig.php: -------------------------------------------------------------------------------- 1 | '', 10 | // 应用密钥 11 | 'appMasterSecret' => '', 12 | // 是否产品模式 13 | 'productionMode' => true 14 | ]; 15 | const IOS = [ 16 | // 应用key 17 | 'appKey' => 'app_key', 18 | // 应用密钥 19 | 'appMasterSecret' => 'app_secret', 20 | // 是否产品模式 21 | 'productionMode' => true 22 | ]; 23 | } -------------------------------------------------------------------------------- /src/UmengNotification.php: -------------------------------------------------------------------------------- 1 | NULL, 26 | "timestamp" => NULL, 27 | "type" => NULL, 28 | "production_mode" => "true" 29 | ]; 30 | protected $DATA_KEYS = [ 31 | "appkey", 32 | "timestamp", 33 | "type", 34 | "device_tokens", 35 | "alias", 36 | "alias_type", 37 | "file_id", 38 | "filter", 39 | "production_mode", 40 | "feedback", 41 | "description", 42 | "thirdparty_id" 43 | ]; 44 | protected $POLICY_KEYS = [ 45 | "start_time", 46 | "expire_time", 47 | "max_send_num" 48 | ]; 49 | 50 | public function __construct() 51 | { 52 | } 53 | 54 | public function setAppMasterSecret($secret) 55 | { 56 | $this->appMasterSecret = $secret; 57 | } 58 | 59 | // return TRUE if it's complete, otherwise throw exception with details 60 | public function isComplete() 61 | { 62 | if (is_null($this->appMasterSecret)) 63 | throw new Exception("Please set your app master secret for generating the signature!"); 64 | $this->checkArrayValues($this->data); 65 | return TRUE; 66 | } 67 | 68 | private function checkArrayValues($arr) 69 | { 70 | foreach ($arr as $key => $value) { 71 | if (is_null($value)) 72 | throw new Exception($key . " is NULL!"); 73 | else if (is_array($value)) { 74 | $this->checkArrayValues($value); 75 | } 76 | } 77 | } 78 | 79 | // Set key/value for $data array, for the keys which can be set please see $DATA_KEYS, $PAYLOAD_KEYS, $BODY_KEYS, $POLICY_KEYS 80 | abstract function setPredefinedKeyValue($key, $value); 81 | 82 | // send the notification to umeng, return response data if SUCCESS , otherwise throw Exception with details. 83 | public function send() 84 | { 85 | // check the fields to make sure that they are not NULL 86 | $this->isComplete(); 87 | 88 | $url = $this->host . $this->postPath; 89 | $postBody = json_encode($this->data); 90 | $sign = md5("POST" . $url . $postBody . $this->appMasterSecret); 91 | $url = $url . "?sign=" . $sign; 92 | $ch = curl_init($url); 93 | curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 94 | curl_setopt($ch, CURLOPT_BINARYTRANSFER, 1); 95 | curl_setopt($ch, CURLOPT_POST, 1); 96 | curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); 97 | curl_setopt($ch, CURLOPT_TIMEOUT, 60); 98 | curl_setopt($ch, CURLOPT_POSTFIELDS, $postBody); 99 | $result = curl_exec($ch); 100 | $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); 101 | $curlErrNo = curl_errno($ch); 102 | $curlErr = curl_error($ch); 103 | curl_close($ch); 104 | // print($result . "\r\n"); 105 | if ($httpCode == "0") { 106 | // Time out 107 | throw new Exception("Curl error number:" . $curlErrNo . " , Curl error details:" . $curlErr . "\r\n"); 108 | } else if ($httpCode != "200") { 109 | // We did send the notifition out and got a non-200 response 110 | throw new Exception("Http code:" . $httpCode . " details:" . $result . "\r\n"); 111 | } else { 112 | return $result; 113 | } 114 | } 115 | } -------------------------------------------------------------------------------- /src/UmengNotifyApi.php: -------------------------------------------------------------------------------- 1 | checkOs($os); 38 | $this->os = $os; 39 | $conf = $os === 'android' ? NotificationConfig::ANDROID : NotificationConfig::IOS; 40 | $this->appkey = $key ? : $conf['appKey']; 41 | $this->appMasterSecret = $secret ? : $conf['appMasterSecret']; 42 | $this->productionMode = is_null($productionMode) ? $conf['productionMode'] : $productionMode; 43 | $this->timestamp = strval(time()); 44 | } 45 | 46 | private function checkOs($os) 47 | { 48 | if (! in_array($os, [ 49 | 'android', 50 | 'ios' 51 | ])) { 52 | throw new Exception('系统类型错误,os 必须为android或ios'); 53 | } 54 | } 55 | 56 | /** 57 | * 设置设备系统类型 58 | * 59 | * @param unknown $os 60 | */ 61 | public function setOs($os) 62 | { 63 | $this->checkOs($os); 64 | $this->os = $os; 65 | return $this; 66 | } 67 | 68 | public function setAppKey($appKey) 69 | { 70 | $this->appkey = $appKey; 71 | return $this; 72 | } 73 | 74 | public function setAppMasterSecret($secret) 75 | { 76 | $this->appMasterSecret = $secret; 77 | return $this; 78 | } 79 | 80 | /** 81 | * 82 | * @param string $ticker 通知栏提示文字 83 | * @return \Hacklee\Umeng\UmengNotifyApi 84 | */ 85 | public function setAndroidTicker($ticker) 86 | { 87 | $this->params['ticker'] = $ticker; 88 | return $this; 89 | } 90 | 91 | /** 92 | * 93 | * @param string $title 通知标题 94 | * @return \Hacklee\Umeng\UmengNotifyApi 95 | */ 96 | public function setAndroidTitle($title) 97 | { 98 | $this->params['title'] = $title; 99 | return $this; 100 | } 101 | 102 | /** 103 | * 104 | * @param string $text 通知文字描述 105 | * @return \Hacklee\Umeng\UmengNotifyApi 106 | */ 107 | public function setAndroidText($text) 108 | { 109 | $this->params['text'] = $text; 110 | return $this; 111 | } 112 | 113 | /** 114 | * 115 | * @param string $afterOpen "go_app": 打开应用 "go_url": 跳转到URL "go_activity": 打开特定的activity "go_custom": 用户自定义内容。 116 | * @return \Hacklee\Umeng\UmengNotifyApi 117 | */ 118 | public function setAndroidAfterOpen($afterOpen = 'go_app') 119 | { 120 | $this->params['after_open'] = $afterOpen; 121 | return $this; 122 | } 123 | 124 | /** 125 | * 126 | * @param string $tokens 设备唯一标识 当type=unicast时,必填, 表示指定的单个设备 当type=listcast时,必填,要求不超过500个, 多个device_token以英文逗号间隔 127 | * @return \Hacklee\Umeng\UmengNotifyApi 128 | */ 129 | public function setDeviceTokens($tokens) 130 | { 131 | $this->params['device_tokens'] = $tokens; 132 | return $this; 133 | } 134 | 135 | /** 136 | * 137 | * @param array $filter = array( "where" => array( "and" => array( array( "tag" => "iostest" ) ) ) ); 138 | */ 139 | public function setFilter(array $filter) 140 | { 141 | $this->params['filter'] = $filter; 142 | return $this; 143 | } 144 | 145 | /** 146 | * 147 | * @param string $alias 要求不超过50个alias,多个alias以英文逗号间隔。 148 | * @return \Hacklee\Umeng\UmengNotifyApi 149 | */ 150 | public function setAlias($alias) 151 | { 152 | $this->params['alias'] = $alias; 153 | return $this; 154 | } 155 | 156 | /** 157 | * 158 | * @param string $aliasType alias_type可由开发者自定义,开发者在SDK中 调用setAlias(alias, alias_type)时所设置的alias_type 159 | * @return \Hacklee\Umeng\UmengNotifyApi 160 | */ 161 | public function setAliasType($aliasType) 162 | { 163 | $this->params['alias_type'] = $aliasType; 164 | return $this; 165 | } 166 | 167 | /** 168 | * 169 | * @param string $alert 通知内容 ios必填字段 170 | * @return \Hacklee\Umeng\UmengNotifyApi 171 | */ 172 | public function setIosAlert($alert) 173 | { 174 | $this->params['alert'] = $alert; 175 | return $this; 176 | } 177 | 178 | /** 179 | * 180 | * @param unknown $badge 181 | * @return \Hacklee\Umeng\UmengNotifyApi 182 | */ 183 | public function setIosBadge($badge = 0) 184 | { 185 | $this->params['badge'] = $badge; 186 | return $this; 187 | } 188 | 189 | /** 190 | * 如果该字段为空,采用SDK默认的声音, 即res/raw/下的 umeng_push_notification_default_sound声音文件 如果SDK默认声音文件不存在, 则使用系统默认的Notification提示音。 191 | * 192 | * @param string $sound 193 | * @return \Hacklee\Umeng\UmengNotifyApi 194 | */ 195 | public function setIosSound($sound = 'chime') 196 | { 197 | $this->params['sound'] = $sound; 198 | return $this; 199 | } 200 | 201 | /** 202 | * 203 | * @param string $content 文件内容,多个device_token/alias请用回车符"\n"分隔。 204 | * @return \Hacklee\Umeng\UmengNotifyApi 205 | */ 206 | public function setFileContent($content) 207 | { 208 | $this->fileContent = $content; 209 | return $this; 210 | } 211 | 212 | /** 213 | * 可选 用户自定义key-value。只对"通知" (display_type=notification)生效。 可以配合通知到达后,打开App,打开URL,打开Activity使用。 214 | * 215 | * @param array $ext 216 | */ 217 | public function setExtraField(array $ext) 218 | { 219 | $this->ext = $ext; 220 | return $this; 221 | } 222 | 223 | /** 224 | * 安卓广播 225 | * 226 | * @param array $params ['ticker','title','text','after_open'] 227 | * @param unknown $ext 扩展字段 228 | */ 229 | public function sendAndroidBroadcast(array $params = [], array $ext = []) 230 | { 231 | $this->sendCast('AndroidBroadcast', $params, $ext); 232 | } 233 | 234 | /** 235 | * 安卓单播 236 | * 237 | * @param array $params ['device_tokens','ticker','title','text','after_open'] 238 | * @param unknown $ext 扩展字段 239 | */ 240 | public function sendAndroidUnicast(array $params = [], array $ext = []) 241 | { 242 | $this->sendCast('AndroidUnicast', $params, $ext); 243 | } 244 | 245 | /** 246 | * 安卓文件播 247 | * 248 | * @param array $params ['ticker','title','text','after_open'] 249 | * @param string $content 250 | */ 251 | public function sendAndroidFilecast(array $params = [], $content = null) 252 | { 253 | $this->sendCast('AndroidFilecast', $params, [], $content); 254 | } 255 | 256 | /** 257 | * 安卓组播 258 | * 259 | * @param array $params ['ticker','title','text','after_open','filter'] 260 | */ 261 | public function sendAndroidGroupcast(array $params = []) 262 | { 263 | $this->sendCast('AndroidGroupcast', $params); 264 | } 265 | 266 | /** 267 | * 安卓自定义alias进行推送 268 | * 269 | * @param array $params ['alias','alias_type','ticker','title','text','after_open','filter'] 270 | */ 271 | public function sendAndroidCustomizedcast(array $params = []) 272 | { 273 | $this->sendCast('AndroidCustomizedcast', $params); 274 | } 275 | 276 | /** 277 | * ios广播 278 | * 279 | * @param array $params ['alert','badge','sound'] 280 | * @param unknown $ext 扩展字段 281 | */ 282 | public function sendIOSBroadcast(array $params = [], array $ext = []) 283 | { 284 | $this->sendCast('IOSBroadcast', $params, $ext); 285 | } 286 | 287 | /** 288 | * ios单播 289 | * 290 | * @param array $params ['device_tokens','alert','badge','sound'] 291 | * @param unknown $ext 扩展字段 292 | */ 293 | public function sendIOSUnicast(array $params = [], array $ext = []) 294 | { 295 | $this->sendCast('IOSUnicast', $params, $ext); 296 | } 297 | 298 | /** 299 | * ios文件播 300 | * 301 | * @param array $params ['alert','badge','sound'] 302 | * @param string $content 303 | */ 304 | public function sendIOSFilecast(array $params = [], $content = null) 305 | { 306 | $this->sendCast('IOSFilecast', $params, [], $content); 307 | } 308 | 309 | /** 310 | * ios组播 311 | * 312 | * @param array $params ['filter','alert','badge','sound'] 313 | */ 314 | public function sendIOSGroupcast(array $params = []) 315 | { 316 | $this->sendCast('IOSGroupcast', $params); 317 | } 318 | 319 | /** 320 | * ios利用自定义alias进行推送 321 | * 322 | * @param array $params ['alias','alias_type','alert','badge','sound'] 323 | */ 324 | public function sendIOSCustomizedcast(array $params = []) 325 | { 326 | $this->sendCast('IOSCustomizedcast', $params); 327 | } 328 | 329 | /** 330 | * 创建cast对象,并初始化基础参数 331 | * 332 | * @param unknown $className 333 | */ 334 | private function getCastObj($className) 335 | { 336 | $className = $this->nameSpace . ucfirst($this->os) . "\\{$className}"; 337 | $obj = new $className(); 338 | $obj->setAppMasterSecret($this->appMasterSecret); 339 | $obj->setPredefinedKeyValue("appkey", $this->appkey); 340 | $obj->setPredefinedKeyValue("timestamp", $this->timestamp); 341 | 342 | $obj->setPredefinedKeyValue("production_mode", $this->productionMode); 343 | return $obj; 344 | } 345 | 346 | /** 347 | * 向友盟服务器发送请求 348 | * 349 | * @param unknown $className 消息对象 350 | * @param array $params 消息参数 351 | * @param array $ext 扩展字段 352 | * @param string $file 文件内容 353 | */ 354 | private function sendCast($className, array $params = [], array $ext = [], $file = null) 355 | { 356 | try { 357 | $brocast = $this->getCastObj($className); 358 | $params = array_merge($this->params, $params); 359 | foreach ($params as $key => $val) { 360 | $brocast->setPredefinedKeyValue($key, $val); 361 | } 362 | $ext = array_merge($this->ext, $ext); 363 | // [optional]Set extra fields 364 | if (count($ext)) { 365 | $func = $this->os == 'android' ? 'setExtraField' : 'setCustomizedField'; 366 | foreach ($ext as $key => $val) { 367 | $brocast->{$func}($key, $val); 368 | } 369 | } 370 | $file || ($file = $this->fileContent); 371 | $file && $brocast->uploadContents($file); 372 | $brocast->send(); 373 | } catch (Exception $e) { 374 | } 375 | } 376 | } 377 | --------------------------------------------------------------------------------