Passed
Pull Request — cache (#765)
by Arnaud
08:40 queued 05:39
created

Cache::getMultiple()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 2
dl 0
loc 3
rs 10
1
<?php
2
/**
3
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Assets;
12
13
use Cecil\Builder;
14
use Cecil\Config;
15
use Cecil\Util;
16
use Exception;
17
use Psr\SimpleCache\CacheInterface;
18
19
class Cache implements CacheInterface
20
{
21
    /** @var Builder */
22
    protected $builder;
23
    /** @var Config */
24
    protected $config;
25
    /** @var string */
26
    protected $pool;
27
    /** @var string */
28
    protected $rootPath;
29
    /** @var string */
30
    protected $cacheDir;
31
32
    /**
33
     * @param Builder $builder
34
     * @param string  $pool
35
     * @param string  $rootPath
36
     */
37
    public function __construct(Builder $builder, string $pool, string $rootPath)
38
    {
39
        $this->builder = $builder;
40
        $this->config = $builder->getConfig();
41
        $this->pool = $pool;
42
        $this->rootPath = $rootPath;
43
        $this->cacheDir = Util::joinFile($this->config->getCachePath(), $pool);
44
    }
45
46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function get($key, $default = null)
50
    {
51
        return file_get_contents($this->getValueFilePathname($key)) ?: $default;
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57
    public function set($key, $value, $ttl = null)
58
    {
59
        if ($ttl !== null) {
60
            throw new Exception(sprintf('%s::%s(%s) not yet implemented.', __CLASS__, __FUNCTION__, 'ttl'));
61
        }
62
63
        try {
64
            Util::getFS()->dumpFile($this->getValueFilePathname($key), $value);
65
            $this->pruneHashFiles($key);
66
            Util::getFS()->mkdir(Util::joinFile($this->cacheDir, 'hash'));
67
            Util::getFS()->touch($this->getHashFilePathname($key, $this->createHash($value)));
68
        } catch (Exception $e) {
69
            $this->builder->getLogger()->warning($e->getMessage());
70
71
            return false;
72
        }
73
74
        return true;
75
    }
76
77
    /**
78
     * {@inheritdoc}
79
     */
80
    public function delete($key)
81
    {
82
        try {
83
            Util::getFS()->remove($this->getValueFilePathname($key));
84
            $this->pruneHashFiles($key);
85
        } catch (Exception $e) {
86
            $this->builder->getLogger()->warning($e->getMessage());
87
88
            return false;
89
        }
90
91
        return true;
92
    }
93
94
    /**
95
     * {@inheritdoc}
96
     */
97
    public function clear()
98
    {
99
        try {
100
            Util::getFS()->remove($this->cacheDir);
101
        } catch (Exception $e) {
102
            $this->builder->getLogger()->warning($e->getMessage());
103
104
            return false;
105
        }
106
107
        return true;
108
    }
109
110
    /**
111
     * {@inheritdoc}
112
     */
113
    public function getMultiple($keys, $default = null)
114
    {
115
        throw new Exception(sprintf('%s::%s not yet implemented.', __CLASS__, __FUNCTION__));
116
    }
117
118
    /**
119
     * {@inheritdoc}
120
     */
121
    public function setMultiple($values, $ttl = null)
122
    {
123
        throw new Exception(sprintf('%s::%s not yet implemented.', __CLASS__, __FUNCTION__));
124
    }
125
126
    /**
127
     * {@inheritdoc}
128
     */
129
    public function deleteMultiple($keys)
130
    {
131
        throw new Exception(sprintf('%s::%s not yet implemented.', __CLASS__, __FUNCTION__));
132
    }
133
134
    /**
135
     * {@inheritdoc}
136
     */
137
    public function has($key)
138
    {
139
        if ($this->config->get('cache.enabled') === false) {
140
            return false;
141
        }
142
143
        if (!Util::getFS()->exists($this->getValueFilePathname($key))) {
144
            return false;
145
        }
146
147
        return true;
148
    }
149
150
    /**
151
     * Creates the hash (MD5) of a value.
152
     *
153
     * @param string $value
154
     *
155
     * @return string
156
     */
157
    public function createHash(string $value): string
158
    {
159
        return hash('md5', $value);
160
    }
161
162
    /**
163
     * Returns value file pathname.
164
     *
165
     * @param string $key
166
     *
167
     * @return string
168
     */
169
    protected function getValueFilePathname(string $key): string
170
    {
171
        return Util::joinFile(
172
            $this->cacheDir,
173
            'files',
174
            $key
175
        );
176
    }
177
178
    /**
179
     * Returns hash file pathname.
180
     *
181
     * @param string $key
182
     * @param string $hash
183
     *
184
     * @return string
185
     */
186
    protected function getHashFilePathname(string $key, string $hash): string
187
    {
188
        return Util::joinFile(
189
            $this->cacheDir,
190
            'hash',
191
            $this->preparesHashFile($key).trim($hash)
192
        );
193
    }
194
195
    /**
196
     * Prepares hash file.
197
     *
198
     * @param string $key
199
     *
200
     * @return string
201
     */
202
    private function preparesHashFile(string $key): string
203
    {
204
        return str_replace(DIRECTORY_SEPARATOR, '-', $key).'_';
205
    }
206
207
    /**
208
     * Removes previous hash files.
209
     *
210
     * @param string $key
211
     *
212
     * @return bool
213
     */
214
    private function pruneHashFiles(string $key): bool
215
    {
216
        try {
217
            $pattern = Util::joinFile($this->cacheDir, 'hash', $this->preparesHashFile($key)).'*';
218
            foreach (glob($pattern) as $filename) {
219
                Util::getFS()->remove($filename);
220
            }
221
        } catch (Exception $e) {
222
            $this->builder->getLogger()->warning($e->getMessage());
223
224
            return false;
225
        }
226
227
        return true;
228
    }
229
}
230