PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 4.14.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v4.14.1
5.12.0 5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Tracker / TableLogAction / Cache.php
matomo / app / core / Tracker / TableLogAction Last commit date
Cache.php 3 years ago
Cache.php
165 lines
1 <?php
2 /**
3 * Matomo - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 *
8 */
9
10 namespace Piwik\Tracker\TableLogAction;
11
12 use Piwik\Common;
13 use Piwik\Config;
14 use Psr\Log\LoggerInterface;
15
16 class Cache
17 {
18 /**
19 * @var bool
20 */
21 public $isEnabled;
22
23 /**
24 * @var int cache lifetime in seconds
25 */
26 protected $lifetime;
27
28 /**
29 * @var LoggerInterface
30 */
31 private $logger;
32
33 /**
34 * @var \Matomo\Cache\Lazy
35 */
36 private $cache;
37
38 /**
39 * @var bool
40 */
41 private $limitActionIds;
42
43 public function __construct(LoggerInterface $logger, Config $config, \Matomo\Cache\Lazy $cache)
44 {
45 $this->isEnabled = (bool)$config->General['enable_segments_subquery_cache'];
46 $this->limitActionIds = $config->General['segments_subquery_cache_limit'];
47 $this->lifetime = $config->General['segments_subquery_cache_ttl'];
48 $this->logger = $logger;
49 $this->cache = $cache;
50 }
51
52 /**
53 * @param $valueToMatch
54 * @param $sql
55 * @return array|null
56 * @throws \Exception
57 */
58 public function getIdActionFromSegment($valueToMatch, $sql)
59 {
60 if (!$this->isEnabled) {
61 return array(
62 // mark that the returned value is an sql-expression instead of a literal value
63 'SQL' => $sql,
64 'bind' => $valueToMatch,
65 );
66 }
67
68 $ids = self::getIdsFromCache($valueToMatch, $sql);
69
70 if(is_null($ids)) {
71 // Too Big To Cache, issue SQL as subquery instead
72 return array(
73 'SQL' => $sql,
74 'bind' => $valueToMatch,
75 );
76 }
77
78 if(count($ids) === 0) {
79 return null;
80 }
81
82
83 $sql = Common::getSqlStringFieldsArray($ids);
84 $bind = $ids;
85
86 return array(
87 // mark that the returned value is an sql-expression instead of a literal value
88 'SQL' => $sql,
89 'bind' => $bind,
90 );
91 }
92
93
94 /**
95 * @param $valueToMatch
96 * @param $sql
97 * @return array of IDs, or null if the returnset is too big to cache
98 */
99 private function getIdsFromCache($valueToMatch, $sql)
100 {
101 $cacheKey = $this->getCacheKey($valueToMatch, $sql);
102
103 if ($this->cache->contains($cacheKey) === true) { // TODO: hits
104 $this->logger->debug("Segment subquery cache HIT (for '$valueToMatch' and SQL '$sql)");
105 return $this->cache->fetch($cacheKey);
106 }
107
108 $ids = $this->fetchActionIdsFromDb($valueToMatch, $sql);
109
110 if($this->isTooBigToCache($ids)) {
111 $this->logger->debug("Segment subquery cache SKIPPED SAVE (too many IDs returned by subquery: %s ids)'", array(count($ids)));
112 $this->cache->save($cacheKey, $ids = null, $this->lifetime);
113 return null;
114 }
115
116 $this->cache->save($cacheKey, $ids, $this->lifetime);
117 $this->logger->debug("Segment subquery cache SAVE (for '$valueToMatch' and SQL '$sql')'");
118
119 return $ids;
120 }
121
122 /**
123 * @param $valueToMatch
124 * @param $sql
125 * @return string
126 * @throws
127 */
128 private function getCacheKey($valueToMatch, $sql)
129 {
130 if(is_array($valueToMatch)) {
131 throw new \Exception("value to match is an array: this is not expected");
132 }
133
134 $uniqueKey = md5($sql . $valueToMatch);
135 $cacheKey = 'TableLogAction.getIdActionFromSegment.' . $uniqueKey;
136 return $cacheKey;
137 }
138
139 /**
140 * @param $valueToMatch
141 * @param $sql
142 * @return array|null
143 * @throws \Exception
144 */
145 private function fetchActionIdsFromDb($valueToMatch, $sql)
146 {
147 $idActions = \Piwik\Db::fetchAll($sql, $valueToMatch);
148
149 $ids = array();
150 foreach ($idActions as $idAction) {
151 $ids[] = $idAction['idaction'];
152 }
153
154 return $ids;
155 }
156
157 /**
158 * @param $ids
159 * @return bool
160 */
161 private function isTooBigToCache($ids)
162 {
163 return count($ids) > $this->limitActionIds;
164 }
165 }