Passed
Push — master ( 8e03b4...59061c )
by Konstantin
02:28
created

Client::execute()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 15
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 5
eloc 12
c 0
b 0
f 0
nc 5
nop 1
dl 0
loc 15
rs 9.5555
1
<?php
2
3
namespace Phrlog\Zvonok;
4
5
use JsonMapper, JsonMapper_Exception;
6
use Http\Client\{Exception, HttpClient};
7
use Http\Discovery\{HttpClientDiscovery, Psr17FactoryDiscovery};
8
use Psr\Http\Message\RequestFactoryInterface;
9
use Phrlog\Zvonok\Exception\{EmptyResponseException, ResponseWithErrorException, UnknownRequestException};
10
use Phrlog\Zvonok\Phone\Mapper\{AddCallMapper, GetCallByIdMapper, GetRegionByPhoneMapper, GetCallByPhoneMapper};
11
use Phrlog\Zvonok\Phone\Request\{
12
    RequestInterface,
13
    AddCallRequest,
14
    GetCallByIdRequest,
15
    GetRegionByPhoneRequest,
16
    GetCallByPhoneRequest
17
};
18
use Phrlog\Zvonok\Phone\Response\{AddCallResponse, CallResultResponse, RegionResponse};
19
20
/**
21
 * Class Client
22
 */
23
class Client
24
{
25
    public const VERSION = '1.1.0';
26
27
    /**
28
     * @var Config
29
     */
30
    private $config;
31
32
    /**
33
     * @var HttpClient
34
     */
35
    private $httpClient;
36
37
    /**
38
     * @var RequestFactoryInterface
39
     */
40
    private $requestFactory;
41
42
    /**
43
     * @var JsonMapper
44
     */
45
    private $jsonMapper;
46
47
    /**
48
     * Client constructor.
49
     *
50
     * @param Config $config
51
     * @param JsonMapper|null $jsonMapper
52
     * @param HttpClient|null $httpClient
53
     * @param RequestFactoryInterface|null $requestFactory
54
     */
55
    public function __construct(
56
        Config $config,
57
        JsonMapper $jsonMapper = null,
58
        HttpClient $httpClient = null,
59
        RequestFactoryInterface $requestFactory = null)
60
    {
61
        $this->config = $config;
62
        $this->jsonMapper = $jsonMapper ?? new JsonMapper();
63
        $this->httpClient = $httpClient ?? HttpClientDiscovery::find();
64
        $this->requestFactory = $requestFactory ?? Psr17FactoryDiscovery::findRequestFactory();
65
    }
66
67
    /**
68
     * @param RequestInterface $request
69
     * @return AddCallResponse|CallResultResponse|RegionResponse
70
     * @throws Exception
71
     * @throws JsonMapper_Exception
72
     */
73
    public function execute(RequestInterface $request)
74
    {
75
        $class = get_class($request);
76
77
        switch($class) {
78
            case AddCallRequest::class:
79
                return $this->addCall($request);
80
            case GetCallByIdRequest::class:
81
                return $this->getCallById($request);
82
            case GetCallByPhoneRequest::class:
83
                return $this->getCallByPhone($request);
84
            case GetRegionByPhoneRequest::class:
85
                return $this->getRegionByPhone($request);
86
            default:
87
                throw new UnknownRequestException($class);
88
        }
89
    }
90
91
    /**
92
     * @param AddCallRequest $request
93
     *
94
     * @return AddCallResponse
95
     *
96
     * @throws Exception
97
     * @throws JsonMapper_Exception
98
     */
99
    public function addCall(AddCallRequest $request): AddCallResponse
100
    {
101
        $request->setPublicKey($this->config->publicKey());
102
103
        $requestBody = $this->doRequest($request);
104
105
        $mapper = new AddCallMapper($this->jsonMapper);
106
107
        return $mapper->map($requestBody);
108
    }
109
110
    /**
111
     * @param GetCallByIdRequest $request
112
     *
113
     * @return CallResultResponse
114
     *
115
     * @throws Exception
116
     * @throws JsonMapper_Exception
117
     */
118
    public function getCallById(GetCallByIdRequest $request): CallResultResponse
119
    {
120
        $request->setPublicKey($this->config->publicKey());
121
122
        $requestBody = $this->doRequest($request);
123
124
        $mapper = new GetCallByIdMapper($this->jsonMapper);
125
126
        return $mapper->map($requestBody);
127
    }
128
    /**
129
     * @param GetCallByPhoneRequest $request
130
     *
131
     * @return CallResultResponse
132
     *
133
     * @throws Exception
134
     * @throws JsonMapper_Exception
135
     */
136
    public function getCallByPhone(GetCallByPhoneRequest $request): CallResultResponse
137
    {
138
        $request->setPublicKey($this->config->publicKey());
139
140
        $requestBody = $this->doRequest($request);
141
142
        $mapper = new GetCallByPhoneMapper($this->jsonMapper);
143
144
        return $mapper->map($requestBody);
145
    }
146
147
    /**
148
     * @param GetRegionByPhoneRequest $request
149
     *
150
     * @return RegionResponse
151
     *
152
     * @throws Exception
153
     * @throws JsonMapper_Exception
154
     */
155
    public function getRegionByPhone(GetRegionByPhoneRequest $request): RegionResponse
156
    {
157
        $requestBody = $this->doRequest($request);
158
159
        $mapper = new GetRegionByPhoneMapper($this->jsonMapper);
160
161
        return $mapper->map($requestBody);
162
    }
163
164
    /**
165
     * @param RequestInterface $request
166
     *
167
     * @return string
168
     *
169
     * @throws Exception
170
     */
171
    private function doRequest(RequestInterface $request): string
172
    {
173
        $apiResponse = $this->httpClient->sendRequest(
174
            $this->requestFactory->createRequest(
175
                'GET',
176
                $this->config->domain() . $request->generateUri()
177
            )->withHeader('user-agent', $this->composeUserAgent())
178
        );
179
180
        $requestBody = $apiResponse->getBody()->getContents();
181
182
        $this->throwExceptionIfError($requestBody);
183
184
        return $requestBody;
185
    }
186
187
    /**
188
     * @return string
189
     */
190
    private function composeUserAgent(): string
191
    {
192
        return 'phrlog/zvonok-client ' . static::VERSION;
193
    }
194
195
    /**
196
     * @param string $requestBody
197
     */
198
    private function throwExceptionIfError(string $requestBody)
199
    {
200
        $body = json_decode($requestBody, true);
201
202
        if (null === $body) {
203
            throw new EmptyResponseException('Ответ API пуст');
204
        }
205
206
        if (isset($body['status']) && $body['status'] === 'error') {
207
            $message = $body['data'] ?? null;
208
            throw new ResponseWithErrorException($message);
209
        }
210
    }
211
}
212