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; }
/** * 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; }
/** * 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; }
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)); } } } } }
/** * 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']) . ") "); } } }
/** * 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); }
/** * 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); }
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)); } } } } }
/** * 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; }
public static function disconnectDatabase() { if (isset(self::$db)) { self::$db->disconnect(); self::$db = null; } }
/** * 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); }
/** * 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();
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); } }
/** * 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..."); } }
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()); } }
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); } }
/** * 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; } }
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);
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();
/** * 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..."); } }
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; }
/** * 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); }
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(); } }
/** * 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(); } }