Matomo Analytics – Ethical Stats. Powerful Insights. - Version 1.1.0

Version Description

Download this release

Release Info

Developer matomoteam
Plugin Icon 128x128 Matomo Analytics – Ethical Stats. Powerful Insights.
Version 1.1.0
Comparing to
See all releases

Code changes from version 1.0.6 to 1.1.0

Files changed (46) hide show
  1. app/core/CliMulti/RequestCommand.php +4 -0
  2. app/core/Db/Adapter.php +1 -1
  3. app/core/Theme.php +1 -1
  4. app/core/Tracker/Request.php +4 -1
  5. app/core/Updates/3.13.6-b1.php +38 -0
  6. app/core/Version.php +1 -1
  7. app/js/piwik.min.js +18 -17
  8. app/matomo.js +18 -17
  9. app/piwik.js +18 -17
  10. app/plugins/CoreAdminHome/Tasks.php +5 -0
  11. app/plugins/GeoIp2/Commands/ConvertRegionCodesToIso.php +0 -124
  12. assets/css/admin-style.css +5 -23
  13. classes/WpMatomo.php +4 -1
  14. classes/WpMatomo/Admin/AdminSettings.php +1 -1
  15. classes/WpMatomo/Admin/AdvancedSettings.php +19 -2
  16. classes/WpMatomo/Admin/Dashboard.php +129 -0
  17. classes/WpMatomo/Admin/GeolocationSettings.php +1 -1
  18. classes/WpMatomo/Admin/Menu.php +7 -6
  19. classes/WpMatomo/Admin/Summary.php +30 -0
  20. classes/WpMatomo/Admin/SystemReport.php +78 -1
  21. classes/WpMatomo/Admin/views/access.php +5 -0
  22. classes/WpMatomo/Admin/views/advanced_settings.php +14 -0
  23. classes/WpMatomo/Admin/views/geolocation_settings.php +7 -2
  24. classes/WpMatomo/Admin/views/info_multisite.php +3 -1
  25. classes/WpMatomo/Admin/views/marketplace.php +190 -189
  26. classes/WpMatomo/Admin/views/summary.php +29 -1
  27. classes/WpMatomo/Admin/views/tracking.php +13 -7
  28. classes/WpMatomo/Compatibility.php +0 -3
  29. classes/WpMatomo/Db/Settings.php +66 -0
  30. classes/WpMatomo/Installer.php +5 -1
  31. classes/WpMatomo/OptOut.php +0 -2
  32. classes/WpMatomo/Referral.php +0 -3
  33. classes/WpMatomo/Report/Metadata.php +3 -0
  34. classes/WpMatomo/Report/Renderer.php +47 -4
  35. classes/WpMatomo/Report/views/table_map_no_dimension.php +38 -0
  36. classes/WpMatomo/Settings.php +11 -0
  37. classes/WpMatomo/Uninstaller.php +18 -67
  38. classes/WpMatomo/Updater.php +3 -1
  39. classes/WpMatomo/User/Sync.php +29 -2
  40. config/config.php +1 -0
  41. matomo.php +1 -1
  42. plugins/WordPress/Menu.php +24 -0
  43. plugins/WordPress/WordPress.php +2 -0
  44. plugins/WordPress/templates/blogselection.twig +5 -0
  45. readme.txt +1 -1
  46. uninstall.php +2 -1
app/core/CliMulti/RequestCommand.php CHANGED
@@ -81,6 +81,10 @@ class RequestCommand extends ConsoleCommand
81
  if (!empty($process)) {
82
  $process->finishProcess();
83
  }
 
 
 
 
84
  }
85
 
86
  private function isTestModeEnabled()
81
  if (!empty($process)) {
82
  $process->finishProcess();
83
  }
84
+
85
+ while (ob_get_level()) {
86
+ echo ob_get_clean();
87
+ }
88
  }
89
 
90
  private function isTestModeEnabled()
app/core/Db/Adapter.php CHANGED
@@ -25,7 +25,7 @@ class Adapter
25
  public static function factory($adapterName, & $dbInfos, $connect = true)
26
  {
27
  if ($connect) {
28
- if ($dbInfos['port'][0] == '/') {
29
  $dbInfos['unix_socket'] = $dbInfos['port'];
30
  unset($dbInfos['host']);
31
  unset($dbInfos['port']);
25
  public static function factory($adapterName, & $dbInfos, $connect = true)
26
  {
27
  if ($connect) {
28
+ if (isset($dbInfos['port']) && is_string($dbInfos['port']) && $dbInfos['port'][0] == '/') {
29
  $dbInfos['unix_socket'] = $dbInfos['port'];
30
  unset($dbInfos['host']);
31
  unset($dbInfos['port']);
app/core/Theme.php CHANGED
@@ -146,7 +146,7 @@ class Theme
146
  foreach (Manager::getAlternativeWebRootDirectories() as $absDir => $webRootDirectory) {
147
  $withoutPlugins = str_replace('plugins/', '', $pathAsset);
148
  if (file_exists($absDir . '/' . $withoutPlugins)) {
149
- return $webRootDirectory . $withoutPlugins;
150
  }
151
  }
152
 
146
  foreach (Manager::getAlternativeWebRootDirectories() as $absDir => $webRootDirectory) {
147
  $withoutPlugins = str_replace('plugins/', '', $pathAsset);
148
  if (file_exists($absDir . '/' . $withoutPlugins)) {
149
+ return str_replace($pathAsset, $webRootDirectory . $withoutPlugins, $source);
150
  }
151
  }
152
 
app/core/Tracker/Request.php CHANGED
@@ -95,7 +95,10 @@ class Request
95
 
96
  protected function replaceUnsupportedUtf8Chars($value, $key=false)
97
  {
98
- if (is_string($value) && preg_match('/[\x{10000}-\x{10FFFF}]/u', $value)) {
 
 
 
99
  Common::printDebug("Unsupport character detected in $key. Replacing with \xEF\xBF\xBD");
100
  return preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $value);
101
  }
95
 
96
  protected function replaceUnsupportedUtf8Chars($value, $key=false)
97
  {
98
+ $dbConfig = Config::getInstance()->database;
99
+ if (!empty($dbConfig['charset'])
100
+ && $dbConfig['charset'] !=='utf8mb4'
101
+ && is_string($value) && preg_match('/[\x{10000}-\x{10FFFF}]/u', $value)) {
102
  Common::printDebug("Unsupport character detected in $key. Replacing with \xEF\xBF\xBD");
103
  return preg_replace('/[\x{10000}-\x{10FFFF}]/u', "\xEF\xBF\xBD", $value);
104
  }
app/core/Updates/3.13.6-b1.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Piwik - 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\Updates;
11
+
12
+ use Piwik\Updater;
13
+ use Piwik\Updates as PiwikUpdates;
14
+ use WpMatomo\Logger;
15
+
16
+ class Updates_3_13_6_b1 extends PiwikUpdates
17
+ {
18
+ public function doUpdate(Updater $updater)
19
+ {
20
+ global $wpdb;
21
+
22
+ if ($wpdb->charset === 'utf8mb4') {
23
+ $db_settings = new \WpMatomo\Db\Settings();
24
+ $installed_tables = $db_settings->get_installed_matomo_tables();
25
+ if (!empty($installed_tables)) {
26
+ foreach ($installed_tables as $installed_table) {
27
+ try {
28
+ $wpdb->query('ALTER TABLE `'.$installed_table.'` CONVERT TO CHARACTER SET utf8mb4');
29
+ } catch (\Exception $e) {
30
+ $logger = new Logger();
31
+ $logger->log("Failed to convert character set: " . $e->getMessage());
32
+ }
33
+ }
34
+ }
35
+ }
36
+ }
37
+
38
+ }
app/core/Version.php CHANGED
@@ -20,7 +20,7 @@ final class Version
20
  * The current Matomo version.
21
  * @var string
22
  */
23
- const VERSION = '3.13.5';
24
 
25
  public function isStableVersion($version)
26
  {
20
  * The current Matomo version.
21
  * @var string
22
  */
23
+ const VERSION = '3.13.6-b1';
24
 
25
  public function isStableVersion($version)
26
  {
app/js/piwik.min.js CHANGED
@@ -59,22 +59,23 @@ v.setHrefAttribute(dq,dk);return true}return false}function aM(dk){if(!dk||!dk.l
59
  return false}var dk=cs(cO(dl,dn,dj,dm),dq,"event");bE(dk,bI,dp)}function b7(dj,dm,dk,dn){var dl=cs("search="+t(dj)+(dm?"&search_cat="+t(dm):"")+(J(dk)?"&search_count="+dk:""),dn,"sitesearch");bE(dl,bI)}function cT(dj,dn,dm,dl){var dk=cs("idgoal="+dj+(dn?"&revenue="+dn:""),dm,"goal");bE(dk,bI,dl)}function c1(dm,dj,dr,dq,dl){var dp=dj+"="+t(b1(dm));var dk=ct(dl,"click",dm);if(dk){dp+="&"+dk}var dn=cs(dp,dr,"link");bE(dn,bI,dq)}function bT(dk,dj){if(dk!==""){return dk+dj.charAt(0).toUpperCase()+dj.slice(1)}return dj}function cg(dp){var dn,dj,dm=["","webkit","ms","moz"],dl;if(!be){for(dj=0;dj<dm.length;dj++){dl=dm[dj];if(Object.prototype.hasOwnProperty.call(G,bT(dl,"hidden"))){if(G[bT(dl,"visibilityState")]==="prerender"){dn=true}break}}}if(dn){an(G,dl+"visibilitychange",function dk(){G.removeEventListener(dl+"visibilitychange",dk,false);dp()});return}dp()}function bq(){var dk=aY().uuid;var dj=aI();return dk+dj}function ci(dj){if(!dj){return}if(!ae.hasNodeAttribute(dj,"href")){return}var dk=ae.getAttributeValueFromNode(dj,"href");
60
  if(!dk||aU(dk)){return}dk=k(dk,av);var dl=bq();dk=F(dk,av,dl);ae.setAnyAttribute(dj,"href",dk)}function aA(dm){var dn=ae.getAttributeValueFromNode(dm,"href");if(!dn){return false}dn=String(dn);var dk=dn.indexOf("//")===0||dn.indexOf("http://")===0||dn.indexOf("https://")===0;if(!dk){return false}var dj=dm.pathname||ck(dm.href);var dl=(dm.hostname||d(dm.href)).toLowerCase();if(ar(dl,dj)){if(!cF(cU,L(dl))){return true}return false}return false}function cE(dj){var dk=dc(dj);if(dk&&dk.type){dk.href=p(dk.href);c1(dk.href,dk.type,undefined,null,dj);return}if(cM){dj=au(dj);if(aA(dj)){ci(dj)}}}function cv(){return G.all&&!G.addEventListener}function cV(dj){var dl=dj.which;var dk=(typeof dj.button);if(!dl&&dk!=="undefined"){if(cv()){if(dj.button&1){dl=1}else{if(dj.button&2){dl=3}else{if(dj.button&4){dl=2}}}}else{if(dj.button===0||dj.button==="0"){dl=1}else{if(dj.button&1){dl=2}else{if(dj.button&2){dl=3}}}}}return dl}function bS(dj){switch(cV(dj)){case 1:return"left";case 2:return"middle";case 3:return"right"
61
  }}function a1(dj){return dj.target||dj.srcElement}function aB(dj){return function(dm){dm=dm||T.event;var dl=bS(dm);var dn=a1(dm);if(dm.type==="click"){var dk=false;if(dj&&dl==="middle"){dk=true}if(dn&&!dk){cE(dn)}}else{if(dm.type==="mousedown"){if(dl==="middle"&&dn){aR=dl;bz=dn}else{aR=bz=null}}else{if(dm.type==="mouseup"){if(dl===aR&&dn===bz){cE(dn)}aR=bz=null}else{if(dm.type==="contextmenu"){cE(dn)}}}}}}function aq(dl,dk){var dj=typeof dk;if(dj==="undefined"){dk=true}an(dl,"click",aB(dk),false);if(dk){an(dl,"mouseup",aB(dk),false);an(dl,"mousedown",aB(dk),false);an(dl,"contextmenu",aB(dk),false)}}function bC(dl,dn){ap=true;var dm,dk=a0(by,"ignore"),dp=G.links,dj=null,dq=null;if(dp){for(dm=0;dm<dp.length;dm++){dj=dp[dm];if(!dk.test(dj.className)){dq=typeof dj.piwikTrackers;if("undefined"===dq){dj.piwikTrackers=[]}if(-1===M(dj.piwikTrackers,dn)){dj.piwikTrackers.push(dn);aq(dj,dl)}}}}}function aS(dk,dn,dp){if(ce){return true}ce=true;var dq=false;var dm,dl;function dj(){dq=true}n(function(){function dr(dt){setTimeout(function(){if(!ce){return
62
- }dq=false;dp.trackVisibleContentImpressions();dr(dt)},dt)}function ds(dt){setTimeout(function(){if(!ce){return}if(dq){dq=false;dp.trackVisibleContentImpressions()}ds(dt)},dt)}if(dk){dm=["scroll","resize"];for(dl=0;dl<dm.length;dl++){if(G.addEventListener){G.addEventListener(dm[dl],dj,false)}else{T.attachEvent("on"+dm[dl],dj)}}ds(100)}if(dn&&dn>0){dn=parseInt(dn,10);dr(dn)}})}var bB={enabled:true,requests:[],timeout:null,interval:2500,sendRequests:function(){var dj=this.requests;this.requests=[];if(dj.length===1){bE(dj[0],bI)}else{df(dj,bI)}},push:function(dj){if(!dj){return}if(m||!this.enabled){bE(dj,bI);return}bB.requests.push(dj);if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.timeout=setTimeout(function(){bB.timeout=null;bB.sendRequests()},bB.interval);var dk="RequestQueue"+aw;if(!Object.prototype.hasOwnProperty.call(b,dk)){b[dk]={unload:function(){if(bB.timeout){clearTimeout(bB.timeout)}bB.sendRequests()}}}}};bh();aL();this.hasConsent=function(){return bA};this.getVisitorId=function(){return aY().uuid
63
- };this.getVisitorInfo=function(){return cN()};this.getAttributionInfo=function(){return bL()};this.getAttributionCampaignName=function(){return bL()[0]};this.getAttributionCampaignKeyword=function(){return bL()[1]};this.getAttributionReferrerTimestamp=function(){return bL()[2]};this.getAttributionReferrerUrl=function(){return bL()[3]};this.setTrackerUrl=function(dj){aD=dj};this.getTrackerUrl=function(){return aD};this.getPiwikUrl=function(){return O(this.getTrackerUrl(),bG)};this.addTracker=function(dj,dl){if(!J(dj)||null===dj){dj=this.getTrackerUrl()}var dk=new Q(dj,dl);I.push(dk);e.trigger("TrackerAdded",[this]);return dk};this.getSiteId=function(){return b5};this.setSiteId=function(dj){b2(dj)};this.resetUserId=function(){bx=""};this.setUserId=function(dj){if(Y(dj)){bx=dj}};this.getUserId=function(){return bx};this.setCustomData=function(dj,dk){if(W(dj)){ao=dj}else{if(!ao){ao={}}ao[dj]=dk}};this.getCustomData=function(){return ao};this.setCustomRequestProcessing=function(dj){ca=dj};this.appendToTrackingUrl=function(dj){cZ=dj
64
- };this.getRequest=function(dj){return cs(dj)};this.addPlugin=function(dj,dk){b[dj]=dk};this.setCustomDimension=function(dj,dk){dj=parseInt(dj,10);if(dj>0){if(!J(dk)){dk=""}if(!w(dk)){dk=String(dk)}bl[dj]=dk}};this.getCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0&&Object.prototype.hasOwnProperty.call(bl,dj)){return bl[dj]}};this.deleteCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0){delete bl[dj]}};this.setCustomVariable=function(dk,dj,dn,dl){var dm;if(!J(dl)){dl="visit"}if(!J(dj)){return}if(!J(dn)){dn=""}if(dk>0){dj=!w(dj)?String(dj):dj;dn=!w(dn)?String(dn):dn;dm=[dj.slice(0,bs),dn.slice(0,bs)];if(dl==="visit"||dl===2){cD();aQ[dk]=dm}else{if(dl==="page"||dl===3){bV[dk]=dm}else{if(dl==="event"){cl[dk]=dm}}}}};this.getCustomVariable=function(dk,dl){var dj;if(!J(dl)){dl="visit"}if(dl==="page"||dl===3){dj=bV[dk]}else{if(dl==="event"){dj=cl[dk]}else{if(dl==="visit"||dl===2){cD();dj=aQ[dk]}}}if(!J(dj)||(dj&&dj[0]==="")){return false}return dj};this.deleteCustomVariable=function(dj,dk){if(this.getCustomVariable(dj,dk)){this.setCustomVariable(dj,"","",dk)
65
- }};this.deleteCustomVariables=function(dj){if(dj==="page"||dj===3){bV={}}else{if(dj==="event"){cl={}}else{if(dj==="visit"||dj===2){aQ={}}}}};this.storeCustomVariablesInCookie=function(){bP=true};this.setLinkTrackingTimer=function(dj){bI=dj};this.getLinkTrackingTimer=function(){return bI};this.setDownloadExtensions=function(dj){if(w(dj)){dj=dj.split("|")}c6=dj};this.addDownloadExtensions=function(dk){var dj;if(w(dk)){dk=dk.split("|")}for(dj=0;dj<dk.length;dj++){c6.push(dk[dj])}};this.removeDownloadExtensions=function(dl){var dk,dj=[];if(w(dl)){dl=dl.split("|")}for(dk=0;dk<c6.length;dk++){if(M(dl,c6[dk])===-1){dj.push(c6[dk])}}c6=dj};this.setDomains=function(dj){ax=w(dj)?[dj]:dj;var dn=false,dl=0,dk;for(dl;dl<ax.length;dl++){dk=String(ax[dl]);if(cF(cU,L(dk))){dn=true;break}var dm=ck(dk);if(dm&&dm!=="/"&&dm!=="/*"){dn=true;break}}if(!dn){ax.push(cU)}};this.enableCrossDomainLinking=function(){cM=true};this.disableCrossDomainLinking=function(){cM=false};this.isCrossDomainLinkingEnabled=function(){return cM
66
- };this.setCrossDomainLinkingTimeout=function(dj){aZ=dj};this.getCrossDomainLinkingUrlParameter=function(){return t(av)+"="+t(bq())};this.setIgnoreClasses=function(dj){by=w(dj)?[dj]:dj};this.setRequestMethod=function(dj){da=dj||ch};this.setRequestContentType=function(dj){cw=dj||aH};this.setReferrerUrl=function(dj){bm=dj};this.setCustomUrl=function(dj){a4=bU(bM,dj)};this.getCurrentUrl=function(){return a4||bM};this.setDocumentTitle=function(dj){bi=dj};this.setAPIUrl=function(dj){bG=dj};this.setDownloadClasses=function(dj){bK=w(dj)?[dj]:dj};this.setLinkClasses=function(dj){a8=w(dj)?[dj]:dj};this.setCampaignNameKey=function(dj){cq=w(dj)?[dj]:dj};this.setCampaignKeywordKey=function(dj){bF=w(dj)?[dj]:dj};this.discardHashTag=function(dj){bO=dj};this.setCookieNamePrefix=function(dj){bj=dj;aQ=bW()};this.setCookieDomain=function(dj){var dk=L(dj);if(bv(dk)){cX=dk;bh()}};this.getCookieDomain=function(){return cX};this.hasCookies=function(){return"1"===b4()};this.setSessionCookie=function(dl,dk,dj){if(!dl){throw new Error("Missing cookie name")
67
- }if(!J(dj)){dj=co}bt.push(dl);de(aT(dl),dk,dj,bo,cX)};this.getCookie=function(dk){var dj=aC(aT(dk));if(dj===0){return null}return dj};this.setCookiePath=function(dj){bo=dj;bh()};this.getCookiePath=function(dj){return bo};this.setVisitorCookieTimeout=function(dj){cI=dj*1000};this.setSessionCookieTimeout=function(dj){co=dj*1000};this.getSessionCookieTimeout=function(){return co};this.setReferralCookieTimeout=function(dj){c5=dj*1000};this.setConversionAttributionFirstReferrer=function(dj){bu=dj};this.setSecureCookie=function(dj){bR=dj};this.disableCookies=function(){bk=true;c8.cookie="0";if(b5){aE()}};this.deleteCookies=function(){aE()};this.setDoNotTrack=function(dk){var dj=h.doNotTrack||h.msDoNotTrack;cP=dk&&(dj==="yes"||dj==="1");if(cP){this.disableCookies()}};this.alwaysUseSendBeacon=function(){cW=true};this.addListener=function(dk,dj){aq(dk,dj)};this.enableLinkTracking=function(dk){c9=true;var dj=this;cg(function(){q(function(){bC(dk,dj)})})};this.enableJSErrorTracking=function(){if(cS){return
68
- }cS=true;var dj=T.onerror;T.onerror=function(dp,dm,dl,dn,dk){cg(function(){var dq="JavaScript Errors";var dr=dm+":"+dl;if(dn){dr+=":"+dn}at(dq,dr,dp)});if(dj){return dj(dp,dm,dl,dn,dk)}return false}};this.disablePerformanceTracking=function(){a2=false};this.setGenerationTimeMs=function(dj){cm=parseInt(dj,10)};this.setVisitStandardLength=function(dj){dj=Math.max(dj,5);c7=dj};this.enableHeartBeatTimer=function(dj){dj=Math.max(dj,5);a5=(dj||15)*1000;if(cY!==null){dg()}};this.disableHeartBeatTimer=function(){bJ();if(a5||aN){if(T.removeEventListener){T.removeEventListener("focus",ba);T.removeEventListener("blur",ay)}else{if(T.detachEvent){T.detachEvent("onfocus",ba);T.detachEvent("onblur",ay)}}}a5=null;aN=false};this.killFrame=function(){if(T.location!==T.top.location){T.top.location=T.location}};this.redirectFile=function(dj){if(T.location.protocol==="file:"){T.location=dj}};this.setCountPreRendered=function(dj){be=dj};this.trackGoal=function(dj,dm,dl,dk){cg(function(){cT(dj,dm,dl,dk)})};this.trackLink=function(dk,dj,dm,dl){cg(function(){c1(dk,dj,dm,dl)
69
- })};this.getNumTrackedPageViews=function(){return cr};this.trackPageView=function(dj,dl,dk){b9=[];cJ=[];if(N(b5)){cg(function(){Z(aD,bG,b5)})}else{cg(function(){cr++;bZ(dj,dl,dk)})}};this.trackAllContentImpressions=function(){if(N(b5)){return}cg(function(){q(function(){var dj=v.findContentNodes();var dk=cy(dj);df(dk,bI)})})};this.trackVisibleContentImpressions=function(dj,dk){if(N(b5)){return}if(!J(dj)){dj=true}if(!J(dk)){dk=750}aS(dj,dk,this);cg(function(){n(function(){var dl=v.findContentNodes();var dm=a9(dl);df(dm,bI)})})};this.trackContentImpression=function(dl,dj,dk){if(N(b5)){return}dl=a(dl);dj=a(dj);dk=a(dk);if(!dl){return}dj=dj||"Unknown";cg(function(){var dm=aF(dl,dj,dk);bE(dm,bI)})};this.trackContentImpressionsWithinNode=function(dj){if(N(b5)||!dj){return}cg(function(){if(ce){n(function(){var dk=v.findContentNodesWithinNode(dj);var dl=a9(dk);df(dl,bI)})}else{q(function(){var dk=v.findContentNodesWithinNode(dj);var dl=cy(dk);df(dl,bI)})}})};this.trackContentInteraction=function(dl,dm,dj,dk){if(N(b5)){return
70
- }dl=a(dl);dm=a(dm);dj=a(dj);dk=a(dk);if(!dl||!dm){return}dj=dj||"Unknown";cg(function(){var dn=aP(dl,dm,dj,dk);if(dn){bE(dn,bI)}})};this.trackContentInteractionNode=function(dk,dj){if(N(b5)||!dk){return}cg(function(){var dl=db(dk,dj);if(dl){bE(dl,bI)}})};this.logAllContentBlocksOnPage=function(){var dl=v.findContentNodes();var dj=v.collectContent(dl);var dk=typeof console;if(dk!=="undefined"&&console&&console.log){console.log(dj)}};this.trackEvent=function(dk,dm,dj,dl,dp,dn){cg(function(){at(dk,dm,dj,dl,dp,dn)})};this.trackSiteSearch=function(dj,dl,dk,dm){b9=[];cg(function(){b7(dj,dl,dk,dm)})};this.setEcommerceView=function(dm,dj,dl,dk){if(Y(dl)){dl=String(dl)}if(!J(dl)||dl===null||dl===false||!dl.length){dl=""}else{if(dl instanceof Array){dl=JSON_PIWIK.stringify(dl)}}bV[5]=["_pkc",dl];if(J(dk)&&dk!==null&&dk!==false&&String(dk).length){bV[2]=["_pkp",dk]}if(!Y(dm)&&!Y(dj)){return}if(Y(dm)){bV[3]=["_pks",dm]}if(!Y(dj)){dj=""}bV[4]=["_pkn",dj]};this.getEcommerceItems=function(){return JSON.parse(JSON.stringify(c0))
71
- };this.addEcommerceItem=function(dn,dj,dl,dk,dm){if(Y(dn)){c0[dn]=[String(dn),dj,dl,dk,dm]}};this.removeEcommerceItem=function(dj){if(Y(dj)){dj=String(dj);delete c0[dj]}};this.clearEcommerceCart=function(){c0={}};this.trackEcommerceOrder=function(dj,dn,dm,dl,dk,dp){bY(dj,dn,dm,dl,dk,dp)};this.trackEcommerceCartUpdate=function(dj){br(dj)};this.trackRequest=function(dk,dm,dl,dj){cg(function(){var dn=cs(dk,dm,dj);bE(dn,bI,dl)})};this.ping=function(){this.trackRequest("ping=1",null,null,"ping")};this.disableQueueRequest=function(){bB.enabled=false};this.setRequestQueueInterval=function(dj){if(dj<1000){throw new Error("Request queue interval needs to be at least 1000ms")}bB.interval=dj};this.queueRequest=function(dj){cg(function(){var dk=cs(dj);bB.push(dk)})};this.isConsentRequired=function(){return cz};this.getRememberedConsent=function(){var dj=aC(bd);if(aC(cL)){if(dj){bX(bd,bo,cX)}return null}if(!dj||dj===0){return null}return dj};this.hasRememberedConsent=function(){return !!this.getRememberedConsent()
72
- };this.requireConsent=function(){cz=true;bA=this.hasRememberedConsent();x++;b["CoreConsent"+x]={unload:function(){if(!bA){aE()}}}};this.setConsentGiven=function(){bA=true;bX(cL,bo,cX);var dk,dj;for(dk=0;dk<cJ.length;dk++){dj=typeof cJ[dk];if(dj==="string"){bE(cJ[dk],bI)}else{if(dj==="object"){df(cJ[dk],bI)}}}cJ=[]};this.rememberConsentGiven=function(dk){if(dk){dk=dk*60*60*1000}else{dk=30*365*24*60*60*1000}this.setConsentGiven();var dj=new Date().getTime();de(bd,dj,dk,bo,cX,bR)};this.forgetConsentGiven=function(){var dj=30*365*24*60*60*1000;bX(bd,bo,cX);de(cL,new Date().getTime(),dj,bo,cX,bR);this.requireConsent()};this.isUserOptedOut=function(){return !bA};this.optUserOut=this.forgetConsentGiven;this.forgetUserOptOut=this.rememberConsentGiven;e.trigger("TrackerSetup",[this])}function H(){return{push:af}}function c(au,at){var av={};var aq,ar;for(aq=0;aq<at.length;aq++){var ao=at[aq];av[ao]=1;for(ar=0;ar<au.length;ar++){if(au[ar]&&au[ar][0]){var ap=au[ar][0];if(ao===ap){af(au[ar]);delete au[ar];
73
- if(av[ap]>1&&ap!=="addTracker"){ak("The method "+ap+' is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: https://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')}av[ap]++}}}}return au}var C=["addTracker","disableCookies","setTrackerUrl","setAPIUrl","enableCrossDomainLinking","setCrossDomainLinkingTimeout","setSessionCookieTimeout","setVisitorCookieTimeout","setSecureCookie","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","alwaysUseSendBeacon","enableLinkTracking","requireConsent","setConsentGiven"];function ad(ao,aq){var ap=new Q(ao,aq);I.push(ap);_paq=c(_paq,C);for(E=0;E<_paq.length;E++){if(_paq[E]){af(_paq[E])}}_paq=new H();e.trigger("TrackerAdded",[ap]);return ap}an(T,"beforeunload",ai,false);an(T,"message",function(au){if(!au||!au.origin){return}var aw,ar,ap;var ax=d(au.origin);var at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){ap=d(at[ar].getPiwikUrl());
74
- if(ap===ax){aw=at[ar];break}}if(!aw){return}var aq=null;try{aq=JSON.parse(au.data)}catch(av){return}if(!aq){return}function ao(aA){var aC=G.getElementsByTagName("iframe");for(ar=0;ar<aC.length;ar++){var aB=aC[ar];var ay=d(aB.src);if(aB.contentWindow&&J(aB.contentWindow.postMessage)&&ay===ax){var az=JSON.stringify(aA);aB.contentWindow.postMessage(az,"*")}}}if(J(aq.maq_initial_value)){ao({maq_opted_in:aq.maq_initial_value&&aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}else{if(J(aq.maq_opted_in)){at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){aw=at[ar];if(aq.maq_opted_in){aw.rememberConsentGiven()}else{aw.forgetConsentGiven()}}ao({maq_confirm_opted_in:aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}}},false);Date.prototype.getTimeAlias=Date.prototype.getTime;e={initialized:false,JSON:JSON_PIWIK,DOM:{addEventListener:function(ar,aq,ap,ao){var at=typeof ao;if(at==="undefined"){ao=false}an(ar,aq,ap,ao)},onLoad:n,onReady:q,isNodeVisible:j,isOrWasNodeVisible:v.isNodeVisible},on:function(ap,ao){if(!y[ap]){y[ap]=[]
75
- }y[ap].push(ao)},off:function(aq,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){if(y[aq][ao]===ap){y[aq].splice(ao,1)}}},trigger:function(aq,ar,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){y[aq][ao].apply(ap||T,ar)}},addPlugin:function(ao,ap){b[ao]=ap},getTracker:function(ao,ap){if(!J(ap)){ap=this.getAsyncTracker().getSiteId()}if(!J(ao)){ao=this.getAsyncTracker().getTrackerUrl()}return new Q(ao,ap)},getAsyncTrackers:function(){return I},addTracker:function(ao,aq){var ap;if(!I.length){ap=ad(ao,aq)}else{ap=I[0].addTracker(ao,aq)}return ap},getAsyncTracker:function(ap,at){var ar;if(I&&I.length&&I[0]){ar=I[0]}else{return ad(ap,at)}if(!at&&!ap){return ar}if((!J(at)||null===at)&&ar){at=ar.getSiteId()}if((!J(ap)||null===ap)&&ar){ap=ar.getTrackerUrl()}var aq,ao=0;for(ao;ao<I.length;ao++){aq=I[ao];if(aq&&String(aq.getSiteId())===String(at)&&aq.getTrackerUrl()===ap){return aq}}},retryMissedPluginCalls:function(){var ap=ah;ah=[];var ao=0;for(ao;ao<ap.length;ao++){af(ap[ao])
76
- }}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return e});define("matomo",[],function(){return e})}return e}())}
77
  /*!!! pluginTrackerHook */
78
- (function(){function b(){if("object"!==typeof _paq){return false}var c=typeof _paq.length;if("undefined"===c){return false}return !!_paq.length}if(window&&"object"===typeof window.piwikPluginAsyncInit&&window.piwikPluginAsyncInit.length){var a=0;for(a;a<window.piwikPluginAsyncInit.length;a++){if(typeof window.piwikPluginAsyncInit[a]==="function"){window.piwikPluginAsyncInit[a]()}}}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}if(!window.Piwik.getAsyncTrackers().length){if(b()){window.Piwik.addTracker()}else{_paq={push:function(c){var d=typeof console;if(d!=="undefined"&&console&&console.error){console.error("_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js. Alternatively, you can create a tracker via Matomo.addTracker() manually and then use _paq.push but it may not fully work as tracker methods may not be executed in the correct order.",c)
79
- }}}}}window.Piwik.trigger("PiwikInitialized",[]);window.Piwik.initialized=true}());(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=window.Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=window.Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}}
 
80
  /*!! @license-end */;
59
  return false}var dk=cs(cO(dl,dn,dj,dm),dq,"event");bE(dk,bI,dp)}function b7(dj,dm,dk,dn){var dl=cs("search="+t(dj)+(dm?"&search_cat="+t(dm):"")+(J(dk)?"&search_count="+dk:""),dn,"sitesearch");bE(dl,bI)}function cT(dj,dn,dm,dl){var dk=cs("idgoal="+dj+(dn?"&revenue="+dn:""),dm,"goal");bE(dk,bI,dl)}function c1(dm,dj,dr,dq,dl){var dp=dj+"="+t(b1(dm));var dk=ct(dl,"click",dm);if(dk){dp+="&"+dk}var dn=cs(dp,dr,"link");bE(dn,bI,dq)}function bT(dk,dj){if(dk!==""){return dk+dj.charAt(0).toUpperCase()+dj.slice(1)}return dj}function cg(dp){var dn,dj,dm=["","webkit","ms","moz"],dl;if(!be){for(dj=0;dj<dm.length;dj++){dl=dm[dj];if(Object.prototype.hasOwnProperty.call(G,bT(dl,"hidden"))){if(G[bT(dl,"visibilityState")]==="prerender"){dn=true}break}}}if(dn){an(G,dl+"visibilitychange",function dk(){G.removeEventListener(dl+"visibilitychange",dk,false);dp()});return}dp()}function bq(){var dk=aY().uuid;var dj=aI();return dk+dj}function ci(dj){if(!dj){return}if(!ae.hasNodeAttribute(dj,"href")){return}var dk=ae.getAttributeValueFromNode(dj,"href");
60
  if(!dk||aU(dk)){return}dk=k(dk,av);var dl=bq();dk=F(dk,av,dl);ae.setAnyAttribute(dj,"href",dk)}function aA(dm){var dn=ae.getAttributeValueFromNode(dm,"href");if(!dn){return false}dn=String(dn);var dk=dn.indexOf("//")===0||dn.indexOf("http://")===0||dn.indexOf("https://")===0;if(!dk){return false}var dj=dm.pathname||ck(dm.href);var dl=(dm.hostname||d(dm.href)).toLowerCase();if(ar(dl,dj)){if(!cF(cU,L(dl))){return true}return false}return false}function cE(dj){var dk=dc(dj);if(dk&&dk.type){dk.href=p(dk.href);c1(dk.href,dk.type,undefined,null,dj);return}if(cM){dj=au(dj);if(aA(dj)){ci(dj)}}}function cv(){return G.all&&!G.addEventListener}function cV(dj){var dl=dj.which;var dk=(typeof dj.button);if(!dl&&dk!=="undefined"){if(cv()){if(dj.button&1){dl=1}else{if(dj.button&2){dl=3}else{if(dj.button&4){dl=2}}}}else{if(dj.button===0||dj.button==="0"){dl=1}else{if(dj.button&1){dl=2}else{if(dj.button&2){dl=3}}}}}return dl}function bS(dj){switch(cV(dj)){case 1:return"left";case 2:return"middle";case 3:return"right"
61
  }}function a1(dj){return dj.target||dj.srcElement}function aB(dj){return function(dm){dm=dm||T.event;var dl=bS(dm);var dn=a1(dm);if(dm.type==="click"){var dk=false;if(dj&&dl==="middle"){dk=true}if(dn&&!dk){cE(dn)}}else{if(dm.type==="mousedown"){if(dl==="middle"&&dn){aR=dl;bz=dn}else{aR=bz=null}}else{if(dm.type==="mouseup"){if(dl===aR&&dn===bz){cE(dn)}aR=bz=null}else{if(dm.type==="contextmenu"){cE(dn)}}}}}}function aq(dl,dk){var dj=typeof dk;if(dj==="undefined"){dk=true}an(dl,"click",aB(dk),false);if(dk){an(dl,"mouseup",aB(dk),false);an(dl,"mousedown",aB(dk),false);an(dl,"contextmenu",aB(dk),false)}}function bC(dl,dn){ap=true;var dm,dk=a0(by,"ignore"),dp=G.links,dj=null,dq=null;if(dp){for(dm=0;dm<dp.length;dm++){dj=dp[dm];if(!dk.test(dj.className)){dq=typeof dj.piwikTrackers;if("undefined"===dq){dj.piwikTrackers=[]}if(-1===M(dj.piwikTrackers,dn)){dj.piwikTrackers.push(dn);aq(dj,dl)}}}}}function aS(dk,dn,dp){if(ce){return true}ce=true;var dq=false;var dm,dl;function dj(){dq=true}n(function(){function dr(dt){setTimeout(function(){if(!ce){return
62
+ }dq=false;dp.trackVisibleContentImpressions();dr(dt)},dt)}function ds(dt){setTimeout(function(){if(!ce){return}if(dq){dq=false;dp.trackVisibleContentImpressions()}ds(dt)},dt)}if(dk){dm=["scroll","resize"];for(dl=0;dl<dm.length;dl++){if(G.addEventListener){G.addEventListener(dm[dl],dj,false)}else{T.attachEvent("on"+dm[dl],dj)}}ds(100)}if(dn&&dn>0){dn=parseInt(dn,10);dr(dn)}})}var bB={enabled:true,requests:[],timeout:null,interval:2500,sendRequests:function(){var dj=this.requests;this.requests=[];if(dj.length===1){bE(dj[0],bI)}else{df(dj,bI)}},canQueue:function(){return !m&&this.enabled},pushMultiple:function(dk){if(!this.canQueue()){df(dk,bI);return}var dj;for(dj=0;dj<dk.length;dj++){this.push(dk[dj])}},push:function(dj){if(!dj){return}if(!this.canQueue()){bE(dj,bI);return}bB.requests.push(dj);if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.timeout=setTimeout(function(){bB.timeout=null;bB.sendRequests()},bB.interval);var dk="RequestQueue"+aw;if(!Object.prototype.hasOwnProperty.call(b,dk)){b[dk]={unload:function(){if(bB.timeout){clearTimeout(bB.timeout)
63
+ }bB.sendRequests()}}}}};bh();aL();this.hasConsent=function(){return bA};this.getVisitorId=function(){return aY().uuid};this.getVisitorInfo=function(){return cN()};this.getAttributionInfo=function(){return bL()};this.getAttributionCampaignName=function(){return bL()[0]};this.getAttributionCampaignKeyword=function(){return bL()[1]};this.getAttributionReferrerTimestamp=function(){return bL()[2]};this.getAttributionReferrerUrl=function(){return bL()[3]};this.setTrackerUrl=function(dj){aD=dj};this.getTrackerUrl=function(){return aD};this.getPiwikUrl=function(){return O(this.getTrackerUrl(),bG)};this.addTracker=function(dj,dl){if(!J(dj)||null===dj){dj=this.getTrackerUrl()}var dk=new Q(dj,dl);I.push(dk);e.trigger("TrackerAdded",[this]);return dk};this.getSiteId=function(){return b5};this.setSiteId=function(dj){b2(dj)};this.resetUserId=function(){bx=""};this.setUserId=function(dj){if(Y(dj)){bx=dj}};this.getUserId=function(){return bx};this.setCustomData=function(dj,dk){if(W(dj)){ao=dj}else{if(!ao){ao={}
64
+ }ao[dj]=dk}};this.getCustomData=function(){return ao};this.setCustomRequestProcessing=function(dj){ca=dj};this.appendToTrackingUrl=function(dj){cZ=dj};this.getRequest=function(dj){return cs(dj)};this.addPlugin=function(dj,dk){b[dj]=dk};this.setCustomDimension=function(dj,dk){dj=parseInt(dj,10);if(dj>0){if(!J(dk)){dk=""}if(!w(dk)){dk=String(dk)}bl[dj]=dk}};this.getCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0&&Object.prototype.hasOwnProperty.call(bl,dj)){return bl[dj]}};this.deleteCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0){delete bl[dj]}};this.setCustomVariable=function(dk,dj,dn,dl){var dm;if(!J(dl)){dl="visit"}if(!J(dj)){return}if(!J(dn)){dn=""}if(dk>0){dj=!w(dj)?String(dj):dj;dn=!w(dn)?String(dn):dn;dm=[dj.slice(0,bs),dn.slice(0,bs)];if(dl==="visit"||dl===2){cD();aQ[dk]=dm}else{if(dl==="page"||dl===3){bV[dk]=dm}else{if(dl==="event"){cl[dk]=dm}}}}};this.getCustomVariable=function(dk,dl){var dj;if(!J(dl)){dl="visit"}if(dl==="page"||dl===3){dj=bV[dk]}else{if(dl==="event"){dj=cl[dk]
65
+ }else{if(dl==="visit"||dl===2){cD();dj=aQ[dk]}}}if(!J(dj)||(dj&&dj[0]==="")){return false}return dj};this.deleteCustomVariable=function(dj,dk){if(this.getCustomVariable(dj,dk)){this.setCustomVariable(dj,"","",dk)}};this.deleteCustomVariables=function(dj){if(dj==="page"||dj===3){bV={}}else{if(dj==="event"){cl={}}else{if(dj==="visit"||dj===2){aQ={}}}}};this.storeCustomVariablesInCookie=function(){bP=true};this.setLinkTrackingTimer=function(dj){bI=dj};this.getLinkTrackingTimer=function(){return bI};this.setDownloadExtensions=function(dj){if(w(dj)){dj=dj.split("|")}c6=dj};this.addDownloadExtensions=function(dk){var dj;if(w(dk)){dk=dk.split("|")}for(dj=0;dj<dk.length;dj++){c6.push(dk[dj])}};this.removeDownloadExtensions=function(dl){var dk,dj=[];if(w(dl)){dl=dl.split("|")}for(dk=0;dk<c6.length;dk++){if(M(dl,c6[dk])===-1){dj.push(c6[dk])}}c6=dj};this.setDomains=function(dj){ax=w(dj)?[dj]:dj;var dn=false,dl=0,dk;for(dl;dl<ax.length;dl++){dk=String(ax[dl]);if(cF(cU,L(dk))){dn=true;break}var dm=ck(dk);
66
+ if(dm&&dm!=="/"&&dm!=="/*"){dn=true;break}}if(!dn){ax.push(cU)}};this.enableCrossDomainLinking=function(){cM=true};this.disableCrossDomainLinking=function(){cM=false};this.isCrossDomainLinkingEnabled=function(){return cM};this.setCrossDomainLinkingTimeout=function(dj){aZ=dj};this.getCrossDomainLinkingUrlParameter=function(){return t(av)+"="+t(bq())};this.setIgnoreClasses=function(dj){by=w(dj)?[dj]:dj};this.setRequestMethod=function(dj){da=dj||ch};this.setRequestContentType=function(dj){cw=dj||aH};this.setReferrerUrl=function(dj){bm=dj};this.setCustomUrl=function(dj){a4=bU(bM,dj)};this.getCurrentUrl=function(){return a4||bM};this.setDocumentTitle=function(dj){bi=dj};this.setAPIUrl=function(dj){bG=dj};this.setDownloadClasses=function(dj){bK=w(dj)?[dj]:dj};this.setLinkClasses=function(dj){a8=w(dj)?[dj]:dj};this.setCampaignNameKey=function(dj){cq=w(dj)?[dj]:dj};this.setCampaignKeywordKey=function(dj){bF=w(dj)?[dj]:dj};this.discardHashTag=function(dj){bO=dj};this.setCookieNamePrefix=function(dj){bj=dj;
67
+ aQ=bW()};this.setCookieDomain=function(dj){var dk=L(dj);if(bv(dk)){cX=dk;bh()}};this.getCookieDomain=function(){return cX};this.hasCookies=function(){return"1"===b4()};this.setSessionCookie=function(dl,dk,dj){if(!dl){throw new Error("Missing cookie name")}if(!J(dj)){dj=co}bt.push(dl);de(aT(dl),dk,dj,bo,cX)};this.getCookie=function(dk){var dj=aC(aT(dk));if(dj===0){return null}return dj};this.setCookiePath=function(dj){bo=dj;bh()};this.getCookiePath=function(dj){return bo};this.setVisitorCookieTimeout=function(dj){cI=dj*1000};this.setSessionCookieTimeout=function(dj){co=dj*1000};this.getSessionCookieTimeout=function(){return co};this.setReferralCookieTimeout=function(dj){c5=dj*1000};this.setConversionAttributionFirstReferrer=function(dj){bu=dj};this.setSecureCookie=function(dj){bR=dj};this.disableCookies=function(){bk=true;c8.cookie="0";if(b5){aE()}};this.deleteCookies=function(){aE()};this.setDoNotTrack=function(dk){var dj=h.doNotTrack||h.msDoNotTrack;cP=dk&&(dj==="yes"||dj==="1");if(cP){this.disableCookies()
68
+ }};this.alwaysUseSendBeacon=function(){cW=true};this.addListener=function(dk,dj){aq(dk,dj)};this.enableLinkTracking=function(dk){c9=true;var dj=this;cg(function(){q(function(){bC(dk,dj)});n(function(){bC(dk,dj)})})};this.enableJSErrorTracking=function(){if(cS){return}cS=true;var dj=T.onerror;T.onerror=function(dp,dm,dl,dn,dk){cg(function(){var dq="JavaScript Errors";var dr=dm+":"+dl;if(dn){dr+=":"+dn}at(dq,dr,dp)});if(dj){return dj(dp,dm,dl,dn,dk)}return false}};this.disablePerformanceTracking=function(){a2=false};this.setGenerationTimeMs=function(dj){cm=parseInt(dj,10)};this.setVisitStandardLength=function(dj){dj=Math.max(dj,5);c7=dj};this.enableHeartBeatTimer=function(dj){dj=Math.max(dj,5);a5=(dj||15)*1000;if(cY!==null){dg()}};this.disableHeartBeatTimer=function(){bJ();if(a5||aN){if(T.removeEventListener){T.removeEventListener("focus",ba);T.removeEventListener("blur",ay)}else{if(T.detachEvent){T.detachEvent("onfocus",ba);T.detachEvent("onblur",ay)}}}a5=null;aN=false};this.killFrame=function(){if(T.location!==T.top.location){T.top.location=T.location
69
+ }};this.redirectFile=function(dj){if(T.location.protocol==="file:"){T.location=dj}};this.setCountPreRendered=function(dj){be=dj};this.trackGoal=function(dj,dm,dl,dk){cg(function(){cT(dj,dm,dl,dk)})};this.trackLink=function(dk,dj,dm,dl){cg(function(){c1(dk,dj,dm,dl)})};this.getNumTrackedPageViews=function(){return cr};this.trackPageView=function(dj,dl,dk){b9=[];cJ=[];if(N(b5)){cg(function(){Z(aD,bG,b5)})}else{cg(function(){cr++;bZ(dj,dl,dk)})}};this.trackAllContentImpressions=function(){if(N(b5)){return}cg(function(){q(function(){var dj=v.findContentNodes();var dk=cy(dj);bB.pushMultiple(dk)})})};this.trackVisibleContentImpressions=function(dj,dk){if(N(b5)){return}if(!J(dj)){dj=true}if(!J(dk)){dk=750}aS(dj,dk,this);cg(function(){n(function(){var dl=v.findContentNodes();var dm=a9(dl);bB.pushMultiple(dm)})})};this.trackContentImpression=function(dl,dj,dk){if(N(b5)){return}dl=a(dl);dj=a(dj);dk=a(dk);if(!dl){return}dj=dj||"Unknown";cg(function(){var dm=aF(dl,dj,dk);bB.push(dm)})};this.trackContentImpressionsWithinNode=function(dj){if(N(b5)||!dj){return
70
+ }cg(function(){if(ce){n(function(){var dk=v.findContentNodesWithinNode(dj);var dl=a9(dk);bB.pushMultiple(dl)})}else{q(function(){var dk=v.findContentNodesWithinNode(dj);var dl=cy(dk);bB.pushMultiple(dl)})}})};this.trackContentInteraction=function(dl,dm,dj,dk){if(N(b5)){return}dl=a(dl);dm=a(dm);dj=a(dj);dk=a(dk);if(!dl||!dm){return}dj=dj||"Unknown";cg(function(){var dn=aP(dl,dm,dj,dk);if(dn){bB.push(dn)}})};this.trackContentInteractionNode=function(dk,dj){if(N(b5)||!dk){return}cg(function(){var dl=db(dk,dj);if(dl){bB.push(dl)}})};this.logAllContentBlocksOnPage=function(){var dl=v.findContentNodes();var dj=v.collectContent(dl);var dk=typeof console;if(dk!=="undefined"&&console&&console.log){console.log(dj)}};this.trackEvent=function(dk,dm,dj,dl,dp,dn){cg(function(){at(dk,dm,dj,dl,dp,dn)})};this.trackSiteSearch=function(dj,dl,dk,dm){b9=[];cg(function(){b7(dj,dl,dk,dm)})};this.setEcommerceView=function(dm,dj,dl,dk){if(Y(dl)){dl=String(dl)}if(!J(dl)||dl===null||dl===false||!dl.length){dl=""}else{if(dl instanceof Array){dl=JSON_PIWIK.stringify(dl)
71
+ }}bV[5]=["_pkc",dl];if(J(dk)&&dk!==null&&dk!==false&&String(dk).length){bV[2]=["_pkp",dk]}if(!Y(dm)&&!Y(dj)){return}if(Y(dm)){bV[3]=["_pks",dm]}if(!Y(dj)){dj=""}bV[4]=["_pkn",dj]};this.getEcommerceItems=function(){return JSON.parse(JSON.stringify(c0))};this.addEcommerceItem=function(dn,dj,dl,dk,dm){if(Y(dn)){c0[dn]=[String(dn),dj,dl,dk,dm]}};this.removeEcommerceItem=function(dj){if(Y(dj)){dj=String(dj);delete c0[dj]}};this.clearEcommerceCart=function(){c0={}};this.trackEcommerceOrder=function(dj,dn,dm,dl,dk,dp){bY(dj,dn,dm,dl,dk,dp)};this.trackEcommerceCartUpdate=function(dj){br(dj)};this.trackRequest=function(dk,dm,dl,dj){cg(function(){var dn=cs(dk,dm,dj);bE(dn,bI,dl)})};this.ping=function(){this.trackRequest("ping=1",null,null,"ping")};this.disableQueueRequest=function(){bB.enabled=false};this.setRequestQueueInterval=function(dj){if(dj<1000){throw new Error("Request queue interval needs to be at least 1000ms")}bB.interval=dj};this.queueRequest=function(dj){cg(function(){var dk=cs(dj);
72
+ bB.push(dk)})};this.isConsentRequired=function(){return cz};this.getRememberedConsent=function(){var dj=aC(bd);if(aC(cL)){if(dj){bX(bd,bo,cX)}return null}if(!dj||dj===0){return null}return dj};this.hasRememberedConsent=function(){return !!this.getRememberedConsent()};this.requireConsent=function(){cz=true;bA=this.hasRememberedConsent();x++;b["CoreConsent"+x]={unload:function(){if(!bA){aE()}}}};this.setConsentGiven=function(){bA=true;bX(cL,bo,cX);var dk,dj;for(dk=0;dk<cJ.length;dk++){dj=typeof cJ[dk];if(dj==="string"){bE(cJ[dk],bI)}else{if(dj==="object"){df(cJ[dk],bI)}}}cJ=[]};this.rememberConsentGiven=function(dk){if(dk){dk=dk*60*60*1000}else{dk=30*365*24*60*60*1000}this.setConsentGiven();var dj=new Date().getTime();de(bd,dj,dk,bo,cX,bR)};this.forgetConsentGiven=function(){var dj=30*365*24*60*60*1000;bX(bd,bo,cX);de(cL,new Date().getTime(),dj,bo,cX,bR);this.requireConsent()};this.isUserOptedOut=function(){return !bA};this.optUserOut=this.forgetConsentGiven;this.forgetUserOptOut=this.rememberConsentGiven;
73
+ e.trigger("TrackerSetup",[this])}function H(){return{push:af}}function c(au,at){var av={};var aq,ar;for(aq=0;aq<at.length;aq++){var ao=at[aq];av[ao]=1;for(ar=0;ar<au.length;ar++){if(au[ar]&&au[ar][0]){var ap=au[ar][0];if(ao===ap){af(au[ar]);delete au[ar];if(av[ap]>1&&ap!=="addTracker"){ak("The method "+ap+' is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: https://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')}av[ap]++}}}}return au}var C=["addTracker","disableCookies","setTrackerUrl","setAPIUrl","enableCrossDomainLinking","setCrossDomainLinkingTimeout","setSessionCookieTimeout","setVisitorCookieTimeout","setSecureCookie","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","alwaysUseSendBeacon","enableLinkTracking","requireConsent","setConsentGiven"];function ad(ao,aq){var ap=new Q(ao,aq);I.push(ap);_paq=c(_paq,C);for(E=0;E<_paq.length;E++){if(_paq[E]){af(_paq[E])
74
+ }}_paq=new H();e.trigger("TrackerAdded",[ap]);return ap}an(T,"beforeunload",ai,false);an(T,"message",function(au){if(!au||!au.origin){return}var aw,ar,ap;var ax=d(au.origin);var at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){ap=d(at[ar].getPiwikUrl());if(ap===ax){aw=at[ar];break}}if(!aw){return}var aq=null;try{aq=JSON.parse(au.data)}catch(av){return}if(!aq){return}function ao(aA){var aC=G.getElementsByTagName("iframe");for(ar=0;ar<aC.length;ar++){var aB=aC[ar];var ay=d(aB.src);if(aB.contentWindow&&J(aB.contentWindow.postMessage)&&ay===ax){var az=JSON.stringify(aA);aB.contentWindow.postMessage(az,"*")}}}if(J(aq.maq_initial_value)){ao({maq_opted_in:aq.maq_initial_value&&aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}else{if(J(aq.maq_opted_in)){at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){aw=at[ar];if(aq.maq_opted_in){aw.rememberConsentGiven()}else{aw.forgetConsentGiven()}}ao({maq_confirm_opted_in:aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})
75
+ }}},false);Date.prototype.getTimeAlias=Date.prototype.getTime;e={initialized:false,JSON:JSON_PIWIK,DOM:{addEventListener:function(ar,aq,ap,ao){var at=typeof ao;if(at==="undefined"){ao=false}an(ar,aq,ap,ao)},onLoad:n,onReady:q,isNodeVisible:j,isOrWasNodeVisible:v.isNodeVisible},on:function(ap,ao){if(!y[ap]){y[ap]=[]}y[ap].push(ao)},off:function(aq,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){if(y[aq][ao]===ap){y[aq].splice(ao,1)}}},trigger:function(aq,ar,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){y[aq][ao].apply(ap||T,ar)}},addPlugin:function(ao,ap){b[ao]=ap},getTracker:function(ao,ap){if(!J(ap)){ap=this.getAsyncTracker().getSiteId()}if(!J(ao)){ao=this.getAsyncTracker().getTrackerUrl()}return new Q(ao,ap)},getAsyncTrackers:function(){return I},addTracker:function(ao,aq){var ap;if(!I.length){ap=ad(ao,aq)}else{ap=I[0].addTracker(ao,aq)}return ap},getAsyncTracker:function(ap,at){var ar;if(I&&I.length&&I[0]){ar=I[0]}else{return ad(ap,at)}if(!at&&!ap){return ar
76
+ }if((!J(at)||null===at)&&ar){at=ar.getSiteId()}if((!J(ap)||null===ap)&&ar){ap=ar.getTrackerUrl()}var aq,ao=0;for(ao;ao<I.length;ao++){aq=I[ao];if(aq&&String(aq.getSiteId())===String(at)&&aq.getTrackerUrl()===ap){return aq}}},retryMissedPluginCalls:function(){var ap=ah;ah=[];var ao=0;for(ao;ao<ap.length;ao++){af(ap[ao])}}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return e});define("matomo",[],function(){return e})}return e}())}
77
  /*!!! pluginTrackerHook */
78
+ (function(){function b(){if("object"!==typeof _paq){return false}var c=typeof _paq.length;if("undefined"===c){return false}return !!_paq.length}if(window&&"object"===typeof window.piwikPluginAsyncInit&&window.piwikPluginAsyncInit.length){var a=0;for(a;a<window.piwikPluginAsyncInit.length;a++){if(typeof window.piwikPluginAsyncInit[a]==="function"){window.piwikPluginAsyncInit[a]()}}}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}if(!window.Piwik.getAsyncTrackers().length){if(b()){window.Piwik.addTracker()
79
+ }else{_paq={push:function(c){var d=typeof console;if(d!=="undefined"&&console&&console.error){console.error("_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js. Alternatively, you can create a tracker via Matomo.addTracker() manually and then use _paq.push but it may not fully work as tracker methods may not be executed in the correct order.",c)}}}}}window.Piwik.trigger("PiwikInitialized",[]);window.Piwik.initialized=true}());(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=window.Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=window.Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");
80
+ if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}}
81
  /*!! @license-end */;
app/matomo.js CHANGED
@@ -59,22 +59,23 @@ v.setHrefAttribute(dq,dk);return true}return false}function aM(dk){if(!dk||!dk.l
59
  return false}var dk=cs(cO(dl,dn,dj,dm),dq,"event");bE(dk,bI,dp)}function b7(dj,dm,dk,dn){var dl=cs("search="+t(dj)+(dm?"&search_cat="+t(dm):"")+(J(dk)?"&search_count="+dk:""),dn,"sitesearch");bE(dl,bI)}function cT(dj,dn,dm,dl){var dk=cs("idgoal="+dj+(dn?"&revenue="+dn:""),dm,"goal");bE(dk,bI,dl)}function c1(dm,dj,dr,dq,dl){var dp=dj+"="+t(b1(dm));var dk=ct(dl,"click",dm);if(dk){dp+="&"+dk}var dn=cs(dp,dr,"link");bE(dn,bI,dq)}function bT(dk,dj){if(dk!==""){return dk+dj.charAt(0).toUpperCase()+dj.slice(1)}return dj}function cg(dp){var dn,dj,dm=["","webkit","ms","moz"],dl;if(!be){for(dj=0;dj<dm.length;dj++){dl=dm[dj];if(Object.prototype.hasOwnProperty.call(G,bT(dl,"hidden"))){if(G[bT(dl,"visibilityState")]==="prerender"){dn=true}break}}}if(dn){an(G,dl+"visibilitychange",function dk(){G.removeEventListener(dl+"visibilitychange",dk,false);dp()});return}dp()}function bq(){var dk=aY().uuid;var dj=aI();return dk+dj}function ci(dj){if(!dj){return}if(!ae.hasNodeAttribute(dj,"href")){return}var dk=ae.getAttributeValueFromNode(dj,"href");
60
  if(!dk||aU(dk)){return}dk=k(dk,av);var dl=bq();dk=F(dk,av,dl);ae.setAnyAttribute(dj,"href",dk)}function aA(dm){var dn=ae.getAttributeValueFromNode(dm,"href");if(!dn){return false}dn=String(dn);var dk=dn.indexOf("//")===0||dn.indexOf("http://")===0||dn.indexOf("https://")===0;if(!dk){return false}var dj=dm.pathname||ck(dm.href);var dl=(dm.hostname||d(dm.href)).toLowerCase();if(ar(dl,dj)){if(!cF(cU,L(dl))){return true}return false}return false}function cE(dj){var dk=dc(dj);if(dk&&dk.type){dk.href=p(dk.href);c1(dk.href,dk.type,undefined,null,dj);return}if(cM){dj=au(dj);if(aA(dj)){ci(dj)}}}function cv(){return G.all&&!G.addEventListener}function cV(dj){var dl=dj.which;var dk=(typeof dj.button);if(!dl&&dk!=="undefined"){if(cv()){if(dj.button&1){dl=1}else{if(dj.button&2){dl=3}else{if(dj.button&4){dl=2}}}}else{if(dj.button===0||dj.button==="0"){dl=1}else{if(dj.button&1){dl=2}else{if(dj.button&2){dl=3}}}}}return dl}function bS(dj){switch(cV(dj)){case 1:return"left";case 2:return"middle";case 3:return"right"
61
  }}function a1(dj){return dj.target||dj.srcElement}function aB(dj){return function(dm){dm=dm||T.event;var dl=bS(dm);var dn=a1(dm);if(dm.type==="click"){var dk=false;if(dj&&dl==="middle"){dk=true}if(dn&&!dk){cE(dn)}}else{if(dm.type==="mousedown"){if(dl==="middle"&&dn){aR=dl;bz=dn}else{aR=bz=null}}else{if(dm.type==="mouseup"){if(dl===aR&&dn===bz){cE(dn)}aR=bz=null}else{if(dm.type==="contextmenu"){cE(dn)}}}}}}function aq(dl,dk){var dj=typeof dk;if(dj==="undefined"){dk=true}an(dl,"click",aB(dk),false);if(dk){an(dl,"mouseup",aB(dk),false);an(dl,"mousedown",aB(dk),false);an(dl,"contextmenu",aB(dk),false)}}function bC(dl,dn){ap=true;var dm,dk=a0(by,"ignore"),dp=G.links,dj=null,dq=null;if(dp){for(dm=0;dm<dp.length;dm++){dj=dp[dm];if(!dk.test(dj.className)){dq=typeof dj.piwikTrackers;if("undefined"===dq){dj.piwikTrackers=[]}if(-1===M(dj.piwikTrackers,dn)){dj.piwikTrackers.push(dn);aq(dj,dl)}}}}}function aS(dk,dn,dp){if(ce){return true}ce=true;var dq=false;var dm,dl;function dj(){dq=true}n(function(){function dr(dt){setTimeout(function(){if(!ce){return
62
- }dq=false;dp.trackVisibleContentImpressions();dr(dt)},dt)}function ds(dt){setTimeout(function(){if(!ce){return}if(dq){dq=false;dp.trackVisibleContentImpressions()}ds(dt)},dt)}if(dk){dm=["scroll","resize"];for(dl=0;dl<dm.length;dl++){if(G.addEventListener){G.addEventListener(dm[dl],dj,false)}else{T.attachEvent("on"+dm[dl],dj)}}ds(100)}if(dn&&dn>0){dn=parseInt(dn,10);dr(dn)}})}var bB={enabled:true,requests:[],timeout:null,interval:2500,sendRequests:function(){var dj=this.requests;this.requests=[];if(dj.length===1){bE(dj[0],bI)}else{df(dj,bI)}},push:function(dj){if(!dj){return}if(m||!this.enabled){bE(dj,bI);return}bB.requests.push(dj);if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.timeout=setTimeout(function(){bB.timeout=null;bB.sendRequests()},bB.interval);var dk="RequestQueue"+aw;if(!Object.prototype.hasOwnProperty.call(b,dk)){b[dk]={unload:function(){if(bB.timeout){clearTimeout(bB.timeout)}bB.sendRequests()}}}}};bh();aL();this.hasConsent=function(){return bA};this.getVisitorId=function(){return aY().uuid
63
- };this.getVisitorInfo=function(){return cN()};this.getAttributionInfo=function(){return bL()};this.getAttributionCampaignName=function(){return bL()[0]};this.getAttributionCampaignKeyword=function(){return bL()[1]};this.getAttributionReferrerTimestamp=function(){return bL()[2]};this.getAttributionReferrerUrl=function(){return bL()[3]};this.setTrackerUrl=function(dj){aD=dj};this.getTrackerUrl=function(){return aD};this.getPiwikUrl=function(){return O(this.getTrackerUrl(),bG)};this.addTracker=function(dj,dl){if(!J(dj)||null===dj){dj=this.getTrackerUrl()}var dk=new Q(dj,dl);I.push(dk);e.trigger("TrackerAdded",[this]);return dk};this.getSiteId=function(){return b5};this.setSiteId=function(dj){b2(dj)};this.resetUserId=function(){bx=""};this.setUserId=function(dj){if(Y(dj)){bx=dj}};this.getUserId=function(){return bx};this.setCustomData=function(dj,dk){if(W(dj)){ao=dj}else{if(!ao){ao={}}ao[dj]=dk}};this.getCustomData=function(){return ao};this.setCustomRequestProcessing=function(dj){ca=dj};this.appendToTrackingUrl=function(dj){cZ=dj
64
- };this.getRequest=function(dj){return cs(dj)};this.addPlugin=function(dj,dk){b[dj]=dk};this.setCustomDimension=function(dj,dk){dj=parseInt(dj,10);if(dj>0){if(!J(dk)){dk=""}if(!w(dk)){dk=String(dk)}bl[dj]=dk}};this.getCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0&&Object.prototype.hasOwnProperty.call(bl,dj)){return bl[dj]}};this.deleteCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0){delete bl[dj]}};this.setCustomVariable=function(dk,dj,dn,dl){var dm;if(!J(dl)){dl="visit"}if(!J(dj)){return}if(!J(dn)){dn=""}if(dk>0){dj=!w(dj)?String(dj):dj;dn=!w(dn)?String(dn):dn;dm=[dj.slice(0,bs),dn.slice(0,bs)];if(dl==="visit"||dl===2){cD();aQ[dk]=dm}else{if(dl==="page"||dl===3){bV[dk]=dm}else{if(dl==="event"){cl[dk]=dm}}}}};this.getCustomVariable=function(dk,dl){var dj;if(!J(dl)){dl="visit"}if(dl==="page"||dl===3){dj=bV[dk]}else{if(dl==="event"){dj=cl[dk]}else{if(dl==="visit"||dl===2){cD();dj=aQ[dk]}}}if(!J(dj)||(dj&&dj[0]==="")){return false}return dj};this.deleteCustomVariable=function(dj,dk){if(this.getCustomVariable(dj,dk)){this.setCustomVariable(dj,"","",dk)
65
- }};this.deleteCustomVariables=function(dj){if(dj==="page"||dj===3){bV={}}else{if(dj==="event"){cl={}}else{if(dj==="visit"||dj===2){aQ={}}}}};this.storeCustomVariablesInCookie=function(){bP=true};this.setLinkTrackingTimer=function(dj){bI=dj};this.getLinkTrackingTimer=function(){return bI};this.setDownloadExtensions=function(dj){if(w(dj)){dj=dj.split("|")}c6=dj};this.addDownloadExtensions=function(dk){var dj;if(w(dk)){dk=dk.split("|")}for(dj=0;dj<dk.length;dj++){c6.push(dk[dj])}};this.removeDownloadExtensions=function(dl){var dk,dj=[];if(w(dl)){dl=dl.split("|")}for(dk=0;dk<c6.length;dk++){if(M(dl,c6[dk])===-1){dj.push(c6[dk])}}c6=dj};this.setDomains=function(dj){ax=w(dj)?[dj]:dj;var dn=false,dl=0,dk;for(dl;dl<ax.length;dl++){dk=String(ax[dl]);if(cF(cU,L(dk))){dn=true;break}var dm=ck(dk);if(dm&&dm!=="/"&&dm!=="/*"){dn=true;break}}if(!dn){ax.push(cU)}};this.enableCrossDomainLinking=function(){cM=true};this.disableCrossDomainLinking=function(){cM=false};this.isCrossDomainLinkingEnabled=function(){return cM
66
- };this.setCrossDomainLinkingTimeout=function(dj){aZ=dj};this.getCrossDomainLinkingUrlParameter=function(){return t(av)+"="+t(bq())};this.setIgnoreClasses=function(dj){by=w(dj)?[dj]:dj};this.setRequestMethod=function(dj){da=dj||ch};this.setRequestContentType=function(dj){cw=dj||aH};this.setReferrerUrl=function(dj){bm=dj};this.setCustomUrl=function(dj){a4=bU(bM,dj)};this.getCurrentUrl=function(){return a4||bM};this.setDocumentTitle=function(dj){bi=dj};this.setAPIUrl=function(dj){bG=dj};this.setDownloadClasses=function(dj){bK=w(dj)?[dj]:dj};this.setLinkClasses=function(dj){a8=w(dj)?[dj]:dj};this.setCampaignNameKey=function(dj){cq=w(dj)?[dj]:dj};this.setCampaignKeywordKey=function(dj){bF=w(dj)?[dj]:dj};this.discardHashTag=function(dj){bO=dj};this.setCookieNamePrefix=function(dj){bj=dj;aQ=bW()};this.setCookieDomain=function(dj){var dk=L(dj);if(bv(dk)){cX=dk;bh()}};this.getCookieDomain=function(){return cX};this.hasCookies=function(){return"1"===b4()};this.setSessionCookie=function(dl,dk,dj){if(!dl){throw new Error("Missing cookie name")
67
- }if(!J(dj)){dj=co}bt.push(dl);de(aT(dl),dk,dj,bo,cX)};this.getCookie=function(dk){var dj=aC(aT(dk));if(dj===0){return null}return dj};this.setCookiePath=function(dj){bo=dj;bh()};this.getCookiePath=function(dj){return bo};this.setVisitorCookieTimeout=function(dj){cI=dj*1000};this.setSessionCookieTimeout=function(dj){co=dj*1000};this.getSessionCookieTimeout=function(){return co};this.setReferralCookieTimeout=function(dj){c5=dj*1000};this.setConversionAttributionFirstReferrer=function(dj){bu=dj};this.setSecureCookie=function(dj){bR=dj};this.disableCookies=function(){bk=true;c8.cookie="0";if(b5){aE()}};this.deleteCookies=function(){aE()};this.setDoNotTrack=function(dk){var dj=h.doNotTrack||h.msDoNotTrack;cP=dk&&(dj==="yes"||dj==="1");if(cP){this.disableCookies()}};this.alwaysUseSendBeacon=function(){cW=true};this.addListener=function(dk,dj){aq(dk,dj)};this.enableLinkTracking=function(dk){c9=true;var dj=this;cg(function(){q(function(){bC(dk,dj)})})};this.enableJSErrorTracking=function(){if(cS){return
68
- }cS=true;var dj=T.onerror;T.onerror=function(dp,dm,dl,dn,dk){cg(function(){var dq="JavaScript Errors";var dr=dm+":"+dl;if(dn){dr+=":"+dn}at(dq,dr,dp)});if(dj){return dj(dp,dm,dl,dn,dk)}return false}};this.disablePerformanceTracking=function(){a2=false};this.setGenerationTimeMs=function(dj){cm=parseInt(dj,10)};this.setVisitStandardLength=function(dj){dj=Math.max(dj,5);c7=dj};this.enableHeartBeatTimer=function(dj){dj=Math.max(dj,5);a5=(dj||15)*1000;if(cY!==null){dg()}};this.disableHeartBeatTimer=function(){bJ();if(a5||aN){if(T.removeEventListener){T.removeEventListener("focus",ba);T.removeEventListener("blur",ay)}else{if(T.detachEvent){T.detachEvent("onfocus",ba);T.detachEvent("onblur",ay)}}}a5=null;aN=false};this.killFrame=function(){if(T.location!==T.top.location){T.top.location=T.location}};this.redirectFile=function(dj){if(T.location.protocol==="file:"){T.location=dj}};this.setCountPreRendered=function(dj){be=dj};this.trackGoal=function(dj,dm,dl,dk){cg(function(){cT(dj,dm,dl,dk)})};this.trackLink=function(dk,dj,dm,dl){cg(function(){c1(dk,dj,dm,dl)
69
- })};this.getNumTrackedPageViews=function(){return cr};this.trackPageView=function(dj,dl,dk){b9=[];cJ=[];if(N(b5)){cg(function(){Z(aD,bG,b5)})}else{cg(function(){cr++;bZ(dj,dl,dk)})}};this.trackAllContentImpressions=function(){if(N(b5)){return}cg(function(){q(function(){var dj=v.findContentNodes();var dk=cy(dj);df(dk,bI)})})};this.trackVisibleContentImpressions=function(dj,dk){if(N(b5)){return}if(!J(dj)){dj=true}if(!J(dk)){dk=750}aS(dj,dk,this);cg(function(){n(function(){var dl=v.findContentNodes();var dm=a9(dl);df(dm,bI)})})};this.trackContentImpression=function(dl,dj,dk){if(N(b5)){return}dl=a(dl);dj=a(dj);dk=a(dk);if(!dl){return}dj=dj||"Unknown";cg(function(){var dm=aF(dl,dj,dk);bE(dm,bI)})};this.trackContentImpressionsWithinNode=function(dj){if(N(b5)||!dj){return}cg(function(){if(ce){n(function(){var dk=v.findContentNodesWithinNode(dj);var dl=a9(dk);df(dl,bI)})}else{q(function(){var dk=v.findContentNodesWithinNode(dj);var dl=cy(dk);df(dl,bI)})}})};this.trackContentInteraction=function(dl,dm,dj,dk){if(N(b5)){return
70
- }dl=a(dl);dm=a(dm);dj=a(dj);dk=a(dk);if(!dl||!dm){return}dj=dj||"Unknown";cg(function(){var dn=aP(dl,dm,dj,dk);if(dn){bE(dn,bI)}})};this.trackContentInteractionNode=function(dk,dj){if(N(b5)||!dk){return}cg(function(){var dl=db(dk,dj);if(dl){bE(dl,bI)}})};this.logAllContentBlocksOnPage=function(){var dl=v.findContentNodes();var dj=v.collectContent(dl);var dk=typeof console;if(dk!=="undefined"&&console&&console.log){console.log(dj)}};this.trackEvent=function(dk,dm,dj,dl,dp,dn){cg(function(){at(dk,dm,dj,dl,dp,dn)})};this.trackSiteSearch=function(dj,dl,dk,dm){b9=[];cg(function(){b7(dj,dl,dk,dm)})};this.setEcommerceView=function(dm,dj,dl,dk){if(Y(dl)){dl=String(dl)}if(!J(dl)||dl===null||dl===false||!dl.length){dl=""}else{if(dl instanceof Array){dl=JSON_PIWIK.stringify(dl)}}bV[5]=["_pkc",dl];if(J(dk)&&dk!==null&&dk!==false&&String(dk).length){bV[2]=["_pkp",dk]}if(!Y(dm)&&!Y(dj)){return}if(Y(dm)){bV[3]=["_pks",dm]}if(!Y(dj)){dj=""}bV[4]=["_pkn",dj]};this.getEcommerceItems=function(){return JSON.parse(JSON.stringify(c0))
71
- };this.addEcommerceItem=function(dn,dj,dl,dk,dm){if(Y(dn)){c0[dn]=[String(dn),dj,dl,dk,dm]}};this.removeEcommerceItem=function(dj){if(Y(dj)){dj=String(dj);delete c0[dj]}};this.clearEcommerceCart=function(){c0={}};this.trackEcommerceOrder=function(dj,dn,dm,dl,dk,dp){bY(dj,dn,dm,dl,dk,dp)};this.trackEcommerceCartUpdate=function(dj){br(dj)};this.trackRequest=function(dk,dm,dl,dj){cg(function(){var dn=cs(dk,dm,dj);bE(dn,bI,dl)})};this.ping=function(){this.trackRequest("ping=1",null,null,"ping")};this.disableQueueRequest=function(){bB.enabled=false};this.setRequestQueueInterval=function(dj){if(dj<1000){throw new Error("Request queue interval needs to be at least 1000ms")}bB.interval=dj};this.queueRequest=function(dj){cg(function(){var dk=cs(dj);bB.push(dk)})};this.isConsentRequired=function(){return cz};this.getRememberedConsent=function(){var dj=aC(bd);if(aC(cL)){if(dj){bX(bd,bo,cX)}return null}if(!dj||dj===0){return null}return dj};this.hasRememberedConsent=function(){return !!this.getRememberedConsent()
72
- };this.requireConsent=function(){cz=true;bA=this.hasRememberedConsent();x++;b["CoreConsent"+x]={unload:function(){if(!bA){aE()}}}};this.setConsentGiven=function(){bA=true;bX(cL,bo,cX);var dk,dj;for(dk=0;dk<cJ.length;dk++){dj=typeof cJ[dk];if(dj==="string"){bE(cJ[dk],bI)}else{if(dj==="object"){df(cJ[dk],bI)}}}cJ=[]};this.rememberConsentGiven=function(dk){if(dk){dk=dk*60*60*1000}else{dk=30*365*24*60*60*1000}this.setConsentGiven();var dj=new Date().getTime();de(bd,dj,dk,bo,cX,bR)};this.forgetConsentGiven=function(){var dj=30*365*24*60*60*1000;bX(bd,bo,cX);de(cL,new Date().getTime(),dj,bo,cX,bR);this.requireConsent()};this.isUserOptedOut=function(){return !bA};this.optUserOut=this.forgetConsentGiven;this.forgetUserOptOut=this.rememberConsentGiven;e.trigger("TrackerSetup",[this])}function H(){return{push:af}}function c(au,at){var av={};var aq,ar;for(aq=0;aq<at.length;aq++){var ao=at[aq];av[ao]=1;for(ar=0;ar<au.length;ar++){if(au[ar]&&au[ar][0]){var ap=au[ar][0];if(ao===ap){af(au[ar]);delete au[ar];
73
- if(av[ap]>1&&ap!=="addTracker"){ak("The method "+ap+' is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: https://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')}av[ap]++}}}}return au}var C=["addTracker","disableCookies","setTrackerUrl","setAPIUrl","enableCrossDomainLinking","setCrossDomainLinkingTimeout","setSessionCookieTimeout","setVisitorCookieTimeout","setSecureCookie","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","alwaysUseSendBeacon","enableLinkTracking","requireConsent","setConsentGiven"];function ad(ao,aq){var ap=new Q(ao,aq);I.push(ap);_paq=c(_paq,C);for(E=0;E<_paq.length;E++){if(_paq[E]){af(_paq[E])}}_paq=new H();e.trigger("TrackerAdded",[ap]);return ap}an(T,"beforeunload",ai,false);an(T,"message",function(au){if(!au||!au.origin){return}var aw,ar,ap;var ax=d(au.origin);var at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){ap=d(at[ar].getPiwikUrl());
74
- if(ap===ax){aw=at[ar];break}}if(!aw){return}var aq=null;try{aq=JSON.parse(au.data)}catch(av){return}if(!aq){return}function ao(aA){var aC=G.getElementsByTagName("iframe");for(ar=0;ar<aC.length;ar++){var aB=aC[ar];var ay=d(aB.src);if(aB.contentWindow&&J(aB.contentWindow.postMessage)&&ay===ax){var az=JSON.stringify(aA);aB.contentWindow.postMessage(az,"*")}}}if(J(aq.maq_initial_value)){ao({maq_opted_in:aq.maq_initial_value&&aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}else{if(J(aq.maq_opted_in)){at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){aw=at[ar];if(aq.maq_opted_in){aw.rememberConsentGiven()}else{aw.forgetConsentGiven()}}ao({maq_confirm_opted_in:aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}}},false);Date.prototype.getTimeAlias=Date.prototype.getTime;e={initialized:false,JSON:JSON_PIWIK,DOM:{addEventListener:function(ar,aq,ap,ao){var at=typeof ao;if(at==="undefined"){ao=false}an(ar,aq,ap,ao)},onLoad:n,onReady:q,isNodeVisible:j,isOrWasNodeVisible:v.isNodeVisible},on:function(ap,ao){if(!y[ap]){y[ap]=[]
75
- }y[ap].push(ao)},off:function(aq,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){if(y[aq][ao]===ap){y[aq].splice(ao,1)}}},trigger:function(aq,ar,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){y[aq][ao].apply(ap||T,ar)}},addPlugin:function(ao,ap){b[ao]=ap},getTracker:function(ao,ap){if(!J(ap)){ap=this.getAsyncTracker().getSiteId()}if(!J(ao)){ao=this.getAsyncTracker().getTrackerUrl()}return new Q(ao,ap)},getAsyncTrackers:function(){return I},addTracker:function(ao,aq){var ap;if(!I.length){ap=ad(ao,aq)}else{ap=I[0].addTracker(ao,aq)}return ap},getAsyncTracker:function(ap,at){var ar;if(I&&I.length&&I[0]){ar=I[0]}else{return ad(ap,at)}if(!at&&!ap){return ar}if((!J(at)||null===at)&&ar){at=ar.getSiteId()}if((!J(ap)||null===ap)&&ar){ap=ar.getTrackerUrl()}var aq,ao=0;for(ao;ao<I.length;ao++){aq=I[ao];if(aq&&String(aq.getSiteId())===String(at)&&aq.getTrackerUrl()===ap){return aq}}},retryMissedPluginCalls:function(){var ap=ah;ah=[];var ao=0;for(ao;ao<ap.length;ao++){af(ap[ao])
76
- }}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return e});define("matomo",[],function(){return e})}return e}())}
77
  /*!!! pluginTrackerHook */
78
- (function(){function b(){if("object"!==typeof _paq){return false}var c=typeof _paq.length;if("undefined"===c){return false}return !!_paq.length}if(window&&"object"===typeof window.piwikPluginAsyncInit&&window.piwikPluginAsyncInit.length){var a=0;for(a;a<window.piwikPluginAsyncInit.length;a++){if(typeof window.piwikPluginAsyncInit[a]==="function"){window.piwikPluginAsyncInit[a]()}}}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}if(!window.Piwik.getAsyncTrackers().length){if(b()){window.Piwik.addTracker()}else{_paq={push:function(c){var d=typeof console;if(d!=="undefined"&&console&&console.error){console.error("_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js. Alternatively, you can create a tracker via Matomo.addTracker() manually and then use _paq.push but it may not fully work as tracker methods may not be executed in the correct order.",c)
79
- }}}}}window.Piwik.trigger("PiwikInitialized",[]);window.Piwik.initialized=true}());(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=window.Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=window.Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}}
 
80
  /*!! @license-end */;
59
  return false}var dk=cs(cO(dl,dn,dj,dm),dq,"event");bE(dk,bI,dp)}function b7(dj,dm,dk,dn){var dl=cs("search="+t(dj)+(dm?"&search_cat="+t(dm):"")+(J(dk)?"&search_count="+dk:""),dn,"sitesearch");bE(dl,bI)}function cT(dj,dn,dm,dl){var dk=cs("idgoal="+dj+(dn?"&revenue="+dn:""),dm,"goal");bE(dk,bI,dl)}function c1(dm,dj,dr,dq,dl){var dp=dj+"="+t(b1(dm));var dk=ct(dl,"click",dm);if(dk){dp+="&"+dk}var dn=cs(dp,dr,"link");bE(dn,bI,dq)}function bT(dk,dj){if(dk!==""){return dk+dj.charAt(0).toUpperCase()+dj.slice(1)}return dj}function cg(dp){var dn,dj,dm=["","webkit","ms","moz"],dl;if(!be){for(dj=0;dj<dm.length;dj++){dl=dm[dj];if(Object.prototype.hasOwnProperty.call(G,bT(dl,"hidden"))){if(G[bT(dl,"visibilityState")]==="prerender"){dn=true}break}}}if(dn){an(G,dl+"visibilitychange",function dk(){G.removeEventListener(dl+"visibilitychange",dk,false);dp()});return}dp()}function bq(){var dk=aY().uuid;var dj=aI();return dk+dj}function ci(dj){if(!dj){return}if(!ae.hasNodeAttribute(dj,"href")){return}var dk=ae.getAttributeValueFromNode(dj,"href");
60
  if(!dk||aU(dk)){return}dk=k(dk,av);var dl=bq();dk=F(dk,av,dl);ae.setAnyAttribute(dj,"href",dk)}function aA(dm){var dn=ae.getAttributeValueFromNode(dm,"href");if(!dn){return false}dn=String(dn);var dk=dn.indexOf("//")===0||dn.indexOf("http://")===0||dn.indexOf("https://")===0;if(!dk){return false}var dj=dm.pathname||ck(dm.href);var dl=(dm.hostname||d(dm.href)).toLowerCase();if(ar(dl,dj)){if(!cF(cU,L(dl))){return true}return false}return false}function cE(dj){var dk=dc(dj);if(dk&&dk.type){dk.href=p(dk.href);c1(dk.href,dk.type,undefined,null,dj);return}if(cM){dj=au(dj);if(aA(dj)){ci(dj)}}}function cv(){return G.all&&!G.addEventListener}function cV(dj){var dl=dj.which;var dk=(typeof dj.button);if(!dl&&dk!=="undefined"){if(cv()){if(dj.button&1){dl=1}else{if(dj.button&2){dl=3}else{if(dj.button&4){dl=2}}}}else{if(dj.button===0||dj.button==="0"){dl=1}else{if(dj.button&1){dl=2}else{if(dj.button&2){dl=3}}}}}return dl}function bS(dj){switch(cV(dj)){case 1:return"left";case 2:return"middle";case 3:return"right"
61
  }}function a1(dj){return dj.target||dj.srcElement}function aB(dj){return function(dm){dm=dm||T.event;var dl=bS(dm);var dn=a1(dm);if(dm.type==="click"){var dk=false;if(dj&&dl==="middle"){dk=true}if(dn&&!dk){cE(dn)}}else{if(dm.type==="mousedown"){if(dl==="middle"&&dn){aR=dl;bz=dn}else{aR=bz=null}}else{if(dm.type==="mouseup"){if(dl===aR&&dn===bz){cE(dn)}aR=bz=null}else{if(dm.type==="contextmenu"){cE(dn)}}}}}}function aq(dl,dk){var dj=typeof dk;if(dj==="undefined"){dk=true}an(dl,"click",aB(dk),false);if(dk){an(dl,"mouseup",aB(dk),false);an(dl,"mousedown",aB(dk),false);an(dl,"contextmenu",aB(dk),false)}}function bC(dl,dn){ap=true;var dm,dk=a0(by,"ignore"),dp=G.links,dj=null,dq=null;if(dp){for(dm=0;dm<dp.length;dm++){dj=dp[dm];if(!dk.test(dj.className)){dq=typeof dj.piwikTrackers;if("undefined"===dq){dj.piwikTrackers=[]}if(-1===M(dj.piwikTrackers,dn)){dj.piwikTrackers.push(dn);aq(dj,dl)}}}}}function aS(dk,dn,dp){if(ce){return true}ce=true;var dq=false;var dm,dl;function dj(){dq=true}n(function(){function dr(dt){setTimeout(function(){if(!ce){return
62
+ }dq=false;dp.trackVisibleContentImpressions();dr(dt)},dt)}function ds(dt){setTimeout(function(){if(!ce){return}if(dq){dq=false;dp.trackVisibleContentImpressions()}ds(dt)},dt)}if(dk){dm=["scroll","resize"];for(dl=0;dl<dm.length;dl++){if(G.addEventListener){G.addEventListener(dm[dl],dj,false)}else{T.attachEvent("on"+dm[dl],dj)}}ds(100)}if(dn&&dn>0){dn=parseInt(dn,10);dr(dn)}})}var bB={enabled:true,requests:[],timeout:null,interval:2500,sendRequests:function(){var dj=this.requests;this.requests=[];if(dj.length===1){bE(dj[0],bI)}else{df(dj,bI)}},canQueue:function(){return !m&&this.enabled},pushMultiple:function(dk){if(!this.canQueue()){df(dk,bI);return}var dj;for(dj=0;dj<dk.length;dj++){this.push(dk[dj])}},push:function(dj){if(!dj){return}if(!this.canQueue()){bE(dj,bI);return}bB.requests.push(dj);if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.timeout=setTimeout(function(){bB.timeout=null;bB.sendRequests()},bB.interval);var dk="RequestQueue"+aw;if(!Object.prototype.hasOwnProperty.call(b,dk)){b[dk]={unload:function(){if(bB.timeout){clearTimeout(bB.timeout)
63
+ }bB.sendRequests()}}}}};bh();aL();this.hasConsent=function(){return bA};this.getVisitorId=function(){return aY().uuid};this.getVisitorInfo=function(){return cN()};this.getAttributionInfo=function(){return bL()};this.getAttributionCampaignName=function(){return bL()[0]};this.getAttributionCampaignKeyword=function(){return bL()[1]};this.getAttributionReferrerTimestamp=function(){return bL()[2]};this.getAttributionReferrerUrl=function(){return bL()[3]};this.setTrackerUrl=function(dj){aD=dj};this.getTrackerUrl=function(){return aD};this.getPiwikUrl=function(){return O(this.getTrackerUrl(),bG)};this.addTracker=function(dj,dl){if(!J(dj)||null===dj){dj=this.getTrackerUrl()}var dk=new Q(dj,dl);I.push(dk);e.trigger("TrackerAdded",[this]);return dk};this.getSiteId=function(){return b5};this.setSiteId=function(dj){b2(dj)};this.resetUserId=function(){bx=""};this.setUserId=function(dj){if(Y(dj)){bx=dj}};this.getUserId=function(){return bx};this.setCustomData=function(dj,dk){if(W(dj)){ao=dj}else{if(!ao){ao={}
64
+ }ao[dj]=dk}};this.getCustomData=function(){return ao};this.setCustomRequestProcessing=function(dj){ca=dj};this.appendToTrackingUrl=function(dj){cZ=dj};this.getRequest=function(dj){return cs(dj)};this.addPlugin=function(dj,dk){b[dj]=dk};this.setCustomDimension=function(dj,dk){dj=parseInt(dj,10);if(dj>0){if(!J(dk)){dk=""}if(!w(dk)){dk=String(dk)}bl[dj]=dk}};this.getCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0&&Object.prototype.hasOwnProperty.call(bl,dj)){return bl[dj]}};this.deleteCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0){delete bl[dj]}};this.setCustomVariable=function(dk,dj,dn,dl){var dm;if(!J(dl)){dl="visit"}if(!J(dj)){return}if(!J(dn)){dn=""}if(dk>0){dj=!w(dj)?String(dj):dj;dn=!w(dn)?String(dn):dn;dm=[dj.slice(0,bs),dn.slice(0,bs)];if(dl==="visit"||dl===2){cD();aQ[dk]=dm}else{if(dl==="page"||dl===3){bV[dk]=dm}else{if(dl==="event"){cl[dk]=dm}}}}};this.getCustomVariable=function(dk,dl){var dj;if(!J(dl)){dl="visit"}if(dl==="page"||dl===3){dj=bV[dk]}else{if(dl==="event"){dj=cl[dk]
65
+ }else{if(dl==="visit"||dl===2){cD();dj=aQ[dk]}}}if(!J(dj)||(dj&&dj[0]==="")){return false}return dj};this.deleteCustomVariable=function(dj,dk){if(this.getCustomVariable(dj,dk)){this.setCustomVariable(dj,"","",dk)}};this.deleteCustomVariables=function(dj){if(dj==="page"||dj===3){bV={}}else{if(dj==="event"){cl={}}else{if(dj==="visit"||dj===2){aQ={}}}}};this.storeCustomVariablesInCookie=function(){bP=true};this.setLinkTrackingTimer=function(dj){bI=dj};this.getLinkTrackingTimer=function(){return bI};this.setDownloadExtensions=function(dj){if(w(dj)){dj=dj.split("|")}c6=dj};this.addDownloadExtensions=function(dk){var dj;if(w(dk)){dk=dk.split("|")}for(dj=0;dj<dk.length;dj++){c6.push(dk[dj])}};this.removeDownloadExtensions=function(dl){var dk,dj=[];if(w(dl)){dl=dl.split("|")}for(dk=0;dk<c6.length;dk++){if(M(dl,c6[dk])===-1){dj.push(c6[dk])}}c6=dj};this.setDomains=function(dj){ax=w(dj)?[dj]:dj;var dn=false,dl=0,dk;for(dl;dl<ax.length;dl++){dk=String(ax[dl]);if(cF(cU,L(dk))){dn=true;break}var dm=ck(dk);
66
+ if(dm&&dm!=="/"&&dm!=="/*"){dn=true;break}}if(!dn){ax.push(cU)}};this.enableCrossDomainLinking=function(){cM=true};this.disableCrossDomainLinking=function(){cM=false};this.isCrossDomainLinkingEnabled=function(){return cM};this.setCrossDomainLinkingTimeout=function(dj){aZ=dj};this.getCrossDomainLinkingUrlParameter=function(){return t(av)+"="+t(bq())};this.setIgnoreClasses=function(dj){by=w(dj)?[dj]:dj};this.setRequestMethod=function(dj){da=dj||ch};this.setRequestContentType=function(dj){cw=dj||aH};this.setReferrerUrl=function(dj){bm=dj};this.setCustomUrl=function(dj){a4=bU(bM,dj)};this.getCurrentUrl=function(){return a4||bM};this.setDocumentTitle=function(dj){bi=dj};this.setAPIUrl=function(dj){bG=dj};this.setDownloadClasses=function(dj){bK=w(dj)?[dj]:dj};this.setLinkClasses=function(dj){a8=w(dj)?[dj]:dj};this.setCampaignNameKey=function(dj){cq=w(dj)?[dj]:dj};this.setCampaignKeywordKey=function(dj){bF=w(dj)?[dj]:dj};this.discardHashTag=function(dj){bO=dj};this.setCookieNamePrefix=function(dj){bj=dj;
67
+ aQ=bW()};this.setCookieDomain=function(dj){var dk=L(dj);if(bv(dk)){cX=dk;bh()}};this.getCookieDomain=function(){return cX};this.hasCookies=function(){return"1"===b4()};this.setSessionCookie=function(dl,dk,dj){if(!dl){throw new Error("Missing cookie name")}if(!J(dj)){dj=co}bt.push(dl);de(aT(dl),dk,dj,bo,cX)};this.getCookie=function(dk){var dj=aC(aT(dk));if(dj===0){return null}return dj};this.setCookiePath=function(dj){bo=dj;bh()};this.getCookiePath=function(dj){return bo};this.setVisitorCookieTimeout=function(dj){cI=dj*1000};this.setSessionCookieTimeout=function(dj){co=dj*1000};this.getSessionCookieTimeout=function(){return co};this.setReferralCookieTimeout=function(dj){c5=dj*1000};this.setConversionAttributionFirstReferrer=function(dj){bu=dj};this.setSecureCookie=function(dj){bR=dj};this.disableCookies=function(){bk=true;c8.cookie="0";if(b5){aE()}};this.deleteCookies=function(){aE()};this.setDoNotTrack=function(dk){var dj=h.doNotTrack||h.msDoNotTrack;cP=dk&&(dj==="yes"||dj==="1");if(cP){this.disableCookies()
68
+ }};this.alwaysUseSendBeacon=function(){cW=true};this.addListener=function(dk,dj){aq(dk,dj)};this.enableLinkTracking=function(dk){c9=true;var dj=this;cg(function(){q(function(){bC(dk,dj)});n(function(){bC(dk,dj)})})};this.enableJSErrorTracking=function(){if(cS){return}cS=true;var dj=T.onerror;T.onerror=function(dp,dm,dl,dn,dk){cg(function(){var dq="JavaScript Errors";var dr=dm+":"+dl;if(dn){dr+=":"+dn}at(dq,dr,dp)});if(dj){return dj(dp,dm,dl,dn,dk)}return false}};this.disablePerformanceTracking=function(){a2=false};this.setGenerationTimeMs=function(dj){cm=parseInt(dj,10)};this.setVisitStandardLength=function(dj){dj=Math.max(dj,5);c7=dj};this.enableHeartBeatTimer=function(dj){dj=Math.max(dj,5);a5=(dj||15)*1000;if(cY!==null){dg()}};this.disableHeartBeatTimer=function(){bJ();if(a5||aN){if(T.removeEventListener){T.removeEventListener("focus",ba);T.removeEventListener("blur",ay)}else{if(T.detachEvent){T.detachEvent("onfocus",ba);T.detachEvent("onblur",ay)}}}a5=null;aN=false};this.killFrame=function(){if(T.location!==T.top.location){T.top.location=T.location
69
+ }};this.redirectFile=function(dj){if(T.location.protocol==="file:"){T.location=dj}};this.setCountPreRendered=function(dj){be=dj};this.trackGoal=function(dj,dm,dl,dk){cg(function(){cT(dj,dm,dl,dk)})};this.trackLink=function(dk,dj,dm,dl){cg(function(){c1(dk,dj,dm,dl)})};this.getNumTrackedPageViews=function(){return cr};this.trackPageView=function(dj,dl,dk){b9=[];cJ=[];if(N(b5)){cg(function(){Z(aD,bG,b5)})}else{cg(function(){cr++;bZ(dj,dl,dk)})}};this.trackAllContentImpressions=function(){if(N(b5)){return}cg(function(){q(function(){var dj=v.findContentNodes();var dk=cy(dj);bB.pushMultiple(dk)})})};this.trackVisibleContentImpressions=function(dj,dk){if(N(b5)){return}if(!J(dj)){dj=true}if(!J(dk)){dk=750}aS(dj,dk,this);cg(function(){n(function(){var dl=v.findContentNodes();var dm=a9(dl);bB.pushMultiple(dm)})})};this.trackContentImpression=function(dl,dj,dk){if(N(b5)){return}dl=a(dl);dj=a(dj);dk=a(dk);if(!dl){return}dj=dj||"Unknown";cg(function(){var dm=aF(dl,dj,dk);bB.push(dm)})};this.trackContentImpressionsWithinNode=function(dj){if(N(b5)||!dj){return
70
+ }cg(function(){if(ce){n(function(){var dk=v.findContentNodesWithinNode(dj);var dl=a9(dk);bB.pushMultiple(dl)})}else{q(function(){var dk=v.findContentNodesWithinNode(dj);var dl=cy(dk);bB.pushMultiple(dl)})}})};this.trackContentInteraction=function(dl,dm,dj,dk){if(N(b5)){return}dl=a(dl);dm=a(dm);dj=a(dj);dk=a(dk);if(!dl||!dm){return}dj=dj||"Unknown";cg(function(){var dn=aP(dl,dm,dj,dk);if(dn){bB.push(dn)}})};this.trackContentInteractionNode=function(dk,dj){if(N(b5)||!dk){return}cg(function(){var dl=db(dk,dj);if(dl){bB.push(dl)}})};this.logAllContentBlocksOnPage=function(){var dl=v.findContentNodes();var dj=v.collectContent(dl);var dk=typeof console;if(dk!=="undefined"&&console&&console.log){console.log(dj)}};this.trackEvent=function(dk,dm,dj,dl,dp,dn){cg(function(){at(dk,dm,dj,dl,dp,dn)})};this.trackSiteSearch=function(dj,dl,dk,dm){b9=[];cg(function(){b7(dj,dl,dk,dm)})};this.setEcommerceView=function(dm,dj,dl,dk){if(Y(dl)){dl=String(dl)}if(!J(dl)||dl===null||dl===false||!dl.length){dl=""}else{if(dl instanceof Array){dl=JSON_PIWIK.stringify(dl)
71
+ }}bV[5]=["_pkc",dl];if(J(dk)&&dk!==null&&dk!==false&&String(dk).length){bV[2]=["_pkp",dk]}if(!Y(dm)&&!Y(dj)){return}if(Y(dm)){bV[3]=["_pks",dm]}if(!Y(dj)){dj=""}bV[4]=["_pkn",dj]};this.getEcommerceItems=function(){return JSON.parse(JSON.stringify(c0))};this.addEcommerceItem=function(dn,dj,dl,dk,dm){if(Y(dn)){c0[dn]=[String(dn),dj,dl,dk,dm]}};this.removeEcommerceItem=function(dj){if(Y(dj)){dj=String(dj);delete c0[dj]}};this.clearEcommerceCart=function(){c0={}};this.trackEcommerceOrder=function(dj,dn,dm,dl,dk,dp){bY(dj,dn,dm,dl,dk,dp)};this.trackEcommerceCartUpdate=function(dj){br(dj)};this.trackRequest=function(dk,dm,dl,dj){cg(function(){var dn=cs(dk,dm,dj);bE(dn,bI,dl)})};this.ping=function(){this.trackRequest("ping=1",null,null,"ping")};this.disableQueueRequest=function(){bB.enabled=false};this.setRequestQueueInterval=function(dj){if(dj<1000){throw new Error("Request queue interval needs to be at least 1000ms")}bB.interval=dj};this.queueRequest=function(dj){cg(function(){var dk=cs(dj);
72
+ bB.push(dk)})};this.isConsentRequired=function(){return cz};this.getRememberedConsent=function(){var dj=aC(bd);if(aC(cL)){if(dj){bX(bd,bo,cX)}return null}if(!dj||dj===0){return null}return dj};this.hasRememberedConsent=function(){return !!this.getRememberedConsent()};this.requireConsent=function(){cz=true;bA=this.hasRememberedConsent();x++;b["CoreConsent"+x]={unload:function(){if(!bA){aE()}}}};this.setConsentGiven=function(){bA=true;bX(cL,bo,cX);var dk,dj;for(dk=0;dk<cJ.length;dk++){dj=typeof cJ[dk];if(dj==="string"){bE(cJ[dk],bI)}else{if(dj==="object"){df(cJ[dk],bI)}}}cJ=[]};this.rememberConsentGiven=function(dk){if(dk){dk=dk*60*60*1000}else{dk=30*365*24*60*60*1000}this.setConsentGiven();var dj=new Date().getTime();de(bd,dj,dk,bo,cX,bR)};this.forgetConsentGiven=function(){var dj=30*365*24*60*60*1000;bX(bd,bo,cX);de(cL,new Date().getTime(),dj,bo,cX,bR);this.requireConsent()};this.isUserOptedOut=function(){return !bA};this.optUserOut=this.forgetConsentGiven;this.forgetUserOptOut=this.rememberConsentGiven;
73
+ e.trigger("TrackerSetup",[this])}function H(){return{push:af}}function c(au,at){var av={};var aq,ar;for(aq=0;aq<at.length;aq++){var ao=at[aq];av[ao]=1;for(ar=0;ar<au.length;ar++){if(au[ar]&&au[ar][0]){var ap=au[ar][0];if(ao===ap){af(au[ar]);delete au[ar];if(av[ap]>1&&ap!=="addTracker"){ak("The method "+ap+' is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: https://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')}av[ap]++}}}}return au}var C=["addTracker","disableCookies","setTrackerUrl","setAPIUrl","enableCrossDomainLinking","setCrossDomainLinkingTimeout","setSessionCookieTimeout","setVisitorCookieTimeout","setSecureCookie","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","alwaysUseSendBeacon","enableLinkTracking","requireConsent","setConsentGiven"];function ad(ao,aq){var ap=new Q(ao,aq);I.push(ap);_paq=c(_paq,C);for(E=0;E<_paq.length;E++){if(_paq[E]){af(_paq[E])
74
+ }}_paq=new H();e.trigger("TrackerAdded",[ap]);return ap}an(T,"beforeunload",ai,false);an(T,"message",function(au){if(!au||!au.origin){return}var aw,ar,ap;var ax=d(au.origin);var at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){ap=d(at[ar].getPiwikUrl());if(ap===ax){aw=at[ar];break}}if(!aw){return}var aq=null;try{aq=JSON.parse(au.data)}catch(av){return}if(!aq){return}function ao(aA){var aC=G.getElementsByTagName("iframe");for(ar=0;ar<aC.length;ar++){var aB=aC[ar];var ay=d(aB.src);if(aB.contentWindow&&J(aB.contentWindow.postMessage)&&ay===ax){var az=JSON.stringify(aA);aB.contentWindow.postMessage(az,"*")}}}if(J(aq.maq_initial_value)){ao({maq_opted_in:aq.maq_initial_value&&aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}else{if(J(aq.maq_opted_in)){at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){aw=at[ar];if(aq.maq_opted_in){aw.rememberConsentGiven()}else{aw.forgetConsentGiven()}}ao({maq_confirm_opted_in:aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})
75
+ }}},false);Date.prototype.getTimeAlias=Date.prototype.getTime;e={initialized:false,JSON:JSON_PIWIK,DOM:{addEventListener:function(ar,aq,ap,ao){var at=typeof ao;if(at==="undefined"){ao=false}an(ar,aq,ap,ao)},onLoad:n,onReady:q,isNodeVisible:j,isOrWasNodeVisible:v.isNodeVisible},on:function(ap,ao){if(!y[ap]){y[ap]=[]}y[ap].push(ao)},off:function(aq,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){if(y[aq][ao]===ap){y[aq].splice(ao,1)}}},trigger:function(aq,ar,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){y[aq][ao].apply(ap||T,ar)}},addPlugin:function(ao,ap){b[ao]=ap},getTracker:function(ao,ap){if(!J(ap)){ap=this.getAsyncTracker().getSiteId()}if(!J(ao)){ao=this.getAsyncTracker().getTrackerUrl()}return new Q(ao,ap)},getAsyncTrackers:function(){return I},addTracker:function(ao,aq){var ap;if(!I.length){ap=ad(ao,aq)}else{ap=I[0].addTracker(ao,aq)}return ap},getAsyncTracker:function(ap,at){var ar;if(I&&I.length&&I[0]){ar=I[0]}else{return ad(ap,at)}if(!at&&!ap){return ar
76
+ }if((!J(at)||null===at)&&ar){at=ar.getSiteId()}if((!J(ap)||null===ap)&&ar){ap=ar.getTrackerUrl()}var aq,ao=0;for(ao;ao<I.length;ao++){aq=I[ao];if(aq&&String(aq.getSiteId())===String(at)&&aq.getTrackerUrl()===ap){return aq}}},retryMissedPluginCalls:function(){var ap=ah;ah=[];var ao=0;for(ao;ao<ap.length;ao++){af(ap[ao])}}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return e});define("matomo",[],function(){return e})}return e}())}
77
  /*!!! pluginTrackerHook */
78
+ (function(){function b(){if("object"!==typeof _paq){return false}var c=typeof _paq.length;if("undefined"===c){return false}return !!_paq.length}if(window&&"object"===typeof window.piwikPluginAsyncInit&&window.piwikPluginAsyncInit.length){var a=0;for(a;a<window.piwikPluginAsyncInit.length;a++){if(typeof window.piwikPluginAsyncInit[a]==="function"){window.piwikPluginAsyncInit[a]()}}}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}if(!window.Piwik.getAsyncTrackers().length){if(b()){window.Piwik.addTracker()
79
+ }else{_paq={push:function(c){var d=typeof console;if(d!=="undefined"&&console&&console.error){console.error("_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js. Alternatively, you can create a tracker via Matomo.addTracker() manually and then use _paq.push but it may not fully work as tracker methods may not be executed in the correct order.",c)}}}}}window.Piwik.trigger("PiwikInitialized",[]);window.Piwik.initialized=true}());(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=window.Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=window.Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");
80
+ if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}}
81
  /*!! @license-end */;
app/piwik.js CHANGED
@@ -59,22 +59,23 @@ v.setHrefAttribute(dq,dk);return true}return false}function aM(dk){if(!dk||!dk.l
59
  return false}var dk=cs(cO(dl,dn,dj,dm),dq,"event");bE(dk,bI,dp)}function b7(dj,dm,dk,dn){var dl=cs("search="+t(dj)+(dm?"&search_cat="+t(dm):"")+(J(dk)?"&search_count="+dk:""),dn,"sitesearch");bE(dl,bI)}function cT(dj,dn,dm,dl){var dk=cs("idgoal="+dj+(dn?"&revenue="+dn:""),dm,"goal");bE(dk,bI,dl)}function c1(dm,dj,dr,dq,dl){var dp=dj+"="+t(b1(dm));var dk=ct(dl,"click",dm);if(dk){dp+="&"+dk}var dn=cs(dp,dr,"link");bE(dn,bI,dq)}function bT(dk,dj){if(dk!==""){return dk+dj.charAt(0).toUpperCase()+dj.slice(1)}return dj}function cg(dp){var dn,dj,dm=["","webkit","ms","moz"],dl;if(!be){for(dj=0;dj<dm.length;dj++){dl=dm[dj];if(Object.prototype.hasOwnProperty.call(G,bT(dl,"hidden"))){if(G[bT(dl,"visibilityState")]==="prerender"){dn=true}break}}}if(dn){an(G,dl+"visibilitychange",function dk(){G.removeEventListener(dl+"visibilitychange",dk,false);dp()});return}dp()}function bq(){var dk=aY().uuid;var dj=aI();return dk+dj}function ci(dj){if(!dj){return}if(!ae.hasNodeAttribute(dj,"href")){return}var dk=ae.getAttributeValueFromNode(dj,"href");
60
  if(!dk||aU(dk)){return}dk=k(dk,av);var dl=bq();dk=F(dk,av,dl);ae.setAnyAttribute(dj,"href",dk)}function aA(dm){var dn=ae.getAttributeValueFromNode(dm,"href");if(!dn){return false}dn=String(dn);var dk=dn.indexOf("//")===0||dn.indexOf("http://")===0||dn.indexOf("https://")===0;if(!dk){return false}var dj=dm.pathname||ck(dm.href);var dl=(dm.hostname||d(dm.href)).toLowerCase();if(ar(dl,dj)){if(!cF(cU,L(dl))){return true}return false}return false}function cE(dj){var dk=dc(dj);if(dk&&dk.type){dk.href=p(dk.href);c1(dk.href,dk.type,undefined,null,dj);return}if(cM){dj=au(dj);if(aA(dj)){ci(dj)}}}function cv(){return G.all&&!G.addEventListener}function cV(dj){var dl=dj.which;var dk=(typeof dj.button);if(!dl&&dk!=="undefined"){if(cv()){if(dj.button&1){dl=1}else{if(dj.button&2){dl=3}else{if(dj.button&4){dl=2}}}}else{if(dj.button===0||dj.button==="0"){dl=1}else{if(dj.button&1){dl=2}else{if(dj.button&2){dl=3}}}}}return dl}function bS(dj){switch(cV(dj)){case 1:return"left";case 2:return"middle";case 3:return"right"
61
  }}function a1(dj){return dj.target||dj.srcElement}function aB(dj){return function(dm){dm=dm||T.event;var dl=bS(dm);var dn=a1(dm);if(dm.type==="click"){var dk=false;if(dj&&dl==="middle"){dk=true}if(dn&&!dk){cE(dn)}}else{if(dm.type==="mousedown"){if(dl==="middle"&&dn){aR=dl;bz=dn}else{aR=bz=null}}else{if(dm.type==="mouseup"){if(dl===aR&&dn===bz){cE(dn)}aR=bz=null}else{if(dm.type==="contextmenu"){cE(dn)}}}}}}function aq(dl,dk){var dj=typeof dk;if(dj==="undefined"){dk=true}an(dl,"click",aB(dk),false);if(dk){an(dl,"mouseup",aB(dk),false);an(dl,"mousedown",aB(dk),false);an(dl,"contextmenu",aB(dk),false)}}function bC(dl,dn){ap=true;var dm,dk=a0(by,"ignore"),dp=G.links,dj=null,dq=null;if(dp){for(dm=0;dm<dp.length;dm++){dj=dp[dm];if(!dk.test(dj.className)){dq=typeof dj.piwikTrackers;if("undefined"===dq){dj.piwikTrackers=[]}if(-1===M(dj.piwikTrackers,dn)){dj.piwikTrackers.push(dn);aq(dj,dl)}}}}}function aS(dk,dn,dp){if(ce){return true}ce=true;var dq=false;var dm,dl;function dj(){dq=true}n(function(){function dr(dt){setTimeout(function(){if(!ce){return
62
- }dq=false;dp.trackVisibleContentImpressions();dr(dt)},dt)}function ds(dt){setTimeout(function(){if(!ce){return}if(dq){dq=false;dp.trackVisibleContentImpressions()}ds(dt)},dt)}if(dk){dm=["scroll","resize"];for(dl=0;dl<dm.length;dl++){if(G.addEventListener){G.addEventListener(dm[dl],dj,false)}else{T.attachEvent("on"+dm[dl],dj)}}ds(100)}if(dn&&dn>0){dn=parseInt(dn,10);dr(dn)}})}var bB={enabled:true,requests:[],timeout:null,interval:2500,sendRequests:function(){var dj=this.requests;this.requests=[];if(dj.length===1){bE(dj[0],bI)}else{df(dj,bI)}},push:function(dj){if(!dj){return}if(m||!this.enabled){bE(dj,bI);return}bB.requests.push(dj);if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.timeout=setTimeout(function(){bB.timeout=null;bB.sendRequests()},bB.interval);var dk="RequestQueue"+aw;if(!Object.prototype.hasOwnProperty.call(b,dk)){b[dk]={unload:function(){if(bB.timeout){clearTimeout(bB.timeout)}bB.sendRequests()}}}}};bh();aL();this.hasConsent=function(){return bA};this.getVisitorId=function(){return aY().uuid
63
- };this.getVisitorInfo=function(){return cN()};this.getAttributionInfo=function(){return bL()};this.getAttributionCampaignName=function(){return bL()[0]};this.getAttributionCampaignKeyword=function(){return bL()[1]};this.getAttributionReferrerTimestamp=function(){return bL()[2]};this.getAttributionReferrerUrl=function(){return bL()[3]};this.setTrackerUrl=function(dj){aD=dj};this.getTrackerUrl=function(){return aD};this.getPiwikUrl=function(){return O(this.getTrackerUrl(),bG)};this.addTracker=function(dj,dl){if(!J(dj)||null===dj){dj=this.getTrackerUrl()}var dk=new Q(dj,dl);I.push(dk);e.trigger("TrackerAdded",[this]);return dk};this.getSiteId=function(){return b5};this.setSiteId=function(dj){b2(dj)};this.resetUserId=function(){bx=""};this.setUserId=function(dj){if(Y(dj)){bx=dj}};this.getUserId=function(){return bx};this.setCustomData=function(dj,dk){if(W(dj)){ao=dj}else{if(!ao){ao={}}ao[dj]=dk}};this.getCustomData=function(){return ao};this.setCustomRequestProcessing=function(dj){ca=dj};this.appendToTrackingUrl=function(dj){cZ=dj
64
- };this.getRequest=function(dj){return cs(dj)};this.addPlugin=function(dj,dk){b[dj]=dk};this.setCustomDimension=function(dj,dk){dj=parseInt(dj,10);if(dj>0){if(!J(dk)){dk=""}if(!w(dk)){dk=String(dk)}bl[dj]=dk}};this.getCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0&&Object.prototype.hasOwnProperty.call(bl,dj)){return bl[dj]}};this.deleteCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0){delete bl[dj]}};this.setCustomVariable=function(dk,dj,dn,dl){var dm;if(!J(dl)){dl="visit"}if(!J(dj)){return}if(!J(dn)){dn=""}if(dk>0){dj=!w(dj)?String(dj):dj;dn=!w(dn)?String(dn):dn;dm=[dj.slice(0,bs),dn.slice(0,bs)];if(dl==="visit"||dl===2){cD();aQ[dk]=dm}else{if(dl==="page"||dl===3){bV[dk]=dm}else{if(dl==="event"){cl[dk]=dm}}}}};this.getCustomVariable=function(dk,dl){var dj;if(!J(dl)){dl="visit"}if(dl==="page"||dl===3){dj=bV[dk]}else{if(dl==="event"){dj=cl[dk]}else{if(dl==="visit"||dl===2){cD();dj=aQ[dk]}}}if(!J(dj)||(dj&&dj[0]==="")){return false}return dj};this.deleteCustomVariable=function(dj,dk){if(this.getCustomVariable(dj,dk)){this.setCustomVariable(dj,"","",dk)
65
- }};this.deleteCustomVariables=function(dj){if(dj==="page"||dj===3){bV={}}else{if(dj==="event"){cl={}}else{if(dj==="visit"||dj===2){aQ={}}}}};this.storeCustomVariablesInCookie=function(){bP=true};this.setLinkTrackingTimer=function(dj){bI=dj};this.getLinkTrackingTimer=function(){return bI};this.setDownloadExtensions=function(dj){if(w(dj)){dj=dj.split("|")}c6=dj};this.addDownloadExtensions=function(dk){var dj;if(w(dk)){dk=dk.split("|")}for(dj=0;dj<dk.length;dj++){c6.push(dk[dj])}};this.removeDownloadExtensions=function(dl){var dk,dj=[];if(w(dl)){dl=dl.split("|")}for(dk=0;dk<c6.length;dk++){if(M(dl,c6[dk])===-1){dj.push(c6[dk])}}c6=dj};this.setDomains=function(dj){ax=w(dj)?[dj]:dj;var dn=false,dl=0,dk;for(dl;dl<ax.length;dl++){dk=String(ax[dl]);if(cF(cU,L(dk))){dn=true;break}var dm=ck(dk);if(dm&&dm!=="/"&&dm!=="/*"){dn=true;break}}if(!dn){ax.push(cU)}};this.enableCrossDomainLinking=function(){cM=true};this.disableCrossDomainLinking=function(){cM=false};this.isCrossDomainLinkingEnabled=function(){return cM
66
- };this.setCrossDomainLinkingTimeout=function(dj){aZ=dj};this.getCrossDomainLinkingUrlParameter=function(){return t(av)+"="+t(bq())};this.setIgnoreClasses=function(dj){by=w(dj)?[dj]:dj};this.setRequestMethod=function(dj){da=dj||ch};this.setRequestContentType=function(dj){cw=dj||aH};this.setReferrerUrl=function(dj){bm=dj};this.setCustomUrl=function(dj){a4=bU(bM,dj)};this.getCurrentUrl=function(){return a4||bM};this.setDocumentTitle=function(dj){bi=dj};this.setAPIUrl=function(dj){bG=dj};this.setDownloadClasses=function(dj){bK=w(dj)?[dj]:dj};this.setLinkClasses=function(dj){a8=w(dj)?[dj]:dj};this.setCampaignNameKey=function(dj){cq=w(dj)?[dj]:dj};this.setCampaignKeywordKey=function(dj){bF=w(dj)?[dj]:dj};this.discardHashTag=function(dj){bO=dj};this.setCookieNamePrefix=function(dj){bj=dj;aQ=bW()};this.setCookieDomain=function(dj){var dk=L(dj);if(bv(dk)){cX=dk;bh()}};this.getCookieDomain=function(){return cX};this.hasCookies=function(){return"1"===b4()};this.setSessionCookie=function(dl,dk,dj){if(!dl){throw new Error("Missing cookie name")
67
- }if(!J(dj)){dj=co}bt.push(dl);de(aT(dl),dk,dj,bo,cX)};this.getCookie=function(dk){var dj=aC(aT(dk));if(dj===0){return null}return dj};this.setCookiePath=function(dj){bo=dj;bh()};this.getCookiePath=function(dj){return bo};this.setVisitorCookieTimeout=function(dj){cI=dj*1000};this.setSessionCookieTimeout=function(dj){co=dj*1000};this.getSessionCookieTimeout=function(){return co};this.setReferralCookieTimeout=function(dj){c5=dj*1000};this.setConversionAttributionFirstReferrer=function(dj){bu=dj};this.setSecureCookie=function(dj){bR=dj};this.disableCookies=function(){bk=true;c8.cookie="0";if(b5){aE()}};this.deleteCookies=function(){aE()};this.setDoNotTrack=function(dk){var dj=h.doNotTrack||h.msDoNotTrack;cP=dk&&(dj==="yes"||dj==="1");if(cP){this.disableCookies()}};this.alwaysUseSendBeacon=function(){cW=true};this.addListener=function(dk,dj){aq(dk,dj)};this.enableLinkTracking=function(dk){c9=true;var dj=this;cg(function(){q(function(){bC(dk,dj)})})};this.enableJSErrorTracking=function(){if(cS){return
68
- }cS=true;var dj=T.onerror;T.onerror=function(dp,dm,dl,dn,dk){cg(function(){var dq="JavaScript Errors";var dr=dm+":"+dl;if(dn){dr+=":"+dn}at(dq,dr,dp)});if(dj){return dj(dp,dm,dl,dn,dk)}return false}};this.disablePerformanceTracking=function(){a2=false};this.setGenerationTimeMs=function(dj){cm=parseInt(dj,10)};this.setVisitStandardLength=function(dj){dj=Math.max(dj,5);c7=dj};this.enableHeartBeatTimer=function(dj){dj=Math.max(dj,5);a5=(dj||15)*1000;if(cY!==null){dg()}};this.disableHeartBeatTimer=function(){bJ();if(a5||aN){if(T.removeEventListener){T.removeEventListener("focus",ba);T.removeEventListener("blur",ay)}else{if(T.detachEvent){T.detachEvent("onfocus",ba);T.detachEvent("onblur",ay)}}}a5=null;aN=false};this.killFrame=function(){if(T.location!==T.top.location){T.top.location=T.location}};this.redirectFile=function(dj){if(T.location.protocol==="file:"){T.location=dj}};this.setCountPreRendered=function(dj){be=dj};this.trackGoal=function(dj,dm,dl,dk){cg(function(){cT(dj,dm,dl,dk)})};this.trackLink=function(dk,dj,dm,dl){cg(function(){c1(dk,dj,dm,dl)
69
- })};this.getNumTrackedPageViews=function(){return cr};this.trackPageView=function(dj,dl,dk){b9=[];cJ=[];if(N(b5)){cg(function(){Z(aD,bG,b5)})}else{cg(function(){cr++;bZ(dj,dl,dk)})}};this.trackAllContentImpressions=function(){if(N(b5)){return}cg(function(){q(function(){var dj=v.findContentNodes();var dk=cy(dj);df(dk,bI)})})};this.trackVisibleContentImpressions=function(dj,dk){if(N(b5)){return}if(!J(dj)){dj=true}if(!J(dk)){dk=750}aS(dj,dk,this);cg(function(){n(function(){var dl=v.findContentNodes();var dm=a9(dl);df(dm,bI)})})};this.trackContentImpression=function(dl,dj,dk){if(N(b5)){return}dl=a(dl);dj=a(dj);dk=a(dk);if(!dl){return}dj=dj||"Unknown";cg(function(){var dm=aF(dl,dj,dk);bE(dm,bI)})};this.trackContentImpressionsWithinNode=function(dj){if(N(b5)||!dj){return}cg(function(){if(ce){n(function(){var dk=v.findContentNodesWithinNode(dj);var dl=a9(dk);df(dl,bI)})}else{q(function(){var dk=v.findContentNodesWithinNode(dj);var dl=cy(dk);df(dl,bI)})}})};this.trackContentInteraction=function(dl,dm,dj,dk){if(N(b5)){return
70
- }dl=a(dl);dm=a(dm);dj=a(dj);dk=a(dk);if(!dl||!dm){return}dj=dj||"Unknown";cg(function(){var dn=aP(dl,dm,dj,dk);if(dn){bE(dn,bI)}})};this.trackContentInteractionNode=function(dk,dj){if(N(b5)||!dk){return}cg(function(){var dl=db(dk,dj);if(dl){bE(dl,bI)}})};this.logAllContentBlocksOnPage=function(){var dl=v.findContentNodes();var dj=v.collectContent(dl);var dk=typeof console;if(dk!=="undefined"&&console&&console.log){console.log(dj)}};this.trackEvent=function(dk,dm,dj,dl,dp,dn){cg(function(){at(dk,dm,dj,dl,dp,dn)})};this.trackSiteSearch=function(dj,dl,dk,dm){b9=[];cg(function(){b7(dj,dl,dk,dm)})};this.setEcommerceView=function(dm,dj,dl,dk){if(Y(dl)){dl=String(dl)}if(!J(dl)||dl===null||dl===false||!dl.length){dl=""}else{if(dl instanceof Array){dl=JSON_PIWIK.stringify(dl)}}bV[5]=["_pkc",dl];if(J(dk)&&dk!==null&&dk!==false&&String(dk).length){bV[2]=["_pkp",dk]}if(!Y(dm)&&!Y(dj)){return}if(Y(dm)){bV[3]=["_pks",dm]}if(!Y(dj)){dj=""}bV[4]=["_pkn",dj]};this.getEcommerceItems=function(){return JSON.parse(JSON.stringify(c0))
71
- };this.addEcommerceItem=function(dn,dj,dl,dk,dm){if(Y(dn)){c0[dn]=[String(dn),dj,dl,dk,dm]}};this.removeEcommerceItem=function(dj){if(Y(dj)){dj=String(dj);delete c0[dj]}};this.clearEcommerceCart=function(){c0={}};this.trackEcommerceOrder=function(dj,dn,dm,dl,dk,dp){bY(dj,dn,dm,dl,dk,dp)};this.trackEcommerceCartUpdate=function(dj){br(dj)};this.trackRequest=function(dk,dm,dl,dj){cg(function(){var dn=cs(dk,dm,dj);bE(dn,bI,dl)})};this.ping=function(){this.trackRequest("ping=1",null,null,"ping")};this.disableQueueRequest=function(){bB.enabled=false};this.setRequestQueueInterval=function(dj){if(dj<1000){throw new Error("Request queue interval needs to be at least 1000ms")}bB.interval=dj};this.queueRequest=function(dj){cg(function(){var dk=cs(dj);bB.push(dk)})};this.isConsentRequired=function(){return cz};this.getRememberedConsent=function(){var dj=aC(bd);if(aC(cL)){if(dj){bX(bd,bo,cX)}return null}if(!dj||dj===0){return null}return dj};this.hasRememberedConsent=function(){return !!this.getRememberedConsent()
72
- };this.requireConsent=function(){cz=true;bA=this.hasRememberedConsent();x++;b["CoreConsent"+x]={unload:function(){if(!bA){aE()}}}};this.setConsentGiven=function(){bA=true;bX(cL,bo,cX);var dk,dj;for(dk=0;dk<cJ.length;dk++){dj=typeof cJ[dk];if(dj==="string"){bE(cJ[dk],bI)}else{if(dj==="object"){df(cJ[dk],bI)}}}cJ=[]};this.rememberConsentGiven=function(dk){if(dk){dk=dk*60*60*1000}else{dk=30*365*24*60*60*1000}this.setConsentGiven();var dj=new Date().getTime();de(bd,dj,dk,bo,cX,bR)};this.forgetConsentGiven=function(){var dj=30*365*24*60*60*1000;bX(bd,bo,cX);de(cL,new Date().getTime(),dj,bo,cX,bR);this.requireConsent()};this.isUserOptedOut=function(){return !bA};this.optUserOut=this.forgetConsentGiven;this.forgetUserOptOut=this.rememberConsentGiven;e.trigger("TrackerSetup",[this])}function H(){return{push:af}}function c(au,at){var av={};var aq,ar;for(aq=0;aq<at.length;aq++){var ao=at[aq];av[ao]=1;for(ar=0;ar<au.length;ar++){if(au[ar]&&au[ar][0]){var ap=au[ar][0];if(ao===ap){af(au[ar]);delete au[ar];
73
- if(av[ap]>1&&ap!=="addTracker"){ak("The method "+ap+' is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: https://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')}av[ap]++}}}}return au}var C=["addTracker","disableCookies","setTrackerUrl","setAPIUrl","enableCrossDomainLinking","setCrossDomainLinkingTimeout","setSessionCookieTimeout","setVisitorCookieTimeout","setSecureCookie","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","alwaysUseSendBeacon","enableLinkTracking","requireConsent","setConsentGiven"];function ad(ao,aq){var ap=new Q(ao,aq);I.push(ap);_paq=c(_paq,C);for(E=0;E<_paq.length;E++){if(_paq[E]){af(_paq[E])}}_paq=new H();e.trigger("TrackerAdded",[ap]);return ap}an(T,"beforeunload",ai,false);an(T,"message",function(au){if(!au||!au.origin){return}var aw,ar,ap;var ax=d(au.origin);var at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){ap=d(at[ar].getPiwikUrl());
74
- if(ap===ax){aw=at[ar];break}}if(!aw){return}var aq=null;try{aq=JSON.parse(au.data)}catch(av){return}if(!aq){return}function ao(aA){var aC=G.getElementsByTagName("iframe");for(ar=0;ar<aC.length;ar++){var aB=aC[ar];var ay=d(aB.src);if(aB.contentWindow&&J(aB.contentWindow.postMessage)&&ay===ax){var az=JSON.stringify(aA);aB.contentWindow.postMessage(az,"*")}}}if(J(aq.maq_initial_value)){ao({maq_opted_in:aq.maq_initial_value&&aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}else{if(J(aq.maq_opted_in)){at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){aw=at[ar];if(aq.maq_opted_in){aw.rememberConsentGiven()}else{aw.forgetConsentGiven()}}ao({maq_confirm_opted_in:aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}}},false);Date.prototype.getTimeAlias=Date.prototype.getTime;e={initialized:false,JSON:JSON_PIWIK,DOM:{addEventListener:function(ar,aq,ap,ao){var at=typeof ao;if(at==="undefined"){ao=false}an(ar,aq,ap,ao)},onLoad:n,onReady:q,isNodeVisible:j,isOrWasNodeVisible:v.isNodeVisible},on:function(ap,ao){if(!y[ap]){y[ap]=[]
75
- }y[ap].push(ao)},off:function(aq,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){if(y[aq][ao]===ap){y[aq].splice(ao,1)}}},trigger:function(aq,ar,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){y[aq][ao].apply(ap||T,ar)}},addPlugin:function(ao,ap){b[ao]=ap},getTracker:function(ao,ap){if(!J(ap)){ap=this.getAsyncTracker().getSiteId()}if(!J(ao)){ao=this.getAsyncTracker().getTrackerUrl()}return new Q(ao,ap)},getAsyncTrackers:function(){return I},addTracker:function(ao,aq){var ap;if(!I.length){ap=ad(ao,aq)}else{ap=I[0].addTracker(ao,aq)}return ap},getAsyncTracker:function(ap,at){var ar;if(I&&I.length&&I[0]){ar=I[0]}else{return ad(ap,at)}if(!at&&!ap){return ar}if((!J(at)||null===at)&&ar){at=ar.getSiteId()}if((!J(ap)||null===ap)&&ar){ap=ar.getTrackerUrl()}var aq,ao=0;for(ao;ao<I.length;ao++){aq=I[ao];if(aq&&String(aq.getSiteId())===String(at)&&aq.getTrackerUrl()===ap){return aq}}},retryMissedPluginCalls:function(){var ap=ah;ah=[];var ao=0;for(ao;ao<ap.length;ao++){af(ap[ao])
76
- }}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return e});define("matomo",[],function(){return e})}return e}())}
77
  /*!!! pluginTrackerHook */
78
- (function(){function b(){if("object"!==typeof _paq){return false}var c=typeof _paq.length;if("undefined"===c){return false}return !!_paq.length}if(window&&"object"===typeof window.piwikPluginAsyncInit&&window.piwikPluginAsyncInit.length){var a=0;for(a;a<window.piwikPluginAsyncInit.length;a++){if(typeof window.piwikPluginAsyncInit[a]==="function"){window.piwikPluginAsyncInit[a]()}}}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}if(!window.Piwik.getAsyncTrackers().length){if(b()){window.Piwik.addTracker()}else{_paq={push:function(c){var d=typeof console;if(d!=="undefined"&&console&&console.error){console.error("_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js. Alternatively, you can create a tracker via Matomo.addTracker() manually and then use _paq.push but it may not fully work as tracker methods may not be executed in the correct order.",c)
79
- }}}}}window.Piwik.trigger("PiwikInitialized",[]);window.Piwik.initialized=true}());(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=window.Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=window.Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}}
 
80
  /*!! @license-end */;
59
  return false}var dk=cs(cO(dl,dn,dj,dm),dq,"event");bE(dk,bI,dp)}function b7(dj,dm,dk,dn){var dl=cs("search="+t(dj)+(dm?"&search_cat="+t(dm):"")+(J(dk)?"&search_count="+dk:""),dn,"sitesearch");bE(dl,bI)}function cT(dj,dn,dm,dl){var dk=cs("idgoal="+dj+(dn?"&revenue="+dn:""),dm,"goal");bE(dk,bI,dl)}function c1(dm,dj,dr,dq,dl){var dp=dj+"="+t(b1(dm));var dk=ct(dl,"click",dm);if(dk){dp+="&"+dk}var dn=cs(dp,dr,"link");bE(dn,bI,dq)}function bT(dk,dj){if(dk!==""){return dk+dj.charAt(0).toUpperCase()+dj.slice(1)}return dj}function cg(dp){var dn,dj,dm=["","webkit","ms","moz"],dl;if(!be){for(dj=0;dj<dm.length;dj++){dl=dm[dj];if(Object.prototype.hasOwnProperty.call(G,bT(dl,"hidden"))){if(G[bT(dl,"visibilityState")]==="prerender"){dn=true}break}}}if(dn){an(G,dl+"visibilitychange",function dk(){G.removeEventListener(dl+"visibilitychange",dk,false);dp()});return}dp()}function bq(){var dk=aY().uuid;var dj=aI();return dk+dj}function ci(dj){if(!dj){return}if(!ae.hasNodeAttribute(dj,"href")){return}var dk=ae.getAttributeValueFromNode(dj,"href");
60
  if(!dk||aU(dk)){return}dk=k(dk,av);var dl=bq();dk=F(dk,av,dl);ae.setAnyAttribute(dj,"href",dk)}function aA(dm){var dn=ae.getAttributeValueFromNode(dm,"href");if(!dn){return false}dn=String(dn);var dk=dn.indexOf("//")===0||dn.indexOf("http://")===0||dn.indexOf("https://")===0;if(!dk){return false}var dj=dm.pathname||ck(dm.href);var dl=(dm.hostname||d(dm.href)).toLowerCase();if(ar(dl,dj)){if(!cF(cU,L(dl))){return true}return false}return false}function cE(dj){var dk=dc(dj);if(dk&&dk.type){dk.href=p(dk.href);c1(dk.href,dk.type,undefined,null,dj);return}if(cM){dj=au(dj);if(aA(dj)){ci(dj)}}}function cv(){return G.all&&!G.addEventListener}function cV(dj){var dl=dj.which;var dk=(typeof dj.button);if(!dl&&dk!=="undefined"){if(cv()){if(dj.button&1){dl=1}else{if(dj.button&2){dl=3}else{if(dj.button&4){dl=2}}}}else{if(dj.button===0||dj.button==="0"){dl=1}else{if(dj.button&1){dl=2}else{if(dj.button&2){dl=3}}}}}return dl}function bS(dj){switch(cV(dj)){case 1:return"left";case 2:return"middle";case 3:return"right"
61
  }}function a1(dj){return dj.target||dj.srcElement}function aB(dj){return function(dm){dm=dm||T.event;var dl=bS(dm);var dn=a1(dm);if(dm.type==="click"){var dk=false;if(dj&&dl==="middle"){dk=true}if(dn&&!dk){cE(dn)}}else{if(dm.type==="mousedown"){if(dl==="middle"&&dn){aR=dl;bz=dn}else{aR=bz=null}}else{if(dm.type==="mouseup"){if(dl===aR&&dn===bz){cE(dn)}aR=bz=null}else{if(dm.type==="contextmenu"){cE(dn)}}}}}}function aq(dl,dk){var dj=typeof dk;if(dj==="undefined"){dk=true}an(dl,"click",aB(dk),false);if(dk){an(dl,"mouseup",aB(dk),false);an(dl,"mousedown",aB(dk),false);an(dl,"contextmenu",aB(dk),false)}}function bC(dl,dn){ap=true;var dm,dk=a0(by,"ignore"),dp=G.links,dj=null,dq=null;if(dp){for(dm=0;dm<dp.length;dm++){dj=dp[dm];if(!dk.test(dj.className)){dq=typeof dj.piwikTrackers;if("undefined"===dq){dj.piwikTrackers=[]}if(-1===M(dj.piwikTrackers,dn)){dj.piwikTrackers.push(dn);aq(dj,dl)}}}}}function aS(dk,dn,dp){if(ce){return true}ce=true;var dq=false;var dm,dl;function dj(){dq=true}n(function(){function dr(dt){setTimeout(function(){if(!ce){return
62
+ }dq=false;dp.trackVisibleContentImpressions();dr(dt)},dt)}function ds(dt){setTimeout(function(){if(!ce){return}if(dq){dq=false;dp.trackVisibleContentImpressions()}ds(dt)},dt)}if(dk){dm=["scroll","resize"];for(dl=0;dl<dm.length;dl++){if(G.addEventListener){G.addEventListener(dm[dl],dj,false)}else{T.attachEvent("on"+dm[dl],dj)}}ds(100)}if(dn&&dn>0){dn=parseInt(dn,10);dr(dn)}})}var bB={enabled:true,requests:[],timeout:null,interval:2500,sendRequests:function(){var dj=this.requests;this.requests=[];if(dj.length===1){bE(dj[0],bI)}else{df(dj,bI)}},canQueue:function(){return !m&&this.enabled},pushMultiple:function(dk){if(!this.canQueue()){df(dk,bI);return}var dj;for(dj=0;dj<dk.length;dj++){this.push(dk[dj])}},push:function(dj){if(!dj){return}if(!this.canQueue()){bE(dj,bI);return}bB.requests.push(dj);if(this.timeout){clearTimeout(this.timeout);this.timeout=null}this.timeout=setTimeout(function(){bB.timeout=null;bB.sendRequests()},bB.interval);var dk="RequestQueue"+aw;if(!Object.prototype.hasOwnProperty.call(b,dk)){b[dk]={unload:function(){if(bB.timeout){clearTimeout(bB.timeout)
63
+ }bB.sendRequests()}}}}};bh();aL();this.hasConsent=function(){return bA};this.getVisitorId=function(){return aY().uuid};this.getVisitorInfo=function(){return cN()};this.getAttributionInfo=function(){return bL()};this.getAttributionCampaignName=function(){return bL()[0]};this.getAttributionCampaignKeyword=function(){return bL()[1]};this.getAttributionReferrerTimestamp=function(){return bL()[2]};this.getAttributionReferrerUrl=function(){return bL()[3]};this.setTrackerUrl=function(dj){aD=dj};this.getTrackerUrl=function(){return aD};this.getPiwikUrl=function(){return O(this.getTrackerUrl(),bG)};this.addTracker=function(dj,dl){if(!J(dj)||null===dj){dj=this.getTrackerUrl()}var dk=new Q(dj,dl);I.push(dk);e.trigger("TrackerAdded",[this]);return dk};this.getSiteId=function(){return b5};this.setSiteId=function(dj){b2(dj)};this.resetUserId=function(){bx=""};this.setUserId=function(dj){if(Y(dj)){bx=dj}};this.getUserId=function(){return bx};this.setCustomData=function(dj,dk){if(W(dj)){ao=dj}else{if(!ao){ao={}
64
+ }ao[dj]=dk}};this.getCustomData=function(){return ao};this.setCustomRequestProcessing=function(dj){ca=dj};this.appendToTrackingUrl=function(dj){cZ=dj};this.getRequest=function(dj){return cs(dj)};this.addPlugin=function(dj,dk){b[dj]=dk};this.setCustomDimension=function(dj,dk){dj=parseInt(dj,10);if(dj>0){if(!J(dk)){dk=""}if(!w(dk)){dk=String(dk)}bl[dj]=dk}};this.getCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0&&Object.prototype.hasOwnProperty.call(bl,dj)){return bl[dj]}};this.deleteCustomDimension=function(dj){dj=parseInt(dj,10);if(dj>0){delete bl[dj]}};this.setCustomVariable=function(dk,dj,dn,dl){var dm;if(!J(dl)){dl="visit"}if(!J(dj)){return}if(!J(dn)){dn=""}if(dk>0){dj=!w(dj)?String(dj):dj;dn=!w(dn)?String(dn):dn;dm=[dj.slice(0,bs),dn.slice(0,bs)];if(dl==="visit"||dl===2){cD();aQ[dk]=dm}else{if(dl==="page"||dl===3){bV[dk]=dm}else{if(dl==="event"){cl[dk]=dm}}}}};this.getCustomVariable=function(dk,dl){var dj;if(!J(dl)){dl="visit"}if(dl==="page"||dl===3){dj=bV[dk]}else{if(dl==="event"){dj=cl[dk]
65
+ }else{if(dl==="visit"||dl===2){cD();dj=aQ[dk]}}}if(!J(dj)||(dj&&dj[0]==="")){return false}return dj};this.deleteCustomVariable=function(dj,dk){if(this.getCustomVariable(dj,dk)){this.setCustomVariable(dj,"","",dk)}};this.deleteCustomVariables=function(dj){if(dj==="page"||dj===3){bV={}}else{if(dj==="event"){cl={}}else{if(dj==="visit"||dj===2){aQ={}}}}};this.storeCustomVariablesInCookie=function(){bP=true};this.setLinkTrackingTimer=function(dj){bI=dj};this.getLinkTrackingTimer=function(){return bI};this.setDownloadExtensions=function(dj){if(w(dj)){dj=dj.split("|")}c6=dj};this.addDownloadExtensions=function(dk){var dj;if(w(dk)){dk=dk.split("|")}for(dj=0;dj<dk.length;dj++){c6.push(dk[dj])}};this.removeDownloadExtensions=function(dl){var dk,dj=[];if(w(dl)){dl=dl.split("|")}for(dk=0;dk<c6.length;dk++){if(M(dl,c6[dk])===-1){dj.push(c6[dk])}}c6=dj};this.setDomains=function(dj){ax=w(dj)?[dj]:dj;var dn=false,dl=0,dk;for(dl;dl<ax.length;dl++){dk=String(ax[dl]);if(cF(cU,L(dk))){dn=true;break}var dm=ck(dk);
66
+ if(dm&&dm!=="/"&&dm!=="/*"){dn=true;break}}if(!dn){ax.push(cU)}};this.enableCrossDomainLinking=function(){cM=true};this.disableCrossDomainLinking=function(){cM=false};this.isCrossDomainLinkingEnabled=function(){return cM};this.setCrossDomainLinkingTimeout=function(dj){aZ=dj};this.getCrossDomainLinkingUrlParameter=function(){return t(av)+"="+t(bq())};this.setIgnoreClasses=function(dj){by=w(dj)?[dj]:dj};this.setRequestMethod=function(dj){da=dj||ch};this.setRequestContentType=function(dj){cw=dj||aH};this.setReferrerUrl=function(dj){bm=dj};this.setCustomUrl=function(dj){a4=bU(bM,dj)};this.getCurrentUrl=function(){return a4||bM};this.setDocumentTitle=function(dj){bi=dj};this.setAPIUrl=function(dj){bG=dj};this.setDownloadClasses=function(dj){bK=w(dj)?[dj]:dj};this.setLinkClasses=function(dj){a8=w(dj)?[dj]:dj};this.setCampaignNameKey=function(dj){cq=w(dj)?[dj]:dj};this.setCampaignKeywordKey=function(dj){bF=w(dj)?[dj]:dj};this.discardHashTag=function(dj){bO=dj};this.setCookieNamePrefix=function(dj){bj=dj;
67
+ aQ=bW()};this.setCookieDomain=function(dj){var dk=L(dj);if(bv(dk)){cX=dk;bh()}};this.getCookieDomain=function(){return cX};this.hasCookies=function(){return"1"===b4()};this.setSessionCookie=function(dl,dk,dj){if(!dl){throw new Error("Missing cookie name")}if(!J(dj)){dj=co}bt.push(dl);de(aT(dl),dk,dj,bo,cX)};this.getCookie=function(dk){var dj=aC(aT(dk));if(dj===0){return null}return dj};this.setCookiePath=function(dj){bo=dj;bh()};this.getCookiePath=function(dj){return bo};this.setVisitorCookieTimeout=function(dj){cI=dj*1000};this.setSessionCookieTimeout=function(dj){co=dj*1000};this.getSessionCookieTimeout=function(){return co};this.setReferralCookieTimeout=function(dj){c5=dj*1000};this.setConversionAttributionFirstReferrer=function(dj){bu=dj};this.setSecureCookie=function(dj){bR=dj};this.disableCookies=function(){bk=true;c8.cookie="0";if(b5){aE()}};this.deleteCookies=function(){aE()};this.setDoNotTrack=function(dk){var dj=h.doNotTrack||h.msDoNotTrack;cP=dk&&(dj==="yes"||dj==="1");if(cP){this.disableCookies()
68
+ }};this.alwaysUseSendBeacon=function(){cW=true};this.addListener=function(dk,dj){aq(dk,dj)};this.enableLinkTracking=function(dk){c9=true;var dj=this;cg(function(){q(function(){bC(dk,dj)});n(function(){bC(dk,dj)})})};this.enableJSErrorTracking=function(){if(cS){return}cS=true;var dj=T.onerror;T.onerror=function(dp,dm,dl,dn,dk){cg(function(){var dq="JavaScript Errors";var dr=dm+":"+dl;if(dn){dr+=":"+dn}at(dq,dr,dp)});if(dj){return dj(dp,dm,dl,dn,dk)}return false}};this.disablePerformanceTracking=function(){a2=false};this.setGenerationTimeMs=function(dj){cm=parseInt(dj,10)};this.setVisitStandardLength=function(dj){dj=Math.max(dj,5);c7=dj};this.enableHeartBeatTimer=function(dj){dj=Math.max(dj,5);a5=(dj||15)*1000;if(cY!==null){dg()}};this.disableHeartBeatTimer=function(){bJ();if(a5||aN){if(T.removeEventListener){T.removeEventListener("focus",ba);T.removeEventListener("blur",ay)}else{if(T.detachEvent){T.detachEvent("onfocus",ba);T.detachEvent("onblur",ay)}}}a5=null;aN=false};this.killFrame=function(){if(T.location!==T.top.location){T.top.location=T.location
69
+ }};this.redirectFile=function(dj){if(T.location.protocol==="file:"){T.location=dj}};this.setCountPreRendered=function(dj){be=dj};this.trackGoal=function(dj,dm,dl,dk){cg(function(){cT(dj,dm,dl,dk)})};this.trackLink=function(dk,dj,dm,dl){cg(function(){c1(dk,dj,dm,dl)})};this.getNumTrackedPageViews=function(){return cr};this.trackPageView=function(dj,dl,dk){b9=[];cJ=[];if(N(b5)){cg(function(){Z(aD,bG,b5)})}else{cg(function(){cr++;bZ(dj,dl,dk)})}};this.trackAllContentImpressions=function(){if(N(b5)){return}cg(function(){q(function(){var dj=v.findContentNodes();var dk=cy(dj);bB.pushMultiple(dk)})})};this.trackVisibleContentImpressions=function(dj,dk){if(N(b5)){return}if(!J(dj)){dj=true}if(!J(dk)){dk=750}aS(dj,dk,this);cg(function(){n(function(){var dl=v.findContentNodes();var dm=a9(dl);bB.pushMultiple(dm)})})};this.trackContentImpression=function(dl,dj,dk){if(N(b5)){return}dl=a(dl);dj=a(dj);dk=a(dk);if(!dl){return}dj=dj||"Unknown";cg(function(){var dm=aF(dl,dj,dk);bB.push(dm)})};this.trackContentImpressionsWithinNode=function(dj){if(N(b5)||!dj){return
70
+ }cg(function(){if(ce){n(function(){var dk=v.findContentNodesWithinNode(dj);var dl=a9(dk);bB.pushMultiple(dl)})}else{q(function(){var dk=v.findContentNodesWithinNode(dj);var dl=cy(dk);bB.pushMultiple(dl)})}})};this.trackContentInteraction=function(dl,dm,dj,dk){if(N(b5)){return}dl=a(dl);dm=a(dm);dj=a(dj);dk=a(dk);if(!dl||!dm){return}dj=dj||"Unknown";cg(function(){var dn=aP(dl,dm,dj,dk);if(dn){bB.push(dn)}})};this.trackContentInteractionNode=function(dk,dj){if(N(b5)||!dk){return}cg(function(){var dl=db(dk,dj);if(dl){bB.push(dl)}})};this.logAllContentBlocksOnPage=function(){var dl=v.findContentNodes();var dj=v.collectContent(dl);var dk=typeof console;if(dk!=="undefined"&&console&&console.log){console.log(dj)}};this.trackEvent=function(dk,dm,dj,dl,dp,dn){cg(function(){at(dk,dm,dj,dl,dp,dn)})};this.trackSiteSearch=function(dj,dl,dk,dm){b9=[];cg(function(){b7(dj,dl,dk,dm)})};this.setEcommerceView=function(dm,dj,dl,dk){if(Y(dl)){dl=String(dl)}if(!J(dl)||dl===null||dl===false||!dl.length){dl=""}else{if(dl instanceof Array){dl=JSON_PIWIK.stringify(dl)
71
+ }}bV[5]=["_pkc",dl];if(J(dk)&&dk!==null&&dk!==false&&String(dk).length){bV[2]=["_pkp",dk]}if(!Y(dm)&&!Y(dj)){return}if(Y(dm)){bV[3]=["_pks",dm]}if(!Y(dj)){dj=""}bV[4]=["_pkn",dj]};this.getEcommerceItems=function(){return JSON.parse(JSON.stringify(c0))};this.addEcommerceItem=function(dn,dj,dl,dk,dm){if(Y(dn)){c0[dn]=[String(dn),dj,dl,dk,dm]}};this.removeEcommerceItem=function(dj){if(Y(dj)){dj=String(dj);delete c0[dj]}};this.clearEcommerceCart=function(){c0={}};this.trackEcommerceOrder=function(dj,dn,dm,dl,dk,dp){bY(dj,dn,dm,dl,dk,dp)};this.trackEcommerceCartUpdate=function(dj){br(dj)};this.trackRequest=function(dk,dm,dl,dj){cg(function(){var dn=cs(dk,dm,dj);bE(dn,bI,dl)})};this.ping=function(){this.trackRequest("ping=1",null,null,"ping")};this.disableQueueRequest=function(){bB.enabled=false};this.setRequestQueueInterval=function(dj){if(dj<1000){throw new Error("Request queue interval needs to be at least 1000ms")}bB.interval=dj};this.queueRequest=function(dj){cg(function(){var dk=cs(dj);
72
+ bB.push(dk)})};this.isConsentRequired=function(){return cz};this.getRememberedConsent=function(){var dj=aC(bd);if(aC(cL)){if(dj){bX(bd,bo,cX)}return null}if(!dj||dj===0){return null}return dj};this.hasRememberedConsent=function(){return !!this.getRememberedConsent()};this.requireConsent=function(){cz=true;bA=this.hasRememberedConsent();x++;b["CoreConsent"+x]={unload:function(){if(!bA){aE()}}}};this.setConsentGiven=function(){bA=true;bX(cL,bo,cX);var dk,dj;for(dk=0;dk<cJ.length;dk++){dj=typeof cJ[dk];if(dj==="string"){bE(cJ[dk],bI)}else{if(dj==="object"){df(cJ[dk],bI)}}}cJ=[]};this.rememberConsentGiven=function(dk){if(dk){dk=dk*60*60*1000}else{dk=30*365*24*60*60*1000}this.setConsentGiven();var dj=new Date().getTime();de(bd,dj,dk,bo,cX,bR)};this.forgetConsentGiven=function(){var dj=30*365*24*60*60*1000;bX(bd,bo,cX);de(cL,new Date().getTime(),dj,bo,cX,bR);this.requireConsent()};this.isUserOptedOut=function(){return !bA};this.optUserOut=this.forgetConsentGiven;this.forgetUserOptOut=this.rememberConsentGiven;
73
+ e.trigger("TrackerSetup",[this])}function H(){return{push:af}}function c(au,at){var av={};var aq,ar;for(aq=0;aq<at.length;aq++){var ao=at[aq];av[ao]=1;for(ar=0;ar<au.length;ar++){if(au[ar]&&au[ar][0]){var ap=au[ar][0];if(ao===ap){af(au[ar]);delete au[ar];if(av[ap]>1&&ap!=="addTracker"){ak("The method "+ap+' is registered more than once in "_paq" variable. Only the last call has an effect. Please have a look at the multiple Piwik trackers documentation: https://developer.piwik.org/guides/tracking-javascript-guide#multiple-piwik-trackers')}av[ap]++}}}}return au}var C=["addTracker","disableCookies","setTrackerUrl","setAPIUrl","enableCrossDomainLinking","setCrossDomainLinkingTimeout","setSessionCookieTimeout","setVisitorCookieTimeout","setSecureCookie","setCookiePath","setCookieDomain","setDomains","setUserId","setSiteId","alwaysUseSendBeacon","enableLinkTracking","requireConsent","setConsentGiven"];function ad(ao,aq){var ap=new Q(ao,aq);I.push(ap);_paq=c(_paq,C);for(E=0;E<_paq.length;E++){if(_paq[E]){af(_paq[E])
74
+ }}_paq=new H();e.trigger("TrackerAdded",[ap]);return ap}an(T,"beforeunload",ai,false);an(T,"message",function(au){if(!au||!au.origin){return}var aw,ar,ap;var ax=d(au.origin);var at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){ap=d(at[ar].getPiwikUrl());if(ap===ax){aw=at[ar];break}}if(!aw){return}var aq=null;try{aq=JSON.parse(au.data)}catch(av){return}if(!aq){return}function ao(aA){var aC=G.getElementsByTagName("iframe");for(ar=0;ar<aC.length;ar++){var aB=aC[ar];var ay=d(aB.src);if(aB.contentWindow&&J(aB.contentWindow.postMessage)&&ay===ax){var az=JSON.stringify(aA);aB.contentWindow.postMessage(az,"*")}}}if(J(aq.maq_initial_value)){ao({maq_opted_in:aq.maq_initial_value&&aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})}else{if(J(aq.maq_opted_in)){at=e.getAsyncTrackers();for(ar=0;ar<at.length;ar++){aw=at[ar];if(aq.maq_opted_in){aw.rememberConsentGiven()}else{aw.forgetConsentGiven()}}ao({maq_confirm_opted_in:aw.hasConsent(),maq_url:aw.getPiwikUrl(),maq_optout_by_default:aw.isConsentRequired()})
75
+ }}},false);Date.prototype.getTimeAlias=Date.prototype.getTime;e={initialized:false,JSON:JSON_PIWIK,DOM:{addEventListener:function(ar,aq,ap,ao){var at=typeof ao;if(at==="undefined"){ao=false}an(ar,aq,ap,ao)},onLoad:n,onReady:q,isNodeVisible:j,isOrWasNodeVisible:v.isNodeVisible},on:function(ap,ao){if(!y[ap]){y[ap]=[]}y[ap].push(ao)},off:function(aq,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){if(y[aq][ao]===ap){y[aq].splice(ao,1)}}},trigger:function(aq,ar,ap){if(!y[aq]){return}var ao=0;for(ao;ao<y[aq].length;ao++){y[aq][ao].apply(ap||T,ar)}},addPlugin:function(ao,ap){b[ao]=ap},getTracker:function(ao,ap){if(!J(ap)){ap=this.getAsyncTracker().getSiteId()}if(!J(ao)){ao=this.getAsyncTracker().getTrackerUrl()}return new Q(ao,ap)},getAsyncTrackers:function(){return I},addTracker:function(ao,aq){var ap;if(!I.length){ap=ad(ao,aq)}else{ap=I[0].addTracker(ao,aq)}return ap},getAsyncTracker:function(ap,at){var ar;if(I&&I.length&&I[0]){ar=I[0]}else{return ad(ap,at)}if(!at&&!ap){return ar
76
+ }if((!J(at)||null===at)&&ar){at=ar.getSiteId()}if((!J(ap)||null===ap)&&ar){ap=ar.getTrackerUrl()}var aq,ao=0;for(ao;ao<I.length;ao++){aq=I[ao];if(aq&&String(aq.getSiteId())===String(at)&&aq.getTrackerUrl()===ap){return aq}}},retryMissedPluginCalls:function(){var ap=ah;ah=[];var ao=0;for(ao;ao<ap.length;ao++){af(ap[ao])}}};if(typeof define==="function"&&define.amd){define("piwik",[],function(){return e});define("matomo",[],function(){return e})}return e}())}
77
  /*!!! pluginTrackerHook */
78
+ (function(){function b(){if("object"!==typeof _paq){return false}var c=typeof _paq.length;if("undefined"===c){return false}return !!_paq.length}if(window&&"object"===typeof window.piwikPluginAsyncInit&&window.piwikPluginAsyncInit.length){var a=0;for(a;a<window.piwikPluginAsyncInit.length;a++){if(typeof window.piwikPluginAsyncInit[a]==="function"){window.piwikPluginAsyncInit[a]()}}}if(window&&window.piwikAsyncInit){window.piwikAsyncInit()}if(!window.Piwik.getAsyncTrackers().length){if(b()){window.Piwik.addTracker()
79
+ }else{_paq={push:function(c){var d=typeof console;if(d!=="undefined"&&console&&console.error){console.error("_paq.push() was used but Matomo tracker was not initialized before the matomo.js file was loaded. Make sure to configure the tracker via _paq.push before loading matomo.js. Alternatively, you can create a tracker via Matomo.addTracker() manually and then use _paq.push but it may not fully work as tracker methods may not be executed in the correct order.",c)}}}}}window.Piwik.trigger("PiwikInitialized",[]);window.Piwik.initialized=true}());(function(){var a=(typeof AnalyticsTracker);if(a==="undefined"){AnalyticsTracker=window.Piwik}}());if(typeof piwik_log!=="function"){piwik_log=function(b,f,d,g){function a(h){try{if(window["piwik_"+h]){return window["piwik_"+h]}}catch(i){}return}var c,e=window.Piwik.getTracker(d,f);e.setDocumentTitle(b);e.setCustomData(g);c=a("tracker_pause");if(c){e.setLinkTrackingTimer(c)}c=a("download_extensions");if(c){e.setDownloadExtensions(c)}c=a("hosts_alias");
80
+ if(c){e.setDomains(c)}c=a("ignore_classes");if(c){e.setIgnoreClasses(c)}e.trackPageView();if(a("install_tracker")){piwik_track=function(i,k,j,h){e.setSiteId(k);e.setTrackerUrl(j);e.trackLink(i,h)};e.enableLinkTracking()}}}
81
  /*!! @license-end */;
app/plugins/CoreAdminHome/Tasks.php CHANGED
@@ -277,6 +277,11 @@ class Tasks extends \Piwik\Plugin\Tasks
277
  if (empty($purgedDates[$yesterdayStr])) {
278
  $this->archivePurger->purgeInvalidatedArchivesFrom($yesterday);
279
  }
 
 
 
 
 
280
  }
281
 
282
  public function optimizeArchiveTable()
277
  if (empty($purgedDates[$yesterdayStr])) {
278
  $this->archivePurger->purgeInvalidatedArchivesFrom($yesterday);
279
  }
280
+ // handle year start table
281
+ $yearStart = $today->toString('Y-01');
282
+ if (empty($purgedDates[$yearStart])) {
283
+ $this->archivePurger->purgeInvalidatedArchivesFrom(Date::factory($yearStart . '-01'));
284
+ }
285
  }
286
 
287
  public function optimizeArchiveTable()
app/plugins/GeoIp2/Commands/ConvertRegionCodesToIso.php DELETED
@@ -1,124 +0,0 @@
1
- <?php
2
- /**
3
- * Piwik - 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
- namespace Piwik\Plugins\GeoIp2\Commands;
10
-
11
- use Piwik\Common;
12
- use Piwik\Db;
13
- use Piwik\DbHelper;
14
- use Piwik\Option;
15
- use Piwik\Plugin\ConsoleCommand;
16
- use Piwik\Plugins\UserCountry\LocationProvider;
17
- use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2;
18
- use Symfony\Component\Console\Input\InputInterface;
19
- use Symfony\Component\Console\Output\OutputInterface;
20
-
21
- class ConvertRegionCodesToIso extends ConsoleCommand
22
- {
23
- const OPTION_NAME = 'regioncodes_converted';
24
- const MAPPING_TABLE_NAME = 'fips2iso';
25
-
26
- protected function configure()
27
- {
28
- $this->setName('usercountry:convert-region-codes');
29
- $this->setDescription("Convert FIPS region codes saved by GeoIP legacy provider to ISO.");
30
- }
31
-
32
- public function isEnabled()
33
- {
34
- return (LocationProvider::getCurrentProvider() instanceof GeoIp2);
35
- }
36
-
37
- /**
38
- * @param InputInterface $input
39
- * @param OutputInterface $output
40
- * @return void|int
41
- */
42
- protected function execute(InputInterface $input, OutputInterface $output)
43
- {
44
- // chick if option is set to disable second run
45
- if (Option::get(self::OPTION_NAME)) {
46
- $output->writeln('Converting region codes already done.');
47
- return;
48
- }
49
-
50
- $output->setDecorated(true);
51
-
52
- $output->write('Creating mapping table in database');
53
-
54
- Db::query('DROP table if exists ' . self::MAPPING_TABLE_NAME);
55
-
56
- DbHelper::createTable(self::MAPPING_TABLE_NAME,
57
- "`country_code` VARCHAR(2) NOT NULL,
58
- `fips_code` VARCHAR(2) NOT NULL,
59
- `iso_code` VARCHAR(4) NULL DEFAULT NULL,
60
- PRIMARY KEY (`country_code`, `fips_code`)");
61
-
62
- $output->writeln(' <fg=green>✓</>');
63
-
64
- $mappings = include __DIR__ . '/../data/regionMapping.php';
65
-
66
- $output->write('Inserting mapping data ');
67
-
68
- $counter = 0;
69
- foreach ($mappings as $country => $regionMapping) {
70
- foreach ($regionMapping as $fips => $iso) {
71
- if ($fips == $iso) {
72
- continue; // nothing needs to be changed, so ignore the mapping
73
- }
74
-
75
- Db::query('INSERT INTO `'.Common::prefixTable(self::MAPPING_TABLE_NAME).'` VALUES (?, ?, ?)', [$country, $fips, $iso]);
76
- $counter++;
77
- if ($counter%50 == 0) {
78
- $output->write('.');
79
- }
80
- }
81
- }
82
-
83
- $output->writeln(' <fg=green>✓</>');
84
-
85
- $output->writeln('Updating Matomo log tables:');
86
-
87
- $activationTime = Option::get(GeoIp2::SWITCH_TO_ISO_REGIONS_OPTION_NAME);
88
- $activationDateTime = date('Y-m-d H:i:s', $activationTime);
89
-
90
- // fix country and region of tibet so it wil be updated correctly afterwards
91
- $tibetFixQuery = 'UPDATE %s SET location_country = "cn", location_region = "14" WHERE location_country = "ti"';
92
-
93
- // replace invalid country codes used by GeoIP Legacy
94
- $fixInvalidCountriesQuery = 'UPDATE %s SET location_country = "" WHERE location_country IN("AP", "EU", "A1", "A2")';
95
-
96
- $query = "UPDATE %s INNER JOIN %s ON location_country = country_code AND location_region = fips_code SET location_region = iso_code
97
- WHERE `%s` < ?";
98
-
99
- $logTables = ['log_visit' => 'visit_first_action_time', 'log_conversion' => 'server_time'];
100
-
101
- foreach ($logTables as $logTable => $dateField) {
102
- $output->write('- Updating ' . $logTable);
103
-
104
- Db::query(sprintf($tibetFixQuery, Common::prefixTable($logTable)));
105
- Db::query(sprintf($fixInvalidCountriesQuery, Common::prefixTable($logTable)));
106
-
107
- $sql = sprintf($query, Common::prefixTable($logTable), Common::prefixTable(self::MAPPING_TABLE_NAME), $dateField);
108
- Db::query($sql, $activationDateTime);
109
-
110
- $output->writeln(' <fg=green>✓</>');
111
- }
112
-
113
- $output->write('Removing mapping table from database ');
114
- Db::dropTables(Common::prefixTable(self::MAPPING_TABLE_NAME));
115
- $output->writeln(' <fg=green>✓</>');
116
-
117
- // save option to prevent a second run
118
- Option::set(self::OPTION_NAME, true);
119
-
120
- $output->writeln('All region codes converted.');
121
- }
122
-
123
-
124
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
assets/css/admin-style.css CHANGED
@@ -10,27 +10,6 @@
10
  word-break: break-all;
11
  }
12
 
13
- .matomo-hero {
14
- text-align: center;background: #3152a0;padding: 30px 20%;
15
- }
16
-
17
- .matomo-hero h2 {
18
- color: white;font-size: 26px;line-height: 1.3;margin-top: 0;
19
- }
20
- .matomo-hero .matomo-cta-button {
21
- background: #f77b00;color: white;padding: 8px 24px;
22
- min-height: 28px;
23
- height: auto;
24
- }
25
- .matomo-hero .matomo-next-link {
26
- margin-left: 12px;
27
- }
28
- .matomo-hero a:not(.matomo-cta-button) {
29
- color: white;
30
- margin-top: 10px;
31
- display: inline-block;
32
- }
33
-
34
  ul.matomo-list {
35
  list-style-type: disc;
36
  margin-left: 20px;
@@ -40,10 +19,13 @@ ol.matomo-list {
40
  margin-left: 20px;
41
  }
42
 
43
- .plugin-card .matomo-description {
44
- min-height: 57px;
45
  }
46
 
 
 
 
47
  .matomo-blockquote {
48
  margin: .5em 10px;
49
  border-left: 4px solid #ccc;
10
  word-break: break-all;
11
  }
12
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  ul.matomo-list {
14
  list-style-type: disc;
15
  margin-left: 20px;
19
  margin-left: 20px;
20
  }
21
 
22
+ .matomo-plugin-list .plugin-card-top {
23
+ min-height: auto;
24
  }
25
 
26
+ .matomo-marketplace-notice .dashicons-video-alt3 {
27
+ display: inline-block;
28
+ }
29
  .matomo-blockquote {
30
  margin: .5em 10px;
31
  border-left: 4px solid #ccc;
classes/WpMatomo.php CHANGED
@@ -12,12 +12,12 @@ if ( ! defined( 'ABSPATH' ) ) {
12
  }
13
 
14
  use WpMatomo\Admin\Menu;
 
15
  use WpMatomo\Commands\MatomoCommands;
16
  use WpMatomo\Ecommerce\EasyDigitalDownloads;
17
  use WpMatomo\Ecommerce\MemberPress;
18
  use WpMatomo\OptOut;
19
  use WpMatomo\Paths;
20
- use WpMatomo\PrivacyBadge;
21
  use WpMatomo\ScheduledTasks;
22
  use \WpMatomo\Site\Sync as SiteSync;
23
  use WpMatomo\AjaxTracker;
@@ -82,6 +82,9 @@ class WpMatomo {
82
  if ( is_admin() ) {
83
  new Admin( self::$settings );
84
 
 
 
 
85
  $site_sync = new SiteSync( self::$settings );
86
  $site_sync->register_hooks();
87
  $user_sync = new UserSync();
12
  }
13
 
14
  use WpMatomo\Admin\Menu;
15
+ use WpMatomo\Admin\Dashboard;
16
  use WpMatomo\Commands\MatomoCommands;
17
  use WpMatomo\Ecommerce\EasyDigitalDownloads;
18
  use WpMatomo\Ecommerce\MemberPress;
19
  use WpMatomo\OptOut;
20
  use WpMatomo\Paths;
 
21
  use WpMatomo\ScheduledTasks;
22
  use \WpMatomo\Site\Sync as SiteSync;
23
  use WpMatomo\AjaxTracker;
82
  if ( is_admin() ) {
83
  new Admin( self::$settings );
84
 
85
+ $dashboard = new Dashboard();
86
+ $dashboard->register_hooks();
87
+
88
  $site_sync = new SiteSync( self::$settings );
89
  $site_sync->register_hooks();
90
  $user_sync = new UserSync();
classes/WpMatomo/Admin/AdminSettings.php CHANGED
@@ -44,7 +44,7 @@ class AdminSettings {
44
  $exclusions = new ExclusionSettings( $this->settings );
45
  $geolocation = new GeolocationSettings( $this->settings );
46
  $privacy = new PrivacySettings();
47
- $advanced = new AdvancedSettings();
48
  $setting_tabs = array(
49
  self::TAB_TRACKING => $tracking,
50
  self::TAB_ACCESS => $access_settings,
44
  $exclusions = new ExclusionSettings( $this->settings );
45
  $geolocation = new GeolocationSettings( $this->settings );
46
  $privacy = new PrivacySettings();
47
+ $advanced = new AdvancedSettings( $this->settings );
48
  $setting_tabs = array(
49
  self::TAB_TRACKING => $tracking,
50
  self::TAB_ACCESS => $access_settings,
classes/WpMatomo/Admin/AdvancedSettings.php CHANGED
@@ -14,8 +14,6 @@ use Piwik\IP;
14
  use WpMatomo\Bootstrap;
15
  use WpMatomo\Capabilities;
16
  use WpMatomo\Settings;
17
- use WpMatomo\Site;
18
- use WpMatomo\TrackingCode\TrackingCodeGenerator;
19
 
20
  if ( ! defined( 'ABSPATH' ) ) {
21
  exit; // if accessed directly
@@ -37,6 +35,18 @@ class AdvancedSettings implements AdminSettingsInterface {
37
  'HTTP_X_CLUSTER_CLIENT_IP',
38
  );
39
 
 
 
 
 
 
 
 
 
 
 
 
 
40
  public function get_title() {
41
  return esc_html__( 'Advanced', 'matomo' );
42
  }
@@ -60,6 +70,12 @@ class AdvancedSettings implements AdminSettingsInterface {
60
  }
61
 
62
  private function apply_settings() {
 
 
 
 
 
 
63
  Bootstrap::do_bootstrap();
64
  $config = Config::getInstance();
65
  $general = $config->General;
@@ -89,6 +105,7 @@ class AdvancedSettings implements AdminSettingsInterface {
89
  }
90
 
91
  $matomo_detected_ip = IP::getIpFromHeader();
 
92
 
93
  include dirname( __FILE__ ) . '/views/advanced_settings.php';
94
  }
14
  use WpMatomo\Bootstrap;
15
  use WpMatomo\Capabilities;
16
  use WpMatomo\Settings;
 
 
17
 
18
  if ( ! defined( 'ABSPATH' ) ) {
19
  exit; // if accessed directly
35
  'HTTP_X_CLUSTER_CLIENT_IP',
36
  );
37
 
38
+ /**
39
+ * @var Settings
40
+ */
41
+ private $settings;
42
+
43
+ /**
44
+ * @param Settings $settings
45
+ */
46
+ public function __construct( $settings ) {
47
+ $this->settings = $settings;
48
+ }
49
+
50
  public function get_title() {
51
  return esc_html__( 'Advanced', 'matomo' );
52
  }
70
  }
71
 
72
  private function apply_settings() {
73
+ if (!defined('MATOMO_REMOVE_ALL_DATA')) {
74
+ $this->settings->apply_changes(array(
75
+ Settings::DELETE_ALL_DATA_ON_UNINSTALL => !empty($_POST['matomo']['delete_all_data'])
76
+ ));
77
+ }
78
+
79
  Bootstrap::do_bootstrap();
80
  $config = Config::getInstance();
81
  $general = $config->General;
105
  }
106
 
107
  $matomo_detected_ip = IP::getIpFromHeader();
108
+ $matomo_delete_all_data = $this->settings->should_delete_all_data_on_uninstall();
109
 
110
  include dirname( __FILE__ ) . '/views/advanced_settings.php';
111
  }
classes/WpMatomo/Admin/Dashboard.php ADDED
@@ -0,0 +1,129 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * @package matomo
8
+ */
9
+
10
+ namespace WpMatomo\Admin;
11
+
12
+ use WpMatomo\Capabilities;
13
+ use WpMatomo\Logger;
14
+ use WpMatomo\Report\Dates;
15
+ use WpMatomo\Report\Metadata;
16
+ use WpMatomo\Report\Renderer;
17
+ use WpMatomo\Uninstaller;
18
+
19
+ if ( ! defined( 'ABSPATH' ) ) {
20
+ exit; // if accessed directly
21
+ }
22
+
23
+ class Dashboard {
24
+
25
+ const DASHBOARD_USER_OPTION = 'matomo_dashboard_widgets';
26
+
27
+ public function register_hooks() {
28
+ add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widgets' ) );
29
+ }
30
+
31
+ public function add_dashboard_widgets()
32
+ {
33
+ $widgets = $this->get_widgets();
34
+ if (!empty($widgets) && is_array($widgets) && current_user_can(Capabilities::KEY_VIEW)) {
35
+ foreach ($widgets as $widget) {
36
+
37
+ try {
38
+
39
+ $widget_meta = $this->is_valid_widget($widget['unique_id'], $widget['date']);
40
+ if (!empty($widget_meta['report']['name'])) {
41
+ $id = 'matomo_dashboard_widget_' . $widget['unique_id'] . '_' . $widget['date'];
42
+
43
+ $title = $widget_meta['report']['name'] . ' - ' . $widget_meta['date'] . ' - Matomo';
44
+ wp_add_dashboard_widget( $id, esc_html($title), function () use ($widget) {
45
+ $renderer = new Renderer();
46
+ echo $renderer->show_report(array(
47
+ 'unique_id' => $widget['unique_id'],
48
+ 'report_date' => $widget['date'],
49
+ 'limit' => 10,
50
+ ));
51
+ });
52
+ }
53
+ } catch (\Exception $e) {
54
+ // dont want to break dashboard if there is any issue with matomo ... eg in case bootstrap fails
55
+ // or is reinstalled but matomo not yet fully installed etc
56
+ $logger = new Logger();
57
+ $logger->log(sprintf('Failed to add Matomo widget %s to dashboard: %s', wp_json_encode($widget), $e->getMessage()));
58
+ }
59
+ }
60
+ }
61
+ }
62
+
63
+ public function is_valid_widget( $unique_id, $date )
64
+ {
65
+ if (empty($unique_id) || empty($date)) {
66
+ return false;
67
+ }
68
+
69
+ $metadata = new Metadata();
70
+ $report = $metadata->find_report_by_unique_id( $unique_id );
71
+
72
+ if (empty($report)) {
73
+ return false;
74
+ }
75
+
76
+ $report_dates_obj = new Dates();
77
+ $report_dates = $report_dates_obj->get_supported_dates();
78
+
79
+ if (empty($report_dates[$date])) {
80
+ return false;
81
+ }
82
+
83
+ return array('report' => $report, 'date' => $report_dates[$date]);
84
+ }
85
+
86
+ public function has_widget($report_unique_id, $report_date)
87
+ {
88
+ $widgets = $this->get_widgets();
89
+ foreach ($widgets as $index => $widget) {
90
+ if ($widget['unique_id'] === $report_unique_id && $widget['date'] === $report_date) {
91
+ return true;
92
+ }
93
+ }
94
+ return false;
95
+ }
96
+
97
+ public function toggle_widget($report_unique_id, $report_date)
98
+ {
99
+ $widgets = $this->get_widgets();
100
+ foreach ($widgets as $index => $widget) {
101
+ if ($widget['unique_id'] === $report_unique_id && $widget['date'] === $report_date) {
102
+ unset($widgets[$index]);
103
+ $this->set_widgets(array_values($widgets));
104
+ return;
105
+ }
106
+ }
107
+ $widgets[] = array('unique_id' => $report_unique_id, 'date' => $report_date);
108
+
109
+ $this->set_widgets($widgets);
110
+ }
111
+
112
+ public function get_widgets()
113
+ {
114
+ $meta = get_user_meta(get_current_user_id(), self::DASHBOARD_USER_OPTION, true);
115
+ if (empty($meta)) {
116
+ $meta = array();
117
+ }
118
+ return $meta;
119
+ }
120
+
121
+ private function set_widgets($widgets)
122
+ {
123
+ update_user_meta(get_current_user_id(),self::DASHBOARD_USER_OPTION, $widgets);
124
+ }
125
+
126
+ public function uninstall() {
127
+ Uninstaller::uninstall_user_meta(self::DASHBOARD_USER_OPTION);
128
+ }
129
+ }
classes/WpMatomo/Admin/GeolocationSettings.php CHANGED
@@ -41,7 +41,7 @@ class GeolocationSettings implements AdminSettingsInterface {
41
  && check_admin_referer( self::NONCE_NAME )
42
  && current_user_can( Capabilities::KEY_SUPERUSER ) ) {
43
 
44
- $maxmind_license = stripslashes($_POST[ self::FORM_NAME ]);
45
 
46
  if (empty($maxmind_license)) {
47
  $maxmind_license = '';
41
  && check_admin_referer( self::NONCE_NAME )
42
  && current_user_can( Capabilities::KEY_SUPERUSER ) ) {
43
 
44
+ $maxmind_license = trim(stripslashes($_POST[ self::FORM_NAME ]));
45
 
46
  if (empty($maxmind_license)) {
47
  $maxmind_license = '';
classes/WpMatomo/Admin/Menu.php CHANGED
@@ -72,11 +72,6 @@ class Menu {
72
 
73
  $admin_settings = new AdminSettings( $this->settings );
74
 
75
- // managing matomo only works when
76
- // * Network mode is enabled and then it works only in the network mode
77
- // * Network mode is not enabled then it works only for individual blogs as they manage it themselves
78
- $can_matomo_be_managed = $this->settings->is_network_enabled() || ! is_network_admin();
79
-
80
  add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, 'dashicons-analytics' );
81
 
82
  if ( $this->settings->get_global_option( Settings::SHOW_GET_STARTED_PAGE ) && $get_started->can_user_manage() ) {
@@ -147,6 +142,12 @@ class Menu {
147
 
148
  }
149
 
 
 
 
 
 
 
150
  if ( $can_matomo_be_managed ) {
151
  add_submenu_page(
152
  self::$parent_slug,
@@ -175,7 +176,7 @@ class Menu {
175
  );
176
  }
177
 
178
- if ( $can_matomo_be_managed ) {
179
  add_submenu_page(
180
  self::$parent_slug,
181
  __( 'Diagnostics', 'matomo' ),
72
 
73
  $admin_settings = new AdminSettings( $this->settings );
74
 
 
 
 
 
 
75
  add_menu_page( 'Matomo Analytics', 'Matomo Analytics', self::CAP_NOT_EXISTS, 'matomo', null, 'dashicons-analytics' );
76
 
77
  if ( $this->settings->get_global_option( Settings::SHOW_GET_STARTED_PAGE ) && $get_started->can_user_manage() ) {
142
 
143
  }
144
 
145
+ // managing matomo only works when
146
+ // * Network mode is enabled and then it works only in the network mode
147
+ // * Network mode is not enabled then it works only for individual blogs as they manage it themselves
148
+ $can_matomo_be_managed = ( $this->settings->is_network_enabled() && is_network_admin() )
149
+ || ( ! $this->settings->is_network_enabled() && ! is_network_admin() );
150
+
151
  if ( $can_matomo_be_managed ) {
152
  add_submenu_page(
153
  self::$parent_slug,
176
  );
177
  }
178
 
179
+ if ( $this->settings->is_network_enabled() || ! is_network_admin() ) {
180
  add_submenu_page(
181
  self::$parent_slug,
182
  __( 'Diagnostics', 'matomo' ),
classes/WpMatomo/Admin/Summary.php CHANGED
@@ -9,8 +9,10 @@
9
 
10
  namespace WpMatomo\Admin;
11
 
 
12
  use WpMatomo\Report\Dates;
13
  use WpMatomo\Report\Metadata;
 
14
  use WpMatomo\Settings;
15
 
16
  if ( ! defined( 'ABSPATH' ) ) {
@@ -19,6 +21,8 @@ if ( ! defined( 'ABSPATH' ) ) {
19
 
20
  class Summary {
21
 
 
 
22
  /**
23
  * @var Settings
24
  */
@@ -31,7 +35,30 @@ class Summary {
31
  $this->settings = $settings;
32
  }
33
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  public function show() {
 
 
35
  $settings = $this->settings;
36
 
37
  $reports_to_show = $this->get_reports_to_show();
@@ -49,6 +76,8 @@ class Summary {
49
 
50
  $is_tracking = $this->settings->is_tracking_enabled();
51
 
 
 
52
  include dirname( __FILE__ ) . '/views/summary.php';
53
  }
54
 
@@ -78,6 +107,7 @@ class Summary {
78
  $reports_to_show[] = 'Goals_getItemsName';
79
  }
80
 
 
81
  $reports_to_show = apply_filters( 'matomo_report_summary_report_ids', $reports_to_show );
82
 
83
  $report_metadata = array();
9
 
10
  namespace WpMatomo\Admin;
11
 
12
+ use WpMatomo\Capabilities;
13
  use WpMatomo\Report\Dates;
14
  use WpMatomo\Report\Metadata;
15
+ use WpMatomo\Report\Renderer;
16
  use WpMatomo\Settings;
17
 
18
  if ( ! defined( 'ABSPATH' ) ) {
21
 
22
  class Summary {
23
 
24
+ const NONCE_DASHBOARD = 'matomo_pin_dashboard';
25
+
26
  /**
27
  * @var Settings
28
  */
35
  $this->settings = $settings;
36
  }
37
 
38
+ private function pin_if_submitted() {
39
+ if ( ! empty( $_GET[ 'pin' ] )
40
+ && ! empty( $_GET[ 'report_uniqueid' ] )
41
+ && ! empty( $_GET[ 'report_date' ] )
42
+ && is_admin()
43
+ && check_admin_referer( self::NONCE_DASHBOARD )
44
+ && is_user_logged_in()
45
+ && current_user_can( Capabilities::KEY_VIEW ) ) {
46
+ $unique_id = $_GET[ 'report_uniqueid' ];
47
+ $date = $_GET[ 'report_date' ];
48
+
49
+ $dashobard = new Dashboard();
50
+ if ($dashobard->is_valid_widget($unique_id, $date)) {
51
+ $dashobard->toggle_widget( $unique_id, $date );
52
+ return true;
53
+ }
54
+ }
55
+
56
+ return false;
57
+ }
58
+
59
  public function show() {
60
+ $matomo_pinned = $this->pin_if_submitted();
61
+
62
  $settings = $this->settings;
63
 
64
  $reports_to_show = $this->get_reports_to_show();
76
 
77
  $is_tracking = $this->settings->is_tracking_enabled();
78
 
79
+ $matomo_dashboard = new Dashboard();
80
+
81
  include dirname( __FILE__ ) . '/views/summary.php';
82
  }
83
 
107
  $reports_to_show[] = 'Goals_getItemsName';
108
  }
109
 
110
+ $reports_to_show[] = Renderer::CUSTOM_UNIQUE_ID_VISITS_OVER_TIME;
111
  $reports_to_show = apply_filters( 'matomo_report_summary_report_ids', $reports_to_show );
112
 
113
  $report_metadata = array();
classes/WpMatomo/Admin/SystemReport.php CHANGED
@@ -11,6 +11,7 @@ namespace WpMatomo\Admin;
11
 
12
  use Piwik\CliMulti;
13
  use Piwik\Common;
 
14
  use Piwik\Container\StaticContainer;
15
  use Piwik\Filesystem;
16
  use Piwik\MetricsFormatter;
@@ -19,6 +20,7 @@ use Piwik\Plugins\Diagnostics\DiagnosticService;
19
  use Piwik\Plugins\UserCountry\LocationProvider;
20
  use WpMatomo\Bootstrap;
21
  use WpMatomo\Capabilities;
 
22
  use WpMatomo\Logger;
23
  use WpMatomo\Paths;
24
  use WpMatomo\ScheduledTasks;
@@ -322,7 +324,7 @@ class SystemReport {
322
  } catch ( \Exception $e ) {
323
  $rows[] = array(
324
  'name' => esc_html__( 'Matomo System Check', 'matomo' ),
325
- 'value' => 'Failed to run, please open the system check in Matomo',
326
  'comment' => $e->getMessage(),
327
  );
328
  }
@@ -337,6 +339,12 @@ class SystemReport {
337
  'comment' => '',
338
  );
339
 
 
 
 
 
 
 
340
  $rows[] = array(
341
  'section' => 'Endpoints',
342
  );
@@ -457,6 +465,24 @@ class SystemReport {
457
  );
458
  }
459
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
  $num_days_check_visits = 5;
461
  $had_visits = $this->had_visits_in_last_days($num_days_check_visits);
462
  if ($had_visits === false || $had_visits === true) {
@@ -927,6 +953,18 @@ class SystemReport {
927
  );
928
  }
929
 
 
 
 
 
 
 
 
 
 
 
 
 
930
  $grants = $this->get_db_grants();
931
 
932
  // we only show these grants for security reasons as only they are needed and we don't need to know any other ones
@@ -968,6 +1006,45 @@ class SystemReport {
968
  return $rows;
969
  }
970
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
971
  private function get_db_grants() {
972
  global $wpdb;
973
 
11
 
12
  use Piwik\CliMulti;
13
  use Piwik\Common;
14
+ use Piwik\Config;
15
  use Piwik\Container\StaticContainer;
16
  use Piwik\Filesystem;
17
  use Piwik\MetricsFormatter;
20
  use Piwik\Plugins\UserCountry\LocationProvider;
21
  use WpMatomo\Bootstrap;
22
  use WpMatomo\Capabilities;
23
+ use WpMatomo\Installer;
24
  use WpMatomo\Logger;
25
  use WpMatomo\Paths;
26
  use WpMatomo\ScheduledTasks;
324
  } catch ( \Exception $e ) {
325
  $rows[] = array(
326
  'name' => esc_html__( 'Matomo System Check', 'matomo' ),
327
+ 'value' => 'Failed to run Matomo system check.',
328
  'comment' => $e->getMessage(),
329
  );
330
  }
339
  'comment' => '',
340
  );
341
 
342
+ $rows[] = array(
343
+ 'name' => esc_html__( 'Matomo Install Version', 'matomo' ),
344
+ 'value' => get_option(Installer::OPTION_NAME_INSTALL_VERSION),
345
+ 'comment' => '',
346
+ );
347
+
348
  $rows[] = array(
349
  'section' => 'Endpoints',
350
  );
465
  );
466
  }
467
 
468
+ if ( ! \WpMatomo::is_safe_mode() ) {
469
+ Bootstrap::do_bootstrap();
470
+ $general = Config::getInstance()->General;
471
+ if (empty($general['proxy_client_headers'])) {
472
+ foreach (AdvancedSettings::$valid_host_headers as $header) {
473
+ if (!empty($_SERVER[$header])) {
474
+ $rows[] = array(
475
+ 'name' => 'Proxy header',
476
+ 'value' => $header,
477
+ 'is_warning' => true,
478
+ 'comment' => 'A proxy header is set which means you maybe need to configure a proxy header in the Advanced settings to make location reporting work. If the location in your reports is detected correctly, you can ignore this warning.',
479
+ );
480
+ }
481
+ }
482
+ }
483
+
484
+ }
485
+
486
  $num_days_check_visits = 5;
487
  $had_visits = $this->had_visits_in_last_days($num_days_check_visits);
488
  if ($had_visits === false || $had_visits === true) {
953
  );
954
  }
955
 
956
+ $rows[] = array(
957
+ 'name' => 'Matomo tables found',
958
+ 'value' => $this->get_num_matomo_tables(),
959
+ );
960
+
961
+ foreach (['user', 'site'] as $table) {
962
+ $rows[] = array(
963
+ 'name' => 'Matomo '.$table.'s found',
964
+ 'value' => $this->get_num_entries_in_table($table),
965
+ );
966
+ }
967
+
968
  $grants = $this->get_db_grants();
969
 
970
  // we only show these grants for security reasons as only they are needed and we don't need to know any other ones
1006
  return $rows;
1007
  }
1008
 
1009
+ private function get_num_entries_in_table($table) {
1010
+ global $wpdb;
1011
+
1012
+ $db_settings = new \WpMatomo\Db\Settings();
1013
+ $prefix = $db_settings->prefix_table_name($table);
1014
+
1015
+ $results = null;
1016
+ try {
1017
+ $results = $wpdb->get_var('select count(*) from '.$prefix);
1018
+ } catch (\Exception $e) {
1019
+ }
1020
+
1021
+ if (isset($results) && is_numeric($results)) {
1022
+ return $results;
1023
+ }
1024
+
1025
+ return 'table not exists';
1026
+ }
1027
+
1028
+ private function get_num_matomo_tables() {
1029
+ global $wpdb;
1030
+
1031
+ $db_settings = new \WpMatomo\Db\Settings();
1032
+ $prefix = $db_settings->prefix_table_name('');
1033
+
1034
+ $results = null;
1035
+ try {
1036
+ $results = $wpdb->get_results('show tables like "'.$prefix.'%"');
1037
+ } catch (\Exception $e) {
1038
+ $this->logger->log('no show tables: ' . $e->getMessage());
1039
+ }
1040
+
1041
+ if (is_array($results)) {
1042
+ return count($results);
1043
+ }
1044
+
1045
+ return 'show tables not working';
1046
+ }
1047
+
1048
  private function get_db_grants() {
1049
  global $wpdb;
1050
 
classes/WpMatomo/Admin/views/access.php CHANGED
@@ -52,6 +52,11 @@ use WpMatomo\Admin\AccessSettings;
52
  </form>
53
 
54
  <p>
 
 
 
 
 
55
  <?php esc_html_e( 'Learn about the differences between these Matomo roles:', 'matomo' ); ?>
56
  <a href="https://matomo.org/faq/general/faq_70/" target="_blank" rel="noopener"><?php esc_html_e( 'View', 'matomo' ); ?></a>,
57
  <a href="https://matomo.org/faq/general/faq_26910/" target="_blank"
52
  </form>
53
 
54
  <p>
55
+ <?php
56
+ if (!is_multisite()) {
57
+ esc_html_e( 'A user with role administrator automatically has the super user role.', 'matomo' );
58
+ }
59
+ ?>
60
  <?php esc_html_e( 'Learn about the differences between these Matomo roles:', 'matomo' ); ?>
61
  <a href="https://matomo.org/faq/general/faq_70/" target="_blank" rel="noopener"><?php esc_html_e( 'View', 'matomo' ); ?></a>,
62
  <a href="https://matomo.org/faq/general/faq_26910/" target="_blank"
classes/WpMatomo/Admin/views/advanced_settings.php CHANGED
@@ -50,6 +50,20 @@ if ( $was_updated ) {
50
  <?php esc_html_e( 'Should your IP address not match the above value, your WordPress might be behind a proxy and you may need to select a different HTTP header depending on which of the values on the left shows your correct IP address.', 'matomo' ) ?>
51
  </td>
52
  </tr>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
  <tr>
54
  <td colspan="3"><p class="submit"><input name="Submit" type="submit" class="button-primary"
55
  value="<?php esc_attr_e( 'Save Changes', 'matomo' ) ?>"/></p></td>
50
  <?php esc_html_e( 'Should your IP address not match the above value, your WordPress might be behind a proxy and you may need to select a different HTTP header depending on which of the values on the left shows your correct IP address.', 'matomo' ) ?>
51
  </td>
52
  </tr>
53
+ <?php if (!defined('MATOMO_REMOVE_ALL_DATA')) { ?>
54
+ <tr>
55
+ <th width="20%" scope="row"><label for="matomo[delete_all_data]"><?php esc_html_e( 'Delete all data on uninstall', 'matomo' ) ?>:</label>
56
+ </th>
57
+ <td>
58
+ <?php
59
+ echo '<span style="white-space: nowrap;display: inline-block;"><input type="checkbox" ' . ( !empty($matomo_delete_all_data) ? 'checked="checked" ' : '' ) . ' value="1" name="matomo[delete_all_data]" /> '.esc_html__( 'Yes', 'matomo' ).'</span>';
60
+ ?>
61
+ </td>
62
+ <td width="50%">
63
+ By default, when you uninstall the Matomo plugin, all data is deleted and cannot be restored unless you have backups. When you disable this feature, the tracked data in the database will be kept. This can be useful to prevent accidental deletion of all your historical analytics data when you uninstall the plugin. <a href="https://matomo.org/faq/wordpress/how-do-i-delete-or-reset-the-matomo-for-wordpress-data-completely/" target="_blank" rel="noreferrer noopener">Learn more</a>
64
+ </td>
65
+ </tr>
66
+ <?php } ?>
67
  <tr>
68
  <td colspan="3"><p class="submit"><input name="Submit" type="submit" class="button-primary"
69
  value="<?php esc_attr_e( 'Save Changes', 'matomo' ) ?>"/></p></td>
classes/WpMatomo/Admin/views/geolocation_settings.php CHANGED
@@ -58,8 +58,13 @@ if ($invalid_format) { ?>
58
  name="<?php echo esc_attr( GeolocationSettings::FORM_NAME ) ?>" value="<?php echo esc_attr($current_maxmind_license) ?>">
59
  </td>
60
  <td>
61
- <?php esc_html_e('Leave the field empty and click on "Save Changes" to configure the default DB-IP database.', 'matomo') ?>
62
- <?php esc_html_e('When configured, your WordPress will send an HTTP request to a MaxMind server to download an approx. 60MB database and store it in your "wp-content/uploads/matomo" directory.', 'matomo') ?>
 
 
 
 
 
63
  </td>
64
  </tr>
65
  <tr>
58
  name="<?php echo esc_attr( GeolocationSettings::FORM_NAME ) ?>" value="<?php echo esc_attr($current_maxmind_license) ?>">
59
  </td>
60
  <td>
61
+ <?php if (!empty($current_maxmind_license)) {?>
62
+ <p style="color: green;"><span class="dashicons dashicons-yes" ></span> <?php esc_html_e('MaxMind is configured.', 'matomo') ?></p>
63
+ <?php }?>
64
+ <p>
65
+ <?php esc_html_e('Leave the field empty and click on "Save Changes" to configure the default DB-IP database.', 'matomo') ?>
66
+ <?php esc_html_e('When configured, your WordPress will send an HTTP request to a MaxMind server to download an approx. 60MB database and store it in your "wp-content/uploads/matomo" directory.', 'matomo') ?>
67
+ </p>
68
  </td>
69
  </tr>
70
  <tr>
classes/WpMatomo/Admin/views/info_multisite.php CHANGED
@@ -60,7 +60,9 @@ if ( ! defined( 'ABSPATH' ) ) {
60
  foreach ( get_sites() as $matomo_site ) {
61
  /** @var WP_Site $matomo_site */
62
  switch_to_blog( $matomo_site->blog_id );
63
- echo '<li><a href="' . admin_url( 'admin.php?page=matomo-reporting' ) . '">' . $matomo_site->blogname . ' (Blog ID: ' . $matomo_site->blog_id . ')</a></li>';
 
 
64
  restore_current_blog();
65
  }
66
  }
60
  foreach ( get_sites() as $matomo_site ) {
61
  /** @var WP_Site $matomo_site */
62
  switch_to_blog( $matomo_site->blog_id );
63
+ if (function_exists('is_plugin_active') && is_plugin_active('matomo/matomo.php')) {
64
+ echo '<li><a href="' . esc_url(admin_url( 'admin.php?page=matomo-reporting' )) . '">' . esc_html($matomo_site->blogname) . ' (Blog ID: ' . esc_html($matomo_site->blog_id) . ')</a></li>';
65
+ }
66
  restore_current_blog();
67
  }
68
  }
classes/WpMatomo/Admin/views/marketplace.php CHANGED
@@ -28,35 +28,121 @@ $matomo_extra_url_params = '&' . http_build_query(
28
  <p><?php esc_html_e( 'Only super users can see this page', 'matomo' ); ?></p>
29
  </div>
30
  <?php } ?>
31
- <?php if ( $matomo_show_offer ) { ?>
32
- <div class="notice notice-info">
33
- <h3>Limited time only</h3><p>300€ Off Matomo Premium Bundle. Now only 199€/year.</p>
34
- <p><a href="https://matomo.org/wp-premium-bundle/" target="_blank" rel="noreferrer noopener" class="button-primary">Learn more</a></p>
35
- <div style="clear:both;"></div>
36
- </div>
37
- <?php } ?>
38
 
39
  <div id="icon-plugins" class="icon32"></div>
40
 
41
  <h1><?php matomo_header_icon(); ?> <?php esc_html_e( 'Discover new functionality for your Matomo', 'matomo' ); ?></h1>
42
- <p>
43
- <?php esc_html_e( 'Take your Matomo (formerly Piwik) to the next level and drive your conversions & revenue with these premium features. All features are fully hosted on your WordPress and come with 100% data ownership and no limitations.', 'matomo' ); ?>
44
- <?php if ( is_plugin_active( MATOMO_MARKETPLACE_PLUGIN_NAME ) ) { ?>
45
- <a href="https://plugins.matomo.org/?wp=1" target="_blank" rel="noreferrer noopener">&#187; <?php esc_html_e( 'Browse our Marketplace with over 100 free plugins and premium features', 'matomo' ); ?></a>
46
- <?php } ?>
47
- </p>
48
 
49
  <?php if ( ! is_plugin_active( MATOMO_MARKETPLACE_PLUGIN_NAME ) ) { ?>
50
- <div class="matomo-hero">
51
- <h2><?php echo sprintf( esc_html__( 'Easily install over 100 free plugins & %1$spremium features%2$s for Matomo with just a click' ), '<span style="white-space: nowrap;">', '</span>' ); ?></h2>
52
- <a href="https://builds.matomo.org/matomo-marketplace-for-wordpress-latest.zip" rel="noreferrer noopener" class="button matomo-cta-button"><?php esc_html_e( 'Download Matomo Marketplace for WordPress', 'matomo' ); ?></a>
53
- <br>
54
- <a target="_blank" href="https://matomo.org/faq/wordpress/how-do-i-install-a-matomo-marketplace-plugin-in-matomo-for-wordpress/"><span class="dashicons-before dashicons-video-alt3"></span></a> <a target="_blank" href="https://matomo.org/faq/wordpress/how-do-i-install-a-matomo-marketplace-plugin-in-matomo-for-wordpress/"><?php esc_html_e( 'Install instructions', 'matomo' ); ?></a>
55
- <a target="_blank" href="https://plugins.matomo.org/?wp=1" rel="noreferrer noopener" class="matomo-next-link"><?php esc_html_e( 'Browse Marketplace', 'matomo' ); ?></a>
56
- </div>
 
57
  <?php } ?>
58
 
59
  <?php
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
  $matomo_feature_sections = array(
61
  array(
62
  'title' => 'Top free plugins',
@@ -66,233 +152,148 @@ $matomo_extra_url_params = '&' . http_build_query(
66
  array(
67
  array(
68
  'name' => 'Custom Dimensions',
69
- 'description' => 'Extend Matomo to your needs by defining and tracking Custom Dimensions in scope Action or Visit',
70
- 'price' => '',
71
  'download_url' => 'https://plugins.matomo.org/api/2.0/plugins/CustomDimensions/download/latest?wp=1' . $matomo_extra_url_params,
72
- 'url' => 'https://plugins.matomo.org/CustomDimensions?wp=1',
73
  'image' => '',
74
  ),
75
  array(
76
  'name' => 'Custom Alerts',
77
  'description' => 'Create custom Alerts to be notified of important changes on your website or app!',
78
- 'price' => '',
79
  'download_url' => 'https://plugins.matomo.org/api/2.0/plugins/CustomAlerts/download/latest?wp=1' . $matomo_extra_url_params,
80
- 'url' => 'https://plugins.matomo.org/CustomAlerts?wp=1',
81
  'image' => '',
82
  ),
83
  array(
84
  'name' => 'Marketing Campaigns Reporting',
85
  'description' => 'Measure the effectiveness of your marketing campaigns. Track up to five channels instead of two: campaign, source, medium, keyword, content.',
86
- 'price' => '',
87
  'download_url' => 'https://plugins.matomo.org/api/2.0/plugins/MarketingCampaignsReporting/download/latest?wp=1' . $matomo_extra_url_params,
88
- 'url' => 'https://plugins.matomo.org/MarketingCampaignsReporting?wp=1',
89
  'image' => '',
90
  ),
91
  ),
92
  ),
 
 
 
 
 
93
  array(
94
- 'title' => 'Most popular premium features',
95
  'features' =>
96
  array(
97
  array(
98
- 'name' => 'Premium Bundle',
99
- 'description' => 'All premium features in one bundle, make the most out of your Matomo for WordPress and enjoy discounts of over 20%!',
100
- 'price' => '499EUR / 579USD',
101
- 'url' => 'https://plugins.matomo.org/WpPremiumBundle?wp=1',
 
102
  'image' => '',
103
  ),
104
  array(
105
- 'name' => 'Heatmap & Session Recording',
106
- 'description' => 'Truly understand your visitors by seeing where they click, hover, type and scroll. Replay their actions in a video and ultimately increase conversions.',
107
- 'price' => '99EUR / 119USD',
108
- 'url' => 'https://plugins.matomo.org/HeatmapSessionRecording?wp=1',
 
109
  'image' => '',
110
  ),
111
  array(
112
- 'name' => 'Custom Reports',
113
- 'description' => 'Pull out the information you need in order to be successful. Develop your custom strategy to meet your individualized goals while saving money & time.',
114
- 'price' => '99EUR / 119USD',
115
- 'url' => 'https://plugins.matomo.org/CustomReports?wp=1',
 
116
  'image' => '',
117
  ),
118
-
119
- ),
120
- ),
121
- array(
122
- 'title' => 'Most popular content engagement',
123
- 'features' =>
124
- array(
125
  array(
126
  'name' => 'Form Analytics',
127
- 'description' => 'Increase conversions on your online forms and lose less visitors by learning everything about your users behavior and their pain points on your forms.',
128
- 'price' => '79EUR / 89USD',
129
- 'url' => 'https://plugins.matomo.org/FormAnalytics?wp=1',
130
  'image' => '',
 
131
  ),
132
  array(
133
- 'name' => 'Media Analytics',
134
- 'description' => 'Grow your business with advanced video & audio analytics. Get powerful insights into how your audience watches your videos and listens to your audio.',
135
- 'price' => '79EUR / 89USD',
136
- 'url' => 'https://plugins.matomo.org/MediaAnalytics?wp=1',
137
  'image' => '',
 
138
  ),
139
- array(
140
- 'name' => 'Users Flow',
141
- 'description' => 'Users Flow is a visual representation of the most popular paths your users take through your website & app which lets you understand your users needs.',
142
- 'price' => '39EUR / 39USD',
143
- 'url' => 'https://plugins.matomo.org/UsersFlow?wp=1',
144
- 'image' => '',
145
- ),
146
- ),
147
- ),
148
- array(
149
- 'title' => 'Most popular conversion optimisation',
150
- 'features' =>
151
- array(
152
  array(
153
  'name' => 'Funnels',
154
  'description' => 'Identify and understand where your visitors drop off to increase your conversions, sales and revenue with your existing traffic.',
155
- 'price' => '89EUR / 99USD',
156
- 'url' => 'https://plugins.matomo.org/Funnels?wp=1',
 
157
  'image' => '',
158
  ),
159
  array(
160
- 'name' => 'Multi Attribution',
161
- 'description' => 'Get a clear understanding of how much credit each of your marketing channel is actually responsible for to shift your marketing efforts wisely.',
162
- 'price' => '39EUR / 39USD',
163
- 'url' => 'https://plugins.matomo.org/MultiChannelConversionAttribution?wp=1',
 
164
  'image' => '',
165
  ),
166
- ),
167
- ),
168
- array(
169
- 'title' => 'Other Premium Features',
170
- 'features' =>
171
- array(
172
  array(
173
- 'name' => 'Cohorts',
174
- 'description' => 'Track your retention efforts over time and keep your visitors engaged and coming back for more.',
175
- 'price' => '49EUR / 59USD',
176
- 'url' => 'https://plugins.matomo.org/Cohorts?wp=1',
 
177
  'image' => '',
178
  ),
179
  array(
180
- 'name' => 'Search Engine Keywords Performance',
181
- 'description' => 'All keywords searched by your users on search engines are now visible into your Referrers reports! The ultimate solution to \'Keyword not defined\'.',
182
- 'price' => '69EUR / 79USD',
183
- 'url' => 'https://plugins.matomo.org/SearchEngineKeywordsPerformance?wp=1',
 
184
  'image' => '',
185
  ),
186
  array(
187
- 'name' => 'Paid Advertising Performance',
188
- 'description' => 'Analyse the success of your Google Ads campaigns directly in your Matomo. See what keywords and search queries are leading to clicks for your paid ads and bringing your business the highest ROI.',
189
- 'price' => '79EUR / 89USD',
190
- 'url' => 'https://plugins.matomo.org/PaidAdvertisingPerformance?wp=1',
191
  'image' => '',
 
192
  ),
193
- /*
194
  array(
195
- 'name' => 'Activity Log',
196
- 'description' => 'Truly understand your visitors by seeing where they click, hover, type and scroll. Replay their actions in a video and ultimately increase conversions',
197
- 'price' => '19EUR / 19USD',
198
- 'url' => 'https://plugins.matomo.org/ActivityLog?wp=1',
199
  'image' => '',
200
- ),*/
 
201
  ),
202
  ),
203
  );
204
- foreach ( $matomo_feature_sections as $matomo_feature_section ) {
205
- echo '<h2>' . esc_html( $matomo_feature_section['title'] ) . '</h2>';
206
- echo '<div class="wp-list-table widefat plugin-install"><div id="the-list">';
207
- foreach ( $matomo_feature_section['features'] as $matomo_index => $matomo_feature ) {
208
- if ($matomo_show_offer && $matomo_feature['name'] === 'Premium Bundle') {
209
- ?><div class="plugin-card" style="width: calc(33% - 8px);min-width:282px;max-width:350px;">
210
- <div style="border: 6px dashed red;text-align: center">
211
- <h2 style="font-size: 24px;">
212
- <a href="https://matomo.org/wp-premium-bundle/" target="_blank" rel="noreferrer noopener"><span style="color: black;">Limited time!</span><br><br><span style="color:red">300€ Off Premium Bundle</span></a></h2>
213
- <p>All premium features in one bundle.<br>
214
- No risk 100% money back guarantee.<br><br>
215
- <a class="button-primary" href="https://matomo.org/wp-premium-bundle/" target="_blank" rel="noreferrer noopener">Get it for only 199€/year</a>
216
- <br>
217
- </p>
218
- </div>
219
- </div><?php
220
- continue;
221
- }
222
- $matomo_style = '';
223
- $matomo_is_3_columns = count( $matomo_feature_section['features'] ) === 3;
224
- if ( $matomo_is_3_columns ) {
225
- $matomo_style = 'width: calc(33% - 8px);min-width:282px;max-width:350px;';
226
- if ( $matomo_index % 3 === 2 ) {
227
- $matomo_style .= 'clear: inherit;margin-right: 0;margin-left: 16px;';
228
- }
229
- }
230
- ?>
231
- <div class="plugin-card" style="<?php echo $matomo_style; ?>">
232
- <?php
233
- if ( $matomo_is_3_columns && ! empty( $matomo_feature['image'] ) ) {
234
- ?>
235
- <a
236
- href="<?php echo esc_url( $matomo_feature['url'] ); ?>"
237
- rel="noreferrer noopener" target="_blank"
238
- class="thickbox open-plugin-details-modal"><img
239
- src="<?php echo esc_url( $matomo_feature['image'] ); ?>"
240
- style="height: 80px;width:100%;object-fit: cover;" alt=""></a><?php } ?>
241
 
242
- <div class="plugin-card-top">
243
- <div class="
244
- <?php
245
- if ( ! $matomo_is_3_columns ) {
246
- ?>
247
- name column-name<?php } ?>" style="margin-right: 0;<?php if ( empty( $matomo_feature['image'] )) { echo 'margin-left: 0;'; } ?>">
248
- <h3>
249
- <a href="<?php echo esc_url( $matomo_feature['url'] ); ?>"
250
- rel="noreferrer noopener" target="_blank"
251
- class="thickbox open-plugin-details-modal">
252
- <?php echo esc_html( $matomo_feature['name'] ); ?>
253
- </a>
254
- <?php
255
- if ( ! $matomo_is_3_columns && ! empty( $matomo_feature['image'] ) ) {
256
- ?>
257
- <a
258
- href="<?php echo esc_url( $matomo_feature['url'] ); ?>"
259
- rel="noreferrer noopener" target="_blank"
260
- class="thickbox open-plugin-details-modal"><img
261
- src="<?php echo esc_url( $matomo_feature['image'] ); ?>" class="plugin-icon"
262
- style="object-fit: cover;"
263
- alt=""></a><?php } ?>
264
- </h3>
265
- </div>
266
- <div class="
267
- <?php
268
- if ( ! $matomo_is_3_columns ) {
269
- ?>
270
- desc column-description<?php } ?>"
271
- style="margin-right: 0;<?php if ( empty( $matomo_feature['image'] )) { echo 'margin-left: 0;'; } ?>">
272
- <p class="matomo-description"><?php echo esc_html( $matomo_feature['description'] ); ?></p>
273
- <p class="authors"><a class="button-primary"
274
- rel="noreferrer noopener" target="_blank"
275
- href="<?php echo esc_url( ! empty( $matomo_feature['download_url'] ) ? $matomo_feature['download_url'] : $matomo_feature['url'] ); ?>">
276
- <?php
277
- if ( ! empty( $matomo_feature['price'] ) ) {
278
- ?>
279
- <?php echo esc_html( $matomo_feature['price'] ); ?>
280
- <?php
281
- } else {
282
- ?>
283
- Download<?php } ?></a>
284
- </p>
285
- </div>
286
- </div>
287
- </div>
288
- <?php
289
- }
290
- echo '<div style="clear:both;"></div>';
291
- echo '</div>';
292
- if (!empty($matomo_feature_section['more_url'])) {
293
- echo '<a target="_blank" rel="noreferrer noopener" href="'.esc_attr($matomo_feature_section['more_url']).'"><span class="dashicons dashicons-arrow-right-alt2"></span>'. esc_html($matomo_feature_section['more_text']).'</a>';
294
- }
295
- echo '</div>';
296
- }
297
  ?>
 
 
 
 
 
 
298
  </div>
28
  <p><?php esc_html_e( 'Only super users can see this page', 'matomo' ); ?></p>
29
  </div>
30
  <?php } ?>
 
 
 
 
 
 
 
31
 
32
  <div id="icon-plugins" class="icon32"></div>
33
 
34
  <h1><?php matomo_header_icon(); ?> <?php esc_html_e( 'Discover new functionality for your Matomo', 'matomo' ); ?></h1>
 
 
 
 
 
 
35
 
36
  <?php if ( ! is_plugin_active( MATOMO_MARKETPLACE_PLUGIN_NAME ) ) { ?>
37
+ <div class="updated notice matomo-marketplace-notice">
38
+ <p><?php echo sprintf( esc_html__( 'Easily install over 100 free plugins & %1$spremium features%2$s for Matomo with just a click' ), '<span style="white-space: nowrap;">', '</span>' ); ?>
39
+ </p>
40
+ <p><a href="https://builds.matomo.org/matomo-marketplace-for-wordpress-latest.zip" rel="noreferrer noopener" class="button"><?php esc_html_e( 'Download Matomo Marketplace for WordPress', 'matomo' ); ?></a>
41
+
42
+ <a target="_blank" href="https://matomo.org/faq/wordpress/how-do-i-install-a-matomo-marketplace-plugin-in-matomo-for-wordpress/"><span class="dashicons-before dashicons-video-alt3"></span></a> <a target="_blank" href="https://matomo.org/faq/wordpress/how-do-i-install-a-matomo-marketplace-plugin-in-matomo-for-wordpress/"><?php esc_html_e( 'Install instructions', 'matomo' ); ?></a>
43
+ </p>
44
+ </div>
45
  <?php } ?>
46
 
47
  <?php
48
+ function matomo_show_tables($matomo_feature_sections, $matomo_show_offer) {
49
+
50
+ foreach ( $matomo_feature_sections as $matomo_feature_section ) {
51
+ echo '<h2>' . esc_html( $matomo_feature_section['title'] ) . '</h2>';
52
+ echo '<div class="wp-list-table widefat plugin-install matomo-plugin-list"><div id="the-list">';
53
+ foreach ( $matomo_feature_section['features'] as $matomo_index => $matomo_feature ) {
54
+ if ($matomo_show_offer && $matomo_feature['name'] === 'Premium Bundle') {
55
+ ?><div class="plugin-card" style="">
56
+ <div style="border: 6px dashed red;text-align: center">
57
+ <h2 style="font-size: 24px;">
58
+ <a href="https://matomo.org/wp-premium-bundle/" target="_blank" rel="noreferrer noopener"><span style="color: black;">Limited time!</span><br><br><span style="color:red">300€ Off Premium Bundle</span></a></h2>
59
+ <p>All premium features in one bundle.<br>
60
+ No risk 100% money back guarantee.<br><br>
61
+ <a class="button-primary" href="https://matomo.org/wp-premium-bundle/" target="_blank" rel="noreferrer noopener">Get it for only 199€/year</a>
62
+ <br>
63
+ </p>
64
+ </div>
65
+ </div><?php
66
+ continue;
67
+ }
68
+ $matomo_style = '';
69
+ $matomo_is_3_columns = count( $matomo_feature_section['features'] ) === 3;
70
+ if ( $matomo_is_3_columns ) {
71
+ $matomo_style = '';
72
+ }
73
+ ?>
74
+ <div class="plugin-card" style="<?php echo $matomo_style; ?>">
75
+ <?php
76
+ if ( $matomo_is_3_columns && ! empty( $matomo_feature['image'] ) ) {
77
+ ?>
78
+ <a
79
+ href="<?php echo esc_url( $matomo_feature['url'] ); ?>"
80
+ rel="noreferrer noopener" target="_blank"
81
+ class="thickbox open-plugin-details-modal"><img
82
+ src="<?php echo esc_url( $matomo_feature['image'] ); ?>"
83
+ style="height: 80px;width:100%;object-fit: cover;" alt=""></a><?php } ?>
84
+
85
+ <div class="plugin-card-top">
86
+ <div class="
87
+ <?php
88
+ if ( ! $matomo_is_3_columns ) {
89
+ ?>
90
+ name column-name<?php } ?>" style="margin-right: 0;<?php if ( empty( $matomo_feature['image'] )) { echo 'margin-left: 0;'; } ?>">
91
+ <h3>
92
+ <a href="<?php echo esc_url( !empty($matomo_feature['video']) ? $matomo_feature['video'] : $matomo_feature['url'] ); ?>"
93
+ rel="noreferrer noopener" target="_blank"
94
+ class="thickbox open-plugin-details-modal">
95
+ <?php echo esc_html( $matomo_feature['name'] ); ?>
96
+ </a>
97
+ <?php
98
+ if ( ! $matomo_is_3_columns && ! empty( $matomo_feature['image'] ) ) {
99
+ ?>
100
+ <a
101
+ href="<?php echo esc_url( $matomo_feature['url'] ); ?>"
102
+ rel="noreferrer noopener" target="_blank"
103
+ class="thickbox open-plugin-details-modal"><img
104
+ src="<?php echo esc_url( $matomo_feature['image'] ); ?>" class="plugin-icon"
105
+ style="object-fit: cover;"
106
+ alt=""></a><?php } ?>
107
+ </h3>
108
+ </div>
109
+ <div class="
110
+ <?php
111
+ if ( ! $matomo_is_3_columns ) {
112
+ ?>
113
+ desc column-description<?php } ?>"
114
+ style="margin-right: 0;<?php if ( empty( $matomo_feature['image'] )) { echo 'margin-left: 0;'; } ?>">
115
+ <p class="matomo-description"><?php echo esc_html( $matomo_feature['description'] ); ?>
116
+ <?php if (!empty($matomo_feature['video'])) {
117
+ echo ' <a target="_blank" rel="noreferrer noopener" style="white-space: nowrap;" href="'. esc_url($matomo_feature['video']).'"><span class="dashicons dashicons-video-alt3"></span> '. esc_html__( 'Learn more', 'matomo' ).'</a>';
118
+ } elseif (!empty($matomo_feature['url'])) {
119
+ echo ' <a target="_blank" rel="noreferrer noopener" style="white-space: nowrap;" href="'. esc_url($matomo_feature['url']).'">'. esc_html__( 'Learn more', 'matomo' ).'</a>';
120
+ } ?></p>
121
+ <?php if ( ! empty( $matomo_feature['price'] )) {?><p class="authors"><a class="button-primary"
122
+ rel="noreferrer noopener" target="_blank"
123
+ href="<?php echo esc_url( ! empty( $matomo_feature['download_url'] ) ? $matomo_feature['download_url'] : $matomo_feature['url'] ); ?>">
124
+ <?php
125
+ if ($matomo_feature['price'] === 'free' ) {
126
+ esc_html_e('Download', 'matomo');
127
+ } else {
128
+ echo esc_html( $matomo_feature['price'] );
129
+ } ?>
130
+ </a>
131
+ </p><?php } ?>
132
+ </div>
133
+ </div>
134
+ </div>
135
+ <?php
136
+ }
137
+ echo '';
138
+ echo '</div><div style="clear: both"></div>';
139
+ if (!empty($matomo_feature_section['more_url'])) {
140
+ echo '<a target="_blank" rel="noreferrer noopener" href="'.esc_attr($matomo_feature_section['more_url']).'"><span class="dashicons dashicons-arrow-right-alt2"></span>'. esc_html($matomo_feature_section['more_text']).'</a>';
141
+ }
142
+ echo '</div>';
143
+ }
144
+ }
145
+
146
  $matomo_feature_sections = array(
147
  array(
148
  'title' => 'Top free plugins',
152
  array(
153
  array(
154
  'name' => 'Custom Dimensions',
155
+ 'description' => 'Extend Matomo to your needs by defining and tracking Custom Dimensions in scope Action or Visit.',
156
+ 'price' => 'free',
157
  'download_url' => 'https://plugins.matomo.org/api/2.0/plugins/CustomDimensions/download/latest?wp=1' . $matomo_extra_url_params,
158
+ 'url' => 'https://plugins.matomo.org/CustomDimensions?wp=1&pk_campaign=WP&pk_source=Plugin',
159
  'image' => '',
160
  ),
161
  array(
162
  'name' => 'Custom Alerts',
163
  'description' => 'Create custom Alerts to be notified of important changes on your website or app!',
164
+ 'price' => 'free',
165
  'download_url' => 'https://plugins.matomo.org/api/2.0/plugins/CustomAlerts/download/latest?wp=1' . $matomo_extra_url_params,
166
+ 'url' => 'https://plugins.matomo.org/CustomAlerts?wp=1&pk_campaign=WP&pk_source=Plugin',
167
  'image' => '',
168
  ),
169
  array(
170
  'name' => 'Marketing Campaigns Reporting',
171
  'description' => 'Measure the effectiveness of your marketing campaigns. Track up to five channels instead of two: campaign, source, medium, keyword, content.',
172
+ 'price' => 'free',
173
  'download_url' => 'https://plugins.matomo.org/api/2.0/plugins/MarketingCampaignsReporting/download/latest?wp=1' . $matomo_extra_url_params,
174
+ 'url' => 'https://plugins.matomo.org/MarketingCampaignsReporting?wp=1&pk_campaign=WP&pk_source=Plugin',
175
  'image' => '',
176
  ),
177
  ),
178
  ),
179
+ );
180
+
181
+ matomo_show_tables($matomo_feature_sections, $matomo_show_offer);
182
+
183
+ $matomo_feature_sections = array(
184
  array(
185
+ 'title' => '',
186
  'features' =>
187
  array(
188
  array(
189
+ 'name' => 'Heatmaps',
190
+ 'description' => 'Truly understand your visitors by seeing where they click, hover, type and scroll. Find confusing elements, discover useless parts and find out what content your users actually engage with.',
191
+ 'price' => '',
192
+ 'url' => 'https://matomo.org/heatmaps/',
193
+ 'video' => 'https://matomo.org/docs/video-matomos-heatmaps-feature/?pk_campaign=WP&pk_source=Plugin',
194
  'image' => '',
195
  ),
196
  array(
197
+ 'name' => 'Session Recording',
198
+ 'description' => 'Watch videos of how your real visitors use your website and what experience they have. Find out why they leave and what they are looking for so you can improve the usability of your site.',
199
+ 'price' => '',
200
+ 'url' => 'https://matomo.org/session-recordings/',
201
+ 'video' => 'https://matomo.org/docs/matomos-session-recordings-feature/?pk_campaign=WP&pk_source=Plugin',
202
  'image' => '',
203
  ),
204
  array(
205
+ 'name' => 'Users Flow',
206
+ 'description' => 'A visual representation of the most popular paths your users take through your website & app which lets you understand your users needs and where they leave.',
207
+ 'price' => '',
208
+ 'url' => 'https://matomo.org/docs/users-flow/?pk_campaign=WP&pk_source=Plugin',
209
+ 'video' => '',
210
  'image' => '',
211
  ),
 
 
 
 
 
 
 
212
  array(
213
  'name' => 'Form Analytics',
214
+ 'description' => 'Increase conversions on your online forms and lose less visitors by learning everything about your users behavior and their pain points on your forms. No setup needed.',
215
+ 'price' => '',
216
+ 'url' => 'https://matomo.org/form-analytics/?pk_campaign=WP&pk_source=Plugin',
217
  'image' => '',
218
+ 'video' => 'https://matomo.org/docs/video-matomos-form-analytics-feature/?pk_campaign=WP&pk_source=Plugin',
219
  ),
220
  array(
221
+ 'name' => 'Video & Audio Analytics',
222
+ 'description' => 'Get extensive insights into every detail of how your audience watches your videos and listens to your audio. No setup needed.',
223
+ 'price' => '',
224
+ 'url' => 'https://matomo.org/media-analytics/?pk_campaign=WP&pk_source=Plugin',
225
  'image' => '',
226
+ 'video' => 'https://matomo.org/docs/video-media-analytics/?pk_campaign=WP&pk_source=Plugin',
227
  ),
 
 
 
 
 
 
 
 
 
 
 
 
 
228
  array(
229
  'name' => 'Funnels',
230
  'description' => 'Identify and understand where your visitors drop off to increase your conversions, sales and revenue with your existing traffic.',
231
+ 'price' => '',
232
+ 'url' => 'https://matomo.org/funnels/?pk_campaign=WP&pk_source=Plugin',
233
+ 'video' => 'https://matomo.org/docs/video-matomo-analytics-funnels-feature/?pk_campaign=WP&pk_source=Plugin',
234
  'image' => '',
235
  ),
236
  array(
237
+ 'name' => 'Search Engine Keywords',
238
+ 'description' => 'All keywords searched by your users on search engines are now visible into your Referrers reports! The ultimate solution to \'Keyword not defined\'.',
239
+ 'price' => '',
240
+ 'url' => 'https://matomo.org/docs/search-engine-keywords-performance/?pk_campaign=WP&pk_source=Plugin',
241
+ 'video' => '',
242
  'image' => '',
243
  ),
 
 
 
 
 
 
244
  array(
245
+ 'name' => 'Google Ads Integration',
246
+ 'description' => 'Analyse the success of your Google Ads campaigns and how well they contribute to your goals. See what keywords and search queries are leading to clicks for your paid a ds and bringing your business the highest ROI.',
247
+ 'price' => '',
248
+ 'url' => 'https://matomo.org/docs/paid-advertising-performance/?pk_campaign=WP&pk_source=Plugin',
249
+ 'video' => '',
250
  'image' => '',
251
  ),
252
  array(
253
+ 'name' => 'Multi Attribution',
254
+ 'description' => 'Get a clear understanding of how much credit each of your marketing channel is actually responsible for to shift your marketing efforts wisely.',
255
+ 'price' => '',
256
+ 'url' => 'https://matomo.org/multi-attribution/?pk_campaign=WP&pk_source=Plugin',
257
+ 'video' => 'https://matomo.org/docs/video-matomo-analytics-attribution-feature/?pk_campaign=WP&pk_source=Plugin',
258
  'image' => '',
259
  ),
260
  array(
261
+ 'name' => 'Custom Reports',
262
+ 'description' => 'Pull out the information you need in order to be successful. Develop your custom strategy to meet your individualized goals while saving money & time.',
263
+ 'price' => '',
264
+ 'url' => 'https://matomo.org/custom-reports/?pk_campaign=WP&pk_source=Plugin',
265
  'image' => '',
266
+ 'video' => 'https://matomo.org/docs/video-matomos-custom-reports-feature/?pk_campaign=WP&pk_source=Plugin',
267
  ),
 
268
  array(
269
+ 'name' => 'Cohorts',
270
+ 'description' => 'Track your retention efforts over time and keep your visitors engaged and coming back for more.',
271
+ 'price' => '',
272
+ 'url' => 'https://matomo.org/docs/cohorts/?pk_campaign=WP&pk_source=Plugin',
273
  'image' => '',
274
+ 'video' => '',
275
+ ),
276
  ),
277
  ),
278
  );
279
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
280
 
281
+ <div style="border: 1px solid #ddd;padding: 20px;margin-top: 30px;background: white;text-align: center;">
282
+ <h1 style="color: red">Limited time offer! Matomo Premium Bundle only 199€/year (300€ off)</h1>
283
+ <h3>Your marketing efforts are too valuable to focus on the wrong things.<br> Take your Matomo for WordPress to the next level to push out content and changes to your website that make you consistently more successful for less than 17€/month. 🚀</h3>
284
+ <a href="https://matomo.org/wp-premium-bundle/" class="button button-primary"
285
+ style="background: limegreen;border-color: limegreen;font-size: 18px;"
286
+ target="_blank" rel="noreferrer noopener" role="button">Learn more</a>
287
+
288
+ <h2>What's included in this bundle?</h2>
289
+ <?php
290
+
291
+ matomo_show_tables($matomo_feature_sections, $matomo_show_offer);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
292
  ?>
293
+ <h3>All features come with no data limits, max privacy protection and are fully hosted within your WordPress. You own 100% of the data. No data is shared with any other party, ever.
294
+ </h3>
295
+ <h3>Matomo is free open source software. <strong>Purchasing this bundle will help fund the future of the Matomo open-source project.</strong><br>Thank you for your support!</h3>
296
+ <a href="https://matomo.org/wp-premium-bundle/"
297
+ style="background: limegreen;border-color: limegreen;font-size: 18px;" class="button button-primary" target="_blank" rel="noreferrer noopener" role="button">Learn more</a>
298
+ </div>
299
  </div>
classes/WpMatomo/Admin/views/summary.php CHANGED
@@ -20,8 +20,17 @@ if ( ! defined( 'ABSPATH' ) ) {
20
  /** @var string $report_date */
21
  /** @var string $report_period_selected */
22
  /** @var string $report_date_selected */
 
23
  /** @var bool $is_tracking */
 
24
  global $wp;
 
 
 
 
 
 
 
25
  ?>
26
  <?php if ( ! $is_tracking ) { ?>
27
  <div class="notice notice-warning"><p><?php esc_html_e( 'Matomo Tracking is not enabled.', 'matomo' ); ?></p></div>
@@ -70,6 +79,7 @@ global $wp;
70
  title="<?php esc_html_e( 'Click to view the report in detail', 'matomo' ); ?>"><a
71
  href="
72
  <?php
 
73
  echo Menu::get_matomo_reporting_url(
74
  $matomo_report_meta['page']['category'],
75
  $matomo_report_meta['page']['subcategory'],
@@ -82,7 +92,25 @@ global $wp;
82
  " style="color: inherit;text-decoration: none;" target="_blank" rel="noreferrer noopener"
83
  class="dashicons-before dashicons-external" aria-hidden="true"></a></button>
84
  <?php } ?>
85
- <h2 class="hndle ui-sortable-handle"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
86
  style="cursor: help;"
87
  title="<?php echo ! empty( $matomo_report_meta['documentation'] ) ? ( wp_strip_all_tags( $matomo_report_meta['documentation'] ) . ' ' ) : null; ?><?php esc_html_e( 'You can embed this report on any page using the shortcode:', 'matomo' ); ?> <?php echo esc_attr( $shortcode ); ?>"
88
  ><?php echo esc_html( $matomo_report_meta['name'] ); ?></h2>
20
  /** @var string $report_date */
21
  /** @var string $report_period_selected */
22
  /** @var string $report_date_selected */
23
+ /** @var bool $matomo_pinned */
24
  /** @var bool $is_tracking */
25
+ /** @var \WpMatomo\Admin\Dashboard $matomo_dashboard */
26
  global $wp;
27
+
28
+ $matomo_dashboard_nonce = wp_create_nonce(\WpMatomo\Admin\Summary::NONCE_DASHBOARD);
29
+ ?>
30
+ <?php
31
+ if ($matomo_pinned) {
32
+ echo '<div class="notice notice-success"><p>' . esc_html__( 'Dashboard updated.', 'matomo' ) . '</p></div>';
33
+ }
34
  ?>
35
  <?php if ( ! $is_tracking ) { ?>
36
  <div class="notice notice-warning"><p><?php esc_html_e( 'Matomo Tracking is not enabled.', 'matomo' ); ?></p></div>
79
  title="<?php esc_html_e( 'Click to view the report in detail', 'matomo' ); ?>"><a
80
  href="
81
  <?php
82
+
83
  echo Menu::get_matomo_reporting_url(
84
  $matomo_report_meta['page']['category'],
85
  $matomo_report_meta['page']['subcategory'],
92
  " style="color: inherit;text-decoration: none;" target="_blank" rel="noreferrer noopener"
93
  class="dashicons-before dashicons-external" aria-hidden="true"></a></button>
94
  <?php } ?>
95
+
96
+ <?php
97
+ $matomo_is_dashboard_widget = $matomo_dashboard->has_widget($matomo_report_meta['uniqueId'], $report_date);
98
+ ?>
99
+ <button type="button" class="handlediv" aria-expanded="true"
100
+ title="<?php if ($matomo_is_dashboard_widget) { esc_html_e( 'Click to remove this report from the WordPress admin dashboard', 'matomo' ); } else { esc_html_e( 'Click to add this report to the WordPress admin dashboard', 'matomo' ); } ?>"><a
101
+ href="
102
+ <?php
103
+ echo esc_url(add_query_arg(array(
104
+ 'pin' => true,
105
+ '_wpnonce' => $matomo_dashboard_nonce,
106
+ 'report_uniqueid' => $matomo_report_meta['uniqueId'],
107
+ 'report_date' => $report_date,
108
+ ), menu_page_url(Menu::SLUG_REPORT_SUMMARY, false)));
109
+ ?>
110
+ " style="color: inherit;text-decoration: none;<?php if ($matomo_is_dashboard_widget) { echo 'opacity: 0.4 !important'; } ?>"
111
+ class="dashicons-before dashicons-admin-post" aria-hidden="true"></a></button>
112
+
113
+ <h2 class="hndle ui-sortable-handle"
114
  style="cursor: help;"
115
  title="<?php echo ! empty( $matomo_report_meta['documentation'] ) ? ( wp_strip_all_tags( $matomo_report_meta['documentation'] ) . ' ' ) : null; ?><?php esc_html_e( 'You can embed this report on any page using the shortcode:', 'matomo' ); ?> <?php echo esc_attr( $shortcode ); ?>"
116
  ><?php echo esc_html( $matomo_report_meta['name'] ); ?></h2>
classes/WpMatomo/Admin/views/tracking.php CHANGED
@@ -34,8 +34,14 @@ if ( $was_updated ) {
34
  ?>
35
  <form method="post">
36
  <?php wp_nonce_field( TrackingSettings::NONCE_NAME ); ?>
37
-
38
- <p><?php esc_html_e( 'Configure the tracking to your liking.', 'matomo' ); ?></p>
 
 
 
 
 
 
39
  <table class="matomo-tracking-form widefat">
40
  <tbody>
41
 
@@ -49,10 +55,10 @@ if ( $was_updated ) {
49
  $matomo_description = sprintf( '%s<br /><strong>%s:</strong> %s<br /><strong>%s:</strong> %s<br /><strong>%s:</strong> %s<br /><strong>%s:</strong> %s', esc_html__( 'You can choose between four tracking code modes:', 'matomo' ), esc_html__( 'Disabled', 'matomo' ), esc_html__( 'matomo will not add the tracking code. Use this, if you want to add the tracking code to your template files or you use another plugin to add the tracking code.', 'matomo' ), esc_html__( 'Default tracking', 'matomo' ), esc_html__( 'matomo will use Matomo\'s standard tracking code.', 'matomo' ), esc_html__( 'Enter manually', 'matomo' ), esc_html__( 'Enter your own tracking code manually. You can choose one of the prior options, pre-configure your tracking code and switch to manually editing at last.', 'matomo' ) . ( $settings->is_network_enabled() ? ' ' . esc_html__( 'Use the placeholder {ID} to add the Matomo site ID.', 'matomo' ) : '' ), esc_html__( 'Tag Manager', 'matomo' ), esc_html__( 'If you have created containers in the Tag Manager, you can select one of them and it will embed the code for the container automatically.', 'matomo' ) );
50
  $matomo_form->show_select( 'track_mode', esc_html__( 'Add tracking code', 'matomo' ), $track_modes, $matomo_description, 'jQuery(\'tr.matomo-track-option\').addClass(\'hidden\'); jQuery(\'tr.matomo-track-option-\' + jQuery(\'#track_mode\').val()).removeClass(\'hidden\'); jQuery(\'#tracking_code, #noscript_code\').prop(\'readonly\', jQuery(\'#track_mode\').val() != \'manually\');' );
51
 
52
- $matomo_manually_network = '';
53
- if ( $settings->is_network_enabled() ) {
54
- $matomo_manually_network = ' ' . sprintf( esc_html__( 'You can use these variables: %1$s. %2$sLearn more%3$s', 'matomo' ), '{MATOMO_IDSITE}, {MATOMO_API_ENDPOINT}, {MATOMO_JS_ENDPOINT}', '<a href="https://matomo.org/faq/wordpress/how-can-i-configure-the-tracking-code-manually-when-i-have-wordpress-network-enabled-in-multisite-mode/" target="_blank" rel="noreferrer noopener">', '</a>' );
55
- }
56
 
57
  if ( ! empty( $containers ) ) {
58
  echo '<tr class="matomo-track-option matomo-track-option-tagmanager ' . ( $matomo_is_not_tracking ? ' hidden' : '' ) . '">';
@@ -65,7 +71,7 @@ if ( $was_updated ) {
65
  echo '</td></tr>';
66
  }
67
 
68
- $matomo_form->show_textarea( 'tracking_code', esc_html__( 'Tracking code', 'matomo' ), 15, 'This is a preview of your current tracking code. If you choose to enter your tracking code manually, you can change it here. Have a look at the system report to get a list of all available JS tracker and tracking API endpoints.' . $matomo_manually_network, $matomo_is_not_tracking, 'matomo-track-option matomo-track-option-default matomo-track-option-tagmanager matomo-track-option-manually', true, '', ( $settings->get_global_option( 'track_mode' ) !== 'manually' ), false );
69
 
70
  $matomo_form->show_select(
71
  'track_codeposition',
34
  ?>
35
  <form method="post">
36
  <?php wp_nonce_field( TrackingSettings::NONCE_NAME ); ?>
37
+ <p>
38
+ <?php esc_html_e( 'Configure the tracking to your liking.', 'matomo' );
39
+ if ( $settings->is_network_enabled() ) {
40
+ echo ' ';
41
+ esc_html_e( 'These settings will be applied to all blogs in your network.', 'matomo' );
42
+ }
43
+ ?>
44
+ </p>
45
  <table class="matomo-tracking-form widefat">
46
  <tbody>
47
 
55
  $matomo_description = sprintf( '%s<br /><strong>%s:</strong> %s<br /><strong>%s:</strong> %s<br /><strong>%s:</strong> %s<br /><strong>%s:</strong> %s', esc_html__( 'You can choose between four tracking code modes:', 'matomo' ), esc_html__( 'Disabled', 'matomo' ), esc_html__( 'matomo will not add the tracking code. Use this, if you want to add the tracking code to your template files or you use another plugin to add the tracking code.', 'matomo' ), esc_html__( 'Default tracking', 'matomo' ), esc_html__( 'matomo will use Matomo\'s standard tracking code.', 'matomo' ), esc_html__( 'Enter manually', 'matomo' ), esc_html__( 'Enter your own tracking code manually. You can choose one of the prior options, pre-configure your tracking code and switch to manually editing at last.', 'matomo' ) . ( $settings->is_network_enabled() ? ' ' . esc_html__( 'Use the placeholder {ID} to add the Matomo site ID.', 'matomo' ) : '' ), esc_html__( 'Tag Manager', 'matomo' ), esc_html__( 'If you have created containers in the Tag Manager, you can select one of them and it will embed the code for the container automatically.', 'matomo' ) );
56
  $matomo_form->show_select( 'track_mode', esc_html__( 'Add tracking code', 'matomo' ), $track_modes, $matomo_description, 'jQuery(\'tr.matomo-track-option\').addClass(\'hidden\'); jQuery(\'tr.matomo-track-option-\' + jQuery(\'#track_mode\').val()).removeClass(\'hidden\'); jQuery(\'#tracking_code, #noscript_code\').prop(\'readonly\', jQuery(\'#track_mode\').val() != \'manually\');' );
57
 
58
+ $matomo_manually_network = '';
59
+ if ( $settings->is_network_enabled() ) {
60
+ $matomo_manually_network = ' ' . sprintf( esc_html__( 'You can use these variables: %1$s. %2$sLearn more%3$s', 'matomo' ), '{MATOMO_IDSITE}, {MATOMO_API_ENDPOINT}, {MATOMO_JS_ENDPOINT}', '<a href="https://matomo.org/faq/wordpress/how-can-i-configure-the-tracking-code-manually-when-i-have-wordpress-network-enabled-in-multisite-mode/" target="_blank" rel="noreferrer noopener">', '</a>' );
61
+ }
62
 
63
  if ( ! empty( $containers ) ) {
64
  echo '<tr class="matomo-track-option matomo-track-option-tagmanager ' . ( $matomo_is_not_tracking ? ' hidden' : '' ) . '">';
71
  echo '</td></tr>';
72
  }
73
 
74
+ $matomo_form->show_textarea( 'tracking_code', esc_html__( 'Tracking code', 'matomo' ), 15, 'This is a preview of your current tracking code. If you choose to enter your tracking code manually, you can change it here. Have a look at the system report to get a list of all available JS tracker and tracking API endpoints.' . $matomo_manually_network, $matomo_is_not_tracking, 'matomo-track-option matomo-track-option-default matomo-track-option-tagmanager matomo-track-option-manually', ! $settings->is_network_enabled(), '', ( $settings->get_global_option( 'track_mode' ) !== 'manually' ), false );
75
 
76
  $matomo_form->show_select(
77
  'track_codeposition',
classes/WpMatomo/Compatibility.php CHANGED
@@ -9,9 +9,6 @@
9
 
10
  namespace WpMatomo;
11
 
12
- use WP_Roles;
13
- use WpMatomo\Admin\Menu;
14
-
15
  if ( ! defined( 'ABSPATH' ) ) {
16
  exit; // if accessed directly
17
  }
9
 
10
  namespace WpMatomo;
11
 
 
 
 
12
  if ( ! defined( 'ABSPATH' ) ) {
13
  exit; // if accessed directly
14
  }
classes/WpMatomo/Db/Settings.php CHANGED
@@ -29,4 +29,70 @@ class Settings {
29
  return $wpdb->prefix . MATOMO_DATABASE_PREFIX . $table_name_to_prefix;
30
  }
31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  }
29
  return $wpdb->prefix . MATOMO_DATABASE_PREFIX . $table_name_to_prefix;
30
  }
31
 
32
+ public function get_installed_matomo_tables() {
33
+ global $wpdb;
34
+
35
+ $table_names = array();
36
+ $tables = $wpdb->get_results( 'SHOW TABLES LIKE "' . $wpdb->prefix . str_replace( '_', '\_', MATOMO_DATABASE_PREFIX ) . '%"', ARRAY_N );
37
+ foreach ( $tables as $table_name_to_look_for ) {
38
+ $table_names[] = array_shift( $table_name_to_look_for );
39
+ }
40
+
41
+ // we need to hard code them unfortunately for tests cause there are temporary tables used and we can't find a
42
+ // list of existing temp tables
43
+ $table_names_to_look_for = array(
44
+ 'access',
45
+ 'archive_blob_2010_01',
46
+ 'archive_numeric_2010_01',
47
+ 'brute_force_log',
48
+ 'goal',
49
+ 'locks',
50
+ 'log_action',
51
+ 'log_conversion',
52
+ 'log_conversion_item',
53
+ 'log_link_visit_action',
54
+ 'log_profiling',
55
+ 'log_visit',
56
+ 'logger_message',
57
+ 'option',
58
+ 'plugin_setting',
59
+ 'privacy_logdata_anonymizations',
60
+ 'report',
61
+ 'report_subscriptions',
62
+ 'segment',
63
+ 'sequence',
64
+ 'session',
65
+ 'site',
66
+ 'site_setting',
67
+ 'site_url',
68
+ 'tagmanager_container',
69
+ 'tagmanager_container_release',
70
+ 'tagmanager_container_version',
71
+ 'tagmanager_tag',
72
+ 'tagmanager_trigger',
73
+ 'tagmanager_variable',
74
+ 'tracking_failure',
75
+ 'twofactor_recovery_code',
76
+ 'user',
77
+ 'user_dashboard',
78
+ 'user_language',
79
+ );
80
+ foreach ( range( 2010, gmdate( 'Y' ) + 1 ) as $year ) {
81
+ foreach ( range( 1, 12 ) as $month ) {
82
+ $table_names_to_look_for[] = 'archive_numeric_' . $year . '_' . str_pad( $month, 2, '0' );
83
+ $table_names_to_look_for[] = 'archive_blob_' . $year . '_' . str_pad( $month, 2, '0' );
84
+ }
85
+ }
86
+ $table_names_to_look_for = apply_filters( 'matomo_install_tables', $table_names_to_look_for );
87
+
88
+ foreach ( $table_names_to_look_for as $table_name_to_look_for ) {
89
+ $table_name_to_test = $this->prefix_table_name($table_name_to_look_for);
90
+ if ( ! in_array( $table_name_to_test, $table_names, true ) ) {
91
+ $table_names[] = $table_name_to_test;
92
+ }
93
+ }
94
+
95
+ return $table_names;
96
+ }
97
+
98
  }
classes/WpMatomo/Installer.php CHANGED
@@ -15,7 +15,6 @@ use Piwik\Container\StaticContainer;
15
  use Piwik\DbHelper;
16
  use Piwik\Exception\NotYetInstalledException;
17
  use Piwik\Plugin\API as PluginApi;
18
- use Piwik\Plugins\Installation\FormDatabaseSetup;
19
  use Piwik\SettingsPiwik;
20
  use WpMatomo\Site\Sync;
21
 
@@ -26,6 +25,7 @@ if ( ! defined( 'ABSPATH' ) ) {
26
  class Installer {
27
 
28
  const OPTION_NAME_INSTALL_DATE = 'matomo-install-date';
 
29
 
30
  /**
31
  * @var Settings
@@ -114,6 +114,10 @@ class Installer {
114
  wp_schedule_single_event( time() + 35, ScheduledTasks::EVENT_SYNC );
115
 
116
  update_option(self::OPTION_NAME_INSTALL_DATE, time());
 
 
 
 
117
 
118
  $this->create_website();
119
  $this->create_user(); // we sync users as early as possible to make sure things are set up correctly
15
  use Piwik\DbHelper;
16
  use Piwik\Exception\NotYetInstalledException;
17
  use Piwik\Plugin\API as PluginApi;
 
18
  use Piwik\SettingsPiwik;
19
  use WpMatomo\Site\Sync;
20
 
25
  class Installer {
26
 
27
  const OPTION_NAME_INSTALL_DATE = 'matomo-install-date';
28
+ const OPTION_NAME_INSTALL_VERSION = 'matomo-install-version';
29
 
30
  /**
31
  * @var Settings
114
  wp_schedule_single_event( time() + 35, ScheduledTasks::EVENT_SYNC );
115
 
116
  update_option(self::OPTION_NAME_INSTALL_DATE, time());
117
+ $plugin_data = get_plugin_data( MATOMO_ANALYTICS_FILE, $markup = false, $translate = false );
118
+ if ( ! empty( $plugin_data['Version'] )) {
119
+ update_option( self::OPTION_NAME_INSTALL_VERSION, $plugin_data['Version'] );
120
+ }
121
 
122
  $this->create_website();
123
  $this->create_user(); // we sync users as early as possible to make sure things are set up correctly
classes/WpMatomo/OptOut.php CHANGED
@@ -9,8 +9,6 @@
9
 
10
  namespace WpMatomo;
11
 
12
- use WP_Roles;
13
-
14
  if ( ! defined( 'ABSPATH' ) ) {
15
  exit; // if accessed directly
16
  }
9
 
10
  namespace WpMatomo;
11
 
 
 
12
  if ( ! defined( 'ABSPATH' ) ) {
13
  exit; // if accessed directly
14
  }
classes/WpMatomo/Referral.php CHANGED
@@ -9,9 +9,6 @@
9
 
10
  namespace WpMatomo;
11
 
12
- use WP_Roles;
13
- use WpMatomo\Admin\Menu;
14
-
15
  if ( ! defined( 'ABSPATH' ) ) {
16
  exit; // if accessed directly
17
  }
9
 
10
  namespace WpMatomo;
11
 
 
 
 
12
  if ( ! defined( 'ABSPATH' ) ) {
13
  exit; // if accessed directly
14
  }
classes/WpMatomo/Report/Metadata.php CHANGED
@@ -59,6 +59,9 @@ class Metadata {
59
  }
60
 
61
  public function find_report_by_unique_id( $unique_id ) {
 
 
 
62
  $all_reports = self::get_all_reports();
63
 
64
  if ( isset( $all_reports[ $unique_id ] ) ) {
59
  }
60
 
61
  public function find_report_by_unique_id( $unique_id ) {
62
+ if ($unique_id === Renderer::CUSTOM_UNIQUE_ID_VISITS_OVER_TIME) {
63
+ return array('uniqueId' => Renderer::CUSTOM_UNIQUE_ID_VISITS_OVER_TIME, 'name' => 'Visits over time');
64
+ }
65
  $all_reports = self::get_all_reports();
66
 
67
  if ( isset( $all_reports[ $unique_id ] ) ) {
classes/WpMatomo/Report/Renderer.php CHANGED
@@ -16,11 +16,47 @@ if ( ! defined( 'ABSPATH' ) ) {
16
  }
17
 
18
  class Renderer {
 
19
 
20
  public function register_hooks() {
21
  add_shortcode( 'matomo_report', array( $this, 'show_report' ) );
22
  }
23
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
24
  public function show_report( $atts ) {
25
  $a = shortcode_atts(
26
  array(
@@ -31,10 +67,17 @@ class Renderer {
31
  $atts
32
  );
33
 
34
- if ( ! current_user_can( Capabilities::KEY_VIEW ) ) {
35
- // not needed as processRequest checks permission anyway but it's faster this way and double ensures to not
36
- // letting users view it when they have no access.
37
- return esc_html__( 'Sorry, you are not allowed to view this report.', 'matomo' );
 
 
 
 
 
 
 
38
  }
39
 
40
  $metadata = new Metadata();
16
  }
17
 
18
  class Renderer {
19
+ CONST CUSTOM_UNIQUE_ID_VISITS_OVER_TIME = 'visits_over_time';
20
 
21
  public function register_hooks() {
22
  add_shortcode( 'matomo_report', array( $this, 'show_report' ) );
23
  }
24
 
25
+ public function show_visits_over_time($limit)
26
+ {
27
+ $cannot_view = $this->check_cannot_view();
28
+ if ($cannot_view) {
29
+ return $cannot_view;
30
+ }
31
+
32
+ if (is_numeric($limit)) {
33
+ $limit = (int) $limit;
34
+ } else {
35
+ $limit = 14;
36
+ }
37
+
38
+ $report_meta = array('module' => 'VisitsSummary', 'action' => 'get');
39
+
40
+ $data = new Data();
41
+ $report = $data->fetch_report($report_meta, 'day', 'last' . $limit, 'label', $limit);
42
+ $first_metric_name = 'nb_visits';
43
+
44
+ ob_start();
45
+
46
+ include 'views/table_map_no_dimension.php';
47
+
48
+ return ob_get_clean();
49
+ }
50
+
51
+ private function check_cannot_view()
52
+ {
53
+ if ( ! current_user_can( Capabilities::KEY_VIEW ) ) {
54
+ // not needed as processRequest checks permission anyway but it's faster this way and double ensures to not
55
+ // letting users view it when they have no access.
56
+ return esc_html__( 'Sorry, you are not allowed to view this report.', 'matomo' );
57
+ }
58
+ }
59
+
60
  public function show_report( $atts ) {
61
  $a = shortcode_atts(
62
  array(
67
  $atts
68
  );
69
 
70
+ $cannot_view = $this->check_cannot_view();
71
+ if ($cannot_view) {
72
+ return $cannot_view;
73
+ }
74
+
75
+ if ($a['unique_id'] === 'visits_over_time') {
76
+ $is_default_limit = $a['limit'] === 10;
77
+ if ($is_default_limit) {
78
+ $a['limit'] = 14;
79
+ }
80
+ return $this->show_visits_over_time($a['limit']);
81
  }
82
 
83
  $metadata = new Metadata();
classes/WpMatomo/Report/views/table_map_no_dimension.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ * @package matomo
8
+ */
9
+
10
+ if ( ! defined( 'ABSPATH' ) ) {
11
+ exit; // if accessed directly
12
+ }
13
+
14
+ /** @var array $report */
15
+ /** @var array $report_meta */
16
+ /** @var string $first_metric_name */
17
+ ?>
18
+ <div class="table">
19
+ <table class="widefat matomo-table">
20
+
21
+ <tbody>
22
+ <?php
23
+ $matomo_report_metadata = $report['reportMetadata'];
24
+ $matomo_tables = $report['reportData']->getDataTables();
25
+ foreach (array_reverse($matomo_tables) as $matomo_report_date => $matomo_report_table ) {
26
+ /** @var \Piwik\DataTable\Simple $matomo_report_table */
27
+ echo '<tr><td width="75%">' . esc_html( $matomo_report_date ) . '</td><td width="25%">';
28
+ if ($matomo_report_table->getFirstRow()) {
29
+ echo esc_html( $matomo_report_table->getFirstRow()->getColumn( $first_metric_name ) );
30
+ } else {
31
+ echo '-';
32
+ }
33
+ echo '</td></tr>';
34
+ }
35
+ ?>
36
+ </tbody>
37
+ </table>
38
+ </div>
classes/WpMatomo/Settings.php CHANGED
@@ -30,6 +30,7 @@ class Settings {
30
  const OPTION_LAST_TRACKING_SETTINGS_CHANGE = 'last_tracking_settings_update';
31
  const OPTION_LAST_TRACKING_CODE_UPDATE = 'last_tracking_code_update';
32
  const SHOW_GET_STARTED_PAGE = 'show_get_started_page';
 
33
 
34
  public static $is_doing_action_tracking_related = false;
35
 
@@ -52,6 +53,7 @@ class Settings {
52
  self::OPTION_LAST_TRACKING_SETTINGS_CHANGE => 0,
53
  self::OPTION_KEY_STEALTH => array(),
54
  self::OPTION_KEY_CAPS_ACCESS => array(),
 
55
  // User settings: Stats configuration
56
  // User settings: Tracking configuration
57
  'track_mode' => 'disabled',
@@ -389,6 +391,15 @@ class Settings {
389
  return '';
390
  }
391
 
 
 
 
 
 
 
 
 
 
392
  /**
393
  * Check if feed tracking is enabled
394
  *
30
  const OPTION_LAST_TRACKING_SETTINGS_CHANGE = 'last_tracking_settings_update';
31
  const OPTION_LAST_TRACKING_CODE_UPDATE = 'last_tracking_code_update';
32
  const SHOW_GET_STARTED_PAGE = 'show_get_started_page';
33
+ const DELETE_ALL_DATA_ON_UNINSTALL = 'delete_all_data_uninstall';
34
 
35
  public static $is_doing_action_tracking_related = false;
36
 
53
  self::OPTION_LAST_TRACKING_SETTINGS_CHANGE => 0,
54
  self::OPTION_KEY_STEALTH => array(),
55
  self::OPTION_KEY_CAPS_ACCESS => array(),
56
+ self::DELETE_ALL_DATA_ON_UNINSTALL => true,
57
  // User settings: Stats configuration
58
  // User settings: Tracking configuration
59
  'track_mode' => 'disabled',
391
  return '';
392
  }
393
 
394
+ public function should_delete_all_data_on_uninstall()
395
+ {
396
+ if (defined( 'MATOMO_REMOVE_ALL_DATA' )) {
397
+ return (bool) MATOMO_REMOVE_ALL_DATA;
398
+ }
399
+
400
+ return (bool) $this->get_global_option(self::DELETE_ALL_DATA_ON_UNINSTALL);
401
+ }
402
+
403
  /**
404
  * Check if feed tracking is enabled
405
  *
classes/WpMatomo/Uninstaller.php CHANGED
@@ -9,6 +9,8 @@
9
 
10
  namespace WpMatomo;
11
 
 
 
12
  if ( ! defined( 'ABSPATH' ) ) {
13
  exit; // if accessed directly
14
  }
@@ -49,6 +51,9 @@ class Uninstaller {
49
  $roles = new Roles( $settings );
50
  $roles->uninstall();
51
 
 
 
 
52
  $paths = new Paths();
53
 
54
  if ( $should_remove_all_data ) {
@@ -98,6 +103,17 @@ class Uninstaller {
98
  self::uninstall_options( $prefix );
99
  }
100
 
 
 
 
 
 
 
 
 
 
 
 
101
  public function uninstall_multisite( $should_remove_all_data ) {
102
  global $wpdb;
103
 
@@ -116,76 +132,11 @@ class Uninstaller {
116
  }
117
  }
118
 
119
- public function get_installed_matomo_tables() {
120
- global $wpdb;
121
-
122
- $table_names = array();
123
- $tables = $wpdb->get_results( 'SHOW TABLES LIKE "' . $wpdb->prefix . str_replace( '_', '\_', MATOMO_DATABASE_PREFIX ) . '%"', ARRAY_N );
124
- foreach ( $tables as $table_name_to_look_for ) {
125
- $table_names[] = array_shift( $table_name_to_look_for );
126
- }
127
-
128
- // we need to hard code them unfortunately for tests cause there are temporary tables used and we can't find a
129
- // list of existing temp tables
130
- $table_names_to_look_for = array(
131
- 'access',
132
- 'archive_blob_2010_01',
133
- 'archive_numeric_2010_01',
134
- 'brute_force_log',
135
- 'goal',
136
- 'locks',
137
- 'log_action',
138
- 'log_conversion',
139
- 'log_conversion_item',
140
- 'log_link_visit_action',
141
- 'log_profiling',
142
- 'log_visit',
143
- 'logger_message',
144
- 'option',
145
- 'plugin_setting',
146
- 'privacy_logdata_anonymizations',
147
- 'report',
148
- 'report_subscriptions',
149
- 'segment',
150
- 'sequence',
151
- 'session',
152
- 'site',
153
- 'site_setting',
154
- 'site_url',
155
- 'tagmanager_container',
156
- 'tagmanager_container_release',
157
- 'tagmanager_container_version',
158
- 'tagmanager_tag',
159
- 'tagmanager_trigger',
160
- 'tagmanager_variable',
161
- 'tracking_failure',
162
- 'twofactor_recovery_code',
163
- 'user',
164
- 'user_dashboard',
165
- 'user_language',
166
- );
167
- foreach ( range( 2010, gmdate( 'Y' ) + 1 ) as $year ) {
168
- foreach ( range( 1, 12 ) as $month ) {
169
- $table_names_to_look_for[] = 'archive_numeric_' . $year . '_' . str_pad( $month, 2, '0' );
170
- $table_names_to_look_for[] = 'archive_blob_' . $year . '_' . str_pad( $month, 2, '0' );
171
- }
172
- }
173
- $table_names_to_look_for = apply_filters( 'matomo_install_tables', $table_names_to_look_for );
174
-
175
- foreach ( $table_names_to_look_for as $table_name_to_look_for ) {
176
- $table_name_to_test = $wpdb->prefix . MATOMO_DATABASE_PREFIX . $table_name_to_look_for;
177
- if ( ! in_array( $table_name_to_test, $table_names, true ) ) {
178
- $table_names[] = $table_name_to_test;
179
- }
180
- }
181
-
182
- return $table_names;
183
- }
184
-
185
  private function drop_tables() {
186
  global $wpdb;
187
 
188
- $installed_tables = $this->get_installed_matomo_tables();
 
189
  $this->logger->log( sprintf( 'Matomo will now drop %s matomo tables', count( $installed_tables ) ) );
190
 
191
  foreach ( $installed_tables as $table_name ) {
9
 
10
  namespace WpMatomo;
11
 
12
+ use WpMatomo\Admin\Dashboard;
13
+
14
  if ( ! defined( 'ABSPATH' ) ) {
15
  exit; // if accessed directly
16
  }
51
  $roles = new Roles( $settings );
52
  $roles->uninstall();
53
 
54
+ $dashboard = new Dashboard();
55
+ $dashboard->uninstall();
56
+
57
  $paths = new Paths();
58
 
59
  if ( $should_remove_all_data ) {
103
  self::uninstall_options( $prefix );
104
  }
105
 
106
+ public static function uninstall_user_meta( $prefix ) {
107
+ global $wpdb;
108
+
109
+ if ( ! empty( $wpdb->usermeta ) ) {
110
+ self::make_logger()->log( 'Removing usermeta with prefix ' . $prefix );
111
+ $wpdb->query( "DELETE FROM $wpdb->usermeta WHERE meta_key LIKE '" . $prefix . "%';" );
112
+
113
+ wp_cache_flush();
114
+ }
115
+ }
116
+
117
  public function uninstall_multisite( $should_remove_all_data ) {
118
  global $wpdb;
119
 
132
  }
133
  }
134
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
135
  private function drop_tables() {
136
  global $wpdb;
137
 
138
+ $db_settings = new \WpMatomo\Db\Settings();
139
+ $installed_tables = $db_settings->get_installed_matomo_tables();
140
  $this->logger->log( sprintf( 'Matomo will now drop %s matomo tables', count( $installed_tables ) ) );
141
 
142
  foreach ( $installed_tables as $table_name ) {
classes/WpMatomo/Updater.php CHANGED
@@ -115,6 +115,9 @@ class Updater {
115
  $this->settings->set_global_option( 'core_version', Version::VERSION );
116
  $this->settings->save();
117
 
 
 
 
118
  \Piwik\Access::doAsSuperUser(
119
  function () {
120
  self::update_components();
@@ -122,7 +125,6 @@ class Updater {
122
  }
123
  );
124
 
125
- $paths = new Paths();
126
  $upload_dir = $paths->get_upload_base_dir();
127
  if ( is_dir( $upload_dir ) && is_writable( $upload_dir ) ) {
128
  @file_put_contents( $upload_dir . '/index.php', '//hello' );
115
  $this->settings->set_global_option( 'core_version', Version::VERSION );
116
  $this->settings->save();
117
 
118
+ $paths = new Paths();
119
+ $paths->clear_cache_dir();
120
+
121
  \Piwik\Access::doAsSuperUser(
122
  function () {
123
  self::update_components();
125
  }
126
  );
127
 
 
128
  $upload_dir = $paths->get_upload_base_dir();
129
  if ( is_dir( $upload_dir ) && is_writable( $upload_dir ) ) {
130
  @file_put_contents( $upload_dir . '/index.php', '//hello' );
classes/WpMatomo/User/Sync.php CHANGED
@@ -63,7 +63,7 @@ class Sync {
63
 
64
  try {
65
  if ( $idsite ) {
66
- $users = get_users( array( 'blog_id' => $site->blog_id ) );
67
  $this->sync_users( $users, $idsite );
68
  }
69
  } catch ( \Exception $e ) {
@@ -78,10 +78,37 @@ class Sync {
78
  }
79
  }
80
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  public function sync_current_users() {
82
  $idsite = Site::get_matomo_site_id( get_current_blog_id() );
83
  if ( $idsite ) {
84
- $users = get_users();
85
  $this->sync_users( $users, $idsite );
86
  }
87
  }
63
 
64
  try {
65
  if ( $idsite ) {
66
+ $users = $this->get_users( array('blog_id' => $site->blog_id ) );
67
  $this->sync_users( $users, $idsite );
68
  }
69
  } catch ( \Exception $e ) {
78
  }
79
  }
80
 
81
+ private function get_users($options = array())
82
+ {
83
+ /** @var \WP_User[] $users */
84
+ $users = get_users( $options );
85
+ if (is_multisite()) {
86
+ $super_admins = get_super_admins();
87
+ if (!empty($super_admins)) {
88
+ foreach ($super_admins as $super_admin) {
89
+ $found = false;
90
+ foreach ($users as $user) {
91
+ if ($user->user_login === $super_admin) {
92
+ $found = true;
93
+ break;
94
+ }
95
+ }
96
+ if (!$found) {
97
+ $user = get_user_by('login', $super_admin);
98
+ if (!empty($user)) {
99
+ $users[] = $user;
100
+ }
101
+ }
102
+ }
103
+ }
104
+ }
105
+ return $users;
106
+ }
107
+
108
  public function sync_current_users() {
109
  $idsite = Site::get_matomo_site_id( get_current_blog_id() );
110
  if ( $idsite ) {
111
+ $users = $this->get_users();
112
  $this->sync_users( $users, $idsite );
113
  }
114
  }
config/config.php CHANGED
@@ -17,6 +17,7 @@ return array(
17
  $paths = new \WpMatomo\Paths();
18
  return $paths->get_relative_dir_to_matomo($paths->get_upload_base_dir()) . '/';
19
  },
 
20
  'path.geoip2' => function () {
21
  $paths = new \WpMatomo\Paths();
22
  return $paths->get_gloal_upload_dir_if_possible('DBIP-City.mmdb') . '/';
17
  $paths = new \WpMatomo\Paths();
18
  return $paths->get_relative_dir_to_matomo($paths->get_upload_base_dir()) . '/';
19
  },
20
+ 'EnableDbVersionCheck' => false,
21
  'path.geoip2' => function () {
22
  $paths = new \WpMatomo\Paths();
23
  return $paths->get_gloal_upload_dir_if_possible('DBIP-City.mmdb') . '/';
matomo.php CHANGED
@@ -4,7 +4,7 @@
4
  * Description: The #1 Google Analytics alternative that gives you full control over your data and protects the privacy for your users. Free, secure and open.
5
  * Author: Matomo
6
  * Author URI: https://matomo.org
7
- * Version: 1.0.6
8
  * Domain Path: /languages
9
  * WC requires at least: 2.4.0
10
  * WC tested up to: 4.0.0
4
  * Description: The #1 Google Analytics alternative that gives you full control over your data and protects the privacy for your users. Free, secure and open.
5
  * Author: Matomo
6
  * Author URI: https://matomo.org
7
+ * Version: 1.1.0
8
  * Domain Path: /languages
9
  * WC requires at least: 2.4.0
10
  * WC tested up to: 4.0.0
plugins/WordPress/Menu.php CHANGED
@@ -12,6 +12,9 @@ namespace Piwik\Plugins\WordPress;
12
  use Piwik\Menu\MenuAdmin;
13
  use Piwik\Menu\MenuTop;
14
  use Piwik\Piwik;
 
 
 
15
 
16
  class Menu extends \Piwik\Plugin\Menu
17
  {
@@ -33,6 +36,27 @@ class Menu extends \Piwik\Plugin\Menu
33
 
34
  public function configureTopMenu(MenuTop $menu)
35
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
36
  $menu->addItem(__('WordPress Admin', 'matomo'), null, $this->urlForAction('goToWordPress'), '500', __('Go back to WordPress Admin Dashboard', 'matomo'), 'icon-close');
37
  $menu->remove('General_Help');
38
  }
12
  use Piwik\Menu\MenuAdmin;
13
  use Piwik\Menu\MenuTop;
14
  use Piwik\Piwik;
15
+ use Piwik\Plugins\LanguagesManager\API;
16
+ use Piwik\View;
17
+ use WpMatomo\Capabilities;
18
 
19
  class Menu extends \Piwik\Plugin\Menu
20
  {
36
 
37
  public function configureTopMenu(MenuTop $menu)
38
  {
39
+ if (is_multisite()) {
40
+
41
+ $view = new View("@WordPress/blogselection");
42
+ $sites = array();
43
+ foreach ( get_sites() as $matomo_site ) {
44
+ /** @var \WP_Site $matomo_site */
45
+ switch_to_blog( $matomo_site->blog_id );
46
+ if (function_exists('is_plugin_active')
47
+ && is_plugin_active('matomo/matomo.php')
48
+ && current_user_can(Capabilities::KEY_VIEW)) {
49
+ $sites[] = array('id' => $matomo_site->blog_id, 'name' => $matomo_site->blogname, 'url' => admin_url( 'admin.php?page=matomo-reporting' ));
50
+ }
51
+ restore_current_blog();
52
+ }
53
+ if (!empty($sites) && count($sites) > 1) {
54
+ $view->currentId = get_current_blog_id();
55
+ $view->sites = $sites;
56
+ $menu->addHtml('BlogSelector', $view->render(), true, $order = 30, false);
57
+ }
58
+ }
59
+
60
  $menu->addItem(__('WordPress Admin', 'matomo'), null, $this->urlForAction('goToWordPress'), '500', __('Go back to WordPress Admin Dashboard', 'matomo'), 'icon-close');
61
  $menu->remove('General_Help');
62
  }
plugins/WordPress/WordPress.php CHANGED
@@ -83,6 +83,8 @@ class WordPress extends Plugin
83
  if ($challenge['id'] === 'track_data') {
84
  $challenges[$index]['url'] = ''; // we can't generate menu url for tracking settings since we're not showing the menu
85
  $challenges[$index]['description'] = __('In WordPress Admin go to Matomo Analytics => Settings => Tracking to embed the tracking code.', 'matomo');
 
 
86
  }
87
  }
88
  }
83
  if ($challenge['id'] === 'track_data') {
84
  $challenges[$index]['url'] = ''; // we can't generate menu url for tracking settings since we're not showing the menu
85
  $challenges[$index]['description'] = __('In WordPress Admin go to Matomo Analytics => Settings => Tracking to embed the tracking code.', 'matomo');
86
+ } elseif ($challenge['id'] === 'custom_logo') {
87
+ unset($challenges[$index]);
88
  }
89
  }
90
  }
plugins/WordPress/templates/blogselection.twig ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <div class="languageSelection" ng-cloak menu-title="Blogs" piwik-menudropdown>
2
+ {% for site in sites %}
3
+ <a class="item {% if currentId == site.id %}active{% endif %}" href="{{ site.url|e('html_attr') }}"> {{ site.name }} (Blog ID: {{ site.id }})</a>
4
+ {% endfor %}
5
+ </div>
readme.txt CHANGED
@@ -4,7 +4,7 @@ Donate link: https://www.paypal.com/cgi-bin/webscr?cmd=_s-xclick&hosted_button_i
4
  Tags: matomo,piwik,analytics,statistics,stats,tracking,ecommerce
5
  Requires at least: 4.8
6
  Tested up to: 5.4
7
- Stable tag: 1.0.6
8
  Requires PHP: 7.2
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
4
  Tags: matomo,piwik,analytics,statistics,stats,tracking,ecommerce
5
  Requires at least: 4.8
6
  Tested up to: 5.4
7
+ Stable tag: 1.1.0
8
  Requires PHP: 7.2
9
  License: GPLv3 or later
10
  License URI: https://www.gnu.org/licenses/gpl-3.0.html
uninstall.php CHANGED
@@ -15,7 +15,8 @@ if ( ! defined( 'WP_UNINSTALL_PLUGIN' ) ) {
15
  require 'shared.php';
16
 
17
  $matomo_is_using_multi_site = function_exists( 'is_multisite' ) && is_multisite();
18
- $matomo_should_remove_all_data = defined( 'MATOMO_REMOVE_ALL_DATA' ) && MATOMO_REMOVE_ALL_DATA === true;
 
19
 
20
  $matomo_uninstaller = new \WpMatomo\Uninstaller();
21
  $matomo_uninstaller->uninstall( $matomo_should_remove_all_data );
15
  require 'shared.php';
16
 
17
  $matomo_is_using_multi_site = function_exists( 'is_multisite' ) && is_multisite();
18
+ $matomo_settings = new \WpMatomo\Settings();
19
+ $matomo_should_remove_all_data = $matomo_settings->should_delete_all_data_on_uninstall();
20
 
21
  $matomo_uninstaller = new \WpMatomo\Uninstaller();
22
  $matomo_uninstaller->uninstall( $matomo_should_remove_all_data );