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: | |