Passed
Push — main ( 6bf038...55787e )
by Aleksandr
08:10
created

Client::sendRequest()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 13
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 9
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 10
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 13
ccs 9
cts 9
cp 1
crap 3
rs 9.9332
1
<?php
2
3
declare(strict_types=1);
4
5
namespace DalliSDK;
6
7
use DalliSDK\Models\Interval;
8
use DalliSDK\Models\Order;
9
use DalliSDK\Models\OrderResponse;
10
use DalliSDK\Models\Point;
11
use DalliSDK\Models\Service;
12
use DalliSDK\Requests\Stickers\StickersBase64Request;
13
use DalliSDK\Requests\Stickers\StickersStreamRequest;
14
use DalliSDK\Requests\Stickers\StickersXmlRequest;
15
use DalliSDK\Responses\Act\ActBase64Response;
16
use DalliSDK\Responses\CreateBasketResponse;
17
use DalliSDK\Responses\DeliveryCostResponse;
18
use DalliSDK\Responses\EditBasketResponse;
19
use DalliSDK\Responses\GetBasketResponse;
20
use DalliSDK\Responses\IntervalsResponse;
21
use DalliSDK\Responses\OrderDeliveryStatusResponse;
22
use DalliSDK\Responses\PointResponse;
23
use DalliSDK\Responses\RemoveBasketResponse;
24
use DalliSDK\Responses\RuPostResponse;
25
use DalliSDK\Responses\SendToDeliveryResponse;
26
use DalliSDK\Responses\ServicesResponse;
27
use DalliSDK\Responses\SimpleResponse;
28
use DalliSDK\Responses\Stickers\StickersBase64Response;
29
use DalliSDK\Responses\Stickers\StickersXmlResponse;
30
use JMS\Serializer\Naming\CamelCaseNamingStrategy;
31
use JMS\Serializer\Naming\SerializedNameAnnotationStrategy;
32
use JMS\Serializer\SerializerBuilder;
33
use JMS\Serializer\SerializerInterface;
34
use Psr\Http\Client\ClientExceptionInterface;
35
36
/**
37
 * @method ServicesResponse|Service[]               sendServicesRequest(Requests\ServicesRequest $request)
38
 * @method IntervalsResponse|Interval[]             sendIntervalsRequest(Requests\IntervalsRequest $request)
39
 * @method PointResponse|Point[]                    sendPointRequest(Requests\PointRequest $request)
40
 * @method DeliveryCostResponse                     sendDeliveryCostRequest(Requests\DeliveryCostRequest $request)
41
 * @method OrderDeliveryStatusResponse              sendStatusRequest(Requests\OrderDeliveryStatusRequest $request)
42
 *
43
 * @method CreateBasketResponse|OrderResponse[]     sendCreateBasketRequest(Requests\CreateBasketRequest $request)
44
 * @method RuPostResponse|OrderResponse[]           sendCreateRuPostRequest(Requests\RuPostRequest $request)
45
 * @method GetBasketResponse|Order[]                sendGetBasketRequest(Requests\GetBasketRequest $request)
46
 * @method EditBasketResponse|OrderResponse         sendEditBasketRequest(Requests\EditBasketRequest $request)
47
 * @method RemoveBasketResponse                     sendRemoveBasketRequest(Requests\RemoveBasketRequest $request)
48
 * @method SendToDeliveryResponse|OrderResponse[]   sendToDeliveryRequest(Requests\SendToDeliveryBasketRequest $request)
49
 *
50
 * @method SimpleResponse                           sendStickersStreamRequest(StickersStreamRequest $request)
51
 * @method StickersBase64Response                   sendStickersBase64Request(StickersBase64Request $request)
52
 * @method StickersXmlResponse                      sendStickersXmlRequest(StickersXmlRequest $request)
53
 *
54
 * @method SimpleResponse                           sendStickersBasketStreamRequest(Requests\Stickers\Basket\StickersStreamRequest $request)
55
 * @method StickersBase64Response                   sendStickersBasketBase64Request(Requests\Stickers\Basket\StickersBase64Request $request)
56
 * @method StickersXmlResponse                      sendStickersBasketXmlRequest(Requests\Stickers\Basket\StickersXmlRequest $request)
57
 *
58
 * @method SimpleResponse                           sendActStreamRequest(Requests\Act\ActStreamRequest $request)
59
 * @method ActBase64Response                        sendActBase64Request(Requests\Act\ActBase64Request $request)
60
 */
61
class Client
62
{
63
    private \Psr\Http\Client\ClientInterface $httpClient;
64
    private SerializerInterface $serializer;
65
    private string $token;
66
    private string $url;
67
68 3
    public function __construct(\Psr\Http\Client\ClientInterface $http, string $token, string $url)
69
    {
70 3
        $this->httpClient = $http;
71 3
        $this->token = $token;
72 3
        $this->url = $url;
73
74 3
        $this->serializer = SerializerBuilder::create()
75 3
            ->setPropertyNamingStrategy(new SerializedNameAnnotationStrategy(new CamelCaseNamingStrategy()))
76 3
            ->build();
77
    }
78
79 3
    public function __call(string $name, array $arguments): \DalliSDK\Responses\ResponseInterface
80
    {
81 3
        if (0 === \strpos($name, 'send')) {
82 2
            return $this->sendRequest(...$arguments);
0 ignored issues
show
Bug introduced by
$arguments is expanded, but the parameter $request of DalliSDK\Client::sendRequest() does not expect variable arguments. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

82
            return $this->sendRequest(/** @scrutinizer ignore-type */ ...$arguments);
Loading history...
83
        }
84 1
        throw new \BadMethodCallException(\sprintf('Method [%s] not found in [%s].', $name, __CLASS__));
85
    }
86
87
88
    /**
89
     * @param \DalliSDK\Requests\RequestInterface $request
90
     *
91
     * @return \DalliSDK\Responses\ResponseInterface
92
     * @throws ClientExceptionInterface
93
     */
94 2
    public function sendRequest(\DalliSDK\Requests\RequestInterface $request): \DalliSDK\Responses\ResponseInterface
95
    {
96 2
        $response = $this->doRequest($request);
97
        if (
98 2
            $response->hasHeader('Content-Type') &&
99 2
            \strpos(implode(',', $response->getHeader('Content-Type')), 'text/xml') !== false
100
        ) {
101 1
            $body = $response->getBody()->getContents();
102 1
            $body = $this->fixNullAttributes($body);
103 1
            $body = $this->fixAmpersand($body);
104 1
            return $this->serializer->deserialize($body, $request->getResponseClass(), 'xml');
105
        } else {
106 1
            return new SimpleResponse((string)$response->getBody(), (int)$response->getStatusCode());
107
        }
108
    }
109
110
111
    /**
112
     * @param \DalliSDK\Requests\RequestInterface $request
113
     *
114
     * @return \Psr\Http\Message\ResponseInterface
115
     * @throws \Psr\Http\Client\ClientExceptionInterface
116
     */
117 2
    private function doRequest(\DalliSDK\Requests\RequestInterface $request): \Psr\Http\Message\ResponseInterface
118
    {
119 2
        $request->setAuth($this->token);
120 2
        $body = $this->serializer->serialize($request, 'xml');
121 2
        return $this->httpClient->sendRequest(new \Nyholm\Psr7\Request('POST', $this->url, [], $body));
122
    }
123
124
125
    /**
126
     * В ответе от Dalli отсутствующие значения обязательных аттрибутов почему-то приходят не согласно спецификации xml
127
     * и поэтому ломается удобная десериализация, чтобы этого не было, фиксим отсутствующие атрибуты
128
     *
129
     * @param string $xml
130
     *
131
     * @return array|string|string[]|null
132
     */
133 1
    private function fixNullAttributes(string $xml)
134
    {
135 1
        return preg_replace('/([a-zA-Z]+)=""/', 'xsi:$1="nill"', $xml);
136
    }
137
138
    /**
139
     * Заменям символ амперсанда, так как из-за него ломается десериализация
140
     *
141
     * @param string $xml
142
     *
143
     * @return array|string|string[]
144
     */
145 1
    private function fixAmpersand(string $xml)
146
    {
147 1
        return str_replace('&', '&amp;', $xml);
148
    }
149
}
150