1<?php
2
3/*
4 * This file is part of the Assetic package, an OpenSky project.
5 *
6 * (c) 2010-2014 OpenSky Project Inc
7 *
8 * For the full copyright and license information, please view the LICENSE
9 * file that was distributed with this source code.
10 */
11
12namespace Assetic\Cache;
13
14/**
15 * A config cache stores values using var_export() and include.
16 *
17 * @author Kris Wallsmith <kris.wallsmith@gmail.com>
18 */
19class ConfigCache
20{
21    private $dir;
22
23    /**
24     * Construct.
25     *
26     * @param string $dir The cache directory
27     */
28    public function __construct($dir)
29    {
30        $this->dir = $dir;
31    }
32
33    /**
34     * Checks of the cache has a file.
35     *
36     * @param string $resource A cache key
37     *
38     * @return Boolean True if a file exists
39     */
40    public function has($resource)
41    {
42        return file_exists($this->getSourcePath($resource));
43    }
44
45    /**
46     * Writes a value to a file.
47     *
48     * @param string $resource A cache key
49     * @param mixed  $value    A value to cache
50     */
51    public function set($resource, $value)
52    {
53        $path = $this->getSourcePath($resource);
54
55        if (!is_dir($dir = dirname($path)) && false === @mkdir($dir, 0777, true)) {
56            // @codeCoverageIgnoreStart
57            throw new \RuntimeException('Unable to create directory '.$dir);
58            // @codeCoverageIgnoreEnd
59        }
60
61        if (false === @file_put_contents($path, sprintf("<?php\n\n// $resource\nreturn %s;\n", var_export($value, true)))) {
62            // @codeCoverageIgnoreStart
63            throw new \RuntimeException('Unable to write file '.$path);
64            // @codeCoverageIgnoreEnd
65        }
66    }
67
68    /**
69     * Loads and returns the value for the supplied cache key.
70     *
71     * @param string $resource A cache key
72     *
73     * @return mixed The cached value
74     */
75    public function get($resource)
76    {
77        $path = $this->getSourcePath($resource);
78
79        if (!file_exists($path)) {
80            throw new \RuntimeException('There is no cached value for '.$resource);
81        }
82
83        return include $path;
84    }
85
86    /**
87     * Returns a timestamp for when the cache was created.
88     *
89     * @param string $resource A cache key
90     *
91     * @return integer A UNIX timestamp
92     */
93    public function getTimestamp($resource)
94    {
95        $path = $this->getSourcePath($resource);
96
97        if (!file_exists($path)) {
98            throw new \RuntimeException('There is no cached value for '.$resource);
99        }
100
101        if (false === $mtime = @filemtime($path)) {
102            // @codeCoverageIgnoreStart
103            throw new \RuntimeException('Unable to determine file mtime for '.$path);
104            // @codeCoverageIgnoreEnd
105        }
106
107        return $mtime;
108    }
109
110    /**
111     * Returns the path where the file corresponding to the supplied cache key can be included from.
112     *
113     * @param string $resource A cache key
114     *
115     * @return string A file path
116     */
117    private function getSourcePath($resource)
118    {
119        $key = md5($resource);
120
121        return $this->dir.'/'.$key[0].'/'.$key.'.php';
122    }
123}
124