diff options
author | mattab <matthieu.aubry@gmail.com> | 2013-10-24 02:58:16 +0400 |
---|---|---|
committer | mattab <matthieu.aubry@gmail.com> | 2013-10-24 02:58:16 +0400 |
commit | 85b75a60dfe49b0135846d12d6ddeb10fda90118 (patch) | |
tree | b5c1c35f841929ef34fde27e6b2985709ffb94ea /libs | |
parent | b7c423246c42b125136e2eb24080d356781b916d (diff) | |
parent | 7f2e967e7e390d5ab2035df5b61c897201b18d5f (diff) |
Merge branch 'php_client_cookies' of https://github.com/claytondaley/piwik into claytondaley-php_client_cookies
Diffstat (limited to 'libs')
-rw-r--r-- | libs/PiwikTracker/PiwikTracker.php | 152 |
1 files changed, 144 insertions, 8 deletions
diff --git a/libs/PiwikTracker/PiwikTracker.php b/libs/PiwikTracker/PiwikTracker.php index ebfdb2e0ba..9a6e10ded2 100644 --- a/libs/PiwikTracker/PiwikTracker.php +++ b/libs/PiwikTracker/PiwikTracker.php @@ -88,6 +88,17 @@ class PiwikTracker $this->generationTime = false; $this->requestCookie = ''; + $this->updateClientCookies = false; + $this->clientCookiePath = '/'; + $this->clientCookieDomain = ''; + $this->newVisitor = 1; + $this->cookieVisitorId = ''; + $this->currentTs = time(); + $this->createTs = $this->currentTs; + $this->visitCount = 0; + $this->currentVisitTs = ''; + $this->lastVisitTs = ''; + $this->lastEcommerceOrderTs = ''; $this->idSite = $idSite; $this->urlReferrer = !empty($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : false; $this->pageCharset = self::DEFAULT_CHARSET_PARAMETER_VALUES; @@ -100,6 +111,13 @@ class PiwikTracker } $this->setNewVisitorId(); + // Life of the visitor cookie (in milliseconds) + $this->configVisitorCookieTimeout = 63072000000; // 2 years + // Life of the session cookie (in milliseconds) + $this->configSessionCookieTimeout = 1800000; // 30 minutes + // Life of the referral cookie (in milliseconds) + $this->configReferralCookieTimeout = 15768000000; // 6 months + // Allow debug while blocking the request $this->requestTimeout = 600; $this->doBulkRequests = false; @@ -225,7 +243,7 @@ class PiwikTracker if (!empty($this->visitorCustomVar[$id])) { return $this->visitorCustomVar[$id]; } - $customVariablesCookie = 'cvar.' . $this->idSite . '.'; + $customVariablesCookie = $this->getCookieName('cvar'); $cookie = $this->getCookieMatchingName($customVariablesCookie); if (!$cookie) { return false; @@ -354,6 +372,55 @@ class PiwikTracker } /** + * Enable Cookie Creation - this will cause a first party VisitorId cookie to be set when the VisitorId is set or reset + * + * @param bool $create determines whether or not client cookies will be updated + * $param string $domain sets the domain under which the cookie will be placed (primarily used to create domain wildcard cookies) + */ + public function setUpdateClientCookies( $create, $domain = '', $path = '/' ) + { + $this->updateClientCookies = $create; + $this->clientCookieDomain = self::domainFixup($domain); + $this->clientCookiePath = $path; + } + + /* + * Fix-up domain + */ + static protected function domainFixup($domain) { + $dl = strlen($domain); + // remove trailing '.' + if ($domain{--$dl} === '.') { + $domain = substr($domain, 0, $dl); + } + // remove leading '*' + if (substr($domain, 0, 2) === '*.') { + $domain = substr($domain, 1); + } + return $domain; + } + + /** + * Get cookie name with prefix and domain hash + */ + function getCookieName($baseName) { + // NOTE: If the cookie name is changed, we must also update the method in piwik.js with + // the same name. + $hash = substr( sha1( ($this->clientCookieDomain == '' ? self::getCurrentHost() : $this->clientCookieDomain) . $this->clientCookiePath ), 0, 4); + return '_pk_' . $baseName . '.' . $this->idSite . '.' . $hash; + } + + /** + * Sets a first party cookie. This is useful when using the PHP Tracking API along with the Javascript Tracking API. + * + * @return bool + */ + protected function setVisitorIdCookie($visitorId, $createTs, $visitCount, $nowTs, $lastVisitTs, $lastEcommerceOrderTs = '') + { + return setcookie( $this->getCookieName('id'), $visitorId . '.' . $createTs . '.' . $visitCount . '.' . $nowTs . '.' . $lastVisitTs . '.' . $lastEcommerceOrderTs, $nowTs + $this->configVisitorCookieTimeout / 1000, $this->clientCookiePath, $this->clientCookieDomain ); + } + + /** * Tracks a page view * * @param string $documentTitle Page title as it will appear in the Actions > Page titles report @@ -757,19 +824,55 @@ class PiwikTracker { if (!empty($this->forcedVisitorId)) { return $this->forcedVisitorId; + } else if ($this->loadVisitorIdCookie()) { + return $this->cookieVisitorId; + } else { + return $this->visitorId; } + } - $idCookieName = 'id.' . $this->idSite . '.'; + /** + * Loads values from the VisitorId Cookie + * + * @return bool True if cookie exists and is valid, False otherwise + */ + protected function loadVisitorIdCookie() + { + $idCookieName = $this->getCookieName('id'); $idCookie = $this->getCookieMatchingName($idCookieName); if ($idCookie !== false) { - $visitorId = substr($idCookie, 0, strpos($idCookie, '.')); - if (strlen($visitorId) == self::LENGTH_VISITOR_ID) { - return $visitorId; + $parts = explode('.',$idCookie); + if (strlen($parts[0]) == self::LENGTH_VISITOR_ID) { + $this->newVisitor = 0; + $this->cookieVisitorId = $parts[0]; // provides backward compatibility since getVisitorId() didn't change any existing VisitorId value + $this->createTs = $parts[1]; + $this->visitCount = $parts[2]; + $this->currentVisitTs = $parts[3]; + $this->lastVisitTs = $parts[4]; + if (count($parts)>5) { + $this->lastEcommerceOrderTs = $parts[5]; + } else { + $this->lastEcommerceOrderTs = ''; + } + return true; } } - return $this->visitorId; + return false; } - + + /** + * Deletes all cookies from client + * + */ + public function deleteCookies() + { + return + setcookie($this->getCookieName('id'), '', $this->currentTs - 86400, $this->clientCookiePath, $this->clientCookieDomain) && + setcookie($this->getCookieName('ses'), '', $this->currentTs - 86400, $this->clientCookiePath, $this->clientCookieDomain) && + setcookie($this->getCookieName('cvar'), '', $this->currentTs - 86400, $this->clientCookiePath, $this->clientCookieDomain) && + setcookie($this->getCookieName('ref'), '', $this->currentTs - 86400, $this->clientCookiePath, $this->clientCookieDomain); + } + /** * Returns the currently assigned Attribution Information stored in a first party cookie. * @@ -782,7 +885,7 @@ class PiwikTracker */ public function getAttributionInfo() { - $attributionCookieName = 'ref.' . $this->idSite . '.'; + $attributionCookieName = $this->getCookieName('ref'); return $this->getCookieMatchingName($attributionCookieName); } @@ -1034,6 +1137,32 @@ class PiwikTracker */ protected function getRequest($idSite) { + // Update client cookies in getRequest to parallel piwik.js logic + if ($this->updateClientCookies) { + // If we're setting cookies, we want to make sure we've loaded prevoius cookies + // Initialize cookie data if it's still defaulted to false + if (empty($this->lastVisitTs)) { + $this->loadVisitorIdCookie(); + } + // Set the id cookie + $this->setVisitorIdCookie($this->getVisitorId(), $this->createTs, $this->visitCount, $this->currentTs, $this->lastVisitTs, $this->lastEcommerceOrderTs); + + // Set/update the session cookie + $sesname = $this->getCookieName('ses'); + if (!$this->getCookieMatchingName($sesname)) { + // new session (new visit) + $this->visitCount++; + $this->lastVisitTs = $this->currentVisitTs; + } + setrawcookie($sesname, '*', $this->currentTs + $this->configSessionCookieTimeout / 1000, $this->clientCookiePath, $this->clientCookieDomain); + + // Set the custom variable cookie if custom variables have been set + if (!empty($this->visitorCustomVar)) { + $cvarame = $this->getCookieName('cvar'); + setcookie($cvarname, json_encode($this->visitorCustomVar), $this->currentTs + $this->configSessionCookieTimeout / 1000, $this->clientCookiePath, $this->clientCookieDomain); + } + } + $url = $this->getBaseUrl() . '?idsite=' . $idSite . '&rec=1' . @@ -1050,6 +1179,13 @@ class PiwikTracker (!empty($this->forcedDatetime) ? '&cdt=' . urlencode($this->forcedDatetime) : '') . ((!empty($this->token_auth) && !$this->doBulkRequests) ? '&token_auth=' . urlencode($this->token_auth) : '') . + // Values collected from cookie + '&_idts=' . $this->createTs . + '&_idvc=' . $this->visitCount . + '&_idn=' . $this->newVisitor . // currently unused + (!empty($this->lastVisitTs) ? '&_viewts=' . $this->lastVisitTs : '' ) . // note that piwik.js sends an empty value instead of skipping + (!empty($this->lastEcommerceOrderTs) ? '&_ects=' . $this->lastEcommerceOrderTs : '' ) . + // These parameters are set by the JS, but optional when using API (!empty($this->plugins) ? $this->plugins : '') . (($this->localHour !== false && $this->localMinute !== false && $this->localSecond !== false) ? '&h=' . $this->localHour . '&m=' . $this->localMinute . '&s=' . $this->localSecond : '') . |