Passed
Push — master ( b74a1f...762e12 )
by MoshiMoshi
03:10
created

ConfigCache::findRestorableCache()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 0
crap 2
1
<?php
2
3
/*
4
 * This file is part of the ConfigCacheBundle package.
5
 *
6
 * Copyright (c) 2015-2016 Yahoo Japan Corporation
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11
12
namespace YahooJapan\ConfigCacheBundle\ConfigCache;
13
14
use Doctrine\Common\Cache\Cache;
15
use Symfony\Component\Config\Loader\LoaderInterface;
16
use Symfony\Component\Config\Definition\ArrayNode;
17
use Symfony\Component\Config\Definition\ConfigurationInterface;
18
use YahooJapan\ConfigCacheBundle\ConfigCache\Definition\Processor;
19
use YahooJapan\ConfigCacheBundle\ConfigCache\Resource\FileResource;
20
use YahooJapan\ConfigCacheBundle\ConfigCache\Util\ArrayAccessInterface;
21
22
/**
23
 * ConfigCache manages user-defined configuration files.
24
 */
25
class ConfigCache
26
{
27
    const DEFAULT_ID       = 'cache';
28
    const TAG_CACHE_WARMER = 'config_cache.warmer';
29
30
    protected $cache;
31
    protected $loader;
32
    protected $config = array();
33
    protected $arrayAccess;
34
    protected $configuration;
35
    protected $resources = array();
36
    // doctrine cache ID
37
    protected $id;
38
    protected $strict = true;
39
40
    /**
41
     * Constructor.
42
     *
43
     * @param Cache           $cache
44
     * @param LoaderInterface $loader
45
     * @param array           $config
46
     */
47 12
    public function __construct(Cache $cache, LoaderInterface $loader, array $config = array())
48
    {
49 12
        $this->cache  = $cache;
50 12
        $this->loader = $loader;
51 12
        $this->config = $config;
52 12
    }
53
54
    /**
55
     * Sets a loader.
56
     *
57
     * @param LoaderInterface $loader
58
     *
59
     * @return ConfigCache
60
     */
61 15
    public function setLoader(LoaderInterface $loader)
62
    {
63 15
        $this->loader = $loader;
64
65 15
        return $this;
66
    }
67
68
    /**
69
     * Sets a ArrayAccess to find array value using dotted key.
70
     *
71
     * @param ArrayAccessInterface $arrayAccess
72
     *
73
     * @return ConfigCache
74
     */
75 14
    public function setArrayAccess(ArrayAccessInterface $arrayAccess)
76
    {
77 14
        $this->arrayAccess = $arrayAccess;
78
79 14
        return $this;
80
    }
81
82
    /**
83
     * Adds a resource.
84
     *
85
     * @param string                      $resource
86
     * @param ConfigurationInterface|null $configuration
87
     *
88
     * @return ConfigCache
89
     */
90 40
    public function addResource($resource, ConfigurationInterface $configuration = null)
91
    {
92 40
        $this->resources[] = new FileResource($resource, $configuration);
93
94 40
        return $this;
95
    }
96
97
    /**
98
     * Sets a configuration.
99
     *
100
     * @param ConfigurationInterface $configuration
101
     *
102
     * @return ConfigCache
103
     */
104 11
    public function setConfiguration(ConfigurationInterface $configuration)
105
    {
106 11
        $this->configuration = $configuration;
107
108 11
        return $this;
109
    }
110
111
    /**
112
     * Sets a doctrine cache ID (only once).
113
     *
114
     * @param string $id
115
     *
116
     * @return ConfigCache
117
     *
118
     * @throws \RuntimeException
119
     */
120 11
    public function setId($id)
121
    {
122 11
        if (!is_null($this->id)) {
123 1
            throw new \RuntimeException('The key must not be set if already set.');
124
        }
125
126 11
        $this->id = $id;
127
128 11
        return $this;
129
    }
130
131
    /**
132
     * Sets a strict mode.
133
     *
134
     * @param bool $strict
135
     *
136
     * @return ConfigCache
137
     */
138 12
    public function setStrict($strict)
139
    {
140 12
        $this->strict = $strict;
141
142 12
        return $this;
143
    }
144
145
    /**
146
     * Finds cached array.
147
     *
148
     * @param string $key
149
     * @param mixed  $default
150
     *
151
     * @return array
152
     */
153 1
    public function find($key, $default = array())
154
    {
155 1
        return $this->findInternal($this->findAll(), $key, $default);
156
    }
157
158
    /**
159
     * Finds All cached array.
160
     *
161
     * @return array
162
     */
163 11
    public function findAll()
164
    {
165 11
        $data = $this->cache->fetch($this->findId());
166 11
        if (!$data) {
167 10
            $data = $this->createInternal();
168 10
        }
169
170 11
        return $data;
171
    }
172
173
    /**
174
     * Creates PHP cache file.
175
     */
176 4
    public function create()
177
    {
178 4
        if (!$this->cache->contains($this->findId())) {
179 3
            $this->createInternal();
180 3
        }
181 4
    }
182
183
    /**
184
     * Saves PHP cache file to the temporary directory.
185
     *
186
     * @throws \RuntimeException
187
     */
188 2
    public function save()
189
    {
190 2
        $this->findRestorableCache()->saveToTemp($this->findId());
191 2
    }
192
193
    /**
194
     * Restores PHP cache file to the cache directory.
195
     *
196
     * @throws \RuntimeException
197
     */
198 1
    public function restore()
199
    {
200 1
        $this->findRestorableCache()->restore($this->findId());
201 1
    }
202
203
    /**
204
     * Creates PHP cache file internal processing.
205
     *
206
     * @return array
207
     */
208 15
    protected function createInternal()
209
    {
210 15
        $data = $this->load();
211 15
        $this->cache->save($this->findId(), $data);
212
213 15
        return $data;
214
    }
215
216
    /**
217
     * Finds a doctrine cache ID.
218
     *
219
     * @return string
220
     */
221 26
    protected function findId()
222
    {
223 26
        return $this->id ?: static::DEFAULT_ID;
224
    }
225
226
    /**
227
     * Whether the mode is strict or not.
228
     *
229
     * @return bool
230
     */
231 28
    protected function isStrict()
232
    {
233 28
        return $this->strict;
234
    }
235
236
    /**
237
     * Finds cached array internal processing.
238
     *
239
     * @param array  $data
240
     * @param string $key
241
     * @param mixed  $default
242
     *
243
     * @return array
244
     */
245 7
    protected function findInternal(array $data, $key, $default = array())
246
    {
247 7
        if (is_null($this->arrayAccess)) {
248 3
            $result = isset($data[$key]) ? $data[$key] : $default;
249 3
        } else {
250 4
            $result = $this->arrayAccess->replace($data)->get($key, $default);
251
        }
252
253 7
        return $result;
254
    }
255
256
    /**
257
     * Loads config files.
258
     *
259
     * @return array
260
     */
261 28
    protected function load()
262
    {
263 28
        if ($this->resources === array()) {
264 1
            throw new \Exception('No added resources.');
265
        }
266 27
        if (!$this->isStrict() && count($this->resources) === 1) {
267 2
            return $this->loadOne();
268
        }
269
270 25
        $loaded     = $this->config;
271 25
        $masterNode = $this->createMasterNode();
272
273 25
        foreach ($this->resources as $file) {
274 25
            list($loaded, $masterNode) = $this->processConfiguration(
275 25
                $loaded,
276 25
                $this->loader->load($file->getResource()),
277 25
                $file->getConfiguration(),
278
                $masterNode
279 25
            );
280 25
        }
281
282 25
        return $loaded;
283
    }
284
285
    /**
286
     * Loads a config file which is not strict mode.
287
     *
288
     * @return array
289
     */
290 3
    protected function loadOne()
291
    {
292 3
        return $this->loader->load($this->resources[0]->getResource());
293
    }
294
295
    /**
296
     * Processes an array of configurations.
297
     *
298
     * @param array                  $validated     validated array
299
     * @param array                  $validating    validating array
300
     * @param ConfigurationInterface $configuration configuration
301
     * @param ArrayNode              $masterNode    master node
302
     *
303
     * @return array list of (array, ArrayNode)
304
     */
305 28
    protected function processConfiguration(
306
        array $validated,
307
        array $validating,
308
        ConfigurationInterface $configuration,
309
        ArrayNode $masterNode = null
310
    ) {
311 28
        $processor = new Processor();
312
313 28
        return $processor->processConfiguration(
314 28
            $validated,
315 28
            $validating,
316 28
            $configuration,
317
            $masterNode
318 28
        );
319
    }
320
321
    /**
322
     * Creates master node.
323
     *
324
     * @return ArrayNode
325
     */
326 27
    protected function createMasterNode()
327
    {
328 27
        if (is_null($this->configuration)) {
329 24
            return $this->configuration;
330
        } else {
331 3
            return $this->configuration->getConfigTreeBuilder()->buildTree();
332
        }
333
    }
334
335
    /**
336
     * Finds a restorable cache object.
337
     *
338
     * @return RestorablePhpFileCache
339
     *
340
     * @throws \RuntimeException
341
     */
342 6
    protected function findRestorableCache()
343
    {
344 6
        if (!($this->cache instanceof RestorablePhpFileCache)) {
345 1
            throw new \RuntimeException('RestorablePhpFileCache should be set to use save/restore method.');
346
        }
347
348 5
        return $this->cache;
349
    }
350
}
351