function archivePeriod($notification) { $archiveProcessing = $notification->getNotificationObject(); $metricsToSum = array('nb_conversions', 'revenue'); $goalIdsToSum = Piwik_Tracker_GoalManager::getGoalIds($archiveProcessing->idsite); $fieldsToSum = array(); foreach ($metricsToSum as $metricName) { foreach ($goalIdsToSum as $goalId) { $fieldsToSum[] = self::getRecordName($metricName, $goalId); $fieldsToSum[] = self::getRecordName($metricName, $goalId, 0); $fieldsToSum[] = self::getRecordName($metricName, $goalId, 1); } $fieldsToSum[] = self::getRecordName($metricName); } $records = $archiveProcessing->archiveNumericValuesSum($fieldsToSum); // also recording conversion_rate for each goal foreach ($goalIdsToSum as $goalId) { $nb_conversions = $records[self::getRecordName('nb_conversions', $goalId)]->value; $conversion_rate = $this->getConversionRate($nb_conversions, $archiveProcessing); $archiveProcessing->insertNumericRecord(self::getRecordName('conversion_rate', $goalId), $conversion_rate); } // global conversion rate $nb_conversions = $records[self::getRecordName('nb_conversions')]->value; $conversion_rate = $this->getConversionRate($nb_conversions, $archiveProcessing); $archiveProcessing->insertNumericRecord(self::getRecordName('conversion_rate'), $conversion_rate); }
/** * Main algorithm to handle the visit. * * Once we have the visitor information, we have to determine if the visit is a new or a known visit. * * 1) When the last action was done more than 30min ago, * or if the visitor is new, then this is a new visit. * * 2) If the last action is less than 30min ago, then the same visit is going on. * Because the visit goes on, we can get the time spent during the last action. * * NB: * - In the case of a new visit, then the time spent * during the last action of the previous visit is unknown. * * - In the case of a new visit but with a known visitor, * we can set the 'returning visitor' flag. * * In all the cases we set a cookie to the visitor with the new information. */ public function handle() { if ($this->isExcluded()) { return; } $goalManager = new Piwik_Tracker_GoalManager(); $someGoalsConverted = false; $actionId = 0; $action = null; $idGoal = Piwik_Common::getRequestVar('idgoal', 0, 'int', $this->request); // this request is from the JS call to piwikTracker.trackGoal() if ($idGoal > 0) { $someGoalsConverted = $goalManager->detectGoalId($this->idsite, $idGoal, $this->request); // if we find a idgoal in the URL, but then the goal is not valid, this is most likely a fake request if (!$someGoalsConverted) { unset($goalManager); return; } } else { $action = $this->newAction(); $this->handleAction($action); $someGoalsConverted = $goalManager->detectGoalsMatchingUrl($this->idsite, $action); $actionId = $action->getIdAction(); } // the visitor and session $this->recognizeTheVisitor(); $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit(); // Known visit when: // - the visitor has the Piwik cookie with the idcookie ID used by Piwik to match the visitor // OR // - the visitor doesn't have the Piwik cookie but could be match using heuristics @see recognizeTheVisitor() // AND // - the last page view for this visitor was less than 30 minutes ago @see isLastActionInTheSameVisit() if ($this->isVisitorKnown() && $isLastActionInTheSameVisit) { $idActionReferer = $this->visitorInfo['visit_exit_idaction']; try { $this->handleKnownVisit($actionId, $someGoalsConverted); if (!is_null($action)) { $action->record($this->visitorInfo['idvisit'], $idActionReferer, $this->visitorInfo['time_spent_ref_action']); } } catch (Piwik_Tracker_Visit_VisitorNotFoundInDatabase $e) { printDebug($e->getMessage()); $this->visitorKnown = false; } } // New visit when: // - the visitor has the Piwik cookie but the last action was performed more than 30 min ago @see isLastActionInTheSameVisit() // - the visitor doesn't have the Piwik cookie, and couldn't be matched in @see recognizeTheVisitor() // - the visitor does have the Piwik cookie but the idcookie and idvisit found in the cookie didn't match to any existing visit in the DB if (!$this->isVisitorKnown() || !$isLastActionInTheSameVisit) { $this->handleNewVisit($actionId, $someGoalsConverted); if (!is_null($action)) { $action->record($this->visitorInfo['idvisit'], 0, 0); } } // update the cookie with the new visit information $this->updateCookie(); // record the goals if applicable if ($someGoalsConverted) { $goalManager->setCookie($this->cookie); $goalManager->recordGoals($this->visitorInfo, $action); } unset($goalManager); unset($action); }
/** * Hooks on Period archiving. * Sums up Goal conversions stats, and processes overall conversion rate * * @param Piwik_Event_Notification $notification * @return void */ function archivePeriod($notification) { /** * @var Piwik_ArchiveProcessing */ $archiveProcessing = $notification->getNotificationObject(); if (!$archiveProcessing->shouldProcessReportsForPlugin($this->getPluginName())) { return; } /* * Archive Ecommerce Items */ if ($this->shouldArchiveEcommerceItems($archiveProcessing)) { $dataTableToSum = $this->dimensions; foreach ($this->dimensions as $recordName) { $dataTableToSum[] = self::getItemRecordNameAbandonedCart($recordName); } $archiveProcessing->archiveDataTable($dataTableToSum); } /* * Archive General Goal metrics */ $goalIdsToSum = Piwik_Tracker_GoalManager::getGoalIds($archiveProcessing->idsite); //Ecommerce $goalIdsToSum[] = Piwik_Tracker_GoalManager::IDGOAL_ORDER; $goalIdsToSum[] = Piwik_Tracker_GoalManager::IDGOAL_CART; //bug here if idgoal=1 // Overall goal metrics $goalIdsToSum[] = false; $fieldsToSum = array(); foreach ($goalIdsToSum as $goalId) { $metricsToSum = Piwik_Goals::getGoalColumns($goalId); unset($metricsToSum[array_search('conversion_rate', $metricsToSum)]); foreach ($metricsToSum as $metricName) { $fieldsToSum[] = self::getRecordName($metricName, $goalId); } } $records = $archiveProcessing->archiveNumericValuesSum($fieldsToSum); // also recording conversion_rate for each goal foreach ($goalIdsToSum as $goalId) { $nb_conversions = $records[self::getRecordName('nb_visits_converted', $goalId)]; $conversion_rate = $this->getConversionRate($nb_conversions, $archiveProcessing); $archiveProcessing->insertNumericRecord(self::getRecordName('conversion_rate', $goalId), $conversion_rate); // sum up the visits to conversion data table & the days to conversion data table $archiveProcessing->archiveDataTable(array(self::getRecordName(self::VISITS_UNTIL_RECORD_NAME, $goalId), self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME, $goalId))); } // sum up goal overview reports $archiveProcessing->archiveDataTable(array(self::getRecordName(self::VISITS_UNTIL_RECORD_NAME), self::getRecordName(self::DAYS_UNTIL_CONV_RECORD_NAME))); }
/** * In the case of a new visit, we have to do the following actions: * * 1) Insert the new action * * 2) Insert the visit information * @param $idActionUrl * @param $idActionName * @param $actionType * @param $visitIsConverted */ protected function handleNewVisit($idActionUrl, $idActionName, $actionType, $visitIsConverted) { printDebug("New Visit (IP = " . Piwik_IP::N2P($this->getVisitorIp()) . ")"); $localTimes = array('h' => (string) Piwik_Common::getRequestVar('h', $this->getCurrentDate("H"), 'int', $this->request), 'i' => (string) Piwik_Common::getRequestVar('m', $this->getCurrentDate("i"), 'int', $this->request), 's' => (string) Piwik_Common::getRequestVar('s', $this->getCurrentDate("s"), 'int', $this->request)); foreach ($localTimes as $k => $time) { if (strlen($time) == 1) { $localTimes[$k] = '0' . $time; } } $localTime = $localTimes['h'] . ':' . $localTimes['i'] . ':' . $localTimes['s']; $idcookie = $this->getVisitorIdcookie(); $defaultTimeOnePageVisit = Piwik_Config::getInstance()->Tracker['default_time_one_page_visit']; // Days since first visit $cookieFirstVisitTimestamp = Piwik_Common::getRequestVar('_idts', 0, 'int', $this->request); if (!$this->isTimestampValid($cookieFirstVisitTimestamp)) { $cookieFirstVisitTimestamp = $this->getCurrentTimestamp(); } $daysSinceFirstVisit = round(($this->getCurrentTimestamp() - $cookieFirstVisitTimestamp) / 86400, $precision = 0); if ($daysSinceFirstVisit < 0) { $daysSinceFirstVisit = 0; } // Number of Visits $visitCount = Piwik_Common::getRequestVar('_idvc', 1, 'int', $this->request); if ($visitCount < 1) { $visitCount = 1; } // Days since last visit $daysSinceLastVisit = 0; $lastVisitTimestamp = Piwik_Common::getRequestVar('_viewts', 0, 'int', $this->request); if ($this->isTimestampValid($lastVisitTimestamp)) { $daysSinceLastVisit = round(($this->getCurrentTimestamp() - $lastVisitTimestamp) / 86400, $precision = 0); if ($daysSinceLastVisit < 0) { $daysSinceLastVisit = 0; } } $daysSinceLastOrder = 0; $isReturningCustomer = false; $lastOrderTimestamp = Piwik_Common::getRequestVar('_ects', 0, 'int', $this->request); if ($this->isTimestampValid($lastOrderTimestamp)) { $daysSinceLastOrder = round(($this->getCurrentTimestamp() - $lastOrderTimestamp) / 86400, $precision = 0); if ($daysSinceLastOrder < 0) { $daysSinceLastOrder = 0; } $isReturningCustomer = true; } // User settings $userInfo = $this->getUserSettingsInformation(); $country = Piwik_Common::getCountry($userInfo['location_browser_lang'], $enableLanguageToCountryGuess = Piwik_Config::getInstance()->Tracker['enable_language_to_country_guess'], $this->getVisitorIp()); // Referrer data $referrer = new Piwik_Tracker_Visit_Referer(); $refererUrl = Piwik_Common::getRequestVar('urlref', '', 'string', $this->request); $currentUrl = Piwik_Common::getRequestVar('url', '', 'string', $this->request); $refererInfo = $referrer->getRefererInformation($refererUrl, $currentUrl, $this->idsite); /** * Save the visitor */ $this->visitorInfo = array('idsite' => $this->idsite, 'visitor_localtime' => $localTime, 'idvisitor' => $idcookie, 'visitor_returning' => $isReturningCustomer ? 2 : ($visitCount > 1 || $this->isVisitorKnown() ? 1 : 0), 'visitor_count_visits' => $visitCount, 'visitor_days_since_last' => $daysSinceLastVisit, 'visitor_days_since_order' => $daysSinceLastOrder, 'visitor_days_since_first' => $daysSinceFirstVisit, 'visit_first_action_time' => Piwik_Tracker::getDatetimeFromTimestamp($this->getCurrentTimestamp()), 'visit_last_action_time' => Piwik_Tracker::getDatetimeFromTimestamp($this->getCurrentTimestamp()), 'visit_entry_idaction_url' => (int) $idActionUrl, 'visit_entry_idaction_name' => (int) $idActionName, 'visit_exit_idaction_url' => (int) $idActionUrl, 'visit_exit_idaction_name' => (int) $idActionName, 'visit_total_actions' => in_array($actionType, array(Piwik_Tracker_Action::TYPE_ACTION_URL, Piwik_Tracker_Action::TYPE_DOWNLOAD, Piwik_Tracker_Action::TYPE_OUTLINK)) ? 1 : 0, 'visit_total_time' => $defaultTimeOnePageVisit, 'visit_goal_converted' => $visitIsConverted ? 1 : 0, 'visit_goal_buyer' => $this->goalManager->getBuyerType(), 'referer_type' => $refererInfo['referer_type'], 'referer_name' => $refererInfo['referer_name'], 'referer_url' => $refererInfo['referer_url'], 'referer_keyword' => $refererInfo['referer_keyword'], 'config_id' => $userInfo['config_id'], 'config_os' => $userInfo['config_os'], 'config_browser_name' => $userInfo['config_browser_name'], 'config_browser_version' => $userInfo['config_browser_version'], 'config_resolution' => $userInfo['config_resolution'], 'config_pdf' => $userInfo['config_pdf'], 'config_flash' => $userInfo['config_flash'], 'config_java' => $userInfo['config_java'], 'config_director' => $userInfo['config_director'], 'config_quicktime' => $userInfo['config_quicktime'], 'config_realplayer' => $userInfo['config_realplayer'], 'config_windowsmedia' => $userInfo['config_windowsmedia'], 'config_gears' => $userInfo['config_gears'], 'config_silverlight' => $userInfo['config_silverlight'], 'config_cookie' => $userInfo['config_cookie'], 'location_ip' => $this->getVisitorIp(), 'location_browser_lang' => $userInfo['location_browser_lang'], 'location_country' => $country); // Add Custom variable key,value to the visitor array $this->visitorInfo = array_merge($this->visitorInfo, $this->visitorCustomVariables); Piwik_PostEvent('Tracker.newVisitorInformation', $this->visitorInfo); $debugVisitInfo = $this->visitorInfo; $debugVisitInfo['idvisitor'] = bin2hex($debugVisitInfo['idvisitor']); $debugVisitInfo['config_id'] = bin2hex($debugVisitInfo['config_id']); printDebug($debugVisitInfo); $this->saveVisitorInformation(); }
/** * Main algorithm to handle the visit. * * Once we have the visitor information, we have to determine if the visit is a new or a known visit. * * 1) When the last action was done more than 30min ago, * or if the visitor is new, then this is a new visit. * * 2) If the last action is less than 30min ago, then the same visit is going on. * Because the visit goes on, we can get the time spent during the last action. * * NB: * - In the case of a new visit, then the time spent * during the last action of the previous visit is unknown. * * - In the case of a new visit but with a known visitor, * we can set the 'returning visitor' flag. * * In all the cases we set a cookie to the visitor with the new information. */ public function handle() { // the IP is needed by isExcluded() and GoalManager->recordGoals() $this->visitorInfo['location_ip'] = $this->ipString; if ($this->isExcluded()) { return; } $this->visitorCustomVariables = $this->getCustomVariables(); $goalManager = new Piwik_Tracker_GoalManager(); $someGoalsConverted = false; $idActionUrl = $idActionName = 0; $action = null; $idGoal = Piwik_Common::getRequestVar('idgoal', 0, 'int', $this->request); $requestIsManualGoalConversion = $idGoal > 0; // this request is from the JS call to piwikTracker.trackGoal() if ($requestIsManualGoalConversion) { $someGoalsConverted = $goalManager->detectGoalId($this->idsite, $idGoal, $this->request); // if we find a idgoal in the URL, but then the goal is not valid, this is most likely a fake request if (!$someGoalsConverted) { printDebug('Invalid goal tracking request for goal id = ' . $idGoal); unset($goalManager); return; } } else { $action = $this->newAction(); $isActionValid = $this->handleAction($action); if (!$isActionValid) { printDebug('Not tracking this action as it is flagged as invalid.'); return; } $someGoalsConverted = $goalManager->detectGoalsMatchingUrl($this->idsite, $action); $action->loadIdActionNameAndUrl(); $idActionUrl = $action->getIdActionUrl(); $idActionName = $action->getIdActionName(); } // the visitor and session $this->recognizeTheVisitor(); $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit(); // Known visit when: // ( - the visitor has the Piwik cookie with the idcookie ID used by Piwik to match the visitor // OR // - the visitor doesn't have the Piwik cookie but could be match using heuristics @see recognizeTheVisitor() // ) // AND // - the last page view for this visitor was less than 30 minutes ago @see isLastActionInTheSameVisit() if ($this->isVisitorKnown() && $isLastActionInTheSameVisit) { $idRefererActionUrl = $this->visitorInfo['visit_exit_idaction_url']; $idRefererActionName = $this->visitorInfo['visit_exit_idaction_name']; try { $this->handleKnownVisit($idActionUrl, $idActionName, $someGoalsConverted); if (!is_null($action)) { $action->record($this->visitorInfo['idvisit'], $this->visitorInfo['idvisitor'], $idRefererActionUrl, $idRefererActionName, $this->visitorInfo['time_spent_ref_action']); } } catch (Piwik_Tracker_Visit_VisitorNotFoundInDatabase $e) { // There is an edge case when: // - two manual goal conversions happen in the same second // - which result in handleKnownVisit throwing the exception // because the UPDATE didn't affect any rows (one row was found, but not updated since no field changed) // - the exception is caught here and will result in a new visit incorrectly // In this case, we cancel the current conversion to be recorded: if ($requestIsManualGoalConversion) { $someGoalsConverted = false; } else { $this->visitorKnown = false; } } } // New visit when: // - the visitor has the Piwik cookie but the last action was performed more than 30 min ago @see isLastActionInTheSameVisit() // - the visitor doesn't have the Piwik cookie, and couldn't be matched in @see recognizeTheVisitor() // - the visitor does have the Piwik cookie but the idcookie and idvisit found in the cookie didn't match to any existing visit in the DB if (!$this->isVisitorKnown() || !$isLastActionInTheSameVisit) { $this->handleNewVisit($idActionUrl, $idActionName, $someGoalsConverted); if (!is_null($action)) { $action->record($this->visitorInfo['idvisit'], $this->visitorInfo['idvisitor'], 0, 0, 0); } } // update the cookie with the new visit information $this->setThirdPartyCookie(); // record the goals if applicable if ($someGoalsConverted) { $refererTimestamp = Piwik_Common::getRequestVar('_refts', 0, 'int', $this->request); $refererUrl = Piwik_Common::getRequestVar('_ref', '', 'string', $this->request); $refererCampaignName = Piwik_Common::getRequestVar('_rcn', '', 'string', $this->request); $refererCampaignKeyword = Piwik_Common::getRequestVar('_rck', '', 'string', $this->request); $goalManager->recordGoals($this->idsite, $this->visitorInfo, $this->visitorCustomVariables, $action, $refererTimestamp, $refererUrl, $refererCampaignName, $refererCampaignKeyword); } unset($goalManager); unset($action); $this->printCookie(); }
/** * Main algorith to handle the visit. * * Once we have the visitor information, we have to define if the visit is a new or a known visit. * * 1) When the last action was done more than 30min ago, * or if the visitor is new, then this is a new visit. * * 2) If the last action is less than 30min ago, then the same visit is going on. * Because the visit goes on, we can get the time spent during the last action. * * NB: * - In the case of a new visit, then the time spent * during the last action of the previous visit is unknown. * * - In the case of a new visit but with a known visitor, * we can set the 'returning visitor' flag. * * In all the cases we set a cookie to the visitor with the new information. */ public function handle() { if ($this->isExcluded()) { return; } $action = $this->newAction(); $action->setIdSite($this->idsite); $action->setRequest($this->request); $action->init(); if ($this->detectActionIsOutlinkOnAliasHost($action)) { printDebug("The outlink's URL host is one of the known host for this website. We don't record this click."); return; } $actionId = $action->getIdAction(); if (isset($GLOBALS['PIWIK_TRACKER_DEBUG']) && $GLOBALS['PIWIK_TRACKER_DEBUG']) { switch ($action->getActionType()) { case Piwik_Tracker_Action::TYPE_ACTION: $type = "normal page view"; break; case Piwik_Tracker_Action::TYPE_DOWNLOAD: $type = "download"; break; case Piwik_Tracker_Action::TYPE_OUTLINK: $type = "outlink"; break; } printDebug("Detected action <u>{$type}</u>, \n\t\t\t\t\t\tAction name: " . $action->getActionName() . ", \n\t\t\t\t\t\tAction URL = " . $action->getActionUrl()); } // goal matched? $goalManager = new Piwik_Tracker_GoalManager($action); $someGoalsConverted = false; if ($goalManager->detectGoals($this->idsite)) { $someGoalsConverted = true; } // the visitor and session $this->recognizeTheVisitor(); $isLastActionInTheSameVisit = $this->isLastActionInTheSameVisit(); // Known visit when: // - the visitor has the Piwik cookie with the idcookie ID used by Piwik to match the visitor // OR // - the visitor doesn't have the Piwik cookie but could be match using heuristics @see recognizeTheVisitor() // AND // - the last page view for this visitor was less than 30 minutes ago @see isLastActionInTheSameVisit() if ($this->isVisitorKnown() && $isLastActionInTheSameVisit) { $idActionReferer = $this->visitorInfo['visit_exit_idaction']; try { $this->handleKnownVisit($actionId, $someGoalsConverted); $action->record($this->visitorInfo['idvisit'], $idActionReferer, $this->visitorInfo['time_spent_ref_action']); } catch (Piwik_Tracker_Visit_VisitorNotFoundInDatabase $e) { printDebug($e->getMessage()); $this->visitorKnown = false; } } // New visit when: // - the visitor has the Piwik cookie but the last action was performed more than 30 min ago @see isLastActionInTheSameVisit() // - the visitor doesn't have the Piwik cookie, and couldn't be matched in @see recognizeTheVisitor() // - the visitor does have the Piwik cookie but the idcookie and idvisit found in the cookie didn't match to any existing visit in the DB if (!$this->isVisitorKnown() || !$isLastActionInTheSameVisit) { $this->handleNewVisit($actionId, $someGoalsConverted); $action->record($this->visitorInfo['idvisit'], 0, 0); } // update the cookie with the new visit information $this->updateCookie(); // record the goals if applicable if ($someGoalsConverted) { $goalManager->setCookie($this->cookie); $goalManager->recordGoals($this->visitorInfo); } unset($goalManager); unset($action); }