PageRenderTime 51ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/class.c2dm.php

https://bitbucket.org/ritmas/php-c2dm
PHP | 215 lines | 187 code | 17 blank | 11 comment | 8 complexity | 2d0d7bb1b0024047d6563a0276614da8 MD5 | raw file
  1. <?php
  2. /**
  3. * A single class for Android Cloud to Device messaging
  4. *
  5. * The clever bits are copied from
  6. * http://stackoverflow.com/questions/4121508/c2dm-implementation-php-code/5232809#5232809
  7. */
  8. class C2DM {
  9. private $source;
  10. private $authCode;
  11. private $username;
  12. private $password;
  13. public function __construct() {
  14. }
  15. public function setSource($s) {
  16. $this->source = $s;
  17. }
  18. public function setUsername($u) {
  19. $this->username = $u;
  20. }
  21. public function setPassword($p) {
  22. $this->password = $p;
  23. }
  24. public function setAuthCode($a) {
  25. $this->authCode = $a;
  26. }
  27. public function getAuthCode() {
  28. if($this->authCode) {
  29. return $this->authCode;
  30. } else {
  31. return $this->googleAuthenticate();
  32. }
  33. }
  34. /**
  35. * Get the ClientLogin token for ac2dm. Techinically, you can change the service
  36. * and get a token for whatever you please
  37. */
  38. public function googleAuthenticate($service="ac2dm") {
  39. if(empty($this->username) || empty($this->password) || empty($this->source)) {
  40. throw new Exception("Username, password and source must all be set to get auth code");
  41. }
  42. $ch = curl_init();
  43. if(!$ch){
  44. throw new Exception("Curl must be enabled");
  45. }
  46. curl_setopt($ch, CURLOPT_URL, "https://www.google.com/accounts/ClientLogin");
  47. $post_fields = "accountType=" . urlencode('HOSTED_OR_GOOGLE')
  48. . "&Email=" . urlencode($this->username)
  49. . "&Passwd=" . urlencode($this->password)
  50. . "&source=" . urlencode($this->source)
  51. . "&service=" . urlencode($service);
  52. curl_setopt($ch, CURLOPT_HEADER, true);
  53. curl_setopt($ch, CURLOPT_POST, true);
  54. curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
  55. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  56. curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
  57. curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
  58. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  59. $response = curl_exec($ch);
  60. curl_close($ch);
  61. if (strpos($response, '200 OK') === false) {
  62. throw new InvalidResponseException($response);
  63. }
  64. // find the auth code
  65. preg_match("/(Auth=)([\w|-]+)/", $response, $matches);
  66. if (!$matches[2]) {
  67. throw new Exception("Can't parse the auth code from the response");
  68. }
  69. $this->authCode = $matches[2];
  70. return $matches[2];
  71. }
  72. public function send($deviceRegistrationId, $msgType, $payloadData = null, $retry = true) {
  73. $auth = $this->getAuthCode();
  74. $headers = array('Authorization: GoogleLogin auth=' . $auth);
  75. $data = array(
  76. 'registration_id' => $deviceRegistrationId,
  77. 'collapse_key' => $msgType
  78. );
  79. if(!empty($payloadData)) {
  80. foreach($payloadData as $key => $value) {
  81. $data['data.' . $key] = $value;
  82. }
  83. }
  84. $curlpost = "";
  85. foreach($data as $key=>$value) {
  86. $curlpost .= "{$key}={$value}&";
  87. }
  88. $curlpost = rtrim($curlpost, '&');
  89. $ch = curl_init();
  90. curl_setopt($ch, CURLOPT_URL, "https://android.apis.google.com/c2dm/send");
  91. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  92. curl_setopt($ch, CURLOPT_POSTFIELDS, $curlpost);
  93. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  94. curl_setopt($ch, CURLOPT_POST, true);
  95. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  96. //curl_setopt($ch, CURLOPT_HEADER, true);
  97. //curl_setopt($ch, CURLINFO_HEADER_OUT, true);
  98. $response = curl_exec($ch);
  99. $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  100. if($code == 200) {
  101. if(strpos($response, "Error") !== false) {
  102. throw new Exception($response);
  103. }
  104. } else if ($code == 401) {
  105. $this->authCode = null;
  106. if($retry) {
  107. $this->send($deviceRegistrationId, $msgType, $payloadData, false);
  108. }
  109. } else {
  110. throw new Exception("C2DM Message returned code {$code}");
  111. }
  112. curl_close($ch);
  113. return $response;
  114. }
  115. }
  116. /**
  117. * C2DM renamed to GCM
  118. * http://developer.android.com/guide/google/gcm/c2dm.html
  119. */
  120. class GCM extends C2DM {
  121. private $apiKey;
  122. public function __construct() {
  123. parent::__construct();
  124. }
  125. public function setApiKey($a) {
  126. $this->apiKey = $a;
  127. }
  128. /**
  129. * Get the ClientLogin token for GCM
  130. */
  131. public function googleAuthenticate($service="ac2dm") {
  132. return parent::googleAuthenticate($service);
  133. }
  134. public function send($deviceRegistrationId, $msgType, $payloadData = null, $retry = true) {
  135. $headers = array(
  136. "Content-Type: application/json; charset=utf-8",
  137. "Authorization: key=" . $this->apiKey
  138. );
  139. $data = array(
  140. 'registration_ids' => array($deviceRegistrationId),
  141. 'collapse_key' => $msgType,
  142. 'data' => array()
  143. );
  144. if(!empty($payloadData)) {
  145. foreach($payloadData as $key => $value) {
  146. $data['data'][$key] = $value;
  147. }
  148. }
  149. $ch = curl_init();
  150. curl_setopt($ch, CURLOPT_URL, "https://android.googleapis.com/gcm/send");
  151. curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
  152. curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
  153. curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
  154. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
  155. curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
  156. //curl_setopt($ch, CURLOPT_HEADER, true);
  157. //curl_setopt($ch, CURLINFO_HEADER_OUT, true);
  158. $response = curl_exec($ch);
  159. $code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
  160. if($code == 200) {
  161. if(strpos($response, "Error") !== false) {
  162. throw new Exception($response);
  163. }
  164. } else if ($code == 401) {
  165. $this->authCode = null;
  166. if($retry) {
  167. $this->send($deviceRegistrationId, $msgType, $payloadData, false);
  168. }
  169. } else {
  170. throw new Exception("GCM Message returned code {$code}");
  171. }
  172. curl_close($ch);
  173. return $response;
  174. }
  175. }