PushPayload.php 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673
  1. <?php
  2. namespace JPush;
  3. use InvalidArgumentException;
  4. class PushPayload {
  5. private static $EFFECTIVE_DEVICE_TYPES = array('ios', 'android', 'winphone');
  6. const PUSH_URL = 'https://api.jpush.cn/v3/push';
  7. const PUSH_VALIDATE_URL = 'https://api.jpush.cn/v3/push/validate';
  8. private $client;
  9. private $platform;
  10. private $audience;
  11. private $tags;
  12. private $tagAnds;
  13. private $alias;
  14. private $registrationIds;
  15. private $notificationAlert;
  16. private $iosNotification;
  17. private $androidNotification;
  18. private $winPhoneNotification;
  19. private $smsMessage;
  20. private $message;
  21. private $options;
  22. /**
  23. * PushPayload constructor.
  24. * @param $client JPush
  25. */
  26. function __construct($client) {
  27. $this->client = $client;
  28. }
  29. public function setPlatform($platform) {
  30. # $required_keys = array('all', 'android', 'ios', 'winphone');
  31. if (is_string($platform)) {
  32. $ptf = strtolower($platform);
  33. if ('all' === $ptf) {
  34. $this->platform = 'all';
  35. } elseif (in_array($ptf, self::$EFFECTIVE_DEVICE_TYPES)) {
  36. $this->platform = array($ptf);
  37. }
  38. } elseif (is_array($platform)) {
  39. $ptf = array_map('strtolower', $platform);
  40. $this->platform = array_intersect($ptf, self::$EFFECTIVE_DEVICE_TYPES);
  41. }
  42. return $this;
  43. }
  44. public function setAudience($all) {
  45. if (strtolower($all) === 'all') {
  46. $this->addAllAudience();
  47. return $this;
  48. } else {
  49. throw new InvalidArgumentException('Invalid audience value');
  50. }
  51. }
  52. public function addAllAudience() {
  53. $this->audience = "all";
  54. return $this;
  55. }
  56. public function addTag($tag) {
  57. if (is_null($this->tags)) {
  58. $this->tags = array();
  59. }
  60. if (is_array($tag)) {
  61. foreach($tag as $_tag) {
  62. if (!is_string($_tag)) {
  63. throw new InvalidArgumentException("Invalid tag value");
  64. }
  65. if (!in_array($_tag, $this->tags)) {
  66. array_push($this->tags, $_tag);
  67. }
  68. }
  69. } else if (is_string($tag)) {
  70. if (!in_array($tag, $this->tags)) {
  71. array_push($this->tags, $tag);
  72. }
  73. } else {
  74. throw new InvalidArgumentException("Invalid tag value");
  75. }
  76. return $this;
  77. }
  78. public function addTagAnd($tag) {
  79. if (is_null($this->tagAnds)) {
  80. $this->tagAnds = array();
  81. }
  82. if (is_array($tag)) {
  83. foreach($tag as $_tag) {
  84. if (!is_string($_tag)) {
  85. throw new InvalidArgumentException("Invalid tag_and value");
  86. }
  87. if (!in_array($_tag, $this->tagAnds)) {
  88. array_push($this->tagAnds, $_tag);
  89. }
  90. }
  91. } else if (is_string($tag)) {
  92. if (!in_array($tag, $this->tagAnds)) {
  93. array_push($this->tagAnds, $tag);
  94. }
  95. } else {
  96. throw new InvalidArgumentException("Invalid tag_and value");
  97. }
  98. return $this;
  99. }
  100. public function addAlias($alias) {
  101. if (is_null($this->alias)) {
  102. $this->alias = array();
  103. }
  104. if (is_array($alias)) {
  105. foreach($alias as $_alias) {
  106. if (!is_string($_alias)) {
  107. throw new InvalidArgumentException("Invalid alias value");
  108. }
  109. if (!in_array($_alias, $this->alias)) {
  110. array_push($this->alias, $_alias);
  111. }
  112. }
  113. } else if (is_string($alias)) {
  114. if (!in_array($alias, $this->alias)) {
  115. array_push($this->alias, $alias);
  116. }
  117. } else {
  118. throw new InvalidArgumentException("Invalid alias value");
  119. }
  120. return $this;
  121. }
  122. public function addRegistrationId($registrationId) {
  123. if (is_null($this->registrationIds)) {
  124. $this->registrationIds = array();
  125. }
  126. if (is_array($registrationId)) {
  127. foreach($registrationId as $_registrationId) {
  128. if (!is_string($_registrationId)) {
  129. throw new InvalidArgumentException("Invalid registration_id value");
  130. }
  131. if (!in_array($_registrationId, $this->registrationIds)) {
  132. array_push($this->registrationIds, $_registrationId);
  133. }
  134. }
  135. } else if (is_string($registrationId)) {
  136. if (!in_array($registrationId, $this->registrationIds)) {
  137. array_push($this->registrationIds, $registrationId);
  138. }
  139. } else {
  140. throw new InvalidArgumentException("Invalid registration_id value");
  141. }
  142. return $this;
  143. }
  144. public function setNotificationAlert($alert) {
  145. if (!is_string($alert)) {
  146. throw new InvalidArgumentException("Invalid alert value");
  147. }
  148. $this->notificationAlert = $alert;
  149. return $this;
  150. }
  151. public function addWinPhoneNotification($alert=null, $title=null, $_open_page=null, $extras=null) {
  152. $winPhone = array();
  153. if (!is_null($alert)) {
  154. if (!is_string($alert)) {
  155. throw new InvalidArgumentException("Invalid winphone notification");
  156. }
  157. $winPhone['alert'] = $alert;
  158. }
  159. if (!is_null($title)) {
  160. if (!is_string($title)) {
  161. throw new InvalidArgumentException("Invalid winphone title notification");
  162. }
  163. if(strlen($title) > 0) {
  164. $winPhone['title'] = $title;
  165. }
  166. }
  167. if (!is_null($_open_page)) {
  168. if (!is_string($_open_page)) {
  169. throw new InvalidArgumentException("Invalid winphone _open_page notification");
  170. }
  171. if (strlen($_open_page) > 0) {
  172. $winPhone['_open_page'] = $_open_page;
  173. }
  174. }
  175. if (!is_null($extras)) {
  176. if (!is_array($extras)) {
  177. throw new InvalidArgumentException("Invalid winphone extras notification");
  178. }
  179. if (count($extras) > 0) {
  180. $winPhone['extras'] = $extras;
  181. }
  182. }
  183. if (count($winPhone) <= 0) {
  184. throw new InvalidArgumentException("Invalid winphone notification");
  185. }
  186. $this->winPhoneNotification = $winPhone;
  187. return $this;
  188. }
  189. public function setSmsMessage($content, $delay_time = 0) {
  190. $sms = array();
  191. if (is_string($content) && mb_strlen($content) < 480) {
  192. $sms['content'] = $content;
  193. } else {
  194. throw new InvalidArgumentException('Invalid sms content, sms content\'s length must in [0, 480]');
  195. }
  196. $sms['delay_time'] = ($delay_time === 0 || (is_int($delay_time) && $delay_time > 0 && $delay_time <= 86400)) ? $delay_time : 0;
  197. $this->smsMessage = $sms;
  198. return $this;
  199. }
  200. public function build() {
  201. $payload = array();
  202. // validate platform
  203. if (is_null($this->platform)) {
  204. throw new InvalidArgumentException("platform must be set");
  205. }
  206. $payload["platform"] = $this->platform;
  207. // validate audience
  208. $audience = array();
  209. if (!is_null($this->tags)) {
  210. $audience["tag"] = $this->tags;
  211. }
  212. if (!is_null($this->tagAnds)) {
  213. $audience["tag_and"] = $this->tagAnds;
  214. }
  215. if (!is_null($this->alias)) {
  216. $audience["alias"] = $this->alias;
  217. }
  218. if (!is_null($this->registrationIds)) {
  219. $audience["registration_id"] = $this->registrationIds;
  220. }
  221. if (is_null($this->audience) && count($audience) <= 0) {
  222. throw new InvalidArgumentException("audience must be set");
  223. } else if (!is_null($this->audience) && count($audience) > 0) {
  224. throw new InvalidArgumentException("you can't add tags/alias/registration_id/tag_and when audience='all'");
  225. } else if (is_null($this->audience)) {
  226. $payload["audience"] = $audience;
  227. } else {
  228. $payload["audience"] = $this->audience;
  229. }
  230. // validate notification
  231. $notification = array();
  232. if (!is_null($this->notificationAlert)) {
  233. $notification['alert'] = $this->notificationAlert;
  234. }
  235. if (!is_null($this->androidNotification)) {
  236. $notification['android'] = $this->androidNotification;
  237. if (is_null($this->androidNotification['alert'])) {
  238. if (is_null($this->notificationAlert)) {
  239. throw new InvalidArgumentException("Android alert can not be null");
  240. } else {
  241. $notification['android']['alert'] = $this->notificationAlert;
  242. }
  243. }
  244. }
  245. if (!is_null($this->iosNotification)) {
  246. $notification['ios'] = $this->iosNotification;
  247. if (is_null($this->iosNotification['alert'])) {
  248. if (is_null($this->notificationAlert)) {
  249. throw new InvalidArgumentException("iOS alert can not be null");
  250. } else {
  251. $notification['ios']['alert'] = $this->notificationAlert;
  252. }
  253. }
  254. }
  255. if (!is_null($this->winPhoneNotification)) {
  256. $notification['winphone'] = $this->winPhoneNotification;
  257. if (is_null($this->winPhoneNotification['alert'])) {
  258. if (is_null($this->winPhoneNotification)) {
  259. throw new InvalidArgumentException("WinPhone alert can not be null");
  260. } else {
  261. $notification['winphone']['alert'] = $this->notificationAlert;
  262. }
  263. }
  264. }
  265. if (count($notification) > 0) {
  266. $payload['notification'] = $notification;
  267. }
  268. if (count($this->message) > 0) {
  269. $payload['message'] = $this->message;
  270. }
  271. if (!array_key_exists('notification', $payload) && !array_key_exists('message', $payload)) {
  272. throw new InvalidArgumentException('notification and message can not all be null');
  273. }
  274. if (count($this->smsMessage)) {
  275. $payload['sms_message'] = $this->smsMessage;
  276. }
  277. if (is_null($this->options)) {
  278. $this->options();
  279. }
  280. $payload['options'] = $this->options;
  281. return $payload;
  282. }
  283. public function toJSON() {
  284. $payload = $this->build();
  285. return json_encode($payload);
  286. }
  287. public function printJSON() {
  288. echo $this->toJSON();
  289. return $this;
  290. }
  291. public function send() {
  292. $url = PushPayload::PUSH_URL;
  293. return Http::post($this->client, $url, $this->build());
  294. }
  295. public function validate() {
  296. $url = PushPayload::PUSH_VALIDATE_URL;
  297. return Http::post($this->client, $url, $this->build());
  298. }
  299. private function generateSendno() {
  300. return rand(100000, getrandmax());
  301. }
  302. # new methods
  303. public function iosNotification($alert = '', array $notification = array()) {
  304. # $required_keys = array('sound', 'badge', 'content-available', 'mutable-content', category', 'extras');
  305. $ios = array();
  306. $ios['alert'] = (is_string($alert) || is_array($alert)) ? $alert : '';
  307. if (!empty($notification)) {
  308. if (isset($notification['sound']) && is_string($notification['sound'])) {
  309. $ios['sound'] = $notification['sound'];
  310. }
  311. if (isset($notification['badge'])) {
  312. $ios['badge'] = (int)$notification['badge'] ? $notification['badge'] : 0;
  313. }
  314. if (isset($notification['content-available']) && is_bool($notification['content-available']) && $notification['content-available']) {
  315. $ios['content-available'] = $notification['content-available'];
  316. }
  317. if (isset($notification['mutable-content']) && is_bool($notification['mutable-content']) && $notification['mutable-content']) {
  318. $ios['mutable-content'] = $notification['mutable-content'];
  319. }
  320. if (isset($notification['category']) && is_string($notification['category'])) {
  321. $ios['category'] = $notification['category'];
  322. }
  323. if (isset($notification['extras']) && is_array($notification['extras']) && !empty($notification['extras'])) {
  324. $ios['extras'] = $notification['extras'];
  325. }
  326. }
  327. if (!isset($ios['sound'])) {
  328. $ios['sound'] = '';
  329. }
  330. if (!isset($ios['badge'])) {
  331. $ios['badge'] = '+1';
  332. }
  333. $this->iosNotification = $ios;
  334. return $this;
  335. }
  336. public function androidNotification($alert = '', array $notification = array()) {
  337. # $required_keys = array('title', 'builder_id', 'extras');
  338. $android = array();
  339. $android['alert'] = is_string($alert) ? $alert : '';
  340. if (!empty($notification)) {
  341. if (isset($notification['title']) && is_string($notification['title'])) {
  342. $android['title'] = $notification['title'];
  343. }
  344. if (isset($notification['builder_id']) && is_int($notification['builder_id'])) {
  345. $android['builder_id'] = $notification['builder_id'];
  346. }
  347. if (isset($notification['extras']) && is_array($notification['extras']) && !empty($notification['extras'])) {
  348. $android['extras'] = $notification['extras'];
  349. }
  350. if (isset($notification['priority']) && is_int($notification['priority'])) {
  351. $android['priority'] = $notification['priority'];
  352. }
  353. if (isset($notification['category']) && is_string($notification['category'])) {
  354. $android['category'] = $notification['category`'];
  355. }
  356. if (isset($notification['style']) && is_int($notification['style'])) {
  357. $android['style'] = $notification['style'];
  358. }
  359. if (isset($notification['big_text']) && is_string($notification['big_text'])) {
  360. $android['big_text'] = $notification['big_text'];
  361. }
  362. if (isset($notification['inbox']) && is_array($notification['inbox'])) {
  363. $android['inbox'] = $notification['inbox'];
  364. }
  365. if (isset($notification['big_pic_path']) && is_string($notification['big_pic_path'])) {
  366. $android['big_pic_path'] = $notification['big_pic_path'];
  367. }
  368. }
  369. $this->androidNotification = $android;
  370. return $this;
  371. }
  372. public function message($msg_content, array $msg = array()) {
  373. # $required_keys = array('title', 'content_type', 'extras');
  374. if (is_string($msg_content)) {
  375. $message = array();
  376. $message['msg_content'] = $msg_content;
  377. if (!empty($msg)) {
  378. if (isset($msg['title']) && is_string($msg['title'])) {
  379. $message['title'] = $msg['title'];
  380. }
  381. if (isset($msg['content_type']) && is_string($msg['content_type'])) {
  382. $message['content_type'] = $msg['content_type'];
  383. }
  384. if (isset($msg['extras']) && is_array($msg['extras']) && !empty($msg['extras'])) {
  385. $message['extras'] = $msg['extras'];
  386. }
  387. }
  388. $this->message = $message;
  389. }
  390. return $this;
  391. }
  392. public function options(array $opts = array()) {
  393. # $required_keys = array('sendno', 'time_to_live', 'override_msg_id', 'apns_production', 'big_push_duration');
  394. $options = array();
  395. if (isset($opts['sendno']) && is_int($opts['sendno'])) {
  396. $options['sendno'] = $opts['sendno'];
  397. } else {
  398. $options['sendno'] = $this->generateSendno();
  399. }
  400. if (isset($opts['time_to_live']) && is_int($opts['time_to_live']) && $opts['time_to_live'] <= 864000 && $opts['time_to_live'] >= 0) {
  401. $options['time_to_live'] = $opts['time_to_live'];
  402. }
  403. if (isset($opts['override_msg_id']) && is_long($opts['override_msg_id'])) {
  404. $options['override_msg_id'] = $opts['override_msg_id'];
  405. }
  406. if (isset($opts['apns_production']) && is_bool($opts['apns_production'])) {
  407. $options['apns_production'] = $opts['apns_production'];
  408. } else {
  409. $options['apns_production'] = false;
  410. }
  411. if (isset($opts['big_push_duration']) && is_int($opts['big_push_duration']) && $opts['big_push_duration'] <= 1400 && $opts['big_push_duration'] >= 0) {
  412. $options['big_push_duration'] = $opts['big_push_duration'];
  413. }
  414. $this->options = $options;
  415. return $this;
  416. }
  417. ###############################################################################
  418. ############# 以下函数已过期,不推荐使用,仅作为兼容接口存在 #########################
  419. ###############################################################################
  420. public function addIosNotification($alert=null, $sound=null, $badge=null, $content_available=null, $category=null, $extras=null) {
  421. $ios = array();
  422. if (!is_null($alert)) {
  423. if (!is_string($alert) && !is_array($alert)) {
  424. throw new InvalidArgumentException("Invalid ios alert value");
  425. }
  426. $ios['alert'] = $alert;
  427. }
  428. if (!is_null($sound)) {
  429. if (!is_string($sound)) {
  430. throw new InvalidArgumentException("Invalid ios sound value");
  431. }
  432. if ($sound !== Config::DISABLE_SOUND) {
  433. $ios['sound'] = $sound;
  434. }
  435. } else {
  436. // 默认sound为''
  437. $ios['sound'] = '';
  438. }
  439. if (!is_null($badge)) {
  440. if (is_string($badge) && !preg_match("/^[+-]{1}[0-9]{1,3}$/", $badge)) {
  441. if (!is_int($badge)) {
  442. throw new InvalidArgumentException("Invalid ios badge value");
  443. }
  444. }
  445. if ($badge != Config::DISABLE_BADGE) {
  446. $ios['badge'] = $badge;
  447. }
  448. } else {
  449. // 默认badge为'+1'
  450. $ios['badge'] = '+1';
  451. }
  452. if (!is_null($content_available)) {
  453. if (!is_bool($content_available)) {
  454. throw new InvalidArgumentException("Invalid ios content-available value");
  455. }
  456. $ios['content-available'] = $content_available;
  457. }
  458. if (!is_null($category)) {
  459. if (!is_string($category)) {
  460. throw new InvalidArgumentException("Invalid ios category value");
  461. }
  462. if (strlen($category)) {
  463. $ios['category'] = $category;
  464. }
  465. }
  466. if (!is_null($extras)) {
  467. if (!is_array($extras)) {
  468. throw new InvalidArgumentException("Invalid ios extras value");
  469. }
  470. if (count($extras) > 0) {
  471. $ios['extras'] = $extras;
  472. }
  473. }
  474. if (count($ios) <= 0) {
  475. throw new InvalidArgumentException("Invalid iOS notification");
  476. }
  477. $this->iosNotification = $ios;
  478. return $this;
  479. }
  480. public function addAndroidNotification($alert=null, $title=null, $builderId=null, $extras=null) {
  481. $android = array();
  482. if (!is_null($alert)) {
  483. if (!is_string($alert)) {
  484. throw new InvalidArgumentException("Invalid android alert value");
  485. }
  486. $android['alert'] = $alert;
  487. }
  488. if (!is_null($title)) {
  489. if(!is_string($title)) {
  490. throw new InvalidArgumentException("Invalid android title value");
  491. }
  492. if(strlen($title) > 0) {
  493. $android['title'] = $title;
  494. }
  495. }
  496. if (!is_null($builderId)) {
  497. if (!is_int($builderId)) {
  498. throw new InvalidArgumentException("Invalid android builder_id value");
  499. }
  500. $android['builder_id'] = $builderId;
  501. }
  502. if (!is_null($extras)) {
  503. if (!is_array($extras)) {
  504. throw new InvalidArgumentException("Invalid android extras value");
  505. }
  506. if (count($extras) > 0) {
  507. $android['extras'] = $extras;
  508. }
  509. }
  510. if (count($android) <= 0) {
  511. throw new InvalidArgumentException("Invalid android notification");
  512. }
  513. $this->androidNotification = $android;
  514. return $this;
  515. }
  516. public function setMessage($msg_content, $title=null, $content_type=null, $extras=null) {
  517. $message = array();
  518. if (is_null($msg_content) || !is_string($msg_content)) {
  519. throw new InvalidArgumentException("Invalid message content");
  520. } else {
  521. $message['msg_content'] = $msg_content;
  522. }
  523. if (!is_null($title)) {
  524. if (!is_string($title)) {
  525. throw new InvalidArgumentException("Invalid message title");
  526. }
  527. $message['title'] = $title;
  528. }
  529. if (!is_null($content_type)) {
  530. if (!is_string($content_type)) {
  531. throw new InvalidArgumentException("Invalid message content type");
  532. }
  533. $message["content_type"] = $content_type;
  534. }
  535. if (!is_null($extras)) {
  536. if (!is_array($extras)) {
  537. throw new InvalidArgumentException("Invalid message extras");
  538. }
  539. if (count($extras) > 0) {
  540. $message['extras'] = $extras;
  541. }
  542. }
  543. $this->message = $message;
  544. return $this;
  545. }
  546. public function setOptions($sendno=null, $time_to_live=null, $override_msg_id=null, $apns_production=null, $big_push_duration=null) {
  547. $options = array();
  548. if (!is_null($sendno)) {
  549. if (!is_int($sendno)) {
  550. throw new InvalidArgumentException('Invalid option sendno');
  551. }
  552. $options['sendno'] = $sendno;
  553. } else {
  554. $options['sendno'] = $this->generateSendno();
  555. }
  556. if (!is_null($time_to_live)) {
  557. if (!is_int($time_to_live) || $time_to_live < 0 || $time_to_live > 864000) {
  558. throw new InvalidArgumentException('Invalid option time to live, it must be a int and in [0, 864000]');
  559. }
  560. $options['time_to_live'] = $time_to_live;
  561. }
  562. if (!is_null($override_msg_id)) {
  563. if (!is_long($override_msg_id)) {
  564. throw new InvalidArgumentException('Invalid option override msg id');
  565. }
  566. $options['override_msg_id'] = $override_msg_id;
  567. }
  568. if (!is_null($apns_production)) {
  569. if (!is_bool($apns_production)) {
  570. throw new InvalidArgumentException('Invalid option apns production');
  571. }
  572. $options['apns_production'] = $apns_production;
  573. } else {
  574. $options['apns_production'] = false;
  575. }
  576. if (!is_null($big_push_duration)) {
  577. if (!is_int($big_push_duration) || $big_push_duration < 0 || $big_push_duration > 1440) {
  578. throw new InvalidArgumentException('Invalid option big push duration, it must be a int and in [0, 1440]');
  579. }
  580. $options['big_push_duration'] = $big_push_duration;
  581. }
  582. $this->options = $options;
  583. return $this;
  584. }
  585. }