Completed
Push — master ( e31a71...bd9098 )
by Westin
02:03
created

Cache::add()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

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