Skip to content

Commit

Permalink
First version with a lot of bugs
Browse files Browse the repository at this point in the history
  • Loading branch information
Christian committed Jun 13, 2016
1 parent 7fa2d38 commit d906c9b
Show file tree
Hide file tree
Showing 18 changed files with 1,243 additions and 0 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
composer.lock
vendor/
31 changes: 31 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
{
"name": "khrizt/push-notiphications",
"description": "Push notifications library for Apns and Gcm for PHP",
"keywords": ["apple", "iphone", "apns", "android", "gcm", "notification", "message", "push", "pusher", "notiphications"],
"homepage": "https://github.com/khrizt/PushNotiphications",
"type": "standalone",
"license": "Apache License 2.0",
"authors": [
{
"name": "Christian Fuentes",
"email": "[email protected]"
},
{
"name": "Contributors",
"homepage": "https://github.com/khrizt/PushNotiphications/contributors"
}
],
"require": {
"php": ">=5.5",
"symfony/console": "~2.3"
},
"config": {
"bin-dir": "bin"
},
"bin": ["send"],
"autoload": {
"psr-0": {
"Khrizt": "src/"
}
}
}
13 changes: 13 additions & 0 deletions send
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#!/usr/bin/env php
<?php

if (file_exists($a = __DIR__.'/../../autoload.php')) {
require_once $a;
} else {
require_once __DIR__.'/vendor/autoload.php';
}

use Khrizt\PushNotiphications\Console\Application;

$application = new Application();
$application->run();
8 changes: 8 additions & 0 deletions src/Khrizt/PushNotiphications/Client/AbstractClient.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?php

namespace Khrizt\PushNotiphications\Client;

abstract class AbstractClient
{
abstract public function send();
}
74 changes: 74 additions & 0 deletions src/Khrizt/PushNotiphications/Client/Apns.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
<?php

namespace Khrizt\PushNotiphications\Client;

use Khrizt\PushNotiphications\Model\Apns\Message;
use Khrizt\PushNotiphications\Model\Apns\Response;
use Khrizt\PushNotiphications\Collection\Collection;
use Khrizt\PushNotiphications\Exceptions\NoHttp2SupportException;
use Khrizt\PushNotiphications\Constants;

class Apns
{
protected $apnsUrl;

protected $handler;

protected $certificate;

protected $passPhrase;

public function __construct($environment, $certificate, $passPhrase = null)
{
if ($environment == Constants::PRODUCTION) {
$this->apnsUrl = 'https://api.push.apple.com';
} else {
$this->apnsUrl = 'https://api.development.push.apple.com';
}
$this->apnsUrl .= '/3/device/';
$this->certificate = $certificate;
$this->passPhrase = $passPhrase;
}

public function send(Message $message, Collection $deviceCollection) : Collection
{
if (!defined('CURL_HTTP_VERSION_2_0')) {
throw new NoHttp2SupportException();
}

// open connection handler if there's none
if (is_null($this->handler)) {
$this->handler = curl_init();
}

curl_setopt($this->handler, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
curl_setopt($this->handler, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->handler, CURLOPT_POST, 1);
curl_setopt($this->handler, CURLOPT_HEADER, true);
curl_setopt($this->handler, CURLOPT_POSTFIELDS, $message->getPayload());
curl_setopt($this->handler, CURLOPT_HTTPHEADER, $message->getHeaders());
curl_setopt($this->handler, CURLOPT_SSLCERT, $this->certificate);
if (!is_null($this->passPhrase)) {
curl_setopt($this->handler, CURLOPT_SSLCERTPASSWD, $this->passPhrase);
}
curl_setopt($this->handler, CURLOPT_VERBOSE, true);

$responseCollection = new Collection();
foreach ($deviceCollection as $device) {
curl_setopt($this->handler, CURLOPT_URL, $this->apnsUrl.$device->getToken());

$rawResponse = curl_exec($this->handler);
var_dump('rawResponse', $rawResponse);

$status = curl_getinfo($this->handler, CURLINFO_HTTP_CODE);

$headerSize = curl_getinfo($this->handler, CURLINFO_HEADER_SIZE);
$responseHeaders = substr($rawResponse, 0, $headerSize);
$responseBody = substr($rawResponse, $headerSize);

$responseCollection->append(Response::parse($status, $responseHeaders, $responseBody));
}

return $responseCollection;
}
}
Empty file.
20 changes: 20 additions & 0 deletions src/Khrizt/PushNotiphications/Collection/Collection.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?php

namespace Khrizt\PushNotiphications\Collection;

use ArrayIterator;

class Collection extends ArrayIterator
{
public function append($item)
{
parent::append($item);
}

public function clear()
{
for ($this->rewind(); $this->valid(); $this->next()) {
$this->offsetUnset($this->key());
}
}
}
24 changes: 24 additions & 0 deletions src/Khrizt/PushNotiphications/Console/Application.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

namespace Khrizt\PushNotiphications\Console;

use Symfony\Component\Console\Application as BaseApplication;
use Khrizt\PushNotiphications\Console\Commands\PushCommand;

/**
* Application.
*
* @uses \Symfony\Component\Console\Application
*/
class Application extends BaseApplication
{
/**
* Constructor.
*/
public function __construct()
{
parent::__construct('PushNotiphications');

$this->add(new PushCommand());
}
}
124 changes: 124 additions & 0 deletions src/Khrizt/PushNotiphications/Console/Commands/PushCommand.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
<?php

namespace Khrizt\PushNotiphications\Console\Commands;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Input\InputOption;
use Symfony\Component\Console\Output\OutputInterface;
use Khrizt\PushNotiphications\Client\Apns;
use Khrizt\PushNotiphications\Collection\Collection;
use Khrizt\PushNotiphications\Constants;
use Khrizt\PushNotiphications\Model\Device;
use Khrizt\PushNotiphications\Model\Apns\Message as ApnsMessage;

/**
* PushCommand.
*/
class PushCommand extends Command
{
/**
* @see Command
*/
protected function configure()
{
parent::configure();

$this
->setName('push')
->setDescription('Manual push notification')
->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(
'certificatePassphrase',
null,
InputOption::VALUE_OPTIONAL,
'Certificate passphrase (for APNS adapter)'
)
->addOption(
'topic',
null,
InputOption::VALUE_OPTIONAL,
'Topic (for APNS adapter)',
null
)
->addOption(
'apiKey',
null,
InputOption::VALUE_OPTIONAL,
'API key (for GCM adapter)'
)
->addOption(
'env',
null,
InputOption::VALUE_REQUIRED,
sprintf(
'Environment (%s, %s)',
Constants::DEVELOPMENT,
Constants::PRODUCTION
),
Constants::DEVELOPMENT
);
}

/**
* {@inheritdoc}
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$adapter = $input->getArgument('adapter');
$token = $input->getArgument('token');
$message = $input->getArgument('message');
$env = $input->getOption('env');

if ($adapter === 'apns') {
$certificate = $input->getOption('certificate');
if (!file_exists($certificate)) {
throw new \InvalidArgumentException('Certificate does not exists');
}
$certificatePassphrase = $input->getOption('certificatePassphrase');
$topic = $input->getOption('topic');
$this->sendApnsNotification($token, $message, $certificate, $env, $certificatePassphrase, $topic);
} elseif ($adapter === 'gcm') {
//
} else {
throw new \InvalidArgumentException('Adapter '.$adapter.' is not a valid value. Values are: apns and gcm');
}
}

protected function sendApnsNotification(string $token, string $message, string $certificate, string $env, string $certificatePassphrase = null, string $topic = null)
{
$apnsMessage = new ApnsMessage();
$apnsMessage->setBody($message);
if (!is_null($topic)) {
$apnsMessage->setTopic($topic);
}

$device = new Device($token);
$collection = new Collection();
$collection->append($device);

$client = new Apns($env, $certificate, $certificatePassphrase);
print_r($client->send($apnsMessage, $collection));
}
}
9 changes: 9 additions & 0 deletions src/Khrizt/PushNotiphications/Constants.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

namespace Khrizt\PushNotiphications;

class Constants
{
const PRODUCTION = 'prod';
const DEVELOPMENT = 'dev';
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<?php

namespace Khrizt\PushNotiphications\Exceptions;

use Exception;

class NoHttp2SupportException extends Exception
{
public function __construct()
{
parent::__construct('Your curl library must have HTTP2 support. Take a look at this page to achieve that: https://serversforhackers.com/video/curl-with-http2-support');
}
}
Loading

0 comments on commit d906c9b

Please sign in to comment.