Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 83
0.00% covered (danger)
0.00%
0 / 8
CRAP
0.00% covered (danger)
0.00%
0 / 1
RemoteCheckIn
0.00% covered (danger)
0.00%
0 / 83
0.00% covered (danger)
0.00%
0 / 8
306
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
2
 create
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
12
 sendSMS
0.00% covered (danger)
0.00%
0 / 12
0.00% covered (danger)
0.00%
0 / 1
6
 sendCheckInSMS
0.00% covered (danger)
0.00%
0 / 25
0.00% covered (danger)
0.00%
0 / 1
20
 generate_uuid
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 crypto_rand_secure
0.00% covered (danger)
0.00%
0 / 11
0.00% covered (danger)
0.00%
0 / 1
6
 checkFloodLimit
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 addToSMSCount
0.00% covered (danger)
0.00%
0 / 7
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2
3namespace BuyerKiosk\Core;
4
5class RemoteCheckIn extends Store
6{
7    private $db;
8    private $log;
9    private $redis;
10    private $storeInfo;
11
12    public $uuid;
13    public $phone;
14
15
16    public function __construct($typeNum)
17    {
18        $this->log = new \KLogger($_ENV['LOG_DIR'] . "remoteCheckIn.log", \KLogger::DEBUG);
19        $this->createStore($typeNum);
20        global $db_name;
21        $this->db = dbConnectByName($db_name);
22        $this->db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
23        $this->redis = new \Predis\Client($_ENV['REDIS_URL']);
24        $this->storeInfo = getStoreInfo($this);
25    }
26
27    public function create($phone)
28    {
29        $this->uuid = $this->generate_uuid(8);
30        $this->phone = $phone;
31        //$this->log->LogDebug("UUID: ".$this->uuid);
32        //$this->log->LogDebug("Phone: ".$this->phone);
33        $stmt = $this->db->prepare("INSERT INTO remoteCheckIns (uuid, phone, typeNum, used) VALUES (:uuid, :phone, :typeNum, 0)");
34        $stmt->bindValue(":uuid", $this->uuid);
35        $stmt->bindValue(":phone", $this->phone);
36        $stmt->bindValue(":typeNum", $this->getTypeNum());
37        if ($stmt->execute()) {
38            return $this->db->lastInsertId();
39        } else {
40            //UUID is a unique key in database. If duplicate uuid exists in the database recursively generate a new one until we no longer have a collision.
41            if ((int)$stmt->errorCode() == 1062) {
42                return $this->create($phone);
43            } else {
44                $this->log->LogError($stmt->errorInfo());
45            }
46        }
47        return null;
48    }
49
50
51    public function sendSMS()
52    {
53        $this->log->LogDebug("[".$this->phone."] flood count: ".$this->checkFloodLimit());
54        if($this->checkFloodLimit() > 100) {
55            $this->log->LogDebug("[".$this->phone."] exceeded flood limit");
56        } else {
57            $URL = "https://v2ts.co/r/" . $this->uuid;
58            $message = "Welcome to ".$this->storeInfo['type']." Mobile Check-In! Here is your URL to check in: " . $URL;
59            $this->log->LogDebug("New Outgoing SMS: " . $message);
60            $this->sendCheckInSMS($this->phone, null, $message);
61            $storeDB = dbConnectByName($this->getDbName());
62            $stmt = $storeDB->prepare("INSERT INTO texts (timestamp, customerID, employeeNumber, type, message) VALUES (CURRENT_TIMESTAMP, 0, 0, 2, :message)");
63            $stmt->bindValue(":message", $message);
64            $stmt->execute();
65
66            $this->addToSMSCount();
67        }
68
69    }
70    function sendCheckInSMS($number,$shortName = null,$message=null) {
71        $this->log->LogDebug("[".$number."] - ".$shortName." - ".$message);
72        if($shortName !== null) {
73            $message = new \LoyaltyMessage(null, $shortName);
74            if(strlen($message->getMessage()) > 0) {
75                $text = $message->getMessage();
76            }
77        } elseif($message !== null) {
78            $text = $message;
79        } else {
80            return null;
81        }
82
83        $postfields = array(
84            'api_key'=>'67e71b29',
85            'api_secret'=>'47f48c40b1586e71',
86            'from' => '91904',
87            'text' => $text,
88            'to' => "+1".$number,
89        );
90        $ch = curl_init();
91        curl_setopt($ch, CURLOPT_URL, 'https://rest.nexmo.com/sms/json');
92        curl_setopt($ch, CURLOPT_POST, 1);
93        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
94        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($postfields));
95        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 1);
96        $result = curl_exec($ch);
97        $response = json_decode($result);
98        curl_close($ch);
99        return $response;
100    }
101
102    public function generate_uuid($len = 8)
103    {
104
105        $token = "";
106        $codeAlphabet = "ABCDEFGHIJKLMNPQRSTUVWXYZ";
107        $codeAlphabet .= "abcdefghijklmnpqrstuvwxyz";
108        $codeAlphabet .= "123456789";
109        $max = strlen($codeAlphabet); // edited
110
111        for ($i = 0; $i < $len; $i++) {
112            $token .= $codeAlphabet[$this->crypto_rand_secure(0, $max - 1)];
113        }
114        return $token;
115    }
116
117    public function crypto_rand_secure($min, $max)
118    {
119        $range = $max - $min;
120        if ($range < 1) {
121            return $min;
122        } // not so random...
123        $log = ceil(log($range, 2));
124        $bytes = (int)($log / 8) + 1; // length in bytes
125        $bits = (int)$log + 1; // length in bits
126        $filter = (int)(1 << $bits) - 1; // set all lower bits to 1
127        do {
128            $rnd = hexdec(bin2hex(openssl_random_pseudo_bytes($bytes)));
129            $rnd = $rnd & $filter; // discard irrelevant bits
130        } while ($rnd > $range);
131        return $min + $rnd;
132    }
133    public function checkFloodLimit() {
134        return $this->redis->get($this->phone."_mc");
135    }
136    public function addToSMSCount() {
137        if($this->redis->exists($this->phone."_mc")) {
138            $current = $this->redis->get($this->phone."_mc");
139        } else {
140            $current = 0;
141        }
142        $current++;
143        $this->redis->set($this->phone."_mc", $current);
144        $expireAt = strtotime("tomorrow 05:00:00");
145        $this->redis->expireat($this->phone."_mc", $expireAt);
146    }
147}