SingleAccessClient::getTrackingUrl()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 1
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
c 3
b 0
f 0
cc 1
nc 1
nop 1
crap 1
1
<?php
2
3
/**
4
 * This file is part of RussianPost SDK package.
5
 *
6
 * © Appwilio (http://appwilio.com), greabock (https://github.com/greabock), JhaoDa (https://github.com/jhaoda)
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
declare(strict_types=1);
13
14
namespace Appwilio\RussianPostSDK\Tracking;
15
16
use Psr\Log\NullLogger;
17
use Psr\Log\LoggerAwareTrait;
18
use Psr\Log\LoggerAwareInterface;
19
use Appwilio\RussianPostSDK\Tracking\Single\TrackingEventsResponse;
20
use Appwilio\RussianPostSDK\Tracking\Single\CashOnDeliveryEventsRequest;
21
use Appwilio\RussianPostSDK\Tracking\Single\CashOnDeliveryEventsResponse;
22
use Appwilio\RussianPostSDK\Tracking\Exceptions\SingleAccessException;
23
24
class SingleAccessClient implements LoggerAwareInterface
25
{
26
    use LoggerAwareTrait;
27
28
    public const LANG_ENG = 'ENG';
29
    public const LANG_RUS = 'RUS';
30
31
    public const HISTORY_OPERATIONS    = 0;
32
    public const HISTORY_NOTIFICATIONS = 1;
33
34
    protected const LINK_URL = 'https://www.pochta.ru/tracking';
35
    protected const WSDL_URL = 'https://tracking.pochta.ru/tracking-web-static/rtm34_wsdl.xml';
36
37
    protected const XML_NS_DATA     = 'http://russianpost.org/operationhistory/data';
38
    protected const XML_NS_COD_DATA = 'http://www.russianpost.org/RTM/DataExchangeESPP/Data';
39
40
    /** @var \SoapClient */
41
    protected $client;
42
43
    /** @var string */
44
    private $login;
45
46
    /** @var string */
47
    private $password;
48
49
    private $options = [
50
        'soap_version' => SOAP_1_2,
51
        'trace'        => 1,
52
        'classmap'     => [
53
            'Rtm02Parameter'                   => Single\Parameter::class,
54
55
            'getOperationHistoryResponse'      => Single\TrackingEventsResponse::class,
56
            'OperationHistoryRecord'           => Single\TrackingEvent::class,
57
            'Address'                          => Single\TrackingEventAddress::class,
58
            'Country'                          => Single\TrackingEventCountry::class,
59
            'OperationHistoryData'             => Single\TrackingEventsWrapper::class,
60
            'OperationParameters'              => Single\TrackingEventOperationParameters::class,
61
            'UserParameters'                   => Single\TrackingEventUserParameters::class,
62
            'ItemParameters'                   => Single\TrackingEventItemParameters::class,
63
            'AddressParameters'                => Single\TrackingEventAddressParameters::class,
64
            'FinanceParameters'                => Single\TrackingEventFinanceParameters::class,
65
66
            'PostalOrderEvent'                 => Single\CashOnDeliveryEvent::class,
67
            'PostalOrderEventsForMailResponse' => Single\CashOnDeliveryEventsResponse::class,
68
            'PostalOrderEventsForMailInput'    => Single\CashOnDeliveryEventsRequest::class,
69
            // Mai – не опечатка
70
            'PostalOrderEventsForMaiOutput'    => Single\CashOnDeliveryEventsWrapper::class,
71
        ],
72
    ];
73
74 9
    public function __construct(string $login, string $password)
75
    {
76 9
        $this->login = $login;
77 9
        $this->password = $password;
78
79 9
        $this->logger = new NullLogger();
80 9
    }
81
82 1
    public function getTrackingUrl(string $number): string
83
    {
84 1
        return self::LINK_URL."#{$number}";
85
    }
86
87 4
    public function getTrackingEvents(
88
        string $track,
89
        string $language = self::LANG_RUS,
90
        int $type = self::HISTORY_OPERATIONS
91
    ): TrackingEventsResponse {
92
        /** @var TrackingEventsResponse $response */
93 4
        $response = $this->callSoapMethod(
94 4
            'getOperationHistory',
95 4
            $this->assembleTrackingRequestArguments($track, $language, $type)
96
        );
97
98 2
        if (\count($response->getEvents()) === 0) {
99 1
            throw SingleAccessException::becauseEmptyTrackingResponse($track);
100
        }
101
102 1
        return $response;
103
    }
104
105 3
    public function getCashOnDeliveryEvents(
106
        string $track,
107
        string $language = self::LANG_RUS
108
    ): CashOnDeliveryEventsResponse {
109
        /** @var CashOnDeliveryEventsResponse $response */
110 3
        $response = $this->callSoapMethod(
111 3
            'PostalOrderEventsForMail',
112 3
            $this->assembleCashOnDeliveryRequestArguments($track, $language)
113
        );
114
115 3
        if (\count($response->getEvents()) === 0) {
116 1
            throw SingleAccessException::becauseEmptyCODResponse($track);
117
        }
118
119 2
        return $response;
120
    }
121
122 7
    protected function getClient(): \SoapClient
123
    {
124 7
        return $this->client ?? ($this->client = new \SoapClient(self::WSDL_URL, $this->options));
125
    }
126
127 7
    private function callSoapMethod(string $method, \SoapVar $arguments)
128
    {
129
        try {
130 7
            return $this->getClient()->__soapCall($method, [$arguments]);
131 2
        } catch (\SoapFault $e) {
132 2
            if (\property_exists($e, 'detail')) {
133 1
                $detail = \get_object_vars($e->detail);
134
135 1
                throw new SingleAccessException(\key($detail).': '.\current($detail), $e->getCode(), $e);
136
            }
137
138 1
            throw new SingleAccessException($e->getMessage(), $e->getCode(), $e);
139
        } finally {
140 7
            $this->logger->info("Single Tracking request: {$this->getClient()->__getLastRequest()}");
141 7
            $this->logger->info("Single Tracking response: {$this->getClient()->__getLastResponse()}");
142
        }
143
    }
144
145 4
    private function assembleTrackingRequestArguments(string $track, string $language, int $type): \SoapVar
146
    {
147 4
        return new \SoapVar([
148 4
            new \SoapVar([
149 4
                new \SoapVar($track, \XSD_STRING, '', '', 'Barcode', self::XML_NS_DATA),
150 4
                new \SoapVar($type, \XSD_STRING, '', '', 'MessageType', self::XML_NS_DATA),
151 4
                new \SoapVar($language, \XSD_STRING, '', '', 'Language', self::XML_NS_DATA),
152 4
            ], \SOAP_ENC_OBJECT, '', '', 'OperationHistoryRequest', self::XML_NS_DATA),
153 4
            $this->assembleAuthorizationHeader(),
154 4
        ], \SOAP_ENC_OBJECT);
155
    }
156
157 3
    private function assembleCashOnDeliveryRequestArguments(string $code, string $language): \SoapVar
158
    {
159 3
        $input = new CashOnDeliveryEventsRequest($code, $language);
160
161 3
        return new \SoapVar([
162 3
            new \SoapVar($input, \SOAP_ENC_OBJECT, '', '', 'PostalOrderEventsForMailInput', self::XML_NS_COD_DATA),
163 3
            $this->assembleAuthorizationHeader(),
164 3
        ], \SOAP_ENC_OBJECT);
165
    }
166
167 7
    private function assembleAuthorizationHeader(): \SoapVar
168
    {
169 7
        return new \SoapVar([
170 7
            new \SoapVar($this->login, \XSD_STRING, '', '', 'login', self::XML_NS_DATA),
171 7
            new \SoapVar($this->password, \XSD_STRING, '', '', 'password', self::XML_NS_DATA),
172 7
        ], \SOAP_ENC_OBJECT, '', '', 'AuthorizationHeader', self::XML_NS_DATA);
173
    }
174
}
175