PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 5.12.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v5.12.1
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 / offline-service-worker.js
matomo / app Last commit date
config 2 weeks ago core 2 weeks ago js 2 weeks ago lang 2 weeks ago libs 2 months ago node_modules 5 months ago plugins 2 weeks ago vendor 2 weeks ago .htaccess 6 years ago AGENTS.md 1 month ago DIObject.php 2 years ago LEGALNOTICE 8 months ago LICENSE 2 years ago LegacyAutoloader.php 2 years ago PRIVACY.md 5 years ago README.md 8 months ago SECURITY.md 2 years ago bootstrap.php 2 months ago console 6 years ago favicon.ico 2 years ago index.php 2 years ago matomo.js 2 weeks ago matomo.php 2 years ago offline-service-worker.js 5 years ago piwik.js 2 weeks ago piwik.php 8 months ago robots.txt 5 years ago
offline-service-worker.js
175 lines
1 var matomoAnalytics = {initialize: function (options) {
2 if ('object' !== typeof options) {
3 options = {};
4 }
5
6 var maxLimitQueue = options.queueLimit || 50;
7 var maxTimeLimit = options.timeLimit || (60 * 60 * 24); // in seconds...
8 // same as configured in in tracking_requests_require_authentication_when_custom_timestamp_newer_than
9
10 function getQueue()
11 {
12 return new Promise(function(resolve, reject) {
13 // do a thing, possibly async, then...
14
15 if (!indexedDB) {
16 reject(new Error('No support for IndexedDB'));
17 return;
18 }
19 var request = indexedDB.open("matomo", 1);
20
21 request.onerror = function() {
22 console.error("Error", request.error);
23 reject(new Error(request.error));
24 };
25 request.onupgradeneeded = function(event) {
26 console.log('onupgradeneeded')
27 var db = event.target.result;
28
29 if (!db.objectStoreNames.contains('requests')) {
30 db.createObjectStore('requests', {autoIncrement : true, keyPath: 'id'});
31 }
32
33 };
34 request.onsuccess = function(event) {
35 var db = event.target.result;
36 let transaction = db.transaction("requests", "readwrite");
37 let requests =transaction.objectStore("requests");
38 resolve(requests);
39
40
41 };
42 });
43 }
44
45 function syncQueue () {
46 // check something in indexdb
47 return getQueue().then(function (queue) {
48 queue.openCursor().onsuccess = function(event) {
49 var cursor = event.target.result;
50 if (cursor && navigator.onLine) {
51 cursor.continue();
52 var queueId = cursor.value.id;
53
54 var secondsQueuedAgo = ((Date.now() - cursor.value.created) / 1000);
55 secondsQueuedAgo = parseInt(secondsQueuedAgo, 10);
56 if (secondsQueuedAgo > maxTimeLimit) {
57 // too old
58 getQueue().then(function (queue) {
59 queue.delete(queueId);
60 });
61 return;
62 }
63
64 console.log("Cursor " + cursor.key);
65
66 var init = {
67 headers: cursor.value.headers,
68 method: cursor.value.method,
69 }
70 if (cursor.value.body) {
71 init.body = cursor.value.body;
72 }
73
74 if (cursor.value.url.includes('?')) {
75 cursor.value.url += '&cdo=' + secondsQueuedAgo;
76 } else if (init.body) {
77 // todo test if this actually works for bulk requests
78 init.body = init.body.replace('&idsite=', '&cdo=' + secondsQueuedAgo + '&idsite=');
79 }
80
81 fetch(cursor.value.url, init).then(function (response) {
82 console.log('server response', response);
83 if (response.status < 400) {
84 getQueue().then(function (queue) {
85 queue.delete(queueId);
86 });
87 }
88 }).catch(function (error) {
89 console.error('Send to Server failed:', error);
90 throw error
91 })
92 }
93 else {
94 console.log("No more entries!");
95 }
96 };
97 });
98 }
99
100 function limitQueueIfNeeded(queue)
101 {
102 var countRequest = queue.count();
103 countRequest.onsuccess = function(event) {
104 if (event.result > maxLimitQueue) {
105 // we delete only one at a time because of concurrency some other process might delete data too
106 queue.openCursor().onsuccess = function(event) {
107 var cursor = event.target.result;
108 if (cursor) {
109 queue.delete(cursor.value.id);
110 limitQueueIfNeeded(queue);
111 }
112 }
113 }
114 }
115 }
116
117 self.addEventListener('sync', function(event) {
118 if (event.tag === 'matomoSync') {
119 syncQueue();
120 }
121 });
122
123 self.addEventListener('fetch', function (event) {
124 let isOnline = navigator.onLine;
125
126 let isTrackingRequest = (event.request.url.includes('/matomo.php')
127 || event.request.url.includes('/piwik.php'));
128 let isTrackerRequest = event.request.url.endsWith('/matomo.js')
129 || event.request.url.endsWith('/piwik.js');
130
131 if (isTrackerRequest) {
132 if (isOnline) {
133 syncQueue();
134 }
135 caches.open('matomo').then(function(cache) {
136 return cache.match(event.request).then(function (response) {
137 return response || fetch(event.request).then(function(response) {
138 cache.put(event.request, response.clone());
139 return response;
140 });
141 });
142 })
143 } else if (isTrackingRequest && isOnline) {
144 syncQueue();
145 event.respondWith(fetch(event.request));
146 } else if (isTrackingRequest && !isOnline) {
147
148 var headers = {};
149 for (const [header, value] of event.request.headers) {
150 headers[header] = value;
151 }
152
153 let requestInfo = {
154 url: event.request.url,
155 referrer : event.request.referrer,
156 method : event.request.method,
157 referrerPolicy : event.request.referrerPolicy,
158 headers : headers,
159 created: Date.now()
160 };
161 event.request.text().then(function (postData) {
162 requestInfo.body = postData;
163
164 getQueue().then(function (queue) {
165 queue.add(requestInfo);
166 limitQueueIfNeeded(queue);
167
168 return queue;
169 });
170 });
171
172 }
173 });
174 }
175 };