PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.0.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.0.1
5.13.0 5.12.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 / Cache.php
matomo / app / core / Tracker Last commit date
Db 2 years ago Handler 2 years ago Visit 2 years ago Action.php 2 years ago ActionPageview.php 2 years ago Cache.php 2 years ago Db.php 2 years ago Failures.php 2 years ago FingerprintSalt.php 2 years ago GoalManager.php 2 years ago Handler.php 2 years ago IgnoreCookie.php 2 years ago LogTable.php 2 years ago Model.php 2 years ago PageUrl.php 2 years ago Request.php 2 years ago RequestProcessor.php 2 years ago RequestSet.php 2 years ago Response.php 2 years ago ScheduledTasksRunner.php 2 years ago Settings.php 2 years ago TableLogAction.php 2 years ago TrackerCodeGenerator.php 2 years ago TrackerConfig.php 2 years ago Visit.php 2 years ago VisitExcluded.php 2 years ago VisitInterface.php 2 years ago Visitor.php 2 years ago VisitorNotFoundInDb.php 2 years ago VisitorRecognizer.php 2 years ago
Cache.php
271 lines
1 <?php
2
3 /**
4 * Matomo - free/libre analytics platform
5 *
6 * @link https://matomo.org
7 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
8 *
9 */
10 namespace Piwik\Tracker;
11
12 use Piwik\Access;
13 use Piwik\ArchiveProcessor\Rules;
14 use Piwik\Cache as PiwikCache;
15 use Piwik\Config;
16 use Piwik\Container\StaticContainer;
17 use Piwik\Option;
18 use Piwik\Piwik;
19 use Piwik\Tracker;
20 use Piwik\Log\LoggerInterface;
21 /**
22 * Simple cache mechanism used in Tracker to avoid requesting settings from mysql on every request
23 *
24 */
25 class Cache
26 {
27 /**
28 * {@see self::withDelegatedCacheClears()}
29 * @var bool
30 */
31 private static $delegatingCacheClears;
32 /**
33 * {@see self::withDelegatedCacheClears()}
34 * @var array
35 */
36 private static $delegatedClears = [];
37 private static $cacheIdGeneral = 'general';
38 /**
39 * Public for tests only
40 * @var \Matomo\Cache\Lazy
41 */
42 public static $cache;
43 /**
44 * @return \Matomo\Cache\Lazy
45 */
46 private static function getCache()
47 {
48 if (is_null(self::$cache)) {
49 self::$cache = PiwikCache::getLazyCache();
50 }
51 return self::$cache;
52 }
53 private static function getTtl()
54 {
55 return Config::getInstance()->Tracker['tracker_cache_file_ttl'];
56 }
57 /**
58 * Returns array containing data about the website: goals, URLs, etc.
59 *
60 * @param int $idSite
61 * @return array
62 */
63 public static function getCacheWebsiteAttributes($idSite)
64 {
65 if ('all' === $idSite) {
66 return array();
67 }
68 $idSite = (int) $idSite;
69 if ($idSite <= 0) {
70 return array();
71 }
72 $cache = self::getCache();
73 $cacheId = self::getCacheKeyWebsiteAttributes($idSite);
74 $cacheContent = $cache->fetch($cacheId);
75 if (false !== $cacheContent) {
76 return $cacheContent;
77 }
78 return self::updateCacheWebsiteAttributes($idSite);
79 }
80 private static function getCacheKeyWebsiteAttributes($idSite)
81 {
82 return $idSite;
83 }
84 /**
85 * Updates the website specific tracker cache containing data about the website: goals, URLs, etc.
86 *
87 * @param int $idSite
88 *
89 * @return array
90 */
91 public static function updateCacheWebsiteAttributes($idSite)
92 {
93 $cache = self::getCache();
94 $cacheId = self::getCacheKeyWebsiteAttributes($idSite);
95 Tracker::initCorePiwikInTrackerMode();
96 $content = array();
97 Access::doAsSuperUser(function () use(&$content, $idSite) {
98 /**
99 * Triggered to get the attributes of a site entity that might be used by the
100 * Tracker.
101 *
102 * Plugins add new site attributes for use in other tracking events must
103 * use this event to put those attributes in the Tracker Cache.
104 *
105 * **Example**
106 *
107 * public function getSiteAttributes($content, $idSite)
108 * {
109 * $sql = "SELECT info FROM " . Common::prefixTable('myplugin_extra_site_info') . " WHERE idsite = ?";
110 * $content['myplugin_site_data'] = Db::fetchOne($sql, array($idSite));
111 * }
112 *
113 * @param array &$content Array mapping of site attribute names with values.
114 * @param int $idSite The site ID to get attributes for.
115 */
116 Piwik::postEvent('Tracker.Cache.getSiteAttributes', array(&$content, $idSite));
117 $logger = StaticContainer::get(LoggerInterface::class);
118 $logger->debug("Website {$idSite} tracker cache was re-created.");
119 });
120 // if nothing is returned from the plugins, we don't save the content
121 // this is not expected: all websites are expected to have at least one URL
122 if (!empty($content)) {
123 $cache->save($cacheId, $content, self::getTtl());
124 }
125 Tracker::restoreTrackerPlugins();
126 return $content;
127 }
128 /**
129 * Clear general (global) cache
130 */
131 public static function clearCacheGeneral()
132 {
133 if (self::$delegatingCacheClears) {
134 self::$delegatedClears[__FUNCTION__] = [__FUNCTION__, []];
135 return;
136 }
137 self::getCache()->delete(self::$cacheIdGeneral);
138 }
139 /**
140 * Returns contents of general (global) cache.
141 * If the cache file tmp/cache/tracker/general.php does not exist yet, create it
142 *
143 * @return array
144 */
145 public static function getCacheGeneral()
146 {
147 $cache = self::getCache();
148 $cacheContent = $cache->fetch(self::$cacheIdGeneral);
149 if (false !== $cacheContent) {
150 return $cacheContent;
151 }
152 return self::updateGeneralCache();
153 }
154 /**
155 * Updates the contents of the general (global) cache.
156 *
157 * @return array
158 */
159 public static function updateGeneralCache()
160 {
161 Tracker::initCorePiwikInTrackerMode();
162 $cacheContent = array('isBrowserTriggerEnabled' => Rules::isBrowserTriggerEnabled(), 'lastTrackerCronRun' => Option::get('lastTrackerCronRun'));
163 /**
164 * Triggered before the [general tracker cache](/guides/all-about-tracking#the-tracker-cache)
165 * is saved to disk. This event can be used to add extra content to the cache.
166 *
167 * Data that is used during tracking but is expensive to compute/query should be
168 * cached to keep tracking efficient. One example of such data are options
169 * that are stored in the option table. Querying data for each tracking
170 * request means an extra unnecessary database query for each visitor action. Using
171 * a cache solves this problem.
172 *
173 * **Example**
174 *
175 * public function setTrackerCacheGeneral(&$cacheContent)
176 * {
177 * $cacheContent['MyPlugin.myCacheKey'] = Option::get('MyPlugin_myOption');
178 * }
179 *
180 * @param array &$cacheContent Array of cached data. Each piece of data must be
181 * mapped by name.
182 */
183 Piwik::postEvent('Tracker.setTrackerCacheGeneral', array(&$cacheContent));
184 self::setCacheGeneral($cacheContent);
185 $logger = StaticContainer::get(LoggerInterface::class);
186 $logger->debug("General tracker cache was re-created.");
187 Tracker::restoreTrackerPlugins();
188 return $cacheContent;
189 }
190 /**
191 * Store data in general (global cache)
192 *
193 * @param mixed $value
194 * @return bool
195 */
196 public static function setCacheGeneral($value)
197 {
198 $cache = self::getCache();
199 return $cache->save(self::$cacheIdGeneral, $value, self::getTtl());
200 }
201 /**
202 * Regenerate Tracker cache files
203 *
204 * @param array|int $idSites Array of idSites to clear cache for
205 */
206 public static function regenerateCacheWebsiteAttributes($idSites = array())
207 {
208 if (!is_array($idSites)) {
209 $idSites = array($idSites);
210 }
211 foreach ($idSites as $idSite) {
212 self::deleteCacheWebsiteAttributes($idSite);
213 self::getCacheWebsiteAttributes($idSite);
214 }
215 }
216 /**
217 * Delete existing Tracker cache
218 *
219 * @param string $idSite (website ID of the site to clear cache for
220 */
221 public static function deleteCacheWebsiteAttributes($idSite)
222 {
223 if (self::$delegatingCacheClears) {
224 self::$delegatedClears[__FUNCTION__ . $idSite] = [__FUNCTION__, func_get_args()];
225 return;
226 }
227 self::getCache()->delete((int) $idSite);
228 }
229 /**
230 * Deletes all Tracker cache files
231 */
232 public static function deleteTrackerCache()
233 {
234 if (self::$delegatingCacheClears) {
235 self::$delegatedClears[__FUNCTION__] = [__FUNCTION__, []];
236 return;
237 }
238 self::getCache()->flushAll();
239 }
240 /**
241 * Runs `$callback` without clearing any tracker cache, just collecting which delete methods were called.
242 * After `$callback` finishes, we clear caches, but just once per type of delete/clear method collected.
243 *
244 * Use this method if your code will create many cache clears in a short amount of time (eg, if you
245 * are invalidating a lot of archives at once).
246 *
247 * @param $callback
248 */
249 public static function withDelegatedCacheClears($callback)
250 {
251 try {
252 self::$delegatingCacheClears = true;
253 self::$delegatedClears = [];
254 return $callback();
255 } finally {
256 self::$delegatingCacheClears = false;
257 self::callAllDelegatedClears();
258 self::$delegatedClears = [];
259 }
260 }
261 private static function callAllDelegatedClears()
262 {
263 foreach (self::$delegatedClears as list($methodName, $params)) {
264 if (!method_exists(self::class, $methodName)) {
265 continue;
266 }
267 call_user_func_array([self::class, $methodName], $params);
268 }
269 }
270 }
271