From d8ed9a11808fbe89cf4f13df0afee1a27a4944d7 Mon Sep 17 00:00:00 2001 From: mattpiwik <matthieu.aubry@gmail.com> Date: Mon, 16 May 2011 22:37:02 +0000 Subject: [PATCH] Refs #898 * New segment visitType=returningCustomer for visits that are returning, and bought something in a previous visit + integration tests Refs #2432 * Tracking Custom vars per page + PHP Tracking API + tests * TODO: JS API + js tests + Reporting Also trying to improve mysqli build.. git-svn-id: http://dev.piwik.org/svn/trunk@4709 59fd770c-687e-43c8-a1e3-f5a4ff64c105 --- core/Archive/Array/IndexedByDate.php | 2 +- core/Archive/Single.php | 2 +- core/Db/Schema/Myisam.php | 10 ++ core/Segment.php | 2 +- core/Tracker/Action.php | 46 ++++--- core/Tracker/Visit.php | 45 ++++--- core/Updates/1.5-b2.php | 41 +++++++ core/Version.php | 2 +- lang/en.php | 1 + libs/PiwikTracker/PiwikTracker.php | 50 +++++++- plugins/API/API.php | 6 +- plugins/Goals/Controller.php | 2 +- plugins/Goals/Goals.php | 1 - plugins/Live/Visitor.php | 4 +- plugins/Live/templates/lastVisits.tpl | 2 +- plugins/Live/templates/visitorLog.tpl | 2 +- plugins/Referers/Referers.php | 1 - plugins/VisitFrequency/VisitFrequency.php | 2 +- tests/integration/Main.test.php | 25 ++-- ...eportMetadata__API.getSegmentsMetadata.xml | 4 +- ...Items_GoalAbandonedCart__Goals.get_day.xml | 2 +- ...tems_GoalAbandonedCart__Goals.get_week.xml | 2 +- ...ithItems_GoalMatchTitle__Goals.get_day.xml | 2 +- ...thItems_GoalMatchTitle__Goals.get_week.xml | 2 +- ...rderWithItems_GoalOrder__Goals.get_day.xml | 2 +- ...derWithItems_GoalOrder__Goals.get_week.xml | 2 +- ...erWithItems_GoalOverall__Goals.get_day.xml | 4 +- ...rWithItems_GoalOverall__Goals.get_week.xml | 4 +- ...Ordered__Live.getLastVisitsDetails_day.xml | 10 +- ...ntAbandonedCart__VisitsSummary.get_day.xml | 4 +- ...entNewVisitors__VisitsSummary.get_week.xml | 13 ++ ...mentNoEcommerce__VisitsSummary.get_day.xml | 16 +-- ...rderedSomething__VisitsSummary.get_day.xml | 4 +- ...rningCustomers__VisitsSummary.get_week.xml | 13 ++ ...urningVisitors__VisitsSummary.get_week.xml | 13 ++ ...rWithItems__API.getProcessedReport_day.xml | 6 +- ...ecommerceOrderWithItems__Goals.get_day.xml | 4 +- ...commerceOrderWithItems__Goals.get_week.xml | 4 +- ...thItems__Live.getLastVisitsDetails_day.xml | 114 ++++++++++++++---- ...ithItems__UserCountry.getContinent_day.xml | 8 +- ...rWithItems__UserCountry.getCountry_day.xml | 8 +- 41 files changed, 362 insertions(+), 125 deletions(-) create mode 100644 core/Updates/1.5-b2.php create mode 100644 tests/integration/expected/test_ecommerceOrderWithItems_SegmentNewVisitors__VisitsSummary.get_week.xml create mode 100644 tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningCustomers__VisitsSummary.get_week.xml create mode 100644 tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningVisitors__VisitsSummary.get_week.xml diff --git a/core/Archive/Array/IndexedByDate.php b/core/Archive/Array/IndexedByDate.php index 6783e39f29..ecbc5cab1f 100644 --- a/core/Archive/Array/IndexedByDate.php +++ b/core/Archive/Array/IndexedByDate.php @@ -114,7 +114,7 @@ class Piwik_Archive_Array_IndexedByDate extends Piwik_Archive_Array foreach($values as $value) { $timestamp = Piwik_Date::factory($value['startDate'])->getTimestamp(); - $arrayValues[$timestamp][$value['name']] = (float)$value['value']; + $arrayValues[$timestamp][$value['name']] = round((float)$value['value'],2); } } diff --git a/core/Archive/Single.php b/core/Archive/Single.php index af56b6acf8..8bbd96f7da 100644 --- a/core/Archive/Single.php +++ b/core/Archive/Single.php @@ -421,7 +421,7 @@ class Piwik_Archive_Single extends Piwik_Archive public function getNumeric( $name ) { // we cast the result as float because returns false when no visitors - return (float)$this->get($name, 'numeric'); + return round((float)$this->get($name, 'numeric'), 2); } diff --git a/core/Db/Schema/Myisam.php b/core/Db/Schema/Myisam.php index bff0fc44b2..25930c348d 100644 --- a/core/Db/Schema/Myisam.php +++ b/core/Db/Schema/Myisam.php @@ -303,6 +303,16 @@ class Piwik_Db_Schema_Myisam implements Piwik_Db_Schema_Interface idaction_name INTEGER(10) UNSIGNED, idaction_name_ref INTEGER(10) UNSIGNED NOT NULL, time_spent_ref_action INTEGER(10) UNSIGNED NOT NULL, + custom_var_k1 VARCHAR(50) DEFAULT NULL, + custom_var_v1 VARCHAR(50) DEFAULT NULL, + custom_var_k2 VARCHAR(50) DEFAULT NULL, + custom_var_v2 VARCHAR(50) DEFAULT NULL, + custom_var_k3 VARCHAR(50) DEFAULT NULL, + custom_var_v3 VARCHAR(50) DEFAULT NULL, + custom_var_k4 VARCHAR(50) DEFAULT NULL, + custom_var_v4 VARCHAR(50) DEFAULT NULL, + custom_var_k5 VARCHAR(50) DEFAULT NULL, + custom_var_v5 VARCHAR(50) DEFAULT NULL, PRIMARY KEY(idlink_va), INDEX index_idvisit(idvisit), INDEX index_idsite_servertime ( idsite, server_time ) diff --git a/core/Segment.php b/core/Segment.php index 110a0736a9..096059ad01 100644 --- a/core/Segment.php +++ b/core/Segment.php @@ -128,7 +128,7 @@ class Piwik_Segment { throw new Exception("Segment '$name' is not a supported segment."); } - return array( $sqlName, $expression[1], $value ); + return array( $sqlName, $matchType, $value ); } public function getString() diff --git a/core/Tracker/Action.php b/core/Tracker/Action.php index 49f635bf77..1c89497795 100644 --- a/core/Tracker/Action.php +++ b/core/Tracker/Action.php @@ -380,20 +380,36 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface $idActionName = in_array($this->getActionType(), array(Piwik_Tracker_Action::TYPE_ACTION_NAME, Piwik_Tracker_Action::TYPE_ACTION_URL)) ? $this->getIdActionName() : null; - 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) - VALUES (?,?,?,?,?,?,?,?,?)", - array( $idVisit, - $this->idSite, - $visitorIdCookie, - Piwik_Tracker::getDatetimeFromTimestamp($this->timestamp), - (int)$this->getIdActionUrl(), - $idActionName, - $idRefererActionUrl, - $idRefererActionName, - $timeSpentRefererAction - )); + $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(); @@ -405,7 +421,7 @@ class Piwik_Tracker_Action implements Piwik_Tracker_Action_Interface 'idRefererActionName' => $idRefererActionName, 'timeSpentRefererAction' => $timeSpentRefererAction, ); - printDebug($info); + printDebug($insertWithoutNulls); /* * send the Action object ($this) and the list of ids ($info) as arguments to the event diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php index 1162ea1585..37dc883603 100644 --- a/core/Tracker/Visit.php +++ b/core/Tracker/Visit.php @@ -136,7 +136,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface { return; } - $this->visitorCustomVariables = $this->getCustomVariables(); + $this->visitorCustomVariables = self::getCustomVariables($scope = 'visit', $this->request); $this->goalManager = new Piwik_Tracker_GoalManager(); $someGoalsConverted = $visitIsConverted = false; @@ -468,11 +468,16 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface } $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; + if($daysSinceLastOrder < 0) + { + $daysSinceLastOrder = 0; + } + $isReturningCustomer = true; } // User settings @@ -494,7 +499,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface 'idsite' => $this->idsite, 'visitor_localtime' => $localTime, 'idvisitor' => $idcookie, - 'visitor_returning' => $visitCount > 1 || $this->isVisitorKnown() ? 1 : 0, + 'visitor_returning' => $isReturningCustomer ? 2 : ($visitCount > 1 || $this->isVisitorKnown() ? 1 : 0), 'visitor_count_visits' => $visitCount, 'visitor_days_since_last' => $daysSinceLastVisit, 'visitor_days_since_order' => $daysSinceLastOrder, @@ -963,16 +968,26 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface } } - protected function getCustomVariables() + static public function getCustomVariables($scope, $request) { - $customVar = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar( '_cvar', '', 'string', $this->request)); + if($scope == 'visit') + { + $parameter = '_cvar'; + $debug = 'Visit level'; + } + else + { + $parameter = 'cvar'; + $debug = 'Page level'; + } + $customVar = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar( $parameter, '', 'string', $request)); $customVar = @json_decode($customVar, $assoc = true); if(!is_array($customVar)) { return array(); } - $visitorCustomVar = array(); + $customVariables = array(); foreach($customVar as $id => $keyValue) { $id = (int)$id; @@ -990,20 +1005,20 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface // We keep in the URL when Custom Variable have empty names // and values, as it means they can be deleted server side - $key = $this->truncateCustomVariable($keyValue[0]); - $value = $this->truncateCustomVariable($keyValue[1]); - $visitorCustomVar['custom_var_k'.$id] = $key; - $visitorCustomVar['custom_var_v'.$id] = $value; + $key = self::truncateCustomVariable($keyValue[0]); + $value = self::truncateCustomVariable($keyValue[1]); + $customVariables['custom_var_k'.$id] = $key; + $customVariables['custom_var_v'.$id] = $value; } - if(!empty($visitorCustomVar)) + if(!empty($customVariables)) { - printDebug("Visitor Custom Variables: "); - printDebug($visitorCustomVar); + printDebug("$debug Custom Variables: "); + printDebug($customVariables); } - return $visitorCustomVar; + return $customVariables; } - protected function truncateCustomVariable($input) + static public function truncateCustomVariable($input) { return substr($input, 0, Piwik_Tracker::MAX_LENGTH_CUSTOM_VARIABLE); } diff --git a/core/Updates/1.5-b2.php b/core/Updates/1.5-b2.php new file mode 100644 index 0000000000..34a2463a88 --- /dev/null +++ b/core/Updates/1.5-b2.php @@ -0,0 +1,41 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * @version $Id$ + * + * @category Piwik + * @package Updates + */ + +/** + * @package Updates + */ +class Piwik_Updates_1_5_b2 extends Piwik_Updates +{ + static function getSql($schema = 'Myisam') + { + $tables = Piwik::getTablesCreateSql(); + + return array( + 'ALTER TABLE `'. Piwik_Common::prefixTable('log_link_visit_action') .'` + ADD custom_var_k1 VARCHAR(50) DEFAULT NULL AFTER time_spent_ref_action, + ADD custom_var_v1 VARCHAR(50) DEFAULT NULL, + ADD custom_var_k2 VARCHAR(50) DEFAULT NULL, + ADD custom_var_v2 VARCHAR(50) DEFAULT NULL, + ADD custom_var_k3 VARCHAR(50) DEFAULT NULL, + ADD custom_var_v3 VARCHAR(50) DEFAULT NULL, + ADD custom_var_k4 VARCHAR(50) DEFAULT NULL, + ADD custom_var_v4 VARCHAR(50) DEFAULT NULL, + ADD custom_var_k5 VARCHAR(50) DEFAULT NULL, + ADD custom_var_v5 VARCHAR(50) DEFAULT NULL' => false, + ); + } + + static function update() + { + Piwik_Updater::updateDatabase(__FILE__, self::getSql()); + } +} diff --git a/core/Version.php b/core/Version.php index f9cabbd42d..3a7c7cd1c8 100644 --- a/core/Version.php +++ b/core/Version.php @@ -17,5 +17,5 @@ */ final class Piwik_Version { - const VERSION = '1.5-b1'; + const VERSION = '1.5-b2'; } diff --git a/lang/en.php b/lang/en.php index de89eff4d6..f2dcd8251f 100644 --- a/lang/en.php +++ b/lang/en.php @@ -47,6 +47,7 @@ $translations = array( 'General_VisitorIP' => 'Visitor IP', 'General_VisitorID' => 'Visitor ID', 'General_VisitType' => 'Visitor type', + 'General_VisitTypeExample' => 'For example, to select all visitors who have returned to the website, including those who have bought something in their previous visits, the API request would contain %s', 'General_DaysSinceLastVisit' => 'Days since last visit', 'General_DaysSinceFirstVisit' => 'Days since first visit', 'General_DaysSinceLastEcommerceOrder' => 'Days since last Ecommerce order', diff --git a/libs/PiwikTracker/PiwikTracker.php b/libs/PiwikTracker/PiwikTracker.php index a7f04e1254..a3e90672a9 100644 --- a/libs/PiwikTracker/PiwikTracker.php +++ b/libs/PiwikTracker/PiwikTracker.php @@ -63,7 +63,6 @@ class PiwikTracker function __construct( $idSite, $apiUrl = false ) { $this->cookieSupport = true; - $this->userAgent = false; $this->localHour = false; $this->localMinute = false; @@ -71,10 +70,12 @@ class PiwikTracker $this->hasCookies = false; $this->plugins = false; $this->visitorCustomVar = false; + $this->pageCustomVar = false; $this->customData = false; $this->forcedDatetime = false; $this->token_auth = false; $this->attributionInfo = false; + $this->ecommerceLastOrderTimestamp = false; $this->ecommerceItems = array(); $this->requestCookie = ''; @@ -146,14 +147,26 @@ class PiwikTracker * @param int Custom variable slot ID from 1-5 * @param string Custom variable name * @param string Custom variable value + * @param string Custom variable scope. Possible values: visit, page */ - public function setCustomVariable($id, $name, $value) + public function setCustomVariable($id, $name, $value, $scope = 'visit') { if(!is_int($id)) { throw new Exception("Parameter id to setCustomVariable should be an integer"); } - $this->visitorCustomVar[$id] = array($name, $value); + if($scope == 'page') + { + $this->pageCustomVar[$id] = array($name, $value); + } + elseif($scope == 'visit') + { + $this->visitorCustomVar[$id] = array($name, $value); + } + else + { + throw new Exception("Invalid 'scope' parameter value"); + } } /** @@ -163,11 +176,21 @@ class PiwikTracker * can be read by PHP from the $_COOKIE array. * * @param int Custom Variable integer index to fetch from cookie. Should be a value from 1 to 5 - * @return array An array with this format: array( 0 => CustomVariableName, 1 => CustomVariableValue ) + * @param string Custom variable scope. Possible values: visit, page + * + * @return array|false An array with this format: array( 0 => CustomVariableName, 1 => CustomVariableValue ) * @see Piwik.js getCustomVariable() */ - public function getCustomVariable($id) + public function getCustomVariable($id, $scope = 'visit') { + if($scope == 'page') + { + return isset($this->pageCustomVar[$id]) ? $this->pageCustomVar[$id] : false; + } + else if($scope != 'visit') + { + throw new Exception("Invalid 'scope' parameter value"); + } if(!empty($this->visitorCustomVar[$id])) { return $this->visitorCustomVar[$id]; @@ -337,7 +360,7 @@ class PiwikTracker } $url = $this->getUrlTrackEcommerce($grandTotal, $subTotal, $tax, $shipping, $discount); $url .= '&ec_id=' . urlencode($orderId); - + $this->ecommerceLastOrderTimestamp = $this->getTimestamp(); return $url; } @@ -701,6 +724,17 @@ class PiwikTracker return $content; } + /** + * Returns current timestamp, or forced timestamp/datetime if it was set + * @return string|int + */ + protected function getTimestamp() + { + return !empty($this->forcedDatetime) + ? strtotime($this->forcedDatetime) + : time(); + } + /** * @ignore */ @@ -736,8 +770,12 @@ class PiwikTracker (($this->localHour !== false && $this->localMinute !== false && $this->localSecond !== false) ? '&h=' . $this->localHour . '&m=' . $this->localMinute . '&s=' . $this->localSecond : '' ). (!empty($this->width) && !empty($this->height) ? '&res=' . $this->width . 'x' . $this->height : '') . (!empty($this->hasCookies) ? '&cookie=' . $this->hasCookies : '') . + (!empty($this->ecommerceLastOrderTimestamp) ? '&_ects=' . urlencode($this->ecommerceLastOrderTimestamp) : '') . + + // Various important attributes (!empty($this->customData) ? '&data=' . $this->customData : '') . (!empty($this->visitorCustomVar) ? '&_cvar=' . urlencode(json_encode($this->visitorCustomVar)) : '') . + (!empty($this->pageCustomVar) ? '&cvar=' . urlencode(json_encode($this->pageCustomVar)) : '') . // URL parameters '&url=' . urlencode($this->pageUrl) . diff --git a/plugins/API/API.php b/plugins/API/API.php index 93b46a2e25..ea470f89e6 100644 --- a/plugins/API/API.php +++ b/plugins/API/API.php @@ -165,11 +165,11 @@ class Piwik_API_API $segments[] = array( 'type' => 'dimension', 'category' => 'Visit', - 'name' => 'General_VisitType', + 'name' => Piwik_Translate('General_VisitType') . ". ".Piwik_Translate('General_VisitTypeExample', '"&segment=visitorType==returning,visitorType==returningCustomer"'), 'segment' => 'visitorType', - 'acceptedValues' => 'new, returning', + 'acceptedValues' => 'new, returning, returningCustomer', 'sqlSegment' => 'visitor_returning', - 'sqlFilter' => create_function('$type', 'return $type == "new" ? 0 : 1;'), + 'sqlFilter' => create_function('$type', 'return $type == "new" ? 0 : ($type == "returning" ? 1 : 2);'), ); $segments[] = array( 'type' => 'metric', diff --git a/plugins/Goals/Controller.php b/plugins/Goals/Controller.php index 728caec14f..fbdb695e4f 100644 --- a/plugins/Goals/Controller.php +++ b/plugins/Goals/Controller.php @@ -83,7 +83,7 @@ class Piwik_Goals_Controller extends Piwik_Controller $view->topDimensions = $this->getTopDimensions($idGoal); // conversion rate for new and returning visitors - $segment = 'visitorType==returning'; + $segment = 'visitorType==returning,visitorType==returningCustomer'; $conversionRateReturning = Piwik_Goals_API::getInstance()->getConversionRate($this->idSite, Piwik_Common::getRequestVar('period'), Piwik_Common::getRequestVar('date'), $segment, $idGoal); $view->conversion_rate_returning = $this->formatConversionRate($conversionRateReturning); $segment = 'visitorType==new'; diff --git a/plugins/Goals/Goals.php b/plugins/Goals/Goals.php index 1f88750e8d..17aa19ce34 100644 --- a/plugins/Goals/Goals.php +++ b/plugins/Goals/Goals.php @@ -377,7 +377,6 @@ class Piwik_Goals extends Piwik_Plugin ); foreach($totalAllGoals as $recordName => $value) { - $value = round($value, 2); $archiveProcessing->insertNumericRecord($recordName, $value); } } diff --git a/plugins/Live/Visitor.php b/plugins/Live/Visitor.php index 77b97c0c81..5ddea435b1 100644 --- a/plugins/Live/Visitor.php +++ b/plugins/Live/Visitor.php @@ -42,7 +42,7 @@ class Piwik_Live_Visitor 'idVisit' => $this->getIdVisit(), 'visitIp' => $this->getIp(), 'visitorId' => $this->getVisitorId(), - 'visitorType' => $this->isVisitorReturning() ? 'returning' : 'new', + 'visitorType' => $this->getVisitorReturning() == 2 ? 'returningCustomer' : ($this->getVisitorReturning() == 1 ? 'returning' : 'new'), 'visitConverted' => $this->isVisitorGoalConverted(), 'visitEcommerceStatus' => $this->getVisitEcommerceStatus(), @@ -167,7 +167,7 @@ class Piwik_Live_Visitor return Piwik::getPrettyTimeFromSeconds($this->details['visit_total_time']); } - function isVisitorReturning() + function getVisitorReturning() { return $this->details['visitor_returning']; } diff --git a/plugins/Live/templates/lastVisits.tpl b/plugins/Live/templates/lastVisits.tpl index c0d0fab5fb..e6449e1c4f 100644 --- a/plugins/Live/templates/lastVisits.tpl +++ b/plugins/Live/templates/lastVisits.tpl @@ -13,7 +13,7 @@ <img src="themes/default/images/goal.png" /> <span class='hash'>#</span>{$visitor.goalConversions} </span>{/if} - {if $visitor.visitorType=='returning'} <img src="plugins/Live/templates/images/returningVisitor.gif" title="{'General_ReturningVisitor'|translate}" />{/if} + {if $visitor.visitorType=='returning' || $visitor.visitorType=='returningCustomer'} <img src="plugins/Live/templates/images/returningVisitor.gif" title="{'General_ReturningVisitor'|translate}" />{/if} {if $visitor.visitIp}- <span title="{if !empty($visitor.visitorId)}{'General_VisitorID'|translate}: {$visitor.visitorId}{/if}">IP: {$visitor.visitIp}</span>{/if} </div> <!--<div class="settings"></div>--> diff --git a/plugins/Live/templates/visitorLog.tpl b/plugins/Live/templates/visitorLog.tpl index 03686c2874..92d55097e4 100644 --- a/plugins/Live/templates/visitorLog.tpl +++ b/plugins/Live/templates/visitorLog.tpl @@ -64,7 +64,7 @@ <img src="{$visitor.columns.countryFlag}" title="{$visitor.columns.country}, Provider {$visitor.columns.provider}" /> <img src="{$visitor.columns.browserIcon}" title="{$visitor.columns.browserName} with plugins {$visitor.columns.plugins} enabled" /> <img src="{$visitor.columns.operatingSystemIcon}" title="{$visitor.columns.operatingSystem}, {$visitor.columns.resolution} ({$visitor.columns.screenType})" /> - {if $visitor.columns.visitorType=='returning'} + {if $visitor.columns.visitorType=='returning' || $visitor.columns.visitorType=='returningCustomer'} <img src="plugins/Live/templates/images/returningVisitor.gif" title="{'General_ReturningVisitor'|translate}" /> {/if} {if $visitor.columns.visitConverted} diff --git a/plugins/Referers/Referers.php b/plugins/Referers/Referers.php index 4d5fa40697..be08447b58 100644 --- a/plugins/Referers/Referers.php +++ b/plugins/Referers/Referers.php @@ -378,7 +378,6 @@ class Piwik_Referers extends Piwik_Plugin { $this->distinctUrls[$row['referer_url']] = true; } - break; case Piwik_Common::REFERER_TYPE_CAMPAIGN: diff --git a/plugins/VisitFrequency/VisitFrequency.php b/plugins/VisitFrequency/VisitFrequency.php index 13edc7205f..3b2c6c09eb 100644 --- a/plugins/VisitFrequency/VisitFrequency.php +++ b/plugins/VisitFrequency/VisitFrequency.php @@ -111,7 +111,7 @@ class Piwik_VisitFrequency extends Piwik_Plugin WHERE visit_last_action_time >= ? AND visit_last_action_time <= ? AND idsite = ? - AND visitor_returning = 1"; + AND visitor_returning >= 1"; $row = $archiveProcessing->db->fetchRow($query, array( $archiveProcessing->getStartDatetimeUTC(), $archiveProcessing->getEndDatetimeUTC(), $archiveProcessing->idsite ) ); if($row === false || $row === null) diff --git a/tests/integration/Main.test.php b/tests/integration/Main.test.php index 2f60676d83..956790358c 100644 --- a/tests/integration/Main.test.php +++ b/tests/integration/Main.test.php @@ -43,27 +43,32 @@ class Test_Piwik_Integration_Main extends Test_Integration $t = $this->getTracker($idSite, $dateTime, $defaultInit = true); // Record 1st page view $t->setUrl( 'http://example.org/index.htm' ); + $t->setCustomVariable(3, 'ec_p', 'PRODUCT name', 'page'); + $t->setCustomVariable(4, 'ec_s', 'SKU2', 'page'); + $category = 'Electronics & Cameras'; + $t->setCustomVariable(5, 'ec_c', $category, 'page'); + $this->assertTrue($t->getCustomVariable(5, 'page') == $category); $this->checkResponse($t->doTrackPageView( 'incredible title!')); - $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.3)->getDatetime()); + $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(1.3)->getDatetime()); //Add to cart $t->addEcommerceItem($sku = 'SKU VERY nice indeed', $name = 'PRODUCT name' , $category = 'Electronics & Cameras', $price = 500, $quantity = 1); $t->addEcommerceItem($sku = 'SKU VERY nice indeed', $name = 'PRODUCT name' , $category = 'Electronics & Cameras', $price = 500, $quantity = 2); $this->checkResponse($t->doTrackEcommerceCartUpdate($grandTotal = 1000)); - $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.4)->getDatetime()); + $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(1.4)->getDatetime()); //Order $t->addEcommerceItem($sku = 'SKU VERY nice indeed', $name = 'PRODUCT name' , $category = 'Electronics & Cameras', $price = 500, $quantity = 2); $this->checkResponse($t->doTrackEcommerceOrder($orderId = '937nsjusu 3894', $grandTotal = 1111.11, $subTotal = 1000, $tax = 111, $shipping = 0.11, $discount = 666)); - $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.5)->getDatetime()); + $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(1.5)->getDatetime()); //Another Order $t->addEcommerceItem($sku = 'SKU2', $name = 'Canon SLR' , $category = 'Electronics & Cameras', $price = 1500, $quantity = 1); $this->checkResponse($t->doTrackEcommerceOrder($orderId = '1037nsjusu4s3894', $grandTotal = 2000, $subTotal = 1500, $tax = 400, $shipping = 100, $discount = 0)); // Refresh the page with the receipt for the second order, should be ignored - $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.55)->getDatetime()); + $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(1.55)->getDatetime()); // Recording the same ecommerce order, this time with some crazy amount and quantity // we test that both the order, and the products, are not updated on subsequent "Receipt" views @@ -71,7 +76,7 @@ class Test_Piwik_Integration_Main extends Test_Integration $this->checkResponse($t->doTrackEcommerceOrder($orderId = '1037nsjusu4s3894', $grandTotal = 20000000, $subTotal = 1500, $tax = 400, $shipping = 100, $discount = 0)); // Leave with an opened cart - $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.6)->getDatetime()); + $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(1.6)->getDatetime()); // No category $t->addEcommerceItem($sku = 'SKU IN ABANDONED CART ONE', $name = 'PRODUCT ONE LEFT in cart' , $category = '', $price = 500.11111112, $quantity = 2); $this->checkResponse($t->doTrackEcommerceCartUpdate($grandTotal = 1000)); @@ -79,7 +84,7 @@ class Test_Piwik_Integration_Main extends Test_Integration // Record the same visit leaving twice an abandoned cart foreach(array(0, 5, 24) as $offsetHour) { - $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour($offsetHour + 0.65)->getDatetime()); + $t->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour($offsetHour + 1.65)->getDatetime()); // Also recording an order the day after if($offsetHour >= 24) { @@ -146,10 +151,16 @@ class Test_Piwik_Integration_Main extends Test_Integration $segment = 'visitEcommerceStatus==abandonedCart,visitEcommerceStatus==orderedThenAbandonedCart'; $this->callGetApiCompareOutput(__FUNCTION__ . '_SegmentAbandonedCart', 'xml', $idSite, $dateTime, $periods = array('day'), $setDateLastN = false, $language = false, $segment); + $segment = 'visitorType==new'; + $this->callGetApiCompareOutput(__FUNCTION__ . '_SegmentNewVisitors', 'xml', $idSite, $dateTime, $periods = array('week'), $setDateLastN = false, $language = false, $segment); + $segment = 'visitorType==returning'; + $this->callGetApiCompareOutput(__FUNCTION__ . '_SegmentReturningVisitors', 'xml', $idSite, $dateTime, $periods = array('week'), $setDateLastN = false, $language = false, $segment); + $segment = 'visitorType==returningCustomer'; + $this->callGetApiCompareOutput(__FUNCTION__ . '_SegmentReturningCustomers', 'xml', $idSite, $dateTime, $periods = array('week'), $setDateLastN = false, $language = false, $segment); + // test Live! output is OK also for the visit that just bought something (other visits leave an abandoned cart) $this->setApiToCall(array('Live.getLastVisitsDetails')); $this->callGetApiCompareOutput(__FUNCTION__ . '_LiveEcommerceStatusOrdered', 'xml', $idSite, Piwik_Date::factory($dateTime)->addHour( 30.65 )->getDatetime(), $periods = array('day')); -// exit; } function test_trackGoals_allowMultipleConversionsPerVisit() diff --git a/tests/integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml b/tests/integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml index 9bcc275e38..9a2be71326 100644 --- a/tests/integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml +++ b/tests/integration/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml @@ -53,9 +53,9 @@ <row> <type>dimension</type> <category>Visit</category> - <name>Visitor type</name> + <name>Visitor type. For example, to select all visitors who have returned to the website, including those who have bought something in their previous visits, the API request would contain "&segment=visitorType==returning,visitorType==returningCustomer"</name> <segment>visitorType</segment> - <acceptedValues>new, returning</acceptedValues> + <acceptedValues>new, returning, returningCustomer</acceptedValues> </row> <row> <type>dimension</type> diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_day.xml index 693e7dbc32..3d1e468761 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_day.xml @@ -2,7 +2,7 @@ <result> <nb_conversions>2</nb_conversions> <nb_visits_converted>2</nb_visits_converted> - <conversion_rate>100</conversion_rate> + <conversion_rate>66.67</conversion_rate> <revenue>5000.22</revenue> <items>6</items> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_week.xml index 5c8effaf28..4be3207e04 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_week.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalAbandonedCart__Goals.get_week.xml @@ -2,7 +2,7 @@ <result> <nb_conversions>3</nb_conversions> <nb_visits_converted>3</nb_visits_converted> - <conversion_rate>75</conversion_rate> + <conversion_rate>60</conversion_rate> <revenue>7500.33</revenue> <items>9</items> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_day.xml index fc62e5e6a5..28ecffa619 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_day.xml @@ -2,6 +2,6 @@ <result> <nb_conversions>1</nb_conversions> <nb_visits_converted>1</nb_visits_converted> - <conversion_rate>50</conversion_rate> + <conversion_rate>33.33</conversion_rate> <revenue>10</revenue> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_week.xml index c29e706e50..46934b1c19 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_week.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalMatchTitle__Goals.get_week.xml @@ -2,6 +2,6 @@ <result> <nb_conversions>1</nb_conversions> <nb_visits_converted>1</nb_visits_converted> - <conversion_rate>25</conversion_rate> + <conversion_rate>20</conversion_rate> <revenue>10</revenue> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_day.xml index 857aa10333..e2457ce0b6 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_day.xml @@ -2,7 +2,7 @@ <result> <nb_conversions>2</nb_conversions> <nb_visits_converted>1</nb_visits_converted> - <conversion_rate>50</conversion_rate> + <conversion_rate>33.33</conversion_rate> <revenue>3111.11</revenue> <revenue_subtotal>2500</revenue_subtotal> <revenue_tax>511</revenue_tax> diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_week.xml index af971d8048..5c6a2acc82 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_week.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOrder__Goals.get_week.xml @@ -2,7 +2,7 @@ <result> <nb_conversions>4</nb_conversions> <nb_visits_converted>2</nb_visits_converted> - <conversion_rate>50</conversion_rate> + <conversion_rate>40</conversion_rate> <revenue>13351.1</revenue> <revenue_subtotal>2700</revenue_subtotal> <revenue_tax>531</revenue_tax> diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_day.xml index 5867f1dd24..fc23e7158e 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_day.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" ?> <result> <nb_conversions>3</nb_conversions> - <nb_visits_converted>1</nb_visits_converted> - <conversion_rate>50</conversion_rate> + <nb_visits_converted>2</nb_visits_converted> + <conversion_rate>66.67</conversion_rate> <revenue>3121.11</revenue> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_week.xml index 3b8f443470..b45696b9b6 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_week.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_GoalOverall__Goals.get_week.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" ?> <result> <nb_conversions>5</nb_conversions> - <nb_visits_converted>3</nb_visits_converted> - <conversion_rate>75</conversion_rate> + <nb_visits_converted>4</nb_visits_converted> + <conversion_rate>80</conversion_rate> <revenue>13361.1</revenue> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_LiveEcommerceStatusOrdered__Live.getLastVisitsDetails_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_LiveEcommerceStatusOrdered__Live.getLastVisitsDetails_day.xml index d2520843fa..1c27aedd3f 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_LiveEcommerceStatusOrdered__Live.getLastVisitsDetails_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_LiveEcommerceStatusOrdered__Live.getLastVisitsDetails_day.xml @@ -2,10 +2,10 @@ <result> <row> <idSite>1</idSite> - <idVisit>4</idVisit> + <idVisit>5</idVisit> <visitIp>156.5.3.2</visitIp> - <visitorType>returning</visitorType> + <visitorType>returningCustomer</visitorType> <visitConverted>1</visitConverted> <visitEcommerceStatus>ordered</visitEcommerceStatus> <actions>1</actions> @@ -125,10 +125,10 @@ </row> <row> <idSite>1</idSite> - <idVisit>3</idVisit> + <idVisit>4</idVisit> <visitIp>156.5.3.2</visitIp> - <visitorType>returning</visitorType> + <visitorType>returningCustomer</visitorType> <visitConverted>1</visitConverted> <visitEcommerceStatus>orderedThenAbandonedCart</visitEcommerceStatus> <actions>1</actions> @@ -154,7 +154,7 @@ <visitCount>1</visitCount> <daysSinceLastVisit>0</daysSinceLastVisit> <daysSinceFirstVisit>0</daysSinceFirstVisit> - <daysSinceLastEcommerceOrder>0</daysSinceLastEcommerceOrder> + <daysSinceLastEcommerceOrder>1</daysSinceLastEcommerceOrder> <country>France</country> <countryFlag>plugins/UserCountry/flags/fr.png</countryFlag> <continent>Europe</continent> diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentAbandonedCart__VisitsSummary.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentAbandonedCart__VisitsSummary.get_day.xml index e8e1fa23a4..d8179a35c6 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentAbandonedCart__VisitsSummary.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentAbandonedCart__VisitsSummary.get_day.xml @@ -5,9 +5,9 @@ <nb_actions>2</nb_actions> <nb_visits_converted>1</nb_visits_converted> <bounce_count>2</bounce_count> - <sum_visit_length>2340</sum_visit_length> + <sum_visit_length>1260</sum_visit_length> <max_actions>1</max_actions> <bounce_rate>100%</bounce_rate> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>1170</avg_time_on_site> + <avg_time_on_site>630</avg_time_on_site> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentNewVisitors__VisitsSummary.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentNewVisitors__VisitsSummary.get_week.xml new file mode 100644 index 0000000000..a4c565ab9c --- /dev/null +++ b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentNewVisitors__VisitsSummary.get_week.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <nb_visits>1</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_actions>1</nb_actions> + <nb_visits_converted>1</nb_visits_converted> + <bounce_count>1</bounce_count> + <sum_visit_length>0</sum_visit_length> + <max_actions>1</max_actions> + <bounce_rate>100%</bounce_rate> + <nb_actions_per_visit>1</nb_actions_per_visit> + <avg_time_on_site>0</avg_time_on_site> +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentNoEcommerce__VisitsSummary.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentNoEcommerce__VisitsSummary.get_day.xml index a4933d174c..a4c565ab9c 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentNoEcommerce__VisitsSummary.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentNoEcommerce__VisitsSummary.get_day.xml @@ -1,13 +1,13 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <nb_visits>0</nb_visits> - <nb_uniq_visitors>0</nb_uniq_visitors> - <nb_actions>0</nb_actions> - <nb_visits_converted>0</nb_visits_converted> - <bounce_count>0</bounce_count> + <nb_visits>1</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_actions>1</nb_actions> + <nb_visits_converted>1</nb_visits_converted> + <bounce_count>1</bounce_count> <sum_visit_length>0</sum_visit_length> - <max_actions>0</max_actions> - <bounce_rate>0%</bounce_rate> - <nb_actions_per_visit>0</nb_actions_per_visit> + <max_actions>1</max_actions> + <bounce_rate>100%</bounce_rate> + <nb_actions_per_visit>1</nb_actions_per_visit> <avg_time_on_site>0</avg_time_on_site> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentOrderedSomething__VisitsSummary.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentOrderedSomething__VisitsSummary.get_day.xml index 95b8e6c667..407aefcdf3 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentOrderedSomething__VisitsSummary.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentOrderedSomething__VisitsSummary.get_day.xml @@ -5,9 +5,9 @@ <nb_actions>1</nb_actions> <nb_visits_converted>1</nb_visits_converted> <bounce_count>1</bounce_count> - <sum_visit_length>2340</sum_visit_length> + <sum_visit_length>1260</sum_visit_length> <max_actions>1</max_actions> <bounce_rate>100%</bounce_rate> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>2340</avg_time_on_site> + <avg_time_on_site>1260</avg_time_on_site> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningCustomers__VisitsSummary.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningCustomers__VisitsSummary.get_week.xml new file mode 100644 index 0000000000..79d67e0097 --- /dev/null +++ b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningCustomers__VisitsSummary.get_week.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <nb_visits>3</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_actions>3</nb_actions> + <nb_visits_converted>2</nb_visits_converted> + <bounce_count>3</bounce_count> + <sum_visit_length>360</sum_visit_length> + <max_actions>1</max_actions> + <bounce_rate>100%</bounce_rate> + <nb_actions_per_visit>1</nb_actions_per_visit> + <avg_time_on_site>120</avg_time_on_site> +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningVisitors__VisitsSummary.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningVisitors__VisitsSummary.get_week.xml new file mode 100644 index 0000000000..407aefcdf3 --- /dev/null +++ b/tests/integration/expected/test_ecommerceOrderWithItems_SegmentReturningVisitors__VisitsSummary.get_week.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <nb_visits>1</nb_visits> + <nb_uniq_visitors>1</nb_uniq_visitors> + <nb_actions>1</nb_actions> + <nb_visits_converted>1</nb_visits_converted> + <bounce_count>1</bounce_count> + <sum_visit_length>1260</sum_visit_length> + <max_actions>1</max_actions> + <bounce_rate>100%</bounce_rate> + <nb_actions_per_visit>1</nb_actions_per_visit> + <avg_time_on_site>1260</avg_time_on_site> +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml index 959c03d202..4be00a0fef 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems__API.getProcessedReport_day.xml @@ -60,11 +60,11 @@ <row> <label>France</label> <nb_uniq_visitors>1</nb_uniq_visitors> - <nb_visits>2</nb_visits> - <nb_actions>2</nb_actions> + <nb_visits>3</nb_visits> + <nb_actions>3</nb_actions> <revenue>$ 3121.11</revenue> <nb_actions_per_visit>1</nb_actions_per_visit> - <avg_time_on_site>00:19:30</avg_time_on_site> + <avg_time_on_site>00:07:00</avg_time_on_site> <bounce_rate>100%</bounce_rate> </row> diff --git a/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_day.xml index 5867f1dd24..fc23e7158e 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_day.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" ?> <result> <nb_conversions>3</nb_conversions> - <nb_visits_converted>1</nb_visits_converted> - <conversion_rate>50</conversion_rate> + <nb_visits_converted>2</nb_visits_converted> + <conversion_rate>66.67</conversion_rate> <revenue>3121.11</revenue> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_week.xml b/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_week.xml index 3b8f443470..b45696b9b6 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_week.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems__Goals.get_week.xml @@ -1,7 +1,7 @@ <?xml version="1.0" encoding="utf-8" ?> <result> <nb_conversions>5</nb_conversions> - <nb_visits_converted>3</nb_visits_converted> - <conversion_rate>75</conversion_rate> + <nb_visits_converted>4</nb_visits_converted> + <conversion_rate>80</conversion_rate> <revenue>13361.1</revenue> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems__Live.getLastVisitsDetails_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems__Live.getLastVisitsDetails_day.xml index 7fddc2974f..3e86fe3d0b 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems__Live.getLastVisitsDetails_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems__Live.getLastVisitsDetails_day.xml @@ -2,10 +2,10 @@ <result> <row> <idSite>1</idSite> - <idVisit>2</idVisit> + <idVisit>3</idVisit> <visitIp>156.5.3.2</visitIp> - <visitorType>returning</visitorType> + <visitorType>returningCustomer</visitorType> <visitConverted>0</visitConverted> <visitEcommerceStatus>abandonedCart</visitEcommerceStatus> <actions>1</actions> @@ -98,30 +98,14 @@ </row> <row> <idSite>1</idSite> - <idVisit>1</idVisit> + <idVisit>2</idVisit> <visitIp>156.5.3.2</visitIp> - <visitorType>new</visitorType> + <visitorType>returning</visitorType> <visitConverted>1</visitConverted> <visitEcommerceStatus>orderedThenAbandonedCart</visitEcommerceStatus> <actions>1</actions> <actionDetails> - <row> - <type>action</type> - <url>http://example.org/index.htm</url> - <pageTitle>incredible title!</pageTitle> - <pageIdAction>2</pageIdAction> - <pageId>1</pageId> - - </row> - <row> - <type>goal</type> - <goalName>triggered js ONCE</goalName> - <revenue>10</revenue> - <goalPageId>1</goalPageId> - - <url>http://example.org/index.htm</url> - </row> <row> <type>ecommerceOrder</type> <orderId>937nsjusu 3894</orderId> @@ -153,15 +137,15 @@ </actionDetails> <customVariables> </customVariables> - <goalConversions>1</goalConversions> + <goalConversions>0</goalConversions> <siteCurrency>USD</siteCurrency> <visitLocalTime>12:34:06</visitLocalTime> - <visitDuration>2340</visitDuration> - <visitDurationPretty>39 min 0s</visitDurationPretty> + <visitDuration>1260</visitDuration> + <visitDurationPretty>21 min 0s</visitDurationPretty> <visitCount>1</visitCount> <daysSinceLastVisit>0</daysSinceLastVisit> <daysSinceFirstVisit>0</daysSinceFirstVisit> @@ -270,4 +254,88 @@ </row> </ecommerce> </row> + <row> + <idSite>1</idSite> + <idVisit>1</idVisit> + <visitIp>156.5.3.2</visitIp> + + <visitorType>new</visitorType> + <visitConverted>1</visitConverted> + <visitEcommerceStatus>none</visitEcommerceStatus> + <actions>1</actions> + <actionDetails> + <row> + <type>goal</type> + <goalName>triggered js ONCE</goalName> + <revenue>10</revenue> + <goalPageId>1</goalPageId> + + <url>http://example.org/index.htm</url> + </row> + <row> + <type>action</type> + <url>http://example.org/index.htm</url> + <pageTitle>incredible title!</pageTitle> + <pageIdAction>2</pageIdAction> + <pageId>1</pageId> + + </row> + </actionDetails> + <customVariables> + </customVariables> + <goalConversions>1</goalConversions> + <siteCurrency>USD</siteCurrency> + + <visitLocalTime>12:34:06</visitLocalTime> + + + + <visitDuration>0</visitDuration> + <visitDurationPretty>0s</visitDurationPretty> + <visitCount>1</visitCount> + <daysSinceLastVisit>0</daysSinceLastVisit> + <daysSinceFirstVisit>0</daysSinceFirstVisit> + <daysSinceLastEcommerceOrder>0</daysSinceLastEcommerceOrder> + <country>France</country> + <countryFlag>plugins/UserCountry/flags/fr.png</countryFlag> + <continent>Europe</continent> + <provider>Unknown</provider> + <providerUrl>http://piwik.org/faq/general/#faq_52</providerUrl> + <referrerType>direct</referrerType> + <referrerTypeName>Direct Entry</referrerTypeName> + <referrerName></referrerName> + <referrerKeyword></referrerKeyword> + <referrerKeywordPosition></referrerKeywordPosition> + <referrerUrl></referrerUrl> + <referrerSearchEngineUrl></referrerSearchEngineUrl> + <referrerSearchEngineIcon></referrerSearchEngineIcon> + <operatingSystem>Windows XP</operatingSystem> + <operatingSystemShortName>Win XP</operatingSystemShortName> + <operatingSystemIcon>plugins/UserSettings/images/os/WXP.gif</operatingSystemIcon> + <browserFamily>gecko</browserFamily> + <browserFamilyDescription>Gecko (Firefox)</browserFamilyDescription> + <browserName>Firefox 3.6</browserName> + <browserIcon>plugins/UserSettings/images/browsers/FF.gif</browserIcon> + <screenType>normal</screenType> + <resolution>1024x768</resolution> + <screenTypeIcon>plugins/UserSettings/images/screens/normal.gif</screenTypeIcon> + <plugins>flash, java</plugins> + <pluginsIcons> + <row> + <pluginIcon>plugins/UserSettings/images/plugins/flash.gif</pluginIcon> + <pluginName>flash</pluginName> + </row> + <row> + <pluginIcon>plugins/UserSettings/images/plugins/java.gif</pluginIcon> + <pluginName>java</pluginName> + </row> + </pluginsIcons> + + + + + + <ecommerce> + </ecommerce> + </row> </result> \ No newline at end of file diff --git a/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getContinent_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getContinent_day.xml index f96445a3b9..db97816885 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getContinent_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getContinent_day.xml @@ -3,11 +3,11 @@ <row> <label>Europe</label> <nb_uniq_visitors>1</nb_uniq_visitors> - <nb_visits>2</nb_visits> - <nb_actions>2</nb_actions> + <nb_visits>3</nb_visits> + <nb_actions>3</nb_actions> <max_actions>1</max_actions> - <sum_visit_length>2340</sum_visit_length> - <bounce_count>2</bounce_count> + <sum_visit_length>1260</sum_visit_length> + <bounce_count>3</bounce_count> <goals> <row idgoal='ecommerceAbandonedCart'> <nb_conversions>2</nb_conversions> diff --git a/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getCountry_day.xml b/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getCountry_day.xml index 2509d485b5..2787ac5751 100644 --- a/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getCountry_day.xml +++ b/tests/integration/expected/test_ecommerceOrderWithItems__UserCountry.getCountry_day.xml @@ -3,11 +3,11 @@ <row> <label>France</label> <nb_uniq_visitors>1</nb_uniq_visitors> - <nb_visits>2</nb_visits> - <nb_actions>2</nb_actions> + <nb_visits>3</nb_visits> + <nb_actions>3</nb_actions> <max_actions>1</max_actions> - <sum_visit_length>2340</sum_visit_length> - <bounce_count>2</bounce_count> + <sum_visit_length>1260</sum_visit_length> + <bounce_count>3</bounce_count> <goals> <row idgoal='ecommerceAbandonedCart'> <nb_conversions>2</nb_conversions> -- GitLab