1
|
|
|
<?php |
2
|
|
|
/** |
3
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
4
|
|
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
5
|
|
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
6
|
|
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
7
|
|
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
8
|
|
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
9
|
|
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
10
|
|
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
11
|
|
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
12
|
|
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
13
|
|
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
14
|
|
|
* |
15
|
|
|
* This software consists of voluntary contributions made by many individuals |
16
|
|
|
* and is licensed under the MIT license. |
17
|
|
|
* |
18
|
|
|
* CacheCollector.php |
19
|
|
|
* @data: 2017-02-08 21:58 |
20
|
|
|
*/ |
21
|
|
|
|
22
|
|
|
namespace DoctrineCacheToolbar\Collector; |
23
|
|
|
|
24
|
|
|
use Doctrine\ORM\EntityManager; |
25
|
|
|
use Zend\Mvc\MvcEvent; |
26
|
|
|
use ZendDeveloperTools\Collector\AbstractCollector; |
27
|
|
|
use ZendDeveloperTools\Collector\AutoHideInterface; |
28
|
|
|
|
29
|
|
|
/** |
30
|
|
|
* Class CacheCollector |
31
|
|
|
* @package DoctrineCacheToolbar\Collector |
32
|
|
|
* @author: Szymon Michałowski <[email protected]> |
33
|
|
|
*/ |
34
|
|
|
class CacheCollector extends AbstractCollector implements AutoHideInterface |
35
|
|
|
{ |
36
|
|
|
/** |
37
|
|
|
* @var string |
38
|
|
|
*/ |
39
|
|
|
protected $name = 'cache.toolbar'; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* @var int |
43
|
|
|
*/ |
44
|
|
|
protected $priority = 15; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* @var EntityManager |
48
|
|
|
*/ |
49
|
|
|
protected $entityManager; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* @param MvcEvent $mvcEvent |
53
|
|
|
* @return array |
54
|
|
|
*/ |
55
|
1 |
|
public function collect(MvcEvent $mvcEvent) |
56
|
|
|
{ |
57
|
1 |
|
if (!isset($this->data)) { |
58
|
1 |
|
return $this->data = []; |
59
|
|
|
} |
60
|
1 |
|
} |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* {@inheritdoc} |
64
|
|
|
* @return bool |
65
|
|
|
*/ |
66
|
1 |
|
public function canHide() |
67
|
|
|
{ |
68
|
1 |
|
if (!$this->getEntityManager()) { |
69
|
1 |
|
return true; |
70
|
|
|
} |
71
|
|
|
|
72
|
1 |
|
$isCacheEnabled = $this->getEntityManager() |
73
|
1 |
|
->getConfiguration() |
74
|
1 |
|
->isSecondLevelCacheEnabled(); |
75
|
|
|
|
76
|
1 |
|
if (!$isCacheEnabled) { |
77
|
1 |
|
return true; |
78
|
|
|
} |
79
|
|
|
|
80
|
1 |
|
return false; |
81
|
|
|
} |
82
|
|
|
|
83
|
|
|
/** |
84
|
|
|
* Get cache stats |
85
|
|
|
* |
86
|
|
|
* @return array |
87
|
|
|
*/ |
88
|
4 |
|
public function getCacheStats() |
89
|
|
|
{ |
90
|
4 |
|
if (!$this->getEntityManager()) { |
91
|
1 |
|
throw new \LogicException('Entity Manager must be set.'); |
92
|
|
|
} |
93
|
|
|
|
94
|
3 |
|
$config = $this->getEntityManager()->getConfiguration(); |
95
|
|
|
|
96
|
3 |
|
if (!$config->isSecondLevelCacheEnabled()) { |
97
|
1 |
|
return $this->data; |
98
|
|
|
} |
99
|
|
|
|
100
|
2 |
|
$logger = $config->getSecondLevelCacheConfiguration() |
101
|
2 |
|
->getCacheLogger(); |
102
|
|
|
|
103
|
2 |
|
if (null === $logger) { |
104
|
1 |
|
throw new \LogicException('Cache logger must be set.'); |
105
|
|
|
} |
106
|
|
|
|
107
|
|
|
$info = [ |
108
|
|
|
'info' => [ |
109
|
1 |
|
'metadata_adapter' => is_object($config->getMetadataCacheImpl()) |
110
|
1 |
|
? get_class($config->getMetadataCacheImpl()) |
111
|
1 |
|
: 'NA', |
112
|
1 |
|
'query_adapter' => is_object($config->getQueryCacheImpl()) |
113
|
1 |
|
? get_class($config->getQueryCacheImpl()) |
114
|
1 |
|
: 'NA', |
115
|
1 |
|
'result_adapter' => is_object($config->getResultCacheImpl()) |
116
|
1 |
|
? get_class($config->getResultCacheImpl()) |
117
|
1 |
|
: 'NA', |
118
|
1 |
|
'hydration_adapter' => is_object($config->getHydrationCacheImpl()) |
119
|
1 |
|
? get_class($config->getHydrationCacheImpl()) |
120
|
1 |
|
: 'NA', |
121
|
|
|
] |
122
|
1 |
|
]; |
123
|
|
|
$total = [ |
124
|
|
|
'total' => [ |
125
|
1 |
|
'put' => $logger->getPutCount(), |
126
|
1 |
|
'hit' => $logger->getHitCount(), |
127
|
1 |
|
'miss' => $logger->getMissCount(), |
128
|
|
|
] |
129
|
1 |
|
]; |
130
|
|
|
$regions = [ |
131
|
|
|
'regions' => [ |
132
|
1 |
|
'put' => $logger->getRegionsPut() ?: ['None' => null], |
133
|
1 |
|
'hit' => $logger->getRegionsHit() ?: ['None' => null], |
134
|
1 |
|
'miss' => $logger->getRegionsMiss() ?: ['None' => null], |
135
|
|
|
] |
136
|
1 |
|
]; |
137
|
|
|
|
138
|
1 |
|
$this->data = array_merge($info, $total, $regions); |
139
|
1 |
|
return $this->data; |
140
|
|
|
} |
141
|
|
|
|
142
|
|
|
/** |
143
|
|
|
* @return string |
144
|
|
|
*/ |
145
|
1 |
|
public function getName() |
146
|
|
|
{ |
147
|
1 |
|
return $this->name; |
148
|
|
|
} |
149
|
|
|
|
150
|
|
|
/** |
151
|
|
|
* @return string |
152
|
|
|
*/ |
153
|
1 |
|
public function getPriority() |
154
|
|
|
{ |
155
|
1 |
|
return $this->priority; |
156
|
|
|
} |
157
|
|
|
|
158
|
|
|
/** |
159
|
|
|
* @return EntityManager |
160
|
|
|
*/ |
161
|
1 |
|
public function getEntityManager() |
162
|
|
|
{ |
163
|
1 |
|
return $this->entityManager; |
164
|
|
|
} |
165
|
|
|
|
166
|
|
|
/** |
167
|
|
|
* @param EntityManager $entityManager |
168
|
|
|
*/ |
169
|
1 |
|
public function setEntityManager(EntityManager $entityManager) |
|
|
|
|
170
|
|
|
{ |
171
|
1 |
|
$this->entityManager = $entityManager; |
172
|
|
|
} |
173
|
|
|
} |
The
EntityManager
might become unusable for example if a transaction is rolled back and it gets closed. Let’s assume that somewhere in your application, or in a third-party library, there is code such as the following:If that code throws an exception and the
EntityManager
is closed. Any other code which depends on the same instance of theEntityManager
during this request will fail.On the other hand, if you instead inject the
ManagerRegistry
, thegetManager()
method guarantees that you will always get a usable manager instance.