public function outputResponse(Tracker $tracker) { if (!$tracker->shouldRecordStatistics()) { $this->outputApiResponse($tracker); Common::printDebug("Logging disabled, display transparent logo"); } elseif (!$tracker->hasLoggedRequests()) { if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) { Common::sendResponseCode(400); } Common::printDebug("Empty request => Piwik page"); echo "This resource is part of Piwik. Keep full control of your data with the leading free and open source <a href='https://piwik.org' target='_blank'>digital analytics platform</a> for web and mobile."; } else { $this->outputApiResponse($tracker); Common::printDebug("Nothing to notice => default behaviour"); } Common::printDebug("End of the page."); if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() && TrackerDb::isProfilingEnabled()) { $db = Tracker::getDatabase(); $db->recordProfiling(); Profiler::displayDbTrackerProfile($db); } if ($tracker->isDebugModeEnabled()) { Common::printDebug($_COOKIE); Common::printDebug((string) $this->timer); } }
/** * @param Request $request * @param Visitor $visitor * @param Action|null $action * @return mixed */ public function onNewVisit(Request $request, Visitor $visitor, $action) { // Adding &dp=1 will disable the provider plugin, this is an "unofficial" parameter used to speed up log importer $disableProvider = $request->getParam('dp'); if (!empty($disableProvider)) { return false; } // if provider info has already been set, abort $locationValue = $visitor->getVisitorColumn('location_provider'); if (!empty($locationValue)) { return false; } $ip = $visitor->getVisitorColumn('location_ip'); $privacyConfig = new PrivacyManagerConfig(); if (!$privacyConfig->useAnonymizedIpForVisitEnrichment) { $ip = $request->getIp(); } $ip = IPUtils::binaryToStringIP($ip); // In case the IP was anonymized, we should not continue since the DNS reverse lookup will fail and this will slow down tracking if (substr($ip, -2, 2) == '.0') { Common::printDebug("IP Was anonymized so we skip the Provider DNS reverse lookup..."); return false; } $hostname = $this->getHost($ip); $hostnameExtension = ProviderPlugin::getCleanHostname($hostname); // add the provider value in the table log_visit $locationProvider = substr($hostnameExtension, 0, 100); return $locationProvider; }
/** * Tracker requests will automatically trigger the Scheduled tasks. * This is useful for users who don't setup the cron, * but still want daily/weekly/monthly PDF reports emailed automatically. * * This is similar to calling the API CoreAdminHome.runScheduledTasks */ public function runScheduledTasks() { $now = time(); // Currently, there are no hourly tasks. When there are some, // this could be too aggressive minimum interval (some hours would be skipped in case of low traffic) $minimumInterval = TrackerConfig::getConfigValue('scheduled_tasks_min_interval'); // If the user disabled browser archiving, he has already setup a cron // To avoid parallel requests triggering the Scheduled Tasks, // Get last time tasks started executing $cache = Cache::getCacheGeneral(); if ($minimumInterval <= 0 || empty($cache['isBrowserTriggerEnabled'])) { Common::printDebug("-> Scheduled tasks not running in Tracker: Browser archiving is disabled."); return; } $nextRunTime = $cache['lastTrackerCronRun'] + $minimumInterval; if (defined('DEBUG_FORCE_SCHEDULED_TASKS') && DEBUG_FORCE_SCHEDULED_TASKS || $cache['lastTrackerCronRun'] === false || $nextRunTime < $now) { $cache['lastTrackerCronRun'] = $now; Cache::setCacheGeneral($cache); Option::set('lastTrackerCronRun', $cache['lastTrackerCronRun']); Common::printDebug('-> Scheduled Tasks: Starting...'); $invokeScheduledTasksUrl = "?module=API&format=csv&convertToUnicode=0&method=CoreAdminHome.runScheduledTasks&trigger=archivephp"; $cliMulti = new CliMulti(); $cliMulti->runAsSuperUser(); $responses = $cliMulti->request(array($invokeScheduledTasksUrl)); $resultTasks = reset($responses); Common::printDebug($resultTasks); Common::printDebug('Finished Scheduled Tasks.'); } else { Common::printDebug("-> Scheduled tasks not triggered."); } Common::printDebug("Next run will be from: " . date('Y-m-d H:i:s', $nextRunTime) . ' UTC'); }
/** * Logs the provider in the log_visit table */ public function enrichVisitWithProviderInfo(&$visitorInfo, \Piwik\Tracker\Request $request) { // if provider info has already been set, abort if (!empty($visitorInfo['location_provider'])) { return; } $privacyConfig = new PrivacyManagerConfig(); $ip = IP::N2P($privacyConfig->useAnonymizedIpForVisitEnrichment ? $visitorInfo['location_ip'] : $request->getIp()); // In case the IP was anonymized, we should not continue since the DNS reverse lookup will fail and this will slow down tracking if (substr($ip, -2, 2) == '.0') { Common::printDebug("IP Was anonymized so we skip the Provider DNS reverse lookup..."); return; } $hostname = $this->getHost($ip); $hostnameExtension = $this->getCleanHostname($hostname); // add the provider value in the table log_visit $visitorInfo['location_provider'] = $hostnameExtension; $visitorInfo['location_provider'] = substr($visitorInfo['location_provider'], 0, 100); // improve the country using the provider extension if valid $hostnameDomain = substr($hostnameExtension, 1 + strrpos($hostnameExtension, '.')); if ($hostnameDomain == 'uk') { $hostnameDomain = 'gb'; } if (array_key_exists($hostnameDomain, Common::getCountriesList())) { $visitorInfo['location_country'] = $hostnameDomain; } }
/** * Checks for DoNotTrack headers and if found, sets `$exclude` to `true`. */ public function checkHeaderInTracker(&$exclude) { if ($exclude) { Common::printDebug("Visit is already excluded, no need to check DoNotTrack support."); return; } if (!$this->isActive()) { Common::printDebug("DoNotTrack support is not enabled, skip check"); return; } if (isset($_SERVER['HTTP_X_DO_NOT_TRACK']) && $_SERVER['HTTP_X_DO_NOT_TRACK'] === '1' || isset($_SERVER['HTTP_DNT']) && substr($_SERVER['HTTP_DNT'], 0, 1) === '1') { $request = new Request($_REQUEST); $ua = $request->getUserAgent(); if (strpos($ua, 'MSIE') !== false || strpos($ua, 'Trident') !== false) { Common::printDebug("INTERNET EXPLORER enable DoNotTrack by default; so Piwik ignores DNT IE browsers..."); return; } Common::printDebug("DoNotTrack header found!"); $exclude = true; $trackingCookie = IgnoreCookie::getTrackingCookie(); $trackingCookie->delete(); // this is an optional supplement to the site's tracking status resource at: // /.well-known/dnt // per Tracking Preference Expression (draft) header('Tk: 1'); } else { Common::printDebug("DoNotTrack header not found"); } }
/** * Uses a GeoIP database to get a visitor's location based on their IP address. * * This function will return different results based on the data used and based * on how the GeoIP module is configured. * * If a region database is used, it may return the country code, region code, * city name, area code, latitude, longitude and postal code of the visitor. * * Alternatively, only the country code may be returned for another database. * * If your HTTP server is not configured to include all GeoIP information, some * information will not be available to Piwik. * * @param array $info Must have an 'ip' field. * @return array */ public function getLocation($info) { $ip = $this->getIpFromInfo($info); // geoip modules that are built into servers can't use a forced IP. in this case we try // to fallback to another version. $myIP = IP::getIpFromHeader(); if (!self::isSameOrAnonymizedIp($ip, $myIP) && (!isset($info['disable_fallbacks']) || !$info['disable_fallbacks'])) { Common::printDebug("The request is for IP address: " . $info['ip'] . " but your IP is: {$myIP}. GeoIP Server Module (apache/nginx) does not support this use case... "); $fallbacks = array(Pecl::ID, Php::ID); foreach ($fallbacks as $fallbackProviderId) { $otherProvider = LocationProvider::getProviderById($fallbackProviderId); if ($otherProvider) { Common::printDebug("Used {$fallbackProviderId} to detect this visitor IP"); return $otherProvider->getLocation($info); } } Common::printDebug("FAILED to lookup the geo location of this IP address, as no fallback location providers is configured. We recommend to configure Geolocation PECL module to fix this error."); return false; } $result = array(); foreach (self::$geoIpServerVars as $resultKey => $geoipVarName) { if (!empty($_SERVER[$geoipVarName])) { $result[$resultKey] = $_SERVER[$geoipVarName]; } } foreach (self::$geoIpUtfServerVars as $resultKey => $geoipVarName) { if (!empty($_SERVER[$geoipVarName])) { $result[$resultKey] = utf8_encode($_SERVER[$geoipVarName]); } } $this->completeLocationResult($result); return $result; }
public function enrichVisitWithLocation(&$visitorInfo, \Piwik\Tracker\Request $request) { require_once PIWIK_INCLUDE_PATH . "/plugins/UserCountry/LocationProvider.php"; $ipAddress = IP::N2P(Config::getInstance()->Tracker['use_anonymized_ip_for_visit_enrichment'] == 1 ? $visitorInfo['location_ip'] : $request->getIp()); $userInfo = array('lang' => $visitorInfo['location_browser_lang'], 'ip' => $ipAddress); $id = Common::getCurrentLocationProviderId(); $provider = LocationProvider::getProviderById($id); if ($provider === false) { $id = DefaultProvider::ID; $provider = LocationProvider::getProviderById($id); Common::printDebug("GEO: no current location provider sent, falling back to default '{$id}' one."); } $location = $provider->getLocation($userInfo); // if we can't find a location, use default provider if ($location === false) { $defaultId = DefaultProvider::ID; $provider = LocationProvider::getProviderById($defaultId); $location = $provider->getLocation($userInfo); Common::printDebug("GEO: couldn't find a location with Geo Module '{$id}', using Default '{$defaultId}' provider as fallback..."); $id = $defaultId; } Common::printDebug("GEO: Found IP {$ipAddress} location (provider '" . $id . "'): " . var_export($location, true)); if (empty($location['country_code'])) { // sanity check $location['country_code'] = \Piwik\Tracker\Visit::UNKNOWN_CODE; } // add optional location components $this->updateVisitInfoWithLocation($visitorInfo, $location); }
public function outputResponse(Tracker $tracker) { if (!$tracker->shouldRecordStatistics()) { $this->outputApiResponse($tracker); Common::printDebug("Logging disabled, display transparent logo"); } elseif (!$tracker->hasLoggedRequests()) { if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) { Common::sendResponseCode(400); } Common::printDebug("Empty request => Piwik page"); echo "<a href='/'>Piwik</a> is a free/libre web <a href='http://piwik.org'>analytics</a> that lets you keep control of your data."; } else { $this->outputApiResponse($tracker); Common::printDebug("Nothing to notice => default behaviour"); } Common::printDebug("End of the page."); if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() && TrackerDb::isProfilingEnabled()) { $db = Tracker::getDatabase(); $db->recordProfiling(); Profiler::displayDbTrackerProfile($db); } if ($tracker->isDebugModeEnabled()) { Common::printDebug($_COOKIE); Common::printDebug((string) $this->timer); } }
public function writeDebugInfo() { parent::writeDebugInfo(); if ($this->detectActionIsOutlinkOnAliasHost($this, $this->request->getIdSite())) { Common::printDebug("INFO: The outlink URL host is one of the known host for this website. "); } }
public function outputResponse(Tracker $tracker) { if (!$tracker->shouldRecordStatistics()) { $this->outputApiResponse($tracker); Common::printDebug("Logging disabled, display transparent logo"); } elseif (!$tracker->hasLoggedRequests()) { if (!$this->isHttpGetRequest() || !empty($_GET) || !empty($_POST)) { Common::sendResponseCode(400); } Common::printDebug("Empty request => Piwik page"); //echo date('Y-m-d H:i:s'); } else { $this->outputApiResponse($tracker); Common::printDebug("Nothing to notice => default behaviour"); } Common::printDebug("End of the page."); if ($tracker->isDebugModeEnabled() && $tracker->isDatabaseConnected() && TrackerDb::isProfilingEnabled()) { $db = Tracker::getDatabase(); $db->recordProfiling(); Profiler::displayDbTrackerProfile($db); } if ($tracker->isDebugModeEnabled()) { Common::printDebug($_COOKIE); Common::printDebug((string) $this->timer); } }
public function writeDebugInfo() { $write = parent::writeDebugInfo(); if ($write) { Common::printDebug("Event Value = " . $this->getCustomFloatValue()); } return $write; }
public function writeDebugInfo() { $write = parent::writeDebugInfo(); if ($write) { Common::printDebug("Event Category = " . $this->eventCategory . ",\n Event Action = " . $this->eventAction . ",\n Event Name = " . $this->eventName . ",\n Event Value = " . $this->getCustomFloatValue()); } return $write; }
public function processRequestParams(VisitProperties $visitProperties, Request $request) { // TODO: re-add optimization where if custom variables exist in request, don't bother selecting them in Visitor $visitorCustomVariables = $request->getCustomVariables($scope = 'visit'); if (!empty($visitorCustomVariables)) { Common::printDebug("Visit level Custom Variables: "); Common::printDebug($visitorCustomVariables); } $request->setMetadata('CustomVariables', 'visitCustomVariables', $visitorCustomVariables); }
/** * Hook on Tracker.Visit.setVisitorIp to anomymize visitor IP addresses */ public function setVisitorIpAddress(&$ip) { if (!$this->isActiveInTracker()) { Common::printDebug("Visitor IP was _not_ anonymized: " . IP::N2P($ip)); return; } $originalIp = $ip; $ip = self::applyIPMask($ip, Config::getInstance()->Tracker['ip_address_mask_length']); Common::printDebug("Visitor IP (was: " . IP::N2P($originalIp) . ") has been anonymized: " . IP::N2P($ip)); }
/** * Hook on Tracker.Visit.setVisitorIp to anomymize visitor IP addresses */ public function setVisitorIpAddress(&$ip) { if (!$this->isActive()) { Common::printDebug("Visitor IP was _not_ anonymized: " . IP::N2P($ip)); return; } $originalIp = $ip; $privacyConfig = new Config(); $ip = self::applyIPMask($ip, $privacyConfig->ipAddressMaskLength); Common::printDebug("Visitor IP (was: " . IP::N2P($originalIp) . ") has been anonymized: " . IP::N2P($ip)); }
private static function insertNewIdsAction($actionsNameAndType, $fieldNamesToInsert) { // Then, we insert all new actions in the lookup table $inserted = array(); foreach ($fieldNamesToInsert as $fieldName) { list($name, $type, $urlPrefix) = $actionsNameAndType[$fieldName]; $actionId = self::getModel()->createNewIdAction($name, $type, $urlPrefix); Common::printDebug("Recorded a new action (" . Action::getTypeAsString($type) . ") in the lookup table: " . $name . " (idaction = " . $actionId . ")"); $inserted[$fieldName] = $actionId; } return $inserted; }
/** * Hook on Tracker.Visit.setVisitorIp to anomymize visitor IP addresses * @param string $ip IP address in binary format (network format) */ public function setVisitorIpAddress(&$ip) { $ipObject = IP::fromBinaryIP($ip); if (!$this->isActive()) { Common::printDebug("Visitor IP was _not_ anonymized: " . $ipObject->toString()); return; } $privacyConfig = new Config(); $newIpObject = self::applyIPMask($ipObject, $privacyConfig->ipAddressMaskLength); $ip = $newIpObject->toBinary(); Common::printDebug("Visitor IP (was: " . $ipObject->toString() . ") has been anonymized: " . $newIpObject->toString()); }
public function onException(Tracker $tracker, RequestSet $requestSet, Exception $e) { Common::printDebug("Exception: " . $e->getMessage()); $statusCode = 500; if ($e instanceof UnexpectedWebsiteFoundException) { $statusCode = 400; } elseif ($e instanceof InvalidRequestParameterException) { $statusCode = 400; } $this->response->outputException($tracker, $e, $statusCode); $this->redirectIfNeeded($requestSet); }
/** * If we should create a new visit when the campaign changes, check if the campaign info changed and if so * force the tracker to create a new visit.i * * @param Request $request * @param Visitor $visitor * @param Action|null $action * @return bool */ public function shouldForceNewVisit(Request $request, Visitor $visitor, Action $action = null) { if (!$this->createNewVisitWhenCampaignChanges) { return false; } $information = $this->getReferrerInformationFromRequest($request, $visitor); if ($information['referer_type'] == Common::REFERRER_TYPE_CAMPAIGN && $this->isReferrerInformationNew($visitor, $information)) { Common::printDebug("Existing visit detected, but creating new visit because campaign information is different than last action."); return true; } return false; }
/** * Check if the request is from a known spammer host. * * @param Request $request * @return bool */ public function isSpam(Request $request) { $spammers = $this->getSpammerListFromCache(); $referrerUrl = $request->getParam('urlref'); foreach ($spammers as $spammerHost) { if (stripos($referrerUrl, $spammerHost) !== false) { Common::printDebug('Referrer URL is a known spam: ' . $spammerHost); return true; } } return false; }
private function processQueue(Queue\Manager $queueManager) { Common::printDebug('We are going to process the queue'); set_time_limit(0); try { $processor = new Processor($queueManager); $processor->process(); } catch (Exception $e) { Common::printDebug('Failed to process queue: ' . $e->getMessage()); // TODO how could we report errors better as the response is already sent? also monitoring ... } $queueManager->unlock(); }
/** * This methods tries to see if the visitor has visited the website before. * * We have to split the visitor into one of the category * - Known visitor * - New visitor */ public function recognize() { $this->setIsVisitorKnown(false); $configId = $this->configId; $idSite = $this->request->getIdSite(); $idVisitor = $this->request->getVisitorId(); $isVisitorIdToLookup = !empty($idVisitor); if ($isVisitorIdToLookup) { $this->visitorInfo['idvisitor'] = $idVisitor; Common::printDebug("Matching visitors with: visitorId=" . bin2hex($idVisitor) . " OR configId=" . bin2hex($configId)); } else { Common::printDebug("Visitor doesn't have the piwik cookie..."); } $numCustomVarsToRead = 0; if (!$this->customVariables) { // No custom var were found in the request, so let's copy the previous one in a potential conversion later $numCustomVarsToRead = CustomVariables::getMaxCustomVariables(); } $persistedVisitAttributes = $this->getVisitFieldsPersist(); $shouldMatchOneFieldOnly = $this->shouldLookupOneVisitorFieldOnly($isVisitorIdToLookup); list($timeLookBack, $timeLookAhead) = $this->getWindowLookupThisVisit(); $model = $this->getModel(); $visitRow = $model->findVisitor($idSite, $configId, $idVisitor, $persistedVisitAttributes, $numCustomVarsToRead, $shouldMatchOneFieldOnly, $isVisitorIdToLookup, $timeLookBack, $timeLookAhead); $isNewVisitForced = $this->request->getParam('new_visit'); $isNewVisitForced = !empty($isNewVisitForced); $enforceNewVisit = $isNewVisitForced || Config::getInstance()->Debug['tracker_always_new_visitor']; if (!$enforceNewVisit && $visitRow && count($visitRow) > 0) { // These values will be used throughout the request foreach ($persistedVisitAttributes as $field) { $this->visitorInfo[$field] = $visitRow[$field]; } $this->visitorInfo['visit_last_action_time'] = strtotime($visitRow['visit_last_action_time']); $this->visitorInfo['visit_first_action_time'] = strtotime($visitRow['visit_first_action_time']); // Custom Variables copied from Visit in potential later conversion if (!empty($numCustomVarsToRead)) { for ($i = 1; $i <= $numCustomVarsToRead; $i++) { if (isset($visitRow['custom_var_k' . $i]) && strlen($visitRow['custom_var_k' . $i])) { $this->visitorInfo['custom_var_k' . $i] = $visitRow['custom_var_k' . $i]; } if (isset($visitRow['custom_var_v' . $i]) && strlen($visitRow['custom_var_v' . $i])) { $this->visitorInfo['custom_var_v' . $i] = $visitRow['custom_var_v' . $i]; } } } $this->setIsVisitorKnown(true); Common::printDebug("The visitor is known (idvisitor = " . bin2hex($this->visitorInfo['idvisitor']) . ",\n config_id = " . bin2hex($configId) . ",\n idvisit = {$this->visitorInfo['idvisit']},\n last action = " . date("r", $this->visitorInfo['visit_last_action_time']) . ",\n first action = " . date("r", $this->visitorInfo['visit_first_action_time']) . ",\n visit_goal_buyer' = " . $this->visitorInfo['visit_goal_buyer'] . ")"); } else { Common::printDebug("The visitor was not matched with an existing visitor..."); } }
public function afterRequestProcessed(VisitProperties $visitProperties, Request $request) { $action = $request->getMetadata('Actions', 'action'); if (empty($action) || !$action instanceof Action) { return; } $customVariables = $action->getCustomVariables(); if (!empty($customVariables)) { Common::printDebug("Page level Custom Variables: "); Common::printDebug($customVariables); foreach ($customVariables as $field => $value) { $action->setCustomField($field, $value); } } }
private function getSpammerListFromCache() { $cache = Cache::getEagerCache(); $cacheId = 'ReferrerSpamFilter-' . self::OPTION_STORAGE_NAME; if ($cache->contains($cacheId)) { $list = $cache->fetch($cacheId); } else { $list = $this->loadSpammerList(); $cache->save($cacheId, $list); } if (!is_array($list)) { Common::printDebug('Warning: could not read list of spammers from cache.'); return array(); } return $list; }
public function afterRequestProcessed(VisitProperties $visitProperties, Request $request) { if ($this->isPingRequest($request)) { // on a ping request that is received before the standard visit length, we just update the visit time w/o adding a new action Common::printDebug("-> ping=1 request: we do not track a new action nor a new visit nor any goal."); $request->setMetadata('Actions', 'action', null); $request->setMetadata('Goals', 'goalsConverted', array()); $request->setMetadata('Goals', 'visitIsConverted', false); // When a ping request is received more than 30 min after the last request/ping, // we choose not to create a new visit. if ($request->getMetadata('CoreHome', 'isNewVisit')) { Common::printDebug("-> ping=1 request: we do _not_ create a new visit."); return true; // abort request } } return false; }
/** * @return bool */ public function isDoNotTrackFound() { if (!$this->isActive()) { Common::printDebug("DoNotTrack support is not enabled, skip check"); return false; } if (!$this->isHeaderDntFound()) { Common::printDebug("DoNotTrack header not found"); return false; } $request = new Request($_REQUEST); $userAgent = $request->getUserAgent(); if ($this->isUserAgentWithDoNotTrackAlwaysEnabled($userAgent)) { Common::printDebug("INTERNET EXPLORER enable DoNotTrack by default; so Piwik ignores DNT IE browsers..."); return false; } Common::printDebug("DoNotTrack header found!"); return true; }
public function processRequestParams(VisitProperties $visitProperties, Request $request) { $this->goalManager = new GoalManager(); if ($this->isManualGoalConversion($request)) { // this request is from the JS call to piwikTracker.trackGoal() $goal = $this->goalManager->detectGoalId($request->getIdSite(), $request); $visitIsConverted = !empty($goal); $request->setMetadata('Goals', 'visitIsConverted', $visitIsConverted); $existingConvertedGoals = $request->getMetadata('Goals', 'goalsConverted') ?: array(); $request->setMetadata('Goals', 'goalsConverted', array_merge($existingConvertedGoals, array($goal))); $request->setMetadata('Actions', 'action', null); // don't track actions when doing manual goal conversions // if we find a idgoal in the URL, but then the goal is not valid, this is most likely a fake request if (!$visitIsConverted) { $idGoal = $request->getParam('idgoal'); Common::printDebug('Invalid goal tracking request for goal id = ' . $idGoal); return true; } } return false; }
public function expireLock($ttlInSeconds) { if ($ttlInSeconds > 0 && $this->lockValue) { $success = $this->backend->expireIfKeyHasValue($this->lockKey, $this->lockValue, $ttlInSeconds); if (!$success) { $value = $this->backend->get($this->lockKey); $message = sprintf('Failed to expire key %s (%s / %s).', $this->lockKey, $this->lockValue, (string) $value); if ($value === false) { Common::printDebug($message . ' It seems like the key already expired as it no longer exists.'); } elseif (!empty($value) && $value == $this->lockValue) { Common::printDebug($message . ' We still have the lock but for some reason it did not expire.'); } elseif (!empty($value)) { Common::printDebug($message . ' It seems to be locked by another queue.'); } else { Common::printDebug($message . ' Failed to expire key.'); } return false; } return true; } return false; }
/** * Checks for DoNotTrack headers and if found, sets `$exclude` to `true`. */ public function checkHeaderInTracker(&$exclude) { if (!$this->isActiveInTracker() || $exclude) { return; } if (isset($_SERVER['HTTP_X_DO_NOT_TRACK']) && $_SERVER['HTTP_X_DO_NOT_TRACK'] === '1' || isset($_SERVER['HTTP_DNT']) && substr($_SERVER['HTTP_DNT'], 0, 1) === '1') { $request = new Request($_REQUEST); $ua = $request->getUserAgent(); if (strpos($ua, 'MSIE 10') !== false || strpos($ua, 'Trident/7') !== false) { Common::printDebug("INTERNET EXPLORER 10 and 11 enable DoNotTrack by default; so Piwik ignores DNT for all IE10 + IE11 browsers..."); return; } $exclude = true; Common::printDebug("DoNotTrack found."); $trackingCookie = IgnoreCookie::getTrackingCookie(); $trackingCookie->delete(); // this is an optional supplement to the site's tracking status resource at: // /.well-known/dnt // per Tracking Preference Expression (draft) header('Tk: 1'); } }
/** * @param $params * @param $tokenAuth * @return array */ protected function trackRequest($params, $tokenAuth) { if ($params instanceof Request) { $request = $params; } else { $request = new Request($params, $tokenAuth); } $this->init($request); $isAuthenticated = $request->isAuthenticated(); try { if ($this->isVisitValid()) { $request->setForceDateTime(self::$forcedDateTime); $request->setForceIp(self::$forcedIpString); $visit = $this->getNewVisitObject(); $visit->setRequest($request); $visit->handle(); } else { Common::printDebug("The request is invalid: empty request, or maybe tracking is disabled in the config.ini.php via record_statistics=0"); } } catch (DbException $e) { Common::printDebug("Exception: " . $e->getMessage()); $this->exitWithException($e, $isAuthenticated); } catch (Exception $e) { $this->exitWithException($e, $isAuthenticated); } $this->clear(); // increment successfully logged request count. make sure to do this after try-catch, // since an excluded visit is considered 'successfully logged' ++$this->countOfLoggedRequests; return $isAuthenticated; }