Files
Ontime/backendpanel/application/models/Notification_model.php
2026-04-01 11:55:47 +07:00

197 lines
6.8 KiB
PHP
Executable File

<?php
class notification_model extends CI_model
{
public function notif_cancel_user($id_driver, $id_transaksi, $token_user)
{
if ($this->is_token_empty($token_user) || !$this->is_valid_fcm_token($token_user)) {
log_message('debug', 'notif_cancel_user: skip, no/invalid Firebase token for user');
return true;
}
// Use FCM HTTP v1 via service account, not legacy keyfcm.
$payload = array(
'id_driver' => $id_driver,
'id_transaksi' => $id_transaksi,
'response' => '5',
'type' => 1,
);
$this->send_generic_to_token($token_user, $payload, array());
return true;
}
public function notif_cancel_driver($id_transaksi, $token_driver)
{
if ($this->is_token_empty($token_driver) || !$this->is_valid_fcm_token($token_driver)) {
log_message('debug', 'notif_cancel_driver: skip, no/invalid Firebase token for driver');
return true;
}
$payload = array(
'id_transaksi' => $id_transaksi,
'response' => '0',
'type' => 1,
);
$this->send_generic_to_token($token_driver, $payload, array());
return true;
}
/**
* Check if token/target is empty (null, empty string, or whitespace).
* Use before sending FCM to avoid sending when device has no token.
*/
private function is_token_empty($token)
{
return $token === null || trim((string) $token) === '';
}
/**
* Check if string looks like a valid FCM v1 device token (not a placeholder).
* Uses shared fcm_v1_is_valid_device_token helper.
*/
private function is_valid_fcm_token($token)
{
if (!function_exists('fcm_v1_is_valid_device_token')) {
get_instance()->load->helper('fcm_v1_helper');
}
return fcm_v1_is_valid_device_token($token);
}
/**
* Send notification via FCM HTTP v1 to a device token (reg_id, token, token_merchant).
* Uses token API so reg_id can be used as FCM v1 target. Skips invalid/placeholder tokens.
* @param string $target FCM device token (from driver.reg_id, pelanggan.token, etc.)
* @return bool True on success or skip, false on failure
*/
public function send_notif($title, $message, $target)
{
if ($this->is_token_empty($target)) {
log_message('debug', 'send_notif: skip, empty target');
return true;
}
if (!function_exists('fcm_v1_validate_token')) {
get_instance()->load->helper('fcm_v1_helper');
}
if (!fcm_v1_validate_token()) {
log_message('error', 'send_notif: Firebase token not ready, skip send');
return false;
}
$data = array(
'title' => $title,
'message' => $message,
'type' => 4,
);
$options = array(
'title' => $title,
'body' => $message,
);
if ($this->is_valid_fcm_token($target)) {
return $this->send_generic_to_token($target, $data, $options);
}
// Values like pelanggan, driver, mitra, ouride are FCM topic names (broadcast).
return $this->send_generic_to_topic(trim((string) $target), $data, $options);
}
public function send_notif_topup($title, $id, $message, $method, $token)
{
if ($this->is_token_empty($token)) {
log_message('debug', 'send_notif_topup: skip, no Firebase token for user id=' . $id);
return;
}
if (!function_exists('fcm_v1_validate_token')) {
get_instance()->load->helper('fcm_v1_helper');
}
if (!fcm_v1_validate_token()) {
log_message('error', 'send_notif_topup: Firebase token not ready, skip send for user id=' . $id);
return;
}
// Direct token notification for topup via HTTP v1.
$data = array(
'title' => $title,
'id' => $id,
'message'=> $message,
'method' => $method,
'type' => 3,
);
$options = array(
'title' => $title,
'body' => $message,
);
$this->send_generic_to_token($token, $data, $options);
}
/**
* Send FCM via HTTP v1 API to a single device token.
* Used by User and Driver apps (notification/send_generic).
* $data must be flat key-value; values are stringified for FCM.
*
* @param string $target FCM device token
* @param array $data Data payload (keys preserved; values cast to string)
* @param array $options Optional 'title', 'body' for notification
* @return bool True on success, false on failure
*/
public function send_generic_to_token($target, $data, $options = array())
{
if ($this->is_token_empty($target)) {
log_message('debug', 'FCM v1 send_generic_to_token: skip, target token empty');
return false;
}
if (!$this->is_valid_fcm_token($target)) {
log_message('debug', 'FCM v1 send_generic_to_token: skip, invalid/placeholder token');
return false;
}
if (!function_exists('fcm_v1_send')) {
get_instance()->load->helper('fcm_v1_helper');
}
if (!fcm_v1_validate_token()) {
log_message('error', 'FCM v1 send_generic_to_token: Firebase token not ready, skip send');
return false;
}
$flat = array();
foreach ($data as $k => $v) {
if (is_array($v) || is_object($v)) {
$flat[$k] = json_encode($v);
} else {
$flat[$k] = (string) $v;
}
}
log_message('debug', 'FCM v1 send_generic_to_token target=' . substr((string)$target, 0, 20) . '... payload=' . json_encode($flat));
$result = fcm_v1_send($target, $flat, false, $options);
if ($result === false) {
log_message('error', 'FCM v1 send_generic_to_token failed for target=' . substr((string)$target, 0, 20) . '...');
}
return $result !== false;
}
/**
* Send FCM via HTTP v1 API to a topic.
*
* @param string $target Topic name (without /topics/ prefix)
* @param array $data Data payload
* @param array $options Optional 'title', 'body'
* @return bool True on success, false on failure
*/
public function send_generic_to_topic($target, $data, $options = array())
{
if (!function_exists('fcm_v1_send')) {
get_instance()->load->helper('fcm_v1_helper');
}
if (!fcm_v1_validate_token()) {
log_message('error', 'FCM v1 send_generic_to_topic: Firebase token not ready, skip send');
return false;
}
$flat = array();
foreach ($data as $k => $v) {
if (is_array($v) || is_object($v)) {
$flat[$k] = json_encode($v);
} else {
$flat[$k] = (string) $v;
}
}
log_message('debug', 'FCM v1 send_generic_to_topic topic=' . (string)$target . ' payload=' . json_encode($flat));
$result = fcm_v1_send($target, $flat, true, $options);
if ($result === false) {
log_message('error', 'FCM v1 send_generic_to_topic failed for topic=' . (string)$target);
}
return $result !== false;
}
}