diff options
author | Stefan Giehl <stefan@matomo.org> | 2021-11-26 17:35:41 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-11-26 17:35:41 +0300 |
commit | 7f1ba0936c83e06356a58396be55cbb4abaf0e1b (patch) | |
tree | 7b045d1a4f87d05a566880abbaa29003460e2560 /plugins/Actions | |
parent | 4a089cb5d0b8777e3a378af350fdb726b69afcd8 (diff) |
Fix time on page calculation in visits log (#18294)
* Try to fix time on page calculation in visits log
* fix calculation of last page view
* updates expected test files
* updates submodules
Diffstat (limited to 'plugins/Actions')
-rw-r--r-- | plugins/Actions/VisitorDetails.php | 75 |
1 files changed, 50 insertions, 25 deletions
diff --git a/plugins/Actions/VisitorDetails.php b/plugins/Actions/VisitorDetails.php index e850e2fb06..36c8c4fa50 100644 --- a/plugins/Actions/VisitorDetails.php +++ b/plugins/Actions/VisitorDetails.php @@ -55,52 +55,67 @@ class VisitorDetails extends VisitorDetailsAbstract $nextActionId = 0; foreach ($actionDetails as $idx => &$action) { - if ($idx < $nextActionId || !$this->shouldHandleAction($action)) { - continue; // skip to next action having timeSpentRef + if ($idx < $nextActionId || !$this->isPageView($action)) { + unset($action['timeSpentRef']); + continue; // skip to next page view } + $action['timeSpent'] = 0; + // search for next action with timeSpentRef - $nextActionId = $idx + 1; + $nextActionId = $idx; $nextAction = null; - while (isset($actionDetails[$nextActionId]) && - (!$this->shouldHandleAction($actionDetails[$nextActionId]) || - !array_key_exists('timeSpentRef', $actionDetails[$nextActionId]))) { + do { $nextActionId++; - } - $nextAction = isset($actionDetails[$nextActionId]) ? $actionDetails[$nextActionId] : null; - // Set the time spent for this action (which is the timeSpentRef of the next action) - if ($nextAction) { - $action['timeSpent'] = $nextAction['timeSpentRef']; - } else { + $nextAction = isset($actionDetails[$nextActionId]) ? $actionDetails[$nextActionId] : null; - // Last action of a visit. - // By default, Piwik does not know how long the user stayed on the page - // If enableHeartBeatTimer() is used in piwik.js then we can find the accurate time on page for the last pageview - $visitTotalTime = $visitorDetails['visitDuration']; - $timeOfLastAction = Date::factory($action['serverTimePretty'])->getTimestamp(); + if (is_null($nextAction)) { + // Last action of a visit. + // By default, Matomo does not know how long the user stayed on the page + // If enableHeartBeatTimer() is used in piwik.js then we can find the accurate time on page for the last pageview + $visitTotalTime = $visitorDetails['visitDuration']; + $timeOfLastAction = Date::factory($action['serverTimePretty'])->getTimestamp(); - $timeSpentOnAllActionsApartFromLastOne = ($timeOfLastAction - $visitorDetails['firstActionTimestamp']); - $timeSpentOnPage = $visitTotalTime - $timeSpentOnAllActionsApartFromLastOne; + $timeSpentOnAllActionsApartFromLastOne = ($timeOfLastAction - $visitorDetails['firstActionTimestamp']); + $timeSpentOnPage = $visitTotalTime - $timeSpentOnAllActionsApartFromLastOne; - // Safe net, we assume the time is correct when it's more than 10 seconds - if ($timeSpentOnPage > 10) { - $action['timeSpent'] = $timeSpentOnPage; + // Safe net, we assume the time is correct when it's more than 10 seconds + if ($timeSpentOnPage > 10) { + $action['timeSpent'] = $timeSpentOnPage; + } + break; + } + + if (!array_key_exists('timeSpentRef', $nextAction)) { + continue; + } + + // Set the time spent for this action (which is the timeSpentRef of the next action) + if ($nextAction) { + $action['timeSpent'] += $nextAction['timeSpentRef'] ?? 0; + } + + // sum spent time until next page view + if ($this->isPageView($nextAction)) { + break; } - } + + } while (isset($actionDetails[$nextActionId])); if (isset($action['timeSpent'])) { $action['timeSpentPretty'] = $formatter->getPrettyTimeFromSeconds($action['timeSpent'], true); } - unset($action['timeSpentRef']); // not needed after timeSpent is added + unset($action['timeSpentRef']); } $actions = $actionDetails; } - private function shouldHandleAction($action) { + private function shouldHandleAction($action) + { $actionTypesToHandle = array( Action::TYPE_PAGE_URL, Action::TYPE_PAGE_TITLE, @@ -113,6 +128,16 @@ class VisitorDetails extends VisitorDetailsAbstract return in_array($action['type'], $actionTypesToHandle) || !empty($action['eventType']); } + private function isPageView($action) + { + $pageViewTypes = array( + Action::TYPE_PAGE_URL, + Action::TYPE_PAGE_TITLE, + ); + + return in_array($action['type'], $pageViewTypes); + } + public function extendActionDetails(&$action, $nextAction, $visitorDetails) { $formatter = new Formatter(); |