/** * Send Message * * @param Zend_Mobile_Push_Message_Mpns $message * @return boolean * @throws Zend_Mobile_Push_Exception */ public function send(Zend_Mobile_Push_Message_Abstract $message) { if (!$message->validate()) { throw new Zend_Mobile_Push_Exception('The message is not valid.'); } $this->connect(); $client = $this->getHttpClient(); $client->setUri($message->getToken()); $client->setHeaders(array('Context-Type' => 'text/xml', 'Accept' => 'application/*', 'X-NotificationClass' => $message->getDelay())); if ($message->getId()) { $client->setHeaders('X-MessageID', $message->getId()); } if ($message->getNotificationType() != Zend_Mobile_Push_Message_Mpns::TYPE_RAW) { $client->setHeaders('X-WindowsPhone-Target', $message->getNotificationType()); } $client->setRawData($message->getXmlPayload(), 'text/xml'); $response = $client->request('POST'); $this->close(); switch ($response->getStatus()) { case 200: // check headers for response? need to test how this actually works to correctly handle different states. if ($response->getHeader('NotificationStatus') == 'QueueFull') { require_once 'Zend/Mobile/Push/Exception/DeviceQuotaExceeded.php'; throw new Zend_Mobile_Push_Exception_DeviceQuotaExceeded('The devices push notification queue is full, use exponential backoff'); } break; case 400: require_once 'Zend/Mobile/Push/Exception/InvalidPayload.php'; throw new Zend_Mobile_Push_Exception_InvalidPayload('The message xml was invalid'); break; case 401: require_once 'Zend/Mobile/Push/Exception/InvalidToken.php'; throw new Zend_Mobile_Push_Exception_InvalidToken('The device token is not valid or there is a mismatch between certificates'); break; case 404: require_once 'Zend/Mobile/Push/Exception/InvalidToken.php'; throw new Zend_Mobile_Push_Exception_InvalidToken('The device subscription is invalid, stop sending notifications to this device'); break; case 405: throw new Zend_Mobile_Push_Exception('Invalid method, only POST is allowed'); // will never be hit unless overwritten break; case 406: require_once 'Zend/Mobile/Push/Exception/QuotaExceeded.php'; throw new Zend_Mobile_Push_Exception_QuotaExceeded('The unauthenticated web service has reached the per-day throttling limit'); break; case 412: require_once 'Zend/Mobile/Push/Exception/InvalidToken.php'; throw new Zend_Mobile_Push_Exception_InvalidToken('The device is in an inactive state. You may retry once per hour'); break; case 503: require_once 'Zend/Mobile/Push/Exception/ServerUnavailable.php'; throw new Zend_Mobile_Push_Exception_ServerUnavailable('The server was unavailable.'); break; default: break; } return true; }
/** * Send Message * * @param Zend_Mobile_Push_Message_Gcm $message * @return Zend_Mobile_Push_Response_Gcm * @throws Zend_Mobile_Push_Exception */ public function send(Zend_Mobile_Push_Message_Abstract $message) { if (!$message->validate()) { throw new Zend_Mobile_Push_Exception('The message is not valid.'); } $this->connect(); $client = $this->getHttpClient(); $client->setUri(self::SERVER_URI); $client->setHeaders('Authorization', 'key=' . $this->getApiKey()); $response = $client->setRawData($message->toJson(), 'application/json')->request('POST'); $this->close(); switch ($response->getStatus()) { case 500: require_once 'Zend/Mobile/Push/Exception/ServerUnavailable.php'; throw new Zend_Mobile_Push_Exception_ServerUnavailable('The server encountered an internal error, try again'); break; case 503: require_once 'Zend/Mobile/Push/Exception/ServerUnavailable.php'; throw new Zend_Mobile_Push_Exception_ServerUnavailable('The server was unavailable, check Retry-After header'); break; case 401: require_once 'Zend/Mobile/Push/Exception/InvalidAuthToken.php'; throw new Zend_Mobile_Push_Exception_InvalidAuthToken('There was an error authenticating the sender account'); break; case 400: require_once 'Zend/Mobile/Push/Exception/InvalidPayload.php'; throw new Zend_Mobile_Push_Exception_InvalidPayload('The request could not be parsed as JSON or contains invalid fields'); break; } return new Zend_Mobile_Push_Response_Gcm($response->getBody(), $message); }
/** * Send Message * * @param Zend_Mobile_Push_Message_Apns $message * @return boolean * @throws Zend_Mobile_Push_Exception * @throws Zend_Mobile_Push_Exception_ServerUnavailable * @throws Zend_Mobile_Push_Exception_InvalidToken * @throws Zend_Mobile_Push_Exception_InvalidTopic * @throws Zend_Mobile_Push_Exception_InvalidPayload */ public function send(Zend_Mobile_Push_Message_Abstract $message) { if (!$message->validate()) { throw new Zend_Mobile_Push_Exception('The message is not valid.'); } if (!$this->_isConnected || !in_array($this->_currentEnv, array(self::SERVER_SANDBOX_URI, self::SERVER_PRODUCTION_URI))) { $this->connect(self::SERVER_PRODUCTION_URI); } $payload = array('aps' => array()); $alert = $message->getAlert(); foreach ($alert as $k => $v) { if ($v == null) { unset($alert[$k]); } } if (!empty($alert)) { $payload['aps']['alert'] = $alert; } $payload['aps']['badge'] = $message->getBadge(); $payload['aps']['sound'] = $message->getSound(); foreach ($message->getCustomData() as $k => $v) { $payload[$k] = $v; } $payload = json_encode($payload); $expire = $message->getExpire(); if ($expire > 0) { $expire += time(); } $id = $message->getId(); if (empty($id)) { $id = time(); } $payload = pack('CNNnH*', 1, $id, $expire, 32, $message->getToken()) . pack('n', strlen($payload)) . $payload; $ret = $this->_write($payload); if ($ret === false) { require_once 'Zend/Mobile/Push/Exception/ServerUnavailable.php'; throw new Zend_Mobile_Push_Exception_ServerUnavailable('Unable to send message'); } // check for errors from apple $err = $this->_read(1024); if (strlen($err) > 0) { $err = unpack('Ccmd/Cerrno/Nid', $err); switch ($err['errno']) { case 0: return true; break; case 1: throw new Zend_Mobile_Push_Exception('A processing error has occurred on the apple push notification server.'); break; case 2: require_once 'Zend/Mobile/Push/Exception/InvalidToken.php'; throw new Zend_Mobile_Push_Exception_InvalidToken('Missing token; you must set a token for the message.'); break; case 3: require_once 'Zend/Mobile/Push/Exception/InvalidTopic.php'; throw new Zend_Mobile_Push_Exception_InvalidTopic('Missing id; you must set an id for the message.'); break; case 4: require_once 'Zend/Mobile/Push/Exception/InvalidPayload.php'; throw new Zend_Mobile_Push_Exception_InvalidPayload('Missing message; the message must always have some content.'); break; case 5: require_once 'Zend/Mobile/Push/Exception/InvalidToken.php'; throw new Zend_Mobile_Push_Exception_InvalidToken('Bad token. This token is too big and is not a regular apns token.'); break; case 6: require_once 'Zend/Mobile/Push/Exception/InvalidTopic.php'; throw new Zend_Mobile_Push_Exception_InvalidTopic('The message id is too big; reduce the size of the id.'); break; case 7: require_once 'Zend/Mobile/Push/Exception/InvalidPayload.php'; throw new Zend_Mobile_Push_Exception_InvalidPayload('The message is too big; reduce the size of the message.'); break; case 8: require_once 'Zend/Mobile/Push/Exception/InvalidToken.php'; throw new Zend_Mobile_Push_Exception_InvalidToken('Bad token. Remove this token from being sent to again.'); break; default: throw new Zend_Mobile_Push_Exception(sprintf('An unknown error occurred: %d', $err['errno'])); break; } } return true; }
/** * Validate proper mpns message * * @return boolean */ public function validate() { if (!isset($this->_token) || strlen($this->_token) === 0) { return false; } return parent::validate(); }