Completed
Push — master ( bd9098...f08431 )
by Westin
10:15
created

Cache::has()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
ccs 0
cts 1
cp 0
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace WShafer\Expressive\Symfony\Router\Cache;
6
7
use Symfony\Component\Routing\Route;
8
use Symfony\Component\Routing\RouteCollection;
9
use WShafer\Expressive\Symfony\Router\Container\InvalidCacheDirectoryException;
10
use WShafer\Expressive\Symfony\Router\Container\InvalidCacheException;
11
use WShafer\Expressive\Symfony\Router\Container\WriteCacheException;
12
13
/**
14
 * @SuppressWarnings(PHPMD.LongVariable)
15
 */
16
class Cache
17
{
18
    /**
19
     * @const string Configuration key used to enable/disable fastroute caching
20
     */
21
    public const CONFIG_CACHE_ENABLED = 'cache_enabled';
22
23
    /**
24
     * @const string Configuration key used to set the cache file path
25
     */
26
    public const CONFIG_CACHE_FILE = 'cache_file';
27
28
    protected $cacheEnabled = false;
29
30
    protected $cacheFile = null;
31
32
    protected $cache = null;
33
34
    protected $cacheNeedsUpdates = false;
35
36
    public function __construct(array $config = null)
37
    {
38
        $this->cacheEnabled = $config[self::CONFIG_CACHE_ENABLED] ?? false;
39
        $this->cacheFile = $config[self::CONFIG_CACHE_FILE] ?? null;
40
    }
41
42
    public function populateCollectionFromCache(RouteCollection $collection) : RouteCollection
43
    {
44
        if (!$this->cacheEnabled) {
45
            return $collection;
46
        }
47
48
        $routes = $this->fetchCache();
49
50
        foreach ($routes as $name => $route) {
51
            $collection->add($name, $route);
52
        }
53
54
        return $collection;
55
    }
56
57
    public function add(string $name, Route $route): void
58
    {
59
        if (!$this->cacheEnabled) {
60
            return;
61
        }
62
63
        // Lets pre-compile this for caching
64
        $route->compile();
65
        $this->cache[$name] = $route;
66
        $this->cacheNeedsUpdates = true;
67
    }
68
69
    public function has($name)
70
    {
71
        return isset($this->cache[$name]);
72
    }
73
74
    public function writeCache() : bool
75
    {
76
        if (!$this->cacheEnabled
77
            || !$this->cacheNeedsUpdates
78
        ) {
79
            return true;
80
        }
81
82
        $cacheDir = dirname($this->cacheFile);
83
84
        if (!is_dir($cacheDir)) {
85
            throw new InvalidCacheDirectoryException(sprintf(
86
                'The cache directory "%s" does not exist',
87
                $cacheDir
88
            ));
89
        }
90
91
        if (!is_writable($cacheDir)) {
92
            throw new InvalidCacheDirectoryException(sprintf(
93
                'The cache directory "%s" is not writable',
94
                $cacheDir
95
            ));
96
        }
97
98
        $bytes = file_put_contents(
99
            $this->cacheFile,
100
            serialize($this->cache)
101
        );
102
103
        if ($bytes === false) {
104
            throw new WriteCacheException('Unable to write cache file: '.$this->cacheFile);
105
        }
106
107
        return true;
108
    }
109
110
    public function invalidateCacheFile() : void
111
    {
112
        if (!$this->cacheEnabled
113
            || empty($this->cacheFile)
114
            || !is_file($this->cacheFile)
115
        ) {
116
            return;
117
        }
118
119
        unlink($this->cacheFile);
120
    }
121
122
    protected function fetchCache()
123
    {
124
        if (!$this->cacheEnabled
125
            || empty($this->cacheFile)
126
            || !is_file($this->cacheFile)
127
        ) {
128
            return [];
129
        }
130
131
        $this->cache = unserialize(file_get_contents($this->cacheFile));
132
133
        if (empty($this->cache)) {
134
            throw new InvalidCacheException('Unable to load route cache');
135
        }
136
137
        return $this->cache;
138
    }
139
}
140