Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
0.00% |
0 / 83 |
|
0.00% |
0 / 8 |
CRAP | |
0.00% |
0 / 1 |
| RemoteCheckIn | |
0.00% |
0 / 83 |
|
0.00% |
0 / 8 |
306 | |
0.00% |
0 / 1 |
| __construct | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
2 | |||
| create | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
12 | |||
| sendSMS | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
6 | |||
| sendCheckInSMS | |
0.00% |
0 / 25 |
|
0.00% |
0 / 1 |
20 | |||
| generate_uuid | |
0.00% |
0 / 8 |
|
0.00% |
0 / 1 |
6 | |||
| crypto_rand_secure | |
0.00% |
0 / 11 |
|
0.00% |
0 / 1 |
6 | |||
| checkFloodLimit | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
| addToSMSCount | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
6 | |||
| 1 | <?php |
| 2 | |
| 3 | namespace BuyerKiosk\Core; |
| 4 | |
| 5 | class 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 | } |