PluginProbe
DPD SK for WooCommerce / trunk
DPD SK for WooCommerce vtrunk
9.2.1 9.1.0 9.2.0 9.0.0 trunk 1.0.0 1.0.1 2.0.0 2.0.1 3.0.0 3.0.1 3.0.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 5.0.0 5.0.1 5.0.2 5.0.3 6.0.0 6.0.1 7.0.0 7.0.1 All 37 releases
wc-dpd / includes / Client.php

Client.php in DPD SK for WooCommerce trunk, at includes/Client.php

271 lines 8.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WcDPD;
4
5 use Exception;
6
7 defined('ABSPATH') || exit;
8
9 /**
10 * Client class
11 */
12 class Client
13 {
14 public const RESPONSE_SUCCESS_STATUS = 'success';
15 public const RESPONSE_ERROR_STATUS = 'error';
16
17 /**
18 * @var string
19 */
20 private $url = "https://api.dpd.sk/";
21
22 /**
23 * Sumit request
24 *
25 * @param string $method
26 * @param string $endpoint
27 * @param array $data
28 * @param bool $log_request
29 *
30 * @throws \Exception
31 *
32 * @return array|bool|false|string
33 */
34 private function call($method = 'get', $endpoint = '', $data = [], $log_request = false)
35 {
36 $method = strtolower(wp_kses_post($method));
37 $methods = ['get', 'post'];
38
39 if (!in_array($method, $methods)) {
40 throw new Exception(sprintf(__('Use the correct request method. Possible values are: %s', 'wc-dpd'), implode(', ', $methods)));
41 }
42
43 $request_data = [
44 'body' => json_encode($data),
45 'timeout' => 45
46 ];
47
48 switch ($method) {
49 case 'post':
50 $response = wp_remote_post($this->url.$endpoint, $request_data);
51 break;
52 default:
53 $response = wp_remote_get($this->url.$endpoint, $request_data);
54 break;
55 }
56
57 $response_body = \wp_remote_retrieve_body($response);
58 $response_body_decoded = json_decode($response_body, true);
59
60 if ($log_request) {
61 wc_dpd_log('Request log', wc_dpd_log_redact([
62 'data' => $data,
63 'response' => json_encode($response),
64 ]));
65 }
66
67 if (is_wp_error($response)) {
68 $error_message = $response->get_error_message();
69 throw new Exception(sprintf(__('Something went wrong: %s', 'wc-dpd'), $response->get_error_message()));
70 }
71
72 if (empty($response)) {
73 throw new Exception(__('Something went wrong! Response is empty!', 'wc-dpd'), 400);
74 }
75
76 if (isset($response_body_decoded['error'])) {
77 $error_message = isset($response_body_decoded['error']['message']) ? $response_body_decoded['error']['message'] : '';
78 $error_code = isset($response_body_decoded['error']['code']) ? (int) $response_body_decoded['error']['code'] : '';
79
80
81 if (!$error_message) {
82 $error_message = isset($response_body_decoded['message']) ? $response_body_decoded['message'] : '';
83 }
84
85 if (!$error_code) {
86 $error_code = isset($response_body_decoded['code']) ? (int) $response_body_decoded['code'] : '';
87 }
88
89 $error_message = apply_filters('wc_dpd_client_error_message', $error_message);
90
91 throw new Exception(esc_html($error_message), $error_code ? $error_code : 400);
92 }
93
94 return $response;
95 }
96
97 /**
98 * Export to DPD
99 *
100 * @param array $data
101 *
102 * @return array
103 *
104 * @throws Exception
105 */
106 public function export($data = [])
107 {
108 $response = false;
109
110 try {
111 $response = $this->call('post', "shipment/json", $data, true);
112 } catch (Exception $e) {
113 throw $e;
114 }
115
116 $response_body = \wp_remote_retrieve_body($response);
117 $response_body = isset($response_body) ? json_decode(wp_kses_post_deep($response_body), true) : [];
118
119 $success = isset($response_body['result']['result'][0]['success']) ? (bool) $response_body['result']['result'][0]['success'] : false;
120
121 if (!$success) {
122 $error_message = isset($response_body['result']['result'][0]['messages'][0]['value']) ? $response_body['result']['result'][0]['messages'][0]['value'] : null;
123
124 if (!$error_message) {
125 $error_message = isset($response_body['result']['result'][0]['messages'][0]) ? $response_body['result']['result'][0]['messages'][0] : __('Something went wrong!', 'wc-dpd');
126 }
127
128 $error_message = apply_filters('wc_dpd_client_error_message', $error_message);
129
130 throw new Exception(esc_html($error_message), 400);
131 }
132
133 $label = isset($response_body['result']['result'][0]['label']) ? wp_kses_post($response_body['result']['result'][0]['label']) : '';
134 $mpsid = isset($response_body['result']['result'][0]['mpsid']) ? (string) wp_kses_post($response_body['result']['result'][0]['mpsid']) : '';
135
136 if (!$mpsid || !preg_match('/^[A-Z0-9]{14,28}$/', $mpsid)) {
137 throw new \Exception(__('DPD API returned an invalid mpsid. Export aborted.', 'wc-dpd'), 400);
138 }
139
140 $package_number = substr($mpsid, 0, -8);
141 if (!preg_match('/^[A-Z0-9]{6,20}$/', $package_number)) {
142 throw new \Exception(__('DPD API returned an invalid package number. Export aborted.', 'wc-dpd'), 400);
143 }
144
145 return [
146 Order::EXPORT_STATUS_META_KEY => self::RESPONSE_SUCCESS_STATUS,
147 Order::EXPORT_LABEL_URL_META_KEY => $label,
148 Order::EXPORT_MPSID_META_KEY => $mpsid,
149 Order::EXPORT_PACKAGE_NUMBER_META_KEY => $package_number,
150 ];
151 }
152
153 /**
154 * Search parcelshop
155 *
156 * @param string $city
157 * @param string $zip
158 * @param string $country
159 *
160 * @return array
161 */
162 public function searchParcelShop($city = '', $zip = '', $country = '')
163 {
164 $city = wp_kses_post($city);
165 $zip = wp_kses_post($zip);
166 $country = wp_kses_post($country);
167
168 $data = [
169 'jsonrpc' => '2.0',
170 'method' => 'getByAddress',
171 'params' => [
172 "city" => $city,
173 "zip" => $zip,
174 "country" => $country,
175 "radius" => 50,
176 ]
177 ];
178
179 $response = false;
180
181 try {
182 $response = $this->call('post', "parcelshop/json", $data);
183 } catch (Exception $e) {
184 wc_dpd_log('DPD parcelshop search request failed', [
185 'endpoint' => 'parcelshop/json#getByAddress',
186 'city' => $city,
187 'zip' => $zip,
188 'country' => $country,
189 'error' => $e->getMessage(),
190 ]);
191
192 return [];
193 }
194
195 $response_body = \wp_remote_retrieve_body($response);
196 $response_body = isset($response_body) ? json_decode(wp_kses_post_deep($response_body), true) : [];
197
198 return !empty($response_body['result']['parcelshops']) ? (array) wp_kses_post_deep($response_body['result']['parcelshops']) : [];
199 }
200
201 /**
202 * Bulk download labels
203 *
204 * @param array $package_numbers
205 *
206 * @return mixed
207 */
208 public function bulkDownloadLabels($package_numbers = [])
209 {
210 if (empty($package_numbers)) {
211 return false;
212 }
213
214 $parcels = [];
215 foreach ($package_numbers as $package_number) {
216 $parcels[]['parcelno'] = $package_number;
217 }
218
219 $settings = DpdExportSettings::getDefaultSettings();
220
221 $data = [
222 'jsonrpc' => '2.0',
223 'method' => 'printLabels',
224 'params' => [
225 'DPDSecurity' => [
226 'SecurityToken' => [
227 'ClientKey' => $settings[DpdExportSettings::API_KEY_OPTION_KEY],
228 'Email' => $settings[DpdExportSettings::EMAIL_OPTION_KEY],
229 ],
230 ],
231 'label' => [
232 'parcels' => [
233 'parcel' => $parcels
234 ],
235 'pageSize' => $settings[DpdExportSettings::LABELS_FORMAT_OPTION_KEY],
236 'position' => '1'
237 ],
238 ]
239 ];
240
241 $response = false;
242
243 try {
244 $response = $this->call('post', "shipment/json", $data);
245 } catch (Exception $e) {
246 wc_dpd_log('DPD bulk label request failed', [
247 'endpoint' => 'shipment/json#printLabels',
248 'parcel_count' => count($parcels),
249 'error' => $e->getMessage(),
250 ]);
251
252 return false;
253 }
254
255 $response_body = \wp_remote_retrieve_body($response);
256 $success = $response_body
257 && preg_match("/^%PDF-1\.[0-9]+/", $response_body)
258 && str_ends_with(rtrim($response_body), '%%EOF');
259
260 if (!$success) {
261 wc_dpd_log('DPD bulk label download: response was not a valid PDF', wc_dpd_log_redact([
262 'content_type' => wp_remote_retrieve_header($response, 'content-type'),
263 'body_snippet' => substr((string) $response_body, 0, 200),
264 ]));
265 return false;
266 }
267
268 return $response_body;
269 }
270 }
271