1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* File was created 06.10.2015 06:25 |
4
|
|
|
*/ |
5
|
|
|
|
6
|
|
|
namespace PeekAndPoke\Component\Slumber\Core\LookUp; |
7
|
|
|
|
8
|
|
|
use Doctrine\Common\Cache\Cache; |
9
|
|
|
|
10
|
|
|
/** |
11
|
|
|
* @author Karsten J. Gerber <[email protected]> |
12
|
|
|
*/ |
13
|
|
|
class CachedEntityConfigLookUp extends DelegatingEntityConfigReader |
14
|
|
|
{ |
15
|
|
|
/** @var Cache */ |
16
|
|
|
private $cache; |
17
|
|
|
/** @var string */ |
18
|
|
|
private $prefix; |
19
|
|
|
/** @var bool */ |
20
|
|
|
private $debug; |
21
|
|
|
|
22
|
|
|
/** |
23
|
|
|
* We have another level of caching here |
24
|
|
|
* |
25
|
|
|
* @var array |
26
|
|
|
*/ |
27
|
|
|
private $known = []; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* @param EntityConfigReader $delegate |
31
|
|
|
* @param Cache $cache |
32
|
|
|
* @param string $prefix |
33
|
|
|
* @param bool $debug |
34
|
|
|
*/ |
35
|
1 |
|
public function __construct(EntityConfigReader $delegate, Cache $cache, $prefix = '[Slumber]@', $debug = false) |
36
|
|
|
{ |
37
|
1 |
|
parent::__construct($delegate); |
38
|
|
|
|
39
|
1 |
|
$this->cache = $cache; |
40
|
1 |
|
$this->prefix = $prefix; |
41
|
1 |
|
$this->debug = $debug; |
42
|
1 |
|
} |
43
|
|
|
|
44
|
|
|
/** |
45
|
|
|
* @param \ReflectionClass $cls |
46
|
|
|
* |
47
|
|
|
* @return PropertyMarkedForSlumber[] |
48
|
|
|
*/ |
49
|
1 |
|
public function getEntityConfig(\ReflectionClass $cls) |
50
|
|
|
{ |
51
|
1 |
|
$cacheKey = $this->prefix . $cls->name; |
52
|
|
|
|
53
|
1 |
|
return $this->loadOrCreate( |
54
|
1 |
|
$cacheKey, |
55
|
1 |
|
function () use ($cacheKey, $cls) { |
56
|
1 |
|
return $this->fetchFromCache($cacheKey, $cls); |
57
|
1 |
|
}, |
58
|
1 |
|
function () use ($cls) { |
59
|
1 |
|
return $this->delegate->getEntityConfig($cls); |
60
|
1 |
|
}, |
61
|
1 |
|
$cls |
62
|
|
|
); |
63
|
|
|
} |
64
|
|
|
|
65
|
|
|
/** |
66
|
|
|
* @param string $cacheKey |
67
|
|
|
* @param \Closure $fetcher |
68
|
|
|
* @param \Closure $creator |
69
|
|
|
* @param \ReflectionClass $class |
70
|
|
|
* |
71
|
|
|
* @return mixed |
72
|
|
|
*/ |
73
|
1 |
|
private function loadOrCreate($cacheKey, \Closure $fetcher, \Closure $creator, \ReflectionClass $class) |
74
|
|
|
{ |
75
|
1 |
|
if (isset($this->known[$cacheKey])) { |
76
|
|
|
return $this->known[$cacheKey]; |
77
|
|
|
} |
78
|
|
|
|
79
|
|
|
/** @var EntityConfig $cacheData */ |
80
|
1 |
|
$cacheData = $fetcher(); |
81
|
1 |
|
if (false === $cacheData) { |
82
|
1 |
|
$cacheData = $creator(); |
83
|
1 |
|
$this->saveToCache($cacheKey, $cacheData, $class); |
84
|
|
|
} |
85
|
|
|
|
86
|
1 |
|
return $this->known[$cacheKey] = $cacheData; |
87
|
|
|
} |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* Fetches a value from the cache. |
91
|
|
|
* |
92
|
|
|
* @param string $rawCacheKey The cache key. |
93
|
|
|
* @param \ReflectionClass $class The related class. |
94
|
|
|
* |
95
|
|
|
* @return mixed The cached value or false when the value is not in cache. |
96
|
|
|
*/ |
97
|
1 |
|
private function fetchFromCache($rawCacheKey, \ReflectionClass $class) |
98
|
|
|
{ |
99
|
1 |
|
$cacheKey = $this->prefix . $rawCacheKey; |
100
|
|
|
|
101
|
1 |
|
if (($data = $this->cache->fetch($cacheKey)) !== false) { |
102
|
|
|
/** @noinspection NestedPositiveIfStatementsInspection */ |
103
|
|
|
if (! $this->debug || $this->isCacheFresh($cacheKey, $class)) { |
104
|
|
|
return $data; |
105
|
|
|
} |
106
|
|
|
} |
107
|
|
|
|
108
|
1 |
|
return false; |
109
|
|
|
} |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* Saves a value to the cache. |
113
|
|
|
* |
114
|
|
|
* @param string $rawCacheKey The cache key. |
115
|
|
|
* @param mixed $value The value. |
116
|
|
|
* @param \ReflectionClass $class |
117
|
|
|
*/ |
118
|
1 |
|
private function saveToCache($rawCacheKey, $value, \ReflectionClass $class) |
119
|
|
|
{ |
120
|
1 |
|
$cacheKey = $this->prefix . $rawCacheKey; |
121
|
1 |
|
$this->cache->save($cacheKey, $value); |
122
|
|
|
|
123
|
|
|
// in debug mode record the creation time of the entry |
124
|
1 |
|
if ($this->debug && false !== $filename = $class->getFileName()) { |
125
|
|
|
|
126
|
1 |
|
$this->cache->save('[C]' . $cacheKey, filemtime($filename)); |
127
|
|
|
} |
128
|
1 |
|
} |
129
|
|
|
|
130
|
|
|
/** |
131
|
|
|
* Checks if the cache is fresh. |
132
|
|
|
* |
133
|
|
|
* @param string $cacheKey |
134
|
|
|
* @param \ReflectionClass $class |
135
|
|
|
* |
136
|
|
|
* @return boolean |
137
|
|
|
*/ |
138
|
|
|
private function isCacheFresh($cacheKey, \ReflectionClass $class) |
139
|
|
|
{ |
140
|
|
|
if (false === $filename = $class->getFileName()) { |
141
|
|
|
return true; |
142
|
|
|
} |
143
|
|
|
|
144
|
|
|
// echo $cacheKey . " " . $this->cache->fetch('[C]'.$cacheKey) . " " . filemtime($filename) . " " . ($this->cache->fetch('[C]'.$cacheKey) >= filemtime($filename)) . "\n"; |
|
|
|
|
145
|
|
|
|
146
|
|
|
// When we have the creation time (debug mode) and it is less than the current file time, the cache is also not |
147
|
|
|
// fresh |
148
|
|
|
return $this->cache->fetch('[C]' . $cacheKey) >= filemtime($filename); |
149
|
|
|
} |
150
|
|
|
} |
151
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.