1C-Bitrix 25.700.0
Загрузка...
Поиск...
Не найдено
rus_post.php
См. документацию.
1<?php
2
3namespace Bitrix\Sale\Delivery\Tracking;
4
5use Bitrix\Main\Error;
6use Bitrix\Sale\Result;
7use Bitrix\Main\Text\Encoding;
8use Bitrix\Main\Localization\Loc;
9
10Loc::loadMessages(__FILE__);
11
17class RusPost extends Base
18{
22 public function getClassTitle()
23 {
24 return Loc::getMessage("SALE_DELIVERY_TRACKING_RUS_POST_TITLE");
25 }
26
30 public function getClassDescription()
31 {
32 return Loc::getMessage(
33 "SALE_DELIVERY_TRACKING_RUS_POST_DESCRIPTION",
34 array(
35 '#A1#' => '<a href="https://tracking.pochta.ru/">',
36 '#A2#' => '</a>'
37 )
38 );
39 }
40
41
46 public function getStatus($trackingNumber)
47 {
48 $trackingNumber = trim($trackingNumber);
49 $result = new StatusResult();
50
51 if(!$this->checkTrackNumberFormat($trackingNumber))
52 $result->addError(new Error(Loc::getMessage('SALE_DELIVERY_TRACKING_RUS_POST_ERROR_TRNUM_FORMAT')));
53
54 if(empty($this->params['LOGIN']))
55 $result->addError(new Error(Loc::getMessage("SALE_DELIVERY_TRACKING_RUS_POST_LOGIN_ERROR")));
56
57 if(empty($this->params['PASSWORD']))
58 $result->addError(new Error(Loc::getMessage("SALE_DELIVERY_TRACKING_RUS_POST_PASSWORD_ERROR")));
59
60 if($result->isSuccess())
61 {
62 $t = new RusPostSingle(
63 $this->params['LOGIN'],
64 $this->params['PASSWORD']
65 );
66
67 $result = $t->getOperationHistory($trackingNumber);
68 }
69
70 return $result;
71 }
72
78 public function getStatuses(array $trackingNumbers)
79 {
80 $data = array();
81
82 foreach($trackingNumbers as $number)
83 $data[$number] = $this->getStatus($number);
84
85 return $data;
86 }
87
91 public function getParamsStructure()
92 {
93 return array(
94 "LOGIN" => array(
95 'TYPE' => 'STRING',
96 'LABEL' => Loc::getMessage("SALE_DELIVERY_TRACKING_RUS_POST_LOGIN")
97 ),
98 "PASSWORD" => array(
99 'TYPE' => 'STRING',
100 'LABEL' => Loc::getMessage("SALE_DELIVERY_TRACKING_RUS_POST_PASSWORD")
101 )
102 );
103 }
104
112 protected function checkTrackNumberFormat($trackNumber)
113 {
114 if(mb_strlen($trackNumber) == 13)
115 return preg_match('/^[A-Z]{2}?\d{9}?[A-Z]{2}$/i', $trackNumber) == 1;
116 elseif(mb_strlen($trackNumber) == 14)
117 return preg_match('/^\d{14}?$/', $trackNumber) == 1;
118 else
119 return false;
120 }
121
126 public function getTrackingUrl($trackingNumber = '')
127 {
128 return 'https://pochta.ru/tracking'.($trackingNumber <> '' ? '#'.$trackingNumber : '');
129 }
130}
131
137{
138 const LANG_RUS = "RUS";
139 const LANG_ENG = "ENG";
140
141 protected $client = null;
142 protected $lang = "";
143 protected $login = "";
144 protected $password = "";
145
146 protected static $url = 'https://tracking.russianpost.ru/rtm34';
147
153 public function __construct($login, $password, $lang = self::LANG_RUS)
154 {
155 $this->httpClient = new \Bitrix\Main\Web\HttpClient(array(
156 "version" => "1.1",
157 "socketTimeout" => 15,
158 "streamTimeout" => 15,
159 "redirect" => true,
160 "redirectMax" => 5,
161 ));
162
163 $this->httpClient->setHeader("Content-Type", "application/soap+xml; charset=utf-8");
164 $this->lang = $lang;
165 $this->login = $login;
166 $this->password = $password;
167 }
168
169 public function sendRequest($requestData)
170 {
171 $result = new Result();
172
173 $httpRes = $this->httpClient->post(self::$url, $requestData);
174 $errors = $this->httpClient->getError();
175
176 if (!$httpRes && !empty($errors))
177 {
178 $strError = "";
179
180 foreach($errors as $errorCode => $errMes)
181 $strError .= $errorCode.": ".$errMes;
182
183 $result->addError(new Error($strError));
184 }
185 else
186 {
187 $status = $this->httpClient->getStatus();
188
189 $objXML = new \CDataXML();
190 $objXML->LoadString($httpRes);
191 $data = $objXML->GetArray();
192 $result->addData($data);
193
194 if ($status != 200)
195 {
196 $result->addError(new Error(Loc::getMessage('SALE_DELIVERY_TRACKING_RUS_POST_ERROR_HTTP_STATUS').': '.$status));
197
198 if(!empty($data['Envelope']['#']['Body'][0]['#']['Fault'][0]['#']['Reason'][0]['#']['Text'][0]['#']))
199 $result->addError(new Error($data['Envelope']['#']['Body'][0]['#']['Fault'][0]['#']['Reason'][0]['#']['Text'][0]['#']));
200
201 if(!empty($data['Envelope']['#']['Body'][0]['#']['Fault'][0]['#']['Detail'][0]['#']['AuthorizationFaultReason'][0]['#']))
202 $result->addError(new Error($data['Envelope']['#']['Body'][0]['#']['Fault'][0]['#']['Detail'][0]['#']['AuthorizationFaultReason'][0]['#']));
203 }
204 }
205
206 return $result;
207 }
208
213 public function getOperationHistory($trackingNumber)
214 {
215 $result = new StatusResult();
216 $requestData = '
217 <soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:oper="http://russianpost.org/operationhistory" xmlns:data="http://russianpost.org/operationhistory/data" xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
218 <soap:Header/>
219 <soap:Body>
220 <oper:getOperationHistory>
221 <data:OperationHistoryRequest>
222 <data:Barcode>'.$trackingNumber.'</data:Barcode>
223 <data:MessageType>0</data:MessageType>
224 <data:Language>'.$this->lang.'</data:Language>
225 </data:OperationHistoryRequest>
226 <data:AuthorizationHeader soapenv:mustUnderstand="1">
227 <data:login>'.$this->login.'</data:login>
228 <data:password>'.$this->password.'</data:password>
229 </data:AuthorizationHeader>
230 </oper:getOperationHistory>
231 </soap:Body>
232 </soap:Envelope>
233 ';
234
235 $res = $this->sendRequest($requestData);
236
237 if(!$res->isSuccess())
238 {
239 $result->addErrors($res->getErrors());
240 return $result;
241 }
242
243 $lastOperation = $this->getLastOperation($res->getData());
244
245 if(!$lastOperation)
246 {
247 $result->addError(new Error(Loc::getMessage('SALE_DELIVERY_TRACKING_RUS_POST_ERROR_LAST_OP')));
248 }
249 else
250 {
251 $result->status = $this->extractStatus($lastOperation);
252 $result->description = $this->createDescription($trackingNumber);
253 $lastOperationTS = $this->extractLastChangeDate($lastOperation);
254
255 if($lastOperationTS > 0)
256 $result->lastChangeTimestamp = $this->extractLastChangeDate($lastOperation);
257
258 $result->trackingNumber = $trackingNumber;
259 }
260
261 return $result;
262 }
263
268 protected function extractLastChangeDate($lastOperation)
269 {
270 if(empty($lastOperation['#']['OperationParameters'][0]['#']['OperDate'][0]['#']))
271 return 0;
272
273 $date = new \DateTime($lastOperation['#']['OperationParameters'][0]['#']['OperDate'][0]['#']);
274 return $date->getTimestamp();
275 }
276
281 protected function getLastOperation(array $answer)
282 {
283 $history = $answer['Envelope']['#']['Body'][0]['#']['getOperationHistoryResponse'][0]['#']['OperationHistoryData'][0]['#']['historyRecord'];
284
285 if(!is_array($history) || empty($history))
286 return null;
287
288 if(!$lastOperation = end($history))
289 return null;
290
291 return $lastOperation;
292 }
293
298 protected function createDescription($trackingNumber)
299 {
300 $link = 'https://pochta.ru/tracking#'.$trackingNumber;
301 return Loc::getMessage('SALE_DELIVERY_TRACKING_RUS_POST_STATUS_DESCR').': '.'<a href="'.$link.'">'.$link.'</a>';
302 }
303
308 protected function extractStatus(array $lastOperation)
309 {
310 if(!isset($lastOperation['#']['OperationParameters']['0']['#']['OperType']['0']['#']['Id']['0']['#']))
311 return Statuses::UNKNOWN;
312
313 if(!isset($lastOperation['#']['OperationParameters'][0]['#']['OperAttr'][0]['#']['Id'][0]['#']))
314 return Statuses::UNKNOWN;
315
316 $oper = $lastOperation['#']['OperationParameters'][0]['#']['OperType'][0]['#']['Id'][0]['#'];
317 $att = $lastOperation['#']['OperationParameters'][0]['#']['OperAttr'][0]['#']['Id'][0]['#'];
318
319 return $this->mapStatus($oper, $att);
320 }
321
328 protected function mapStatus($oper, $attr)
329 {
330 if($oper == '')
331 return Statuses::UNKNOWN;
332
333 /*
334 * if innerStatus1 != innerStatus2 != .......
335 *
336 * opCode1 => array (
337 * attrCode1 => innerStatus1
338 * attrCode2 => innerStatus2
339 * ...
340 * )
341 *
342 * if innerStatus1 == innerStatus2 == .......
343 *
344 * opCode => innerStatus
345 *
346 */
347 $rusPostStatuses = array(
349 2 => array(
350 1 => Statuses::HANDED,
352 3 => Statuses::HANDED,
354 5 => Statuses::HANDED,
355 6 => Statuses::HANDED,
357 8 => Statuses::HANDED,
359 10 => Statuses::HANDED,
360 11 => Statuses::HANDED,
361 12 => Statuses::HANDED,
362 ),
365 5 => array(
371 ),
372 6 => array(
378 ),
380 8 => array(
391 10 => Statuses::ARRIVED,
393 12 => Statuses::ARRIVED,
395 14 => Statuses::ARRIVED,
401
402 ),
406 12 => array(
416 10 => Statuses::PROBLEM,
417 11 => Statuses::ARRIVED,
418 12 => Statuses::PROBLEM,
419 13 => Statuses::PROBLEM,
420 14 => Statuses::PROBLEM,
421 15 => Statuses::ARRIVED,
422 16 => Statuses::PROBLEM,
423 17 => Statuses::ARRIVED,
424 18 => Statuses::ARRIVED,
425 19 => Statuses::PROBLEM,
426 20 => Statuses::PROBLEM,
427 21 => Statuses::PROBLEM,
428 22 => Statuses::ARRIVED,
429 23 => Statuses::PROBLEM,
430 24 => Statuses::PROBLEM,
431 25 => Statuses::ARRIVED,
432 26 => Statuses::PROBLEM,
433 27 => Statuses::ARRIVED,
434 28 => Statuses::PROBLEM,
435 ),
438 15 => Statuses::ARRIVED,
439 16 => Statuses::PROBLEM,
440 17 => Statuses::ARRIVED,
441 18 => Statuses::PROBLEM,
445 22 => Statuses::PROBLEM,
447 24 => Statuses::PROBLEM,
449 26 => Statuses::PROBLEM,
457 );
458
459 if(!isset($rusPostStatuses[$oper]))
460 return Statuses::UNKNOWN;
461
462 if(!is_array($rusPostStatuses[$oper]))
463 return $rusPostStatuses[$oper];
464
465 if($attr == '')
466 return Statuses::UNKNOWN;
467
468 if(!isset($rusPostStatuses[$oper][$attr]))
469 return Statuses::UNKNOWN;
470
471 return $rusPostStatuses[$oper][$attr];
472 }
473}
Определения error.php:15
Определения rus_post.php:18
getClassDescription()
Определения rus_post.php:30
getParamsStructure()
Определения rus_post.php:91
getClassTitle()
Определения rus_post.php:22
getTrackingUrl($trackingNumber='')
Определения rus_post.php:126
getStatuses(array $trackingNumbers)
Определения rus_post.php:78
checkTrackNumberFormat($trackNumber)
Определения rus_post.php:112
getStatus($trackingNumber)
Определения rus_post.php:46
Определения rus_post.php:137
const LANG_RUS
Определения rus_post.php:138
extractStatus(array $lastOperation)
Определения rus_post.php:308
mapStatus($oper, $attr)
Определения rus_post.php:328
getLastOperation(array $answer)
Определения rus_post.php:281
$password
Определения rus_post.php:144
sendRequest($requestData)
Определения rus_post.php:169
const LANG_ENG
Определения rus_post.php:139
__construct($login, $password, $lang=self::LANG_RUS)
Определения rus_post.php:153
$lang
Определения rus_post.php:142
createDescription($trackingNumber)
Определения rus_post.php:298
getOperationHistory($trackingNumber)
Определения rus_post.php:213
static $url
Определения rus_post.php:146
$client
Определения rus_post.php:141
$login
Определения rus_post.php:143
extractLastChangeDate($lastOperation)
Определения rus_post.php:268
$data['IS_AVAILABLE']
Определения .description.php:13
</td ></tr ></table ></td ></tr >< tr >< td class="bx-popup-label bx-width30"><?=GetMessage("PAGE_NEW_TAGS")?> array( $site)
Определения file_new.php:804
$res
Определения filter_act.php:7
$result
Определения get_property_values.php:14
$errors
Определения iblock_catalog_edit.php:74
$strError
Определения options_user_settings.php:4
$status
Определения session.php:10
if( $daysToExpire >=0 &&$daysToExpire< 60 elseif)( $daysToExpire< 0)
Определения prolog_main_admin.php:393
lang
Определения options.php:182