Sh3ll
OdayForums


Server : Apache
System : Linux 145.162.205.92.host.secureserver.net 5.14.0-611.45.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Wed Apr 1 05:56:53 EDT 2026 x86_64
User : tradze ( 1001)
PHP Version : 8.1.34
Disable Function : NONE
Directory :  /home/tradze/www/app/Modules/Notifications/Repositories/

Upload File :
current_dir [ Writeable ] document_root [ Writeable ]

 

Current File : /home/tradze/www/app/Modules/Notifications/Repositories/NotifRepository.php
<?php

namespace App\Modules\Notifications\Repositories;

use App\Modules\Users\Models\UserDevice;
use App\Modules\Notifications\Models\Notification;
use Exception;
use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use Sly\NotificationPusher\PushManager,
    Sly\NotificationPusher\Adapter\Apns as ApnsAdapter,
    Sly\NotificationPusher\Adapter\Gcm as GcmAdapter,
    Sly\NotificationPusher\Collection\DeviceCollection,
    Sly\NotificationPusher\Model\Device,
    Sly\NotificationPusher\Model\Message,
    Sly\NotificationPusher\Model\Push;
use Illuminate\Support\Facades\Mail;

class NotifRepository
{

    /**
     * Register new notification
     * @param array $data
     */
    public function add($user_id, $message, $type = '', $title = '', $extraData = [])
    {
        //get all user devices
        $devices = UserDevice::where('user_id', $user_id)
            ->whereNotNull('push_token')
            ->where('push_token', '<>', 'null')
            ->get();
        //stop the script if no devices is attached to the user account
        if (!$devices->count())
            return;
        //foreach user device, add the notification
        foreach ($devices as $device) {
            //if the registered device push_token is null, continue
            if (!isset($device->push_token))
                continue;
            $is_sent = 0;
            //create push notification data array
            if ($device->os === "iOS") {
                $result = $this->sendAndriod($device->push_token, $message, $type, $title, $extraData);
                if ($result) {
                    $is_sent = 1;
                }
            } else {
                $result = $this->sendAndriod($device->push_token, $message, $type, $title, $extraData);
                if ($result) {
                    $is_sent = 1;
                }
            }

            $data = [
                'user_id' => $user_id,
                'token' => $device->push_token,
                'message' => $message,
                'os' => $device->os,
                'os_version' => $device->os_version,
                'phone_model' => $device->model,
                'is_sent' => $is_sent,
                'data' => json_encode($extraData),
                'type' => $type,
            ];

            //store notification to the DB
            $new = Notification::create($data);
        } //endforeach
    }

    //end method add

    /**
     * Send notifications
     */
    public function send()
    {
        //get all unsent notifications
        $notifications = Notification::where('is_sent', 0)
            ->orderBy('id', 'asc')
            ->get();
        // dd($notifications);
        //if no notification has to be sent, stop the script
        if (!$notifications->count())
            return;

        $result = $this->SendIOS('da07753c31e666b1482cb2237455cf06ef07d3da05f90225a2f02a7ec1834623', 'Test msg', 'message', 'Zenlondon');
        if ($result) {
            $device->is_sent = 1;
            $device->save();
        }
        //send the notification
        foreach ($notifications as $device) {

            //if user device OS is iOS, use the APN adapter
            // if (true) { //$device->os === "iOS"
            //     $result = $this->SendIOS($device->token, $device->message);
            //     if ($result) {
            //         $device->is_sent = 1;
            //         $device->save();
            //     }
            // }
            // else {
            //     $result = $this->sendAndriod('ccL-N97MJFU:APA91bGI_kEx4vuAWST8TjbVnODCA6ZYdj64w_9WjtOOLUvNlHecIRZ_UdH86JuZvAslpHKJ2Hq3uJoD8wvhRLq6MjBWN0vjzbqihr7fyT-ZJFnsXbICviOpANg2WqOoHcf726IEodVp', $device->message, 'bookingCancel');
            //     if ($result) {
            //         $device->is_sent = 1;
            //         $device->save();
            //     }
            // }
        }
    }

    /*
     * Send IOS Push NOtification
     */

    private function SendIOS($token, $message, $type = '', $title = '', $extraData = [])
    {
        // $deviceToken = $token;
        $deviceToken = $token;
        //         $passphrase = 'download';
        //         $url = 'abc';

        //         if (!$message || !$url)
        //             exit('Example Usage: $php newspush.php \'Breaking News!\' \'https://raywenderlich.com\'' . "\n");

        // ////////////////////////////////////////////////////////////////////////////////

        //         $ctx = stream_context_create();
        //         stream_context_set_option($ctx, 'ssl', 'local_cert', '/home/appzenlondon/public_html/public/pushcert_zenlondon.pem');
        //         stream_context_set_option($ctx, 'ssl', '', $passphrase);

        // // Open a connection to the APNS server
        //         $fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);

        //         if (!$fp)
        //             exit("Failed to connect: $err $errstr" . PHP_EOL);



        //         $body['aps'] = array(
        //             'alert' => array('body' => $message, 'title' => $title),
        //             'sound' => 'default',
        //         );
        //         $body['type'] = $type;
        //         $payload = json_encode($body);
        //         //$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
        //         $msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', sprintf('%u', CRC32($deviceToken)))) . pack('n', strlen($payload)) . $payload;

        //         $result = fwrite($fp, $msg, strlen($msg));

        //         fclose($fp);
        //         if (!$result)
        //             return false;
        //         else
        //             return true;

        $keyfile = public_path('AuthKey_4YGC8MX7B4.p8');               # <- Your AuthKey file
        $keyid = '4YGC8MX7B4';                            # <- Your Key ID
        $teamid = 'M79U55JY3R';                           # <- Your Team ID (see Developer Portal)
        $bundleid = 'ro.concept24.ZenLondonMassage';                # <- Your Bundle ID
        $url = 'https://api.push.apple.com';  # <- development url, or use http://api.push.apple.com for production environment
        //$token = 'da07753c31e666b1482cb2237455cf06ef07d3da05f90225a2f02a7ec1834623';              # <- Device Token

        $body['aps'] = array(
            'alert' => array('body' => $message, 'title' => $title)
            // 'sound' => 'customSound.wav',
        );
        $body['type'] = $type;
        $payload = json_encode($body);
        $message = $payload;

        $key = openssl_pkey_get_private('file://' . $keyfile);

        $header = ['alg' => 'ES256', 'kid' => $keyid];
        $claims = ['iss' => $teamid, 'iat' => time()];

        $header_encoded = $this->base64($header);
        $claims_encoded = $this->base64($claims);

        $signature = '';
        openssl_sign($header_encoded . '.' . $claims_encoded, $signature, $key, 'sha256');
        $jwt = $header_encoded . '.' . $claims_encoded . '.' . base64_encode($signature);

        // only needed for PHP prior to 5.5.24
        if (!defined('CURL_HTTP_VERSION_2_0')) {
            define('CURL_HTTP_VERSION_2_0', 3);
        }

        $http2ch = curl_init();
        curl_setopt_array($http2ch, array(
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
            CURLOPT_URL => "$url/3/device/$token",
            CURLOPT_PORT => 443,
            CURLOPT_HTTPHEADER => array(
                "apns-topic: {$bundleid}",
                "authorization: bearer $jwt"
            ),
            CURLOPT_POST => TRUE,
            CURLOPT_POSTFIELDS => $message,
            CURLOPT_RETURNTRANSFER => TRUE,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HEADER => 1
        ));

        $result = curl_exec($http2ch);
        if ($result === FALSE) {
            throw new Exception("Curl failed: " . curl_error($http2ch));
        }

        $status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
        // die($status);
        if ($status == 200) {
            return 1;
        } else {
            return 0;
        }
    }


    function flattenExtraData(array $extraData): array
    {
        $flat = [];
        foreach ($extraData as $key => $value) {
            if (is_array($value)) {
                // Flatten inner array
                foreach ($value as $subKey => $subValue) {
                    // Add a prefix if you want, e.g., "booking_" to avoid key collision
                    $flat[$subKey] = is_array($subValue) ? json_encode($subValue) : (string)$subValue;
                }
            } elseif ($value instanceof \Carbon\Carbon) {
                $flat[$key] = $value->toDateTimeString();
            } else {
                $flat[$key] = (string)$value;
            }
        }
        return $flat;
    }
    /*
      Send Notification To Andriod Device
     */

    // private function sendAndriod($token, $message, $type = '', $title = '',$extraData = []) {

    //     $extraData = $this->flattenExtraData($extraData);

    //     // $url = 'https://fcm.googleapis.com/fcm/send';
    //     // $fields = array(
    //     //     'to' => $id,
    //     //     'notification' => array("title" => $title, "body" => $data),
    //     //     'data' => array('type' => $type)
    //     // );
    //     // $fields = json_encode($fields);

    //     // $headers = array(
    //     //     'Authorization: key=AAAAmaLisgY:APA91bG7U9trDAgO-Yc6e0j1_JHnL_wOifyQQK188Nipm5W1lqKaeDME8FdTyyHmHhgCwV3vpPnkJaQDvJ5dSKlpd4hsvxnzN1DUXIAk2jAJx4QlVTNnMoP0pe9UT2juhN-DGdS7vzFs',
    //     //     'Content-Type: application/json'
    //     // );

    //     // $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);
    //     // curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
    //     // $result = curl_exec($ch);
    //     // $result = json_decode($result, true);
    //     // curl_close($ch);
    //     // if (isset($result['success']) && 1 === $result['success']) {
    //     //     return true;
    //     // }
    //     // return false;

    //     // Set Firebase HTTP v1 API URL
    //     $url = 'https://fcm.googleapis.com/v1/projects/trade-10f11/messages:send';

    //     // Path to your service account key file
    //     $serviceAccountKeyPath = public_path('tradez-firebase.json');

    //     $accessToken = $this->getAccessToken($serviceAccountKeyPath);


    //     // Prepare the payload
    //     // $fields = [
    //     //     'message' => [
    //     //         'token' => $token,
    //     //         'notification' => [
    //     //             'title' => $title,
    //     //             'body' => $message,
    //     //         ],
    //     //         'data' => [
    //     //             'type' => $type,
    //     //         ]
    //     //     ],
    //     // ];

    //     // dd($extraData);

    //     $fields = [
    //         'message' => [
    //             'token' => $token,
    //             'notification' => [
    //                 'title' => $title,
    //                 'body' => $message
    //                 // 'sound' => 'customsound'
    //             ],
    //             'data' => array_merge(['type' => $type], $extraData),
    //         ],
    //     ];

    //     $fields = json_encode($fields);

    //     // Set headers
    //     $headers = [
    //         "Authorization: Bearer $accessToken",
    //         'Content-Type: application/json',
    //     ];

    //     // Initialize cURL
    //     $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_POSTFIELDS, $fields);

    //     // Execute the request
    //     $result = curl_exec($ch);

    //     if (curl_errno($ch)) {
    //         echo 'Error:' . curl_error($ch);
    //     }

    //     curl_close($ch);

    //     // Decode and return the result
    //     $result = json_decode($result, true);
    //     return $result;
    // }

    private function sendAndriod($token, $message, $type = '', $title = '', $extraData = [])
    {
        $url = 'https://fcm.googleapis.com/v1/projects/trade-10f11/messages:send';

        $serviceAccountKeyPath = public_path('tradez-firebase.json');
        $accessToken = $this->getAccessToken($serviceAccountKeyPath);

        $fields = [
            'message' => [
                'token' => $token,

                'notification' => [
                    'title' => $title,
                    'body' => $message,
                ],

                // Android config
                'android' => [
                    'notification' => [
                        'sound' => 'customsound', // Ensure this matches the sound file in your app
                        'channel_id' => 'custom-sound-channel',
                    ],
                    'priority' => 'high'
                ],

                // iOS config via FCM
                'apns' => [
                    'headers' => [
                        'apns-priority' => '10',
                        'apns-push-type' => 'alert'
                    ],
                    'payload' => [
                        'aps' => [
                            'alert' => [
                                'title' => $title,
                                'body' => $message
                            ],
                            'sound' => 'customsound.wav'
                        ]
                    ]
                ],

                // Data payload
                'data' => [
                    'type' => (string)$type,
                    'title' => (string)$title,
                    'message' => (string)$message,
                    'extra' => json_encode($extraData),
                ],
            ],
        ];

        $headers = [
            "Authorization: Bearer $accessToken",
            'Content-Type: application/json',
        ];

        $ch = curl_init();
        curl_setopt_array($ch, [
            CURLOPT_URL => $url,
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_POSTFIELDS => json_encode($fields),
        ]);

        $result = curl_exec($ch);

        if (curl_errno($ch)) {
            \Log::error('FCM Error: ' . curl_error($ch));
        }

        curl_close($ch);

        $response = json_decode($result, true);

        return isset($response['name']);
    }

    function getAccessToken($serviceAccountKeyPath)
    {
        // Read the service account key file
        $key = json_decode(file_get_contents($serviceAccountKeyPath), true);

        // Prepare the JWT header and payload
        $header = base64_encode(json_encode([
            'alg' => 'RS256',
            'typ' => 'JWT',
        ]));

        $now = time();
        $claimSet = [
            'iss' => $key['client_email'],   // Service account email
            'scope' => 'https://www.googleapis.com/auth/firebase.messaging',
            'aud' => 'https://oauth2.googleapis.com/token',
            'exp' => $now + 3600,            // Expiry time in seconds
            'iat' => $now,
        ];
        $claimSetEncoded = base64_encode(json_encode($claimSet));

        // The private key used for signing the JWT
        $privateKey = $key['private_key'];

        // Create the JWT
        $jwt = $header . '.' . $claimSetEncoded;

        // Sign the JWT with the private key using RSA
        $signature = '';

        if (!openssl_sign($jwt, $signature, $privateKey, OPENSSL_ALGO_SHA256)) {
            die('Error signing the JWT');
        }

        $signatureEncoded = base64_encode($signature);

        // Complete JWT
        $signedJwt = $jwt . '.' . $signatureEncoded;

        // Make a request to Google's OAuth2 token endpoint
        $url = 'https://oauth2.googleapis.com/token';
        $data = [
            'grant_type' => 'urn:ietf:params:oauth:grant-type:jwt-bearer',
            'assertion' => $signedJwt,
        ];

        // Use cURL to get the access token
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_POST, true);
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
        $result = curl_exec($ch);
        curl_close($ch);

        $resultData = json_decode($result, true);

        // Return the access token
        return $resultData['access_token'];
    }


    function base64($data)
    {
        return rtrim(strtr(base64_encode(json_encode($data)), '+/', '-_'), '=');
    }
}

ZeroDay Forums Mini