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'}&nbsp;<img src="plugins/Live/templates/images/returningVisitor.gif" title="{'General_ReturningVisitor'|translate}" />{/if}
+				{if $visitor.visitorType=='returning' || $visitor.visitorType=='returningCustomer'}&nbsp;<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 @@
 		&nbsp;<img src="{$visitor.columns.countryFlag}" title="{$visitor.columns.country}, Provider {$visitor.columns.provider}" />
 		&nbsp;<img src="{$visitor.columns.browserIcon}" title="{$visitor.columns.browserName} with plugins {$visitor.columns.plugins} enabled" />
 		&nbsp;<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'}
 			&nbsp;<img src="plugins/Live/templates/images/returningVisitor.gif" title="{'General_ReturningVisitor'|translate}" />
 		{/if}
 		&nbsp;{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 &quot;&amp;segment=visitorType==returning,visitorType==returningCustomer&quot;</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