Passed
Push — master ( 0061ac...ececf1 )
by Scrutinizer
01:23
created

ConfigProtectedMethods::deleteCacheItem()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * This file is part of the keinos/mastodon-streaming-api-config package.
5
 *
6
 * - Authors, copyright, license, usage and etc.:
7
 *   - See: https://github.com/KEINOS/Mastodon_StreamingAPI_Config/
8
 */
9
10
declare(strict_types=1);
11
12
namespace KEINOS\MSTDN_TOOLS;
13
14
use Symfony\Component\HttpClient\HttpClient           as HttpClient;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\HttpClient\HttpClient was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
15
use Symfony\Component\Cache\Adapter\FilesystemAdapter as FilesystemAdapter;
0 ignored issues
show
Bug introduced by
The type Symfony\Component\Cache\Adapter\FilesystemAdapter was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
16
17
/**
18
 * Parent class of \KEINOS\MSTDN_TOOLS\Config class.
19
 *
20
 * Note that the only public method allowed is "__construct()". Other public
21
 * methods and properties must be defined in "Config" child class.
22
 */
23
class ConfigProtectedMethods extends ConfigStaticMethods
24
{
25
    /** @var string */
26
    protected $access_token = '';
27
    /** @var string */
28
    protected $endpoint_api_instance;
29
    /** @var string */
30
    protected $id_hash_self;
31
    /** @var array<mixed,mixed> */
32
    protected $info_server;
33
    /** @var int */
34
    protected $ttl_cache;
35
    /** @var bool */
36
    protected $use_cache = true;
37
    /** @var string */
38
    protected $url_host;
39
    /** @var string */
40
    protected $url_api_instance;
41
42
    /**
43
     * {@inheritdoc}
44
     *
45
     * @param  array<string,string> $settings
46
     * @return void
47
     */
48
    public function __construct(array $settings)
49
    {
50
        $this->setIdHashSelf();
51
        $this->setEndpointApiInstance($settings);
52
        $this->setTtlCache($settings);
53
        $this->setFlagUseCache($settings);
54
        $this->setUrlHost($settings);
55
        $this->setToken($settings);
56
        $this->setUrlApiInstance($settings);
57
        $this->setServerInfo();
58
    }
59
60
    /**
61
     * Clears all the caches.
62
     *
63
     * @return void
64
     * @suppress PhanUndeclaredClassMethod
65
    */
66
    protected function clearCaches(): void
67
    {
68
        $cache_namespace = $this->getIdHashSelf();
69
        $cache_lifetime  = $this->getTtlCache();
70
71
        $cache_pool = new FilesystemAdapter($cache_namespace, $cache_lifetime);
72
        $cache_pool->clear();
73
    }
74
75
    /**
76
     * Delete cache
77
     *
78
     * @param  string $key
79
     * @return bool
80
     * @suppress PhanUndeclaredClassMethod
81
     */
82
    protected function deleteCacheItem(string $key): bool
83
    {
84
        $cache_namespace = $this->getIdHashSelf();
85
        $cache_lifetime  = $this->getTtlCache();
86
87
        $cache_pool = new FilesystemAdapter($cache_namespace, $cache_lifetime);
88
89
        return $cache_pool->deleteItem($key);
90
    }
91
92
    protected function getAccessToken(): string
93
    {
94
        return $this->access_token;
95
    }
96
97
    /**
98
     * @param string $url_api
99
     * @return array<mixed,mixed>
100
     * @throws \Exception
101
     * @suppress PhanUndeclaredClassMethod
102
     */
103
    protected function getContentsAsArray(string $url_api): array
104
    {
105
        try {
106
            $client_http = HttpClient::create();
107
            $response = $client_http->request('GET', $url_api);
108
            // Get contents as array
109
            return $response->toArray();
110
        } catch (\Exception $e) {
111
            $msg = 'Error while setting server info.' . PHP_EOL
112
                 . '- Error details: ' . $e->getMessage() . PHP_EOL;
113
            throw new \Exception($msg);
114
        }
115
    }
116
117
    /**
118
     * Get value from cache.
119
     *
120
     * @param  string $key
121
     * @return null|mixed
122
     * @suppress PhanUndeclaredClassMethod
123
     */
124
    protected function getCache(string $key)
125
    {
126
        $cache_namespace = $this->getIdHashSelf();
127
        $cache_lifetime  = $this->getTtlCache();
128
129
        $cache_pool = new FilesystemAdapter($cache_namespace, $cache_lifetime);
130
        $cache_item = $cache_pool->getItem($key);
131
132
        if (! $cache_item->isHit()) {
133
            return null;
134
        }
135
        return $cache_item->get();
136
    }
137
138
    protected function getEndpointApiInstance(): string
139
    {
140
        return $this->endpoint_api_instance;
141
    }
142
143
    protected function getFlagUseCache(): bool
144
    {
145
        return $this->use_cache;
146
    }
147
148
    protected function getIdHashSelf(): string
149
    {
150
        return $this->id_hash_self;
151
    }
152
153
    protected function getTtlCache(): int
154
    {
155
        return $this->ttl_cache;
156
    }
157
158
    protected function getUrlApiInstance(): string
159
    {
160
        return $this->url_api_instance;
161
    }
162
163
    protected function getUrlHost(): string
164
    {
165
        return $this->url_host;
166
    }
167
168
    /**
169
     * setCache
170
     *
171
     * @param  string $key
172
     * @param  mixed $value
173
     * @return void
174
     * @suppress PhanUndeclaredClassMethod
175
     */
176
    protected function setCache(string $key, $value): void
177
    {
178
        $cache_namespace = $this->getIdHashSelf();
179
        $cache_lifetime  = $this->getTtlCache();
180
181
        $cache_pool = new FilesystemAdapter($cache_namespace, $cache_lifetime);
182
        $cache_item = $cache_pool->getItem($key);
183
184
        $cache_item->set($value);
185
        $cache_pool->save($cache_item);
186
    }
187
188
    /**
189
     * setEndpointApiInstance
190
     *
191
     * @param  array<string,string> $settings
192
     * @return void
193
     */
194
    protected function setEndpointApiInstance(array $settings)
195
    {
196
        $path = self::ENDPOINT_API_INSTANCE;
197
        if (isset($settings['endpoint_api_instance'])) {
198
            $path = $settings['endpoint_api_instance'];
199
        }
200
        $this->endpoint_api_instance = $path;
201
    }
202
203
    /**
204
     * @param  array<string,string> $settings
205
     * @return void
206
     */
207
    protected function setFlagUseCache(array $settings): void
208
    {
209
        if (isset($settings['use_cache'])) {
210
            $this->use_cache = ($settings['use_cache'] === "true");
211
        }
212
    }
213
214
    protected function setIdHashSelf(): void
215
    {
216
        $this->id_hash_self = self::CACHE_PREFIX . strval(hash_file('md5', __FILE__));
217
    }
218
219
    protected function setServerInfo(): void
220
    {
221
        $info = null;
222
        if ($this->getFlagUseCache()) {
223
            $info = $this->getCache('info_server');
224
        } else {
225
            $this->clearCaches();
226
        }
227
228
        if (null === $info) {
229
            $url_api = $this->getUrlApiInstance();
230
            $info = $this->getContentsAsArray($url_api);
231
            // Check if must keys are set
232
            if (! isset($info['urls']['streaming_api'])) {
233
                throw new \Exception('The server did NOT return with "streaming_api" key.');
234
            }
235
        }
236
        // Set/update cache
237
        $this->setCache('info_server', $info);
238
        // Set property
239
        $this->info_server = $info;
240
    }
241
242
    /**
243
     * @param  array<string,string> $settings
244
     * @return void
245
     * @throws \Exception            If the token is in bad format.
246
     */
247
    protected function setToken(array $settings): void
248
    {
249
        if (! isset($settings['access_token'])) {
250
            return;
251
        }
252
253
        $access_token = $settings['access_token'];
254
255
        if (empty(trim($access_token))) {
256
            return;
257
        }
258
259
        if (! self::isAlphaNumeric($access_token)) {
260
            $msg = 'Invalid access token. Should be alpha numeric.';
261
            throw new \Exception($msg);
262
        }
263
264
        // Mastodon's token is 64 byte in length
265
        if (64 !== strlen($access_token)) {
266
            $msg = 'Invalid access token. Should be 64 chars in length.';
267
            throw new \Exception($msg);
268
        }
269
270
        // Set property
271
        $this->access_token = $access_token;
272
    }
273
274
    /**
275
     * @param  array<string,string> $settings
276
     * @return void
277
     */
278
    protected function setTtlCache(array $settings): void
279
    {
280
        $ttl = self::CACHE_TTL_DEFAULT;
281
        if (isset($settings['ttl_cache'])) {
282
            $ttl = $settings['ttl_cache'];
283
        }
284
        $this->ttl_cache = intval($ttl);
285
    }
286
287
    /**
288
     * @param  array<string,string> $settings
289
     * @return void
290
     */
291
    protected function setUrlApiInstance(array $settings): void
292
    {
293
        $endpoint_api_instance = $this->getEndpointApiInstance();
294
        $url_host = $this->getUrlHost();
295
296
        if (isset($settings['endpoint_api_instance'])) {
297
            $endpoint_api_instance = $settings['endpoint_api_instance'];
298
            $this->endpoint_api_instance = $endpoint_api_instance;
299
        }
300
301
        $this->url_api_instance = rtrim($url_host, '/') . $endpoint_api_instance;
302
    }
303
304
    /**
305
     * @param  array<string,string> $settings
306
     * @return void
307
     * @throws \Exception
308
     *   If the server isn't available.
309
     */
310
    protected function setUrlHost(array $settings): void
311
    {
312
        try {
313
            if (! isset($settings['url_host'])) {
314
                $msg = 'Must key "url_host" is missing in the settings array.';
315
                throw new \Exception($msg);
316
            }
317
318
            $url_host = $settings['url_host'];
319
320
            if (self::isUrlProtocolHttp($url_host)) {
321
                $msg = 'Not in "https:" protocol. We do not allow "http:" protocol.';
322
                throw new \Exception($msg);
323
            }
324
325
            /** @phan-suppress-next-line PhanUndeclaredClassMethod */
326
            $client_http = HttpClient::create();
327
328
            $response = $client_http->request('HEAD', $url_host);
329
            if (200 !== $response->getStatusCode()) {
330
                throw new \Exception('The server did not return 200 status.');
331
            }
332
            // Set property
333
            $this->url_host = $url_host;
334
        } catch (\Exception $e) {
335
            $msg = 'Error while setting server host URL.' . PHP_EOL
336
                 . '- Error details: ' . $e->getMessage() . PHP_EOL;
337
            throw new \Exception($msg);
338
        }
339
    }
340
}
341