Skip to content

Instantly share code, notes, and snippets.

@Pamblam
Forked from trbsi/PushNotifications.php
Last active September 12, 2017 19:10
Show Gist options
  • Save Pamblam/cf683e677ae5c15915bc17b5d6e7abf0 to your computer and use it in GitHub Desktop.
Save Pamblam/cf683e677ae5c15915bc17b5d6e7abf0 to your computer and use it in GitHub Desktop.
Simple PHP class to send Android & iOS Push Notifications
<?php
/**
* Class to send a Push notification via Google or Apple in a single statment
*/
class Push{
/**
* Either the API Key from Google or the certificate passphrase from Apple
* @var string
*/
private $API_KEY_OR_PASSPHRASE;
/**
* The platform we're sending to (android|ios)
* @var string
*/
private $platform = "android";
/**
* The title of the message we're sending
* @var string
*/
private $title = "";
/**
* The content of the message
* @var string
*/
private $message = "";
/**
* The registration IDs to send the notification to
* @var array
*/
private $reg_ids = array();
/**
* The raw result from the API call
* @var string
*/
private $result;
/**
* The PEM file for the certificate generated by Apple (for Apple only)
* @var string
*/
private $pemFile;
/**
* Use sandbox? (Apple only)
* @var boolean
*/
private $sandbox = false;
/**
* Any additional data that should be passed into the notification
* @var Array
*/
private $data = array();
/**
* Private constructor - used internally only
* @param string $API_KEY_OR_PASSPHRASE
*/
private function __construct($API_KEY_OR_PASSPHRASE){
$this->API_KEY_OR_PASSPHRASE = $API_KEY_OR_PASSPHRASE;
}
/**
* Convenience constructor allows for chaining
* @param string $key - Either the Google API key of the Passphrase for
* the certiifcate from Apple
* @return \Push
*/
public static function build($key){
return new Push($key);
}
/**
* Set the title of the message
* @param string $title
* @return $this
*/
public function title($title){
$this->title = $title;
return $this;
}
/**
* Add arbitrary data to the notification
* @param type $data
* @return $this
* @throws Exception
*/
public function addData($data){
if(!is_array($data)) throw new Exception("Invalid data - must be an array.");
$this->data = $data;
return $this;
}
/**
* Set the content of the message
* @param string $message
* @return $this
*/
public function message($message){
$this->message = $message;
return $this;
}
/**
* Set the registration ID's to send the notification to
* @param type $reg_ids
* @return $this
*/
public function to($reg_ids){
if(is_array($reg_ids)){
foreach($reg_ids as $id){
if(!in_array($id, $this->reg_ids)) $this->reg_ids[] = $id;
}
}else if(!in_array($reg_ids, $this->reg_ids)) $this->reg_ids[] = $reg_ids;
return $this;
}
/**
* Send the message
* @return $this
*/
public function send(){
return $this->platform === "android" ?
$this->sendAndroid() : $this->sendiOS() ;
return $this;
}
/**
* Sets the certificate file for Apple
* @param string $pathToPEM
* @return $this
*/
public function setPEM($pathToPEM, $sandbox=false){
$this->pemFile = $pathToPEM;
$this->sandbox = $sandbox;
$this->platform = "iOS";
return $this;
}
/**
* Get the result response from the API that sends the notification
* @return string
*/
public function getResult(){
return $this->result;
}
/**
* Send the notification via the Google server
* @return $this
*/
private function sendAndroid(){
$url = 'https://android.googleapis.com/gcm/send';
$headers = array(
'Authorization: key=' . $this->API_KEY_OR_PASSPHRASE,
'Content-Type: application/json'
);
$fields = array(
'registration_ids'=>$this->reg_ids,
'data'=>array(
'title'=>$this->title,
'message'=>$this->message,
'subtitle'=>'',
'tickerText'=>'',
'msgcnt'=>1,
'vibrate'=>1,
'content-available'=>1
)
);
foreach($this->data as $k=>$v) $fields['data'][$k] = $v;
$this->result = self::useCurl($url, $headers, json_encode($fields));
return $this;
}
/**
* Send the notification to the APN server
* @return $this
*/
private function sendiOS(){
$applePushGateway = $this->sandbox ?
"ssl://gateway.sandbox.push.apple.com:2195" :
"ssl://gateway.push.apple.com:2195" ;
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $this->pemFile);
stream_context_set_option($ctx, 'ssl', 'passphrase', $this->API_KEY_OR_PASSPHRASE);
$fp = stream_socket_client($applePushGateway, $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
if(!$fp){
$this->result = "Failed to open stream: $err $errstr";
return $this;
}
$body = array(
"aps" => array(
'alert' => array(
'title' => $this->title,
'body' => $this->message,
'contentAvailable' => 1
)
)
);
foreach($this->data as $k=>$v) $body['aps']['alert'][$k] = $v;
$payload = json_encode($body);
$successCnt = 0;
foreach($this->reg_ids as $deviceToken){
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
if(fwrite($fp, $msg, strlen($msg))) $successCnt++;;
}
fclose($fp);
$this->result = "$successCnt of ".count($this->reg_ids)." messages sent.";
return $this;
}
/**
* Helper function to send a cURL request
* @param string $url
* @param array $headers
* @param string $fields
* @return string
*/
private static function useCurl($url, $headers, $fields = null){
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if($fields) curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$result = curl_exec($ch);
if($result === FALSE) throw new Exception("cURL failed..");
curl_close($ch);
return $result;
}
}
<?php
require_once('PushNotifications.php');
$platform = ""; // "android" or "ios"
$GoogleKey = ""; // Google API key from the Firebase console
$regID = ""; // A registration ID from the device (can also be an Array)
$ApplePassphrase = ""; // Passphrase for your Apple certificate file
$ApplePEM = ""; // Path to the .pem certificate file generated from Apple
if($platform === "android"){
$push = Push::build($GoogleKey)
->title('Thanks for signing up')
->message('Your device is now registerd on the network.')
->to($regID)
->send();
}else{
$push = Push::build($ApplePassphrase)
->setPEM($ApplePEM)
->title('Thanks for signing up')
->message('Your device is now registerd on the network.')
->to($regID)
->send();
}
echo $push->getResult();
?>
@GuibaGold
Copy link

awesome;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment