Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
3.77% covered (danger)
3.77%
2 / 53
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
VonageTextSender
3.77% covered (danger)
3.77%
2 / 53
50.00% covered (danger)
50.00%
1 / 2
18.26
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 sendText
0.00% covered (danger)
0.00%
0 / 51
0.00% covered (danger)
0.00%
0 / 1
12
1<?php
2
3namespace BuyerKiosk\SMS\TextMessageService;
4
5class VonageTextSender implements TextSenderInterface
6{
7    protected $store;
8    protected $usageLog;
9
10    public function __construct($store)
11    {
12        $this->store = $store;
13        $this->usageLog = \KLoggerFactory::getLogger($_ENV['LOG_DIR'] . "/vonage_usage.log", \KLogger::INFO);
14    }
15
16    public function sendText(string $messageText, string $phone)
17    {
18        //TODO: Use https://github.com/vonage/vonage-php-sdk-core when upgraded to PHP > 8.1
19
20        // Build delivery receipt webhook URL
21        $baseUrl = $_ENV['BASE_URL'] ?? 'https://dev2.buyerkiosk.com';
22        $webhookUrl = rtrim($baseUrl, '/') . '/api/webhooks/vonage-delivery-simple.php';
23
24        $postfields = [
25            'api_key'           => $_ENV['VONAGE_KEY'],
26            'api_secret'        => $_ENV['VONAGE_SECRET'],
27            'from'              => $_ENV['VONAGE_NUMBER'],
28            'text'              => $messageText,
29            'to'                => '+1' . $phone,
30            'status-report-req' => '1',  // Request delivery receipt
31            'callback'          => $webhookUrl  // Delivery receipt webhook URL
32        ];
33
34        $ch = curl_init();
35        curl_setopt($ch, CURLOPT_URL, 'https://rest.nexmo.com/sms/json');
36        curl_setopt($ch, CURLOPT_POST, 1);
37        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
38        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields));
39        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
40
41        $result = curl_exec($ch);
42
43        if (curl_errno($ch)) {
44            $error = curl_error($ch);
45            error_log('Nexmo cURL error: ' . $error);
46            $this->usageLog->LogInfo("VONAGE_FAILED,phone=" . $phone . ",error=cURL: " . $error);
47
48            curl_close($ch);
49            return [
50                'provider' => 'nexmo',
51                'status'   => 'failed',
52                'id'       => null,
53                'error'    => $error
54            ];
55        }
56
57        curl_close($ch);
58
59        // Attempt to decode Nexmo's response
60        $decoded = json_decode($result, true);
61        // Typically Nexmo returns an array in 'messages'
62        $messageInfo = $decoded['messages'][0] ?? null;
63        $status      = $messageInfo['status'] ?? null;
64        $messageId   = $messageInfo['message-id'] ?? null;
65        $errorText   = $messageInfo['error-text'] ?? null;
66
67        if ($status !== '0') {
68            // If status is not '0', Nexmo indicates something went wrong
69            error_log('Nexmo error: ' . $errorText);
70            $this->usageLog->LogInfo("VONAGE_FAILED,phone=" . $phone . ",error=" . $errorText);
71            return [
72                'provider' => 'nexmo',
73                'status'   => 'failed',
74                'id'       => $messageId,
75                'error'    => $errorText
76            ];
77        }
78
79        // Otherwise, success
80        $this->usageLog->LogInfo("VONAGE_SUCCESS,phone=" . $phone . ",message_id=" . $messageId);
81        return [
82            'provider' => 'nexmo',
83            'status'   => 'success',
84            'id'       => $messageId,
85            'error'    => ''
86        ];
87    }
88}