Passed
Push — master ( de53d8...b05c35 )
by Jhao
02:13
created

PacketAccessClient   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 117
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 61
c 3
b 0
f 0
dl 0
loc 117
ccs 44
cts 44
cp 1
rs 10
wmc 12

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getTicket() 0 13 3
A getTrackingEvents() 0 5 1
A __construct() 0 6 1
A callSoapMethod() 0 15 3
A getClient() 0 3 1
A assembleTicketRequestArguments() 0 14 2
A assembleTrackingRequestArgument() 0 7 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\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
            'item'                   => Packet\Item::class,      // Item согласно wsdl-описанию называется item
52
            'error'                  => Packet\Error::class,     // корневая ошибка
53
            'Error'                  => Packet\Error::class,     // ошибка конкретного трека
54
            'file'                   => Packet\Wrapper::class,   // value согласно wsdl-описанию называется file
55
            'operation'              => Packet\Operation::class, // Operation согласно wsdl-описанию называется operation
56
57
            'ticketResponse'         => TicketResponse::class,
58
            'answerByTicketResponse' => TrackingResponse::class,
59
        ],
60
    ];
61
62 6
    public function __construct(string $login, string $password)
63
    {
64 6
        $this->logger = new NullLogger();
65
66 6
        $this->login = $login;
67 6
        $this->password = $password;
68 6
    }
69
70 2
    public function getTicket(iterable $tracks, string $language = self::LANG_RUS): TicketResponse
71
    {
72 2
        if (\is_array($tracks)) {
73 1
            $tracks = new \ArrayIterator($tracks);
74
        }
75
76 2
        if (\iterator_count($tracks) > 3000) {
77 1
            throw PacketAccessException::trackNumberLimitExceeded();
78
        }
79
80 1
        return $this->callSoapMethod(
81 1
            'getTicket',
82 1
            $this->assembleTicketRequestArguments($tracks, $language)
83
        );
84
    }
85
86 3
    public function getTrackingEvents(string $ticket): TrackingResponse
87
    {
88 3
        return $this->callSoapMethod(
89 3
            'getResponseByTicket',
90 3
            $this->assembleTrackingRequestArgument($ticket)
91
        );
92
    }
93
94 4
    protected function getClient(): \SoapClient
95
    {
96 4
        return $this->client ?? ($this->client = new \SoapClient(self::WSDL_URL, $this->options));
97
    }
98
99 4
    private function callSoapMethod(string $method, \SoapVar $arguments)
100
    {
101
        try {
102 4
            $response = $this->getClient()->__soapCall($method, [$arguments]);
103
104 3
            if ($response->hasError()) {
105 1
                throw new PacketAccessException($response->getError()->getMessage(), $response->getError()->getCode());
106
            }
107
108 2
            return $response;
109 2
        } catch (\SoapFault $e) {
110 1
            throw new PacketAccessException($e->getMessage(), $e->getCode(), $e);
111
        } finally {
112 4
            $this->logger->info("pochta.ru Packet Tracking request: {$this->getClient()->__getLastRequest()}");
113 4
            $this->logger->info("pochta.ru Packet Tracking response: {$this->getClient()->__getLastResponse()}");
114
        }
115
    }
116
117 1
    private function assembleTicketRequestArguments(iterable $tracks, string $language): \SoapVar
118
    {
119 1
        $items = new \ArrayObject();
120
121 1
        foreach ($tracks as $track) {
122 1
            $items->append(new \SoapVar("<Item Barcode=\"{$track}\" />", \XSD_ANYXML));
123
        }
124
125 1
        return new \SoapVar([
126 1
            new \SoapVar($items, \SOAP_ENC_OBJECT, '', '', 'request'),
127 1
            new \SoapVar($this->login, \XSD_STRING, '', '', 'login'),
128 1
            new \SoapVar($this->password, \XSD_STRING, '', '', 'password'),
129 1
            new \SoapVar($language, \XSD_STRING, '', '', 'language'),
130 1
        ], \SOAP_ENC_OBJECT);
131
    }
132
133 3
    private function assembleTrackingRequestArgument(string $ticket): \SoapVar
134
    {
135 3
        return new \SoapVar([
136 3
            new \SoapVar($ticket, \XSD_STRING, '', '', 'ticket'),
137 3
            new \SoapVar($this->login, \XSD_STRING, '', '', 'login'),
138 3
            new \SoapVar($this->password, \XSD_STRING, '', '', 'password'),
139 3
        ], \SOAP_ENC_OBJECT);
140
    }
141
}
142