laravel-6 support

This commit is contained in:
RafficMohammed
2023-01-08 01:17:22 +05:30
parent 1a5c16ae4b
commit 774eed8b0e
4962 changed files with 279380 additions and 297961 deletions

View File

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

View File

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

View File

@@ -1,12 +0,0 @@
# Hey there!
#
# I plan to develop a new version of NotificationPusher this year,
# including many new features, and a Dockerized standalone microservice (K8s ready). 🙌🕺
# The current version of this lib has been writen in 2013.
#
# Of course, this new version will respect all current PHP standards (DDD powered).
#
# Feel free to participate by giving a small contribution.
# If donations allow, we'll push the project further (hosted mode, SaaS service and more).
custom: ["https://paypal.me/ph3nol"]

View File

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

View File

@@ -1,29 +0,0 @@
language: php
php:
- 5.6
- 7.0
- 7.1
- 7.2
- 7.3
- 7.4
before_script:
- composer self-update || true
- composer install --dev --prefer-source
- mkdir -p web/code-coverage data
- wget https://scrutinizer-ci.com/ocular.phar
after_script:
- php ocular.phar code-coverage:upload --format=php-clover data/coverage.clover
script:
- bin/atoum
notifications:
email:
recipients:
- cedric@dugat.me
- seyferseed@gmail.com
on_success: change
on_failure: change

View File

@@ -1,5 +0,0 @@
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

@@ -1,21 +0,0 @@
The MIT License
Copyright (c) 2013 Cédric Dugat (cedric@dugat.me)
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is furnished
to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -1,13 +0,0 @@
php_bash:
docker-compose -f docker-compose.yml exec php-cli bash -l -c "export TERM=xterm; export COLUMNS=`tput cols`; export LINES=`tput lines`; exec bash -l"
atoum:
docker-compose -f docker-compose.yml exec php-cli bash -c "./bin/atoum"
up:
docker-compose -f docker-compose.yml up -d
down:
docker-compose -f docker-compose.yml down --rmi local --volumes
restart: down up

View File

@@ -1,65 +0,0 @@
# NotificationPusher [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/ph3nol/notificationpusher?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
Standalone PHP library for easy devices message notifications push.
[![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.6+
* PHP Curl and OpenSSL modules
* 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) 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 (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
* Rewrite tests in PHPUnit 8+. (contributions are welcome!)
* 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!
## 1.x users
Old version is still available from [1.x branch](https://github.com/Ph3nol/NotificationPusher/tree/1.x), with dedicated declared tag.
[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/Ph3nol/notificationpusher/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

View File

@@ -1,58 +0,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"
},
{
"name": "Contributors",
"homepage": "https://github.com/Ph3nol/NotificationPusher/contributors"
}
],
"require": {
"php": ">=5.6",
"ext-ctype": "*",
"symfony/options-resolver": ">=2.3,<5",
"symfony/console": ">=2.3,<5",
"symfony/process": ">=2.3,<5",
"zendframework/zendservice-apple-apns": "~1.4",
"zendframework/zendservice-google-gcm": "~2.1",
"zendframework/zend-validator": "^2.12",
"doctrine/inflector": "~1.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-4": {
"Sly\\": "src/Sly/"
}
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,150 +0,0 @@
# NotificationPusher - Documentation
## APNS adapter
[APNS](http://developer.apple.com/library/ios/#documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Introduction.html) adapter is used to push notification to Apple devices.
### Basic notification push example
``` php
<?php
require_once '/path/to/vendor/autoload.php';
use Sly\NotificationPusher\PushManager,
Sly\NotificationPusher\Adapter\Apns as ApnsAdapter,
Sly\NotificationPusher\Collection\DeviceCollection,
Sly\NotificationPusher\Model\Device,
Sly\NotificationPusher\Model\Message,
Sly\NotificationPusher\Model\Push
;
// First, instantiate the manager.
//
// Example for production environment:
// $pushManager = new PushManager(PushManager::ENVIRONMENT_PROD);
//
// Development one by default (without argument).
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
// Then declare an adapter.
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
// Set the device(s) to push the notification to.
$devices = new DeviceCollection(array(
new Device('Token1'),
// ...
));
// Then, create the push skel.
$message = new Message('This is a basic example of push.');
// Finally, create and add the push to the manager, and push it!
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push();
foreach($push->getResponses() as $token => $response) {
// ...
}
```
### Custom notification push example
``` php
<?php
require_once '/path/to/vendor/autoload.php';
use Sly\NotificationPusher\PushManager,
Sly\NotificationPusher\Adapter\Apns as ApnsAdapter,
Sly\NotificationPusher\Collection\DeviceCollection,
Sly\NotificationPusher\Model\Device,
Sly\NotificationPusher\Model\Message,
Sly\NotificationPusher\Model\Push
;
// First, instantiate the manager.
//
// Example for production environment:
// $pushManager = new PushManager(PushManager::ENVIRONMENT_PROD);
//
// Development one by default (without argument).
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
// Then declare an adapter.
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
'passPhrase' => 'example',
));
// Set the device(s) to push the notification to.
$devices = new DeviceCollection(array(
new Device('Token1', array('badge' => 5)),
new Device('Token2', array('badge' => 1)),
new Device('Token3'),
));
// Then, create the push skel.
$message = new Message('This is an example.', array(
'badge' => 1,
'sound' => 'example.aiff',
'actionLocKey' => 'Action button title!',
'locKey' => 'localized key',
'locArgs' => array(
'localized args',
'localized args',
'localized args'
),
'launchImage' => 'image.jpg',
'custom' => array('custom data' => array(
'we' => 'want', 'send to app'
))
));
// Finally, create and add the push to the manager, and push it!
$push = new Push($apnsAdapter, $devices, $message);
$pushManager->add($push);
$pushManager->push(); // Returns a collection of notified devices
```
### Feedback example
The feedback service is used to list tokens of devices which not have your application anymore.
``` php
<?php
require_once '/path/to/vendor/autoload.php';
use Sly\NotificationPusher\PushManager,
Sly\NotificationPusher\Adapter\Apns as ApnsAdapter
;
// First, instantiate the manager.
//
// Example for production environment:
// $pushManager = new PushManager(PushManager::ENVIRONMENT_PROD);
//
// Development one by default (without argument).
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
// Then declare an adapter.
$apnsAdapter = new ApnsAdapter(array(
'certificate' => '/path/to/your/apns-certificate.pem',
));
$feedback = $pushManager->getFeedback($apnsAdapter); // Returns an array of Token + DateTime couples
```
* [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 (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

@@ -1,23 +0,0 @@
# NotificationPusher - Documentation
## Create an adapter
To create your own adapter, just create a class with taking care to extends `\Sly\NotificationPusher\Adapter\BaseAdapter`,
which implicitly implements `\Sly\NotificationPusher\Adapter\AdapterInterface` which contains some required methods:
* `push`: contains the adapter logic to push notifications
* `supports`: return the token condition for using the adapter
* `getDefaultParameters`: returns default parameters used by the adapter
* `getRequiredParameters`: returns required parameters used by the adapter
Feel free to observe [existent adapters](https://github.com/Ph3nol/NotificationPusher/tree/master/src/Sly/NotificationPusher/Adapter) for concrete example.
## 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
* [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

@@ -1,105 +0,0 @@
# 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
``` php
$response->getParsedResponses();
$response->getOriginalResponses();
$response->getPushCollection();
```
### Android facade
``` php
$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
``` php
$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,84 +0,0 @@
# NotificationPusher - Documentation
## 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.
##### Important
Parameter `notificatinData` is mandatory for sending messagev via FCM.
### Custom notification push example
``` php
<?php
require_once '/path/to/vendor/autoload.php';
use Sly\NotificationPusher\PushManager,
Sly\NotificationPusher\Adapter\Gcm as GcmAdapter,
Sly\NotificationPusher\Collection\DeviceCollection,
Sly\NotificationPusher\Model\Device,
Sly\NotificationPusher\Model\Message,
Sly\NotificationPusher\Model\Push
;
// First, instantiate the manager.
//
// Example for production environment:
// $pushManager = new PushManager(PushManager::ENVIRONMENT_PROD);
//
// Development one by default (without argument).
$pushManager = new PushManager(PushManager::ENVIRONMENT_DEV);
// Then declare an adapter.
$gcmAdapter = new GcmAdapter(array(
'apiKey' => 'YourApiKey',
));
// Set the device(s) to push the notification to.
$devices = new DeviceCollection(array(
new Device('Token1'),
new Device('Token2'),
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.', $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
* [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
* [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

@@ -1,95 +0,0 @@
# NotificationPusher - Documentation
## 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 (FCM) etc.)
* The Manager
Here is the basic principle of a notification push:
A **push** has 3 main elements: a composed **message**, some defined **devices** to notify
and an **adapter** matching with these devices.
The **manager** has to collect all push notifications and send them.
Here is how to translate this with code (just a little not-working example):
``` php
<?php
// First, instantiate the manager and declare an adapter.
$pushManager = new Sly\NotificationPusher\PushManager();
$exampleAdapter = new Sly\NotificationPusher\Adapter\Apns();
// Set the device(s) to push the notification to.
$devices = new Sly\NotificationPusher\Collection\DeviceCollection(array(
new Sly\NotificationPusher\Model\Device('Token1'),
new Sly\NotificationPusher\Model\Device('Token2'),
new Sly\NotificationPusher\Model\Device('Token3'),
// ...
));
// Then, create the push skel.
$message = new Sly\NotificationPusher\Model\Message('This is an example.');
// Finally, create and add the push to the manager, and push it!
$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
Some general options can be passed to the message entity and be used by adapters.
A message pushed from APNS adapter can comport a "badge" or "sound" information which will be set with
instance constructor second argument:
``` php
<?php
$message = new Sly\NotificationPusher\Model\Message('This is an example.', array(
'badge' => 1,
'sound' => 'example.aiff',
// ...
));
```
## More about the Device entity
The device can comport some dedicated informations that could be used by adapters.
For example, APNS adapter could want to know a device badge status for incrementing it with message's one.
Here is an example of this:
``` php
<?php
$message = new Sly\NotificationPusher\Model\Message('This is an example.', array(
'badge' => 1,
// ...
));
$devices = new Sly\NotificationPusher\Collection\DeviceCollection(array(
new Sly\NotificationPusher\Model\Device('Token1', array('badge' => 5)),
// ...
));
```
## Documentation index
* [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 (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

@@ -1,17 +0,0 @@
# NotificationPusher - Documentation
## Installation
Use [Composer](http://getcomposer.org) to install this library.
Run `composer require sly/notification-pusher` to install the latest version.
## Documentation index
* 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 (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

@@ -1,35 +0,0 @@
# NotificationPusher - Documentation
## Push from CLI
For some reasons (tests or others), you could be happened to use pushing from CLI.
To do this, use `np` script (available at root directory) this way:
```
./np push <adapter> <token-or-registration-id> "Your message" --option1=value1 --option2=value2 ...
```
Each options matches with adapters required and optional ones.
Here is a concrete APNS adapter example:
```
./np push apns <token> "It's an example!" --certificate=/path/to/the/certificate.pem
```
Here is a concrete GCM adapter example:
```
./np push gcm <token> "It's an example!" --api-key=XXXXXXXXXX
```
## 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
* [Facades](https://github.com/Ph3nol/NotificationPusher/blob/master/doc/facades.md)

View File

@@ -1,6 +0,0 @@
version: "2.0"
services:
php-cli:
build: ./docker/php-cli
volumes:
- ./:/var/www

View File

@@ -1,9 +0,0 @@
FROM php:7.4-cli
RUN apt-get update && apt-get install -y \
curl git
WORKDIR /var/www
#make it running
ENTRYPOINT ["tail", "-f", "/dev/null"]

View File

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

View File

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

View File

@@ -1,73 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Adapter;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Model\PushInterface;
use Sly\NotificationPusher\Model\ResponseInterface;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
interface AdapterInterface
{
/**
* @param PushInterface $push Push
*
* @return DeviceCollection
*/
public function push(PushInterface $push);
/**
* @param string $token Token
*
* @return boolean
*/
public function supports($token);
/**
* @return ResponseInterface
*/
public function getResponse();
/**
* @param ResponseInterface $response
*/
public function setResponse(ResponseInterface $response);
/**
* @return array
*/
public function getDefinedParameters();
/**
* @return array
*/
public function getDefaultParameters();
/**
* @return array
*/
public function getRequiredParameters();
/**
* @return string
*/
public function getEnvironment();
/**
* @param string $environment Environment value to set
*
* @return AdapterInterface
*/
public function setEnvironment($environment);
}

View File

@@ -1,285 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Adapter;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Exception\AdapterException;
use Sly\NotificationPusher\Exception\PushException;
use Sly\NotificationPusher\Model\BaseOptionedModel;
use Sly\NotificationPusher\Model\DeviceInterface;
use Sly\NotificationPusher\Model\MessageInterface;
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\Feedback;
use ZendService\Apple\Apns\Response\Message as ServiceResponse;
/**
* @uses \Sly\NotificationPusher\Adapter\BaseAdapter
*
* @author Cédric Dugat <cedric@dugat.me>
*/
class Apns extends BaseAdapter implements FeedbackAdapterInterface
{
/**
* @var ServiceClient
*/
private $openedClient;
/**
* @var ServiceFeedbackClient
*/
private $feedbackClient;
/**
* {@inheritdoc}
*
* @throws AdapterException
*/
public function __construct(array $parameters = [])
{
parent::__construct($parameters);
$cert = $this->getParameter('certificate');
if (false === file_exists($cert)) {
throw new AdapterException(sprintf('Certificate %s does not exist', $cert));
}
}
/**
* {@inheritdoc}
*
* @throws PushException
*/
public function push(PushInterface $push)
{
$client = $this->getOpenedServiceClient();
$pushedDevices = new DeviceCollection();
foreach ($push->getDevices() as $device) {
$message = $this->getServiceMessageFromOrigin($device, $push->getMessage());
try {
/** @var ServiceResponse $response */
$response = $client->send($message);
$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());
}
}
return $pushedDevices;
}
/**
* @return array
*/
public function getFeedback()
{
$client = $this->getOpenedFeedbackClient();
$responses = [];
$serviceResponses = $client->feedback();
/** @var Feedback $response */
foreach ($serviceResponses as $response) {
$responses[$response->getToken()] = new \DateTime(date('c', $response->getTime()));
}
return $responses;
}
/**
* @param ServiceAbstractClient|null $client Client
*
* @return ServiceAbstractClient
*/
public function getOpenedClient(ServiceAbstractClient $client = null)
{
if (!$client) {
$client = new ServiceClient();
}
$client->open(
$this->isProductionEnvironment() ? ServiceClient::PRODUCTION_URI : ServiceClient::SANDBOX_URI,
$this->getParameter('certificate'),
$this->getParameter('passPhrase')
);
return $client;
}
/**
* @return ServiceClient
*/
protected function getOpenedServiceClient()
{
if (!isset($this->openedClient)) {
$this->openedClient = $this->getOpenedClient(new ServiceClient());
}
return $this->openedClient;
}
/**
* @return ServiceFeedbackClient
*/
private function getOpenedFeedbackClient()
{
if (!isset($this->feedbackClient)) {
$this->feedbackClient = $this->getOpenedClient(new ServiceFeedbackClient());
}
return $this->feedbackClient;
}
/**
* @param DeviceInterface $device Device
* @param BaseOptionedModel|MessageInterface $message Message
*
* @return ServiceMessage
*/
public function getServiceMessageFromOrigin(DeviceInterface $device, BaseOptionedModel $message)
{
$badge = ($message->hasOption('badge'))
? (int) ($message->getOption('badge') + $device->getParameter('badge', 0))
: false;
$sound = $message->getOption('sound');
$contentAvailable = $message->getOption('content-available');
$mutableContent = $message->getOption('mutable-content');
$category = $message->getOption('category');
$urlArgs = $message->getOption('urlArgs');
$expire = $message->getOption('expire');
$alert = new ServiceAlert(
$message->getText(),
$message->getOption('actionLocKey'),
$message->getOption('locKey'),
$message->getOption('locArgs'),
$message->getOption('launchImage'),
$message->getOption('title'),
$message->getOption('titleLocKey'),
$message->getOption('titleLocArgs')
);
if ($actionLocKey = $message->getOption('actionLocKey')) {
$alert->setActionLocKey($actionLocKey);
}
if ($locKey = $message->getOption('locKey')) {
$alert->setLocKey($locKey);
}
if ($locArgs = $message->getOption('locArgs')) {
$alert->setLocArgs($locArgs);
}
if ($launchImage = $message->getOption('launchImage')) {
$alert->setLaunchImage($launchImage);
}
if ($title = $message->getOption('title')) {
$alert->setTitle($title);
}
if ($titleLocKey = $message->getOption('titleLocKey')) {
$alert->setTitleLocKey($titleLocKey);
}
if ($titleLocArgs = $message->getOption('titleLocArgs')) {
$alert->setTitleLocArgs($titleLocArgs);
}
$serviceMessage = new ServiceMessage();
$serviceMessage->setId(sha1($device->getToken() . $message->getText()));
$serviceMessage->setAlert($alert);
$serviceMessage->setToken($device->getToken());
if (false !== $badge) {
$serviceMessage->setBadge($badge);
}
$serviceMessage->setCustom($message->getOption('custom', []));
if (null !== $sound) {
$serviceMessage->setSound($sound);
}
if (null !== $contentAvailable) {
$serviceMessage->setContentAvailable($contentAvailable);
}
if (null !== $mutableContent) {
$serviceMessage->setMutableContent($mutableContent);
}
if (null !== $category) {
$serviceMessage->setCategory($category);
}
if (null !== $urlArgs) {
$serviceMessage->setUrlArgs($urlArgs);
}
if (null !== $expire) {
$serviceMessage->setExpire($expire);
}
return $serviceMessage;
}
/**
* {@inheritdoc}
*/
public function supports($token)
{
return ctype_xdigit($token);
}
/**
* {@inheritdoc}
*/
public function getDefinedParameters()
{
return [];
}
/**
* {@inheritdoc}
*/
public function getDefaultParameters()
{
return ['passPhrase' => null];
}
/**
* {@inheritdoc}
*/
public function getRequiredParameters()
{
return ['certificate'];
}
}

View File

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

View File

@@ -1,124 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Adapter;
use Sly\NotificationPusher\Model\BaseParameteredModel;
use Sly\NotificationPusher\Model\Response;
use Sly\NotificationPusher\Model\ResponseInterface;
use Sly\NotificationPusher\PushManager;
use Symfony\Component\OptionsResolver\OptionsResolver;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
abstract class BaseAdapter extends BaseParameteredModel implements AdapterInterface
{
/**
* @var string
*/
protected $adapterKey;
/**
* @var string
*/
protected $environment;
/**
* @var ResponseInterface
*/
protected $response;
/**
* @param array $parameters Adapter specific parameters
*/
public function __construct(array $parameters = [])
{
$resolver = new OptionsResolver();
$resolver->setDefined($this->getDefinedParameters());
$resolver->setDefaults($this->getDefaultParameters());
$resolver->setRequired($this->getRequiredParameters());
$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;
}
/**
* @return string
*/
public function __toString()
{
return ucfirst($this->getAdapterKey());
}
/**
* @return string
*/
public function getAdapterKey()
{
return $this->adapterKey;
}
/**
* @return string
*/
public function getEnvironment()
{
return $this->environment;
}
/**
* @param string $environment Environment value to set
*
* @return AdapterInterface
*/
public function setEnvironment($environment)
{
$this->environment = $environment;
return $this;
}
/**
* @return boolean
*/
public function isDevelopmentEnvironment()
{
return (PushManager::ENVIRONMENT_DEV === $this->getEnvironment());
}
/**
* @return boolean
*/
public function isProductionEnvironment()
{
return (PushManager::ENVIRONMENT_PROD === $this->getEnvironment());
}
}

View File

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

View File

@@ -1,243 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Adapter;
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\MessageInterface;
use Sly\NotificationPusher\Model\PushInterface;
use Zend\Http\Client as HttpClient;
use Zend\Http\Client\Adapter\Socket as HttpSocketAdapter;
use ZendService\Google\Exception\InvalidArgumentException as ZendInvalidArgumentException;
use ZendService\Google\Exception\RuntimeException as ServiceRuntimeException;
use ZendService\Google\Gcm\Client as ServiceClient;
use ZendService\Google\Gcm\Message as ServiceMessage;
use ZendService\Google\Gcm\Response;
/**
* @uses \Sly\NotificationPusher\Adapter\BaseAdapter
*
* @author Cédric Dugat <cedric@dugat.me>
*/
class Gcm extends BaseAdapter
{
/**
* @var HttpClient
*/
private $httpClient;
/**
* @var ServiceClient
*/
private $openedClient;
/**
* {@inheritdoc}
*/
public function supports($token)
{
return is_string($token) && $token !== '';
}
/**
* {@inheritdoc}
*
* @throws PushException
*/
public function push(PushInterface $push)
{
$client = $this->getOpenedClient();
$pushedDevices = new DeviceCollection();
$tokens = array_chunk($push->getDevices()->getTokens(), 100);
foreach ($tokens as $tokensRange) {
$message = $this->getServiceMessageFromOrigin($tokensRange, $push->getMessage());
try {
/** @var 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());
}
}
return $pushedDevices;
}
/**
* Get opened client.
*
* @return ServiceClient
*/
public function getOpenedClient()
{
if (!isset($this->openedClient)) {
$this->openedClient = new ServiceClient();
$this->openedClient->setApiKey($this->getParameter('apiKey'));
$newClient = new HttpClient(
null,
[
'adapter' => 'Zend\Http\Client\Adapter\Socket',
'sslverifypeer' => false,
]
);
$this->openedClient->setHttpClient($newClient);
}
return $this->openedClient;
}
/**
* Get service message from origin.
*
* @param array $tokens Tokens
* @param BaseOptionedModel|MessageInterface $message Message
*
* @return ServiceMessage
* @throws ZendInvalidArgumentException
*/
public function getServiceMessageFromOrigin(array $tokens, BaseOptionedModel $message)
{
$data = $message->getOptions();
$data['message'] = $message->getText();
$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->setPriority($this->getParameter('priority', 'normal'));
$serviceMessage->setRestrictedPackageName($this->getParameter('restrictedPackageName'));
$serviceMessage->setDelayWhileIdle($this->getParameter('delayWhileIdle', false));
$serviceMessage->setTimeToLive($this->getParameter('ttl', 600));
$serviceMessage->setDryRun($this->getParameter('dryRun', false));
return $serviceMessage;
}
/**
* {@inheritdoc}
*/
public function getDefinedParameters()
{
return [
'collapseKey',
'priority',
'delayWhileIdle',
'ttl',
'restrictedPackageName',
'dryRun',
];
}
/**
* {@inheritdoc}
*/
public function getDefaultParameters()
{
return [];
}
/**
* {@inheritdoc}
*/
public function getRequiredParameters()
{
return ['apiKey'];
}
/**
* Get the current Zend Http Client instance.
*
* @return HttpClient
*/
public function getHttpClient()
{
return $this->httpClient;
}
/**
* Overrides the default Http Client.
*
* @param HttpClient $client
*/
public function setHttpClient(HttpClient $client)
{
$this->httpClient = $client;
}
/**
* Send custom parameters to the Http Adapter without overriding the Http Client.
*
* @param array $config
*
* @throws InvalidArgumentException
*/
public function setAdapterParameters(array $config = [])
{
if (!is_array($config) || empty($config)) {
throw new InvalidArgumentException('$config must be an associative array with at least 1 item.');
}
if ($this->httpClient === null) {
$this->httpClient = new HttpClient();
$this->httpClient->setAdapter(new HttpSocketAdapter());
}
$this->httpClient->getAdapter()->setOptions($config);
}
}

View File

@@ -1,212 +0,0 @@
<?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;
/**
* @package Sly\NotificationPusher
* @author Oleg Abrazhaev <seyferseed@gmail.com>
*/
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).
$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

@@ -1,104 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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;
use ArrayIterator;
use Countable;
use IteratorAggregate;
use SeekableIterator;
use Sly\NotificationPusher\Model\MessageInterface;
/**
* @uses \IteratorAggregate
* @author Cédric Dugat <cedric@dugat.me>
*/
abstract class AbstractCollection implements IteratorAggregate, Countable
{
/**
* @var ArrayIterator
*/
protected $coll;
/**
* @inheritdoc
* @return ArrayIterator|SeekableIterator
*/
abstract public function getIterator();
/**
* @param string $key Key
*
* @return MessageInterface|false
*/
public function get($key)
{
return isset($this->coll[$key]) ? $this->coll[$key] : false;
}
/**
* @return integer
*/
public function count()
{
return $this->getIterator()->count();
}
/**
* @return boolean
*/
public function isEmpty()
{
return $this->count() === 0;
}
/**
* Clear categories.
*/
public function clear()
{
$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

@@ -1,64 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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;
use Sly\NotificationPusher\Model\DeviceInterface;
/**
* @uses \Sly\NotificationPusher\Collection\AbstractCollection
* @uses \IteratorAggregate
* @author Cédric Dugat <cedric@dugat.me>
*/
class DeviceCollection extends AbstractCollection
{
/**
* @param array $devices Devices
*/
public function __construct(array $devices = [])
{
$this->coll = new \ArrayIterator();
foreach ($devices as $device) {
$this->add($device);
}
}
/**
* @return \ArrayIterator
*/
public function getIterator()
{
return $this->coll;
}
/**
* @param DeviceInterface $device Device
*/
public function add(DeviceInterface $device)
{
$this->coll[$device->getToken()] = $device;
}
/**
* @return array
*/
public function getTokens()
{
$tokens = [];
foreach ($this as $device) {
$tokens[] = $device->getToken();
}
return array_unique(array_filter($tokens));
}
}

View File

@@ -1,43 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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;
use Sly\NotificationPusher\Model\MessageInterface;
/**
* @uses \Sly\NotificationPusher\Collection\AbstractCollection
* @uses \IteratorAggregate
* @author Cédric Dugat <cedric@dugat.me>
*/
class MessageCollection extends AbstractCollection
{
public function __construct()
{
$this->coll = new \ArrayIterator();
}
/**
* @return \ArrayIterator
*/
public function getIterator()
{
return $this->coll;
}
/**
* @param MessageInterface $message Message
*/
public function add(MessageInterface $message)
{
$this->coll[] = $message;
}
}

View File

@@ -1,43 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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;
use Sly\NotificationPusher\Model\PushInterface;
/**
* @uses \Sly\NotificationPusher\Collection\AbstractCollection
* @uses \IteratorAggregate
* @author Cédric Dugat <cedric@dugat.me>
*/
class PushCollection extends AbstractCollection
{
public function __construct()
{
$this->coll = new \ArrayIterator();
}
/**
* @return \ArrayIterator
*/
public function getIterator()
{
return $this->coll;
}
/**
* @param PushInterface $push Push
*/
public function add(PushInterface $push)
{
$this->coll[] = $push;
}
}

View File

@@ -1,46 +0,0 @@
<?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
{
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

@@ -1,32 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Console;
use Sly\NotificationPusher\Console\Command\PushCommand;
use Sly\NotificationPusher\NotificationPusher;
use Symfony\Component\Console\Application as BaseApplication;
/**
* @uses \Symfony\Component\Console\Application
* @author Cédric Dugat <cedric@dugat.me>
*/
class Application extends BaseApplication
{
public function __construct()
{
error_reporting(-1);
parent::__construct('NotificationPusher version', NotificationPusher::VERSION);
$this->add(new PushCommand());
}
}

View File

@@ -1,156 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Console\Command;
use Doctrine\Common\Inflector\Inflector;
use Exception;
use Sly\NotificationPusher\Adapter\AdapterInterface;
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;
/**
* @uses \Symfony\Component\Console\Command\Command
* @author Cédric Dugat <cedric@dugat.me>
*/
class PushCommand extends Command
{
/**
* @see Command
*/
protected function configure()
{
parent::configure();
$this
->setName('push')
->setDescription('Manual notification push')
->addArgument(
'adapter',
InputArgument::REQUIRED,
'Adapter (apns, gcm, specific class name, ...)'
)
->addArgument(
'token',
InputArgument::REQUIRED,
'Device Token or Registration ID'
)
->addArgument(
'message',
InputArgument::REQUIRED,
'Message'
)
->addOption(
'certificate',
null,
InputOption::VALUE_OPTIONAL,
'Certificate path (for APNS adapter)'
)
->addOption(
'api-key',
null,
InputOption::VALUE_OPTIONAL,
'API key (for GCM adapter)'
)
->addOption(
'env',
PushManager::ENVIRONMENT_DEV,
InputOption::VALUE_OPTIONAL,
sprintf(
'Environment (%s, %s)',
PushManager::ENVIRONMENT_DEV,
PushManager::ENVIRONMENT_PROD
)
);
}
/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$adapter = $this->getReadyAdapter($input, $output);
$pushManager = new PushManager($input->getOption('env'));
$message = new Message($input->getArgument('message'));
$push = new Push($adapter, new Device($input->getArgument('token')), $message);
$pushManager->add($push);
$pushManager->push();
}
/**
* @param string $argument Given argument
*
* @return string
*
* @throws AdapterException When given adapter class doesn't exist
*/
private function getAdapterClassFromArgument($argument)
{
if (!class_exists($adapterClass = $argument) &&
!class_exists($adapterClass = '\\Sly\\NotificationPusher\\Adapter\\' . ucfirst($argument))) {
throw new AdapterException(
sprintf(
'Adapter class %s does not exist',
$adapterClass
)
);
}
return $adapterClass;
}
/**
* {@inheritdoc}
*
* @return AdapterInterface
*/
private function getReadyAdapter(InputInterface $input, OutputInterface $output)
{
$adapterClass = $this->getAdapterClassFromArgument($input->getArgument('adapter'));
try {
$adapter = new $adapterClass();
} catch (Exception $e) {
$adapterData = [];
preg_match_all('/"(.*)"/i', $e->getMessage(), $matches);
foreach ($matches[1] as $match) {
$optionKey = str_replace('_', '-', Inflector::tableize($match));
$option = $input->getOption($optionKey);
if (!$option) {
throw new AdapterException(
sprintf(
'The option "%s" is needed by %s adapter',
$optionKey,
$adapterClass
)
);
}
$adapterData[$match] = $option;
}
$adapter = new $adapterClass($adapterData);
}
return $adapter;
}
}

View File

@@ -1,22 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Exception;
/**
* @uses \RuntimeException
* @uses \Sly\NotificationPusher\Exception\ExceptionInterface
*
* @author Cédric Dugat <cedric@dugat.me>
*/
class AdapterException extends \RuntimeException implements ExceptionInterface
{
}

View File

@@ -1,19 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Exception;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
interface ExceptionInterface
{
}

View File

@@ -1,22 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Exception;
/**
* @uses \RuntimeException
* @uses \Sly\NotificationPusher\Exception\ExceptionInterface
*
* @author Cédric Dugat <cedric@dugat.me>
*/
class InvalidException extends \RuntimeException implements ExceptionInterface
{
}

View File

@@ -1,22 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Exception;
/**
* @uses \RuntimeException
* @uses \Sly\NotificationPusher\Exception\ExceptionInterface
*
* @author Cédric Dugat <cedric@dugat.me>
*/
class PushException extends \RuntimeException implements ExceptionInterface
{
}

View File

@@ -1,22 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Exception;
/**
* @uses \RuntimeException
* @uses \Sly\NotificationPusher\Exception\ExceptionInterface
*
* @author Cédric Dugat <cedric@dugat.me>
*/
class RuntimeException extends \RuntimeException implements ExceptionInterface
{
}

View File

@@ -1,158 +0,0 @@
<?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
* @author Oleg Abrazhaev <seyferseed@gmail.com>
*/
class GcmPushService extends AbstractPushService
{
/**
* @var string
*/
private $apiKey = '';
/**
* @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).
$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)) {
$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)) {
$tokens[] = $token;
}
}
return $tokens;
}
}

View File

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

View File

@@ -1,77 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
abstract class BaseOptionedModel
{
/**
* @var array
*/
protected $options = [];
/**
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* @param string $key Key
*
* @return boolean
*/
public function hasOption($key)
{
return array_key_exists($key, $this->options);
}
/**
* @param string $key Key
* @param mixed $default Default
*
* @return mixed
*/
public function getOption($key, $default = null)
{
return $this->hasOption($key) ? $this->options[$key] : $default;
}
/**
* @param array $options Options
*
* @return BaseOptionedModel
*/
public function setOptions($options)
{
$this->options = $options;
return $this;
}
/**
* @param string $key Key
* @param mixed $value Value
*
* @return mixed
*/
public function setOption($key, $value)
{
$this->options[$key] = $value;
return $value;
}
}

View File

@@ -1,77 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
abstract class BaseParameteredModel
{
/**
* @var array
*/
protected $parameters = [];
/**
* @return array
*/
public function getParameters()
{
return $this->parameters;
}
/**
* @param string $key Key
*
* @return boolean
*/
public function hasParameter($key)
{
return array_key_exists($key, $this->parameters);
}
/**
* @param string $key Key
* @param mixed $default Default
*
* @return mixed
*/
public function getParameter($key, $default = null)
{
return $this->hasParameter($key) ? $this->parameters[$key] : $default;
}
/**
* @param array $parameters Parameters
*
* @return BaseParameteredModel
*/
public function setParameters($parameters)
{
$this->parameters = $parameters;
return $this;
}
/**
* @param string $key Key
* @param mixed $value Value
*
* @return mixed
*/
public function setParameter($key, $value)
{
$this->parameters[$key] = $value;
return $value;
}
}

View File

@@ -1,53 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
class Device extends BaseParameteredModel implements DeviceInterface
{
/**
* @var string
*/
private $token;
/**
* @param string $token Token
* @param array $parameters Parameters
*/
public function __construct($token, array $parameters = [])
{
$this->token = $token;
$this->parameters = $parameters;
}
/**
* @return string
*/
public function getToken()
{
return $this->token;
}
/**
* @param string $token Token
*
* @return DeviceInterface
*/
public function setToken($token)
{
$this->token = $token;
return $this;
}
}

View File

@@ -1,30 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
interface DeviceInterface
{
/**
* @return string
*/
public function getToken();
/**
* @param string $token Token
*
* @return DeviceInterface
*/
public function setToken($token);
}

View File

@@ -1,28 +0,0 @@
<?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

@@ -1,53 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
class Message extends BaseOptionedModel implements MessageInterface
{
/**
* @var string
*/
protected $text;
/**
* @param string $text Text
* @param array $options Options
*/
public function __construct($text, array $options = [])
{
$this->text = $text;
$this->options = $options;
}
/**
* @return string
*/
public function getText()
{
return $this->text;
}
/**
* @param string $text Text
*
* @return MessageInterface
*/
public function setText($text)
{
$this->text = $text;
return $this;
}
}

View File

@@ -1,30 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
interface MessageInterface
{
/**
* @return string
*/
public function getText();
/**
* @param string $text Text
*
* @return MessageInterface
*/
public function setText($text);
}

View File

@@ -1,242 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
use Sly\NotificationPusher\Adapter\AdapterInterface;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Collection\ResponseCollection;
use Sly\NotificationPusher\Exception\AdapterException;
/**
* @author Cédric Dugat <cedric@dugat.me>
*/
class Push extends BaseOptionedModel implements PushInterface
{
/**
* @var string
*/
private $status;
/**
* @var AdapterInterface
*/
private $adapter;
/**
* @var MessageInterface
*/
private $message;
/**
* @var DeviceCollection
*/
private $devices;
/**
* @var \DateTime
*/
private $pushedAt;
/**
* @var ResponseCollection
*/
private $responses;
/**
* @param AdapterInterface $adapter Adapter
* @param DeviceInterface|DeviceCollection $devices Device(s)
* @param 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.
*
* @throws AdapterException
*/
public function __construct(AdapterInterface $adapter, $devices, MessageInterface $message, array $options = [])
{
if ($devices instanceof DeviceInterface) {
$devices = new DeviceCollection([$devices]);
}
$this->adapter = $adapter;
$this->devices = $devices;
$this->message = $message;
$this->options = $options;
$this->status = self::STATUS_PENDING;
$this->checkDevicesTokens();
}
/**
* @throws AdapterException
*/
private function checkDevicesTokens()
{
$devices = $this->getDevices();
$adapter = $this->getAdapter();
foreach ($devices as $device) {
if (false === $adapter->supports($device->getToken())) {
throw new AdapterException(
sprintf(
'Adapter %s does not support %s token\'s device',
(string) $adapter,
$device->getToken()
)
);
}
}
}
/**
* @return string
*/
public function getStatus()
{
return $this->status;
}
/**
* @param string $status Status
*
* @return PushInterface
*/
public function setStatus($status)
{
$this->status = $status;
return $this;
}
/**
* @return boolean
*/
public function isPushed()
{
return (bool) (self::STATUS_PUSHED === $this->status);
}
/**
* @return PushInterface
*/
public function pushed()
{
$this->status = self::STATUS_PUSHED;
$this->pushedAt = new \DateTime();
return $this;
}
/**
* @return AdapterInterface
*/
public function getAdapter()
{
return $this->adapter;
}
/**
* @param AdapterInterface $adapter Adapter
*
* @return PushInterface
*/
public function setAdapter(AdapterInterface $adapter)
{
$this->adapter = $adapter;
return $this;
}
/**
* @return MessageInterface
*/
public function getMessage()
{
return $this->message;
}
/**
* @param MessageInterface $message Message
*
* @return PushInterface
*/
public function setMessage(MessageInterface $message)
{
$this->message = $message;
return $this;
}
/**
* @return DeviceCollection
*/
public function getDevices()
{
return $this->devices;
}
/**
* @param DeviceCollection $devices Devices
*
* @return PushInterface
*/
public function setDevices(DeviceCollection $devices)
{
$this->devices = $devices;
$this->checkDevicesTokens();
return $this;
}
/**
* @return ResponseCollection
*/
public function getResponses()
{
if (!$this->responses)
$this->responses = new ResponseCollection();
return $this->responses;
}
/**
* @param DeviceInterface $device
* @param mixed $response
*/
public function addResponse(DeviceInterface $device, $response)
{
$this->getResponses()->add($device->getToken(), $response);
}
/**
* @return \DateTime
*/
public function getPushedAt()
{
return $this->pushedAt;
}
/**
* @param \DateTime $pushedAt PushedAt
*
* @return PushInterface
*/
public function setPushedAt(\DateTime $pushedAt)
{
$this->pushedAt = $pushedAt;
return $this;
}
}

View File

@@ -1,107 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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\Model;
use DateTime;
use Sly\NotificationPusher\Adapter\AdapterInterface;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Collection\ResponseCollection;
interface PushInterface
{
/**
* Constants define available statuses
*/
const STATUS_PENDING = 'pending';
const STATUS_PUSHED = 'sent';
/**
* @return string
*/
public function getStatus();
/**
* @param string $status Status
*
* @return PushInterface
*/
public function setStatus($status);
/**
* @return boolean
*/
public function isPushed();
/**
* @return PushInterface
*/
public function pushed();
/**
* @return AdapterInterface
*/
public function getAdapter();
/**
* @param AdapterInterface $adapter Adapter
*
* @return PushInterface
*/
public function setAdapter(AdapterInterface $adapter);
/**
* @return MessageInterface
*/
public function getMessage();
/**
* @param MessageInterface $message Message
*
* @return PushInterface
*/
public function setMessage(MessageInterface $message);
/**
* @return DeviceCollection
*/
public function getDevices();
/**
* @param DeviceCollection $devices Devices
*
* @return PushInterface
*/
public function setDevices(DeviceCollection $devices);
/**
* @return ResponseCollection
*/
public function getResponses();
/**
* @param DeviceInterface $device
* @param mixed $response
*/
public function addResponse(DeviceInterface $device, $response);
/**
* @return DateTime
*/
public function getPushedAt();
/**
* @param DateTime $pushedAt PushedAt
*
* @return PushInterface
*/
public function setPushedAt(DateTime $pushedAt);
}

View File

@@ -1,92 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 09.08.17
* Time: 17:57
*/
namespace Sly\NotificationPusher\Model;
use Sly\NotificationPusher\Collection\PushCollection;
/**
* @author Oleg Abrazhaev <seyferseed@gmail.com>
*/
class Response implements ResponseInterface
{
/**
* @var array
*/
private $parsedResponses = [];
/**
* @var array
*/
private $originalResponses = [];
/**
* @var PushCollection
*/
private $pushCollection;
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 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

@@ -1,49 +0,0 @@
<?php
/**
* Created by PhpStorm.
* User: seyfer
* Date: 10.08.17
* Time: 10:30
*/
namespace Sly\NotificationPusher\Model;
use Sly\NotificationPusher\Collection\PushCollection;
/**
* @author Oleg Abrazhaev <seyferseed@gmail.com>
*/
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 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

@@ -1,17 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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;
class NotificationPusher
{
const VERSION = '2.0';
}

View File

@@ -1,132 +0,0 @@
<?php
/*
* This file is part of NotificationPusher.
*
* (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;
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;
/**
* @uses \Sly\NotificationPusher\Collection\PushCollection
* @author Cédric Dugat <cedric@dugat.me>
*/
class PushManager
{
const ENVIRONMENT_DEV = 'dev';
const ENVIRONMENT_PROD = 'prod';
/**
* @var string
*/
private $environment;
/**
* @var PushCollection
*/
private $pushCollection;
/**
* @var ResponseInterface
*/
private $response;
/**
* @param string $environment Environment
*/
public function __construct($environment = self::ENVIRONMENT_DEV)
{
$this->environment = $environment;
$this->pushCollection = new PushCollection();
}
/**
* @param PushInterface $push Push
*/
public function add(PushInterface $push)
{
$this->pushCollection->add($push);
}
/**
* @return string
*/
public function getEnvironment()
{
return $this->environment;
}
/**
* @return PushCollection
*/
public function push()
{
/** @var Push $push */
foreach ($this->pushCollection as $push) {
$adapter = $push->getAdapter();
$adapter->setEnvironment($this->getEnvironment());
if ($adapter->push($push)) {
$push->pushed();
}
}
if ($this->pushCollection && !$this->pushCollection->isEmpty()) {
/** @var Push $push */
$push = $this->pushCollection->first();
$this->response = $push->getAdapter()->getResponse();
}
return $this->pushCollection;
}
/**
* @param AdapterInterface $adapter Adapter
*
* @return array
*
* @throws AdapterException When the adapter has no dedicated `getFeedback` method
*/
public function getFeedback(AdapterInterface $adapter)
{
if (!$adapter instanceof FeedbackAdapterInterface) {
throw new AdapterException(
sprintf(
'%s adapter has no dedicated "getFeedback" method',
(string) $adapter
)
);
}
$adapter->setEnvironment($this->getEnvironment());
return $adapter->getFeedback();
}
/**
* @return PushCollection
*/
public function getPushCollection()
{
return $this->pushCollection;
}
/**
* @return ResponseInterface
*/
public function getResponse()
{
return $this->response;
}
}

View File

@@ -1,195 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Adapter;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Adapter\Apns as TestedModel;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Exception\AdapterException;
use Sly\NotificationPusher\Model\Device;
use Sly\NotificationPusher\Model\Message;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\Model\Response;
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
use ZendService\Apple\Apns\Client\Feedback;
use ZendService\Apple\Apns\Client\Message as ZendClientMessage;
use ZendService\Apple\Apns\Message as ZendServiceMessage;
use ZendService\Apple\Apns\Response\Message as ZendResponseMessage;
use ZendService\Apple\Exception\InvalidArgumentException;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class Apns extends Units\Test
{
const APNS_TOKEN_EXAMPLE_64 = '111db24975bb6c6b63214a8d268052aa0a965cc1e32110ab06a72b19074c2222';
const APNS_TOKEN_EXAMPLE_65 = '111db24975bb6c6b63214a8d268052aa0a965cc1e32110ab06a72b19074c22225';
public function testConstruct()
{
$this
->exception(static function () {
$object = new TestedModel();
})
->isInstanceOf(MissingOptionsException::class)
->message
->contains('certificate')
->exception(static function () {
$object = new TestedModel(['certificate' => 'absent.pem']);
})
->isInstanceOf(AdapterException::class)
->message
->contains('does not exist')
->when($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\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)
->string($object->getParameter('certificate'))
->isEqualTo('test.pem');
}
public function testSupports()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Apns())
->boolean($object->supports('wrongToken'))
->isFalse()
->boolean($object->supports(self::APNS_TOKEN_EXAMPLE_64))
->isTrue()
->boolean($object->supports(self::APNS_TOKEN_EXAMPLE_65))
->isTrue();
}
public function testDefinedParameters()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Apns())
->array($defaultParameters = $object->getDefinedParameters())
->isEmpty();
}
public function testDefaultParameters()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Apns())
->array($defaultParameters = $object->getDefaultParameters())
->isNotEmpty()
->hasKey('passPhrase')
->variable($defaultParameters['passPhrase'])
->isNull();
}
public function testRequiredParameters()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Apns())
->array($requiredParameters = $object->getRequiredParameters())
->isNotEmpty()
->contains('certificate');
}
public function testGetOpenedClient()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Apns())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockGenerator()->orphanize('open'))
->and($this->mockClass(ZendClientMessage::class, '\Mock\ZendService'))
->and($serviceClient = new \Mock\ZendService\Message())
->and($object->getMockController()->getParameters = [])
->exception(static function () use ($object) {
$object->getOpenedClient(new ZendClientMessage());
})
->isInstanceOf(InvalidArgumentException::class)
->message
->contains('Certificate must be a valid path to a APNS certificate')
->when($object = new TestedModel(['certificate' => __DIR__ . '/../Resources/apns-certificate.pem']))
->and($object->getOpenedClient($serviceClient));
}
public function testGetServiceMessageFromOrigin()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Apns())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Device::class, '\Mock'))
->and($device = new \Mock\Device())
->and($device->getMockController()->getToken = self::APNS_TOKEN_EXAMPLE_64)
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Message::class, '\Mock'))
->and($message = new \Mock\Message())
->and($message->getMockController()->getText = 'Test')
->object($object->getServiceMessageFromOrigin($device, $message))
->isInstanceOf(ZendServiceMessage::class);
}
public function testPush()
{
$this->if($this->mockGenerator()->orphanize('__construct')
->makeVisible('getOpenedServiceClient')
->generate(TestedModel::class, '\Mock', 'Apns'))
->and($object = new \Mock\Apns())
->and($object->setResponse(new Response()))
->and($this->mockClass(ZendResponseMessage::class, '\Mock\ZendService', 'Response'))
->and($serviceResponse = new \Mock\ZendService\Response())
->and($serviceResponse->getMockController()->getCode = ZendResponseMessage::RESULT_OK)
->and($serviceResponse->getMockController()->getId = 0)
->and($this->mockGenerator()->orphanize('__construct')
->orphanize('open')
->orphanize('send')
->generate(ZendClientMessage::class, '\Mock\ZendService'))
->and($serviceClient = new \Mock\ZendService\Message())
->and($serviceClient->getMockController()->send = $serviceResponse)
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Push::class, '\Mock'))
->and($push = new \Mock\Push())
->and($push->getMockController()->getMessage = new Message('Test'))
->and($push->getMockController()->getDevices = new DeviceCollection(
[new Device(self::APNS_TOKEN_EXAMPLE_64)]
))
->and($object->getMockController()->getServiceMessageFromOrigin = new ZendServiceMessage())
->and($object->getMockController()->getOpenedClient = $serviceClient)
->and($this->calling($object)->getOpenedServiceClient = $serviceClient)
->object($result = $object->push($push))
->isInstanceOf(DeviceCollection::class)
->boolean($result->count() == 1)
->isTrue();
}
public function testCountIsEmpty()
{
$this->if($dcoll = new DeviceCollection())
->boolean($dcoll->isEmpty())
->isTrue();
}
public function testFeedback()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Apns())
->and($this->mockClass(ZendResponseMessage::class, '\Mock\ZendService', 'Response'))
->and($serviceResponse = new \Mock\ZendService\Response())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockGenerator()->orphanize('open'))
->and($this->mockGenerator()->orphanize('send'))
->and($this->mockClass(Feedback::class, '\Mock\ZendService'))
->and($serviceClient = new \Mock\ZendService\Feedback())
->and($serviceClient->getMockController()->feedback = $serviceResponse)
->and($object->getMockController()->getServiceMessageFromOrigin = new ZendServiceMessage())
->and($object->getMockController()->getOpenedClient = $serviceClient)
->array($object->getFeedback())
->isEmpty();
}
}

View File

@@ -1,46 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Adapter;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\PushManager;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class BaseAdapter extends Units\Test
{
public function testAdapterKey()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(\Sly\NotificationPusher\Adapter\Apns::class, '\Mock'))
->and($object = new \Mock\Apns())
->and($object->getMockController()->getAdapterKey = 'Apns')
->string($object->getAdapterKey())
->isEqualTo('Apns')
->string((string) $object)
->isEqualTo('Apns');
}
public function testEnvironment()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(\Sly\NotificationPusher\Adapter\Apns::class, '\Mock'))
->and($object = new \Mock\Apns())
->when($object->setEnvironment(PushManager::ENVIRONMENT_DEV))
->string($object->getEnvironment())
->isEqualTo(PushManager::ENVIRONMENT_DEV)
->boolean($object->isDevelopmentEnvironment())
->isTrue()
->boolean($object->isProductionEnvironment())
->isFalse()
->when($object->setEnvironment(PushManager::ENVIRONMENT_PROD))
->string($object->getEnvironment())
->isEqualTo(PushManager::ENVIRONMENT_PROD)
->boolean($object->isProductionEnvironment())
->isTrue()
->boolean($object->isDevelopmentEnvironment())
->isFalse();
}
}

View File

@@ -1,191 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Adapter;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Adapter\Gcm as TestedModel;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Model\Device;
use Sly\NotificationPusher\Model\GcmMessage;
use Sly\NotificationPusher\Model\Message;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\Model\Response;
use Symfony\Component\OptionsResolver\Exception\MissingOptionsException;
use ZendService\Google\Exception\InvalidArgumentException;
use ZendService\Google\Gcm\Client as ZendServiceClient;
use ZendService\Google\Gcm\Message as ZendServiceMessage;
use ZendService\Google\Gcm\Response as ZendResponseAlias;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class Gcm extends Units\Test
{
const GCM_TOKEN_EXAMPLE = 'AAA91bG9ISdL94D55C69NplFlxicy0iFUFTyWh3AAdMfP9npH5r_JQFTo27xpX1jfqGf-aSe6xZAsfWRefjazJpqFt03Isanv-Fi97020EKLye0ApTkHsw_0tJJzgA2Js0NsG1jLWsiJf63YSF8ropAcRp4BSxVBBB';
// The format of GCM tokens apparently have changed, this string looks similar to new format:
const ALT_GCM_TOKEN_EXAMPLE = 'AAA91bG9ISd:L94D55C69NplFlxicy0iFUFTyWh3AAdMfP9npH5r_JQFTo27xpX1jfqGf-aSe6xZAsfWRefjazJpqFt03Isanv-Fi97020EKLye0ApTkHsw_0tJJzgA2Js0NsG1jLWsiJf63YSF8ropA';
public function testConstruct()
{
$this
->exception(function () {
$object = new TestedModel();
})
->isInstanceOf(MissingOptionsException::class)
->message
->contains('apiKey')
->when($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->and($object->setParameters(['apiKey' => 'test']))
->array($object->getParameters())
->isNotEmpty()
->hasSize(1)
->string($object->getParameter('apiKey'))
->isEqualTo('test');
}
public function testSupports()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->boolean($object->supports('')) // Test empty string
->isFalse()
->boolean($object->supports(2)) // Test a number
->isFalse()
->boolean($object->supports([])) // Test an array
->isFalse()
->boolean($object->supports(json_decode('{}'))) // Tests an object
->isFalse()
->boolean($object->supports(self::GCM_TOKEN_EXAMPLE))
->isTrue()
->boolean($object->supports(self::ALT_GCM_TOKEN_EXAMPLE))
->isTrue();
}
public function testDefinedParameters()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->array($definedParameters = $object->getDefinedParameters())
->isNotEmpty()
->containsValues([
'collapseKey',
'delayWhileIdle',
'ttl',
'restrictedPackageName',
'dryRun',
]);
}
public function testDefaultParameters()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->array($defaultParameters = $object->getDefaultParameters())
->isEmpty();
}
public function testRequiredParameters()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->array($requiredParameters = $object->getRequiredParameters())
->isNotEmpty()
->contains('apiKey');
}
public function testGetOpenedClient()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockGenerator()->orphanize('open'))
->and($this->mockClass(ZendServiceClient::class, '\Mock\ZendService'))
->and($serviceClient = new \Mock\ZendService\Client())
->and($object->getMockController()->getParameters = [])
->exception(function () use ($object) {
$object->getOpenedClient(new ZendServiceClient());
})
->isInstanceOf(InvalidArgumentException::class)
->message
->contains('The api key must be a string and not empty')
->when($object = new TestedModel(['apiKey' => 'test']))
->and($object->getOpenedClient($serviceClient));
}
public function testGetServiceMessageFromOrigin()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Message::class, '\Mock'))
->and($message = new \Mock\Message())
->and($message->getMockController()->getOptions = [
'param' => 'test',
'notificationData' => ['some' => 'foobar'],
])
->and($message->getMockController()->getText = 'Test')
->object($originalMessage = $object->getServiceMessageFromOrigin([self::GCM_TOKEN_EXAMPLE], $message))
->isInstanceOf(ZendServiceMessage::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(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(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(ZendServiceMessage::class)
->array($originalMessage->getData())
->notHasKey('notificationData')
->array($originalMessage->getNotification())
->hasKey('some')
->contains('foobar');
}
public function testPush()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(TestedModel::class, '\Mock'))
->and($object = new \Mock\Gcm())
->and($object->setResponse(new Response()))
->and($this->mockClass(ZendResponseAlias::class, '\Mock\ZendService'))
->and($serviceResponse = new \Mock\ZendService\Response())
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockGenerator()->orphanize('open'))
->and($this->mockGenerator()->orphanize('send'))
->and($this->mockClass(ZendServiceClient::class, '\Mock\ZendService'))
->and($serviceClient = new \Mock\ZendService\Message())
->and($serviceClient->getMockController()->send = new $serviceResponse)
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Push::class, '\Mock'))
->and($push = new \Mock\Push())
->and($push->getMockController()->getMessage = new Message('Test'))
->and($push->getMockController()->getDevices = new DeviceCollection([new Device(self::GCM_TOKEN_EXAMPLE)]))
->and($object->getMockController()->getServiceMessageFromOrigin = new ZendServiceMessage())
->and($object->getMockController()->getOpenedClient = $serviceClient)
->object($object->push($push))
->isInstanceOf(DeviceCollection::class)
->hasSize(1);
}
}

View File

@@ -1,43 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Model;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Model\Message;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class BaseOptionedModel extends Units\Test
{
public function testMethods()
{
$this->if($object = new Message('Test', ['param' => 'test']))
->boolean($object->hasOption('param'))
->isTrue()
->string($object->getOption('param'))
->isEqualTo('test')
->boolean($object->hasOption('notExist'))
->isFalse()
->variable($object->getOption('notExist'))
->isNull()
->string($object->getOption('renotExist', '12345'))
->isEqualTo('12345')
->when($object->setOptions(['chuck' => 'norris']))
->boolean($object->hasOption('chuck'))
->isTrue()
->string($object->getOption('chuck'))
->isEqualTo('norris')
->when($object->setOption('poney', 'powerful'))
->boolean($object->hasOption('poney'))
->isTrue()
->string($object->getOption('poney'))
->isEqualTo('powerful')
->when($object->setOption('null', null))
->boolean($object->hasOption('null'))
->isTrue()
->variable($object->getOption('null'))
->isNull();
}
}

View File

@@ -1,43 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Model;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Model\Device;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class BaseParameteredModel extends Units\Test
{
public function testMethods()
{
$this->if($object = new Device('Test', ['param' => 'test']))
->boolean($object->hasParameter('param'))
->isTrue()
->string($object->getParameter('param'))
->isEqualTo('test')
->boolean($object->hasParameter('notExist'))
->isFalse()
->variable($object->getParameter('notExist'))
->isNull()
->string($object->getParameter('renotExist', '12345'))
->isEqualTo('12345')
->when($object->setParameters(['chuck' => 'norris']))
->boolean($object->hasParameter('chuck'))
->isTrue()
->string($object->getParameter('chuck'))
->isEqualTo('norris')
->when($object->setParameter('poney', 'powerful'))
->boolean($object->hasParameter('poney'))
->isTrue()
->string($object->getParameter('poney'))
->isEqualTo('powerful')
->when($object->setParameter('null', null))
->boolean($object->hasParameter('null'))
->isTrue()
->variable($object->getParameter('null'))
->isNull();
}
}

View File

@@ -1,30 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Model;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Model\Device as TestedModel;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class Device extends Units\Test
{
public function testConstruct()
{
$this->if($object = new TestedModel('t0k3n'))
->string($object->getToken())->isEqualTo('t0k3n')
->array($object->getParameters())->isEmpty();
$this->if($object = new TestedModel('t0k3n', ['param' => 'test']))
->string($object->getToken())->isEqualTo('t0k3n')
->when($object->setToken('t0k3ns3tt3d'))
->string($object->getToken())->isEqualTo('t0k3ns3tt3d')
->array($object->getParameters())
->hasKey('param')
->contains('test')
->size
->isEqualTo(1);
}
}

View File

@@ -1,32 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Model;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Model\Message as TestedModel;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class Message extends Units\Test
{
public function testConstruct()
{
$this->if($object = new TestedModel('Test'))
->string($object->getText())->isEqualTo('Test')
->array($object->getOptions())->isEmpty();
$this->if($object = new TestedModel('Test', [
'param' => 'test',
]))
->string($object->getText())->isEqualTo('Test')
->when($object->setText('Test 2'))
->string($object->getText())->isEqualTo('Test 2')
->array($object->getOptions())
->hasKey('param')
->contains('test')
->size
->isEqualTo(1);
}
}

View File

@@ -1,146 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher\Model;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Adapter\AdapterInterface;
use Sly\NotificationPusher\Adapter\Apns;
use Sly\NotificationPusher\Adapter\Gcm;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Exception\AdapterException;
use Sly\NotificationPusher\Model\Device as DeviceModel;
use Sly\NotificationPusher\Model\Message as MessageModel;
use Sly\NotificationPusher\Model\Push as TestedModel;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class Push extends Units\Test
{
const APNS_TOKEN_EXAMPLE = '111db24975bb6c6b63214a8d268052aa0a965cc1e32110ab06a72b19074c2222';
const GCM_TOKEN_EXAMPLE = 'AAA91bG9ISdL94D55C69NplFlxicy0iFUFTyWh3AAdMfP9npH5r_JQFTo27xpX1jfqGf-aSe6xZAsfWRefjazJpqFt03Isanv-Fi97020EKLye0ApTkHsw_0tJJzgA2Js0NsG1jLWsiJf63YSF8ropAcRp4BSxVBBB';
public function testConstructWithOneDevice()
{
$this->if($this->mockClass(AdapterInterface::class, '\Mock'))
->and($adapter = new \Mock\AdapterInterface())
->and($devices = new DeviceModel('Token1'))
->and($message = new MessageModel('Test'))
->and($object = new TestedModel($adapter, $devices, $message))
->object($object->getDevices())
->isInstanceOf(DeviceCollection::class)
->integer($object->getDevices()->count())
->isEqualTo(1)
->array($object->getOptions())
->isEmpty();
}
public function testConstructWithManyDevicesAndOptions()
{
$this->if($this->mockClass(AdapterInterface::class, '\Mock'))
->and($adapter = new \Mock\AdapterInterface())
->and($devices = new DeviceCollection([new DeviceModel('Token1'), new DeviceModel('Token2'),
new DeviceModel('Token3')]))
->and($message = new MessageModel('Test'))
->and($object = new TestedModel($adapter, $devices, $message, ['param' => 'test']))
->object($object->getDevices())
->isInstanceOf(DeviceCollection::class)
->integer($object->getDevices()->count())
->isEqualTo(3)
->array($object->getOptions())
->hasKey('param')
->contains('test')
->size
->isEqualTo(1);
}
public function testStatus()
{
date_default_timezone_set('UTC');
$this->if($this->mockClass(AdapterInterface::class, '\Mock'))
->and($adapter = new \Mock\AdapterInterface())
->and($devices = new DeviceCollection([new DeviceModel('Token1'), new DeviceModel('Token2'),
new DeviceModel('Token3')]))
->and($message = new MessageModel('Test'))
->and($object = new TestedModel($adapter, $devices, $message))
->string($object->getStatus())
->isEqualTo(TestedModel::STATUS_PENDING)
->boolean($object->isPushed())
->isFalse()
->when($object->pushed())
->and($dt = new \DateTime())
->string($object->getStatus())
->isEqualTo(TestedModel::STATUS_PUSHED)
->boolean($object->isPushed())
->isTrue()
->dateTime($object->getPushedAt())
->hasDate($dt->format("Y"), $dt->format("m"), $dt->format('d'))
->when($object->setStatus(TestedModel::STATUS_PENDING))
->string($object->getStatus())
->isEqualTo(TestedModel::STATUS_PENDING)
->boolean($object->isPushed())
->isFalse()
->when($fDt = new \DateTime('2013-01-01'))
->and($object->setPushedAt($fDt))
->dateTime($object->getPushedAt())
->isIdenticalTo($fDt);
}
public function testDevicesTokensCheck()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Apns::class, '\Mock'))
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Gcm::class, '\Mock'))
->and($apnsAdapter = new \mock\Apns())
->and($gcmAdapter = new \mock\Gcm())
->and($badDevice = new DeviceModel('BadToken'))
->and($message = new MessageModel('Test'))
->exception(function () use ($apnsAdapter, $badDevice, $message) {
$object = new TestedModel($apnsAdapter, $badDevice, $message);
})
->isInstanceOf(AdapterException::class)
->when($goodDevice = new DeviceModel(self::APNS_TOKEN_EXAMPLE))
->object($object = new TestedModel($apnsAdapter, $goodDevice, $message));
}
public function testAdapter()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Apns::class, '\Mock'))
->and($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Gcm::class, '\Mock'))
->and($apnsAdapter = new \mock\Apns())
->and($gcmAdapter = new \mock\Gcm())
->and($devices = new DeviceModel(self::APNS_TOKEN_EXAMPLE))
->and($message = new MessageModel('Test'))
->and($object = new TestedModel($apnsAdapter, $devices, $message))
->object($object->getAdapter())
->isInstanceOf(Apns::class)
->when($object->setAdapter($gcmAdapter))
->and($object->setDevices(new DeviceCollection([new DeviceModel(self::GCM_TOKEN_EXAMPLE)])))
->object($object->getAdapter())
->isInstanceOf(Gcm::class);
}
public function testMessage()
{
$this->if($this->mockClass(AdapterInterface::class, '\Mock'))
->and($adapter = new \Mock\AdapterInterface())
->and($devices = new DeviceCollection([new DeviceModel('Token1'), new DeviceModel('Token2'),
new DeviceModel('Token3')]))
->and($message = new MessageModel('Test'))
->and($object = new TestedModel($adapter, $devices, $message))
->object($object->getMessage())
->isInstanceOf(MessageModel::class)
->string($object->getMessage()->getText())
->isEqualTo('Test')
->when($object->setMessage(new MessageModel('Test 2')))
->object($object->getMessage())
->isInstanceOf(MessageModel::class)
->string($object->getMessage()->getText())
->isEqualTo('Test 2');
}
}

View File

@@ -1,82 +0,0 @@
<?php
namespace tests\units\Sly\NotificationPusher;
use mageekguy\atoum as Units;
use Sly\NotificationPusher\Adapter\Apns;
use Sly\NotificationPusher\Collection\DeviceCollection;
use Sly\NotificationPusher\Collection\PushCollection;
use Sly\NotificationPusher\Model\Device;
use Sly\NotificationPusher\Model\Message;
use Sly\NotificationPusher\Model\Push;
use Sly\NotificationPusher\Model\Response;
use Sly\NotificationPusher\PushManager as TestedModel;
/**
* @uses atoum\test
* @author Cédric Dugat <cedric@dugat.me>
*/
class PushManager extends Units\Test
{
const APNS_TOKEN_EXAMPLE = '111db24975bb6c6b63214a8d268052aa0a965cc1e32110ab06a72b19074c2222';
public function testConstruct()
{
$this->if($object = new TestedModel())
->string($object->getEnvironment())
->isEqualTo(TestedModel::ENVIRONMENT_DEV)
->when($object = new TestedModel(TestedModel::ENVIRONMENT_PROD))
->string($object->getEnvironment())
->isEqualTo(TestedModel::ENVIRONMENT_PROD);
}
public function testCollection()
{
$this->if($this->mockGenerator()->orphanize('__construct'))
->and($this->mockClass(Push::class, '\Mock'))
->and($push = new \Mock\Push())
->and($push->getMockController()->getMessage = new Message('Test'))
->and($push->getMockController()->getDevices = new DeviceCollection([new Device(self::APNS_TOKEN_EXAMPLE)]))
->and($push2 = new \Mock\Push())
->and($push2->getMockController()->getMessage = new Message('Test 2'))
->and($push2->getMockController()->getDevices = new DeviceCollection([new Device(self::APNS_TOKEN_EXAMPLE)]))
->and($object = (new TestedModel())->getPushCollection())
->when($object->add($push))
->object($object)
->isInstanceOf(PushCollection::class)
->object($object->getIterator())
->hasSize(1)
->when($object->add($push2))
->object($object)
->isInstanceOf(PushCollection::class)
->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(Apns::class, '\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(Push::class, '\Mock'))
->and($push = new \Mock\Push())
->and($push->getMockController()->getMessage = new Message('Test'))
->and($push->getMockController()->getDevices = new DeviceCollection([new Device(self::APNS_TOKEN_EXAMPLE)]))
->and($push->getMockController()->getAdapter = $apnsAdapter)
->and($object = new TestedModel())
->and($object->add($push))
->object($object->push())
->isInstanceOf(PushCollection::class)
->hasSize(1)
->object($object->getResponse())
->isInstanceOf(Response::class);
}
}