diff options
46 files changed, 685 insertions, 183 deletions
diff --git a/core/API/Request.php b/core/API/Request.php index 4d30aa13db..fd9a7327bc 100644 --- a/core/API/Request.php +++ b/core/API/Request.php @@ -214,6 +214,8 @@ class Request */ public function process() { + $shouldReloadAuth = false; + try { ++self::$nestedApiInvocationCount; @@ -232,7 +234,6 @@ class Request $corsHandler->handle(); $tokenAuth = Common::getRequestVar('token_auth', '', 'string', $this->request); - $shouldReloadAuth = false; // IP check is needed here as we cannot listen to API.Request.authenticate as it would then not return proper API format response. // We can also not do it by listening to API.Request.dispatch as by then the user is already authenticated and we want to make sure @@ -275,6 +276,10 @@ class Request 'ignoreInScreenWriter' => true, ]); + if (empty($response)) { + $response = new ResponseBuilder('console', $this->request); + } + $toReturn = $response->getResponseException($e); } finally { --self::$nestedApiInvocationCount; diff --git a/core/Archive/ArchiveInvalidator.php b/core/Archive/ArchiveInvalidator.php index fcee4f7466..129db58151 100644 --- a/core/Archive/ArchiveInvalidator.php +++ b/core/Archive/ArchiveInvalidator.php @@ -15,6 +15,7 @@ use Piwik\CronArchive\SitesToReprocessDistributedList; use Piwik\DataAccess\ArchiveTableCreator; use Piwik\DataAccess\Model; use Piwik\Date; +use Piwik\Db; use Piwik\Option; use Piwik\Common; use Piwik\Piwik; @@ -124,7 +125,6 @@ class ArchiveInvalidator $generalCache = Cache::getCacheGeneral(); if (empty($generalCache[$cacheKey][$idSite][$dateStr])) { - Cache::clearCacheGeneral(); return []; } @@ -177,12 +177,14 @@ class ArchiveInvalidator public function forgetRememberedArchivedReportsToInvalidateForSite($idSite) { $id = $this->buildRememberArchivedReportIdForSite($idSite) . '_%'; - Option::deleteLike($id); + $this->deleteOptionLike($id); Cache::clearCacheGeneral(); } /** * @internal + * After calling this method, make sure to call Cache::clearCacheGeneral(); For performance reasons we don't call + * this here immediately in case there are multiple invalidations. */ public function forgetRememberedArchivedReportsToInvalidate($idSite, Date $date) { @@ -190,10 +192,28 @@ class ArchiveInvalidator // The process pid is added to the end of the entry in order to support multiple concurrent transactions. // So this must be a deleteLike call to get all the entries, where there used to only be one. - Option::deleteLike($id . '%'); + $this->deleteOptionLike($id); Cache::clearCacheGeneral(); } + private function deleteOptionLike($id) + { + // we're not using deleteLike since it maybe could cause deadlocks see https://github.com/matomo-org/matomo/issues/15545 + // we want to reduce number of rows scanned and only delete specific primary key + $keys = Option::getLike($id . '%'); + + if (empty($keys)) { + return; + } + + $keys = array_keys($keys); + + $placeholders = Common::getSqlStringFieldsArray($keys); + + $table = Common::prefixTable('option'); + Db::query('DELETE FROM `' . $table . '` WHERE `option_name` IN (' . $placeholders . ')', $keys); + } + /** * @param $idSites int[] * @param $dates Date[] @@ -267,6 +287,7 @@ class ArchiveInvalidator $this->forgetRememberedArchivedReportsToInvalidate($idSite, $date); } } + Cache::clearCacheGeneral(); return $invalidationInfo; } @@ -309,6 +330,8 @@ class ArchiveInvalidator } } + Cache::clearCacheGeneral(); + $archivesToPurge = new ArchivesToPurgeDistributedList(); $archivesToPurge->add($invalidatedMonths); diff --git a/core/Cookie.php b/core/Cookie.php index 43b3f777d2..26cbfe6a3f 100644 --- a/core/Cookie.php +++ b/core/Cookie.php @@ -445,14 +445,11 @@ class Cookie $ddFactory = StaticContainer::get(\Piwik\DeviceDetector\DeviceDetectorFactory::class); $deviceDetector = $ddFactory->makeInstance($userAgent); $deviceDetector->parse(); - $browser = $deviceDetector->getClient(); - if (is_array($browser)) { - $browser = $browser['name']; - } - if ((!ProxyHttp::isHttps()) && $browser === 'Chrome') { + $browserFamily = \DeviceDetector\Parser\Client\Browser::getBrowserFamily($deviceDetector->getClient('short_name')); + if ((!ProxyHttp::isHttps()) && $browserFamily === 'Chrome') { $sameSite = 'Lax'; - } else if ($browser === 'Safari') { + } else if ($browserFamily === 'Safari') { $sameSite = ''; } } diff --git a/core/Exception/InvalidRequestParameterException.php b/core/Exception/InvalidRequestParameterException.php index 940651f02b..73ff9456e8 100644 --- a/core/Exception/InvalidRequestParameterException.php +++ b/core/Exception/InvalidRequestParameterException.php @@ -10,4 +10,9 @@ namespace Piwik\Exception; class InvalidRequestParameterException extends Exception { + + public function __toString() + { + return $this->getMessage() . ' ' . $this->getFile() . ':' . $this->getLine(); + } } diff --git a/core/Plugin/Visualization.php b/core/Plugin/Visualization.php index 0827f46449..53c0254382 100644 --- a/core/Plugin/Visualization.php +++ b/core/Plugin/Visualization.php @@ -332,9 +332,12 @@ class Visualization extends ViewDataTable PluginManager::getInstance()->checkIsPluginActivated($module); - $proxyRequestParams = array_merge($request, [ - 'disable_root_datatable_post_processor' => 1, - ]); + $proxyRequestParams = $request; + if ($this->isComparing()) { + $proxyRequestParams = array_merge($proxyRequestParams, [ + 'disable_root_datatable_post_processor' => 1, + ]); + } $class = ApiRequest::getClassNameAPI($module); $dataTable = Proxy::getInstance()->call($class, $method, $proxyRequestParams); diff --git a/core/Session.php b/core/Session.php index d7ee14beb4..bed2df45bc 100644 --- a/core/Session.php +++ b/core/Session.php @@ -175,7 +175,15 @@ class Session extends Zend_Session { $config = Config::getInstance(); $general = $config->General; - if (!empty($general['enable_framed_pages']) && ProxyHttp::isHttps()) { + + $module = Piwik::getModule(); + $action = Piwik::getAction(); + + $isOptOutRequest = $module == 'CoreAdminHome' && $action == 'optOut'; + $isOverlay = $module == 'Overlay'; + $shouldUseNone = !empty($general['enable_framed_pages']) || $isOptOutRequest || $isOverlay; + + if ($shouldUseNone && ProxyHttp::isHttps()) { return 'None'; } @@ -199,10 +207,10 @@ class Session extends Zend_Session { $headerStr = 'Set-Cookie: ' . rawurlencode($name) . '=' . rawurlencode($value); if ($expires) { - $headerStr .= '; expires=' . rawurlencode($expires); + $headerStr .= '; expires=' . $expires; } if ($path) { - $headerStr .= '; path=' . rawurlencode($path); + $headerStr .= '; path=' . $path; } if ($domain) { $headerStr .= '; domain=' . rawurlencode($domain); @@ -214,8 +222,10 @@ class Session extends Zend_Session $headerStr .= '; httponly'; } if ($sameSite) { - $headerStr .= '; SameSite=' . rawurlencode($sameSite); + $headerStr .= '; SameSite=' . $sameSite; } + + Common::sendHeader($headerStr); return $headerStr; } } diff --git a/core/Tracker/IgnoreCookie.php b/core/Tracker/IgnoreCookie.php index e67386d96c..fdda939ff5 100644 --- a/core/Tracker/IgnoreCookie.php +++ b/core/Tracker/IgnoreCookie.php @@ -10,6 +10,7 @@ namespace Piwik\Tracker; use Piwik\Config; use Piwik\Cookie; +use Piwik\ProxyHttp; /** * Tracking cookies. @@ -61,7 +62,12 @@ class IgnoreCookie $ignoreCookie->delete(); } else { $ignoreCookie->set('ignore', '*'); - $ignoreCookie->save('None'); + if (ProxyHttp::isHttps()) { + $ignoreCookie->setSecure(true); + $ignoreCookie->save('None'); + } else { + $ignoreCookie->save('Lax'); + } } self::deleteThirdPartyCookieUIDIfExists(); diff --git a/core/Tracker/Response.php b/core/Tracker/Response.php index d0ef9880a5..417323c6d7 100644 --- a/core/Tracker/Response.php +++ b/core/Tracker/Response.php @@ -89,7 +89,8 @@ class Response if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() - && TrackerDb::isProfilingEnabled()) { + && TrackerDb::isProfilingEnabled() + ) { $db = Tracker::getDatabase(); $db->recordProfiling(); Profiler::displayDbTrackerProfile($db); diff --git a/js/piwik.js b/js/piwik.js index 3031f4d01c..5fb12e6ef3 100644 --- a/js/piwik.js +++ b/js/piwik.js @@ -2366,7 +2366,8 @@ if (typeof window.Piwik !== 'object') { (msToExpire ? ';expires=' + expiryDate.toGMTString() : '') + ';path=' + (path || '/') + (domain ? ';domain=' + domain : '') + - (isSecure ? ';secure' : ''); + (isSecure ? ';secure' : '') + + ';SameSite=Lax'; } /* diff --git a/js/piwik.min.js b/js/piwik.min.js index f4fda77e08..1d4a64a4a0 100644 --- a/js/piwik.min.js +++ b/js/piwik.min.js @@ -29,7 +29,7 @@ if(T.innerHeight&&ao>T.innerHeight){ao=T.innerHeight}return((at.bottom>0||aq)&&a },getLocation:function(){var ao=this.location||T.location;if(!ao.origin){ao.origin=ao.protocol+"//"+ao.hostname+(ao.port?":"+ao.port:"")}return ao},toAbsoluteUrl:function(ap){if((!ap||String(ap)!==ap)&&ap!==""){return ap}if(""===ap){return this.getLocation().href}if(ap.search(/^\/\//)!==-1){return this.getLocation().protocol+ap}if(ap.search(/:\/\//)!==-1){return ap}if(0===ap.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+ap}if(0===ap.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+ap}if(0===ap.search("^[a-zA-Z]{2,11}:")){return ap}if(ap.search(/^\//)!==-1){return this.getLocation().origin+ap}var ao="(.*/)";var aq=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(ao))[0];return aq+ap},isUrlToCurrentDomain:function(ap){var aq=this.toAbsoluteUrl(ap);if(!aq){return false}var ao=this.getLocation().origin;if(ao===aq){return true}if(0===String(aq).indexOf(ao)){if(":"===String(aq).substr(ao.length,1)){return false}return true }return false},setHrefAttribute:function(ap,ao){if(!ap||!ao){return}ae.setAnyAttribute(ap,"href",ao)},shouldIgnoreInteraction:function(aq){var ap=ae.hasNodeAttribute(aq,this.CONTENT_IGNOREINTERACTION_ATTR);var ao=ae.hasNodeCssClass(aq,this.CONTENT_IGNOREINTERACTION_CLASS);return ap||ao}};function O(ap,at){if(at){return at}ap=v.toAbsoluteUrl(ap);if(z(ap,"?")){var ar=ap.indexOf("?");ap=ap.slice(0,ar)}if(R(ap,"matomo.php")){ap=g(ap,"matomo.php".length)}else{if(R(ap,"piwik.php")){ap=g(ap,"piwik.php".length)}else{if(R(ap,".php")){var ao=ap.lastIndexOf("/");var aq=1;ap=ap.slice(0,ao+aq)}}}if(R(ap,"/js/")){ap=g(ap,"js/".length)}return ap}function N(av){var ax="Piwik_Overlay";var ap=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=.*)?$");var aq=ap.exec(G.referrer);if(aq){var at=aq[1];if(at!==String(av)){return false}var au=aq[2],ao=aq[3],ar=aq[4];if(!ar){ar=""}else{if(ar.indexOf("&segment=")===0){ar=ar.substr("&segment=".length) }}T.name=ax+"###"+au+"###"+ao+"###"+ar}var aw=T.name.split("###");return aw.length===4&&aw[0]===ax}function Z(ap,aw,ar){var av=T.name.split("###"),au=av[1],ao=av[2],at=av[3],aq=O(ap,aw);o(aq+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(aq,ar,au,ao,at)})}function u(){var aq;try{aq=T.frameElement}catch(ap){return true}if(J(aq)){return(aq&&String(aq.nodeName).toLowerCase()==="iframe")?true:false}try{return T.self!==T.top}catch(ao){return true}}function Q(cb,b6){var bF=this,bc="mtm_consent",cH="mtm_consent_removed",b1=aa(G.domain,T.location.href,K()),cQ=L(b1[0]),bK=p(b1[1]),bl=p(b1[2]),cO=false,cf="GET",c6=cf,aH="application/x-www-form-urlencoded; charset=UTF-8",cu=aH,aD=cb||"",bE="",cV="",b3=b6||"",bw="",bL="",a3,bh="",c2=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],ax=[cQ],bx=[],bI=[],a7=[],bG=500,cS=true,cE,a4,bO,c3=1800,bM,ao,co=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],bD=["pk_kwd","piwik_kwd","utm_term"],bi="_pk_",av="pk_vid",aY=180,cT,bn,bP=false,bj=false,cL,bd,bt,cF=33955200000,cm=1800000,c1=15768000000,a1=true,ck=0,bN=false,aP=false,b8,bT={},cj={},bk={},br=200,cW={},c4={},b7=[],cc=false,cy=false,ap=false,c5=false,cI=false,aM=false,bb=u(),cN=null,cU=null,b9,aQ,by,b4=am,bm,aK,cp=0,bs=["id","ses","cvar","ref"],cx=false,bz=null,cG=[],aw=U++; -try{bh=G.title}catch(cv){bh=""}function da(dl,dj,di,dk,dh,dg){if(bj){return}var df;if(di){df=new Date();df.setTime(df.getTime()+di)}G.cookie=dl+"="+t(dj)+(di?";expires="+df.toGMTString():"")+";path="+(dk||"/")+(dh?";domain="+dh:"")+(dg?";secure":"")}function aC(dh){if(bj){return 0}var df=new RegExp("(^|;)[ ]*"+dh+"=([^;]*)"),dg=df.exec(G.cookie);return dg?S(dg[2]):0}bz=!aC(cH);function bZ(df){var dg;df=k(df,av);if(bM){dg=new RegExp("#.*");return df.replace(dg,"")}return df}function bS(dh,df){var di=s(df),dg;if(di){return df}if(df.slice(0,1)==="/"){return s(dh)+"://"+d(dh)+df}dh=bZ(dh);dg=dh.indexOf("?");if(dg>=0){dh=dh.slice(0,dg)}dg=dh.lastIndexOf("/");if(dg!==dh.length-1){dh=dh.slice(0,dg+1)}return dh+df}function cC(dh,df){var dg;dh=String(dh).toLowerCase();df=String(df).toLowerCase();if(dh===df){return true}if(df.slice(0,1)==="."){if(dh===df.slice(1)){return true}dg=dh.length-df.length;if((dg>0)&&(dh.slice(dg)===df)){return true}}return false}function ci(df){var dg=document.createElement("a"); +try{bh=G.title}catch(cv){bh=""}function da(dl,dj,di,dk,dh,dg){if(bj){return}var df;if(di){df=new Date();df.setTime(df.getTime()+di)}G.cookie=dl+"="+t(dj)+(di?";expires="+df.toGMTString():"")+";path="+(dk||"/")+(dh?";domain="+dh:"")+(dg?";secure":"")+";SameSite=Lax"}function aC(dh){if(bj){return 0}var df=new RegExp("(^|;)[ ]*"+dh+"=([^;]*)"),dg=df.exec(G.cookie);return dg?S(dg[2]):0}bz=!aC(cH);function bZ(df){var dg;df=k(df,av);if(bM){dg=new RegExp("#.*");return df.replace(dg,"")}return df}function bS(dh,df){var di=s(df),dg;if(di){return df}if(df.slice(0,1)==="/"){return s(dh)+"://"+d(dh)+df}dh=bZ(dh);dg=dh.indexOf("?");if(dg>=0){dh=dh.slice(0,dg)}dg=dh.lastIndexOf("/");if(dg!==dh.length-1){dh=dh.slice(0,dg+1)}return dh+df}function cC(dh,df){var dg;dh=String(dh).toLowerCase();df=String(df).toLowerCase();if(dh===df){return true}if(df.slice(0,1)==="."){if(dh===df.slice(1)){return true}dg=dh.length-df.length;if((dg>0)&&(dh.slice(dg)===df)){return true}}return false}function ci(df){var dg=document.createElement("a"); if(df.indexOf("//")!==0&&df.indexOf("http")!==0){if(df.indexOf("*")===0){df=df.substr(1)}if(df.indexOf(".")===0){df=df.substr(1)}df="http://"+df}dg.href=v.toAbsoluteUrl(df);if(dg.pathname){return dg.pathname}return""}function a2(dg,df){if(!aj(df,"/")){df="/"+df}if(!aj(dg,"/")){dg="/"+dg}var dh=(df==="/"||df==="/*");if(dh){return true}if(dg===df){return true}df=String(df).toLowerCase();dg=String(dg).toLowerCase();if(R(df,"*")){df=df.slice(0,-1);dh=(!df||df==="/");if(dh){return true}if(dg===df){return true}return dg.indexOf(df)===0}if(!R(dg,"/")){dg+="/"}if(!R(df,"/")){df+="/"}return dg.indexOf(df)===0}function ar(dj,dl){var dg,df,dh,di,dk;for(dg=0;dg<ax.length;dg++){di=L(ax[dg]);dk=ci(ax[dg]);if(cC(dj,di)&&a2(dl,dk)){return true}}return false}function aU(di){var dg,df,dh;for(dg=0;dg<ax.length;dg++){df=L(ax[dg].toLowerCase());if(di===df){return true}if(df.slice(0,1)==="."){if(di===df.slice(1)){return true}dh=di.length-df.length;if((dh>0)&&(di.slice(dh)===df)){return true}}}return false}function cn(df,dh){df=df.replace("send_image=0","send_image=1"); var dg=new Image(1,1);dg.onload=function(){E=0;if(typeof dh==="function"){dh({request:df,trackerUrl:aD,success:true})}};dg.onerror=function(){if(typeof dh==="function"){dh({request:df,trackerUrl:aD,success:false})}};dg.src=aD+(aD.indexOf("?")<0?"?":"&")+df}function aJ(){return"object"===typeof h&&"function"===typeof h.sendBeacon&&"function"===typeof Blob}function a5(di,dm){var dh=aJ();if(!dh){return false}var dl={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dk=false;var dg=aD;try{var df=new Blob([di],dl);if(di.length<=2000){df=new Blob([],dl);dg=dg+(dg.indexOf("?")<0?"?":"&")+di}dk=h.sendBeacon(dg,df)}catch(dj){return false}if(dk&&typeof dm==="function"){dm({request:di,trackerUrl:aD,success:true,isSendBeacon:true})}return dk}function c0(dg,dh,df){if(!J(df)||null===df){df=true}if(m&&a5(dg,dh)){return}setTimeout(function(){if(m&&a5(dg,dh)){return}var dk;try{var dj=T.XMLHttpRequest?new T.XMLHttpRequest():T.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dj.open("POST",aD,true); dj.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dl=m&&a5(dg,dh);if(!dl&&df){cn(dg,dh)}else{if(typeof dh==="function"){dh({request:dg,trackerUrl:aD,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dh==="function")){dh({request:dg,trackerUrl:aD,success:true,xhr:this})}}};dj.setRequestHeader("Content-Type",cu);dj.withCredentials=true;dj.send(dg)}catch(di){dk=m&&a5(dg,dh);if(!dk&&df){cn(dg,dh)}else{if(typeof dh==="function"){dh({request:dg,trackerUrl:aD,success:false})}}}},50)}function cd(dg){var df=new Date();var dh=df.getTime()+dg;if(!r||dh>r){r=dh}}function cl(df){if(b9||!a4||!bz){return}b9=setTimeout(function dg(){b9=null;if(!bb){bb=(!G.hasFocus||G.hasFocus())}if(!bb){cl(a4);return}if(bO()){return}var dh=new Date(),di=a4-(dh.getTime()-cU);di=Math.min(a4,di);cl(di)},df||a4)}function bH(){if(!b9){return}clearTimeout(b9);b9=null}function a9(){bb=true;cN=new Date().getTime()}function c9(){var df=new Date().getTime();return !cN||(df-cN)>a4 diff --git a/libs/HTML/QuickForm2/Element/Date.php b/libs/HTML/QuickForm2/Element/Date.php index b7e620691b..6a3dca2429 100644 --- a/libs/HTML/QuickForm2/Element/Date.php +++ b/libs/HTML/QuickForm2/Element/Date.php @@ -128,7 +128,7 @@ class HTML_QuickForm2_Element_Date extends HTML_QuickForm2_Container_Group $separator = ''; for ($i = 0, $length = strlen($this->data['format']); $i < $length; $i++) { - $sign = $this->data['format']{$i}; + $sign = $this->data['format'][$i]; if ($backslash) { $backslash = false; $separator .= $sign; diff --git a/libs/Zend/Session.php b/libs/Zend/Session.php index 3f21dcd9e6..21451e0ffa 100644 --- a/libs/Zend/Session.php +++ b/libs/Zend/Session.php @@ -523,6 +523,8 @@ class Zend_Session extends Zend_Session_Abstract self::$_sessionStarted = true; if (self::$_regenerateIdState === -1) { self::regenerateId(); + } else { + self::rewriteSessionCookieWithSameSiteDirective(); } if (isset($_SESSION['data']) && is_string($_SESSION['data'])) { diff --git a/libs/Zend/Validate/Isbn.php b/libs/Zend/Validate/Isbn.php index 980afc7f7a..2edf21d1dd 100644 --- a/libs/Zend/Validate/Isbn.php +++ b/libs/Zend/Validate/Isbn.php @@ -168,7 +168,7 @@ class Zend_Validate_Isbn extends Zend_Validate_Abstract $isbn10 = str_replace($this->_separator, '', $value); $sum = 0; for ($i = 0; $i < 9; $i++) { - $sum += (10 - $i) * $isbn10{$i}; + $sum += (10 - $i) * $isbn10[$i]; } // checksum @@ -186,9 +186,9 @@ class Zend_Validate_Isbn extends Zend_Validate_Abstract $sum = 0; for ($i = 0; $i < 12; $i++) { if ($i % 2 == 0) { - $sum += $isbn13{$i}; + $sum += $isbn13[$i]; } else { - $sum += 3 * $isbn13{$i}; + $sum += 3 * $isbn13[$i]; } } // checksum @@ -29,7 +29,7 @@ if(T.innerHeight&&ao>T.innerHeight){ao=T.innerHeight}return((at.bottom>0||aq)&&a },getLocation:function(){var ao=this.location||T.location;if(!ao.origin){ao.origin=ao.protocol+"//"+ao.hostname+(ao.port?":"+ao.port:"")}return ao},toAbsoluteUrl:function(ap){if((!ap||String(ap)!==ap)&&ap!==""){return ap}if(""===ap){return this.getLocation().href}if(ap.search(/^\/\//)!==-1){return this.getLocation().protocol+ap}if(ap.search(/:\/\//)!==-1){return ap}if(0===ap.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+ap}if(0===ap.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+ap}if(0===ap.search("^[a-zA-Z]{2,11}:")){return ap}if(ap.search(/^\//)!==-1){return this.getLocation().origin+ap}var ao="(.*/)";var aq=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(ao))[0];return aq+ap},isUrlToCurrentDomain:function(ap){var aq=this.toAbsoluteUrl(ap);if(!aq){return false}var ao=this.getLocation().origin;if(ao===aq){return true}if(0===String(aq).indexOf(ao)){if(":"===String(aq).substr(ao.length,1)){return false}return true }return false},setHrefAttribute:function(ap,ao){if(!ap||!ao){return}ae.setAnyAttribute(ap,"href",ao)},shouldIgnoreInteraction:function(aq){var ap=ae.hasNodeAttribute(aq,this.CONTENT_IGNOREINTERACTION_ATTR);var ao=ae.hasNodeCssClass(aq,this.CONTENT_IGNOREINTERACTION_CLASS);return ap||ao}};function O(ap,at){if(at){return at}ap=v.toAbsoluteUrl(ap);if(z(ap,"?")){var ar=ap.indexOf("?");ap=ap.slice(0,ar)}if(R(ap,"matomo.php")){ap=g(ap,"matomo.php".length)}else{if(R(ap,"piwik.php")){ap=g(ap,"piwik.php".length)}else{if(R(ap,".php")){var ao=ap.lastIndexOf("/");var aq=1;ap=ap.slice(0,ao+aq)}}}if(R(ap,"/js/")){ap=g(ap,"js/".length)}return ap}function N(av){var ax="Piwik_Overlay";var ap=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=.*)?$");var aq=ap.exec(G.referrer);if(aq){var at=aq[1];if(at!==String(av)){return false}var au=aq[2],ao=aq[3],ar=aq[4];if(!ar){ar=""}else{if(ar.indexOf("&segment=")===0){ar=ar.substr("&segment=".length) }}T.name=ax+"###"+au+"###"+ao+"###"+ar}var aw=T.name.split("###");return aw.length===4&&aw[0]===ax}function Z(ap,aw,ar){var av=T.name.split("###"),au=av[1],ao=av[2],at=av[3],aq=O(ap,aw);o(aq+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(aq,ar,au,ao,at)})}function u(){var aq;try{aq=T.frameElement}catch(ap){return true}if(J(aq)){return(aq&&String(aq.nodeName).toLowerCase()==="iframe")?true:false}try{return T.self!==T.top}catch(ao){return true}}function Q(cb,b6){var bF=this,bc="mtm_consent",cH="mtm_consent_removed",b1=aa(G.domain,T.location.href,K()),cQ=L(b1[0]),bK=p(b1[1]),bl=p(b1[2]),cO=false,cf="GET",c6=cf,aH="application/x-www-form-urlencoded; charset=UTF-8",cu=aH,aD=cb||"",bE="",cV="",b3=b6||"",bw="",bL="",a3,bh="",c2=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],ax=[cQ],bx=[],bI=[],a7=[],bG=500,cS=true,cE,a4,bO,c3=1800,bM,ao,co=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],bD=["pk_kwd","piwik_kwd","utm_term"],bi="_pk_",av="pk_vid",aY=180,cT,bn,bP=false,bj=false,cL,bd,bt,cF=33955200000,cm=1800000,c1=15768000000,a1=true,ck=0,bN=false,aP=false,b8,bT={},cj={},bk={},br=200,cW={},c4={},b7=[],cc=false,cy=false,ap=false,c5=false,cI=false,aM=false,bb=u(),cN=null,cU=null,b9,aQ,by,b4=am,bm,aK,cp=0,bs=["id","ses","cvar","ref"],cx=false,bz=null,cG=[],aw=U++; -try{bh=G.title}catch(cv){bh=""}function da(dl,dj,di,dk,dh,dg){if(bj){return}var df;if(di){df=new Date();df.setTime(df.getTime()+di)}G.cookie=dl+"="+t(dj)+(di?";expires="+df.toGMTString():"")+";path="+(dk||"/")+(dh?";domain="+dh:"")+(dg?";secure":"")}function aC(dh){if(bj){return 0}var df=new RegExp("(^|;)[ ]*"+dh+"=([^;]*)"),dg=df.exec(G.cookie);return dg?S(dg[2]):0}bz=!aC(cH);function bZ(df){var dg;df=k(df,av);if(bM){dg=new RegExp("#.*");return df.replace(dg,"")}return df}function bS(dh,df){var di=s(df),dg;if(di){return df}if(df.slice(0,1)==="/"){return s(dh)+"://"+d(dh)+df}dh=bZ(dh);dg=dh.indexOf("?");if(dg>=0){dh=dh.slice(0,dg)}dg=dh.lastIndexOf("/");if(dg!==dh.length-1){dh=dh.slice(0,dg+1)}return dh+df}function cC(dh,df){var dg;dh=String(dh).toLowerCase();df=String(df).toLowerCase();if(dh===df){return true}if(df.slice(0,1)==="."){if(dh===df.slice(1)){return true}dg=dh.length-df.length;if((dg>0)&&(dh.slice(dg)===df)){return true}}return false}function ci(df){var dg=document.createElement("a"); +try{bh=G.title}catch(cv){bh=""}function da(dl,dj,di,dk,dh,dg){if(bj){return}var df;if(di){df=new Date();df.setTime(df.getTime()+di)}G.cookie=dl+"="+t(dj)+(di?";expires="+df.toGMTString():"")+";path="+(dk||"/")+(dh?";domain="+dh:"")+(dg?";secure":"")+";SameSite=Lax"}function aC(dh){if(bj){return 0}var df=new RegExp("(^|;)[ ]*"+dh+"=([^;]*)"),dg=df.exec(G.cookie);return dg?S(dg[2]):0}bz=!aC(cH);function bZ(df){var dg;df=k(df,av);if(bM){dg=new RegExp("#.*");return df.replace(dg,"")}return df}function bS(dh,df){var di=s(df),dg;if(di){return df}if(df.slice(0,1)==="/"){return s(dh)+"://"+d(dh)+df}dh=bZ(dh);dg=dh.indexOf("?");if(dg>=0){dh=dh.slice(0,dg)}dg=dh.lastIndexOf("/");if(dg!==dh.length-1){dh=dh.slice(0,dg+1)}return dh+df}function cC(dh,df){var dg;dh=String(dh).toLowerCase();df=String(df).toLowerCase();if(dh===df){return true}if(df.slice(0,1)==="."){if(dh===df.slice(1)){return true}dg=dh.length-df.length;if((dg>0)&&(dh.slice(dg)===df)){return true}}return false}function ci(df){var dg=document.createElement("a"); if(df.indexOf("//")!==0&&df.indexOf("http")!==0){if(df.indexOf("*")===0){df=df.substr(1)}if(df.indexOf(".")===0){df=df.substr(1)}df="http://"+df}dg.href=v.toAbsoluteUrl(df);if(dg.pathname){return dg.pathname}return""}function a2(dg,df){if(!aj(df,"/")){df="/"+df}if(!aj(dg,"/")){dg="/"+dg}var dh=(df==="/"||df==="/*");if(dh){return true}if(dg===df){return true}df=String(df).toLowerCase();dg=String(dg).toLowerCase();if(R(df,"*")){df=df.slice(0,-1);dh=(!df||df==="/");if(dh){return true}if(dg===df){return true}return dg.indexOf(df)===0}if(!R(dg,"/")){dg+="/"}if(!R(df,"/")){df+="/"}return dg.indexOf(df)===0}function ar(dj,dl){var dg,df,dh,di,dk;for(dg=0;dg<ax.length;dg++){di=L(ax[dg]);dk=ci(ax[dg]);if(cC(dj,di)&&a2(dl,dk)){return true}}return false}function aU(di){var dg,df,dh;for(dg=0;dg<ax.length;dg++){df=L(ax[dg].toLowerCase());if(di===df){return true}if(df.slice(0,1)==="."){if(di===df.slice(1)){return true}dh=di.length-df.length;if((dh>0)&&(di.slice(dh)===df)){return true}}}return false}function cn(df,dh){df=df.replace("send_image=0","send_image=1"); var dg=new Image(1,1);dg.onload=function(){E=0;if(typeof dh==="function"){dh({request:df,trackerUrl:aD,success:true})}};dg.onerror=function(){if(typeof dh==="function"){dh({request:df,trackerUrl:aD,success:false})}};dg.src=aD+(aD.indexOf("?")<0?"?":"&")+df}function aJ(){return"object"===typeof h&&"function"===typeof h.sendBeacon&&"function"===typeof Blob}function a5(di,dm){var dh=aJ();if(!dh){return false}var dl={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dk=false;var dg=aD;try{var df=new Blob([di],dl);if(di.length<=2000){df=new Blob([],dl);dg=dg+(dg.indexOf("?")<0?"?":"&")+di}dk=h.sendBeacon(dg,df)}catch(dj){return false}if(dk&&typeof dm==="function"){dm({request:di,trackerUrl:aD,success:true,isSendBeacon:true})}return dk}function c0(dg,dh,df){if(!J(df)||null===df){df=true}if(m&&a5(dg,dh)){return}setTimeout(function(){if(m&&a5(dg,dh)){return}var dk;try{var dj=T.XMLHttpRequest?new T.XMLHttpRequest():T.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dj.open("POST",aD,true); dj.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dl=m&&a5(dg,dh);if(!dl&&df){cn(dg,dh)}else{if(typeof dh==="function"){dh({request:dg,trackerUrl:aD,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dh==="function")){dh({request:dg,trackerUrl:aD,success:true,xhr:this})}}};dj.setRequestHeader("Content-Type",cu);dj.withCredentials=true;dj.send(dg)}catch(di){dk=m&&a5(dg,dh);if(!dk&&df){cn(dg,dh)}else{if(typeof dh==="function"){dh({request:dg,trackerUrl:aD,success:false})}}}},50)}function cd(dg){var df=new Date();var dh=df.getTime()+dg;if(!r||dh>r){r=dh}}function cl(df){if(b9||!a4||!bz){return}b9=setTimeout(function dg(){b9=null;if(!bb){bb=(!G.hasFocus||G.hasFocus())}if(!bb){cl(a4);return}if(bO()){return}var dh=new Date(),di=a4-(dh.getTime()-cU);di=Math.min(a4,di);cl(di)},df||a4)}function bH(){if(!b9){return}clearTimeout(b9);b9=null}function a9(){bb=true;cN=new Date().getTime()}function c9(){var df=new Date().getTime();return !cN||(df-cN)>a4 @@ -29,7 +29,7 @@ if(T.innerHeight&&ao>T.innerHeight){ao=T.innerHeight}return((at.bottom>0||aq)&&a },getLocation:function(){var ao=this.location||T.location;if(!ao.origin){ao.origin=ao.protocol+"//"+ao.hostname+(ao.port?":"+ao.port:"")}return ao},toAbsoluteUrl:function(ap){if((!ap||String(ap)!==ap)&&ap!==""){return ap}if(""===ap){return this.getLocation().href}if(ap.search(/^\/\//)!==-1){return this.getLocation().protocol+ap}if(ap.search(/:\/\//)!==-1){return ap}if(0===ap.indexOf("#")){return this.getLocation().origin+this.getLocation().pathname+ap}if(0===ap.indexOf("?")){return this.getLocation().origin+this.getLocation().pathname+ap}if(0===ap.search("^[a-zA-Z]{2,11}:")){return ap}if(ap.search(/^\//)!==-1){return this.getLocation().origin+ap}var ao="(.*/)";var aq=this.getLocation().origin+this.getLocation().pathname.match(new RegExp(ao))[0];return aq+ap},isUrlToCurrentDomain:function(ap){var aq=this.toAbsoluteUrl(ap);if(!aq){return false}var ao=this.getLocation().origin;if(ao===aq){return true}if(0===String(aq).indexOf(ao)){if(":"===String(aq).substr(ao.length,1)){return false}return true }return false},setHrefAttribute:function(ap,ao){if(!ap||!ao){return}ae.setAnyAttribute(ap,"href",ao)},shouldIgnoreInteraction:function(aq){var ap=ae.hasNodeAttribute(aq,this.CONTENT_IGNOREINTERACTION_ATTR);var ao=ae.hasNodeCssClass(aq,this.CONTENT_IGNOREINTERACTION_CLASS);return ap||ao}};function O(ap,at){if(at){return at}ap=v.toAbsoluteUrl(ap);if(z(ap,"?")){var ar=ap.indexOf("?");ap=ap.slice(0,ar)}if(R(ap,"matomo.php")){ap=g(ap,"matomo.php".length)}else{if(R(ap,"piwik.php")){ap=g(ap,"piwik.php".length)}else{if(R(ap,".php")){var ao=ap.lastIndexOf("/");var aq=1;ap=ap.slice(0,ao+aq)}}}if(R(ap,"/js/")){ap=g(ap,"js/".length)}return ap}function N(av){var ax="Piwik_Overlay";var ap=new RegExp("index\\.php\\?module=Overlay&action=startOverlaySession&idSite=([0-9]+)&period=([^&]+)&date=([^&]+)(&segment=.*)?$");var aq=ap.exec(G.referrer);if(aq){var at=aq[1];if(at!==String(av)){return false}var au=aq[2],ao=aq[3],ar=aq[4];if(!ar){ar=""}else{if(ar.indexOf("&segment=")===0){ar=ar.substr("&segment=".length) }}T.name=ax+"###"+au+"###"+ao+"###"+ar}var aw=T.name.split("###");return aw.length===4&&aw[0]===ax}function Z(ap,aw,ar){var av=T.name.split("###"),au=av[1],ao=av[2],at=av[3],aq=O(ap,aw);o(aq+"plugins/Overlay/client/client.js?v=1",function(){Piwik_Overlay_Client.initialize(aq,ar,au,ao,at)})}function u(){var aq;try{aq=T.frameElement}catch(ap){return true}if(J(aq)){return(aq&&String(aq.nodeName).toLowerCase()==="iframe")?true:false}try{return T.self!==T.top}catch(ao){return true}}function Q(cb,b6){var bF=this,bc="mtm_consent",cH="mtm_consent_removed",b1=aa(G.domain,T.location.href,K()),cQ=L(b1[0]),bK=p(b1[1]),bl=p(b1[2]),cO=false,cf="GET",c6=cf,aH="application/x-www-form-urlencoded; charset=UTF-8",cu=aH,aD=cb||"",bE="",cV="",b3=b6||"",bw="",bL="",a3,bh="",c2=["7z","aac","apk","arc","arj","asf","asx","avi","azw3","bin","csv","deb","dmg","doc","docx","epub","exe","flv","gif","gz","gzip","hqx","ibooks","jar","jpg","jpeg","js","mobi","mp2","mp3","mp4","mpg","mpeg","mov","movie","msi","msp","odb","odf","odg","ods","odt","ogg","ogv","pdf","phps","png","ppt","pptx","qt","qtm","ra","ram","rar","rpm","sea","sit","tar","tbz","tbz2","bz","bz2","tgz","torrent","txt","wav","wma","wmv","wpd","xls","xlsx","xml","z","zip"],ax=[cQ],bx=[],bI=[],a7=[],bG=500,cS=true,cE,a4,bO,c3=1800,bM,ao,co=["pk_campaign","piwik_campaign","utm_campaign","utm_source","utm_medium"],bD=["pk_kwd","piwik_kwd","utm_term"],bi="_pk_",av="pk_vid",aY=180,cT,bn,bP=false,bj=false,cL,bd,bt,cF=33955200000,cm=1800000,c1=15768000000,a1=true,ck=0,bN=false,aP=false,b8,bT={},cj={},bk={},br=200,cW={},c4={},b7=[],cc=false,cy=false,ap=false,c5=false,cI=false,aM=false,bb=u(),cN=null,cU=null,b9,aQ,by,b4=am,bm,aK,cp=0,bs=["id","ses","cvar","ref"],cx=false,bz=null,cG=[],aw=U++; -try{bh=G.title}catch(cv){bh=""}function da(dl,dj,di,dk,dh,dg){if(bj){return}var df;if(di){df=new Date();df.setTime(df.getTime()+di)}G.cookie=dl+"="+t(dj)+(di?";expires="+df.toGMTString():"")+";path="+(dk||"/")+(dh?";domain="+dh:"")+(dg?";secure":"")}function aC(dh){if(bj){return 0}var df=new RegExp("(^|;)[ ]*"+dh+"=([^;]*)"),dg=df.exec(G.cookie);return dg?S(dg[2]):0}bz=!aC(cH);function bZ(df){var dg;df=k(df,av);if(bM){dg=new RegExp("#.*");return df.replace(dg,"")}return df}function bS(dh,df){var di=s(df),dg;if(di){return df}if(df.slice(0,1)==="/"){return s(dh)+"://"+d(dh)+df}dh=bZ(dh);dg=dh.indexOf("?");if(dg>=0){dh=dh.slice(0,dg)}dg=dh.lastIndexOf("/");if(dg!==dh.length-1){dh=dh.slice(0,dg+1)}return dh+df}function cC(dh,df){var dg;dh=String(dh).toLowerCase();df=String(df).toLowerCase();if(dh===df){return true}if(df.slice(0,1)==="."){if(dh===df.slice(1)){return true}dg=dh.length-df.length;if((dg>0)&&(dh.slice(dg)===df)){return true}}return false}function ci(df){var dg=document.createElement("a"); +try{bh=G.title}catch(cv){bh=""}function da(dl,dj,di,dk,dh,dg){if(bj){return}var df;if(di){df=new Date();df.setTime(df.getTime()+di)}G.cookie=dl+"="+t(dj)+(di?";expires="+df.toGMTString():"")+";path="+(dk||"/")+(dh?";domain="+dh:"")+(dg?";secure":"")+";SameSite=Lax"}function aC(dh){if(bj){return 0}var df=new RegExp("(^|;)[ ]*"+dh+"=([^;]*)"),dg=df.exec(G.cookie);return dg?S(dg[2]):0}bz=!aC(cH);function bZ(df){var dg;df=k(df,av);if(bM){dg=new RegExp("#.*");return df.replace(dg,"")}return df}function bS(dh,df){var di=s(df),dg;if(di){return df}if(df.slice(0,1)==="/"){return s(dh)+"://"+d(dh)+df}dh=bZ(dh);dg=dh.indexOf("?");if(dg>=0){dh=dh.slice(0,dg)}dg=dh.lastIndexOf("/");if(dg!==dh.length-1){dh=dh.slice(0,dg+1)}return dh+df}function cC(dh,df){var dg;dh=String(dh).toLowerCase();df=String(df).toLowerCase();if(dh===df){return true}if(df.slice(0,1)==="."){if(dh===df.slice(1)){return true}dg=dh.length-df.length;if((dg>0)&&(dh.slice(dg)===df)){return true}}return false}function ci(df){var dg=document.createElement("a"); if(df.indexOf("//")!==0&&df.indexOf("http")!==0){if(df.indexOf("*")===0){df=df.substr(1)}if(df.indexOf(".")===0){df=df.substr(1)}df="http://"+df}dg.href=v.toAbsoluteUrl(df);if(dg.pathname){return dg.pathname}return""}function a2(dg,df){if(!aj(df,"/")){df="/"+df}if(!aj(dg,"/")){dg="/"+dg}var dh=(df==="/"||df==="/*");if(dh){return true}if(dg===df){return true}df=String(df).toLowerCase();dg=String(dg).toLowerCase();if(R(df,"*")){df=df.slice(0,-1);dh=(!df||df==="/");if(dh){return true}if(dg===df){return true}return dg.indexOf(df)===0}if(!R(dg,"/")){dg+="/"}if(!R(df,"/")){df+="/"}return dg.indexOf(df)===0}function ar(dj,dl){var dg,df,dh,di,dk;for(dg=0;dg<ax.length;dg++){di=L(ax[dg]);dk=ci(ax[dg]);if(cC(dj,di)&&a2(dl,dk)){return true}}return false}function aU(di){var dg,df,dh;for(dg=0;dg<ax.length;dg++){df=L(ax[dg].toLowerCase());if(di===df){return true}if(df.slice(0,1)==="."){if(di===df.slice(1)){return true}dh=di.length-df.length;if((dh>0)&&(di.slice(dh)===df)){return true}}}return false}function cn(df,dh){df=df.replace("send_image=0","send_image=1"); var dg=new Image(1,1);dg.onload=function(){E=0;if(typeof dh==="function"){dh({request:df,trackerUrl:aD,success:true})}};dg.onerror=function(){if(typeof dh==="function"){dh({request:df,trackerUrl:aD,success:false})}};dg.src=aD+(aD.indexOf("?")<0?"?":"&")+df}function aJ(){return"object"===typeof h&&"function"===typeof h.sendBeacon&&"function"===typeof Blob}function a5(di,dm){var dh=aJ();if(!dh){return false}var dl={type:"application/x-www-form-urlencoded; charset=UTF-8"};var dk=false;var dg=aD;try{var df=new Blob([di],dl);if(di.length<=2000){df=new Blob([],dl);dg=dg+(dg.indexOf("?")<0?"?":"&")+di}dk=h.sendBeacon(dg,df)}catch(dj){return false}if(dk&&typeof dm==="function"){dm({request:di,trackerUrl:aD,success:true,isSendBeacon:true})}return dk}function c0(dg,dh,df){if(!J(df)||null===df){df=true}if(m&&a5(dg,dh)){return}setTimeout(function(){if(m&&a5(dg,dh)){return}var dk;try{var dj=T.XMLHttpRequest?new T.XMLHttpRequest():T.ActiveXObject?new ActiveXObject("Microsoft.XMLHTTP"):null;dj.open("POST",aD,true); dj.onreadystatechange=function(){if(this.readyState===4&&!(this.status>=200&&this.status<300)){var dl=m&&a5(dg,dh);if(!dl&&df){cn(dg,dh)}else{if(typeof dh==="function"){dh({request:dg,trackerUrl:aD,success:false,xhr:this})}}}else{if(this.readyState===4&&(typeof dh==="function")){dh({request:dg,trackerUrl:aD,success:true,xhr:this})}}};dj.setRequestHeader("Content-Type",cu);dj.withCredentials=true;dj.send(dg)}catch(di){dk=m&&a5(dg,dh);if(!dk&&df){cn(dg,dh)}else{if(typeof dh==="function"){dh({request:dg,trackerUrl:aD,success:false})}}}},50)}function cd(dg){var df=new Date();var dh=df.getTime()+dg;if(!r||dh>r){r=dh}}function cl(df){if(b9||!a4||!bz){return}b9=setTimeout(function dg(){b9=null;if(!bb){bb=(!G.hasFocus||G.hasFocus())}if(!bb){cl(a4);return}if(bO()){return}var dh=new Date(),di=a4-(dh.getTime()-cU);di=Math.min(a4,di);cl(di)},df||a4)}function bH(){if(!b9){return}clearTimeout(b9);b9=null}function a9(){bb=true;cN=new Date().getTime()}function c9(){var df=new Date().getTime();return !cN||(df-cN)>a4 diff --git a/plugins/CoreVisualizations/Visualizations/HtmlTable.php b/plugins/CoreVisualizations/Visualizations/HtmlTable.php index 42c0798fbf..ba3bb6b98a 100644 --- a/plugins/CoreVisualizations/Visualizations/HtmlTable.php +++ b/plugins/CoreVisualizations/Visualizations/HtmlTable.php @@ -235,9 +235,11 @@ class HtmlTable extends Visualization $reportTotal = isset($totals[$column]) ? $totals[$column] : 0; - $percentageColumnName = $column . '_row_percentage'; - $rowPercentage = $formatter->formatPercent(Piwik::getPercentageSafe($value, $reportTotal, $precision = 1), $precision); - $row->setMetadata($percentageColumnName, $rowPercentage); + if (is_numeric($value)) { + $percentageColumnName = $column . '_row_percentage'; + $rowPercentage = $formatter->formatPercent(Piwik::getPercentageSafe($value, $reportTotal, $precision = 1), $precision); + $row->setMetadata($percentageColumnName, $rowPercentage); + } if ($siteTotalRow) { $siteTotal = $siteTotalRow->getColumn($column) ?: 0; diff --git a/plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php b/plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php index e062a73516..b35f89364b 100644 --- a/plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php +++ b/plugins/CustomJsTracker/TrackingCode/PluginTrackerFiles.php @@ -17,11 +17,6 @@ class PluginTrackerFiles const MIN_TRACKER_FILE = 'tracker.min.js'; /** - * @var string - */ - protected $dir; - - /** * @var Plugin\Manager */ private $pluginManager; @@ -33,7 +28,6 @@ class PluginTrackerFiles public function __construct() { - $this->dir = PIWIK_DOCUMENT_ROOT . '/plugins/'; $this->pluginManager = Plugin\Manager::getInstance(); } @@ -42,6 +36,18 @@ class PluginTrackerFiles $this->ignoreMinified = true; } + protected function getDirectoriesToLook() + { + $dirs = array(); + $manager = Plugin\Manager::getInstance(); + foreach ($manager->getPluginsLoadedAndActivated() as $pluginName => $plugin) { + if ($plugin->isTrackerPlugin()) { + $dirs[$pluginName] = rtrim(Plugin\Manager::getPluginDirectory($pluginName), '/') . '/'; + } + } + return $dirs; + } + /** * @return File[] */ @@ -49,25 +55,11 @@ class PluginTrackerFiles { $jsFiles = array(); - if (!$this->ignoreMinified) { - $trackerFiles = \_glob($this->dir . '*/' . self::MIN_TRACKER_FILE); - - foreach ($trackerFiles as $trackerFile) { - $plugin = $this->getPluginNameFromFile($trackerFile); - if ($this->isPluginActivated($plugin)) { - $jsFiles[$plugin] = new File($trackerFile); - } - } - } - - $trackerFiles = \_glob($this->dir . '*/' . self::TRACKER_FILE); - - foreach ($trackerFiles as $trackerFile) { - $plugin = $this->getPluginNameFromFile($trackerFile); - if (!isset($jsFiles[$plugin])) { - if ($this->isPluginActivated($plugin)) { - $jsFiles[$plugin] = new File($trackerFile); - } + foreach ($this->getDirectoriesToLook() as $pluginName => $pluginDir) { + if (!$this->ignoreMinified && file_exists($pluginDir . self::MIN_TRACKER_FILE)) { + $jsFiles[$pluginName] = new File($pluginDir . self::MIN_TRACKER_FILE); + } elseif (file_exists($pluginDir . self::TRACKER_FILE)) { + $jsFiles[$pluginName] = new File($pluginDir . self::TRACKER_FILE); } } @@ -101,10 +93,4 @@ class PluginTrackerFiles { return $this->pluginManager->isPluginActivated($pluginName); } - - protected function getPluginNameFromFile($file) - { - $file = str_replace(array($this->dir, self::TRACKER_FILE, self::MIN_TRACKER_FILE), '', $file); - return trim($file, '/'); - } } diff --git a/plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php b/plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php index b063fbab28..7dab1b6032 100644 --- a/plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php +++ b/plugins/CustomJsTracker/tests/Integration/PluginTrackerFilesTest.php @@ -14,33 +14,12 @@ use Piwik\Tests\Framework\TestCase\IntegrationTestCase; class CustomPluginTrackerFiles extends PluginTrackerFiles { - private $pluginNamesForFile = array(); - public function __construct($pluginNameForRegularTrackerFile = 'CustomJsTracker', $pluginNameForMinifiedTracker = 'CustomJsTracker') - { - parent::__construct(); - - $this->dir = PIWIK_DOCUMENT_ROOT . '/plugins/CustomJsTracker/tests/'; - - $this->pluginNamesForFile = array( - 'tracker.js' => $pluginNameForRegularTrackerFile, - 'tracker.min.js' => $pluginNameForMinifiedTracker + protected function getDirectoriesToLook() { + return array( + 'CustomJsTracker' => PIWIK_DOCUMENT_ROOT . '/plugins/CustomJsTracker/tests/resources/' ); } - - protected function getPluginNameFromFile($file) - { - $fileName = basename($file); - return $this->pluginNamesForFile[$fileName]; - } -} - -class CustomPluginTrackerFiles2 extends PluginTrackerFiles { - - public function getPluginNameFromFile($file) - { - return parent::getPluginNameFromFile($file); - } } /** @@ -72,72 +51,20 @@ class PluginTrackerFilesTest extends IntegrationTestCase $this->assertEquals('tracker.js', $foundFiles['CustomJsTracker']->getName()); } - public function test_find_ifMultiplePluginsImplementATracker_ShouldReturnEachOfThem() - { - $trackerFiles = new CustomPluginTrackerFiles('CustomJsTracker', 'Goals'); - $foundFiles = $trackerFiles->find(); - - $this->assertCount(2, $foundFiles); - $this->assertTrue(isset($foundFiles['CustomJsTracker'])); - $this->assertTrue(isset($foundFiles['Goals'])); - $this->assertEquals('tracker.js', $foundFiles['CustomJsTracker']->getName()); - $this->assertEquals('tracker.min.js', $foundFiles['Goals']->getName()); - } - public function test_find_EventsCanIgnoreFiles() { - $trackerFiles = new CustomPluginTrackerFiles('CustomJsTracker', 'Goals'); + $trackerFiles = new CustomPluginTrackerFiles(); $foundFiles = $trackerFiles->find(); - $this->assertCount(2, $foundFiles); + $this->assertCount(1, $foundFiles); Piwik::addAction('CustomJsTracker.shouldAddTrackerFile', function (&$shouldAdd, $pluginName) { - if ($pluginName === 'Goals') { + if ($pluginName === 'CustomJsTracker') { $shouldAdd = false; } }); $foundFiles = $trackerFiles->find(); - $this->assertCount(1, $foundFiles); - $this->assertTrue(isset($foundFiles['CustomJsTracker'])); - $this->assertFalse(isset($foundFiles['Goals'])); - } - - public function test_find_shouldNotReturnATrackerFile_IfPluginIsNotActivatedOrLoaded() - { - $trackerFiles = new CustomPluginTrackerFiles('MyNotExistingPlugin', 'Goals'); - $foundFiles = $trackerFiles->find(); - - $this->assertCount(1, $foundFiles); - $this->assertTrue(isset($foundFiles['Goals'])); - $this->assertEquals('tracker.min.js', $foundFiles['Goals']->getName()); - - $trackerFiles = new CustomPluginTrackerFiles('Goals', 'MyNotExistingPlugin'); - $foundFiles = $trackerFiles->find(); - - $this->assertCount(1, $foundFiles); - $this->assertTrue(isset($foundFiles['Goals'])); - $this->assertEquals('tracker.js', $foundFiles['Goals']->getName()); - } - - public function test_find_shouldNotReturnFileIfNoPluginActivated() - { - $trackerFiles = new CustomPluginTrackerFiles('MyNotExistingPlugin', 'MyNotExistingPlugin2'); - $foundFiles = $trackerFiles->find(); - - $this->assertSame(array(), $foundFiles); - } - - public function test_getPluginNameFromFile_shouldDetectPluginName() - { - $trackerFiles = new CustomPluginTrackerFiles2(); - $pluginName = $trackerFiles->getPluginNameFromFile(PIWIK_DOCUMENT_ROOT . '/plugins/MyFooBarPlugin/tracker.js'); - $this->assertSame('MyFooBarPlugin', $pluginName); - - $pluginName = $trackerFiles->getPluginNameFromFile(PIWIK_DOCUMENT_ROOT . '/plugins//MyFooBarPlugin//tracker.js'); - $this->assertSame('MyFooBarPlugin', $pluginName); - - $pluginName = $trackerFiles->getPluginNameFromFile(PIWIK_DOCUMENT_ROOT . '/plugins//MyFooBarPlugin//tracker.min.js'); - $this->assertSame('MyFooBarPlugin', $pluginName); + $this->assertCount(0, $foundFiles); } } diff --git a/plugins/ExampleTracker/Columns/ExampleVisitDimension.php b/plugins/ExampleTracker/Columns/ExampleVisitDimension.php index f153e4faca..be294660d5 100644 --- a/plugins/ExampleTracker/Columns/ExampleVisitDimension.php +++ b/plugins/ExampleTracker/Columns/ExampleVisitDimension.php @@ -8,6 +8,7 @@ */ namespace Piwik\Plugins\ExampleTracker\Columns; +use Piwik\Common; use Piwik\Piwik; use Piwik\Plugin\Dimension\VisitDimension; use Piwik\Plugin\Segment; @@ -76,6 +77,11 @@ class ExampleVisitDimension extends VisitDimension */ public function onNewVisit(Request $request, Visitor $visitor, $action) { + $paramValue = Common::getRequestVar('myCustomVisitParam', '', 'string', $request->getParams()); + if (!empty($paramValue)) { + return $paramValue; + } + if (empty($action)) { return 0; } @@ -100,6 +106,11 @@ class ExampleVisitDimension extends VisitDimension */ public function onExistingVisit(Request $request, Visitor $visitor, $action) { + $paramValue = Common::getRequestVar('myCustomVisitParam', '', 'string', $request->getParams()); + if (!empty($paramValue)) { + return $paramValue; + } + if (empty($action)) { return false; // Do not change an already persisted value } diff --git a/plugins/ExampleTracker/ExampleTracker.php b/plugins/ExampleTracker/ExampleTracker.php index 22af517aaa..1eb40ce15d 100644 --- a/plugins/ExampleTracker/ExampleTracker.php +++ b/plugins/ExampleTracker/ExampleTracker.php @@ -8,6 +8,25 @@ */ namespace Piwik\Plugins\ExampleTracker; +use Piwik\Common; +use Piwik\Plugins\Live\Visitor; + class ExampleTracker extends \Piwik\Plugin { + public function getListHooksRegistered() + { + return [ + 'Live.getAllVisitorDetails' => 'getAllVisitorDetails', + ]; + } + + public function isTrackerPlugin() + { + return true; + } + + public function getAllVisitorDetails(&$visitor, $visitorRawData) + { + $visitor['myCustomVisitParam'] = isset($visitorRawData['example_visit_dimension']) ? $visitorRawData['example_visit_dimension'] : 'no-value'; + } } diff --git a/plugins/ExampleTracker/VisitorDetails.php b/plugins/ExampleTracker/VisitorDetails.php new file mode 100644 index 0000000000..530fbf0287 --- /dev/null +++ b/plugins/ExampleTracker/VisitorDetails.php @@ -0,0 +1,27 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ + +namespace Piwik\Plugins\ExampleTracker; + +use Piwik\Plugins\Live\VisitorDetailsAbstract; +use Piwik\View; + +class VisitorDetails extends VisitorDetailsAbstract +{ + public function renderIcons($visitorDetails) + { + if (empty($visitorDetails['myCustomVisitParam'])) { + return ''; + } + + $view = new View('@ExampleTracker/_visitorLogIcons'); + $view->myCustomVisitParam = $visitorDetails['myCustomVisitParam']; + return $view->render(); + } +}
\ No newline at end of file diff --git a/plugins/ExampleTracker/templates/_visitorLogIcons.twig b/plugins/ExampleTracker/templates/_visitorLogIcons.twig new file mode 100644 index 0000000000..c582382f9a --- /dev/null +++ b/plugins/ExampleTracker/templates/_visitorLogIcons.twig @@ -0,0 +1 @@ +<span>{{ myCustomVisitParam }}</span>
\ No newline at end of file diff --git a/plugins/ExampleTracker/tracker.js b/plugins/ExampleTracker/tracker.js new file mode 100644 index 0000000000..0383efc9e1 --- /dev/null +++ b/plugins/ExampleTracker/tracker.js @@ -0,0 +1,50 @@ +/** + * Piwik - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ + +(function () { + + var configs = {}; + + function init() { + if ('object' === typeof window && 'object' === typeof window.Piwik && 'object' === typeof window.Piwik.ExampleTracker) { + // do not initialize twice + return; + } + + if ('object' === typeof window && !window.Piwik) { + // piwik is not defined yet + return; + } + + Piwik.ExampleTracker = { + // empty + }; + + Piwik.addPlugin('ExampleTracker', { + log: function (eventParams) { + if (!eventParams || !eventParams.tracker) { + return ''; + } + + return '&myCustomVisitParam=' + 500 + eventParams.tracker.getSiteId(); + }, + }); + } + + if ('object' === typeof window.Piwik) { + init(); + } else { + // tracker is loaded separately for sure + if ('object' !== typeof window.piwikPluginAsyncInit) { + window.piwikPluginAsyncInit = []; + } + + window.piwikPluginAsyncInit.push(init); + } + +})();
\ No newline at end of file diff --git a/plugins/GeoIp2/GeoIP2AutoUpdater.php b/plugins/GeoIp2/GeoIP2AutoUpdater.php index 4af0e8c4b2..423256be83 100644 --- a/plugins/GeoIp2/GeoIP2AutoUpdater.php +++ b/plugins/GeoIp2/GeoIP2AutoUpdater.php @@ -130,7 +130,10 @@ class GeoIP2AutoUpdater extends Task $logger = StaticContainer::get(LoggerInterface::class); $url = trim($url); - if ($this->isDbIpUrl($url)) { + + if (self::isPaidDbIpUrl($url)) { + $url = $this->fetchPaidDbIpUrl($url); + } else if (self::isDbIpUrl($url)) { $url = $this->getDbIpUrlWithLatestDate($url); } @@ -731,7 +734,7 @@ class GeoIP2AutoUpdater extends Task return LocationProviderGeoIp2::$dbNames[$dbType][0] . '.' . $ext; } - private function getDbIpUrlWithLatestDate($url) + protected function getDbIpUrlWithLatestDate($url) { $today = Date::today(); return preg_replace('/-\d{4}-\d{2}\./', '-' . $today->toString('Y-m') . '.', $url); @@ -741,4 +744,35 @@ class GeoIP2AutoUpdater extends Task { return !! preg_match('/db-ip\.com/', $url); } + + protected static function isPaidDbIpUrl($url) + { + return !! preg_match('/db-ip\.com\/account\/[0-9a-z]+\/db/', $url); + } + + protected function fetchPaidDbIpUrl($url) + { + $content = trim($this->fetchUrl($url)); + + if (0 === strpos($content, 'http')) { + return $content; + } + + $content = json_decode($content, true); + + if (!empty($content['mmdb']['url'])) { + return $content['mmdb']['url']; + } + + if (!empty($content['url'])) { + return $content['url']; + } + + throw new Exception('Unable to determine download url'); + } + + protected function fetchUrl($url) + { + return Http::fetchRemoteFile($url); + } } diff --git a/plugins/GeoIp2/LocationProvider/GeoIp2/Php.php b/plugins/GeoIp2/LocationProvider/GeoIp2/Php.php index f2c145e35e..310a273dc4 100644 --- a/plugins/GeoIp2/LocationProvider/GeoIp2/Php.php +++ b/plugins/GeoIp2/LocationProvider/GeoIp2/Php.php @@ -11,6 +11,7 @@ namespace Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; use GeoIp2\Database\Reader; use GeoIp2\Exception\AddressNotFoundException; use MaxMind\Db\Reader\InvalidDatabaseException; +use Piwik\Common; use Piwik\Log; use Piwik\Piwik; use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2; @@ -238,11 +239,35 @@ class Php extends GeoIp2 if (is_array($lookupResult->subdivisions) && count($lookupResult->subdivisions) > 0) { $subdivisions = $lookupResult->subdivisions; $subdivision = $this->determinSubdivision($subdivisions, $result[self::COUNTRY_CODE_KEY]); - $result[self::REGION_CODE_KEY] = strtoupper($subdivision->isoCode); + $result[self::REGION_CODE_KEY] = strtoupper($subdivision->isoCode) ?: $this->determineRegionIsoCodeByNameAndCountryCode($subdivision->name, $result[self::COUNTRY_CODE_KEY]); $result[self::REGION_NAME_KEY] = $subdivision->name; } } + /** + * Try to determine the ISO region code based on the region name and country code + * + * @param string $regionName + * @param string $countryCode + * @return string + */ + protected function determineRegionIsoCodeByNameAndCountryCode($regionName, $countryCode) + { + $regionNames = self::getRegionNames(); + + if (empty($regionNames[$countryCode])) { + return ''; + } + + foreach ($regionNames[$countryCode] as $isoCode => $name) { + if (Common::mb_strtolower($name) === Common::mb_strtolower($regionName)) { + return $isoCode; + } + } + + return ''; + } + protected function determinSubdivision($subdivisions, $countryCode) { if (in_array($countryCode, ['GB'])) { diff --git a/plugins/GeoIp2/tests/Integration/LocationProviderTest.php b/plugins/GeoIp2/tests/Integration/LocationProviderTest.php index bb681f7704..86d9ae5529 100644 --- a/plugins/GeoIp2/tests/Integration/LocationProviderTest.php +++ b/plugins/GeoIp2/tests/Integration/LocationProviderTest.php @@ -34,6 +34,26 @@ class LocationProviderTest extends \PHPUnit\Framework\TestCase ], $result); } + public function testGeoIP2CityWithoutRegionIsoCode() + { + // The IP 99.99.99.99 will only return a region name, based on that the region code should be determined + $locationProvider = new GeoIp2\Php(['loc' => ['GeoIP2-City.mmdb'], 'isp' => []]); + $result = $locationProvider->getLocation(['ip' => '99.99.99.99']); + + $this->assertEquals([ + 'continent_name' => 'North America', + 'continent_code' => 'NA', + 'country_code' => 'US', + 'country_name' => 'United States', + 'city_name' => 'Englewood Cliffs', + 'lat' => 40.892, + 'long' => -73.947, + 'postal_code' => null, + 'region_code' => 'NJ', + 'region_name' => 'New Jersey', + ], $result); + } + public function testGeoIP2Country() { $locationProvider = new GeoIp2\Php(['loc' => ['GeoIP2-Country.mmdb'], 'isp' => []]); diff --git a/plugins/GeoIp2/tests/Unit/GeoIP2AutoUpdaterTest.php b/plugins/GeoIp2/tests/Unit/GeoIP2AutoUpdaterTest.php new file mode 100644 index 0000000000..ce68ee14af --- /dev/null +++ b/plugins/GeoIp2/tests/Unit/GeoIP2AutoUpdaterTest.php @@ -0,0 +1,149 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +namespace Piwik\Plugins\GeoIp2\tests\Unit; + +use Piwik\DataTable; +use Piwik\DataTable\Row; +use Piwik\Plugins\GeoIp2\GeoIP2AutoUpdater; + +class public_GeoIP2AutoUpdater extends GeoIP2AutoUpdater +{ + public static function isPaidDbIpUrl($url) + { + return parent::isPaidDbIpUrl($url); + } + + public function fetchPaidDbIpUrl($url) + { + return parent::fetchPaidDbIpUrl($url); + } +} + +/** + * @group GeoIP2AutoUpdater + */ +class GeoIP2AutoUpdaterTest extends \PHPUnit\Framework\TestCase +{ + /** + * @dataProvider getPaidDbTestUrls + */ + public function testIsPaidDbIpUrl($expected, $url) + { + $this->assertEquals($expected, public_GeoIP2AutoUpdater::isPaidDbIpUrl($url)); + } + + public function getPaidDbTestUrls() + { + return [ + [true, 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-country/'], + [true, 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-location/mmdb/'], + [true, 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-location-isp/mmdb/url'], + [false, 'https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb'], + [false, 'https://download.db-ip.com/free/dbip-country-lite-2020-02.mmdb.gz'], + ]; + } + + /** + * @dataProvider getDbTestUrls + */ + public function testIsDbIpUrl($expected, $url) + { + $this->assertEquals($expected, GeoIP2AutoUpdater::isDbIpUrl($url)); + } + + public function getDbTestUrls() + { + return [ + [true, 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-country/'], + [true, 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-location/mmdb/'], + [true, 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-location-isp/mmdb/url'], + [true, 'https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb'], + [true, 'https://download.db-ip.com/free/dbip-country-lite-2020-02.mmdb.gz'], + [false, 'https://dbip.com/free/dbip-country-lite-2020-02.mmdb.gz'], + ]; + } + + public function testFetchPaidUrlForPlainUrl() + { + $url = 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-country/mmdb/url'; + + $mock = $this->getMockBuilder(public_GeoIP2AutoUpdater::class) + ->setMethods(['fetchUrl']) + ->disableOriginalConstructor() + ->getMock(); + + $mock->expects($this->once())->method('fetchUrl')->with($url)->willReturn('https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb'); + + $determinedUrl = $mock->fetchPaidDbIpUrl($url); + + $this->assertEquals('https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb', $determinedUrl); + } + + public function testFetchPaidUrlForMmdbJson() + { + $url = 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-country/mmdb'; + + $mock = $this->getMockBuilder(public_GeoIP2AutoUpdater::class) + ->setMethods(['fetchUrl']) + ->disableOriginalConstructor() + ->getMock(); + + $mock->expects($this->once())->method('fetchUrl')->with($url)->willReturn(' +{ + "url": "https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb", + "name": "dbip-country-2020-02-22.mmdb.gz", + "date": "February 22nd 2020", + "size": 8807222, + "rows": 808624, + "md5sum": "dd8250ca45ad42dd5c3a63670ff46968", + "sha1sum": "062615e15dd1496ac9fddc311231efa2d75f09d6" +}'); + + $determinedUrl = $mock->fetchPaidDbIpUrl($url); + + $this->assertEquals('https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb', $determinedUrl); + } + + public function testFetchPaidUrlForFullJson() + { + $url = 'https://db-ip.com/account/ad446bf4cb9a44e4fff3f215deabc710f12f3/db/ip-to-country'; + + $mock = $this->getMockBuilder(public_GeoIP2AutoUpdater::class) + ->setMethods(['fetchUrl']) + ->disableOriginalConstructor() + ->getMock(); + + $mock->expects($this->once())->method('fetchUrl')->with($url)->willReturn(' +{ + "csv": { + "url": "https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.csv", + "name": "dbip-country-2020-02-22.csv.gz", + "date": "February 22nd 2020", + "size": 35113592, + "rows": 808314, + "md5sum": "22cd9abcc07e6b5c1c0fe89eef4503e2", + "sha1sum": "d3cc6e7ed30cc58abcc77ae73318d63af2687b06", + "version": 3 + }, + "mmdb": { + "url": "https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb", + "name": "dbip-country-2020-02-22.mmdb.gz", + "date": "February 22nd 2020", + "size": 8807222, + "rows": 808314, + "md5sum": "dd8250ca45ad42c55abc63670ff46968", + "sha1sum": "062615e15e01496ac9fddabc1231efa2d75f09d6" + } +}'); + + $determinedUrl = $mock->fetchPaidDbIpUrl($url); + + $this->assertEquals('https://download.db-ip.com/key/ad446bf4cb9a44e4fff3f215deabc710f12f3.mmdb', $determinedUrl); + } +} diff --git a/plugins/Overlay/Controller.php b/plugins/Overlay/Controller.php index 98ff9937d5..d7d42fa48e 100644 --- a/plugins/Overlay/Controller.php +++ b/plugins/Overlay/Controller.php @@ -20,6 +20,7 @@ use Piwik\Plugins\SegmentEditor\SegmentFormatter; use Piwik\Plugins\SitesManager\API as APISitesManager; use Piwik\ProxyHttp; use Piwik\Segment; +use Piwik\Session; use Piwik\Tracker\Action; use Piwik\Tracker\PageUrl; use Piwik\View; @@ -43,6 +44,12 @@ class Controller extends \Piwik\Plugin\Controller { Piwik::checkUserHasViewAccess($this->idSite); + // Overlay needs to send requests w/ the session cookie from within the tracked website, which means + // we can't use SameSite=Lax. So, we regenerate the session ID here (in Session.php there is a hardcoded + // check for Overlay, so will be set to SameSite=None). + // Note: this means the new session ID will have SameSite=None until it regenerates on a non-Overlay page. + Session::regenerateId(); + $template = '@Overlay/index'; if (Config::getInstance()->General['overlay_disable_framed_mode']) { $template = '@Overlay/index_noframe'; diff --git a/tests/PHPUnit/Fixtures/JSTrackingUIFixture.php b/tests/PHPUnit/Fixtures/JSTrackingUIFixture.php new file mode 100644 index 0000000000..73c86fef61 --- /dev/null +++ b/tests/PHPUnit/Fixtures/JSTrackingUIFixture.php @@ -0,0 +1,53 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link https://matomo.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + */ + +namespace Piwik\Tests\Fixtures; + +use Piwik\Plugins\GeoIp2\LocationProvider\GeoIp2\Php; +use Piwik\Plugins\PrivacyManager\IPAnonymizer; +use Piwik\Plugins\UserCountry\LocationProvider; +use Piwik\Tests\Framework\Fixture; + +class JSTrackingUIFixture extends Fixture +{ + public function setUp() + { + parent::setUp(); + + self::resetPluginsInstalledConfig(); + self::updateDatabase(); + self::installAndActivatePlugins($this->getTestEnvironment()); + self::updateDatabase(); + + // for proper geolocation + LocationProvider::setCurrentProvider(Php::ID); + IPAnonymizer::deactivate(); + + Fixture::createWebsite('2012-02-02 00:00:00'); + } + + public function performSetUp($setupEnvironmentOnly = false) + { + $this->extraTestEnvVars = array( + 'loadRealTranslations' => 1, + ); + $this->extraPluginsToLoad = array( + 'ExampleTracker', + ); + + parent::performSetUp($setupEnvironmentOnly); + + $this->testEnvironment->overlayUrl = UITestFixture::getLocalTestSiteUrl(); + UITestFixture::createOverlayTestSite($idSite = 1); + + $this->testEnvironment->tokenAuth = self::getTokenAuth(); + $this->testEnvironment->pluginsToLoad = $this->extraPluginsToLoad; + $this->testEnvironment->save(); + } +}
\ No newline at end of file diff --git a/tests/PHPUnit/Fixtures/UITestFixture.php b/tests/PHPUnit/Fixtures/UITestFixture.php index 06b4a5650b..e83070eb8f 100644 --- a/tests/PHPUnit/Fixtures/UITestFixture.php +++ b/tests/PHPUnit/Fixtures/UITestFixture.php @@ -17,6 +17,7 @@ use Piwik\DataTable\Row; use Piwik\Date; use Piwik\Db; use Piwik\DbHelper; +use Piwik\Filesystem; use Piwik\FrontController; use Piwik\Option; use Piwik\Piwik; @@ -144,8 +145,8 @@ class UITestFixture extends SqlDump . " WHERE idsite = 2 AND location_latitude IS NOT NULL LIMIT 1")); $this->testEnvironment->forcedIdVisitor = $visitorIdDeterministic; - $this->testEnvironment->overlayUrl = $this->getLocalTestSiteUrl(); - $this->createOverlayTestSite(); + $this->testEnvironment->overlayUrl = self::getLocalTestSiteUrl(); + self::createOverlayTestSite(); $forcedNowTimestamp = Option::get("Tests.forcedNowTimestamp"); if ($forcedNowTimestamp == false) { @@ -237,11 +238,11 @@ class UITestFixture extends SqlDump self::checkBulkTrackingResponse($t->doBulkTrack()); } - private function createOverlayTestSite() + public static function createOverlayTestSite($idSite = 3) { $realDir = PIWIK_INCLUDE_PATH . "/tests/resources/overlay-test-site-real"; if (is_dir($realDir)) { - return; + Filesystem::unlinkRecursive($realDir, true); } $files = array('index.html', 'page-1.html', 'page-2.html', 'page-3.html', 'page-4.html', 'page-5.html', 'page-6.html'); @@ -263,11 +264,12 @@ class UITestFixture extends SqlDump $contents = file_get_contents($path); $contents = str_replace("%trackerBaseUrl%", $url, $contents); + $contents = str_replace("%idSite%", $idSite, $contents); file_put_contents($path, $contents); } } - private function getLocalTestSiteUrl() + public static function getLocalTestSiteUrl() { return self::getRootUrl() . "tests/resources/overlay-test-site-real/"; } diff --git a/tests/PHPUnit/System/ApiGetReportMetadataTest.php b/tests/PHPUnit/System/ApiGetReportMetadataTest.php index 0ac96175cd..a33f3a6663 100644 --- a/tests/PHPUnit/System/ApiGetReportMetadataTest.php +++ b/tests/PHPUnit/System/ApiGetReportMetadataTest.php @@ -75,6 +75,14 @@ class ApiGetReportMetadataTest extends SystemTestCase array('Actions.getPageTitles', array('idSite' => $idSite, 'date' => $dateTime, 'testSuffix' => '_pageTitleZeroString')), + // Test w/ no format, should default to format=json + ['Actions.getPageTitles', [ + 'idSite' => $idSite, + 'date' => $dateTime, + 'testSuffix' => '_defaultFormatValue', + 'format' => 'asldjkf', + ]], + // test php renderer w/ array data array('API.getDefaultMetricTranslations', array('idSite' => $idSite, 'date' => $dateTime, 'format' => 'php', 'testSuffix' => '_phpRenderer')), diff --git a/tests/PHPUnit/System/CookieTest.php b/tests/PHPUnit/System/CookieTest.php index 897db63e1a..2220e37bb4 100644 --- a/tests/PHPUnit/System/CookieTest.php +++ b/tests/PHPUnit/System/CookieTest.php @@ -61,7 +61,7 @@ class CookieTest extends SystemTestCase { $headers = $this->setIgnoreCookie(self::USERAGENT_FIREFOX); $cookie = $this->findIgnoreCookie($headers); - $this->assertCookieSameSiteMatches('None', $cookie); + $this->assertCookieSameSiteMatches('Lax', $cookie); } public function testIgnoreCookieSameSiteSafari() diff --git a/tests/PHPUnit/System/expected/test_apiGetReportMetadata_defaultFormatValue__Actions.getPageTitles_day.asldjkf b/tests/PHPUnit/System/expected/test_apiGetReportMetadata_defaultFormatValue__Actions.getPageTitles_day.asldjkf new file mode 100644 index 0000000000..dd2f5f75aa --- /dev/null +++ b/tests/PHPUnit/System/expected/test_apiGetReportMetadata_defaultFormatValue__Actions.getPageTitles_day.asldjkf @@ -0,0 +1,3 @@ +Error: Renderer format 'asldjkf' not valid. Try any of the following instead: console, csv, html, json, json2, original, php, rss, tsv, xml. + + --> To temporarily debug this error further, set const PIWIK_PRINT_ERROR_BACKTRACE=true; in index.php
\ No newline at end of file diff --git a/tests/UI/expected-screenshots/JSTracker_visitor_log.png b/tests/UI/expected-screenshots/JSTracker_visitor_log.png new file mode 100644 index 0000000000..50f7f03142 --- /dev/null +++ b/tests/UI/expected-screenshots/JSTracker_visitor_log.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e22357b298003038503fbd94e6cc962667b99139cfcf0010b594b8e9ef441ba6 +size 31826 diff --git a/tests/UI/specs/JSTracker_spec.js b/tests/UI/specs/JSTracker_spec.js new file mode 100644 index 0000000000..3101a1b1d0 --- /dev/null +++ b/tests/UI/specs/JSTracker_spec.js @@ -0,0 +1,38 @@ +/*! + * Piwik - free/libre analytics platform + * + * JS tracker UI tests. + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ + +describe("JSTracker", function () { + this.fixture = 'Piwik\\Tests\\Fixtures\\JSTrackingUIFixture'; + + var testWebsiteUrl = 'tests/resources/overlay-test-site-real/index.html'; + var generalParams = 'idSite=1&period=day&date=today', + widgetizeParams = "module=Widgetize&action=iframe", + visitorLogUrl = "?" + widgetizeParams + "&" + generalParams + "&moduleToWidgetize=Live&actionToWidgetize=getVisitorLog"; + + it("run correctly on a website and correctly track visits in the visitor log", async function () { + await page.goto(testWebsiteUrl); + + // view another page + await page.evaluate(() => $('a:contains(Page 3)')[0].click()); + await page.waitForNetworkIdle(); + await page.waitFor(500); + await page.waitForNetworkIdle(); + + // visit visitor log for correct date + await page.goto(visitorLogUrl); + + await page.evaluate(function () { + $('.visitor-log-datetime').html('REMOVED'); + var $e = $('.dataTableWrapper>.row>.column>strong'); + $e.text($e.text().replace(/\d+s/, 'Ns')); + }); + + expect(await page.screenshot({ fullPage: true })).to.matchImage('visitor_log'); + }); +});
\ No newline at end of file diff --git a/tests/lib/geoip-files/GeoIP2-City.json b/tests/lib/geoip-files/GeoIP2-City.json index 8a88e5761b..d9e6f4c0aa 100644 --- a/tests/lib/geoip-files/GeoIP2-City.json +++ b/tests/lib/geoip-files/GeoIP2-City.json @@ -2485,5 +2485,75 @@ } ] } + }, + { + "::99.99.99.99/128": { + "city": { + "geoname_id": 45645645, + "names": { + "de": "Englewood Cliffs", + "en": "Englewood Cliffs" + } + }, + "continent": { + "code": "NA", + "geoname_id": 6255149, + "names": { + "de": "Nordamerika", + "en": "North America", + "es": "Norteamérica", + "fr": "Amérique du Nord", + "ja": "北アメリカ", + "pt-BR": "América do Norte", + "ru": "Северная Америка", + "zh-CN": "北美洲" + } + }, + "country": { + "geoname_id": 6252001, + "iso_code": "US", + "names": { + "de": "USA", + "en": "United States", + "es": "Estados Unidos", + "fr": "États-Unis", + "ja": "アメリカ合衆国", + "pt-BR": "Estados Unidos", + "ru": "США", + "zh-CN": "美国" + } + }, + "location": { + "accuracy_radius": 3500, + "latitude": 40.892, + "longitude": -73.947, + "time_zone": "America\/New_York" + }, + "registered_country": { + "geoname_id": 6252001, + "iso_code": "US", + "names": { + "de": "USA", + "en": "United States", + "es": "Estados Unidos", + "fr": "États-Unis", + "ja": "アメリカ合衆国", + "pt-BR": "Estados Unidos", + "ru": "США", + "zh-CN": "美国" + } + }, + "subdivisions": [ + { + "geoname_id": 4567555, + "iso_code": "", + "names": { + "en": "New Jersey", + "es": "New Jersey", + "fr": "New Jersey" + } + } + ] + } } ]
\ No newline at end of file diff --git a/tests/lib/geoip-files/GeoIP2-City.mmdb b/tests/lib/geoip-files/GeoIP2-City.mmdb Binary files differindex 30b1564cf8..0da250e8ff 100644 --- a/tests/lib/geoip-files/GeoIP2-City.mmdb +++ b/tests/lib/geoip-files/GeoIP2-City.mmdb diff --git a/tests/lib/screenshot-testing/package-lock.json b/tests/lib/screenshot-testing/package-lock.json index fa92d8be8b..6f9918f94c 100644 --- a/tests/lib/screenshot-testing/package-lock.json +++ b/tests/lib/screenshot-testing/package-lock.json @@ -91,9 +91,9 @@ "integrity": "sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==" }, "async-limiter": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz", - "integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg==" + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.1.tgz", + "integrity": "sha512-csOlWGAcRFJaI6m+F2WKdnMKr4HhdhFVBk0H/QbJFMCr+uO2kwohwXQPxw/9OCxp05r5ghVBFSyioixx3gfkNQ==" }, "asynckit": { "version": "0.4.0", @@ -773,9 +773,9 @@ } }, "https-proxy-agent": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.2.tgz", - "integrity": "sha512-c8Ndjc9Bkpfx/vCJueCPy0jlP4ccCCSNDp8xwCZzPjKJUm+B+u9WX2x98Qx4n1PiMNTWo3D7KK5ifNV/yJyRzg==", + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.4.tgz", + "integrity": "sha512-OmvfoQ53WLjtA9HeYP9RNrWMJzzAz1JGaSFr1nijg0PVR1JaD/xbJq1mdEIIlxGpXp9eSe/O2LgU9DJmTPd0Eg==", "requires": { "agent-base": "^4.3.0", "debug": "^3.1.0" @@ -1366,9 +1366,9 @@ "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==" }, "puppeteer": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.18.1.tgz", - "integrity": "sha512-luUy0HPSuWPsPZ1wAp6NinE0zgetWtudf5zwZ6dHjMWfYpTQcmKveFRox7VBNhQ98OjNA9PQ9PzQyX8k/KrxTg==", + "version": "1.20.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-1.20.0.tgz", + "integrity": "sha512-bt48RDBy2eIwZPrkgbcwHtb51mj2nKvHOPMaSH2IsWiv7lOG9k9zhaRzpDZafrk05ajMc3cu+lSQYYOfH2DkVQ==", "requires": { "debug": "^4.1.0", "extract-zip": "^1.6.6", @@ -1446,9 +1446,9 @@ "integrity": "sha512-XzgvowFrwDo6TWcpJ/WTiarb9UI6lhA4PMzS7n1joK3sHfBBBOQHUc0U4u57D6DWO9vHv6lVSWx2Q/Ymfyv4hw==" }, "readable-stream": { - "version": "2.3.6", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", - "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", "requires": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", @@ -1583,17 +1583,17 @@ } }, "rimraf": { - "version": "2.6.3", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", - "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", + "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", "requires": { "glob": "^7.1.3" }, "dependencies": { "glob": { - "version": "7.1.4", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", - "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "version": "7.1.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz", + "integrity": "sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA==", "requires": { "fs.realpath": "^1.0.0", "inflight": "^1.0.4", diff --git a/tests/lib/screenshot-testing/package.json b/tests/lib/screenshot-testing/package.json index 902c7fe3a0..84f5a22f00 100644 --- a/tests/lib/screenshot-testing/package.json +++ b/tests/lib/screenshot-testing/package.json @@ -10,7 +10,7 @@ "chai-image-assert": "^1.2.0", "fs-extra": "^7.0.1", "mocha": "^5.2.0", - "puppeteer": "^1.15.0-next.1556321762762", + "puppeteer": "^1.20.0", "request": "^2.88.0", "request-promise": "^4.2.2", "url-parse": "^1.4.3" diff --git a/tests/resources/overlay-test-site/index.html b/tests/resources/overlay-test-site/index.html index 2b1f099263..d8151c2054 100644 --- a/tests/resources/overlay-test-site/index.html +++ b/tests/resources/overlay-test-site/index.html @@ -86,12 +86,14 @@ <script> var pkBaseURL = (("https:" == document.location.protocol) ? "https://%trackerBaseUrl%" : "http://%trackerBaseUrl%"); try { - var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", 3); + var piwikTracker = Piwik.addTracker(pkBaseURL + "matomo.php", %idSite%); piwikTracker.setCookieDomain('*.piwik.org'); piwikTracker.trackPageView(); piwikTracker.enableLinkTracking(); - } catch( err ) {} + } catch( err ) { + console.log(err.stack || err.message); + } </script> </body> </html>
\ No newline at end of file diff --git a/tests/resources/overlay-test-site/page-1.html b/tests/resources/overlay-test-site/page-1.html index 16330c63a8..70575666ae 100644 --- a/tests/resources/overlay-test-site/page-1.html +++ b/tests/resources/overlay-test-site/page-1.html @@ -83,12 +83,14 @@ <script> var pkBaseURL = (("https:" == document.location.protocol) ? "https://%trackerBaseUrl%" : "http://%trackerBaseUrl%"); try { - var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", 3); + var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", %idSite%); piwikTracker.setCookieDomain('*.piwik.org'); piwikTracker.trackPageView(); piwikTracker.enableLinkTracking(); - } catch( err ) {} + } catch( err ) { + console.log(err.stack || err.message); + } </script> </body> </html>
\ No newline at end of file diff --git a/tests/resources/overlay-test-site/page-2.html b/tests/resources/overlay-test-site/page-2.html index 43f08ee61f..cf83bdb641 100644 --- a/tests/resources/overlay-test-site/page-2.html +++ b/tests/resources/overlay-test-site/page-2.html @@ -83,12 +83,14 @@ <script> var pkBaseURL = (("https:" == document.location.protocol) ? "https://%trackerBaseUrl%" : "http://%trackerBaseUrl%"); try { - var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", 3); + var piwikTracker = Piwik.addTracker(pkBaseURL + "matomo.php", %idSite%); piwikTracker.setCookieDomain('*.piwik.org'); piwikTracker.trackPageView(); piwikTracker.enableLinkTracking(); - } catch( err ) {} + } catch( err ) { + console.log(err.stack || err.message); + } </script> </body> </html>
\ No newline at end of file diff --git a/tests/resources/overlay-test-site/page-3.html b/tests/resources/overlay-test-site/page-3.html index a53f07050e..3399004f97 100644 --- a/tests/resources/overlay-test-site/page-3.html +++ b/tests/resources/overlay-test-site/page-3.html @@ -83,12 +83,14 @@ <script> var pkBaseURL = (("https:" == document.location.protocol) ? "https://%trackerBaseUrl%" : "http://%trackerBaseUrl%"); try { - var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", 3); + var piwikTracker = Piwik.addTracker(pkBaseURL + "matomo.php", %idSite%); piwikTracker.setCookieDomain('*.piwik.org'); piwikTracker.trackPageView(); piwikTracker.enableLinkTracking(); - } catch( err ) {} + } catch( err ) { + console.log(err.stack || err.message); + } </script> </body> </html>
\ No newline at end of file diff --git a/tests/resources/overlay-test-site/page-4.html b/tests/resources/overlay-test-site/page-4.html index 8341fc48c7..6085970787 100644 --- a/tests/resources/overlay-test-site/page-4.html +++ b/tests/resources/overlay-test-site/page-4.html @@ -83,12 +83,14 @@ <script> var pkBaseURL = (("https:" == document.location.protocol) ? "https://%trackerBaseUrl%" : "http://%trackerBaseUrl%"); try { - var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", 3); + var piwikTracker = Piwik.addTracker(pkBaseURL + "matomo.php", %idSite%); piwikTracker.setCookieDomain('*.piwik.org'); piwikTracker.trackPageView(); piwikTracker.enableLinkTracking(); - } catch( err ) {} + } catch( err ) { + console.log(err.stack || err.message); + } </script> </body> </html>
\ No newline at end of file diff --git a/tests/resources/overlay-test-site/page-5.html b/tests/resources/overlay-test-site/page-5.html index e8806b0d68..0e4ece13a5 100644 --- a/tests/resources/overlay-test-site/page-5.html +++ b/tests/resources/overlay-test-site/page-5.html @@ -83,12 +83,14 @@ <script> var pkBaseURL = (("https:" == document.location.protocol) ? "https://%trackerBaseUrl%" : "http://%trackerBaseUrl%"); try { - var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", 3); + var piwikTracker = Piwik.addTracker(pkBaseURL + "matomo.php", %idSite%); piwikTracker.setCookieDomain('*.piwik.org'); piwikTracker.trackPageView(); piwikTracker.enableLinkTracking(); - } catch( err ) {} + } catch( err ) { + console.log(err.stack || err.message); + } </script> </body> </html>
\ No newline at end of file diff --git a/tests/resources/overlay-test-site/page-6.html b/tests/resources/overlay-test-site/page-6.html index 1dbe72c1a8..b43abaac79 100644 --- a/tests/resources/overlay-test-site/page-6.html +++ b/tests/resources/overlay-test-site/page-6.html @@ -83,12 +83,14 @@ <script> var pkBaseURL = (("https:" == document.location.protocol) ? "https://%trackerBaseUrl%" : "http://%trackerBaseUrl%"); try { - var piwikTracker = Piwik.getTracker(pkBaseURL + "matomo.php", 3); + var piwikTracker = Piwik.addTracker(pkBaseURL + "matomo.php", %idSite%); piwikTracker.setCookieDomain('*.piwik.org'); piwikTracker.trackPageView(); piwikTracker.enableLinkTracking(); - } catch( err ) {} + } catch( err ) { + console.log(err.stack || err.message); + } </script> </body> </html>
\ No newline at end of file |