isInstalled(); } public static function loadTrackerEnvironment() { SettingsServer::setIsTrackerApiRequest(); try { $debug = (bool)TrackerConfig::getConfigValue('debug'); } catch(Exception $e) { $debug = false; } $GLOBALS['PIWIK_TRACKER_DEBUG'] = $debug; PluginManager::getInstance()->loadTrackerPlugins(); } private function init() { $this->handleFatalErrors(); \Piwik\FrontController::createConfigObject(); if ($this->isDebugModeEnabled()) { ErrorHandler::registerErrorHandler(); ExceptionHandler::setUp(); Common::printDebug("Debug enabled - Input parameters: "); Common::printDebug(var_export($_GET, true)); } } public function isInstalled() { if (is_null($this->isInstalled)) { $this->isInstalled = SettingsPiwik::isPiwikInstalled(); } return $this->isInstalled; } public function main(Handler $handler, RequestSet $requestSet) { try { $this->init(); $handler->init($this, $requestSet); $this->track($handler, $requestSet); } catch (Exception $e) { $handler->onException($this, $requestSet, $e); } Piwik::postEvent('Tracker.end'); $response = $handler->finish($this, $requestSet); $this->disconnectDatabase(); return $response; } public function track(Handler $handler, RequestSet $requestSet) { if (!$this->shouldRecordStatistics()) { return; } $requestSet->initRequestsAndTokenAuth(); if ($requestSet->hasRequests()) { $handler->onStartTrackRequests($this, $requestSet); $handler->process($this, $requestSet); $handler->onAllRequestsTracked($this, $requestSet); } } /** * @param Request $request * @return array */ public function trackRequest(Request $request) { if ($request->isEmptyRequest()) { Common::printDebug("The request is empty"); } else { $this->loadTrackerPlugins(); Common::printDebug("Current datetime: " . date("Y-m-d H:i:s", $request->getCurrentTimestamp())); $visit = Visit\Factory::make(); $visit->setRequest($request); $visit->handle(); } // increment successfully logged request count. make sure to do this after try-catch, // since an excluded visit is considered 'successfully logged' ++$this->countOfLoggedRequests; } /** * Used to initialize core Piwik components on a piwik.php request * Eg. when cache is missed and we will be calling some APIs to generate cache */ public static function initCorePiwikInTrackerMode() { if (SettingsServer::isTrackerApiRequest() && self::$initTrackerMode === false ) { self::$initTrackerMode = true; require_once PIWIK_INCLUDE_PATH . '/core/Option.php'; Access::getInstance(); Config::getInstance(); try { Db::get(); } catch (Exception $e) { Db::createDatabaseObject(); } PluginManager::getInstance()->loadCorePluginsDuringTracker(); } } public function getCountOfLoggedRequests() { return $this->countOfLoggedRequests; } public function setCountOfLoggedRequests($numLoggedRequests) { $this->countOfLoggedRequests = $numLoggedRequests; } public function hasLoggedRequests() { return 0 !== $this->countOfLoggedRequests; } /** * @deprecated since 2.10.0 use {@link Date::getDatetimeFromTimestamp()} instead */ public static function getDatetimeFromTimestamp($timestamp) { return Date::getDatetimeFromTimestamp($timestamp); } public function isDatabaseConnected() { return !is_null(self::$db); } public static function getDatabase() { if (is_null(self::$db)) { try { self::$db = TrackerDb::connectPiwikTrackerDb(); } catch (Exception $e) { throw new DbException($e->getMessage(), $e->getCode()); } } return self::$db; } protected function disconnectDatabase() { if ($this->isDatabaseConnected()) { // note: I think we do this only for the tests self::$db->disconnect(); self::$db = null; } } public static function setTestEnvironment($args = null, $requestMethod = null) { if (is_null($args)) { $requests = new Requests(); $args = $requests->getRequestsArrayFromBulkRequest($requests->getRawBulkRequest()); $args = $_GET + $args; } if (is_null($requestMethod) && array_key_exists('REQUEST_METHOD', $_SERVER)) { $requestMethod = $_SERVER['REQUEST_METHOD']; } else if (is_null($requestMethod)) { $requestMethod = 'GET'; } // Do not run scheduled tasks during tests TrackerConfig::setConfigValue('scheduled_tasks_min_interval', 0); // if nothing found in _GET/_POST and we're doing a POST, assume bulk request. in which case, // we have to bypass authentication if (empty($args) && $requestMethod == 'POST') { TrackerConfig::setConfigValue('tracking_requests_require_authentication', 0); } // Tests can force the use of 3rd party cookie for ID visitor if (Common::getRequestVar('forceEnableFingerprintingAcrossWebsites', false, null, $args) == 1) { TrackerConfig::setConfigValue('enable_fingerprinting_across_websites', 1); } // Tests can force the use of 3rd party cookie for ID visitor if (Common::getRequestVar('forceUseThirdPartyCookie', false, null, $args) == 1) { TrackerConfig::setConfigValue('use_third_party_id_cookie', 1); } // Tests using window_look_back_for_visitor if (Common::getRequestVar('forceLargeWindowLookBackForVisitor', false, null, $args) == 1 // also look for this in bulk requests (see fake_logs_replay.log) || strpos(json_encode($args, true), '"forceLargeWindowLookBackForVisitor":"1"') !== false ) { TrackerConfig::setConfigValue('window_look_back_for_visitor', 2678400); } // Tests can force the enabling of IP anonymization if (Common::getRequestVar('forceIpAnonymization', false, null, $args) == 1) { self::getDatabase(); // make sure db is initialized $privacyConfig = new PrivacyManagerConfig(); $privacyConfig->ipAddressMaskLength = 2; \Piwik\Plugins\PrivacyManager\IPAnonymizer::activate(); } $pluginsDisabled = array('Provider'); // Disable provider plugin, because it is so slow to do many reverse ip lookups PluginManager::getInstance()->setTrackerPluginsNotToLoad($pluginsDisabled); } protected function loadTrackerPlugins() { try { $pluginManager = PluginManager::getInstance(); $pluginsTracker = $pluginManager->loadTrackerPlugins(); Common::printDebug("Loading plugins: { " . implode(", ", $pluginsTracker) . " }"); } catch (Exception $e) { Common::printDebug("ERROR: " . $e->getMessage()); } } private function handleFatalErrors() { register_shutdown_function(function () { $lastError = error_get_last(); if (!empty($lastError) && $lastError['type'] == E_ERROR) { Common::sendResponseCode(500); } }); } }