/** * @param Request $request * @param Visitor $visitor * @param Action|null $action * @return mixed */ public function onExistingVisit(Request $request, Visitor $visitor, $action) { $firstActionTime = $visitor->getVisitorColumn('visit_first_action_time'); $totalTime = 1 + $request->getCurrentTimestamp() - $firstActionTime; $totalTime = $this->cleanupVisitTotalTime($totalTime); return $totalTime; }
/** * Gather fields=>values that needs to be updated for the existing visit in log_visit * * @param $action * @param $visitIsConverted * @return array */ protected function getExistingVisitFieldsToUpdate($action, $visitIsConverted) { $valuesToUpdate = array(); if ($action) { $idActionUrl = $action->getIdActionUrlForEntryAndExitIds(); $idActionName = $action->getIdActionNameForEntryAndExitIds(); $actionType = $action->getActionType(); if ($idActionName !== false) { $valuesToUpdate['visit_exit_idaction_name'] = $idActionName; } $incrementActions = false; if ($idActionUrl !== false) { $valuesToUpdate['visit_exit_idaction_url'] = $idActionUrl; $incrementActions = true; } if ($actionType == Action::TYPE_SITE_SEARCH) { $valuesToUpdate['visit_total_searches'] = 'visit_total_searches + 1'; $incrementActions = true; } else { if ($actionType == Action::TYPE_EVENT) { $valuesToUpdate['visit_total_events'] = 'visit_total_events + 1'; $incrementActions = true; } } if ($incrementActions) { $valuesToUpdate['visit_total_actions'] = 'visit_total_actions + 1'; } } $datetimeServer = Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()); $valuesToUpdate['visit_last_action_time'] = $datetimeServer; // Add 1 so it's always > 0 $visitTotalTime = 1 + $this->request->getCurrentTimestamp() - $this->visitorInfo['visit_first_action_time']; $valuesToUpdate['visit_total_time'] = self::cleanupVisitTotalTime($visitTotalTime); // Goal conversion if ($visitIsConverted) { $valuesToUpdate['visit_goal_converted'] = 1; // If a pageview and goal conversion in the same second, with previously a goal conversion recorded // the request would not "update" the row since all values are the same as previous // therefore the request below throws exception, instead we make sure the UPDATE will affect the row $valuesToUpdate['visit_total_time'] = self::cleanupVisitTotalTime($valuesToUpdate['visit_total_time'] + $this->goalManager->idGoal + 2); } // Might update the idvisitor when it was forced or overwritten for this visit if (strlen($this->visitorInfo['idvisitor']) == Tracker::LENGTH_BINARY_ID) { $valuesToUpdate['idvisitor'] = $this->visitorInfo['idvisitor']; } // Ecommerce buyer status $visitEcommerceStatus = $this->goalManager->getBuyerType($this->visitorInfo['visit_goal_buyer']); if ($visitEcommerceStatus != GoalManager::TYPE_BUYER_NONE && $visitEcommerceStatus != $this->visitorInfo['visit_goal_buyer']) { $valuesToUpdate['visit_goal_buyer'] = $visitEcommerceStatus; } // Custom Variables overwrite previous values on each page view $valuesToUpdate = array_merge($valuesToUpdate, $this->visitorCustomVariables); return $valuesToUpdate; }
private function markArchivedReportsAsInvalidIfArchiveAlreadyFinished() { $idSite = (int) $this->request->getIdSite(); $time = $this->request->getCurrentTimestamp(); $timezone = $this->getTimezoneForSite($idSite); if (!isset($timezone)) { return; } $date = Date::factory((int) $time, $timezone); if (!$date->isToday()) { // we don't have to handle in case date is in future as it is not allowed by tracker $this->invalidator->rememberToInvalidateArchivedReportsLater($idSite, $date); } }
public function recordLogs(VisitProperties $visitProperties, Request $request) { // if we successfully record some data and the date is older than the site's created time, // update the created time so the data will be viewable in the UI $idSite = $request->getIdSite(); $createdTimeTimestamp = $this->getSiteCreatedTime($idSite); if (empty($createdTimeTimestamp)) { return; } $requestTimestamp = Date::factory((int) $request->getCurrentTimestamp()); // replicating old Piwik logic, see: // https://github.com/piwik/piwik/blob/baa6da86266c7c44bc2d65821c7ffe042c2f4716/core/Archive/ArchiveInvalidator.php#L150 // before when this was done during archive invalidation, the date would not have an attached time and // one extra day was subtracted from the minimum. // I am not sure why this is required or if it is still required, but some tests that check the contents // of archive tables will fail w/o this. $requestTimestamp = $requestTimestamp->subDay(1)->setTime('00:00:00'); if ($requestTimestamp->isEarlier($createdTimeTimestamp)) { $this->updateSiteCreatedTime($idSite, $requestTimestamp); } }
/** * 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 $visitorIdCookie * @param int $idReferrerActionUrl is the ID of the last action done by the current visit. * @param $idReferrerActionName * @param int $timeSpentReferrerAction is the number of seconds since the last action was done. * It is directly related to idReferrerActionUrl. */ public function record($idVisit, $visitorIdCookie, $idReferrerActionUrl, $idReferrerActionName, $timeSpentReferrerAction) { $this->loadIdsFromLogActionTable(); $visitAction = array('idvisit' => $idVisit, 'idsite' => $this->request->getIdSite(), 'idvisitor' => $visitorIdCookie, 'server_time' => Tracker::getDatetimeFromTimestamp($this->request->getCurrentTimestamp()), 'idaction_url' => $this->getIdActionUrl(), 'idaction_url_ref' => $idReferrerActionUrl, 'idaction_name_ref' => $idReferrerActionName, 'time_spent_ref_action' => $timeSpentReferrerAction); // idaction_name is NULLable. we only set it when applicable if ($this->isActionHasActionName()) { $visitAction['idaction_name'] = (int) $this->getIdActionName(); } foreach ($this->actionIdsCached as $field => $idAction) { $visitAction[$field] = $idAction === false ? 0 : $idAction; } $customValue = $this->getCustomFloatValue(); if (!empty($customValue)) { $visitAction[self::DB_COLUMN_CUSTOM_FLOAT] = $customValue; } $customVariables = $this->getCustomVariables(); if (!empty($customVariables)) { Common::printDebug("Page level Custom Variables: "); Common::printDebug($customVariables); } $visitAction = array_merge($visitAction, $customVariables); $fields = implode(", ", array_keys($visitAction)); $bind = array_values($visitAction); $values = Common::getSqlStringFieldsArray($visitAction); $sql = "INSERT INTO " . Common::prefixTable('log_link_visit_action') . " ({$fields}) VALUES ({$values})"; Tracker::getDatabase()->query($sql, $bind); $this->idLinkVisitAction = Tracker::getDatabase()->lastInsertId(); $visitAction['idlink_va'] = $this->idLinkVisitAction; Common::printDebug("Inserted new action:"); Common::printDebug($visitAction); /** * Triggered after successfully persisting a [visit action entity](/guides/persistence-and-the-mysql-backend#visit-actions). * * @param Action $tracker Action The Action tracker instance. * @param array $visitAction The visit action entity that was persisted. Read * [this](/guides/persistence-and-the-mysql-backend#visit-actions) to see what it contains. */ Piwik::postEvent('Tracker.recordAction', array($trackerAction = $this, $visitAction)); }
/** * @param Request $request * @param Visitor $visitor * @param Action|null $action * @return mixed */ public function onNewVisit(Request $request, Visitor $visitor, $action) { return Date::getDatetimeFromTimestamp($request->getCurrentTimestamp()); }
/** * Returns true if the last action was done during the last 30 minutes * @return bool */ protected function isLastActionInTheSameVisit(Visitor $visitor) { $lastActionTime = $visitor->getVisitorColumn('visit_last_action_time'); return isset($lastActionTime) && false !== $lastActionTime && $lastActionTime > $this->request->getCurrentTimestamp() - Config::getInstance()->Tracker['visit_standard_length']; }
/** * By default, we look back 30 minutes to find a previous visitor (for performance reasons). * In some cases, it is useful to look back and count unique visitors more accurately. You can set custom lookback window in * [Tracker] window_look_back_for_visitor * * The returned value is the window range (Min, max) that the matched visitor should fall within * * @return array( datetimeMin, datetimeMax ) */ protected function getWindowLookupThisVisit(Request $request) { $lookAheadNSeconds = $this->visitStandardLength; $lookBackNSeconds = $this->visitStandardLength; if ($this->lookBackNSecondsCustom > $lookBackNSeconds) { $lookBackNSeconds = $this->lookBackNSecondsCustom; } $timeLookBack = date('Y-m-d H:i:s', $request->getCurrentTimestamp() - $lookBackNSeconds); $timeLookAhead = date('Y-m-d H:i:s', $request->getCurrentTimestamp() + $lookAheadNSeconds); return array($timeLookBack, $timeLookAhead); }
/** * @param Request $request * @return array */ public function trackRequest(Request $request) { if ($request->isEmptyRequest()) { Common::printDebug("The request is empty"); } else { Common::printDebug("Current datetime: " . date("Y-m-d H:i:s", $request->getCurrentTimestamp())); $visit = Visit\Factory::make(); $visit->setRequest($request); $visit->handle(); } // increment successfully logged request count. make sure to do this after try-catch, // since an excluded visit is considered 'successfully logged' ++$this->countOfLoggedRequests; }
public function onNewAction(Request $request, Visitor $visitor, Action $action) { $timestamp = $request->getCurrentTimestamp(); return Tracker::getDatetimeFromTimestamp($timestamp); }
/** * Returns true if the last action was not today. * @param VisitProperties $visitor * @return bool */ private function wasLastActionNotToday(VisitProperties $visitProperties, Request $request) { $lastActionTime = $visitProperties->getProperty('visit_last_action_time'); if (empty($lastActionTime)) { return false; } $idSite = $request->getIdSite(); $timezone = $this->getTimezoneForSite($idSite); if (empty($timezone)) { throw new UnexpectedWebsiteFoundException('An unexpected website was found, check idSite in the request'); } $date = Date::factory((int) $lastActionTime, $timezone); $now = $request->getCurrentTimestamp(); $now = Date::factory((int) $now, $timezone); return $date->toString() !== $now->toString(); }