Skip to content
Extraits de code Groupes Projets
Tracker.php 10,3 ko
Newer Older
  • Learn to ignore specific revisions
  •  * Piwik - free/libre analytics platform
    
    robocoder's avatar
    robocoder a validé
     * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
    
    Thomas Steur's avatar
    Thomas Steur a validé
    use Piwik\Plugins\BulkTracking\Tracker\Requests;
    
    use Piwik\Plugins\PrivacyManager\Config as PrivacyManagerConfig;
    
    Thomas Steur's avatar
    Thomas Steur a validé
    use Piwik\Tracker\Db as TrackerDb;
    
    use Piwik\Tracker\Db\DbException;
    
    Thomas Steur's avatar
    Thomas Steur a validé
    use Piwik\Tracker\Handler;
    
    use Piwik\Tracker\Request;
    
    Thomas Steur's avatar
    Thomas Steur a validé
    use Piwik\Tracker\RequestSet;
    use Piwik\Tracker\TrackerConfig;
    
    use Piwik\Tracker\Visit;
    
    Thomas Steur's avatar
    Thomas Steur a validé
    use Piwik\Plugin\Manager as PluginManager;
    
    
    /**
     * Class used by the logging script piwik.php called by the javascript tag.
    
     * Handles the visitor & his/her actions on the website, saves the data in the DB,
    
     * saves information in the cookie, etc.
    
     * We try to include as little files as possible (no dependency on 3rd party modules).
    
    Thomas Steur's avatar
    Thomas Steur a validé
        private static $db = null;
    
    
        // We use hex ID that are 16 chars in length, ie. 64 bits IDs
        const LENGTH_HEX_ID_STRING = 16;
        const LENGTH_BINARY_ID = 8;
    
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public static $initTrackerMode = false;
    
    
        private $countOfLoggedRequests = 0;
    
    Thomas Steur's avatar
    Thomas Steur a validé
        protected $isInstalled = null;
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function isDebugModeEnabled()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return array_key_exists('PIWIK_TRACKER_DEBUG', $GLOBALS) && $GLOBALS['PIWIK_TRACKER_DEBUG'] === true;
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function shouldRecordStatistics()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            $record = TrackerConfig::getConfigValue('record_statistics') != 0;
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if (!$record) {
                Common::printDebug('Tracking is disabled in the config.ini.php via record_statistics=0');
            }
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return $record && $this->isInstalled();
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public static function loadTrackerEnvironment()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            SettingsServer::setIsTrackerApiRequest();
    
    Matthieu Napoli's avatar
    Matthieu Napoli a validé
            $GLOBALS['PIWIK_TRACKER_DEBUG'] = self::isDebugEnabled();
    
    Thomas Steur's avatar
    Thomas Steur a validé
            PluginManager::getInstance()->loadTrackerPlugins();
    
    Thomas Steur's avatar
    Thomas Steur a validé
        private function init()
    
            $this->handleFatalErrors();
    
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if ($this->isDebugModeEnabled()) {
    
    mattab's avatar
    mattab a validé
                ErrorHandler::registerErrorHandler();
    
    Thomas Steur's avatar
    Thomas Steur a validé
                ExceptionHandler::setUp();
    
    Thomas Steur's avatar
    Thomas Steur a validé
                Common::printDebug("Debug enabled - Input parameters: ");
                Common::printDebug(var_export($_GET, true));
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function isInstalled()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if (is_null($this->isInstalled)) {
                $this->isInstalled = SettingsPiwik::isPiwikInstalled();
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return $this->isInstalled;
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function main(Handler $handler, RequestSet $requestSet)
    
    Thomas Steur's avatar
    Thomas Steur a validé
                $this->init();
                $handler->init($this, $requestSet);
                $this->track($handler, $requestSet);
            } catch (Exception $e) {
                $handler->onException($this, $requestSet, $e);
    
    Thomas Steur's avatar
    Thomas Steur a validé
            $response = $handler->finish($this, $requestSet);
    
    Thomas Steur's avatar
    Thomas Steur a validé
            $this->disconnectDatabase();
    
    mattab's avatar
    mattab a validé
    
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return $response;
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function track(Handler $handler, RequestSet $requestSet)
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if (!$this->shouldRecordStatistics()) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
            $requestSet->initRequestsAndTokenAuth();
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if ($requestSet->hasRequests()) {
                $handler->onStartTrackRequests($this, $requestSet);
                $handler->process($this, $requestSet);
                $handler->onAllRequestsTracked($this, $requestSet);
    
    Thomas Steur's avatar
    Thomas Steur a validé
         * @param Request $request
         * @return array
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function trackRequest(Request $request)
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if ($request->isEmptyRequest()) {
                Common::printDebug("The request is empty");
            } else {
                Common::printDebug("Current datetime: " . date("Y-m-d H:i:s", $request->getCurrentTimestamp()));
    
    Thomas Steur's avatar
    Thomas Steur a validé
                $visit = Visit\Factory::make();
                $visit->setRequest($request);
                $visit->handle();
    
    Thomas Steur's avatar
    Thomas Steur a validé
            // increment successfully logged request count. make sure to do this after try-catch,
            // since an excluded visit is considered 'successfully logged'
            ++$this->countOfLoggedRequests;
    
    sgiehl's avatar
    sgiehl a validé
        /**
    
         * 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
         */
    
    Christian Raue's avatar
    Christian Raue a validé
        public static function initCorePiwikInTrackerMode()
    
                && self::$initTrackerMode === false
            ) {
                self::$initTrackerMode = true;
                require_once PIWIK_INCLUDE_PATH . '/core/Option.php';
    
    Christian Raue's avatar
    Christian Raue a validé
                Access::getInstance();
                Config::getInstance();
    
                    Db::createDatabaseObject();
    
    Thomas Steur's avatar
    Thomas Steur a validé
                PluginManager::getInstance()->loadCorePluginsDuringTracker();
    
        public static function restoreTrackerPlugins()
        {
            if (SettingsServer::isTrackerApiRequest() && Tracker::$initTrackerMode) {
                Plugin\Manager::getInstance()->loadTrackerPlugins();
            }
        }
    
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function getCountOfLoggedRequests()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return $this->countOfLoggedRequests;
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function setCountOfLoggedRequests($numLoggedRequests)
    
    Thomas Steur's avatar
    Thomas Steur a validé
            $this->countOfLoggedRequests = $numLoggedRequests;
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function hasLoggedRequests()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return 0 !== $this->countOfLoggedRequests;
    
    Thomas Steur's avatar
    Thomas Steur a validé
         * @deprecated since 2.10.0 use {@link Date::getDatetimeFromTimestamp()} instead
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public static function getDatetimeFromTimestamp($timestamp)
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return Date::getDatetimeFromTimestamp($timestamp);
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public function isDatabaseConnected()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            return !is_null(self::$db);
    
    Thomas Steur's avatar
    Thomas Steur a validé
        public static function getDatabase()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if (is_null(self::$db)) {
                try {
                    self::$db = TrackerDb::connectPiwikTrackerDb();
                } catch (Exception $e) {
                    throw new DbException($e->getMessage(), $e->getCode());
                }
    
    Thomas Steur's avatar
    Thomas Steur a validé
        protected function disconnectDatabase()
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if ($this->isDatabaseConnected()) { // note: I think we do this only for the tests
    
        // for tests
        public static function disconnectCachedDbConnection()
        {
            // code redundancy w/ above is on purpose; above disconnectDatabase depends on method that can potentially be overridden
    
            if (!is_null(self::$db)) {
    
        public static function setTestEnvironment($args = null, $requestMethod = null)
        {
            if (is_null($args)) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                $requests = new Requests();
                $args     = $requests->getRequestsArrayFromBulkRequest($requests->getRawBulkRequest());
                $args = $_GET + $args;
    
    Thomas Steur's avatar
    Thomas Steur a validé
    
    
    Thomas Steur's avatar
    Thomas Steur a validé
            if (is_null($requestMethod) && array_key_exists('REQUEST_METHOD', $_SERVER)) {
    
                $requestMethod = $_SERVER['REQUEST_METHOD'];
    
            } elseif (is_null($requestMethod)) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                $requestMethod = 'GET';
    
            }
    
            // Do not run scheduled tasks during tests
    
            if (!defined('DEBUG_FORCE_SCHEDULED_TASKS')) {
                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') {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                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) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                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
            ) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                TrackerConfig::setConfigValue('window_look_back_for_visitor', 2678400);
    
            // Tests can force the enabling of IP anonymization
    
            if (Common::getRequestVar('forceIpAnonymization', false, null, $args) == 1) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                self::getDatabase(); // make sure db is initialized
    
    
                $privacyConfig = new PrivacyManagerConfig();
                $privacyConfig->ipAddressMaskLength = 2;
    
                \Piwik\Plugins\PrivacyManager\IPAnonymizer::activate();
    
    
                \Piwik\Tracker\Cache::deleteTrackerCache();
                Filesystem::clearPhpCaches();
    
            // Disable provider plugin, because it is so slow to do many reverse ip lookups
    
    Thomas Steur's avatar
    Thomas Steur a validé
            PluginManager::getInstance()->setTrackerPluginsNotToLoad($pluginsDisabled);
    
    Thomas Steur's avatar
    Thomas Steur a validé
        protected function loadTrackerPlugins()
    
    Thomas Steur's avatar
    Thomas Steur a validé
                $pluginManager  = PluginManager::getInstance();
                $pluginsTracker = $pluginManager->loadTrackerPlugins();
                Common::printDebug("Loading plugins: { " . implode(", ", $pluginsTracker) . " }");
    
            } catch (Exception $e) {
    
    Thomas Steur's avatar
    Thomas Steur a validé
                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);
                }
            });
        }
    
    Matthieu Napoli's avatar
    Matthieu Napoli a validé
    
        private static function isDebugEnabled()
        {
            try {
                $debug = (bool) TrackerConfig::getConfigValue('debug');
                if ($debug) {
                    return true;
                }
    
                $debugOnDemand = (bool) TrackerConfig::getConfigValue('debug_on_demand');
                if ($debugOnDemand) {
                    return (bool) Common::getRequestVar('debug', false);
                }
    
            } catch (Exception $e) {
    
    Matthieu Napoli's avatar
    Matthieu Napoli a validé
            }
    
            return false;
        }