GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

Response::isErrorReceived()   A
last analyzed

Complexity

Conditions 3
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 3
nc 2
nop 0
dl 0
loc 7
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Response class which should be instantiated from received or passed raw JSON string.
5
 *
6
 * @package Teebot (Telegram bot framework)
7
 *
8
 * @author Stanislav Drozdov <[email protected]>
9
 */
10
11
declare(strict_types=1);
12
13
namespace Teebot\Api;
14
15
use Teebot\Api\Exception\{
16
    BuildEntityException,
17
    DecodingDataException
18
};
19
use Teebot\Api\Entity\{
20
    Update,
21
    EntityInterface,
22
    Error
23
};
24
25
class Response
26
{
27
    protected const DEFAULT_ENTITY_TYPE = Update::class;
28
29
    /**
30
     * @var array
31
     */
32
    protected $decodedData = [];
33
34
    /**
35
     * @var int
36
     */
37
    protected $lastUpdate = 0;
38
39
    /**
40
     * @var array
41
     */
42
    protected $entities = [];
43
44
    /**
45
     * @var null|EntityInterface
46
     */
47
    protected $parent;
48
49
    /**
50
     * Creates an instanse of Response class from Raw JSON string and builds corresponding entity
51
     * if passed in entity class. This class should be instantiated for every JSON response from Telegram.
52
     *
53
     * @param string               $rawData     Raw JSON string
54
     * @param null|string          $entityClass Entity class that should be instantiated with decoded JSON data
55
     * @param null|EntityInterface $parent      Parent class should be set as parent for newly instantiated entity
56
     *
57
     * @throws DecodingDataException
58
     */
59
    public function __construct(string $rawData, string $entityClass = null, EntityInterface $parent = null)
60
    {
61
        $this->parent      = $parent;
62
        $this->decodedData = $this->decodeData($rawData);
63
64
        if (empty($this->decodedData)) {
65
            throw new DecodingDataException('Error decoding data!');
66
        }
67
68
        $entityClass    = $this->isErrorReceived() ? Error::class : $entityClass;
69
        $entitiesSource = $this->getRawEntitiesList();
70
        $this->entities = $this->buildEntities($entitiesSource, $entityClass);
71
    }
72
73
    /**
74
     * Returns JSON data decoded as an array.
75
     *
76
     * @param string $rawData JSON string
77
     *
78
     * @return array
79
     */
80
    protected function decodeData(string $rawData): ?array
81
    {
82
        if (!is_string($rawData) || !strlen($rawData)) {
83
            return [];
84
        }
85
86
        try {
87
            $result = json_decode($rawData, true);
88
        } catch (\Exception $e) {
89
            return [];
90
        }
91
92
        return $result;
93
    }
94
95
    /**
96
     * Checks whether an error response from Telegram was received.
97
     *
98
     * @return bool
99
     */
100
    public function isErrorReceived(): bool
101
    {
102
        if ((isset($this->decodedData['ok']) && $this->decodedData['ok'] === true)) {
103
            return false;
104
        }
105
106
        return true;
107
    }
108
109
    /**
110
     * Builds entity objects array from an array of raw entity data. Returns an array with built entities.
111
     *
112
     * @param array       $rawData     Raw entity data array
113
     * @param null|string $entityClass Entity class
114
     *
115
     * @return array
116
     */
117
    protected function buildEntities(array $rawData, string $entityClass = null): array
118
    {
119
        $entities = [];
120
121
        if (empty($rawData)) {
122
            return $entities;
123
        }
124
125
        if (!isset($rawData[0])) {
126
            $rawData = [$rawData];
127
        }
128
129
        foreach ($rawData as $rawItemData) {
130
            if (empty($rawItemData)) {
131
                continue;
132
            }
133
134
            $entity = $this->buildEntity($rawItemData, $entityClass);
135
136
            if ($entity && $entity instanceof Update) {
137
                $this->lastUpdate = (int)$entity->getUpdateId();
138
            }
139
140
            $entities[] = $entity;
141
        }
142
143
        return $entities;
144
    }
145
146
    /**
147
     * Builds desired entity from raw entity's data array. Returns class entity
148
     *
149
     * @param array       $rawItemData Array with raw entity's data
150
     * @param null|string $entityClass Entity class to instantiate, if not passed - default Entity class will be used.
151
     *
152
     * @return EntityInterface
153
     *
154
     * @throws BuildEntityException
155
     */
156
    protected function buildEntity(array $rawItemData, $entityClass = null): EntityInterface
157
    {
158
        $entityClass = $entityClass ? $entityClass : static::DEFAULT_ENTITY_TYPE;
159
160
        if (!class_exists($entityClass)) {
161
            throw new BuildEntityException('Entity "' . $entityClass . '" does not exists or not supported yet!');
162
        }
163
164
        /** @var EntityInterface $entity */
165
        $entity = new $entityClass($rawItemData);
166
        $entity->setParent($this->parent);
167
168
        return $entity;
169
    }
170
171
    /**
172
     * Returns an array with entities
173
     *
174
     * @return array
175
     */
176
    public function getEntities(): array
177
    {
178
        return $this->entities;
179
    }
180
181
    /**
182
     * Returns an entity at certain offset or null if entity does not exists.
183
     *
184
     * @param int $offset Offset
185
     *
186
     * @return EntityInterface|null
187
     */
188
    public function getEntityByOffset(int $offset = 0): ?EntityInterface
189
    {
190
        return is_array($this->entities) && isset($this->entities[$offset]) ? $this->entities[$offset] : null;
191
    }
192
193
    /**
194
     * Returns first entity. More meaningful wrapper for self::getEntityByOffset(0) method.
195
     *
196
     * @return EntityInterface|null
197
     */
198
    public function getFirstEntity(): ?EntityInterface
199
    {
200
        return $this->getEntityByOffset();
201
    }
202
203
    /**
204
     * Returns raw entities list from decoded JSON data array.
205
     *
206
     * @return array
207
     */
208
    protected function getRawEntitiesList(): array
209
    {
210
        if (!is_array($this->decodedData) || empty($this->decodedData)) {
211
            return [];
212
        }
213
214
        if (isset($this->decodedData['result']) && is_array($this->decodedData['result'])) {
215
            return $this->decodedData['result'];
216
        }
217
218
        return $this->decodedData;
219
    }
220
221
    /**
222
     * Returns count of entities.
223
     *
224
     * @return int
225
     */
226
    public function getEntitiesCount(): int
227
    {
228
        return count($this->entities);
229
    }
230
231
    /**
232
     * Returns last update id gathered from the last Update entity.
233
     *
234
     * @return int
235
     */
236
    public function getLastUpdate(): int
237
    {
238
        return $this->lastUpdate;
239
    }
240
241
    /**
242
     * Returns an offset to skip previous updates in the listener mode.
243
     *
244
     * @return int
245
     */
246
    public function getOffset(): int
247
    {
248
        return $this->lastUpdate + 1;
249
    }
250
}
251