Completed
Push — master ( 1edf2c...bc33ad )
by Stefano
16s queued 12s
created

ApiCacheComponent::updateCacheIndex()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 2
eloc 5
c 1
b 0
f 1
nc 2
nop 2
dl 0
loc 8
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
        parent::initialize($config);
47
        if (!empty($config['cache'])) {
48
            $this->setConfig('cache', $config['cache']);
49
        }
50
        if (Cache::getConfig($this->getConfig('cache')) === null) {
51
            $this->setConfig('cache', 'default');
52
        }
53
    }
54
55
    /**
56
     * Cache key using type and query string
57
     *
58
     * @param string $path API path
59
     * @param array|null $query Optional query string
60
     * @return string
61
     */
62
    public function cacheKey(string $path, ?array $query = null): string
63
    {
64
        $hash = md5(json_encode($query));
65
        $path = str_replace('/', '_', $path);
66
67
        return sprintf('%s_%s', $path, $hash);
68
    }
69
70
    /**
71
     * -
72
     *
73
     * @param string $key Cache Key
74
     * @param array $params Cache params
75
     * @return void
76
     */
77
    protected function updateCacheIndex(string $key, array $params): void
78
    {
79
        $index = (array)Cache::read('index', $this->getConfig('cache'));
80
        if (!empty($index[$key])) {
81
            return;
82
        }
83
        $index[$key] = $params;
84
        Cache::write('index', $index, $this->getConfig('cache'));
85
    }
86
87
    /**
88
     * Cached GET API call
89
     *
90
     * @param string $path Path invoked
91
     * @param array|null $query Optional query string
92
     * @return array
93
     */
94
    public function get(string $path, ?array $query = null): array
95
    {
96
        $key = $this->cacheKey($path, $query);
97
98
        return (array)Cache::remember(
99
            $key,
100
            function () use ($key, $path, $query) {
101
                $response = (array)ApiClientProvider::getApiClient()->get($path, $query);
102
                $this->updateCacheIndex($key, compact('path', 'query'));
103
104
                return $response;
105
            },
106
            $this->getConfig('cache')
107
        );
108
    }
109
}
110