1 <?php
2
3 namespace Mypos\IPC;
4
5 6 7
8 class Response
9 {
10 11 12
13 private $cnf;
14 private $raw_data, $format, $data, $signature;
15
16 17 18 19 20 21 22 23
24 public function __construct(Config $cnf, $raw_data, $format)
25 {
26 $this->cnf = $cnf;
27 $this->_setData($raw_data, $format);
28 }
29
30 31 32 33 34 35 36
37 private function _setData($raw_data, $format)
38 {
39 if (empty($raw_data)) {
40 throw new IPC_Exception('Invalid Response data');
41 }
42
43 $this->format = $format;
44 $this->raw_data = $raw_data;
45
46 switch ($this->format) {
47 case Defines::COMMUNICATION_FORMAT_JSON:
48 $this->data = json_decode($this->raw_data, 1);
49 break;
50 case Defines::COMMUNICATION_FORMAT_XML:
51 $this->data = (array)new \SimpleXMLElement($this->raw_data);
52 if (isset($this->data['@attributes'])) {
53 unset($this->data['@attributes']);
54 }
55 break;
56 case Defines::COMMUNICATION_FORMAT_POST:
57 $this->data = $this->raw_data;
58 break;
59 default:
60 throw new IPC_Exception('Invalid response format!');
61 break;
62 }
63
64 if (empty($this->data)) {
65 throw new IPC_Exception('No IPC Response!');
66 }
67
68 $this->_extractSignature();
69
70 if (empty($this->signature) && array_key_exists('Status', $this->data) && $this->data['Status'] === Defines::STATUS_IPC_ERROR) {
71 throw new IPC_Exception('IPC Response - General Error!');
72 }
73
74 $this->_verifySignature();
75
76 return $this;
77 }
78
79 private function _extractSignature()
80 {
81 if (is_array($this->data) && !empty($this->data)) {
82 foreach ($this->data as $k => $v) {
83 if (strtolower($k) == 'signature') {
84 $this->signature = $v;
85 unset($this->data[$k]);
86 }
87 }
88 }
89
90 return true;
91 }
92
93 94 95
96 private function _verifySignature()
97 {
98 if (empty($this->signature)) {
99 throw new IPC_Exception('Missing request signature!');
100 }
101
102 if (!$this->cnf) {
103 throw new IPC_Exception('Missing config object!');
104 }
105
106 $pubKeyId = openssl_get_publickey($this->cnf->getAPIPublicKey());
107 if (!openssl_verify($this->_getSignData(), base64_decode($this->signature), $pubKeyId, Defines::SIGNATURE_ALGO)) {
108 throw new IPC_Exception('Signature check failed!');
109 }
110 }
111
112 private function _getSignData()
113 {
114 return base64_encode(implode('-', Helper::getValuesFromMultiDimensionalArray($this->data)));
115 }
116
117 118 119 120 121 122 123 124 125 126
127 public static function getInstance(Config $cnf, $raw_data, $format)
128 {
129 return new self($cnf, $raw_data, $format);
130 }
131
132 133 134 135 136
137 public function isSignatureCorrect()
138 {
139 try {
140 $this->_verifySignature();
141 } catch (\Exception $ex) {
142 return false;
143 }
144
145 return true;
146 }
147
148 149 150 151 152
153 function getSignature()
154 {
155 return $this->signature;
156 }
157
158
159
160 161 162 163 164 165
166 function getStatus()
167 {
168 return Helper::getArrayVal($this->getData(CASE_LOWER), 'status');
169 }
170
171 172 173 174 175 176 177 178
179 function getData($case = null)
180 {
181 if ($case !== null) {
182 if (!in_array($case, [
183 CASE_LOWER,
184 CASE_UPPER,
185 ])) {
186 throw new IPC_Exception('Invalid Key Case!');
187 }
188
189 return array_change_key_case($this->data, $case);
190 }
191
192 return $this->data;
193 }
194
195 196 197 198 199 200
201 function getStatusMsg()
202 {
203 return Helper::getArrayVal($this->getData(CASE_LOWER), 'statusmsg');
204 }
205
206 207 208 209 210
211 function getDataRaw()
212 {
213 return $this->raw_data;
214 }
215 }
216