seeder-migration-issues

This commit is contained in:
RafficMohammed
2023-01-30 14:23:34 +05:30
parent 4d918c722f
commit 2ec836b447
3628 changed files with 116006 additions and 187 deletions

View File

@@ -0,0 +1,7 @@
.DS_STORE
.*.un~
composer.lock
composer.phar
vendor/
php-cs-fixer.phar
/.project

View File

@@ -0,0 +1,18 @@
language: php
php:
- 5.3
- 5.4
- 5.5
- 5.6
- hhvm
before_install:
- cp tests/TestConfiguration.php.travis tests/TestConfiguration.php
- composer install --dev
script:
- phpunit -c tests/phpunit.xml.dist
notifications:
#irc: "irc.freenode.org#zftalk.2"

View File

@@ -0,0 +1,91 @@
# Changelog
All notable changes to this project will be documented in this file, in reverse chronological order by release.
## 1.2.0 - 2015-12-09
### Added
- [#36](https://github.com/zendframework/ZendService_Apple_Apns/pull/36)
Conection failures now raise a ```RuntimeException``` to allow you to catch
stream_socket_client(): SSL: Connection reset by peer warnings.
- [#39](https://github.com/zendframework/ZendService_Apple_Apns/pull/39) Add
safari push support
### Deprecated
- Nothing.
### Removed
- Nothing.
### Fixed
- Nothing.
## 1.1.2 - 2015-12-09
### Added
- Nothing.
### Deprecated
- Nothing.
### Removed
- Nothing.
### Fixed
- [#40](https://github.com/zendframework/ZendService_Apple_Apns/pull/40) Add
missing return $this
## 1.1.1 - 2015-10-13
### Added
- Nothing.
### Deprecated
- Nothing.
### Removed
- Nothing.
### Fixed
- [#38](https://github.com/zendframework/ZendService_Apple_Apns/pull/38) Fix
apns error response when sending a message.
- [#34](https://github.com/zendframework/ZendService_Apple_Apns/pull/34) Fixed
unit tests execution on travis
## 1.1.0 - 2015-07-29
### Added
- [#27](https://github.com/zendframework/ZendService_Apple_Apns/pull/27) Adds in
ANS category support.
- [#29](https://github.com/zendframework/ZendService_Apple_Apns/pull/29) Add in
ANS title, title-loc-key and title-loc-args.
### Deprecated
- Nothing.
### Removed
- Nothing.
### Fixed
- [#26](https://github.com/zendframework/ZendService_Apple_Apns/pull/26) Fixes a
possible infinity fread in certain PHP versions.
- [#28](https://github.com/zendframework/ZendService_Apple_Apns/pull/28) Fixed docblocks
that prevented proper code completion in some editors.
- [#29](https://github.com/zendframework/ZendService_Apple_Apns/pull/29) Force
TLS vs. SSL due to [Apple moving to TLS](https://developer.apple.com/news/?id=10222014a).

View File

@@ -0,0 +1,27 @@
Copyright (c) 2005-2014, Zend Technologies USA, Inc.
All rights reserved.
Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
* Neither the name of Zend Technologies USA, Inc. nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

View File

@@ -0,0 +1,22 @@
ZendService\Apple\Apns [![Build Status](https://travis-ci.org/zendframework/ZendService_Apple_Apns.png?branch=master)](https://travis-ci.org/zendframework/ZendService_Apple_Apns)
================================
Provides support for Apple push notifications.
## Requirements ##
* PHP >= 5.3.3
## Getting Started ##
Install this library using [Composer](http://getcomposer.org/):
```bash
$ composer require zendframework/zendservice-apple-apns
```
## Documentation ##
The documentation can be found at: http://framework.zend.com/manual/current/en/modules/zendservice.apple.apns.html

View File

@@ -0,0 +1,33 @@
{
"name": "zendframework/zendservice-apple-apns",
"description": "OOP Zend Framework 2 wrapper for Apple Push Notification Service",
"type": "library",
"keywords": [
"zf2",
"apns",
"push",
"notification",
"apple"
],
"homepage": "http://packages.zendframework.com/",
"license": "BSD-3-Clause",
"autoload": {
"psr-0": {
"ZendService\\Apple\\Apns\\": "library/",
"ZendService\\Apple\\Exception\\": "library/"
}
},
"repositories": [
{
"type": "composer",
"url": "http://packages.zendframework.com/"
}
],
"require": {
"php": ">=5.3.3",
"zendframework/zend-json": "~2.0"
},
"require-dev": {
"phpunit/phpunit": "3.7.*"
}
}

View File

@@ -0,0 +1,207 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendService\Apple\Apns\Client;
use ZendService\Apple\Exception;
use ZendService\Apple\Exception\StreamSocketClientException;
/**
* Apple Push Notification Abstract Client
*/
abstract class AbstractClient
{
/**
* APNS URI Constants
* @var int
*/
const SANDBOX_URI = 0;
const PRODUCTION_URI = 1;
/**
* APNS URIs
* @var array
*/
protected $uris = array();
/**
* Is Connected
* @var boolean
*/
protected $isConnected = false;
/**
* Stream Socket
* @var Resource
*/
protected $socket;
/**
* Open Connection to APNS Service
*
* @param int $environment
* @param string $certificate
* @param string $passPhrase
* @throws Exception\RuntimeException
* @throws Exception\InvalidArgumentException
* @return AbstractClient
*/
public function open($environment, $certificate, $passPhrase = null)
{
if ($this->isConnected) {
throw new Exception\RuntimeException('Connection has already been opened and must be closed');
}
if (!array_key_exists($environment, $this->uris)) {
throw new Exception\InvalidArgumentException('Environment must be one of PRODUCTION_URI or SANDBOX_URI');
}
if (!is_string($certificate) || !file_exists($certificate)) {
throw new Exception\InvalidArgumentException('Certificate must be a valid path to a APNS certificate');
}
$sslOptions = array(
'local_cert' => $certificate,
);
if ($passPhrase !== null) {
if (!is_scalar($passPhrase)) {
throw new Exception\InvalidArgumentException('SSL passphrase must be a scalar');
}
$sslOptions['passphrase'] = $passPhrase;
}
$this->connect($this->uris[$environment], $sslOptions);
$this->isConnected = true;
return $this;
}
/**
* Connect to Host
*
* @param string $host
* @param array $ssl
* @return AbstractClient
*/
protected function connect($host, array $ssl)
{
set_error_handler(function ($errno, $errstr, $errfile, $errline) {
throw new StreamSocketClientException($errstr, $errno, 1, $errfile, $errline);
});
try {
$this->socket = stream_socket_client(
$host,
$errno,
$errstr,
ini_get('default_socket_timeout'),
STREAM_CLIENT_CONNECT,
stream_context_create(
array(
'ssl' => $ssl,
)
)
);
} catch (StreamSocketClientException $e) {
throw new Exception\RuntimeException(sprintf(
'Unable to connect: %s: %d (%s)',
$host,
$e->getCode(),
$e->getMessage()
));
}
restore_error_handler();
if (!$this->socket) {
throw new Exception\RuntimeException(sprintf(
'Unable to connect: %s: %d (%s)',
$host,
$errno,
$errstr
));
}
stream_set_blocking($this->socket, 0);
stream_set_write_buffer($this->socket, 0);
return $this;
}
/**
* Close Connection
*
* @return AbstractClient
*/
public function close()
{
if ($this->isConnected && is_resource($this->socket)) {
fclose($this->socket);
}
$this->isConnected = false;
return $this;
}
/**
* Is Connected
*
* @return boolean
*/
public function isConnected()
{
return $this->isConnected;
}
/**
* Read from the Server
*
* @param int $length
* @return string
*/
protected function read($length = 6)
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must open the connection prior to reading data');
}
$data = false;
$read = array($this->socket);
$null = null;
if (0 < @stream_select($read, $null, $null, 1, 0)) {
$data = @fread($this->socket, (int) $length);
}
return $data;
}
/**
* Write Payload to the Server
*
* @param string $payload
* @return int
*/
protected function write($payload)
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must open the connection prior to writing data');
}
return @fwrite($this->socket, $payload);
}
/**
* Destructor
*
* @return void
*/
public function __destruct()
{
$this->close();
}
}

View File

@@ -0,0 +1,48 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendService\Apple\Apns\Client;
use ZendService\Apple\Exception;
use ZendService\Apple\Apns\Response\Feedback as FeedbackResponse;
/**
* Feedback Client
*/
class Feedback extends AbstractClient
{
/**
* APNS URIs
* @var array
*/
protected $uris = array(
'tls://feedback.sandbox.push.apple.com:2196',
'tls://feedback.push.apple.com:2196'
);
/**
* Get Feedback
*
* @return array of ZendService\Apple\Apns\Response\Feedback
*/
public function feedback()
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must first open the connection by calling open()');
}
$tokens = array();
while ($token = $this->read(38)) {
$tokens[] = new FeedbackResponse($token);
}
return $tokens;
}
}

View File

@@ -0,0 +1,56 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @category ZendService
* @package ZendService_Apple
* @subpackage Apns
*/
namespace ZendService\Apple\Apns\Client;
use ZendService\Apple\Exception;
use ZendService\Apple\Apns\Message as ApnsMessage;
use ZendService\Apple\Apns\Response\Message as MessageResponse;
/**
* Message Client
*
* @category ZendService
* @package ZendService_Apple
* @subpackage Apns
*/
class Message extends AbstractClient
{
/**
* APNS URIs
* @var array
*/
protected $uris = array(
'tls://gateway.sandbox.push.apple.com:2195',
'tls://gateway.push.apple.com:2195',
);
/**
* Send Message
*
* @param ApnsMessage $message
* @return MessageResponse
*/
public function send(ApnsMessage $message)
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must first open the connection by calling open()');
}
$ret = $this->write($message->getPayloadJson());
if ($ret === false) {
throw new Exception\RuntimeException('Server is unavailable; please retry later');
}
return new MessageResponse($this->read());
}
}

View File

@@ -0,0 +1,419 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendService\Apple\Apns;
use ZendService\Apple\Exception;
use Zend\Json\Encoder as JsonEncoder;
/**
* APNs Message
*/
class Message
{
/**
* Identifier
* @var string
*/
protected $id;
/**
* APN Token
* @var string
*/
protected $token;
/**
* Expiration
* @var int|null
*/
protected $expire;
/**
* Alert Message
* @var Message\Alert|null
*/
protected $alert;
/**
* Badge
* @var int|null
*/
protected $badge;
/**
* Sound
* @var string|null
*/
protected $sound;
/**
* Content Available
* @var int|null
*/
protected $contentAvailable;
/**
* Category
* @var string|null
*/
protected $category;
/**
* URL Arguments
* @var array|null
*/
protected $urlArgs;
/**
* Custom Attributes
* @var array|null
*/
protected $custom;
/**
* Get Identifier
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* Set Identifier
*
* @param string $id
* @return Message
*/
public function setId($id)
{
if (!is_scalar($id)) {
throw new Exception\InvalidArgumentException('Identifier must be a scalar value');
}
$this->id = $id;
return $this;
}
/**
* Get Token
*
* @return string
*/
public function getToken()
{
return $this->token;
}
/**
* Set Token
*
* @param string $token
* @return Message
*/
public function setToken($token)
{
if (!is_string($token)) {
throw new Exception\InvalidArgumentException(sprintf(
'Device token must be a string, "%s" given.',
gettype($token)
));
}
if (preg_match('/[^0-9a-f]/', $token)) {
throw new Exception\InvalidArgumentException(sprintf(
'Device token must be mask "%s". Token given: "%s"',
'/[^0-9a-f]/',
$token
));
}
if (strlen($token) != 64) {
throw new Exception\InvalidArgumentException(sprintf(
'Device token must be a 64 charsets, Token length given: %d.',
mb_strlen($token)
));
}
$this->token = $token;
return $this;
}
/**
* Get Expiration
*
* @return int
*/
public function getExpire()
{
return $this->expire;
}
/**
* Set Expiration
*
* @param int|DateTime $expire
* @return Message
*/
public function setExpire($expire)
{
if ($expire instanceof \DateTime) {
$expire = $expire->getTimestamp();
} elseif (!is_numeric($expire) || $expire != (int) $expire) {
throw new Exception\InvalidArgumentException('Expiration must be a DateTime object or a unix timestamp');
}
$this->expire = $expire;
return $this;
}
/**
* Get Alert
*
* @return Message\Alert|null
*/
public function getAlert()
{
return $this->alert;
}
/**
* Set Alert
*
* @param string|Message\Alert|null $alert
* @return Message
*/
public function setAlert($alert)
{
if (!$alert instanceof Message\Alert && !is_null($alert)) {
$alert = new Message\Alert($alert);
}
$this->alert = $alert;
return $this;
}
/**
* Get Badge
*
* @return int|null
*/
public function getBadge()
{
return $this->badge;
}
/**
* Set Badge
*
* @param int|null $badge
* @return Message
*/
public function setBadge($badge)
{
if ($badge !== null && !$badge == (int) $badge) {
throw new Exception\InvalidArgumentException('Badge must be null or an integer');
}
$this->badge = $badge;
return $this;
}
/**
* Get Sound
*
* @return string|null
*/
public function getSound()
{
return $this->sound;
}
/**
* Set Sound
*
* @param string|null $sound
* @return Message
*/
public function setSound($sound)
{
if ($sound !== null && !is_string($sound)) {
throw new Exception\InvalidArgumentException('Sound must be null or a string');
}
$this->sound = $sound;
return $this;
}
/**
* Get Content Available
*
* @return int|null
*/
public function getContentAvailable()
{
return $this->contentAvailable;
}
/**
* Set Content Available
*
* @param int|null $sound
* @return Message
*/
public function setContentAvailable($value)
{
if ($value !== null && !is_int($value)) {
throw new Exception\InvalidArgumentException('Content Available must be null or an integer');
}
$this->contentAvailable = $value;
return $this;
}
/**
* Get Category
*
* @return string|null
*/
public function getCategory()
{
return $this->category;
}
/**
* Set Category
*
* @param string|null $category
* @return Message
*/
public function setCategory($category)
{
if ($category !== null && !is_string($category)) {
throw new Exception\InvalidArgumentException('Category must be null or a string');
}
$this->category = $category;
return $this;
}
/**
* Get URL arguments
*
* @return array|null
*/
public function getUrlArgs()
{
return $this->urlArgs;
}
/**
* Set URL arguments
*
* @param array|null $urlArgs
* @return Message
*/
public function setUrlArgs(array $urlArgs)
{
$this->urlArgs = $urlArgs;
return $this;
}
/**
* Get Custom Data
*
* @return array|null
*/
public function getCustom()
{
return $this->custom;
}
/**
* Set Custom Data
*
* @param array $custom
* @throws Exception\RuntimeException
* @return Message
*/
public function setCustom(array $custom)
{
if (array_key_exists('aps', $custom)) {
throw new Exception\RuntimeException('custom data must not contain aps key as it is reserved by apple');
}
$this->custom = $custom;
return $this;
}
/**
* Get Payload
* Generate APN array.
*
* @return array
*/
public function getPayload()
{
$message = array();
$aps = array();
if ($this->alert && ($alert = $this->alert->getPayload())) {
$aps['alert'] = $alert;
}
if (!is_null($this->badge)) {
$aps['badge'] = $this->badge;
}
if (!is_null($this->sound)) {
$aps['sound'] = $this->sound;
}
if (!is_null($this->contentAvailable)) {
$aps['content-available'] = $this->contentAvailable;
}
if (!is_null($this->category)) {
$aps['category'] = $this->category;
}
if (!is_null($this->urlArgs)) {
$aps['url-args'] = $this->urlArgs;
}
if (!empty($this->custom)) {
$message = array_merge($this->custom, $message);
}
if (!empty($aps)) {
$message['aps'] = $aps;
}
return $message;
}
/**
* Get Payload JSON
*
* @return string
*/
public function getPayloadJson()
{
$payload = $this->getPayload();
// don't escape utf8 payloads unless json_encode does not exist.
if (defined('JSON_UNESCAPED_UNICODE')) {
$payload = json_encode($payload, JSON_UNESCAPED_UNICODE);
} else {
$payload = JsonEncoder::encode($payload);
}
$length = strlen($payload);
return pack('CNNnH*', 1, $this->id, $this->expire, 32, $this->token)
. pack('n', $length)
. $payload;
}
}

View File

@@ -0,0 +1,345 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendService\Apple\Apns\Message;
use ZendService\Apple\Exception;
/**
* Message Alert Object
*/
class Alert
{
/**
* Message Body
* @var string|null
*/
protected $body;
/**
* Action Locale Key
* @var string|null
*/
protected $actionLocKey;
/**
* Locale Key
* @var string|null
*/
protected $locKey;
/**
* Locale Arguments
* @var array|null
*/
protected $locArgs;
/**
* Launch Image
* @var string|null
*/
protected $launchImage;
/**
* Message Title
* @var string|null
*/
protected $title;
/**
* Title Locale Key
* @var string|null
*/
protected $titleLocKey;
/**
* Title Locale Arguments
* @var array|null
*/
protected $titleLocArgs;
/**
* Constructor
*
* @param string $body
* @param string $actionLocKey
* @param string $locKey
* @param array $locArgs
* @param string $launchImage
* @return Alert
*/
public function __construct($body = null, $actionLocKey = null, $locKey = null, $locArgs = null, $launchImage = null, $title = null, $titleLocKey = null, $titleLocArgs = null)
{
if ($body !== null) {
$this->setBody($body);
}
if ($actionLocKey !== null) {
$this->setActionLocKey($actionLocKey);
}
if ($locKey !== null) {
$this->setLocKey($locKey);
}
if ($locArgs !== null) {
$this->setLocArgs($locArgs);
}
if ($launchImage !== null) {
$this->setLaunchImage($launchImage);
}
if ($title !== null) {
$this->setTitle($title);
}
if ($titleLocKey !== null) {
$this->setTitleLocKey($titleLocKey);
}
if ($titleLocArgs !== null) {
$this->setTitleLocArgs($titleLocArgs);
}
}
/**
* Get Body
*
* @return string|null
*/
public function getBody()
{
return $this->body;
}
/**
* Set Body
*
* @param string|null $body
* @return Alert
*/
public function setBody($body)
{
if (!is_null($body) && !is_scalar($body)) {
throw new Exception\InvalidArgumentException('Body must be null OR a scalar value');
}
$this->body = $body;
return $this;
}
/**
* Get Action Locale Key
*
* @return string|null
*/
public function getActionLocKey()
{
return $this->actionLocKey;
}
/**
* Set Action Locale Key
*
* @param string|null $key
* @return Alert
*/
public function setActionLocKey($key)
{
if (!is_null($key) && !is_scalar($key)) {
throw new Exception\InvalidArgumentException('ActionLocKey must be null OR a scalar value');
}
$this->actionLocKey = $key;
return $this;
}
/**
* Get Locale Key
*
* @return string|null
*/
public function getLocKey()
{
return $this->locKey;
}
/**
* Set Locale Key
*
* @param string|null $key
* @return Alert
*/
public function setLocKey($key)
{
if (!is_null($key) && !is_scalar($key)) {
throw new Exception\InvalidArgumentException('LocKey must be null OR a scalar value');
}
$this->locKey = $key;
return $this;
}
/**
* Get Locale Arguments
*
* @return array|null
*/
public function getLocArgs()
{
return $this->locArgs;
}
/**
* Set Locale Arguments
*
* @param array $args
* @return Alert
*/
public function setLocArgs(array $args)
{
foreach ($args as $a) {
if (!is_scalar($a)) {
throw new Exception\InvalidArgumentException('Arguments must only contain scalar values');
}
}
$this->locArgs = $args;
return $this;
}
/**
* Get Launch Image
*
* @return string|null
*/
public function getLaunchImage()
{
return $this->launchImage;
}
/**
* Set Launch Image
*
* @param string|null $image
* @return Alert
*/
public function setLaunchImage($image)
{
if (!is_null($image) && !is_scalar($image)) {
throw new Exception\InvalidArgumentException('Launch image must be null OR a scalar value');
}
$this->launchImage = $image;
return $this;
}
/**
* Get Title
*
* @return string|null
*/
public function getTitle()
{
return $this->title;
}
/**
* Set Title
*
* @param string|null $title
* @return Alert
*/
public function setTitle($title)
{
if (!is_null($title) && !is_scalar($title)) {
throw new Exception\InvalidArgumentException('Title must be null OR a scalar value');
}
$this->title = $title;
return $this;
}
/**
* Get Title Locale Key
*
* @return string|null
*/
public function getTitleLocKey()
{
return $this->titleLocKey;
}
/**
* Set Title Locale Key
*
* @param string|null $key
* @return Alert
*/
public function setTitleLocKey($key)
{
if (!is_null($key) && !is_scalar($key)) {
throw new Exception\InvalidArgumentException('TitleLocKey must be null OR a scalar value');
}
$this->titleLocKey = $key;
return $this;
}
/**
* Get Title Locale Arguments
*
* @return array|null
*/
public function getTitleLocArgs()
{
return $this->titleLocArgs;
}
/**
* Set Title Locale Arguments
*
* @param array $args
* @return Alert
*/
public function setTitleLocArgs(array $args)
{
foreach ($args as $a) {
if (!is_scalar($a)) {
throw new Exception\InvalidArgumentException('Title Arguments must only contain scalar values');
}
}
$this->titleLocArgs = $args;
return $this;
}
/**
* To Payload
* Formats an APS alert.
*
* @return array|string
*/
public function getPayload()
{
$vars = get_object_vars($this);
if (empty($vars)) {
return null;
}
$alert = array();
foreach ($vars as $key => $value) {
if (!is_null($value)) {
$key = strtolower(preg_replace('/([a-z])([A-Z])/', '$1-$2', $key));
$alert[$key] = $value;
}
}
if (count($alert) === 1) {
return $this->getBody();
}
return $alert;
}
}

View File

@@ -0,0 +1,107 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendService\Apple\Apns\Response;
use ZendService\Apple\Exception;
/**
* Feedback Response
*/
class Feedback
{
/**
* APNS Token
* @var string
*/
protected $token;
/**
* Time
* @var int
*/
protected $time;
/**
* Constructor
*
* @param string $rawResponse
* @return Feedback
*/
public function __construct($rawResponse = null)
{
if ($rawResponse !== null) {
$this->parseRawResponse($rawResponse);
}
}
/**
* Get Token
*
* @return string
*/
public function getToken()
{
return $this->token;
}
/**
* Set Token
*
* @return Feedback
*/
public function setToken($token)
{
if (!is_scalar($token)) {
throw new Exception\InvalidArgumentException('Token must be a scalar value');
}
$this->token = $token;
return $this;
}
/**
* Get Time
*
* @return int
*/
public function getTime()
{
return $this->time;
}
/**
* Set Time
*
* @param int $time
* @return Feedback
*/
public function setTime($time)
{
$this->time = (int) $time;
return $this;
}
/**
* Parse Raw Response
*
* @return Feedback
*/
public function parseRawResponse($rawResponse)
{
$rawResponse = trim($rawResponse);
$token = unpack('Ntime/nlength/H*token', $rawResponse);
$this->setTime($token['time']);
$this->setToken(substr($token['token'], 0, $token['length'] * 2));
return $this;
}
}

View File

@@ -0,0 +1,141 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @category ZendService
* @package ZendService_Apple
* @subpackage Apns
*/
namespace ZendService\Apple\Apns\Response;
use ZendService\Apple\Exception;
/**
* Message Response
*
* @category ZendService
* @package ZendService_Apple
* @subpackage Apns
*/
class Message
{
/**
* Response Codes
* @var int
*/
const RESULT_OK = 0;
const RESULT_PROCESSING_ERROR = 1;
const RESULT_MISSING_TOKEN = 2;
const RESULT_MISSING_TOPIC = 3;
const RESULT_MISSING_PAYLOAD = 4;
const RESULT_INVALID_TOKEN_SIZE = 5;
const RESULT_INVALID_TOPIC_SIZE = 6;
const RESULT_INVALID_PAYLOAD_SIZE = 7;
const RESULT_INVALID_TOKEN = 8;
const RESULT_UNKNOWN_ERROR = 255;
/**
* Identifier
* @var string
*/
protected $id;
/**
* Result Code
* @var int
*/
protected $code;
/**
* Constructor
*
* @param string $rawResponse
* @return Message
*/
public function __construct($rawResponse = null)
{
if ($rawResponse !== null) {
$this->parseRawResponse($rawResponse);
}
}
/**
* Get Code
*
* @return int
*/
public function getCode()
{
return $this->code;
}
/**
* Set Code
*
* @param int $code
* @return Message
*/
public function setCode($code)
{
if (($code < 0 || $code > 8) && $code != 255) {
throw new Exception\InvalidArgumentException('Code must be between 0-8 OR 255');
}
$this->code = $code;
return $this;
}
/**
* Get Identifier
*
* @return string
*/
public function getId()
{
return $this->id;
}
/**
* Set Identifier
*
* @param string $id
* @return Message
*/
public function setId($id)
{
if (!is_scalar($id)) {
throw new Exception\InvalidArgumentException('Identifier must be a scalar value');
}
$this->id = $id;
return $this;
}
/**
* Parse Raw Response
*
* @param string $rawResponse
* @return Message
*/
public function parseRawResponse($rawResponse)
{
if (!is_scalar($rawResponse)) {
throw new Exception\InvalidArgumentException('Response must be a scalar value');
}
if (strlen($rawResponse) === 0) {
$this->code = self::RESULT_OK;
return $this;
}
$response = unpack('Ccmd/Cerrno/Nid', $rawResponse);
$this->setId($response['id']);
$this->setCode($response['errno']);
return $this;
}
}

View File

@@ -0,0 +1,18 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendService\Apple\Exception;
/**
* Invalid Argument Exception
*/
class InvalidArgumentException extends \InvalidArgumentException
{
}

View File

@@ -0,0 +1,15 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendService\Apple\Exception;
class RuntimeException extends \RuntimeException
{
}

View File

@@ -0,0 +1,13 @@
<?php
/**
* Exception for creating stream_socket_client
* @author Soshnikov Artem <213036@skobka.com>
*/
namespace ZendService\Apple\Exception;
use ErrorException;
class StreamSocketClientException extends ErrorException
{
}

View File

@@ -0,0 +1,2 @@
phpunit.xml
TestConfiguration.php

View File

@@ -0,0 +1,93 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2013 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend
*/
/*
* Set error reporting to the level to which Zend Framework code must comply.
*/
error_reporting(E_ALL | E_STRICT);
if (class_exists('PHPUnit_Runner_Version', true)) {
$phpUnitVersion = PHPUnit_Runner_Version::id();
if ('@package_version@' !== $phpUnitVersion && version_compare($phpUnitVersion, '3.7.0', '<')) {
echo 'This version of PHPUnit (' . PHPUnit_Runner_Version::id() . ') is not supported in Zend Framework 2.x unit tests.' . PHP_EOL;
exit(1);
}
unset($phpUnitVersion);
}
/*
* Determine the root, library, and tests directories of the framework
* distribution.
*/
$zfRoot = realpath(dirname(__DIR__));
$zfCoreLibrary = "$zfRoot/library";
$zfCoreTests = "$zfRoot/tests";
/*
* Prepend the Zend Framework library/ and tests/ directories to the
* include_path. This allows the tests to run out of the box and helps prevent
* loading other copies of the framework code and tests that would supersede
* this copy.
*/
$path = array(
$zfCoreLibrary,
$zfCoreTests,
get_include_path(),
);
set_include_path(implode(PATH_SEPARATOR, $path));
/**
* Setup autoloading
*/
include __DIR__ . '/_autoload.php';
/*
* Load the user-defined test configuration file, if it exists; otherwise, load
* the default configuration.
*/
if (is_readable($zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php')) {
require_once $zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php';
} else {
require_once $zfCoreTests . DIRECTORY_SEPARATOR . 'TestConfiguration.php.dist';
}
if (defined('TESTS_GENERATE_REPORT') && TESTS_GENERATE_REPORT === true) {
$codeCoverageFilter = new PHP_CodeCoverage_Filter();
$lastArg = end($_SERVER['argv']);
if (is_dir($zfCoreTests . '/' . $lastArg)) {
$codeCoverageFilter->addDirectoryToWhitelist($zfCoreLibrary . '/' . $lastArg);
} elseif (is_file($zfCoreTests . '/' . $lastArg)) {
$codeCoverageFilter->addDirectoryToWhitelist(dirname($zfCoreLibrary . '/' . $lastArg));
} else {
$codeCoverageFilter->addDirectoryToWhitelist($zfCoreLibrary);
}
/*
* Omit from code coverage reports the contents of the tests directory
*/
$codeCoverageFilter->addDirectoryToBlacklist($zfCoreTests, '');
$codeCoverageFilter->addDirectoryToBlacklist(PEAR_INSTALL_DIR, '');
$codeCoverageFilter->addDirectoryToBlacklist(PHP_LIBDIR, '');
unset($codeCoverageFilter);
}
/**
* Start output buffering, if enabled
*/
if (defined('TESTS_ZEND_OB_ENABLED') && constant('TESTS_ZEND_OB_ENABLED')) {
ob_start();
}
/*
* Unset global variables that are no longer needed.
*/
unset($zfRoot, $zfCoreLibrary, $zfCoreTests, $path);

View File

@@ -0,0 +1,45 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package UnitTests
*/
/**
* This file defines configuration for running the unit tests for the Zend
* Framework. Some tests have dependencies to PHP extensions or databases
* which may not necessary installed on the target system. For these cases,
* the ability to disable or configure testing is provided below. Tests for
* components which should run universally are always run by the master
* suite and cannot be disabled.
*
* Do not edit this file. Instead, copy this file to TestConfiguration.php,
* and edit the new file. Never commit passwords to the source code repository.
*/
/**
* Use the notation:
*
* defined(...) || define(...);
*
* This ensures that, when a test is marked to run in a separate process,
* PHP will not complain of a constant already being defined.
*/
/**
* GENERAL SETTINGS
*
* OB_ENABLED should be enabled for some tests to check if all functionality
* works as expected. Such tests include those for Zend\Soap and Zend\Session,
* which require that headers not be sent in order to work.
*/
defined('TESTS_ZEND_OB_ENABLED') || define('TESTS_ZEND_OB_ENABLED', false);
/**
* PHPUnit Code Coverage / Test Report
*/
defined('TESTS_GENERATE_REPORT') || define('TESTS_GENERATE_REPORT', false);
defined('TESTS_GENERATE_REPORT_TARGET') || define('TESTS_GENERATE_REPORT_TARGET', '/path/to/target');

View File

@@ -0,0 +1,20 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package UnitTests
*/
/**
* This file defines specific configuration that differs from the standard configuration
* for running the unit tests with Travis-CI (http://www.travis-ci.org)
*
* See TestConfiguration.php.dist to get more details.
*
* Never commit passwords to the source code repository.
*/
require_once __DIR__ . '/TestConfiguration.php.dist';

View File

@@ -0,0 +1,48 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendServiceTest\Apple\Apns;
use ZendServiceTest\Apple\Apns\TestAsset\FeedbackClient;
/**
* @category ZendService
* @package ZendService_Apple
* @subpackage UnitTests
* @group ZendService
* @group ZendService_Apple
* @group ZendService_Apple_Apns
*/
class FeedbackClientTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->apns = new FeedbackClient();
}
protected function setupValidBase()
{
$this->apns->open(FeedbackClient::SANDBOX_URI, __DIR__ . '/TestAsset/certificate.pem');
}
public function testFeedback()
{
$this->setupValidBase();
$time = time();
$token = 'abc123';
$length = strlen($token) / 2;
$this->apns->setReadResponse(pack('NnH*', $time, $length, $token));
$response = $this->apns->feedback();
$this->assertCount(1, $response);
$feedback = array_shift($response);
$this->assertEquals($time, $feedback->getTime());
$this->assertEquals($token, $feedback->getToken());
}
}

View File

@@ -0,0 +1,176 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @category ZendService
* @package ZendService_Apple
* @subpackage UnitTests
*/
namespace ZendServiceTest\Apple\Apns;
use ZendServiceTest\Apple\Apns\TestAsset\MessageClient;
use ZendService\Apple\Apns\Message;
use ZendService\Apple\Apns\Response\Message as MessageResponse;
/**
* @category ZendService
* @package ZendService_Apple
* @subpackage UnitTests
* @group ZendService
* @group ZendService_Apple
* @group ZendService_Apple_Apns
*/
class MessageClientTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->apns = new MessageClient();
$this->message = new Message();
}
protected function setupValidBase()
{
$this->apns->open(MessageClient::SANDBOX_URI, __DIR__ . '/TestAsset/certificate.pem');
$this->message->setToken('662cfe5a69ddc65cdd39a1b8f8690647778204b064df7b264e8c4c254f94fdd8');
$this->message->setId(time());
$this->message->setAlert('bar');
}
public function testConnectThrowsExceptionOnInvalidEnvironment()
{
$this->setExpectedException('InvalidArgumentException');
$this->apns->open(5, __DIR__ . '/TestAsset/certificate.pem');
}
public function testSetCertificateThrowsExceptionOnNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->apns->open(MessageClient::PRODUCTION_URI, array('foo'));
}
public function testSetCertificateThrowsExceptionOnMissingFile()
{
$this->setExpectedException('InvalidArgumentException');
$this->apns->open(MessageClient::PRODUCTION_URI, 'foo');
}
public function testSetCertificatePassphraseThrowsExceptionOnNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->apns->open(MessageClient::PRODUCTION_URI, __DIR__ . '/TestAsset/certificate.pem', array('foo'));
}
public function testOpen()
{
$ret = $this->apns->open(MessageClient::SANDBOX_URI, __DIR__ . '/TestAsset/certificate.pem');
$this->assertEquals($this->apns, $ret);
$this->assertTrue($this->apns->isConnected());
}
public function testClose()
{
$this->apns->open(MessageClient::SANDBOX_URI, __DIR__ . '/TestAsset/certificate.pem');
$this->apns->close();
$this->assertFalse($this->apns->isConnected());
}
public function testOpenWhenAlreadyOpenThrowsException()
{
$this->setExpectedException('RuntimeException');
$this->apns->open(MessageClient::SANDBOX_URI, __DIR__ . '/TestAsset/certificate.pem');
$this->apns->open(MessageClient::SANDBOX_URI, __DIR__ . '/TestAsset/certificate.pem');
}
public function testSendReturnsTrueOnSuccess()
{
$this->setupValidBase();
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_OK, $response->getCode());
$this->assertNull($response->getId());
}
public function testSendResponseOnProcessingError()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 1, 1, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_PROCESSING_ERROR, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnMissingToken()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 2, 2, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_MISSING_TOKEN, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnMissingTopic()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 3, 3, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_MISSING_TOPIC, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnMissingPayload()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 4, 4, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_MISSING_PAYLOAD, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnInvalidTokenSize()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 5, 5, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_INVALID_TOKEN_SIZE, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnInvalidTopicSize()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 6, 6, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_INVALID_TOPIC_SIZE, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnInvalidPayloadSize()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 7, 7, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_INVALID_PAYLOAD_SIZE, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnInvalidToken()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 8, 8, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_INVALID_TOKEN, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
public function testSendResponseOnUnknownError()
{
$this->setupValidBase();
$this->apns->setReadResponse(pack('CCN*', 255, 255, 12345));
$response = $this->apns->send($this->message);
$this->assertEquals(MessageResponse::RESULT_UNKNOWN_ERROR, $response->getCode());
$this->assertEquals(12345, $response->getId());
}
}

View File

@@ -0,0 +1,275 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendServiceTest\Apple\Apns\TestAsset;
use ZendService\Apple\Apns\Message;
use ZendService\Apple\Apns\Message\Alert;
use Zend\Json\Encoder as JsonEncoder;
/**
* @category ZendService
* @package ZendService_Apple
* @subpackage UnitTests
* @group ZendService
* @group ZendService_Apple
* @group ZendService_Apple_Apns
*/
class MessageTest extends \PHPUnit_Framework_TestCase
{
public function setUp()
{
$this->alert = new Alert();
$this->message = new Message();
}
public function testSetAlertTextReturnsCorrectly()
{
$text = 'my alert';
$ret = $this->message->setAlert($text);
$this->assertInstanceOf('ZendService\Apple\Apns\Message', $ret);
$checkText = $this->message->getAlert();
$this->assertInstanceOf('ZendService\Apple\Apns\Message\Alert', $checkText);
$this->assertEquals($text, $checkText->getBody());
}
public function testSetAlertThrowsExceptionOnTextNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setAlert(array());
}
public function testSetAlertThrowsExceptionOnActionLocKeyNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->alert->setActionLocKey(array());
}
public function testSetAlertThrowsExceptionOnLocKeyNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->alert->setLocKey(array());
}
public function testSetAlertThrowsExceptionOnLaunchImageNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->alert->setLaunchImage(array());
}
public function testSetAlertThrowsExceptionOnTitleNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->alert->setTitle(array());
}
public function testSetAlertThrowsExceptionOnTitleLocKeyNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->alert->setTitleLocKey(array());
}
public function testSetBadgeReturnsCorrectNumber()
{
$num = 5;
$this->message->setBadge($num);
$this->assertEquals($num, $this->message->getBadge());
}
public function testSetBadgeNonNumericThrowsException()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setBadge('string!');
}
public function testSetBadgeAllowsNull()
{
$this->message->setBadge(null);
$this->assertNull($this->message->getBadge());
}
public function testSetExpireReturnsInteger()
{
$expire = 100;
$this->message->setExpire($expire);
$this->assertEquals($expire, $this->message->getExpire());
}
public function testSetExpireNonNumericThrowsException()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setExpire('sting!');
}
public function testSetSoundReturnsString()
{
$sound = 'test';
$this->message->setSound($sound);
$this->assertEquals($sound, $this->message->getSound());
}
public function testSetSoundThrowsExceptionOnNonScalar()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setSound(array());
}
public function testSetSoundThrowsExceptionOnNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setSound(12345);
}
public function testSetContentAvailableThrowsExceptionOnNonInteger()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setContentAvailable("string");
}
public function testGetContentAvailableReturnsCorrectInteger()
{
$value = 1;
$this->message->setContentAvailable($value);
$this->assertEquals($value, $this->message->getContentAvailable());
}
public function testSetContentAvailableResultsInCorrectPayload()
{
$value = 1;
$this->message->setContentAvailable($value);
$payload = $this->message->getPayload();
$this->assertEquals($value, $payload['aps']['content-available']);
}
public function testSetCategoryReturnsString()
{
$category = 'test';
$this->message->setCategory($category);
$this->assertEquals($category, $this->message->getCategory());
}
public function testSetCategoryThrowsExceptionOnNonScalar()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setCategory(array());
}
public function testSetCategoryThrowsExceptionOnNonString()
{
$this->setExpectedException('InvalidArgumentException');
$this->message->setCategory(12345);
}
public function testSetUrlArgsReturnsString()
{
$urlArgs = array('path/to/somewhere');
$this->message->setUrlArgs($urlArgs);
$this->assertEquals($urlArgs, $this->message->getUrlArgs());
}
public function testSetCustomData()
{
$data = array('key' => 'val', 'key2' => array(1, 2, 3, 4, 5));
$this->message->setCustom($data);
$this->assertEquals($data, $this->message->getCustom());
}
public function testAlertConstructor()
{
$alert = new Alert(
'Foo wants to play Bar!',
'PLAY',
'GAME_PLAY_REQUEST_FORMAT',
array('Foo', 'Baz'),
'Default.png',
'Alert',
'ALERT',
array('Foo', 'Baz')
);
$this->assertEquals('Foo wants to play Bar!', $alert->getBody());
$this->assertEquals('PLAY', $alert->getActionLocKey());
$this->assertEquals('GAME_PLAY_REQUEST_FORMAT', $alert->getLocKey());
$this->assertEquals(array('Foo', 'Baz'), $alert->getLocArgs());
$this->assertEquals('Default.png', $alert->getLaunchImage());
$this->assertEquals('Alert', $alert->getTitle());
$this->assertEquals('ALERT', $alert->getTitleLocKey());
$this->assertEquals(array('Foo', 'Baz'), $alert->getTitleLocArgs());
}
public function testAlertJsonPayload()
{
$alert = new Alert(
'Foo wants to play Bar!',
'PLAY',
'GAME_PLAY_REQUEST_FORMAT',
array('Foo', 'Baz'),
'Default.png',
'Alert',
'ALERT',
array('Foo', 'Baz')
);
$payload = $alert->getPayload();
$this->assertArrayHasKey('body', $payload);
$this->assertArrayHasKey('action-loc-key', $payload);
$this->assertArrayHasKey('loc-key', $payload);
$this->assertArrayHasKey('loc-args', $payload);
$this->assertArrayHasKey('launch-image', $payload);
$this->assertArrayHasKey('title', $payload);
$this->assertArrayHasKey('title-loc-key', $payload);
$this->assertArrayHasKey('title-loc-args', $payload);
}
public function testAlertPayloadSendsOnlyBody()
{
$alert = new Alert('Foo wants Bar');
$payload = $alert->getPayload();
$this->assertEquals('Foo wants Bar', $payload);
}
public function testPayloadJsonFormedCorrectly()
{
$text = 'hi=привет';
$this->message->setAlert($text);
$this->message->setId(1);
$this->message->setExpire(100);
$this->message->setToken('0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef');
$payload = $this->message->getPayload();
$this->assertEquals($payload, array('aps' => array('alert' => 'hi=привет')));
if (defined('JSON_UNESCAPED_UNICODE')) {
$payloadJson = json_encode($payload, JSON_UNESCAPED_UNICODE);
$this->assertEquals($payloadJson, '{"aps":{"alert":"hi=привет"}}');
$length = 35; // 23 + (2 * 6) because UTF-8 (Russian) "привет" contains 2 bytes per letter
$result = pack('CNNnH*', 1, $this->message->getId(), $this->message->getExpire(), 32, $this->message->getToken())
. pack('n', $length)
. $payloadJson;
$this->assertEquals($this->message->getPayloadJson(), $result);
} else {
$payloadJson = JsonEncoder::encode($payload);
$this->assertEquals($payloadJson, '{"aps":{"alert":"hi=\u043f\u0440\u0438\u0432\u0435\u0442"}}');
$length = 59; // (23 + (6 * 6) because UTF-8 (Russian) "привет" converts into 6 bytes per letter constructions
$result = pack('CNNnH*', 1, $this->message->getId(), $this->message->getExpire(), 32, $this->message->getToken())
. pack('n', $length)
. $payloadJson;
$this->assertEquals($this->message->getPayloadJson(), $result);
}
}
public function testCustomDataPayloadDoesNotIncludeEmptyApsData()
{
$data = array('custom' => 'data');
$this->message->setCustom($data);
$payload = $this->message->getPayload();
$this->assertEquals($payload, array('custom' => 'data'));
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendServiceTest\Apple\Apns\TestAsset;
use ZendService\Apple\Apns\Exception;
use ZendService\Apple\Apns\Client\Feedback as ZfFeedbackClient;
/**
* Feedback Client Proxy
* This class is utilized for unit testing purposes
*
* @category ZendService
* @package ZendService_Apple
* @subpackage Apns
*/
class FeedbackClient extends ZfFeedbackClient
{
/**
* Read Response
*
* @var string
*/
protected $readResponse;
/**
* Write Response
*
* @var mixed
*/
protected $writeResponse;
/**
* Set the Response
*
* @param string $str
* @return FeedbackClient
*/
public function setReadResponse($str)
{
$this->readResponse = $str;
return $this;
}
/**
* Set the write response
*
* @param mixed $resp
* @return FeedbackClient
*/
public function setWriteResponse($resp)
{
$this->writeResponse = $resp;
return $this;
}
/**
* Connect to Host
*
* @return FeedbackClient
*/
protected function connect($host, array $ssl)
{
return $this;
}
/**
* Return Response
*
* @param string $length
* @return string
*/
protected function read($length = 1024)
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must open the connection prior to reading data');
}
$ret = substr($this->readResponse, 0, $length);
$this->readResponse = null;
return $ret;
}
/**
* Write and Return Length
*
* @param string $payload
* @return int
*/
protected function write($payload)
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must open the connection prior to writing data');
}
$ret = $this->writeResponse;
$this->writeResponse = null;
return (null === $ret) ? strlen($payload) : $ret;
}
}

View File

@@ -0,0 +1,109 @@
<?php
/**
* Zend Framework (http://framework.zend.com/)
*
* @link http://github.com/zendframework/zf2 for the canonical source repository
* @copyright Copyright (c) 2005-2014 Zend Technologies USA Inc. (http://www.zend.com)
* @license http://framework.zend.com/license/new-bsd New BSD License
* @package Zend_Service
*/
namespace ZendServiceTest\Apple\Apns\TestAsset;
use ZendService\Apple\Apns\Exception;
use ZendService\Apple\Apns\Client\Message as ZfMessageClient;
/**
* Message Client Proxy
* This class is utilized for unit testing purposes
*
* @category ZendService
* @package ZendService_Apple
* @subpackage Apns
*/
class MessageClient extends ZfMessageClient
{
/**
* Read Response
*
* @var string
*/
protected $readResponse;
/**
* Write Response
*
* @var mixed
*/
protected $writeResponse;
/**
* Set the Response
*
* @param string $str
* @return MessageClient
*/
public function setReadResponse($str)
{
$this->readResponse = $str;
return $this;
}
/**
* Set the write response
*
* @param mixed $resp
* @return MessageClient
*/
public function setWriteResponse($resp)
{
$this->writeResponse = $resp;
return $this;
}
/**
* Connect to Host
*
* @return MessageClient
*/
protected function connect($host, array $ssl)
{
return $this;
}
/**
* Return Response
*
* @param string $length
* @return string
*/
protected function read($length = 1024)
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must open the connection prior to reading data');
}
$ret = substr($this->readResponse, 0, $length);
$this->readResponse = null;
return $ret;
}
/**
* Write and Return Length
*
* @param string $payload
* @return int
*/
protected function write($payload)
{
if (!$this->isConnected()) {
throw new Exception\RuntimeException('You must open the connection prior to writing data');
}
$ret = $this->writeResponse;
$this->writeResponse = null;
return (null === $ret) ? strlen($payload) : $ret;
}
}

View File

@@ -0,0 +1,29 @@
<?php
/**
* Setup autoloading
*/
if (!file_exists(__DIR__ . '/../vendor/autoload.php')) {
throw new RuntimeException('This component has dependencies that are unmet.
Please install composer (http://getcomposer.org), and run the following
command in the root of this project:
php /path/to/composer.phar install
After that, you should be able to run tests.');
}
include_once __DIR__ . '/../vendor/autoload.php';
spl_autoload_register(function ($class) {
if (0 !== strpos($class, 'ZendServiceTest\\')) {
return false;
}
$normalized = str_replace('ZendServiceTest\\', '', $class);
$filename = __DIR__ . '/ZendService/' . str_replace(array('\\', '_'), '/', $normalized) . '.php';
if (!file_exists($filename)) {
return false;
}
return include_once $filename;
});

View File

@@ -0,0 +1,13 @@
<phpunit bootstrap="./Bootstrap.php" colors="true">
<testsuites>
<testsuite name="ZendService Apple Apns Test Suite">
<directory>./ZendService</directory>
</testsuite>
</testsuites>
<groups>
<exclude>
<group>disable</group>
</exclude>
</groups>
</phpunit>