PacketAccessClient::callSoapMethod()   A
last analyzed

Complexity

Conditions 3
Paths 14

Size

Total Lines 15
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 10
c 0
b 0
f 0
nc 14
nop 2
dl 0
loc 15
ccs 9
cts 9
cp 1
crap 3
rs 9.9332
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\Packet\TicketResponse;
20
use Appwilio\RussianPostSDK\Tracking\Packet\TrackingResponse;
21
use Appwilio\RussianPostSDK\Tracking\Exceptions\PacketAccessException;
22
23
class PacketAccessClient implements LoggerAwareInterface
24
{
25
    use LoggerAwareTrait;
26
27
    public const LANG_ENG = 'ENG';
28
    public const LANG_RUS = 'RUS';
29
30
    public const HISTORY_OPERATIONS    = 0;
31
    public const HISTORY_NOTIFICATIONS = 1;
32
33
    public const ERROR_NOT_READY = 6;
34
    public const ERROR_INTERNAL  = 16;
35
36
    protected const WSDL_URL = 'https://tracking.pochta.ru/tracking-web-static/fc_wsdl.xml';
37
38
    /** @var string */
39
    protected $login;
40
41
    /** @var string */
42
    protected $password;
43
44
    /** @var \SoapClient */
45
    protected $client;
46
47
    protected $options = [
48
        'soap_version' => \SOAP_1_1,
49
        'trace'        => 1,
50
        'classmap'     => [
51
            // в wsdl-файле некоторые элементы называются не так, как в документации
52
            'item'                   => Packet\Item::class,          // Item → item
53
            'error'                  => Packet\Error::class,         // корневая ошибка
54
            'Error'                  => Packet\Error::class,         // ошибка конкретного РПО
55
            'file'                   => Packet\ItemsWrapper::class,  // value → file
56
            'operation'              => Packet\TrackingEvent::class, // Operation → operation
57
58
            'ticketResponse'         => TicketResponse::class,
59
            'answerByTicketResponse' => TrackingResponse::class,
60
        ],
61
    ];
62
63 6
    public function __construct(string $login, string $password)
64
    {
65 6
        $this->login = $login;
66 6
        $this->password = $password;
67
68 6
        $this->logger = new NullLogger();
69 6
    }
70
71 2
    public function getTicket(iterable $tracks, string $language = self::LANG_RUS): TicketResponse
72
    {
73 2
        if (\is_array($tracks)) {
74 1
            $tracks = new \ArrayIterator($tracks);
75
        }
76
77 2
        if (\iterator_count($tracks) > 3000) {
78 1
            throw PacketAccessException::becauseTrackNumberLimitExceeded();
79
        }
80
81 1
        return $this->callSoapMethod(
82 1
            'getTicket',
83 1
            $this->assembleTicketRequestArguments($tracks, $language)
84
        );
85
    }
86
87 3
    public function getTrackingEvents(string $ticket): TrackingResponse
88
    {
89 3
        return $this->callSoapMethod(
90 3
            'getResponseByTicket',
91 3
            $this->assembleTrackingRequestArgument($ticket)
92
        );
93
    }
94
95 4
    protected function getClient(): \SoapClient
96
    {
97 4
        return $this->client ?? ($this->client = new \SoapClient(self::WSDL_URL, $this->options));
98
    }
99
100 4
    private function callSoapMethod(string $method, \SoapVar $arguments)
101
    {
102
        try {
103 4
            $response = $this->getClient()->__soapCall($method, [$arguments]);
104
105 3
            if ($response->hasError()) {
106 1
                throw new PacketAccessException($response->getError()->getMessage(), $response->getError()->getCode());
107
            }
108
109 2
            return $response;
110 2
        } catch (\SoapFault $e) {
111 1
            throw new PacketAccessException($e->getMessage(), $e->getCode(), $e);
112
        } finally {
113 4
            $this->logger->info("Packet Tracking request: {$this->getClient()->__getLastRequest()}");
114 4
            $this->logger->info("Packet Tracking response: {$this->getClient()->__getLastResponse()}");
115
        }
116
    }
117
118 1
    private function assembleTicketRequestArguments(iterable $tracks, string $language): \SoapVar
119
    {
120 1
        $items = [];
121
122 1
        foreach ($tracks as $track) {
123 1
            $items[] = new \SoapVar("<Item Barcode=\"{$track}\" />", \XSD_ANYXML);
124
        }
125
126 1
        return new \SoapVar([
127 1
            new \SoapVar($items, \SOAP_ENC_OBJECT, '', '', 'request'),
128 1
            new \SoapVar($this->login, \XSD_STRING, '', '', 'login'),
129 1
            new \SoapVar($this->password, \XSD_STRING, '', '', 'password'),
130 1
            new \SoapVar($language, \XSD_STRING, '', '', 'language'),
131 1
        ], \SOAP_ENC_OBJECT);
132
    }
133
134 3
    private function assembleTrackingRequestArgument(string $ticket): \SoapVar
135
    {
136 3
        return new \SoapVar([
137 3
            new \SoapVar($ticket, \XSD_STRING, '', '', 'ticket'),
138 3
            new \SoapVar($this->login, \XSD_STRING, '', '', 'login'),
139 3
            new \SoapVar($this->password, \XSD_STRING, '', '', 'password'),
140 3
        ], \SOAP_ENC_OBJECT);
141
    }
142
}
143