Laravel version update

Laravel version update
This commit is contained in:
Manish Verma
2018-08-06 18:48:58 +05:30
parent d143048413
commit 126fbb0255
13678 changed files with 1031482 additions and 778530 deletions

View File

@@ -1,3 +1,3 @@
<?php
require_once __DIR__.'/vendor/autoload.php';
require_once __DIR__ . '/vendor/autoload.php';

View File

@@ -1,6 +1,6 @@
<?php
$runner->addTestsFromDirectory(__DIR__.'/tests/units');
$runner->addTestsFromDirectory(__DIR__ . '/tests/units');
$script->noCodeCoverageForNamespaces('mageekguy', 'Symfony');
$script->bootstrapFile(__DIR__.DIRECTORY_SEPARATOR.'.atoum.bootstrap.php');
$script->bootstrapFile(__DIR__ . DIRECTORY_SEPARATOR . '.atoum.bootstrap.php');

View File

@@ -1,4 +1,4 @@
bin
composer.lock
vendor/
web/
.idea/

View File

@@ -1,8 +1,10 @@
language: php
php:
- 5.5
- 5.6
- 7.0
- 7.1
- 7.2
before_script:
- composer self-update || true
@@ -20,5 +22,6 @@ notifications:
email:
recipients:
- cedric@dugat.me
- seyferseed@gmail.com
on_success: change
on_failure: change

View File

@@ -0,0 +1,5 @@
If you would like to contribute, please follow the standards defined in the [PSR-1][1], [PSR-2][2] and [PSR-4][4] documents.
[1]: http://www.php-fig.org/psr/psr-1/
[2]: http://www.php-fig.org/psr/psr-2/
[4]: http://www.php-fig.org/psr/psr-4/

View File

@@ -2,39 +2,60 @@
Standalone PHP library for easy devices message notifications push.
[![Latest Stable Version](https://poser.pugx.org/sly/notification-pusher/v/stable.png)](https://packagist.org/packages/sly/notification-pusher)
[![Total Downloads](https://poser.pugx.org/sly/notification-pusher/downloads.png)](https://packagist.org/packages/sly/notification-pusher)
[![Latest Stable Version](https://img.shields.io/packagist/v/sly/notification-pusher.svg)](https://packagist.org/packages/sly/notification-pusher)
[![License](https://img.shields.io/packagist/l/sly/notification-pusher.svg)](https://packagist.org/packages/sly/notification-pusher)
[![Total Downloads](https://img.shields.io/packagist/dt/sly/notification-pusher.svg)](https://packagist.org/packages/sly/notification-pusher)
[![Build Status](https://secure.travis-ci.org/Ph3nol/NotificationPusher.png)](http://travis-ci.org/Ph3nol/NotificationPusher)
[![SensioLabsInsight](https://insight.sensiolabs.com/projects/4f6f80c4-281a-4903-bf4c-1eb264995dbd/big.png)](https://insight.sensiolabs.com/projects/4f6f80c4-281a-4903-bf4c-1eb264995dbd)
**Feel free to contribute! Thanks.**
## Contributors
* [Cédric Dugat](https://github.com/Ph3nol) (Author / Lead developer)
* [Oleg Abrazhaev](https://github.com/seyfer) (Lead developer)
* [Community contributors](https://github.com/Ph3nol/NotificationPusher/graphs/contributors)
## Installation
```
composer require sly/notification-pusher
```
This repository uses PSR-0 autoload.
After installation with [composer](https://getcomposer.org/download/) please adjust you autoloading config if needed
or `include vendor/autoload.php` in your index.php.
## Requirements
* PHP 5.5+
* PHP 5.6+
* PHP Curl and OpenSSL modules
* Specific adapters requirements (like APNS certificate, GCM API key, etc.)
* Specific adapters requirements (like APNS certificate, GCM (FCM) API key, etc.)
**WARNING** Version `v3.0` would support only php 7.0+. Please, update your composer config if needed.
## Today available adapters
* APNS (Apple)
* GCM (Android)
* GCM (Android) and FCM (Android)
## Documentation and examples
* [Installation](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/installation.md)
* [Getting started](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/getting-started.md)
* [APNS adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/apns-adapter.md)
* [GCM adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-adapter.md)
* [GCM (FCM) adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-fcm-adapter.md)
* [Create an adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/create-an-adapter.md)
* [Push from CLI](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/push-from-cli.md)
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)
## Todo
* Add new features (custom APNS payloads, GCM custom options, etc.)
* Add new features (custom APNS payloads, GCM and FCM custom options, etc.)
* Add new adapters (like Blackberry and Windows phones)
* Write more documentation and examples
* Write more documentation and examples!
* Write more tests. (contributions are welcome!)
## 1.x users
@@ -42,4 +63,3 @@ Old version is still available from [1.x branch](https://github.com/Ph3nol/Notif
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/Ph3nol/notificationpusher/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

View File

@@ -1,40 +1,56 @@
{
"name": "sly/notification-pusher",
"description": "Standalone PHP library for easy devices notifications push.",
"keywords": ["apple", "iphone", "apns", "android", "gcm", "notification", "message", "push", "pusher"],
"homepage": "https://github.com/Ph3nol/NotificationPusher",
"type": "standalone",
"license": "MIT",
"authors": [
{
"name": "Cédric Dugat",
"email": "cedric@dugat.me"
},
{
"name": "Contributors",
"homepage": "https://github.com/Ph3nol/NotificationPusher/contributors"
}
],
"require": {
"php": ">=5.5",
"symfony/options-resolver": "~2.3|~3.0",
"symfony/console": "~2.3|~3.0",
"symfony/process": "~2.3|~3.0",
"zendframework/zendservice-apple-apns": "^1.1.0",
"zendframework/zendservice-google-gcm": "1.*",
"doctrine/inflector": "~1.0"
"name": "sly/notification-pusher",
"description": "Standalone PHP library for easy devices notifications push.",
"keywords": [
"apple",
"iphone",
"apns",
"android",
"gcm",
"notification",
"message",
"push",
"pusher"
],
"homepage": "https://github.com/Ph3nol/NotificationPusher",
"type": "standalone",
"license": "MIT",
"authors": [
{
"name": "Cédric Dugat",
"email": "cedric@dugat.me"
},
"require-dev": {
"atoum/atoum": "dev-master"
},
"config": {
"bin-dir": "bin"
},
"bin": ["np"],
"autoload": {
"psr-0": {
"Sly": "src/"
}
{
"name": "Contributors",
"homepage": "https://github.com/Ph3nol/NotificationPusher/contributors"
}
],
"require": {
"php": ">=5.6",
"symfony/options-resolver": ">=2.3,<5",
"symfony/console": ">=2.3,<5",
"symfony/process": ">=2.3,<5",
"zendframework/zendservice-apple-apns": "~1.0",
"zendframework/zendservice-google-gcm": "~2.0",
"doctrine/inflector": "1.*",
"symfony/filesystem": ">=2.3,<5",
"symfony/debug": ">=2.3,<5"
},
"require-dev": {
"atoum/atoum": "^3.1",
"atoum/stubs": "^2.5",
"symfony/var-dumper": ">=2.3,<5",
"atoum/visibility-extension": "^1.3"
},
"config": {
"bin-dir": "bin"
},
"bin": [
"np"
],
"autoload": {
"psr-0": {
"Sly": "src/"
}
}
}

1243
vendor/sly/notification-pusher/composer.lock generated vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -45,6 +45,10 @@ $message = new Message('This is a basic example of push.');
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
foreach($push->getResponses() as $token => $response) {
// ...
}
```
### Custom notification push example
@@ -137,11 +141,10 @@ $apnsAdapter = new ApnsAdapter(array(
$feedback = $pushManager->getFeedback($apnsAdapter); // Returns an array of Token + DateTime couples
```
## Documentation index
* [Installation](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/installation.md)
* [Getting started](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/getting-started.md)
* APNS adapter
* [GCM adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-adapter.md)
* [GCM (FCM) adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-fcm-adapter.md)
* [Create an adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/create-an-adapter.md)
* [Push from CLI](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/push-from-cli.md)
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)

View File

@@ -17,6 +17,7 @@ Feel free to observe [existent adapters](https://github.com/Ph3nol/NotificationP
* [Installation](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/installation.md)
* [Getting started](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/getting-started.md)
* [APNS adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/apns-adapter.md)
* [GCM adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-adapter.md)
* [GCM (FCM) adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-fcm-adapter.md)
* Create an adapter
* [Push from CLI](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/push-from-cli.md)
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)

View File

@@ -0,0 +1,105 @@
# NotificationPusher - Documentation
## Facades
In order to simplify lib usage some service facades were added.
They would return Response object with all information about sent pushes.
Also, facades provide useful methods to filter successful and invalid tokens from responses.
## Basic usage example
### The Response
```
$response->getParsedResponses();
$response->getOriginalResponses();
$response->getPushCollection();
```
### Android facade
```
$android_api_key = 'key';
//get tokens list from your service
$tokensA = ['token1', 'token2'];
//get messages
$messages = [
'hi Luc, it\'s test',
'test noty 2',
];
//maybe you want some params
$params = [];
//init android facade service
$pushNotificationService = new GcmPushService(
$android_api_key, PushManager::ENVIRONMENT_PROD
);
//push! you will get a Response with parsed and original response collections
//and with a push collection
$response = $pushNotificationService->push($tokensA, $messages, $params);
NOTE: if you need to pass not only data, but also notification array
use key notificationData in params, like $params[notificationData] = []
OR you could use optional GcmMessage class instead of Message and
use it's setter setNotificationData()
//easily access list of successful and invalid tokens
$invalidTokens = $pushNotificationService->getInvalidTokens();
$successfulTokens = $pushNotificationService->getSuccessfulTokens();
die(dump($response, $invalidTokens, $successfulTokens));
```
### APNS facade
```
$certificatePath = 'cert.pem';
$passPhrase = '';
//get tokens list
$tokensA = ['token1', 'token2'];
//get messages
$messages = [
'hi Luc, it\'s test',
'test noty 2',
];
//maybe you want some params
$params = [];
//init android facade service
$pushNotificationService = new ApnsPushService(
$certificatePath, $passPhrase, PushManager::ENVIRONMENT_PROD
);
//push! you will get a Response with parsed and original response collections
//and with a push collection
$response = $pushNotificationService->push($tokensA, $messages, $params);
//you could get a feedback with list of successful tokens
$feedback = $pushNotificationService->feedback();
//or!
//easily access list of successful and invalid tokens
//WARNING! these methods would send feedback request anyway
$invalidTokens = $pushNotificationService->getInvalidTokens();
$successfulTokens = $pushNotificationService->getSuccessfulTokens();
die(dump($response, $feedback, $invalidTokens, $successfulTokens));
```
## Documentation index
* [Installation](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/installation.md)
* [Getting started](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/getting-started.md)
* [APNS adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/apns-adapter.md)
* [GCM (FCM) adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-fcm-adapter.md)
* [Create an adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/create-an-adapter.md)
* [Push from CLI](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/push-from-cli.md)
* Facades

View File

@@ -1,8 +1,9 @@
# NotificationPusher - Documentation
## GCM adapter
## GCM (FCM) adapter
[GCM](http://developer.android.com/google/gcm/gs.html) adapter is used to push notification to Google/Android devices.
[FCM](https://firebase.google.com/docs/cloud-messaging/) is supported. Please see [this comment](https://github.com/Ph3nol/NotificationPusher/pull/141#issuecomment-318896948) for explanation.
### Custom notification push example
@@ -39,13 +40,34 @@ $devices = new DeviceCollection(array(
new Device('Token3'),
));
$params = [];
NOTE: if you need to pass not only data, but also notification array
use key notificationData in params, like $params[notificationData] = []
OR you could use optional GcmMessage class instead of Message and
use it's setter setNotificationData()
// Then, create the push skel.
$message = new Message('This is an example.');
$message = new Message('This is an example.', $params);
// Finally, create and add the push to the manager, and push it!
$push = new Push($gcmAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push(); // Returns a collection of notified devices
// each response will contain also
// the data of the overall delivery
foreach($push->getResponses() as $token => $response) {
// > $response
// Array
// (
// [message_id] => fake_message_id
// [multicast_id] => -1
// [success] => 1
// [failure] => 0
// [canonical_ids] => 0
// )
}
```
## Documentation index
@@ -53,6 +75,7 @@ $pushManager->push(); // Returns a collection of notified devices
* [Installation](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/installation.md)
* [Getting started](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/getting-started.md)
* [APNS adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/apns-adapter.md)
* GCM adapter
* GCM (FCM) adapter
* [Create an adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/create-an-adapter.md)
* [Push from CLI](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/push-from-cli.md)
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)

View File

@@ -2,10 +2,13 @@
## Getting started
**NOTE** If you want even easier start, please check our facades
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)
First, we are going to discover this library entities:
* Models (messages, pushes, devices)
* Adapters (APNS, GCM etc.)
* Adapters (APNS, GCM (FCM) etc.)
* The Manager
Here is the basic principle of a notification push:
@@ -38,6 +41,10 @@ $message = new Sly\NotificationPusher\Model\Message('This is an example.');
$push = new Sly\NotificationPusher\Model\Push($exampleAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
foreach($push->getResponses() as $token => $response) {
// ...
}
```
## More about the Message entity
@@ -82,6 +89,7 @@ $devices = new Sly\NotificationPusher\Collection\DeviceCollection(array(
* [Installation](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/installation.md)
* Getting started
* [APNS adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/apns-adapter.md)
* [GCM adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-adapter.md)
* [GCM (FCM) adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-fcm-adapter.md)
* [Create an adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/create-an-adapter.md)
* [Push from CLI](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/push-from-cli.md)
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)

View File

@@ -11,6 +11,7 @@ Run `composer require sly/notification-pusher` to install the latest version.
* Installation
* [Getting started](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/getting-started.md)
* [APNS adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/apns-adapter.md)
* [GCM adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-adapter.md)
* [GCM (FCM) adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-fcm-adapter.md)
* [Create an adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/create-an-adapter.md)
* [Push from CLI](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/push-from-cli.md)
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)

View File

@@ -29,6 +29,7 @@ Here is a concrete GCM adapter example:
* [Installation](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/installation.md)
* [Getting started](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/getting-started.md)
* [APNS adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/apns-adapter.md)
* [GCM adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-adapter.md)
* [GCM (FCM) adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/gcm-fcm-adapter.md)
* [Create an adapter](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/create-an-adapter.md)
* Push from CLI
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)

View File

@@ -1,10 +1,10 @@
#!/usr/bin/env php
<?php
if (file_exists($a = __DIR__.'/../../autoload.php')) {
if (file_exists($a = __DIR__ . '/../../autoload.php')) {
require_once $a;
} else {
require_once __DIR__.'/vendor/autoload.php';
require_once __DIR__ . '/vendor/autoload.php';
}
use Sly\NotificationPusher\Console\Application;

View File

@@ -0,0 +1,42 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 10.08.17
* Time: 11:06
*/
namespace Sly\NotificationPusher;
use Sly\NotificationPusher\Model\ResponseInterface;
abstract class AbstractPushService
{
/**
* @var string
*/
protected $environment;
/**
* @var ResponseInterface
*/
protected $response;
/**
* AbstractPushService constructor.
* @param string $environment
*/
public function __construct($environment = PushManager::ENVIRONMENT_DEV)
{
$this->environment = $environment;
}
/**
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -12,6 +12,8 @@
namespace Sly\NotificationPusher\Adapter;
use Sly\NotificationPusher\Model\PushInterface;
use Sly\NotificationPusher\Model\Response;
use Sly\NotificationPusher\Model\ResponseInterface;
/**
* AdapterInterface.
@@ -38,6 +40,16 @@ interface AdapterInterface
*/
public function supports($token);
/**
* @return ResponseInterface
*/
public function getResponse();
/**
* @param ResponseInterface $response
*/
public function setResponse(ResponseInterface $response);
/**
* Get defined parameters.
*
@@ -58,4 +70,20 @@ interface AdapterInterface
* @return array
*/
public function getRequiredParameters();
/**
* Get Environment.
*
* @return string
*/
public function getEnvironment();
/**
* Set Environment.
*
* @param string $environment Environment value to set
*
* @return \Sly\NotificationPusher\Adapter\AdapterInterface
*/
public function setEnvironment($environment);
}

View File

@@ -11,20 +11,18 @@
namespace Sly\NotificationPusher\Adapter;
use Sly\NotificationPusher\Model\BaseOptionedModel;
use Sly\NotificationPusher\Model\PushInterface;
use Sly\NotificationPusher\Model\DeviceInterface;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Exception\AdapterException;
use Sly\NotificationPusher\Exception\PushException;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Model\BaseOptionedModel;
use Sly\NotificationPusher\Model\DeviceInterface;
use Sly\NotificationPusher\Model\PushInterface;
use ZendService\Apple\Apns\Client\AbstractClient as ServiceAbstractClient;
use ZendService\Apple\Apns\Client\Feedback as ServiceFeedbackClient;
use ZendService\Apple\Apns\Client\Message as ServiceClient;
use ZendService\Apple\Apns\Message as ServiceMessage;
use ZendService\Apple\Apns\Message\Alert as ServiceAlert;
use ZendService\Apple\Apns\Response\Message as ServiceResponse;
use ZendService\Apple\Apns\Exception\RuntimeException as ServiceRuntimeException;
use ZendService\Apple\Apns\Client\Feedback as ServiceFeedbackClient;
/**
* APNS adapter.
@@ -33,13 +31,17 @@ use ZendService\Apple\Apns\Client\Feedback as ServiceFeedbackClient;
*
* @author Cédric Dugat <cedric@dugat.me>
*/
class Apns extends BaseAdapter
class Apns extends BaseAdapter implements FeedbackAdapterInterface
{
/** @var ServiceClient */
/**
* @var ServiceClient
*/
private $openedClient;
/** @var ServiceFeedbackClient */
/**
* @var ServiceFeedbackClient
*/
private $feedbackClient;
/**
@@ -70,16 +72,32 @@ class Apns extends BaseAdapter
$pushedDevices = new DeviceCollection();
foreach ($push->getDevices() as $device) {
/** @var \ZendService\Apple\Apns\Message $message */
$message = $this->getServiceMessageFromOrigin($device, $push->getMessage());
try {
$this->response = $client->send($message);
} catch (ServiceRuntimeException $e) {
throw new PushException($e->getMessage());
}
/** @var \ZendService\Apple\Apns\Response\Message $response */
$response = $client->send($message);
if (ServiceResponse::RESULT_OK === $this->response->getCode()) {
$pushedDevices->add($device);
$responseArr = [
'id' => $response->getId(),
'token' => $response->getCode(),
];
$push->addResponse($device, $responseArr);
if (ServiceResponse::RESULT_OK === $response->getCode()) {
$pushedDevices->add($device);
} else {
$client->close();
unset($this->openedClient, $client);
// Assign returned new client to the in-scope/in-use $client variable
$client = $this->getOpenedServiceClient();
}
$this->response->addOriginalResponse($device, $response);
$this->response->addParsedResponse($device, $responseArr);
} catch (\RuntimeException $e) {
throw new PushException($e->getMessage());
}
}
@@ -97,6 +115,7 @@ class Apns extends BaseAdapter
$responses = [];
$serviceResponses = $client->feedback();
/** @var \ZendService\Apple\Apns\Response\Feedback $response */
foreach ($serviceResponses as $response) {
$responses[$response->getToken()] = new \DateTime(date('c', $response->getTime()));
}
@@ -107,12 +126,16 @@ class Apns extends BaseAdapter
/**
* Get opened client.
*
* @param \ZendService\Apple\Apns\Client\AbstractClient $client Client
* @param \ZendService\Apple\Apns\Client\AbstractClient|null $client Client
*
* @return \ZendService\Apple\Apns\Client\AbstractClient
*/
public function getOpenedClient(ServiceAbstractClient $client)
public function getOpenedClient(ServiceAbstractClient $client = null)
{
if (!$client) {
$client = new ServiceClient();
}
$client->open(
$this->isProductionEnvironment() ? ServiceClient::PRODUCTION_URI : ServiceClient::SANDBOX_URI,
$this->getParameter('certificate'),
@@ -125,9 +148,9 @@ class Apns extends BaseAdapter
/**
* Get opened ServiceClient
*
* @return ServiceAbstractClient
* @return ServiceClient
*/
private function getOpenedServiceClient()
protected function getOpenedServiceClient()
{
if (!isset($this->openedClient)) {
$this->openedClient = $this->getOpenedClient(new ServiceClient());
@@ -139,7 +162,7 @@ class Apns extends BaseAdapter
/**
* Get opened ServiceFeedbackClient
*
* @return ServiceAbstractClient
* @return ServiceFeedbackClient
*/
private function getOpenedFeedbackClient()
{
@@ -161,13 +184,14 @@ class Apns extends BaseAdapter
public function getServiceMessageFromOrigin(DeviceInterface $device, BaseOptionedModel $message)
{
$badge = ($message->hasOption('badge'))
? (int) ($message->getOption('badge') + $device->getParameter('badge', 0))
: false
;
? (int)($message->getOption('badge') + $device->getParameter('badge', 0))
: false;
$sound = $message->getOption('sound', 'bingbong.aiff');
$sound = $message->getOption('sound');
$contentAvailable = $message->getOption('content-available');
$category = $message->getOption('category');
$category = $message->getOption('category');
$urlArgs = $message->getOption('urlArgs');
$expire = $message->getOption('expire');
$alert = new ServiceAlert(
$message->getText(),
@@ -202,7 +226,7 @@ class Apns extends BaseAdapter
}
$serviceMessage = new ServiceMessage();
$serviceMessage->setId(sha1($device->getToken().$message->getText()));
$serviceMessage->setId(sha1($device->getToken() . $message->getText()));
$serviceMessage->setAlert($alert);
$serviceMessage->setToken($device->getToken());
if (false !== $badge) {
@@ -222,6 +246,14 @@ class Apns extends BaseAdapter
$serviceMessage->setCategory($category);
}
if (null !== $urlArgs) {
$serviceMessage->setUrlArgs($urlArgs);
}
if (null !== $expire) {
$serviceMessage->setExpire($expire);
}
return $serviceMessage;
}

View File

@@ -0,0 +1,77 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 09.08.17
* Time: 17:03
*/
namespace Sly\Sly\NotificationPusher\Adapter;
use Sly\NotificationPusher\Adapter\BaseAdapter;
use Sly\NotificationPusher\Model\PushInterface;
/**
* Class ApnsAPI
* @package Sly\Sly\NotificationPusher\Adapter
*
* todo: implement with edamov/pushok
*/
class ApnsAPI extends BaseAdapter
{
/**
* Push.
*
* @param \Sly\NotificationPusher\Model\PushInterface $push Push
*
* @return \Sly\NotificationPusher\Collection\DeviceCollection
*/
public function push(PushInterface $push)
{
// TODO: Implement push() method.
}
/**
* Supports.
*
* @param string $token Token
*
* @return boolean
*/
public function supports($token)
{
// TODO: Implement supports() method.
}
/**
* Get defined parameters.
*
* @return array
*/
public function getDefinedParameters()
{
// TODO: Implement getDefinedParameters() method.
}
/**
* Get default parameters.
*
* @return array
*/
public function getDefaultParameters()
{
// TODO: Implement getDefaultParameters() method.
}
/**
* Get required parameters.
*
* @return array
*/
public function getRequiredParameters()
{
// TODO: Implement getRequiredParameters() method.
}
}

View File

@@ -11,10 +11,11 @@
namespace Sly\NotificationPusher\Adapter;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Sly\NotificationPusher\Model\BaseParameteredModel;
use Sly\NotificationPusher\Model\Response;
use Sly\NotificationPusher\Model\ResponseInterface;
use Sly\NotificationPusher\PushManager;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* BaseAdapter.
@@ -34,7 +35,7 @@ abstract class BaseAdapter extends BaseParameteredModel implements AdapterInterf
protected $environment;
/**
* @var mixed
* @var ResponseInterface
*/
protected $response;
@@ -53,6 +54,23 @@ abstract class BaseAdapter extends BaseParameteredModel implements AdapterInterf
$reflectedClass = new \ReflectionClass($this);
$this->adapterKey = lcfirst($reflectedClass->getShortName());
$this->parameters = $resolver->resolve($parameters);
$this->response = new Response();
}
/**
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}
/**
* @param ResponseInterface $response
*/
public function setResponse(ResponseInterface $response)
{
$this->response = $response;
}
/**
@@ -65,16 +83,6 @@ abstract class BaseAdapter extends BaseParameteredModel implements AdapterInterf
return ucfirst($this->getAdapterKey());
}
/**
* Return the original response.
*
* @return mixed
*/
public function getResponse()
{
return $this->response;
}
/**
* Get AdapterKey.
*
@@ -128,4 +136,5 @@ abstract class BaseAdapter extends BaseParameteredModel implements AdapterInterf
{
return (PushManager::ENVIRONMENT_PROD === $this->getEnvironment());
}
}

View File

@@ -0,0 +1,15 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 09.08.17
* Time: 16:06
*/
namespace Sly\NotificationPusher\Adapter;
interface FeedbackAdapterInterface
{
public function getFeedback();
}

View File

@@ -11,19 +11,18 @@
namespace Sly\NotificationPusher\Adapter;
use Sly\NotificationPusher\Model\BaseOptionedModel;
use Sly\NotificationPusher\Model\PushInterface;
use InvalidArgumentException;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Exception\PushException;
use Sly\NotificationPusher\Model\BaseOptionedModel;
use Sly\NotificationPusher\Model\DeviceInterface;
use Sly\NotificationPusher\Model\GcmMessage;
use Sly\NotificationPusher\Model\PushInterface;
use Zend\Http\Client as HttpClient;
use Zend\Http\Client\Adapter\Socket as HttpSocketAdapter;
use ZendService\Google\Exception\RuntimeException as ServiceRuntimeException;
use ZendService\Google\Gcm\Client as ServiceClient;
use ZendService\Google\Gcm\Message as ServiceMessage;
use ZendService\Google\Exception\RuntimeException as ServiceRuntimeException;
use InvalidArgumentException;
/**
* GCM adapter.
@@ -49,7 +48,7 @@ class Gcm extends BaseAdapter
*/
public function supports($token)
{
return is_string($token) && $token != '';
return is_string($token) && $token !== '';
}
/**
@@ -67,16 +66,40 @@ class Gcm extends BaseAdapter
$message = $this->getServiceMessageFromOrigin($tokensRange, $push->getMessage());
try {
$this->response = $client->send($message);
/** @var \ZendService\Google\Gcm\Response $response */
$response = $client->send($message);
$responseResults = $response->getResults();
foreach ($tokensRange as $token) {
/** @var DeviceInterface $device */
$device = $push->getDevices()->get($token);
// map the overall response object
// into a per device response
$tokenResponse = [];
if (isset($responseResults[$token]) && is_array($responseResults[$token])) {
$tokenResponse = $responseResults[$token];
}
$responseData = $response->getResponse();
if ($responseData && is_array($responseData)) {
$tokenResponse = array_merge(
$tokenResponse,
array_diff_key($responseData, ['results' => true])
);
}
$push->addResponse($device, $tokenResponse);
$pushedDevices->add($device);
$this->response->addOriginalResponse($device, $response);
$this->response->addParsedResponse($device, $tokenResponse);
}
} catch (ServiceRuntimeException $e) {
throw new PushException($e->getMessage());
}
if ((bool) $this->response->getSuccessCount()) {
foreach ($tokensRange as $token) {
$pushedDevices->add($push->getDevices()->get($token));
}
}
}
return $pushedDevices;
@@ -96,8 +119,8 @@ class Gcm extends BaseAdapter
$newClient = new \Zend\Http\Client(
null,
[
'adapter' => 'Zend\Http\Client\Adapter\Socket',
'sslverifypeer' => false
'adapter' => 'Zend\Http\Client\Adapter\Socket',
'sslverifypeer' => false,
]
);
@@ -114,6 +137,7 @@ class Gcm extends BaseAdapter
* @param BaseOptionedModel|\Sly\NotificationPusher\Model\MessageInterface $message Message
*
* @return \ZendService\Google\Gcm\Message
* @throws \ZendService\Google\Exception\InvalidArgumentException
*/
public function getServiceMessageFromOrigin(array $tokens, BaseOptionedModel $message)
{
@@ -122,7 +146,18 @@ class Gcm extends BaseAdapter
$serviceMessage = new ServiceMessage();
$serviceMessage->setRegistrationIds($tokens);
if (isset($data['notificationData']) && !empty($data['notificationData'])) {
$serviceMessage->setNotification($data['notificationData']);
unset($data['notificationData']);
}
if ($message instanceof GcmMessage) {
$serviceMessage->setNotification($message->getNotificationData());
}
$serviceMessage->setData($data);
$serviceMessage->setCollapseKey($this->getParameter('collapseKey'));
$serviceMessage->setRestrictedPackageName($this->getParameter('restrictedPackageName'));
$serviceMessage->setDelayWhileIdle($this->getParameter('delayWhileIdle', false));
@@ -138,11 +173,11 @@ class Gcm extends BaseAdapter
public function getDefinedParameters()
{
return [
'collapse_key',
'delay_while_idle',
'time_to_live',
'restricted_package_name',
'dry_run'
'collapseKey',
'delayWhileIdle',
'ttl',
'restrictedPackageName',
'dryRun',
];
}

View File

@@ -0,0 +1,215 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 10.08.17
* Time: 10:43
*/
namespace Sly\NotificationPusher;
use Sly\NotificationPusher\Adapter\Apns as ApnsAdapter;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Model\Device;
use Sly\NotificationPusher\Model\Message;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\Model\ResponseInterface;
use Symfony\Component\Filesystem\Filesystem;
/**
* Facade for simple use cases
*
* Class ApnsPushService
* @package Sly\NotificationPusher
*/
class ApnsPushService extends AbstractPushService
{
/**
* @var string
*/
private $certificatePath = '';
/**
* @var string|null
*/
private $passPhrase = '';
/**
* @var array
*/
private $feedback = [];
/**
* IOSPushNotificationService constructor.
* @param string $environment
* @param string $certificatePath
* @param string $passPhrase
*/
public function __construct($certificatePath, $passPhrase = null, $environment = PushManager::ENVIRONMENT_DEV)
{
parent::__construct($environment);
$this->certificatePath = $certificatePath;
$this->passPhrase = $passPhrase;
}
/**
* @param array $tokens
* @param array $notifications
* @param array $params
* @return ResponseInterface
*/
public function push(array $tokens = [], array $notifications = [], array $params = [])
{
if (!$tokens || !$notifications) {
return null;
}
if (!$this->certificatePath) {
throw new \RuntimeException('IOS certificate path must be set');
}
$fs = new Filesystem();
if (!$fs->exists($this->certificatePath) || !is_readable($this->certificatePath)) {
throw new \InvalidArgumentException('Wrong or not readable certificate path');
}
$adapterParams = [];
$deviceParams = [];
$messageParams = [];
if (isset($params) && !empty($params)) {
if (isset($params['adapter'])) {
$adapterParams = $params['adapter'];
}
if (isset($params['device'])) {
$deviceParams = $params['device'];
}
if (isset($params['message'])) {
$messageParams = $params['message'];
}
}
$adapterParams['certificate'] = $this->certificatePath;
$adapterParams['passPhrase'] = $this->passPhrase;
// Development one by default (without argument).
/** @var PushManager $pushManager */
$pushManager = new PushManager($this->environment);
// Then declare an adapter.
$apnsAdapter = new ApnsAdapter($adapterParams);
// Set the device(s) to push the notification to.
$devices = new DeviceCollection([]);
//devices
foreach ($tokens as $token) {
$devices->add(new Device($token, $deviceParams));
}
foreach ($notifications as $notificationText) {
// Then, create the push skel.
$message = new Message($notificationText, $messageParams);
// Finally, create and add the push to the manager, and push it!
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
}
// Returns a collection of notified devices
$pushes = $pushManager->push();
$this->response = $apnsAdapter->getResponse();
$this->feedback = [];
return $this->response;
}
/**
* Use feedback to get not registered tokens from last send
* and remove them from your DB
*
* @return array
*/
public function feedback()
{
$adapterParams = [];
$adapterParams['certificate'] = $this->certificatePath;
$adapterParams['passPhrase'] = $this->passPhrase;
// Development one by default (without argument).
/** @var PushManager $pushManager */
$pushManager = new PushManager($this->environment);
// Then declare an adapter.
$apnsAdapter = new ApnsAdapter($adapterParams);
$this->feedback = $pushManager->getFeedback($apnsAdapter);
return $this->feedback;
}
/**
* The Apple Push Notification service includes a feedback service to give you information
* about failed remote notifications. When a remote notification cannot be delivered
* because the intended app does not exist on the device,
* the feedback service adds that devices token to its list.
*
* @return array
*/
public function getFeedback()
{
return $this->feedback;
}
/**
* @return array
*/
public function getInvalidTokens()
{
if (!$this->response) {
return [];
}
if (!$this->feedback) {
$this->feedback = $this->feedback();
}
$feedbackTokens = array_keys($this->feedback);
//all bad
if ($feedbackTokens) {
return $feedbackTokens;
}
return [];
}
/**
* @return array
*/
public function getSuccessfulTokens()
{
if (!$this->response) {
return [];
}
if (!$this->feedback) {
$this->feedback = $this->feedback();
}
$feedbackTokens = array_keys($this->feedback);
$sentTokens = array_keys($this->response->getParsedResponses());
//all bad
if (!$feedbackTokens) {
return $sentTokens;
}
$tokens = array_diff($sentTokens, $feedbackTokens);
return $tokens;
}
}

View File

@@ -17,13 +17,19 @@ namespace Sly\NotificationPusher\Collection;
* @uses \IteratorAggregate
* @author Cédric Dugat <cedric@dugat.me>
*/
abstract class AbstractCollection
abstract class AbstractCollection implements \IteratorAggregate, \Countable
{
/**
* @var \ArrayIterator
*/
protected $coll;
/**
* @inheritdoc
* @return \ArrayIterator|\SeekableIterator
*/
abstract public function getIterator();
/**
* Get.
*
@@ -43,7 +49,7 @@ abstract class AbstractCollection
*/
public function count()
{
return count($this->getIterator());
return $this->getIterator()->count();
}
/**
@@ -63,4 +69,38 @@ abstract class AbstractCollection
{
$this->coll = new \ArrayIterator();
}
/**
* @return mixed|null
*/
public function first()
{
$tmp = clone $this->coll;
//go to the beginning
$tmp->rewind();
if (!$tmp->valid()) {
return null;
}
return $tmp->current();
}
/**
* @return mixed|null
*/
public function last()
{
$tmp = clone $this->coll;
//go to the end
$tmp->seek($tmp->count() - 1);
if (!$tmp->valid()) {
return null;
}
return $tmp->current();
}
}

View File

@@ -20,7 +20,7 @@ use Sly\NotificationPusher\Model\PushInterface;
* @uses \IteratorAggregate
* @author Cédric Dugat <cedric@dugat.me>
*/
class PushCollection extends AbstractCollection implements \IteratorAggregate
class PushCollection extends AbstractCollection
{
/**
* Constructor.

View File

@@ -0,0 +1,49 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (c) 2016 Lukas Klinzing <theluk@gmail.com>
* (c) 2013 Cédric Dugat <cedric@dugat.me>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Sly\NotificationPusher\Collection;
/**
* Response Collection.
* is just a container for a response from a push service
*
* @uses \Sly\NotificationPusher\Collection\AbstractCollection
* @uses \IteratorAggregate
* @author Lukas Klinzing <theluk@gmail.com>
*/
class ResponseCollection extends AbstractCollection
{
/**
* Constructor.
*/
public function __construct()
{
$this->coll = new \ArrayIterator();
}
/**
* @return \ArrayIterator
*/
public function getIterator()
{
return $this->coll;
}
/**
* @param string $token
* @param mixed $response
*/
public function add($token, $response)
{
$this->coll[$token] = $response;
}
}

View File

@@ -11,9 +11,9 @@
namespace Sly\NotificationPusher\Console;
use Symfony\Component\Console\Application as BaseApplication;
use Sly\NotificationPusher\NotificationPusher;
use Sly\NotificationPusher\Console\Command\PushCommand;
use Sly\NotificationPusher\NotificationPusher;
use Symfony\Component\Console\Application as BaseApplication;
/**
* Application.

View File

@@ -11,20 +11,18 @@
namespace Sly\NotificationPusher\Console\Command;
use Doctrine\Common\Inflector\Inflector;
use Sly\NotificationPusher\Exception\AdapterException;
use Sly\NotificationPusher\Model\Device;
use Sly\NotificationPusher\Model\Message;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\PushManager;
use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Sly\NotificationPusher\PushManager;
use Sly\NotificationPusher\Model\Device;
use Sly\NotificationPusher\Model\Message;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\Exception\AdapterException;
use Doctrine\Common\Inflector\Inflector;
/**
* PushCommand.
*
@@ -108,7 +106,7 @@ class PushCommand extends Command
private function getAdapterClassFromArgument($argument)
{
if (!class_exists($adapterClass = $argument) &&
!class_exists($adapterClass = '\\Sly\\NotificationPusher\\Adapter\\'.ucfirst($argument))) {
!class_exists($adapterClass = '\\Sly\\NotificationPusher\\Adapter\\' . ucfirst($argument))) {
throw new AdapterException(
sprintf(
'Adapter class %s does not exist',

View File

@@ -0,0 +1,159 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 10.08.17
* Time: 10:43
*/
namespace Sly\NotificationPusher;
use Sly\NotificationPusher\Adapter\Gcm as GcmAdapter;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Model\Device;
use Sly\NotificationPusher\Model\Message;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\Model\ResponseInterface;
/**
* Facade for simple use cases
*
* Class GcmPushService
* @package Sly\NotificationPusher
*/
class GcmPushService extends AbstractPushService
{
/**
* @var string
*/
private $apiKey = '';
/**
* GcmPushService constructor.
* @param string $environment
* @param string $apiKey
*/
public function __construct($apiKey, $environment = PushManager::ENVIRONMENT_DEV)
{
parent::__construct($environment);
$this->apiKey = $apiKey;
}
/**
* params keys
* adapter
* message
* device
*
* @param array $tokens
* @param array $notifications
* @param array $params
* @return ResponseInterface
*/
public function push(array $tokens = [], array $notifications = [], array $params = [])
{
if (!$tokens || !$notifications) {
return null;
}
$adapterParams = [];
$deviceParams = [];
$messageParams = [];
if (isset($params) && !empty($params)) {
if (isset($params['adapter'])) {
$adapterParams = $params['adapter'];
}
if (isset($params['device'])) {
$deviceParams = $params['device'];
}
if (isset($params['message'])) {
$messageParams = $params['message'];
}
//because we have now notification and data separated
if (isset($params['notificationData'])) {
$messageParams['notificationData'] = $params['notificationData'];
}
}
$adapterParams['apiKey'] = $this->apiKey;
if (!$this->apiKey) {
throw new \RuntimeException('Android api key must be set');
}
// Development one by default (without argument).
/** @var PushManager $pushManager */
$pushManager = new PushManager($this->environment);
// Then declare an adapter.
$gcmAdapter = new GcmAdapter($adapterParams);
// Set the device(s) to push the notification to.
$devices = new DeviceCollection([]);
//devices
foreach ($tokens as $token) {
$devices->add(new Device($token, $deviceParams));
}
foreach ($notifications as $notificationText) {
// Then, create the push skel.
$message = new Message($notificationText, $messageParams);
// Finally, create and add the push to the manager, and push it!
$push = new Push($gcmAdapter, $devices, $message);
$pushManager->add($push);
}
// Returns a collection of notified devices
$pushes = $pushManager->push();
$this->response = $gcmAdapter->getResponse();
return $this->response;
}
/**
* @return array
*/
public function getInvalidTokens()
{
if (!$this->response) {
return [];
}
$tokens = [];
foreach ($this->response->getParsedResponses() as $token => $response) {
if (array_key_exists('error', $response) && !array_key_exists('message_id', $response)) {
array_push($tokens, $token);
}
}
return $tokens;
}
/**
* @return array
*/
public function getSuccessfulTokens()
{
if (!$this->response) {
return [];
}
$tokens = [];
foreach ($this->response->getParsedResponses() as $token => $response) {
if (!array_key_exists('error', $response) && array_key_exists('message_id', $response)) {
array_push($tokens, $token);
}
}
return $tokens;
}
}

View File

@@ -0,0 +1,9 @@
<?php
namespace Sly\NotificationPusher\Model;
class ApnsMessage extends Message
{
}

View File

@@ -48,8 +48,8 @@ abstract class BaseOptionedModel
/**
* Get option.
*
* @param string $key Key
* @param mixed $default Default
* @param string $key Key
* @param mixed $default Default
*
* @return mixed
*/
@@ -75,8 +75,8 @@ abstract class BaseOptionedModel
/**
* Set option.
*
* @param string $key Key
* @param mixed $value Value
* @param string $key Key
* @param mixed $value Value
*
* @return mixed
*/

View File

@@ -48,8 +48,8 @@ abstract class BaseParameteredModel
/**
* Get parameter.
*
* @param string $key Key
* @param mixed $default Default
* @param string $key Key
* @param mixed $default Default
*
* @return mixed
*/
@@ -75,8 +75,8 @@ abstract class BaseParameteredModel
/**
* Set parameter.
*
* @param string $key Key
* @param mixed $value Value
* @param string $key Key
* @param mixed $value Value
*
* @return mixed
*/

View File

@@ -26,8 +26,8 @@ class Device extends BaseParameteredModel implements DeviceInterface
/**
* Constructor.
*
* @param string $token Token
* @param array $parameters Parameters
* @param string $token Token
* @param array $parameters Parameters
*/
public function __construct($token, array $parameters = [])
{

View File

@@ -0,0 +1,28 @@
<?php
namespace Sly\NotificationPusher\Model;
class GcmMessage extends Message
{
/**
* @var array
*/
private $notificationData = [];
/**
* @return array
*/
public function getNotificationData()
{
return $this->notificationData;
}
/**
* @param array $notificationData
*/
public function setNotificationData($notificationData)
{
$this->notificationData = $notificationData;
}
}

View File

@@ -21,13 +21,13 @@ class Message extends BaseOptionedModel implements MessageInterface
/**
* @var string
*/
private $text;
protected $text;
/**
* Constructor.
*
* @param string $text Text
* @param array $options Options
* @param string $text Text
* @param array $options Options
*/
public function __construct($text, array $options = [])
{

View File

@@ -11,8 +11,9 @@
namespace Sly\NotificationPusher\Model;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Adapter\AdapterInterface;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Collection\ResponseCollection;
use Sly\NotificationPusher\Exception\AdapterException;
/**
@@ -48,13 +49,18 @@ class Push extends BaseOptionedModel implements PushInterface
*/
private $pushedAt;
/**
* @var \Sly\NotificationPusher\Collection\ResponseCollection
*/
private $responses;
/**
* Constructor.
*
* @param \Sly\NotificationPusher\Adapter\AdapterInterface $adapter Adapter
* @param DeviceInterface|DeviceCollection $devices Device(s)
* @param \Sly\NotificationPusher\Model\MessageInterface $message Message
* @param array $options Options
* @param DeviceInterface|DeviceCollection $devices Device(s)
* @param \Sly\NotificationPusher\Model\MessageInterface $message Message
* @param array $options Options
*
* Options are adapters specific ones, like Apns "badge" or "sound" option for example.
* Of course, they can be more general.
@@ -78,6 +84,7 @@ class Push extends BaseOptionedModel implements PushInterface
/**
* Check devices tokens.
* @throws \Sly\NotificationPusher\Exception\AdapterException
*/
private function checkDevicesTokens()
{
@@ -89,7 +96,7 @@ class Push extends BaseOptionedModel implements PushInterface
throw new AdapterException(
sprintf(
'Adapter %s does not support %s token\'s device',
(string) $adapter,
(string)$adapter,
$device->getToken()
)
);
@@ -128,7 +135,7 @@ class Push extends BaseOptionedModel implements PushInterface
*/
public function isPushed()
{
return (bool) (self::STATUS_PUSHED === $this->status);
return (bool)(self::STATUS_PUSHED === $this->status);
}
/**
@@ -218,6 +225,28 @@ class Push extends BaseOptionedModel implements PushInterface
return $this;
}
/**
* Get Responses
* @return \Sly\NotificationPusher\Collection\ResponseCollection
*/
public function getResponses()
{
if (!$this->responses)
$this->responses = new ResponseCollection();
return $this->responses;
}
/**
* adds a response
* @param \Sly\NotificationPusher\Model\DeviceInterface $device
* @param mixed $response
*/
public function addResponse(DeviceInterface $device, $response)
{
$this->getResponses()->add($device->getToken(), $response);
}
/**
* Get PushedAt.
*

View File

@@ -104,6 +104,19 @@ interface PushInterface
*/
public function setDevices(DeviceCollection $devices);
/**
* Get Responses
* @return \Sly\NotificationPusher\Collection\ResponseCollection
*/
public function getResponses();
/**
* adds a response
* @param \Sly\NotificationPusher\Model\DeviceInterface $device
* @param mixed $response
*/
public function addResponse(DeviceInterface $device, $response);
/**
* Get PushedAt.
*

View File

@@ -0,0 +1,92 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 09.08.17
* Time: 17:57
*/
namespace Sly\NotificationPusher\Model;
use Sly\NotificationPusher\Collection\PushCollection;
class Response implements ResponseInterface
{
/**
* @var array
*/
private $parsedResponses = [];
/**
* @var array
*/
private $originalResponses = [];
/**
* @var PushCollection
*/
private $pushCollection;
/**
* Response constructor.
*/
public function __construct()
{
$this->pushCollection = new PushCollection();
}
/**
* @param DeviceInterface $device
* @param array $response
*/
public function addParsedResponse(DeviceInterface $device, $response)
{
if (!is_array($response)) {
throw new \InvalidArgumentException('Response must be array type');
}
$this->parsedResponses[$device->getToken()] = $response;
}
/**
* @param DeviceInterface $device
* @param mixed $originalResponse
*/
public function addOriginalResponse(DeviceInterface $device, $originalResponse)
{
$this->originalResponses[$device->getToken()] = $originalResponse;
}
/**
* @param \Sly\NotificationPusher\Model\PushInterface $push Push
*/
public function addPush(PushInterface $push)
{
$this->pushCollection->add($push);
}
/**
* @return array
*/
public function getParsedResponses()
{
return $this->parsedResponses;
}
/**
* @return mixed
*/
public function getOriginalResponses()
{
return $this->originalResponses;
}
/**
* @return PushCollection
*/
public function getPushCollection()
{
return $this->pushCollection;
}
}

View File

@@ -0,0 +1,46 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 10.08.17
* Time: 10:30
*/
namespace Sly\NotificationPusher\Model;
use Sly\NotificationPusher\Collection\PushCollection;
interface ResponseInterface
{
/**
* @param DeviceInterface $device
* @param array $response
*/
public function addParsedResponse(DeviceInterface $device, $response);
/**
* @param DeviceInterface $device
* @param mixed $originalResponse
*/
public function addOriginalResponse(DeviceInterface $device, $originalResponse);
/**
* @param \Sly\NotificationPusher\Model\PushInterface $push Push
*/
public function addPush(PushInterface $push);
/**
* @return array
*/
public function getParsedResponses();
/**
* @return mixed
*/
public function getOriginalResponses();
/**
* @return PushCollection
*/
public function getPushCollection();
}

View File

@@ -11,9 +11,13 @@
namespace Sly\NotificationPusher;
use Sly\NotificationPusher\Collection\PushCollection;
use Sly\NotificationPusher\Adapter\AdapterInterface;
use Sly\NotificationPusher\Adapter\FeedbackAdapterInterface;
use Sly\NotificationPusher\Collection\PushCollection;
use Sly\NotificationPusher\Exception\AdapterException;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\Model\PushInterface;
use Sly\NotificationPusher\Model\ResponseInterface;
/**
* PushManager.
@@ -21,7 +25,7 @@ use Sly\NotificationPusher\Exception\AdapterException;
* @uses \Sly\NotificationPusher\Collection\PushCollection
* @author Cédric Dugat <cedric@dugat.me>
*/
class PushManager extends PushCollection
class PushManager
{
const ENVIRONMENT_DEV = 'dev';
const ENVIRONMENT_PROD = 'prod';
@@ -31,6 +35,16 @@ class PushManager extends PushCollection
*/
private $environment;
/**
* @var PushCollection
*/
private $pushCollection;
/**
* @var ResponseInterface
*/
private $response;
/**
* Constructor.
*
@@ -38,9 +52,16 @@ class PushManager extends PushCollection
*/
public function __construct($environment = self::ENVIRONMENT_DEV)
{
parent::__construct();
$this->environment = $environment;
$this->pushCollection = new PushCollection();
}
$this->environment = $environment;
/**
* @param \Sly\NotificationPusher\Model\PushInterface $push Push
*/
public function add(PushInterface $push)
{
$this->pushCollection->add($push);
}
/**
@@ -56,11 +77,12 @@ class PushManager extends PushCollection
/**
* Push.
*
* @return \Sly\NotificationPusher\Collection\PushCollection
* @return PushCollection
*/
public function push()
{
foreach ($this as $push) {
/** @var Push $push */
foreach ($this->pushCollection as $push) {
$adapter = $push->getAdapter();
$adapter->setEnvironment($this->getEnvironment());
@@ -69,7 +91,13 @@ class PushManager extends PushCollection
}
}
return $this;
if ($this->pushCollection && !$this->pushCollection->isEmpty()) {
/** @var Push $push */
$push = $this->pushCollection->first();
$this->response = $push->getAdapter()->getResponse();
}
return $this->pushCollection;
}
/**
@@ -83,11 +111,11 @@ class PushManager extends PushCollection
*/
public function getFeedback(AdapterInterface $adapter)
{
if (false === method_exists($adapter, 'getFeedback')) {
if (!$adapter instanceof FeedbackAdapterInterface) {
throw new AdapterException(
sprintf(
'%s adapter has no dedicated "getFeedback" method',
(string) $adapter
(string)$adapter
)
);
}
@@ -95,4 +123,20 @@ class PushManager extends PushCollection
return $adapter->getFeedback();
}
/**
* @return PushCollection
*/
public function getPushCollection()
{
return $this->pushCollection;
}
/**
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -4,13 +4,13 @@ namespace tests\units\Sly\NotificationPusher\Adapter;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Adapter\Apns as TestedModel;
use Sly\NotificationPusher\Model\Message as BaseMessage;
use Sly\NotificationPusher\Model\Device as BaseDevice;
use Sly\NotificationPusher\Collection\DeviceCollection as BaseDeviceCollection;
use ZendService\Apple\Apns\Message as BaseServiceMessage;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Model\Device as BaseDevice;
use Sly\NotificationPusher\Model\Message as BaseMessage;
use Sly\NotificationPusher\Model\Response;
use ZendService\Apple\Apns\Client\Message as BaseServiceClient;
use ZendService\Apple\Apns\Message as BaseServiceMessage;
/**
* Apns.
@@ -42,6 +42,7 @@ class Apns extends Units\Test
->and($this->mockClass('\Sly\NotificationPusher\Adapter\Apns', '\Mock'))
->and($object = new \Mock\Apns())
->and($object->setParameters(['certificate' => 'test.pem', 'passPhrase' => 'test']))
->and($object->setResponse(new Response()))
->array($object->getParameters())
->isNotEmpty()
->hasSize(2)
@@ -141,22 +142,26 @@ class Apns extends Units\Test
public function testPush()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass('\Sly\NotificationPusher\Adapter\Apns', '\Mock'))
$this->if($this->mockGenerator()->orphanize('__construct')
->makeVisible('getOpenedServiceClient')
->generate(\Sly\NotificationPusher\Adapter\Apns::class, '\Mock', 'Apns'))
->and($object = new \Mock\Apns())
->and($object->setResponse(new Response()))
->and($this->mockClass('\ZendService\Apple\Apns\Response\Message', '\Mock\ZendService', 'Response'))
->and($this->mockClass(\ZendService\Apple\Apns\Response\Message::class, '\Mock\ZendService', 'Response'))
->and($serviceResponse = new \Mock\ZendService\Response())
->and($serviceResponse->getMockController()->getCode = \ZendService\Apple\Apns\Response\Message::RESULT_OK)
->and($serviceResponse->getMockController()->getId = 0)
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockGenerator()->orphanize('open'))
->and($this->mockGenerator()->orphanize('send'))
->and($this->mockClass('\ZendService\Apple\Apns\Client\Message', '\Mock\ZendService'))
->and($this->mockGenerator()->orphanize('__construct')
->orphanize('open')
->orphanize('send')
->generate(\ZendService\Apple\Apns\Client\Message::class, '\Mock\ZendService'))
->and($serviceClient = new \Mock\ZendService\Message())
->and($serviceClient->getMockController()->send = new $serviceResponse)
->and($serviceClient->getMockController()->send = $serviceResponse)
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass('\Sly\NotificationPusher\Model\Push', '\Mock'))
->and($this->mockClass(\Sly\NotificationPusher\Model\Push::class, '\Mock'))
->and($push = new \Mock\Push())
->and($push->getMockController()->getMessage = new BaseMessage('Test'))
->and($push->getMockController()->getDevices = new BaseDeviceCollection(
@@ -165,11 +170,18 @@ class Apns extends Units\Test
->and($object->getMockController()->getServiceMessageFromOrigin = new BaseServiceMessage())
->and($object->getMockController()->getOpenedClient = $serviceClient)
->and($this->calling($object)->getOpenedServiceClient = $serviceClient)
->object($object->push($push))
->object($result = $object->push($push))
->isInstanceOf('\Sly\NotificationPusher\Collection\DeviceCollection')
->hasSize(1)
;
->boolean($result->count() == 1)
->isTrue();
}
public function testCountIsEmpty() {
$this->if($dcoll = new DeviceCollection())
->boolean($dcoll->isEmpty())
->isTrue();
}
public function testFeedback()

View File

@@ -9,6 +9,7 @@ use Sly\NotificationPusher\Model\Message as BaseMessage;
use Sly\NotificationPusher\Model\Device as BaseDevice;
use Sly\NotificationPusher\Collection\DeviceCollection as BaseDeviceCollection;
use Sly\NotificationPusher\Model\Response;
use ZendService\Google\Gcm\Client as BaseServiceClient;
use ZendService\Google\Gcm\Message as BaseServiceMessage;
@@ -74,11 +75,11 @@ class Gcm extends Units\Test
->array($definedParameters = $object->getDefinedParameters())
->isNotEmpty()
->containsValues([
'collapse_key',
'delay_while_idle',
'time_to_live',
'restricted_package_name',
'dry_run'
'collapseKey',
'delayWhileIdle',
'ttl',
'restrictedPackageName',
'dryRun'
]);
}
@@ -128,17 +129,48 @@ class Gcm extends Units\Test
public function testGetServiceMessageFromOrigin()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass('\Sly\NotificationPusher\Adapter\Gcm', '\Mock'))
->and($this->mockClass(\Sly\NotificationPusher\Adapter\Gcm::class, '\Mock'))
->and($object = new \Mock\Gcm())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass('\Sly\NotificationPusher\Model\Message', '\Mock'))
->and($this->mockClass(\Sly\NotificationPusher\Model\Message::class, '\Mock'))
->and($message = new \Mock\Message())
->and($message->getMockController()->getOptions = [
'param' => 'test',
'notificationData' => ['some' => 'foobar']
])
->and($message->getMockController()->getText = 'Test')
->object($object->getServiceMessageFromOrigin([self::GCM_TOKEN_EXAMPLE], $message))
->isInstanceOf('\ZendService\Google\Gcm\Message')
;
->object($originalMessage = $object->getServiceMessageFromOrigin([self::GCM_TOKEN_EXAMPLE], $message))
->isInstanceOf(\ZendService\Google\Gcm\Message::class)
->array($originalMessage->getData())
->notHasKey('notificationData')
->array($originalMessage->getNotification())
->hasKey('some')
->contains('foobar');
}
public function testGcmMessageUse()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(\Sly\NotificationPusher\Adapter\Gcm::class, '\Mock'))
->and($object = new \Mock\Gcm())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(\Sly\NotificationPusher\Model\GcmMessage::class, '\Mock'))
->and($message = new \Mock\GcmMessage())
->and($message->getMockController()->getNotificationData = [
'some' => 'foobar'
])
->and($message->getMockController()->getText = 'Test')
->object($originalMessage = $object->getServiceMessageFromOrigin([self::GCM_TOKEN_EXAMPLE], $message))
->isInstanceOf(\ZendService\Google\Gcm\Message::class)
->array($originalMessage->getData())
->notHasKey('notificationData')
->array($originalMessage->getNotification())
->hasKey('some')
->contains('foobar');
}
public function testPush()
@@ -146,6 +178,7 @@ class Gcm extends Units\Test
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass('\Sly\NotificationPusher\Adapter\Gcm', '\Mock'))
->and($object = new \Mock\Gcm())
->and($object->setResponse(new Response()))
->and($this->mockClass('\ZendService\Google\Gcm\Response', '\Mock\ZendService'))
->and($serviceResponse = new \Mock\ZendService\Response())

View File

@@ -20,7 +20,9 @@ class Message extends Units\Test
->array($object->getOptions())->isEmpty()
;
$this->if($object = new TestedModel('Test', ['param' => 'test']))
$this->if($object = new TestedModel('Test', [
'param' => 'test',
]))
->string($object->getText())->isEqualTo('Test')
->when($object->setText('Test 2'))
->string($object->getText())->isEqualTo('Test 2')

View File

@@ -62,6 +62,7 @@ class Push extends Units\Test
public function testStatus()
{
date_default_timezone_set('UTC');
$this->if($this->mockClass('\Sly\NotificationPusher\Adapter\AdapterInterface', '\Mock'))
->and($adapter = new \Mock\AdapterInterface())
->and($devices = new BaseDeviceCollection([new BaseDevice('Token1'), new BaseDevice('Token2'), new BaseDevice('Token3')]))
@@ -81,7 +82,7 @@ class Push extends Units\Test
->boolean($object->isPushed())
->isTrue()
->dateTime($object->getPushedAt())
->isCloneOf($dt)
->hasDate($dt->format("Y"), $dt->format("m"), $dt->format('d'))
->when($object->setStatus(TestedModel::STATUS_PENDING))
->string($object->getStatus())
@@ -92,7 +93,7 @@ class Push extends Units\Test
->when($fDt = new \DateTime('2013-01-01'))
->and($object->setPushedAt($fDt))
->dateTime($object->getPushedAt())
->isCloneOf(new \DateTime('2013-01-01'))
->isIdenticalTo($fDt)
;
}
@@ -162,4 +163,5 @@ class Push extends Units\Test
->isEqualTo('Test 2')
;
}
}

View File

@@ -3,6 +3,7 @@
namespace tests\units\Sly\NotificationPusher;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Model\Response;
use Sly\NotificationPusher\PushManager as TestedModel;
use Sly\NotificationPusher\Model\Message as BaseMessage;
@@ -38,22 +39,38 @@ class PushManager extends Units\Test
->and($push = new \Mock\Push())
->and($push->getMockController()->getMessage = new BaseMessage('Test'))
->and($push->getMockController()->getDevices = new BaseDeviceCollection([new BaseDevice(self::APNS_TOKEN_EXAMPLE)]))
->and($push2 = new \Mock\Push())
->and($push2->getMockController()->getMessage = new BaseMessage('Test 2'))
->and($push2->getMockController()->getDevices = new BaseDeviceCollection([new BaseDevice(self::APNS_TOKEN_EXAMPLE)]))
->and($object = new TestedModel())
->and($object = (new TestedModel())->getPushCollection())
->when($object->add($push))
->object($object)
->isInstanceOf('\Sly\NotificationPusher\Collection\PushCollection')
->object($object->getIterator())
->hasSize(1)
->when($object->add($push2))
->object($object)
->isInstanceOf('\Sly\NotificationPusher\Collection\PushCollection')
->object($object->getIterator())
->hasSize(2)
->object($object->first())
->isEqualTo($push)
->object($object->last())
->isEqualTo($push2)
;
}
public function testPush()
{
date_default_timezone_set('UTC');
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass('\Sly\NotificationPusher\Adapter\Apns', '\Mock'))
->and($apnsAdapter = new \Mock\Apns())
->and($apnsAdapter->getMockController()->push = true)
->and($apnsAdapter->getMockController()->getResponse = new Response())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass('\Sly\NotificationPusher\Model\Push', '\Mock'))
@@ -68,6 +85,8 @@ class PushManager extends Units\Test
->object($object->push())
->isInstanceOf('\Sly\NotificationPusher\Collection\PushCollection')
->hasSize(1)
->object($object->getResponse())
->isInstanceOf('\Sly\NotificationPusher\Model\Response')
;
}
}