Passed
Push — master ( 45bce2...5a8248 )
by Nikolay
03:20
created

BotApi   A

Complexity

Total Complexity 10

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 96.15%

Importance

Changes 0
Metric Value
wmc 10
eloc 48
dl 0
loc 146
ccs 50
cts 52
cp 0.9615
rs 10
c 0
b 0
f 0

7 Methods

Rating   Name   Duplication   Size   Complexity  
A denormalize() 0 17 1
A __construct() 0 11 1
A getBotKey() 0 3 1
A call() 0 11 3
A getEndPoint() 0 3 1
A encode() 0 25 2
A getMethodName() 0 6 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace TgBotApi\BotApiBase;
6
7
use Symfony\Component\PropertyInfo\Extractor\PhpDocExtractor;
8
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
9
use Symfony\Component\Serializer\Normalizer\ArrayDenormalizer;
10
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
11
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
12
use Symfony\Component\Serializer\Serializer;
13
use TgBotApi\BotApiBase\Exception\NormalizationException;
14
use TgBotApi\BotApiBase\Exception\ResponseException;
15
use TgBotApi\BotApiBase\Normalizer\AnswerInlineQueryNormalizer;
16
use TgBotApi\BotApiBase\Normalizer\InputFileNormalizer;
17
use TgBotApi\BotApiBase\Normalizer\InputMediaNormalizer;
18
use TgBotApi\BotApiBase\Normalizer\JsonSerializableNormalizer;
19
use TgBotApi\BotApiBase\Normalizer\MediaGroupNormalizer;
20
use TgBotApi\BotApiBase\Normalizer\UserProfilePhotosNormalizer;
21
22
/**
23
 * Class BotApi.
24
 */
25
class BotApi implements BotApiInterface
26
{
27
    /**
28
     * @var string
29
     */
30
    private $botKey;
31
32
    /**
33
     * @var ApiClientInterface
34
     */
35
    private $apiClient;
36
37
    /**
38
     * @var string
39
     */
40
    private $endPoint;
41
42
    /**
43
     * BotApi constructor.
44
     *
45
     * @param string             $botKey
46
     * @param ApiClientInterface $apiClient
47
     * @param string             $endPoint
48
     */
49 207
    public function __construct(
50
        string $botKey,
51
        ApiClientInterface $apiClient,
52
        string $endPoint = 'https://api.telegram.org'
53
    ) {
54 207
        $this->botKey = $botKey;
55 207
        $this->apiClient = $apiClient;
56 207
        $this->endPoint = $endPoint;
57
58 207
        $this->apiClient->setBotKey($botKey);
59 207
        $this->apiClient->setEndpoint($endPoint);
60 207
    }
61
62
    /**
63
     * @param $method
64
     * @param string|null $type
65
     *
66
     * @throws ResponseException
67
     * @throws NormalizationException
68
     *
69
     * @return mixed
70
     */
71 198
    public function call($method, string $type = null)
72
    {
73 198
        list($data, $files) = $this->encode($method);
74
75 198
        $json = $this->apiClient->send($this->getMethodName($method), $data, $files);
76
77 198
        if (true !== $json->ok) {
78
            throw new ResponseException($json->description);
79
        }
80
81 198
        return $type ? $this->denormalize($json, $type) : $json->result;
82
    }
83
84
    /**
85
     * @return string
86
     */
87 6
    public function getBotKey(): string
88
    {
89 6
        return $this->botKey;
90
    }
91
92
    /**
93
     * @return string
94
     */
95 6
    public function getEndPoint(): string
96
    {
97 6
        return $this->endPoint;
98
    }
99
100
    /**
101
     * @param $method
102
     *
103
     * @return string
104
     */
105 198
    private function getMethodName($method): string
106
    {
107 198
        return \lcfirst(\substr(
108 198
            \get_class($method),
109 198
            \strrpos(\get_class($method), '\\') + 1,
110 198
            -1 * \strlen('Method')
111
        ));
112
    }
113
114
    /**
115
     * @param $data
116
     * @param $type
117
     *
118
     * @return object|array
119
     */
120 84
    private function denormalize($data, $type)
121
    {
122 84
        $normalizer = new ObjectNormalizer(
123 84
            null,
124 84
            new CamelCaseToSnakeCaseNameConverter(),
125 84
            null,
126 84
            new PhpDocExtractor()
127
        );
128 84
        $arrayNormalizer = new ArrayDenormalizer();
129 84
        $serializer = new Serializer([
130 84
            new UserProfilePhotosNormalizer($normalizer, $arrayNormalizer),
131 84
            new DateTimeNormalizer(),
132 84
            $normalizer,
133 84
            $arrayNormalizer,
134
        ]);
135
136 84
        return $serializer->denormalize($data->result, $type, null, [DateTimeNormalizer::FORMAT_KEY => 'U']);
137
    }
138
139
    /**
140
     * @param $method
141
     *
142
     * @throws NormalizationException
143
     *
144
     * @return array []
145
     */
146 198
    private function encode($method): array
147
    {
148 198
        $files = [];
149
150 198
        $objectNormalizer = new ObjectNormalizer(null, new CamelCaseToSnakeCaseNameConverter());
151 198
        $serializer = new Serializer([
152 198
            new InputFileNormalizer($files),
153 198
            new MediaGroupNormalizer(new InputMediaNormalizer($objectNormalizer, $files), $objectNormalizer),
154 198
            new JsonSerializableNormalizer($objectNormalizer),
155 198
            new AnswerInlineQueryNormalizer($objectNormalizer),
156 198
            new DateTimeNormalizer(),
157 198
            $objectNormalizer,
158
        ]);
159
160 198
        $data = $serializer->normalize(
161 198
            $method,
162 198
            null,
163 198
            ['skip_null_values' => true, DateTimeNormalizer::FORMAT_KEY => 'U']
164
        );
165
166 198
        if (!\is_array($data)) {
167
            throw new NormalizationException('Normalized data must be array');
168
        }
169
170 198
        return [$data, $files];
171
    }
172
}
173