163 lines
5.7 KiB
PHP
163 lines
5.7 KiB
PHP
<?php
|
|
App::uses('Component', 'Controller');
|
|
App::uses('CakeEmail', 'Network/Email');
|
|
require_once(APP . 'Controller' . DS . 'Traits' . DS . 'ApiCallTrait.php');
|
|
use Google\Auth\Credentials\ServiceAccountCredentials;
|
|
class NotificationComponent extends Component
|
|
{
|
|
use ApiCallTrait;
|
|
/**
|
|
* @var AppModel|bool|mixed|Model|object|string|null
|
|
*/
|
|
private $PushToken;
|
|
public function initialize(Controller $controller)
|
|
{
|
|
$this->PushToken = ClassRegistry::init('PushToken');
|
|
}
|
|
public function sendEmail($data) {
|
|
$default = array(
|
|
'host' => Configure::read('expensecount.email.smtp.host'),
|
|
'port' => 587,
|
|
'auth' => 'plain',
|
|
'username' => Configure::read('expensecount.email.smtp.username'),
|
|
'password' => Configure::read('expensecount.email.smtp.password'),
|
|
'tsl' => false,
|
|
'transport' => 'Smtp',
|
|
'from' => array(Configure::read('expensecount.email.smtp.from') => 'ExpenseCount'),
|
|
'returnPath' => Configure::read('expensecount.email.smtp.from'),
|
|
'layout' => false,
|
|
'emailFormat' => 'html',
|
|
'charset' => 'utf-8',
|
|
'headerCharset' => 'utf-8',
|
|
);
|
|
|
|
try {
|
|
$Email = new CakeEmail($default);
|
|
$Email->to($data["email_to"]);
|
|
$Email->emailFormat('html');
|
|
$Email->template($data["template"], null)->viewVars(array('data' => $data));
|
|
$Email->subject($data["subject"]);
|
|
$Email->replyTo($data["email_from"]);
|
|
$Email->from(array(Configure::read('expensecount.email.smtp.from') => "ExpenseCount.com"));
|
|
$Email->delivery = 'Smtp';
|
|
return $Email->send();
|
|
}catch (Exception $e) {
|
|
CakeLog::write(LOG_ERR, 'Email sending failed: ' . $e->getMessage());
|
|
return $e->getMessage();
|
|
}
|
|
}
|
|
|
|
|
|
private function getAccessToken()
|
|
{
|
|
$cacheFile = TMP . 'fcm_token.cache';
|
|
|
|
if (file_exists($cacheFile)) {
|
|
$cached = json_decode(file_get_contents($cacheFile), true);
|
|
if (!empty($cached['token']) && $cached['expires_at'] > time()) {
|
|
return $cached['token'];
|
|
}
|
|
}
|
|
|
|
$scopes = ['https://www.googleapis.com/auth/firebase.messaging'];
|
|
|
|
$credentials = new ServiceAccountCredentials(
|
|
$scopes,
|
|
json_decode(file_get_contents(FIREBASE_SECRET), true)
|
|
);
|
|
|
|
$token = $credentials->fetchAuthToken();
|
|
|
|
if (!isset($token['access_token'])) {
|
|
throw new \Exception('Unable to get access token');
|
|
}
|
|
|
|
// Google tokens expire in 3600s; cache for 55 minutes to stay safely within that.
|
|
file_put_contents($cacheFile, json_encode([
|
|
'token' => $token['access_token'],
|
|
'expires_at' => time() + 3300,
|
|
]));
|
|
|
|
return $token['access_token'];
|
|
}
|
|
|
|
public function sendPushNotification($tokens, $message, $async = false)
|
|
{
|
|
$projectId = FIREBASE_PROJECT_ID;
|
|
if (empty($projectId)) {
|
|
CakeLog::write(LOG_ERR, 'Push notification: Firebase project_id not configured');
|
|
return ['error' => 'Firebase project_id not configured'];
|
|
}
|
|
$url = "https://fcm.googleapis.com/v1/projects/{$projectId}/messages:send";
|
|
|
|
try {
|
|
$accessToken = $this->getAccessToken();
|
|
} catch (\Exception $e) {
|
|
CakeLog::write(LOG_ERR, 'Push notification: Failed to get access token: ' . $e->getMessage());
|
|
return ['error' => 'Failed to get access token: ' . $e->getMessage()];
|
|
}
|
|
|
|
$responses = [];
|
|
|
|
foreach ($tokens as $key => $token) {
|
|
$payload = [
|
|
"message" => [
|
|
"token" => $token['token'],
|
|
"data" => $message,
|
|
"apns" => [
|
|
"payload" => [
|
|
"aps" => [
|
|
"alert" => [
|
|
"title" => $message['title'],
|
|
"body" => $message['body']
|
|
],
|
|
"sound" => "default",
|
|
"badge" => 1,
|
|
"mutable-content" => 1,
|
|
"content-available" => 1
|
|
]
|
|
]
|
|
]
|
|
]
|
|
];
|
|
$apiResponse = $this->fireAndForget($url, $payload, $accessToken);
|
|
$responses[] = ['request' => [$token['user_id'], $token['device_id']], 'response' => $apiResponse];
|
|
}
|
|
|
|
return $responses;
|
|
}
|
|
|
|
public function send($users,$message){
|
|
|
|
$tokens = array();
|
|
if(!empty($users)){
|
|
$filter = array('status' => 1,'user_id' => $users);
|
|
$db_token = $this->PushToken->getToken($filter);
|
|
|
|
if(!empty($db_token)) {
|
|
foreach ($db_token as $token) {
|
|
$tokens[] = ['user_id'=>$token['PushToken']['user_id'],
|
|
'device_id'=>$token['PushToken']['device_id'],
|
|
'token'=> $token['PushToken']['push_token']];
|
|
}
|
|
}
|
|
if(!empty($tokens)) {
|
|
|
|
$response = $this->sendPushNotification($tokens, $message, true);
|
|
|
|
}else{
|
|
$response["status"] = "-99";
|
|
$response["status_desc"] = "Push Token Not Found!";
|
|
$response["input"] = $users;
|
|
}
|
|
|
|
}else{
|
|
$response["status"] = "-99";
|
|
$response["status_desc"] = "User Not Found!";
|
|
$response["input"] = $users;
|
|
}
|
|
return $response;
|
|
}
|
|
|
|
}
|