Example #1
0
 protected function sendRequest($url, $method = 'GET', $data = null, $force = false)
 {
     // if doing a bulk request, store the url
     if ($this->doBulkRequests && !$force) {
         $this->storedTrackingActions[] = $url;
         return true;
     }
     if ($method == 'POST') {
         $requests = array();
         foreach ($this->storedTrackingActions as $action) {
             $requests[] = $this->parseUrl($action);
         }
         $testEnvironmentArgs = array();
     } else {
         $testEnvironmentArgs = $this->parseUrl($url);
         $requests = array($testEnvironmentArgs);
     }
     // unset cached values
     Piwik_Common::$trackerCache = null;
     Piwik_Tracker::setForceIp(null);
     Piwik_Tracker::setForceDateTime(null);
     Piwik_Tracker::setForceVisitorId(null);
     // save some values
     $plugins = Piwik_Config::getInstance()->Plugins['Plugins'];
     $pluginsTracker = Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker'];
     $oldTrackerConfig = Piwik_Config::getInstance()->Tracker;
     Piwik_PluginsManager::getInstance()->unloadPlugins();
     // modify config
     $GLOBALS['PIWIK_TRACKER_MODE'] = true;
     $GLOBALS['PIWIK_TRACKER_LOCAL_TRACKING'] = true;
     Piwik_Common::$initTrackerMode = false;
     Piwik_Tracker::setTestEnvironment($testEnvironmentArgs, $method);
     // set language
     $oldLang = isset($_SERVER['HTTP_ACCEPT_LANGUAGE']) ? $_SERVER['HTTP_ACCEPT_LANGUAGE'] : '';
     $_SERVER['HTTP_ACCEPT_LANGUAGE'] = $this->acceptLanguage;
     // set user agent
     $oldUserAgent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '';
     $_SERVER['HTTP_USER_AGENT'] = $this->userAgent;
     // set cookie
     $oldCookie = $_COOKIE;
     parse_str(parse_url($this->requestCookie, PHP_URL_QUERY), $_COOKIE);
     // do tracking and capture output
     ob_start();
     $localTracker = new Piwik_Tracker();
     $localTracker->main($requests);
     $output = ob_get_contents();
     ob_end_clean();
     // restore vars
     Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker'] = $pluginsTracker;
     Piwik_Config::getInstance()->Tracker = $oldTrackerConfig;
     $_SERVER['HTTP_ACCEPT_LANGUAGE'] = $oldLang;
     $_SERVER['HTTP_USER_AGENT'] = $oldUserAgent;
     $_COOKIE = $oldCookie;
     $GLOBALS['PIWIK_TRACKER_LOCAL_TRACKING'] = false;
     $GLOBALS['PIWIK_TRACKER_MODE'] = false;
     unset($_GET['bots']);
     // reload plugins
     Piwik_PluginsManager::getInstance()->loadPlugins($plugins);
     return $output;
 }
Example #2
0
 /**
  * Returns array containing data about the website: goals, URLs, etc.
  *
  * @param int $idSite
  * @return array
  */
 static function getCacheWebsiteAttributes($idSite)
 {
     require_once PIWIK_INCLUDE_PATH . '/core/Loader.php';
     static $cache = null;
     if (is_null($cache)) {
         $cache = new Piwik_CacheFile('tracker');
     }
     $filename = $idSite;
     $cacheContent = $cache->get($filename);
     if ($cacheContent !== false) {
         return $cacheContent;
     }
     if (defined('PIWIK_TRACKER_MODE') && PIWIK_TRACKER_MODE) {
         require_once PIWIK_INCLUDE_PATH . '/core/PluginsManager.php';
         require_once PIWIK_INCLUDE_PATH . '/core/Translate.php';
         require_once PIWIK_INCLUDE_PATH . '/core/Option.php';
         Zend_Registry::set('db', Piwik_Tracker::getDatabase());
         Piwik::createAccessObject();
         Piwik::createConfigObject();
         Piwik::setUserIsSuperUser();
         $pluginsManager = Piwik_PluginsManager::getInstance();
         $pluginsManager->setPluginsToLoad(Zend_Registry::get('config')->Plugins->Plugins->toArray());
     }
     $content = array();
     Piwik_PostEvent('Common.fetchWebsiteAttributes', $content, $idSite);
     // if nothing is returned from the plugins, we don't save the content
     // this is not expected: all websites are expected to have at least one URL
     if (!empty($content)) {
         $cache->set($filename, $content);
     }
     return $content;
 }
Example #3
0
 /**
  * Returns the database adapter to use
  *
  * @return Piwik_Tracker_Db|Piwik_Db_Adapter_Interface
  */
 private static function getDb()
 {
     $db = null;
     if (!empty($GLOBALS['PIWIK_TRACKER_MODE'])) {
         $db = Piwik_Tracker::getDatabase();
     }
     if ($db === null) {
         $db = Zend_Registry::get('db');
     }
     return $db;
 }
Example #4
0
 function recordFunnelSteps($notification)
 {
     $info = $notification->getNotificationInfo();
     $idSite = $info['idSite'];
     printDebug('Looking for funnel steps');
     $websiteAttributes = Piwik_Common::getCacheWebsiteAttributes($idSite);
     if (isset($websiteAttributes['funnels'])) {
         $funnels = $websiteAttributes['funnels'];
         printDebug('got funnel steps');
     } else {
         $funnels = array();
     }
     if (count($funnels) > 0) {
         $idVisit = $info['idVisit'];
         $idLinkVisitAction = $info['idLinkVisitAction'];
         $idRefererAction = $info['idRefererAction'];
         $action = $notification->getNotificationObject();
         $actionName = $action->getActionName();
         $sanitizedUrl = $action->getActionUrl();
         $actionUrl = htmlspecialchars_decode($sanitizedUrl);
         $idActionUrl = $action->getIdActionUrl();
         $url = Piwik_Common::getRequestVar('url', '', 'string', $action->getRequest());
         printDebug("idActionUrl" . $idActionUrl . " idSite " . $idSite . " idVisit " . $idVisit . " idRefererAction " . $idRefererAction);
         # Is this the next action for a recorded funnel step?
         $previous_step_action = Piwik_Query("UPDATE " . Piwik_Common::prefixTable('log_funnel_step') . "\n                                                 SET   idaction_url_next = ?\n                                                 WHERE idsite = ? \n                                                 AND   idvisit = ? \n                                                 AND   idaction_url = ?\n                                                 AND   idaction_url_next is null", array($idActionUrl, $idSite, $idVisit, $idRefererAction));
     }
     foreach ($funnels as &$funnel) {
         $steps = $funnel['steps'];
         foreach ($steps as &$step) {
             if ($step['url'] == $actionUrl or $step['name'] == $actionName) {
                 printDebug("Matched Goal Funnel " . $funnel['idfunnel'] . " Step " . $step['idstep'] . "(name: " . $step['name'] . ", url: " . $step['url'] . "). ");
                 $serverTime = time();
                 $datetimeServer = Piwik_Tracker::getDatetimeFromTimestamp($serverTime);
                 // Look to see if this step has already been recorded for this visit
                 $exists = Piwik_FetchOne("SELECT idlink_va\n                                           FROM " . Piwik_Common::prefixTable('log_funnel_step') . " \n                                           WHERE idsite = ? \n                                           AND   idfunnel = ?\n                                           AND   idstep = ?\n                                           AND   idvisit = ?", array($idSite, $funnel['idfunnel'], $step['idstep'], $idVisit));
                 // Record it if not
                 if (!$exists) {
                     printDebug("Recording...");
                     Piwik_Query("INSERT INTO " . Piwik_Common::prefixTable('log_funnel_step') . "\n                                 (idvisit, idsite, idaction_url, url, \n                                  idgoal, idfunnel, idstep, idlink_va, \n                                  idaction_url_ref, server_time)\n                                 VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)", array($idVisit, $idSite, $idActionUrl, $url, $funnel['idgoal'], $step['idfunnel'], $step['idstep'], $idLinkVisitAction, $idRefererAction, $datetimeServer));
                 }
             }
         }
     }
 }
Example #5
0
 /**
  * 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
  * 
  * A known visitor is a visitor that has already visited the website in the current month.
  * We define a known visitor using the algorithm:
  * 
  * 1) Checking if a cookie contains
  * 		// a unique id for the visitor
  * 		- id_visitor 
  * 
  * 		// the timestamp of the last action in the most recent visit
  * 		- timestamp_last_action 
  * 
  *  	// the timestamp of the first action in the most recent visit
  * 		- timestamp_first_action
  * 
  * 		// the ID of the most recent visit (which could be in the past or the current visit)
  * 		- id_visit 
  * 
  * 		// the ID of the most recent action
  * 		- id_last_action
  * 
  * 2) If the visitor doesn't have a cookie, we try to look for a similar visitor configuration.
  * 	  We search for a visitor with the same plugins/OS/Browser/Resolution for today for this website.
  */
 protected function recognizeTheVisitor()
 {
     $this->visitorKnown = false;
     $this->setCookie(new Piwik_Cookie($this->getCookieName(), $this->getCookieExpire()));
     /*
      * Case the visitor has the piwik cookie.
      * We make sure all the data that should saved in the cookie is available.
      */
     if (false !== ($idVisitor = $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_IDVISITOR))) {
         $timestampLastAction = $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_TIMESTAMP_LAST_ACTION);
         $timestampFirstAction = $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_TIMESTAMP_FIRST_ACTION);
         $idVisit = $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_ID_VISIT);
         $idLastAction = $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_ID_LAST_ACTION);
         if ($timestampLastAction !== false && is_numeric($timestampLastAction) && $timestampFirstAction !== false && is_numeric($timestampFirstAction) && $idVisit !== false && is_numeric($idVisit) && $idLastAction !== false && is_numeric($idLastAction)) {
             $this->visitorInfo['visitor_idcookie'] = $idVisitor;
             $this->visitorInfo['visit_last_action_time'] = $timestampLastAction;
             $this->visitorInfo['visit_first_action_time'] = $timestampFirstAction;
             $this->visitorInfo['idvisit'] = $idVisit;
             $this->visitorInfo['visit_exit_idaction'] = $idLastAction;
             $this->visitorKnown = true;
             printDebug("The visitor is known because he has the piwik cookie (idcookie = {$this->visitorInfo['visitor_idcookie']}, idvisit = {$this->visitorInfo['idvisit']}, last action = " . date("r", $this->visitorInfo['visit_last_action_time']) . ") ");
         }
     }
     /*
      * If the visitor doesn't have the piwik cookie, we look for a visitor 
      * that has exactly the same configuration and that visited the website today.
      */
     if (!$this->visitorKnown && Piwik_Tracker_Config::getInstance()->Tracker['enable_detect_unique_visitor_using_settings']) {
         $userInfo = $this->getUserSettingsInformation();
         $md5Config = $userInfo['config_md5config'];
         $visitRow = Piwik_Tracker::getDatabase()->fetch(" SELECT  \tvisitor_idcookie, \n\t\t\t\t\t\t\t\t\t\t\t\t\tUNIX_TIMESTAMP(visit_last_action_time) as visit_last_action_time,\n\t\t\t\t\t\t\t\t\t\t\t\t\tUNIX_TIMESTAMP(visit_first_action_time) as visit_first_action_time,\n\t\t\t\t\t\t\t\t\t\t\t\t\tidvisit,\n\t\t\t\t\t\t\t\t\t\t\t\t\tvisit_exit_idaction \n\t\t\t\t\t\t\t\t\t\tFROM " . Piwik_Common::prefixTable('log_visit') . " WHERE visit_server_date = ?\n\t\t\t\t\t\t\t\t\t\t\tAND idsite = ?\n\t\t\t\t\t\t\t\t\t\t\tAND config_md5config = ?\n\t\t\t\t\t\t\t\t\t\tORDER BY visit_last_action_time DESC\n\t\t\t\t\t\t\t\t\t\tLIMIT 1", array($this->getCurrentDate(), $this->idsite, $md5Config));
         if ($visitRow && count($visitRow) > 0) {
             $this->visitorInfo['visitor_idcookie'] = $visitRow['visitor_idcookie'];
             $this->visitorInfo['visit_last_action_time'] = $visitRow['visit_last_action_time'];
             $this->visitorInfo['visit_first_action_time'] = $visitRow['visit_first_action_time'];
             $this->visitorInfo['idvisit'] = $visitRow['idvisit'];
             $this->visitorInfo['visit_exit_idaction'] = $visitRow['visit_exit_idaction'];
             $this->visitorKnown = true;
             printDebug("The visitor is known because of his userSettings+IP (idcookie = {$visitRow['visitor_idcookie']}, idvisit = {$this->visitorInfo['idvisit']}, last action = " . date("r", $this->visitorInfo['visit_last_action_time']) . ") ");
         }
     }
 }
Example #6
0
	/**
	 * Records in the DB the association between the visit and this action.
	 * 
	 * @param int idVisit is the ID of the current visit in the DB table log_visit
	 * @param int idRefererActionUrl is the ID of the last action done by the current visit. 
	 * @param int timeSpentRefererAction is the number of seconds since the last action was done. 
	 * 				It is directly related to idRefererActionUrl.
	 */
	 public function record( $idVisit, $visitorIdCookie, $idRefererActionUrl, $idRefererActionName, $timeSpentRefererAction)
	 {
		$this->loadIdActionNameAndUrl();
		
		$idActionName = in_array($this->getActionType(), array(Piwik_Tracker_Action::TYPE_ACTION_NAME, Piwik_Tracker_Action::TYPE_ACTION_URL))
							? (int)$this->getIdActionName()
							: null;
		$insert = array(
			'idvisit' => $idVisit, 
			'idsite' => $this->idSite, 
			'idvisitor' => $visitorIdCookie, 
			'server_time' => Piwik_Tracker::getDatetimeFromTimestamp($this->timestamp), 
			'idaction_url' => (int)$this->getIdActionUrl(), 
			'idaction_name' => $idActionName, 
			'idaction_url_ref' => $idRefererActionUrl, 
			'idaction_name_ref' => $idRefererActionName, 
			'time_spent_ref_action' => $timeSpentRefererAction
		);
		$customVariables = Piwik_Tracker_Visit::getCustomVariables($scope = 'page', $this->request);
		$insert = array_merge($insert, $customVariables);

		// Mysqli apparently does not like NULL inserts?
		$insertWithoutNulls = array();
		foreach($insert as $column => $value)
		{
			if(!is_null($value))
			{
				$insertWithoutNulls[$column] = $value;
			}
		}
		
		$fields = implode(", ", array_keys($insertWithoutNulls));
		$bind = array_values($insertWithoutNulls);
		$values = Piwik_Common::getSqlStringFieldsArray($insertWithoutNulls);

		$sql = "INSERT INTO ".Piwik_Common::prefixTable('log_link_visit_action'). " ($fields) VALUES ($values)";
		Piwik_Tracker::getDatabase()->query( $sql, $bind ); 
		
		$this->idLinkVisitAction = Piwik_Tracker::getDatabase()->lastInsertId(); 
		
		$info = array( 
			'idSite' => $this->idSite, 
			'idLinkVisitAction' => $this->idLinkVisitAction, 
			'idVisit' => $idVisit, 
			'idRefererActionUrl' => $idRefererActionUrl, 
			'idRefererActionName' => $idRefererActionName, 
			'timeSpentRefererAction' => $timeSpentRefererAction, 
		); 
		printDebug($insertWithoutNulls);

		/* 
		* send the Action object ($this)  and the list of ids ($info) as arguments to the event 
		*/ 
		Piwik_PostEvent('Tracker.Action.record', $this, $info);
	 }
Example #7
0
 /**
  * Print profiling report for the tracker
  *
  * @param Piwik_Tracker_Db $db Tracker database object (or null)
  */
 public static function printSqlProfilingReportTracker($db = null)
 {
     if (!function_exists('maxSumMsFirst')) {
         function maxSumMsFirst($a, $b)
         {
             return $a['sum_time_ms'] < $b['sum_time_ms'];
         }
     }
     if (is_null($db)) {
         $db = Piwik_Tracker::getDatabase();
     }
     $tableName = Piwik_Common::prefixTable('log_profiling');
     $all = $db->fetchAll('SELECT * FROM ' . $tableName);
     if ($all === false) {
         return;
     }
     uasort($all, 'maxSumMsFirst');
     $infoIndexedByQuery = array();
     foreach ($all as $infoQuery) {
         $query = $infoQuery['query'];
         $count = $infoQuery['count'];
         $sum_time_ms = $infoQuery['sum_time_ms'];
         $infoIndexedByQuery[$query] = array('count' => $count, 'sumTimeMs' => $sum_time_ms);
     }
     Piwik::getSqlProfilingQueryBreakdownOutput($infoIndexedByQuery);
 }
Example #8
0
 function doStepMatchAndSave($idSite, $idVisit, $idRefererAction, $actionName = "", $actionUrl = "", $idActionUrl = Piwik_Funnels::INDEX_MANUAL_CONVERSION)
 {
     printDebug('Looking for funnel steps');
     $websiteAttributes = Piwik_Tracker_Cache::getCacheWebsiteAttributes($idSite);
     if (isset($websiteAttributes['funnels'])) {
         $funnels = $websiteAttributes['funnels'];
         printDebug('got funnel steps');
     } else {
         $funnels = array();
     }
     if (count($funnels) <= 0) {
         return;
     }
     printDebug("idActionUrl " . $idActionUrl . " idSite " . $idSite . " idVisit " . $idVisit . " idRefererAction " . $idRefererAction);
     // Is this the next action for a recorded funnel step?
     $previous_step_action = Piwik_Query("UPDATE " . Piwik_Common::prefixTable('log_funnel_step') . "\n            SET   idaction_url_next = ?\n            WHERE idsite = ? \n            AND   idvisit = ? \n            AND   idaction_url = ?\n            AND   idaction_url_next is null", array($idActionUrl, $idSite, $idVisit, $idRefererAction));
     // early out for special case of manual conversion
     // Since this is a manual conversion for a goal, there is no URL to
     // match with, so the following loop is simply a waste of resources
     if ($idActionUrl == Piwik_Funnels::INDEX_MANUAL_CONVERSION) {
         return;
     }
     foreach ($funnels as &$funnel) {
         $steps = $funnel['steps'];
         foreach ($steps as &$step) {
             $url = $actionUrl;
             // Matching on Page Title
             if ($step['match_attribute'] == 'title') {
                 $url = $actionName;
             }
             if (self::isMatch($url, $step['pattern_type'], $step['url'], $step['case_sensitive'])) {
                 printDebug("Matched Goal Funnel " . $funnel['idfunnel'] . " Step " . $step['idstep'] . "(name: " . $step['name'] . ", url: " . $step['url'] . "). ");
                 $serverTime = time();
                 $datetimeServer = Piwik_Tracker::getDatetimeFromTimestamp($serverTime);
                 // Look to see if this step has already been recorded for this visit
                 $exists = Piwik_FetchOne("SELECT *\n                        FROM " . Piwik_Common::prefixTable('log_funnel_step') . " \n                        WHERE idsite = ? \n                        AND   idfunnel = ?\n                        AND   idstep = ?\n                        AND   idvisit = ?", array($idSite, $funnel['idfunnel'], $step['idstep'], $idVisit));
                 // Record it if not
                 if (!$exists) {
                     printDebug("Recording...");
                     Piwik_Query("INSERT INTO " . Piwik_Common::prefixTable('log_funnel_step') . "\n                            (idvisit, idsite, idaction_url, url, \n                            idgoal, idfunnel, idstep, \n                            idaction_url_ref, server_time)\n                            VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)", array($idVisit, $idSite, $idActionUrl, $url, $funnel['idgoal'], $step['idfunnel'], $step['idstep'], $idRefererAction, $datetimeServer));
                 }
             }
         }
     }
 }
Example #9
0
 /**
  * Returns array containing data about the website: goals, URLs, etc.
  *
  * @param int $idSite
  * @return array
  */
 static function getCacheWebsiteAttributes($idSite)
 {
     static $cache = null;
     if (is_null($cache)) {
         require_once "CacheFile.php";
         $cache = new Piwik_CacheFile('tracker');
     }
     $filename = $idSite;
     $cacheContent = $cache->get($filename);
     if ($cacheContent !== false) {
         return $cacheContent;
     }
     if (defined('PIWIK_TRACKER_MODE') && PIWIK_TRACKER_MODE) {
         //TODO we can remove these includes when #620 is done
         require_once "Zend/Exception.php";
         require_once "Zend/Loader.php";
         require_once "Zend/Auth.php";
         require_once "Timer.php";
         require_once "PluginsManager.php";
         require_once "Piwik.php";
         require_once "Access.php";
         require_once "Auth.php";
         require_once "API/Proxy.php";
         require_once "Archive.php";
         require_once "Site.php";
         require_once "Date.php";
         require_once "DataTable.php";
         require_once "Translate.php";
         require_once "Mail.php";
         require_once "Url.php";
         require_once "Controller.php";
         require_once "Option.php";
         require_once "View.php";
         require_once "UpdateCheck.php";
         Zend_Registry::set('db', Piwik_Tracker::getDatabase());
         Piwik::createAccessObject();
         Piwik::createConfigObject();
         Piwik::setUserIsSuperUser();
         $pluginsManager = Piwik_PluginsManager::getInstance();
         $pluginsManager->setPluginsToLoad(Zend_Registry::get('config')->Plugins->Plugins->toArray());
     }
     $content = array();
     Piwik_PostEvent('Common.fetchWebsiteAttributes', $content, $idSite);
     // if nothing is returned from the plugins, we don't save the content
     // this is not expected: all websites are expected to have at least one URL
     if (!empty($content)) {
         $cache->set($filename, $content);
     }
     return $content;
 }
Example #10
0
 public static function disconnectDatabase()
 {
     if (isset(self::$db)) {
         self::$db->disconnect();
         self::$db = null;
     }
 }
Example #11
0
 /**
  * Records in the DB the association between the visit and this action.
  * 
  * @param int idVisit is the ID of the current visit in the DB table log_visit
  * @param int idRefererActionUrl is the ID of the last action done by the current visit. 
  * @param int timeSpentRefererAction is the number of seconds since the last action was done. 
  * 				It is directly related to idRefererActionUrl.
  */
 public function record($idVisit, $visitorIdCookie, $idRefererActionUrl, $idRefererActionName, $timeSpentRefererAction)
 {
     $this->loadIdActionNameAndUrl();
     $idActionName = $this->getIdActionName();
     if (is_null($idActionName)) {
         $idActionName = 0;
     }
     Piwik_Tracker::getDatabase()->query("INSERT INTO " . Piwik_Common::prefixTable('log_link_visit_action') . " (idvisit, idsite, idvisitor, server_time, idaction_url, idaction_name, idaction_url_ref, idaction_name_ref, time_spent_ref_action) \n\t\t\t\t\t\t\tVALUES (?,?,?,?,?,?,?,?,?)", array($idVisit, $this->idSite, $visitorIdCookie, Piwik_Tracker::getDatetimeFromTimestamp($this->timestamp), $this->getIdActionUrl(), $idActionName, $idRefererActionUrl, $idRefererActionName, $timeSpentRefererAction));
     $this->idLinkVisitAction = Piwik_Tracker::getDatabase()->lastInsertId();
     $info = array('idSite' => $this->idSite, 'idLinkVisitAction' => $this->idLinkVisitAction, 'idVisit' => $idVisit, 'idRefererActionUrl' => $idRefererActionUrl, 'idRefererActionName' => $idRefererActionName, 'timeSpentRefererAction' => $timeSpentRefererAction);
     printDebug($info);
     /* 
      * send the Action object ($this)  and the list of ids ($info) as arguments to the event 
      */
     Piwik_PostEvent('Tracker.Action.record', $this, $info);
 }
Example #12
0
/**
 *  Proxy to normal piwik.php, but in testing mode
 *  
 *  - Use the tests database to record Tracking data
 *  - Allows to overwrite the Visitor IP, and Server datetime 
 *  
 * @see Main.test.php
 * 
 */
// Wrapping the request inside ob_start() calls to ensure that the Test
// calling us waits for the full request to process before unblocking
ob_start();
define('PIWIK_INCLUDE_PATH', '../../..');
define('PIWIK_USER_PATH', PIWIK_INCLUDE_PATH);
require_once PIWIK_INCLUDE_PATH . '/libs/upgradephp/upgrade.php';
require_once PIWIK_INCLUDE_PATH . '/core/Loader.php';
// Config files forced to use the test database
// Note that this also provides security for Piwik installs containing tests files:
// this proxy will not record any data in the production database.
Piwik::createConfigObject();
Piwik_Config::getInstance()->setTestEnvironment();
Piwik_Config::getInstance()->PluginsInstalled['PluginsInstalled'] = array();
Piwik_UserCountry_LocationProvider_GeoIp::$geoIPDatabaseDir = 'tests/lib/geoip-files';
Piwik_Tracker::setTestEnvironment();
Piwik_DataTable_Manager::getInstance()->deleteAll();
Piwik_Option::getInstance()->clearCache();
Piwik_Site::clearCache();
Piwik_Common::deleteTrackerCache();
include PIWIK_INCLUDE_PATH . '/piwik.php';
ob_end_flush();
Example #13
0
 function recordGoals($idSite, $visitorInformation, $visitCustomVariables, $action, $referrerTimestamp, $referrerUrl, $referrerCampaignName, $referrerCampaignKeyword)
 {
     $location_country = isset($visitorInformation['location_country']) ? $visitorInformation['location_country'] : Piwik_Common::getCountry(Piwik_Common::getBrowserLanguage(), $enableLanguageToCountryGuess = Piwik_Tracker_Config::getInstance()->Tracker['enable_language_to_country_guess'], $visitorInformation['location_ip']);
     $location_continent = isset($visitorInformation['location_continent']) ? $visitorInformation['location_continent'] : Piwik_Common::getContinent($location_country);
     $goal = array('idvisit' => $visitorInformation['idvisit'], 'idsite' => $idSite, 'idvisitor' => $visitorInformation['idvisitor'], 'server_time' => Piwik_Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']), 'location_country' => $location_country, 'location_continent' => $location_continent, 'visitor_returning' => $visitorInformation['visitor_returning'], 'visitor_days_since_first' => $visitorInformation['visitor_days_since_first'], 'visitor_count_visits' => $visitorInformation['visitor_count_visits']);
     // Attributing the correct Referrer to this conversion.
     // Priority order is as follows:
     // 1) Campaign name/kwd parsed in the JS
     // 2) Referrer URL stored in the _ref cookie
     // 3) If no info from the cookie, attribute to the current visit referrer
     // 3) Default values: current referrer
     $type = $visitorInformation['referer_type'];
     $name = $visitorInformation['referer_name'];
     $keyword = $visitorInformation['referer_keyword'];
     $time = $visitorInformation['visit_first_action_time'];
     // 1) Campaigns from 1st party cookie
     if (!empty($referrerCampaignName)) {
         $type = Piwik_Common::REFERER_TYPE_CAMPAIGN;
         $name = $referrerCampaignName;
         $keyword = $referrerCampaignKeyword;
         $time = $referrerTimestamp;
     } elseif (!empty($referrerUrl)) {
         $referrer = new Piwik_Tracker_Visit_Referer();
         $referrer = $referrer->getRefererInformation($referrerUrl, $currentUrl = '', $idSite);
         // if the parsed referer is interesting enough, ie. website or search engine
         if (in_array($referrer['referer_type'], array(Piwik_Common::REFERER_TYPE_SEARCH_ENGINE, Piwik_Common::REFERER_TYPE_WEBSITE))) {
             $type = $referrer['referer_type'];
             $name = $referrer['referer_name'];
             $keyword = $referrer['referer_keyword'];
             $time = $referrerTimestamp;
         }
     }
     $goal += array('referer_type' => $type, 'referer_name' => $name, 'referer_keyword' => $keyword, 'referer_visit_server_date' => date("Y-m-d", $time));
     $goal += $visitCustomVariables;
     foreach ($this->convertedGoals as $convertedGoal) {
         printDebug("- Goal " . $convertedGoal['idgoal'] . " matched. Recording...");
         $newGoal = $goal;
         $newGoal['idgoal'] = $convertedGoal['idgoal'];
         $newGoal['url'] = $convertedGoal['url'];
         $newGoal['revenue'] = $convertedGoal['revenue'];
         if (!is_null($action)) {
             $newGoal['idaction_url'] = $action->getIdActionUrl();
             $newGoal['idlink_va'] = $action->getIdLinkVisitAction();
         }
         // If multiple Goal conversions per visit, set a cache buster
         $newGoal['buster'] = $convertedGoal['allow_multiple'] == 0 ? '0' : $visitorInformation['visit_last_action_time'];
         $newGoalDebug = $newGoal;
         $newGoalDebug['idvisitor'] = bin2hex($newGoalDebug['idvisitor']);
         printDebug($newGoalDebug);
         $fields = implode(", ", array_keys($newGoal));
         $bindFields = substr(str_repeat("?,", count($newGoal)), 0, -1);
         $sql = "INSERT IGNORE INTO " . Piwik_Common::prefixTable('log_conversion') . "\t\n\t\t\t\t\t({$fields}) VALUES ({$bindFields}) ";
         $bind = array_values($newGoal);
         Piwik_Tracker::getDatabase()->query($sql, $bind);
     }
 }
Example #14
0
    /**
     * 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
     */
    protected function recognizeTheVisitor()
    {
        $this->visitorKnown = false;
        $this->setCookie(new Piwik_Cookie($this->getCookieName(), $this->getCookieExpire(), $this->getCookiePath()));
        $this->printCookie();
        $userInfo = $this->getUserSettingsInformation();
        $configId = $userInfo['config_id'];
        $this->assignVisitorIdFromRequest();
        $matchVisitorId = !empty($this->visitorInfo['idvisitor']);
        if ($matchVisitorId) {
            printDebug("Matching visitors with: visitorId=" . bin2hex($this->visitorInfo['idvisitor']) . " OR configId=" . bin2hex($configId));
        } else {
            printDebug("Visitor doesn't have the piwik cookie...");
        }
        $selectCustomVariables = '';
        // No custom var were found in the request, so let's copy the previous one in a potential conversion later
        if (!$this->customVariablesSetFromRequest) {
            $selectCustomVariables = ', 
				custom_var_k1, custom_var_v1,
				custom_var_k2, custom_var_v2,
				custom_var_k3, custom_var_v3,
				custom_var_k4, custom_var_v4,
				custom_var_k5, custom_var_v5';
        }
        $select = "SELECT  \tidvisitor,\n\t\t\t\t\t\t\tvisit_last_action_time,\n\t\t\t\t\t\t\tvisit_first_action_time,\n\t\t\t\t\t\t\tidvisit,\n\t\t\t\t\t\t\tvisit_exit_idaction_url,\n\t\t\t\t\t\t\tvisit_exit_idaction_name,\n\t\t\t\t\t\t\tvisitor_returning,\n\t\t\t\t\t\t\tvisitor_days_since_first,\n\t\t\t\t\t\t\tvisitor_days_since_order,\n\t\t\t\t\t\t\tlocation_country,\n\t\t\t\t\t\t\tlocation_continent,\n\t\t\t\t\t\t\treferer_name,\n\t\t\t\t\t\t\treferer_keyword,\n\t\t\t\t\t\t\treferer_type,\n\t\t\t\t\t\t\tvisitor_count_visits,\n\t\t\t\t\t\t\tvisit_goal_buyer\n\t\t\t\t\t\t\t{$selectCustomVariables} \n\t\t";
        $from = "FROM " . Piwik_Common::prefixTable('log_visit');
        $bindSql = array();
        $timeLookBack = date('Y-m-d H:i:s', $this->getCurrentTimestamp() - Piwik_Config::getInstance()->Tracker['visit_standard_length']);
        // This setting would be enabled for Intranet websites, to ensure that visitors using all the same computer config, same IP
        // are not counted as 1 visitor. In this case, we want to enforce and trust the visitor ID from the cookie.
        $trustCookiesOnly = Piwik_Config::getInstance()->Tracker['trust_visitors_cookies'];
        $shouldMatchOneFieldOnly = $matchVisitorId && $trustCookiesOnly || !$matchVisitorId;
        // Two use cases:
        // 1) there is no visitor ID so we try to match only on config_id (heuristics)
        // 		Possible causes of no visitor ID: no browser cookie support, direct Tracking API request without visitor ID passed, etc.
        // 		We can use config_id heuristics to try find the visitor in the past, there is a risk to assign
        // 		this page view to the wrong visitor, but this is better than creating artificial visits.
        // 2) there is a visitor ID and we trust it (config setting trust_visitors_cookies), so we force to look up this visitor id
        if ($shouldMatchOneFieldOnly) {
            $where = "visit_last_action_time >= ? AND idsite = ?";
            $bindSql[] = $timeLookBack;
            $bindSql[] = $this->idsite;
            if (!$matchVisitorId) {
                $where .= ' AND config_id = ?';
                $bindSql[] = $configId;
            } else {
                $where .= ' AND idvisitor = ?';
                $bindSql[] = $this->visitorInfo['idvisitor'];
            }
            $sql = "{$select}\n\t\t\t\t{$from}\n\t\t\t\tWHERE " . $where . "\n\t\t\t\tORDER BY visit_last_action_time DESC\n\t\t\t\tLIMIT 1";
        } else {
            $whereSameBothQueries = "visit_last_action_time >= ? AND idsite = ?";
            // will use INDEX index_idsite_config_datetime (idsite, config_id, visit_last_action_time)
            $bindSql[] = $timeLookBack;
            $bindSql[] = $this->idsite;
            $where = ' AND config_id = ?';
            $bindSql[] = $configId;
            $sqlConfigId = "{$select} ,\n\t\t\t\t\t0 as priority\n\t\t\t\t\t{$from}\n\t\t\t\t\tWHERE {$whereSameBothQueries} {$where}\n\t\t\t\t\tORDER BY visit_last_action_time DESC\n\t\t\t\t\tLIMIT 1\n\t\t\t";
            // will use INDEX index_idsite_idvisitor (idsite, idvisitor)
            $bindSql[] = $timeLookBack;
            $bindSql[] = $this->idsite;
            $where = ' AND idvisitor = ?';
            $bindSql[] = $this->visitorInfo['idvisitor'];
            $sqlVisitorId = "{$select} ,\n\t\t\t\t\t1 as priority\n\t\t\t\t\t{$from}\n\t\t\t\t\tWHERE {$whereSameBothQueries} {$where}\n\t\t\t\t\tLIMIT 1\n\t\t\t";
            // We join both queries and favor the one matching the visitor_id if it did match
            $sql = " ( {$sqlConfigId} ) \n\t\t\t\t\tUNION \n\t\t\t\t\t( {$sqlVisitorId} ) \n\t\t\t\t\tORDER BY priority DESC \n\t\t\t\t\tLIMIT 1";
        }
        $visitRow = Piwik_Tracker::getDatabase()->fetch($sql, $bindSql);
        //		var_dump($sql);var_dump($bindSql);var_dump($visitRow);
        if (!Piwik_Config::getInstance()->Debug['tracker_always_new_visitor'] && $visitRow && count($visitRow) > 0) {
            // These values will be used throughout the request
            $this->visitorInfo['visit_last_action_time'] = strtotime($visitRow['visit_last_action_time']);
            $this->visitorInfo['visit_first_action_time'] = strtotime($visitRow['visit_first_action_time']);
            // We always keep the first idvisitor seen for this visit (so that all page views for this visit have the same idvisitor)
            $this->visitorInfo['idvisitor'] = $visitRow['idvisitor'];
            $this->visitorInfo['idvisit'] = $visitRow['idvisit'];
            $this->visitorInfo['visit_exit_idaction_url'] = $visitRow['visit_exit_idaction_url'];
            $this->visitorInfo['visit_exit_idaction_name'] = $visitRow['visit_exit_idaction_name'];
            $this->visitorInfo['visitor_returning'] = $visitRow['visitor_returning'];
            $this->visitorInfo['visitor_days_since_first'] = $visitRow['visitor_days_since_first'];
            $this->visitorInfo['visitor_days_since_order'] = $visitRow['visitor_days_since_order'];
            $this->visitorInfo['visitor_count_visits'] = $visitRow['visitor_count_visits'];
            $this->visitorInfo['visit_goal_buyer'] = $visitRow['visit_goal_buyer'];
            $this->visitorInfo['location_country'] = $visitRow['location_country'];
            $this->visitorInfo['location_continent'] = $visitRow['location_continent'];
            // Referer information will be potentially used for Goal Conversion attribution
            $this->visitorInfo['referer_name'] = $visitRow['referer_name'];
            $this->visitorInfo['referer_keyword'] = $visitRow['referer_keyword'];
            $this->visitorInfo['referer_type'] = $visitRow['referer_type'];
            // Custom Variables copied from Visit in potential later conversion
            if (!empty($selectCustomVariables)) {
                for ($i = 1; $i <= Piwik_Tracker::MAX_CUSTOM_VARIABLES; $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->visitorKnown = true;
            printDebug("The visitor is known (idvisitor = " . bin2hex($this->visitorInfo['idvisitor']) . ",\n\t\t\t\t\t\tconfig_id = " . bin2hex($configId) . ",\n\t\t\t\t\t\tidvisit = {$this->visitorInfo['idvisit']},\n\t\t\t\t\t\tlast action = " . date("r", $this->visitorInfo['visit_last_action_time']) . ",\n\t\t\t\t\t\tfirst action = " . date("r", $this->visitorInfo['visit_first_action_time']) . ",\n\t\t\t\t\t\tvisit_goal_buyer' = " . $this->visitorInfo['visit_goal_buyer'] . ")");
        } else {
            printDebug("The visitor was not matched with an existing visitor...");
        }
    }
Example #15
0
	protected function loadTrackerPlugins()
	{
		if(isset($this->request['dp'])
			&& $this->authenticated) 
		{
			Piwik_Tracker::setPluginsNotToLoad(array('Provider'));
		}
		try{
			$pluginsTracker = Piwik_Tracker_Config::getInstance()->Plugins_Tracker;
			if(is_array($pluginsTracker)
				&& count($pluginsTracker) != 0)
			{
				$pluginsTracker['Plugins_Tracker'] = array_diff($pluginsTracker['Plugins_Tracker'], self::getPluginsNotToLoad());
				Piwik_PluginsManager::getInstance()->doNotLoadAlwaysActivatedPlugins();
				Piwik_PluginsManager::getInstance()->loadPlugins( $pluginsTracker['Plugins_Tracker'] );
				
				printDebug("Loading plugins: { ". implode(",", $pluginsTracker['Plugins_Tracker']) . " }");
			}
		} catch(Exception $e) {
			printDebug("ERROR: ".$e->getMessage());
		}
	}
Example #16
0
 protected static function initCorePiwikInTrackerMode()
 {
     if (!empty($GLOBALS['PIWIK_TRACKER_MODE']) && self::$initTrackerMode === false) {
         self::$initTrackerMode = true;
         require_once PIWIK_INCLUDE_PATH . '/core/Loader.php';
         require_once PIWIK_INCLUDE_PATH . '/core/Option.php';
         try {
             $access = Zend_Registry::get('access');
         } catch (Exception $e) {
             Piwik::createAccessObject();
         }
         try {
             $config = Piwik_Config::getInstance();
         } catch (Exception $e) {
             Piwik::createConfigObject();
         }
         try {
             $db = Zend_Registry::get('db');
         } catch (Exception $e) {
             Piwik::createDatabaseObject();
         }
         $pluginsManager = Piwik_PluginsManager::getInstance();
         $pluginsToLoad = Piwik_Config::getInstance()->Plugins['Plugins'];
         $pluginsForcedNotToLoad = Piwik_Tracker::getPluginsNotToLoad();
         $pluginsToLoad = array_diff($pluginsToLoad, $pluginsForcedNotToLoad);
         $pluginsManager->loadPlugins($pluginsToLoad);
     }
 }
Example #17
0
 /**
  * Helper function used by other record* methods which will INSERT or UPDATE the conversion in the DB
  * 
  * @param array $newGoal
  * @param bool $mustUpdateNotInsert If set to true, the previous conversion will be UPDATEd. This is used for the Cart Update conversion (only one cart per visit)
  * @param array $updateWhere
  * @return bool
  */
 protected function recordGoal($newGoal, $mustUpdateNotInsert = false, $updateWhere = array())
 {
     $newGoalDebug = $newGoal;
     $newGoalDebug['idvisitor'] = bin2hex($newGoalDebug['idvisitor']);
     printDebug($newGoalDebug);
     $fields = implode(", ", array_keys($newGoal));
     $bindFields = Piwik_Common::getSqlStringFieldsArray($newGoal);
     if ($mustUpdateNotInsert) {
         $updateParts = $sqlBind = $updateWhereParts = array();
         foreach ($newGoal as $name => $value) {
             $updateParts[] = $name . " = ?";
             $sqlBind[] = $value;
         }
         foreach ($updateWhere as $name => $value) {
             $updateWhereParts[] = $name . " = ?";
             $sqlBind[] = $value;
         }
         $sql = 'UPDATE  ' . Piwik_Common::prefixTable('log_conversion') . "\t\n\t\t\t\t\tSET " . implode($updateParts, ', ') . "\n\t\t\t\t\t\tWHERE " . implode($updateWhereParts, ' AND ');
         Piwik_Tracker::getDatabase()->query($sql, $sqlBind);
         return true;
     } else {
         $sql = 'INSERT IGNORE INTO ' . Piwik_Common::prefixTable('log_conversion') . "\t\n\t\t\t\t\t({$fields}) VALUES ({$bindFields}) ";
         $bind = array_values($newGoal);
         $result = Piwik_Tracker::getDatabase()->query($sql, $bind);
         // If a record was inserted, we return true
         return Piwik_Tracker::getDatabase()->rowCount($result) > 0;
     }
 }
Example #18
0
define('PIWIK_INCLUDE_PATH', dirname(__FILE__));
@ignore_user_abort(true);
if (@(include "Version.php") === false || !class_exists('Piwik_Version')) {
    set_include_path(PIWIK_INCLUDE_PATH . '/core' . PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/libs' . PATH_SEPARATOR . PIWIK_INCLUDE_PATH . '/plugins' . PATH_SEPARATOR . get_include_path());
}
require_once "Common.php";
require_once "PluginsManager.php";
require_once "Tracker.php";
require_once "Tracker/Config.php";
require_once "Tracker/Action.php";
require_once "Cookie.php";
require_once "Tracker/Db.php";
require_once "Tracker/Visit.php";
require_once "Tracker/GoalManager.php";
session_cache_limiter('nocache');
ob_start();
if ($GLOBALS['PIWIK_TRACKER_DEBUG'] === true) {
    date_default_timezone_set(date_default_timezone_get());
    require_once "core/ErrorHandler.php";
    require_once "core/ExceptionHandler.php";
    set_error_handler('Piwik_ErrorHandler');
    set_exception_handler('Piwik_ExceptionHandler');
    printDebug($_GET);
    Piwik_Tracker_Db::enableProfiling();
    Piwik::createConfigObject();
    Piwik::createLogObject();
}
$process = new Piwik_Tracker();
$process->main();
ob_end_flush();
printDebug($_COOKIE);
Example #19
0
 protected function loadTrackerPlugins($request)
 {
     // Adding &dp=1 will disable the provider plugin, if token_auth is used (used to speed up bulk imports)
     if (isset($request['dp']) && !empty($request['dp']) && $this->authenticated) {
         Piwik_Tracker::setPluginsNotToLoad(array('Provider'));
     }
     try {
         $pluginsTracker = Piwik_Config::getInstance()->Plugins_Tracker;
         if (is_array($pluginsTracker) && count($pluginsTracker) != 0) {
             $pluginsTracker['Plugins_Tracker'] = array_diff($pluginsTracker['Plugins_Tracker'], self::getPluginsNotToLoad());
             Piwik_PluginsManager::getInstance()->doNotLoadAlwaysActivatedPlugins();
             Piwik_PluginsManager::getInstance()->loadPlugins($pluginsTracker['Plugins_Tracker']);
             printDebug("Loading plugins: { " . implode(",", $pluginsTracker['Plugins_Tracker']) . " }");
         }
     } catch (Exception $e) {
         printDebug("ERROR: " . $e->getMessage());
     }
 }
$forceIpAnonymization = false;
if (Piwik_Common::getRequestVar('forceIpAnonymization', false) == 1) {
    Piwik_Config::getInstance()->Tracker['ip_address_mask_length'] = 2;
    $pluginsTracker = Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker'];
    $pluginsTracker[] = "AnonymizeIP";
    Piwik_Config::getInstance()->Plugins_Tracker['Plugins_Tracker'] = $pluginsTracker;
    $forceIpAnonymization = true;
}
// Custom IP to use for this visitor
$customIp = Piwik_Common::getRequestVar('cip', false);
if (!empty($customIp)) {
    Piwik_Tracker::setForceIp($customIp);
}
// Custom server date time to use
$customDatetime = Piwik_Common::getRequestVar('cdt', false);
if (!empty($customDatetime)) {
    Piwik_Tracker::setForceDateTime($customDatetime);
}
// Custom server date time to use
$customVisitorId = Piwik_Common::getRequestVar('cid', false);
if (!empty($customVisitorId)) {
    Piwik_Tracker::setForceVisitorId($customVisitorId);
}
$pluginsDisabled = array('Provider');
if (!$forceIpAnonymization) {
    $pluginsDisabled[] = 'AnonymizeIP';
}
// Disable provider plugin, because it is so slow to do reverse ip lookup in dev environment somehow
Piwik_Tracker::setPluginsNotToLoad($pluginsDisabled);
include '../../piwik.php';
ob_flush();
Example #21
0
 /**
  * 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
  *
  * A known visitor is a visitor that has already visited the website in the current month.
  * We define a known visitor using the algorithm:
  *
  * 1) Checking if a cookie contains
  * 		// a unique id for the visitor
  * 		- id_visitor
  *
  * 		// the timestamp of the last action in the most recent visit
  * 		- timestamp_last_action
  *
  *  	// the timestamp of the first action in the most recent visit
  * 		- timestamp_first_action
  *
  * 		// the ID of the most recent visit (which could be in the past or the current visit)
  * 		- id_visit
  *
  * 		// the ID of the most recent action
  * 		- id_last_action
  *
  * 2) If the visitor doesn't have a cookie, we try to look for a similar visitor configuration.
  * 	  We search for a visitor with the same plugins/OS/Browser/Resolution for today for this website.
  */
 protected function recognizeTheVisitor()
 {
     $this->visitorKnown = false;
     $this->setCookie(new Piwik_Cookie($this->getCookieName(), $this->getCookieExpire(), $this->getCookiePath()));
     $this->printCookie();
     $found = $forcedVisitorId = false;
     // Was a Visitor ID "forced" (@see Tracking API setVisitorId()) for this request?
     $idVisitor = $this->forcedVisitorId;
     if (!empty($idVisitor)) {
         if (strlen($idVisitor) != Piwik_Tracker::LENGTH_HEX_ID_STRING) {
             throw new Exception("Visitor ID (cid) must be " . Piwik_Tracker::LENGTH_HEX_ID_STRING . " characters long");
         }
         printDebug("Request will be forced to record for this idvisitor = " . $idVisitor);
         $forcedVisitorId = true;
         $found = true;
     }
     if (!$found) {
         // - If set to use 3rd party cookies for Visit ID, read the cookies
         // - By default, reads the first party cookie ID
         $useThirdPartyCookie = $this->shouldUseThirdPartyCookie();
         if ($useThirdPartyCookie) {
             $idVisitor = $this->cookie->get(0);
             if ($idVisitor !== false && strlen($idVisitor) == Piwik_Tracker::LENGTH_HEX_ID_STRING) {
                 $found = true;
             }
         }
     }
     // If a third party cookie was not found, we default to the first party cookie
     if (!$found) {
         $idVisitor = Piwik_Common::getRequestVar('_id', '', 'string', $this->request);
         $found = strlen($idVisitor) >= Piwik_Tracker::LENGTH_HEX_ID_STRING;
     }
     // Does the cookie contain a Visitor ID?
     if ($found) {
         $this->visitorInfo['idvisitor'] = Piwik_Common::hex2bin($idVisitor);
         printDebug("The visitor has the piwik cookie (idvisitor = " . $idVisitor . ") ");
     } else {
         printDebug("Visitor doesn't have the piwik cookie.");
     }
     $userInfo = $this->getUserSettingsInformation();
     $configId = $userInfo['config_id'];
     $timeLookBack = date('Y-m-d H:i:s', $this->getCurrentTimestamp() - self::TIME_IN_PAST_TO_SEARCH_FOR_VISITOR);
     $where = "visit_last_action_time >= ?\n\t\t\t\t\tAND idsite = ?";
     $bindSql = array($timeLookBack, $this->idsite);
     // we always match on the config_id, except if the current request forces the visitor id
     if (!$forcedVisitorId) {
         $where .= ' AND config_id = ? ';
         $bindSql[] = $configId;
     }
     // We force to match a visitor ID
     // 1) If the visitor cookies should be trusted (ie. intranet) - config file setting
     // 2) or if the Visitor ID was forced via the Tracking API setVisitorId()
     if (!empty($this->visitorInfo['idvisitor']) && (Piwik_Tracker_Config::getInstance()->Tracker['trust_visitors_cookies'] || $forcedVisitorId)) {
         printDebug("Matching the visitor based on his idcookie: " . bin2hex($this->visitorInfo['idvisitor']) . "...");
         $where .= ' AND idvisitor = ?';
         $bindSql[] = $this->visitorInfo['idvisitor'];
     }
     $sql = " SELECT  \tidvisitor,\n\t\t\t\t\t\t\tvisit_last_action_time,\n\t\t\t\t\t\t\tvisit_first_action_time,\n\t\t\t\t\t\t\tidvisit,\n\t\t\t\t\t\t\tvisit_exit_idaction_url,\n\t\t\t\t\t\t\tvisit_exit_idaction_name,\n\t\t\t\t\t\t\tvisitor_returning,\n\t\t\t\t\t\t\tvisitor_days_since_first,\n\t\t\t\t\t\t\treferer_name,\n\t\t\t\t\t\t\treferer_keyword,\n\t\t\t\t\t\t\treferer_type,\n\t\t\t\t\t\t\tvisitor_count_visits\n\t\t\t\tFROM " . Piwik_Common::prefixTable('log_visit') . " WHERE " . $where . "\n\t\t\t\tORDER BY visit_last_action_time DESC\n\t\t\t\tLIMIT 1";
     $visitRow = Piwik_Tracker::getDatabase()->fetch($sql, $bindSql);
     if (!Piwik_Tracker_Config::getInstance()->Debug['tracker_always_new_visitor'] && $visitRow && count($visitRow) > 0) {
         // These values will be used throughout the request
         $this->visitorInfo['visit_last_action_time'] = strtotime($visitRow['visit_last_action_time']);
         $this->visitorInfo['visit_first_action_time'] = strtotime($visitRow['visit_first_action_time']);
         $this->visitorInfo['idvisitor'] = $visitRow['idvisitor'];
         $this->visitorInfo['idvisit'] = $visitRow['idvisit'];
         $this->visitorInfo['visit_exit_idaction_url'] = $visitRow['visit_exit_idaction_url'];
         $this->visitorInfo['visit_exit_idaction_name'] = $visitRow['visit_exit_idaction_name'];
         $this->visitorInfo['visitor_returning'] = $visitRow['visitor_returning'];
         $this->visitorInfo['visitor_days_since_first'] = $visitRow['visitor_days_since_first'];
         $this->visitorInfo['visitor_count_visits'] = $visitRow['visitor_count_visits'];
         // Referer information will be potentially used for Goal Conversion attribution
         $this->visitorInfo['referer_name'] = $visitRow['referer_name'];
         $this->visitorInfo['referer_keyword'] = $visitRow['referer_keyword'];
         $this->visitorInfo['referer_type'] = $visitRow['referer_type'];
         $this->visitorKnown = true;
         printDebug("The visitor is known (idvisitor = " . bin2hex($this->visitorInfo['idvisitor']) . ",\n\t\t\t\t\t\tconfig_id = " . bin2hex($configId) . ", \n\t\t\t\t\t\tidvisit = {$this->visitorInfo['idvisit']}, \n\t\t\t\t\t\tlast action = " . date("r", $this->visitorInfo['visit_last_action_time']) . ", \n\t\t\t\t\t\tfirst action = " . date("r", $this->visitorInfo['visit_first_action_time']) . ")");
     } else {
         printDebug("The visitor was not matched with an existing visitor...");
     }
 }
Example #22
0
 public static function connectDatabase()
 {
     if (!is_null(self::$db)) {
         return;
     }
     $db = null;
     Piwik_PostEvent('Tracker.createDatabase', $db);
     if (is_null($db)) {
         $db = self::connectPiwikTrackerDb();
     }
     self::$db = $db;
 }
Example #23
0
 /**
  * Records in the DB the association between the visit and this action.
  * 
  * @param int idVisit is the ID of the current visit in the DB table log_visit
  * @param int idRefererAction is the ID of the last action done by the current visit. 
  * @param int timeSpentRefererAction is the number of seconds since the last action was done. 
  * 				It is directly related to idRefererAction.
  */
 public function record($idVisit, $idRefererAction, $timeSpentRefererAction)
 {
     $actionId = $this->getIdAction();
     if (empty($actionId)) {
         $actionId = 0;
     }
     Piwik_Tracker::getDatabase()->query("/* SHARDING_ID_SITE = " . $this->idSite . " */ INSERT INTO " . Piwik_Common::prefixTable('log_link_visit_action') . " (idvisit, idaction, idaction_ref, time_spent_ref_action) VALUES (?,?,?,?)", array($idVisit, $actionId, $idRefererAction, $timeSpentRefererAction));
     $this->idLinkVisitAction = Piwik_Tracker::getDatabase()->lastInsertId();
     $info = array('idSite' => $this->idSite, 'idLinkVisitAction' => $this->idLinkVisitAction, 'idVisit' => $idVisit, 'idRefererAction' => $idRefererAction, 'timeSpentRefererAction' => $timeSpentRefererAction);
     printDebug($info);
     /* 
      * send the Action object ($this)  and the list of ids ($info) as arguments to the event 
      */
     Piwik_PostEvent('Tracker.Action.record', $this, $info);
 }
Example #24
0
 function recordGoals($visitorInformation, $action)
 {
     $location_country = isset($visitorInformation['location_country']) ? $visitorInformation['location_country'] : Piwik_Common::getCountry(Piwik_Common::getBrowserLanguage(), $enableLanguageToCountryGuess = Piwik_Tracker_Config::getInstance()->Tracker['enable_language_to_country_guess']);
     $location_continent = isset($visitorInformation['location_continent']) ? $visitorInformation['location_continent'] : Piwik_Common::getContinent($location_country);
     $goal = array('idvisit' => $visitorInformation['idvisit'], 'idsite' => $visitorInformation['idsite'], 'visitor_idcookie' => $visitorInformation['visitor_idcookie'], 'server_time' => Piwik_Tracker::getDatetimeFromTimestamp($visitorInformation['visit_last_action_time']), 'visit_server_date' => $visitorInformation['visit_server_date'], 'location_country' => $location_country, 'location_continent' => $location_continent, 'visitor_returning' => $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_VISITOR_RETURNING));
     $referer_idvisit = $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_ID_VISIT);
     if ($referer_idvisit !== false) {
         $goal += array('referer_idvisit' => $referer_idvisit, 'referer_visit_server_date' => date("Y-m-d", $this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_TIMESTAMP)), 'referer_type' => htmlspecialchars_decode($this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_TYPE)), 'referer_name' => htmlspecialchars_decode($this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_NAME)), 'referer_keyword' => htmlspecialchars_decode($this->cookie->get(Piwik_Tracker::COOKIE_INDEX_REFERER_KEYWORD)));
     }
     foreach ($this->convertedGoals as $convertedGoal) {
         printDebug("- Goal " . $convertedGoal['idgoal'] . " matched. Recording...");
         $newGoal = $goal;
         $newGoal['idgoal'] = $convertedGoal['idgoal'];
         $newGoal['url'] = $convertedGoal['url'];
         $newGoal['revenue'] = $convertedGoal['revenue'];
         if (!is_null($action)) {
             $newGoal['idaction'] = $action->getIdAction();
             $newGoal['idlink_va'] = $action->getIdLinkVisitAction();
         }
         printDebug($newGoal);
         $fields = implode(", ", array_keys($newGoal));
         $bindFields = substr(str_repeat("?,", count($newGoal)), 0, -1);
         try {
             Piwik_Tracker::getDatabase()->query("INSERT INTO " . Piwik_Common::prefixTable('log_conversion') . "\t({$fields}) \n\t\t\t\t\tVALUES ({$bindFields}) ", array_values($newGoal));
         } catch (Exception $e) {
             if (strpos($e->getMessage(), '1062') !== false) {
                 // integrity violation when same visit converts to the same goal twice
                 printDebug("--> Goal already recorded for this (idvisit, idgoal)");
             } else {
                 throw $e;
             }
         }
         //$idlog_goal = Piwik_Tracker::getDatabase()->lastInsertId();
     }
 }
Example #25
0
 /**
  * This is called at the end of the Generator script.
  * Calls the Profiler output if the profiler is enabled.
  * 
  * @return void
  */
 public function end()
 {
     Piwik_Tracker::disconnectDatabase();
     if ($this->profiling) {
         Piwik::printSqlProfilingReportTracker();
     }
 }