Passed
Pull Request — master (#43)
by Paolo
02:28
created

ApiCacheComponent::get()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 8
c 1
b 0
f 1
nc 1
nop 2
dl 0
loc 13
rs 10
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * BEdita, API-first content management framework
6
 * Copyright 2021 Atlas Srl, ChannelWeb Srl, Chialab Srl
7
 *
8
 * This file is part of BEdita: you can redistribute it and/or modify
9
 * it under the terms of the GNU Lesser General Public License as published
10
 * by the Free Software Foundation, either version 3 of the License, or
11
 * (at your option) any later version.
12
 *
13
 * See LICENSE.LGPL or <http://gnu.org/licenses/lgpl-3.0.html> for more details.
14
 */
15
16
namespace BEdita\WebTools\Controller\Component;
17
18
use BEdita\WebTools\ApiClientProvider;
19
use Cake\Cache\Cache;
20
use Cake\Controller\Component;
21
22
/**
23
 * Component to cache some GET API calls.
24
 *
25
 * An index is used in order to refresh this cache with an external script.
26
 */
27
class ApiCacheComponent extends Component
28
{
29
    /**
30
     * Default config for this component.
31
     *
32
     * @var array
33
     */
34
    protected $_defaultConfig = [
35
        'cache' => '_apicache_',
36
    ];
37
38
    /**
39
     * Use 'default' as fallback if no cache configuration is found.
40
     *
41
     * @param array $config The configuration settings provided to this helper.
42
     * @return void
43
     */
44
    public function initialize(array $config): void
45
    {
46
        if (Cache::getConfig($this->getConfig('cache')) === null && !empty($config['cache'])) {
47
            $this->setConfig('cache', $config['cache']);
48
        }
49
    }
50
51
    /**
52
     * Cache key using type and query string
53
     *
54
     * @param string $path API path
55
     * @param array|null $query Optional query string
56
     * @return string
57
     */
58
    public function cacheKey(string $path, ?array $query = null): string
59
    {
60
        $hash = md5(json_encode($query));
61
        $path = str_replace('/', '_', $path);
62
63
        return sprintf('%s_%s', $path, $hash);
64
    }
65
66
    /**
67
     * -
68
     *
69
     * @param string $key Cache Key
70
     * @param array $params Cache params
71
     * @return void
72
     */
73
    protected function updateCacheIndex(string $key, array $params): void
74
    {
75
        $index = (array)Cache::read('index', $this->getConfig('cache'));
76
        if (!empty($index[$key])) {
77
            return;
78
        }
79
        $index[$key] = $params;
80
        Cache::write('index', $index, $this->getConfig('cache'));
81
    }
82
83
    /**
84
     * Cached GET API call
85
     *
86
     * @param string $path Path invoked
87
     * @param array|null $query Optional query string
88
     * @return array
89
     */
90
    public function get(string $path, ?array $query = null): array
91
    {
92
        $key = $this->cacheKey($path, $query);
93
94
        return (array)Cache::remember(
95
            $key,
96
            function () use ($key, $path, $query) {
97
                $response = (array)ApiClientProvider::getApiClient()->get($path, $query);
98
                $this->updateCacheIndex($key, compact('path', 'query'));
99
100
                return $response;
101
            },
102
            $this->getConfig('cache')
103
        );
104
    }
105
}
106