Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormattpiwik <matthieu.aubry@gmail.com>2011-01-19 07:24:49 +0300
committermattpiwik <matthieu.aubry@gmail.com>2011-01-19 07:24:49 +0300
commit1afa106695c16ed20888419a67e7812ef77bbd0c (patch)
tree6dbd9b3e7718685b2fffbe535fee213616baeb30
parenta852b0e89b05ba9bc184586fba0fe242d0cf4f79 (diff)
Refs #1984 - New plugins CustomVariables
* Now possible to track up to 5 Custom variables per Visit. Also, Goal conversions will be reported 'By custom variable name & value' * New report in Visitors > Custom Variables, new CustomVars API * Updated schema * Updated PiwikTracker PHP api to allow setting the name,value pairs Code style * Refatoring some API code, and Archiving queries * Changing text from 'segment' to 'dimension' as this is better description + we want to build actual segmentation later * removing getJs calls in some plugins since they only included sparkline.js, moved to CoreHome git-svn-id: http://dev.piwik.org/svn/trunk@3780 59fd770c-687e-43c8-a1e3-f5a4ff64c105
-rw-r--r--core/Archive.php29
-rw-r--r--core/ArchiveProcessing/Day.php96
-rw-r--r--core/Db/Schema/Myisam.php20
-rw-r--r--core/Tracker.php4
-rw-r--r--core/Tracker/GoalManager.php4
-rw-r--r--core/Tracker/Visit.php62
-rw-r--r--core/Updates/1.2.php25
-rw-r--r--lang/en.php11
-rw-r--r--libs/PiwikTracker/PiwikTracker.php16
-rw-r--r--plugins/Actions/API.php35
-rw-r--r--plugins/CoreHome/CoreHome.php1
-rw-r--r--plugins/CustomVariables/API.php50
-rw-r--r--plugins/CustomVariables/Controller.php51
-rw-r--r--plugins/CustomVariables/CustomVariables.php171
-rw-r--r--plugins/Goals/Controller.php22
-rw-r--r--plugins/Goals/Goals.php23
-rw-r--r--plugins/Goals/templates/goals.css8
-rw-r--r--plugins/Goals/templates/list_top_dimension.tpl (renamed from plugins/Goals/templates/list_top_segment.tpl)2
-rw-r--r--plugins/Goals/templates/overview.tpl2
-rw-r--r--plugins/Goals/templates/single_goal.tpl8
-rw-r--r--plugins/Goals/templates/table_by_dimension.tpl (renamed from plugins/Goals/templates/table_by_segment.tpl)42
-rw-r--r--plugins/Referers/API.php14
-rw-r--r--plugins/Referers/Controller.php3
-rw-r--r--plugins/Referers/Referers.php35
-rw-r--r--plugins/UserCountry/UserCountry.php17
-rw-r--r--plugins/VisitFrequency/VisitFrequency.php7
-rw-r--r--plugins/VisitTime/VisitTime.php6
-rw-r--r--plugins/VisitsSummary/VisitsSummary.php7
-rw-r--r--tests/integration/Main.test.php51
-rw-r--r--tests/integration/expected/test_OneVisitorTwoVisits__CustomVariables.getCustomVariables_day.xml2
-rw-r--r--tests/integration/expected/test_OneVisitorTwoVisits__CustomVars.getCustomVariables_day.xml2
-rw-r--r--tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVariables.getCustomVariables_day.xml2
-rw-r--r--tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVars.getCustomVariables_day.xml2
-rw-r--r--tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata.xml32
-rw-r--r--tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml32
-rw-r--r--tests/integration/expected/test_noVisit__CustomVariables.getCustomVariables_day.xml2
-rw-r--r--tests/integration/expected/test_noVisit__CustomVars.getCustomVariables_day.xml2
-rw-r--r--tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml103
-rw-r--r--tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml103
-rw-r--r--tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml23
-rw-r--r--tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml23
-rw-r--r--themes/default/common.css4
42 files changed, 950 insertions, 204 deletions
diff --git a/core/Archive.php b/core/Archive.php
index 120f4b05bb..ebf4160197 100644
--- a/core/Archive.php
+++ b/core/Archive.php
@@ -273,6 +273,35 @@ abstract class Piwik_Archive
*/
abstract public function getDataTableExpanded($name, $idSubTable = null);
+
+ /**
+ * Helper - Loads a DataTable from the Archive.
+ * Optionally loads the table recursively,
+ * or optionally fetches a given subtable with $idSubtable
+ */
+ static public function getDataTableFromArchive($name, $idSite, $period, $date, $expanded, $idSubtable = null )
+ {
+ Piwik::checkUserHasViewAccess( $idSite );
+ $archive = Piwik_Archive::build($idSite, $period, $date );
+ if($idSubtable === false)
+ {
+ $idSubtable = null;
+ }
+
+ if($expanded)
+ {
+ $dataTable = $archive->getDataTableExpanded($name, $idSubtable);
+ }
+ else
+ {
+ $dataTable = $archive->getDataTable($name, $idSubtable);
+ }
+
+ $dataTable->queueFilter('ReplaceSummaryRowLabel');
+
+ return $dataTable;
+ }
+
/**
* Sets the site
*
diff --git a/core/ArchiveProcessing/Day.php b/core/ArchiveProcessing/Day.php
index 031a572a55..8b28feb63c 100644
--- a/core/ArchiveProcessing/Day.php
+++ b/core/ArchiveProcessing/Day.php
@@ -144,22 +144,7 @@ class Piwik_ArchiveProcessing_Day extends Piwik_ArchiveProcessing
*/
public function getArrayInterestForLabel($label)
{
- $query = "SELECT $label as label,
- count(distinct idvisitor) as `". Piwik_Archive::INDEX_NB_UNIQ_VISITORS ."`,
- count(*) as `". Piwik_Archive::INDEX_NB_VISITS ."`,
- sum(visit_total_actions) as `". Piwik_Archive::INDEX_NB_ACTIONS ."`,
- max(visit_total_actions) as `". Piwik_Archive::INDEX_MAX_ACTIONS ."`,
- sum(visit_total_time) as `". Piwik_Archive::INDEX_SUM_VISIT_LENGTH ."`,
- sum(case visit_total_actions when 1 then 1 else 0 end) as `". Piwik_Archive::INDEX_BOUNCE_COUNT ."`,
- sum(case visit_goal_converted when 1 then 1 else 0 end) as `". Piwik_Archive::INDEX_NB_VISITS_CONVERTED ."`
- FROM ".Piwik_Common::prefixTable('log_visit')."
- WHERE visit_last_action_time >= ?
- AND visit_last_action_time <= ?
- AND idsite = ?
- GROUP BY label
- ORDER BY NULL";
- $query = $this->db->query($query, array( $this->getStartDatetimeUTC(), $this->getEndDatetimeUTC(), $this->idsite ) );
-
+ $query = $this->queryVisitsByDimension($label);
$interest = array();
while($row = $query->fetch())
{
@@ -331,37 +316,78 @@ class Piwik_ArchiveProcessing_Day extends Piwik_ArchiveProcessing
$oldRowToUpdate[Piwik_Archive::INDEX_NB_VISITS_CONVERTED] += $newRowToAdd[Piwik_Archive::INDEX_NB_VISITS_CONVERTED];
}
- public function queryConversionsBySegment($segments = '')
+ /**
+ * @param $label mixed Can be a string, eg. "referer_name", will be aliased as 'label' in the returned rows
+ * Can also be an array of strings, when the dimension spans multiple fields, eg. array("referer_name", "referer_keyword")
+ */
+ public function queryVisitsByDimension($label, $where = '')
{
- if(!empty($segments))
- {
- $segments = ", ". $segments;
- }
- $query = "SELECT idgoal,
- count(*) as `". Piwik_Archive::INDEX_GOAL_NB_CONVERSIONS ."`,
- sum(revenue) as `". Piwik_Archive::INDEX_GOAL_REVENUE ."`
- $segments
- FROM ".Piwik_Common::prefixTable('log_conversion')."
- WHERE server_time >= ?
- AND server_time <= ?
- AND idsite = ?
- GROUP BY idgoal $segments
+ if(is_array($label))
+ {
+ $select = implode(", ", $label);
+ $groupBy = $select;
+ }
+ else
+ {
+ $select = $label . " AS label ";
+ $groupBy = 'label';
+ }
+ if(!empty($where))
+ {
+ $where = ' AND '.$where;
+ }
+
+ $query = "SELECT $select,
+ count(distinct idvisitor) as `". Piwik_Archive::INDEX_NB_UNIQ_VISITORS ."`,
+ count(*) as `". Piwik_Archive::INDEX_NB_VISITS ."`,
+ sum(visit_total_actions) as `". Piwik_Archive::INDEX_NB_ACTIONS ."`,
+ max(visit_total_actions) as `". Piwik_Archive::INDEX_MAX_ACTIONS ."`,
+ sum(visit_total_time) as `". Piwik_Archive::INDEX_SUM_VISIT_LENGTH ."`,
+ sum(case visit_total_actions when 1 then 1 else 0 end) as `". Piwik_Archive::INDEX_BOUNCE_COUNT ."`,
+ sum(case visit_goal_converted when 1 then 1 else 0 end) as `". Piwik_Archive::INDEX_NB_VISITS_CONVERTED ."`
+ FROM ".Piwik_Common::prefixTable('log_visit')."
+ WHERE visit_last_action_time >= ?
+ AND visit_last_action_time <= ?
+ AND idsite = ?
+ $where
+ GROUP BY $groupBy
ORDER BY NULL";
- $query = $this->db->query($query, array( $this->getStartDatetimeUTC(), $this->getEndDatetimeUTC(), $this->idsite ));
- return $query;
+ $query = $this->db->query($query, array(
+ $this->getStartDatetimeUTC(),
+ $this->getEndDatetimeUTC(),
+ $this->idsite ) );
+ return $query;
}
- public function queryConversionsBySingleSegment($segment)
+ /**
+ * @see queryVisitsByDimension() Similar to this function, but queries metrics for the requested dimensions, for each Goal conversion
+ */
+ public function queryConversionsByDimension($label, $where = '')
{
+ if(is_array($label))
+ {
+ $select = implode(", ", $label);
+ $groupBy = $select;
+ }
+ else
+ {
+ $select = $label . " AS label ";
+ $groupBy = 'label';
+ }
+ if(!empty($where))
+ {
+ $where = ' AND '.$where;
+ }
$query = "SELECT idgoal,
count(*) as `". Piwik_Archive::INDEX_GOAL_NB_CONVERSIONS ."`,
sum(revenue) as `". Piwik_Archive::INDEX_GOAL_REVENUE ."`,
- $segment as label
+ $select
FROM ".Piwik_Common::prefixTable('log_conversion')."
WHERE server_time >= ?
AND server_time <= ?
AND idsite = ?
- GROUP BY idgoal, label
+ $where
+ GROUP BY idgoal, $groupBy
ORDER BY NULL";
$query = $this->db->query($query, array( $this->getStartDatetimeUTC(), $this->getEndDatetimeUTC(), $this->idsite ));
return $query;
diff --git a/core/Db/Schema/Myisam.php b/core/Db/Schema/Myisam.php
index 829d8fc6c9..f5ff53f31e 100644
--- a/core/Db/Schema/Myisam.php
+++ b/core/Db/Schema/Myisam.php
@@ -204,6 +204,16 @@ class Piwik_Db_Schema_Myisam implements Piwik_Db_Schema_Interface
location_browser_lang VARCHAR(20) NOT NULL,
location_country CHAR(3) NOT NULL,
location_continent CHAR(3) 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(idvisit),
INDEX index_idsite_idvisit (idsite, idvisit),
INDEX index_idsite_datetime_config (idsite, visit_last_action_time, config_id)
@@ -228,6 +238,16 @@ class Piwik_Db_Schema_Myisam implements Piwik_Db_Schema_Interface
url text NOT NULL,
idgoal int(10) unsigned NOT NULL,
revenue float default 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 (idvisit, idgoal),
INDEX index_idsite_datetime ( idsite, server_time )
) DEFAULT CHARSET=utf8
diff --git a/core/Tracker.php b/core/Tracker.php
index 7be3b734ac..d06529bf3d 100644
--- a/core/Tracker.php
+++ b/core/Tracker.php
@@ -45,6 +45,10 @@ class Piwik_Tracker
const LENGTH_HEX_ID_STRING = 16;
const LENGTH_BINARY_ID = 8;
+ // These are also hardcoded in the Javascript
+ const MAX_CUSTOM_VARIABLES = 5;
+ const MAX_LENGTH_CUSTOM_VARIABLE = 50;
+
static protected $forcedDateTime = null;
static protected $forcedIpString = null;
diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php
index 611e031a52..0d6959af90 100644
--- a/core/Tracker/GoalManager.php
+++ b/core/Tracker/GoalManager.php
@@ -161,7 +161,7 @@ class Piwik_Tracker_GoalManager
return true;
}
- function recordGoals($idSite, $visitorInformation, $action)
+ function recordGoals($idSite, $visitorInformation, $visitCustomVariables, $action)
{
$location_country = isset($visitorInformation['location_country'])
? $visitorInformation['location_country']
@@ -206,6 +206,8 @@ class Piwik_Tracker_GoalManager
}
}
+ $goal += $visitCustomVariables;
+
foreach($this->convertedGoals as $convertedGoal)
{
printDebug("- Goal ".$convertedGoal['idgoal'] ." matched. Recording...");
diff --git a/core/Tracker/Visit.php b/core/Tracker/Visit.php
index 1eff39b518..d2ff3dcceb 100644
--- a/core/Tracker/Visit.php
+++ b/core/Tracker/Visit.php
@@ -128,7 +128,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
{
return;
}
-
+ $this->visitorCustomVariables = $this->getCustomVariables();
$goalManager = new Piwik_Tracker_GoalManager();
$someGoalsConverted = false;
$idActionUrl = $idActionName = 0;
@@ -230,7 +230,7 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
if($someGoalsConverted)
{
$goalManager->setCookie($this->cookie);
- $goalManager->recordGoals( $this->idsite, $this->visitorInfo, $action);
+ $goalManager->recordGoals( $this->idsite, $this->visitorInfo, $this->visitorCustomVariables, $action);
}
unset($goalManager);
unset($action);
@@ -315,6 +315,9 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
$valuesToUpdate['visit_last_action_time'] = $datetimeServer;
$valuesToUpdate['visit_total_time'] = $visitTotalTime;
+ // Custom Variables overwrite previous values on each page view
+ $valuesToUpdate = array_merge($valuesToUpdate, $this->visitorCustomVariables);
+
// trigger event before update
Piwik_PostEvent('Tracker.knownVisitorUpdate', $valuesToUpdate);
@@ -441,10 +444,17 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
'location_browser_lang' => $userInfo['location_browser_lang'],
'location_country' => $country,
);
-
+
+ // Add Custom variable key,value to the visitor array
+ $this->visitorInfo = array_merge($this->visitorInfo, $this->visitorCustomVariables);
+
Piwik_PostEvent('Tracker.newVisitorInformation', $this->visitorInfo);
- printDebug($this->visitorInfo);
+ $debugVisitInfo = $this->visitorInfo;
+ $debugVisitInfo['idvisitor'] = bin2hex($debugVisitInfo['idvisitor']);
+ $debugVisitInfo['config_id'] = bin2hex($debugVisitInfo['config_id']);
+ printDebug($debugVisitInfo);
+
$this->saveVisitorInformation();
}
@@ -792,6 +802,50 @@ class Piwik_Tracker_Visit implements Piwik_Tracker_Visit_Interface
}
}
+ protected function getCustomVariables()
+ {
+ $customVar = Piwik_Common::unsanitizeInputValue(Piwik_Common::getRequestVar( 'cvar', '', 'string', $this->request));
+ $customVar = @json_decode($customVar, $assoc = true);
+
+ if(!is_array($customVar))
+ {
+ return array();
+ }
+ $visitorCustomVar = array();
+ foreach($customVar as $id => $keyValue)
+ {
+ $id = (int)$id;
+ if($id < 1
+ || $id > Piwik_Tracker::MAX_CUSTOM_VARIABLES
+ || count($keyValue) != 2
+ || empty($keyValue[0])
+ || empty($keyValue[1])
+ || !is_string($keyValue[0])
+ || !is_string($keyValue[1])
+ )
+ {
+ printDebug("Invalid custom variables detected (id=$id)");
+ continue;
+ }
+
+ $key = $this->truncateCustomVariable($keyValue[0]);
+ $value = $this->truncateCustomVariable($keyValue[1]);
+ $visitorCustomVar['custom_var_k'.$id] = $key;
+ $visitorCustomVar['custom_var_v'.$id] = $value;
+ }
+ if(!empty($visitorCustomVar))
+ {
+ printDebug("Visitor Custom Variables: ");
+ printDebug($visitorCustomVar);
+ }
+ return $visitorCustomVar;
+ }
+
+ protected function truncateCustomVariable($input)
+ {
+ return substr($input, 0, Piwik_Tracker::MAX_LENGTH_CUSTOM_VARIABLE);
+ }
+
/**
* Gets the UserSettings information and returns them in an array of name => value
*
diff --git a/core/Updates/1.2.php b/core/Updates/1.2.php
index c67cc44828..549adbffc0 100644
--- a/core/Updates/1.2.php
+++ b/core/Updates/1.2.php
@@ -29,7 +29,17 @@ class Piwik_Updates_1_2 extends Piwik_Updates
CHANGE `visit_entry_idaction_url` `visit_entry_idaction_url` INT UNSIGNED NOT NULL,
CHANGE `referer_type` `referer_type` TINYINT UNSIGNED NULL DEFAULT NULL,
ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`,
- ADD `config_id` BINARY(8) NOT NULL AFTER `config_md5config`
+ ADD `config_id` BINARY(8) NOT NULL AFTER `config_md5config`,
+ ADD custom_var_k1 VARCHAR(50) DEFAULT NULL,
+ 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,
'ALTER TABLE `'. Piwik_Common::prefixTable('log_link_visit_action') .'`
ADD `idsite` INT( 10 ) UNSIGNED NOT NULL AFTER `idlink_va` ,
@@ -40,7 +50,17 @@ class Piwik_Updates_1_2 extends Piwik_Updates
' => false,
'ALTER TABLE `'. Piwik_Common::prefixTable('log_conversion') .'`
- ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`
+ ADD `idvisitor` BINARY(8) NOT NULL AFTER `idsite`,
+ ADD custom_var_k1 VARCHAR(50) DEFAULT NULL,
+ 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,
// Migrate 128bits IDs inefficiently stored as 8bytes (256 bits) into 64bits
@@ -77,7 +97,6 @@ class Piwik_Updates_1_2 extends Piwik_Updates
// New index used max once per request, in case this table grows significantly in the future
'ALTER TABLE `'. Piwik_Common::prefixTable('option') .'` ADD INDEX ( `autoload` ) ' => false,
-
);
}
diff --git a/lang/en.php b/lang/en.php
index fbb3b8bc15..dd6cac3a7f 100644
--- a/lang/en.php
+++ b/lang/en.php
@@ -39,6 +39,7 @@ $translations = array(
'General_Value' => 'Value',
'General_Details' => 'Details',
'General_Default' => 'Default',
+ 'General_Visit' => 'Visit',
'General_Date' => 'Date',
'General_Period' => 'Period',
'General_ChooseDate' => 'Choose date',
@@ -385,6 +386,10 @@ $translations = array(
'CoreUpdater_ExceptionArchiveIncompatible' => 'Incompatible archive: %s',
'CoreUpdater_ExceptionArchiveEmpty' => 'Empty archive.',
'CoreUpdater_ExceptionArchiveIncomplete' => 'Archive is incomplete: some files are missing (eg. %s).',
+ 'CustomVariables_PluginDescription' => 'Custom Variables are name,value pairs that you can set to a Visit using the Javascript API setVisitCustomVariables() function. Piwik will then report how many visits, pages, conversions for each of these custom names and values.',
+ 'CustomVariables_CustomVariables' => 'Custom Variables',
+ 'CustomVariables_ColumnCustomVariableName' => 'Custom Variable name',
+ 'CustomVariables_ColumnCustomVariableValue' => 'Custom Variable value',
'Dashboard_PluginDescription' => 'Your Web Analytics Dashboard. You can customize Your Dashboard: add new widgets, change the order of your widgets. Each user can access his own custom Dashboard.',
'Dashboard_Dashboard' => 'Dashboard',
'Dashboard_AddWidget' => 'Add a widget...',
@@ -441,9 +446,9 @@ $translations = array(
'Goals_Overview' => 'Overview',
'Goals_GoalsOverview' => 'Goals overview',
'Goals_GoalsManagement' => 'Goals management',
- 'Goals_ConversionsOverviewBySegment' => 'Conversions overview by segment',
- 'Goals_GoalConversionsBySegment' => 'Goal %s conversions by segment',
- 'Goals_ViewGoalsBySegment' => 'View goals by %s',
+ 'Goals_ConversionsOverviewBy' => 'Conversions overview by type of visit',
+ 'Goals_GoalConversionsBy' => 'Goal %s conversions by type of visit',
+ 'Goals_ViewGoalsBy' => 'View goals by %s',
'Goals_PluginDescription' => 'Create Goals and see reports about your goal conversions: evolution over time, revenue per visit, conversions per referrer, per keyword, etc.',
'Goals_ColumnConversions' => 'Conversions',
'Goals_ColumnRevenue' => 'Revenue',
diff --git a/libs/PiwikTracker/PiwikTracker.php b/libs/PiwikTracker/PiwikTracker.php
index 826d10b44a..541a878539 100644
--- a/libs/PiwikTracker/PiwikTracker.php
+++ b/libs/PiwikTracker/PiwikTracker.php
@@ -47,6 +47,7 @@ class PiwikTracker
$this->localSecond = false;
$this->hasCookies = false;
$this->plugins = false;
+ $this->visitorCustomVar = false;
$this->customData = false;
$this->forcedDatetime = false;
@@ -81,6 +82,18 @@ class PiwikTracker
}
/**
+ * Sets Visitor Custom Variable
+ *
+ * @param int Custom variable slot ID from 1-5
+ * @param string Custom variable name
+ * @param string Custom variable value
+ */
+ public function setVisitorCustomVar($id, $name, $value)
+ {
+ $this->visitorCustomVar[$id] = array($name, $value);
+ }
+
+ /**
* Sets custom data to be passed to the piwik.php script,
* with the variable name 'data'. Data will be JSON encoded.
*
@@ -390,7 +403,8 @@ 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->customData) ? '&data=' . $this->customData : '')
+ (!empty($this->customData) ? '&data=' . $this->customData : '') .
+ (!empty($this->visitorCustomVar) ? '&cvar=' . urlencode(json_encode($this->visitorCustomVar)) : '')
;
return $url;
}
diff --git a/plugins/Actions/API.php b/plugins/Actions/API.php
index abc2fcded0..9100104a26 100644
--- a/plugins/Actions/API.php
+++ b/plugins/Actions/API.php
@@ -40,7 +40,7 @@ class Piwik_Actions_API
public function getPageUrls( $idSite, $period, $date, $expanded = false, $idSubtable = false )
{
- $dataTable = $this->getDataTable('Actions_actions_url', $idSite, $period, $date, $expanded, $idSubtable );
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_actions_url', $idSite, $period, $date, $expanded, $idSubtable );
$this->filterPageDatatable($dataTable);
$this->filterActionsDataTable($dataTable, $expanded);
return $dataTable;
@@ -57,7 +57,7 @@ class Piwik_Actions_API
public function getPageTitles( $idSite, $period, $date, $expanded = false, $idSubtable = false)
{
- $dataTable = $this->getDataTable('Actions_actions', $idSite, $period, $date, $expanded, $idSubtable);
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_actions', $idSite, $period, $date, $expanded, $idSubtable);
$this->filterPageDatatable($dataTable);
$this->filterActionsDataTable($dataTable, $expanded);
return $dataTable;
@@ -74,7 +74,7 @@ class Piwik_Actions_API
public function getDownloads( $idSite, $period, $date, $expanded = false, $idSubtable = false )
{
- $dataTable = $this->getDataTable('Actions_downloads', $idSite, $period, $date, $expanded, $idSubtable );
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_downloads', $idSite, $period, $date, $expanded, $idSubtable );
$this->filterActionsDataTable($dataTable, $expanded);
return $dataTable;
}
@@ -89,7 +89,7 @@ class Piwik_Actions_API
public function getOutlinks( $idSite, $period, $date, $expanded = false, $idSubtable = false )
{
- $dataTable = $this->getDataTable('Actions_outlink', $idSite, $period, $date, $expanded, $idSubtable );
+ $dataTable = Piwik_Archive::getDataTableFromArchive('Actions_outlink', $idSite, $period, $date, $expanded, $idSubtable );
$this->filterActionsDataTable($dataTable, $expanded);
return $dataTable;
}
@@ -103,29 +103,6 @@ class Piwik_Actions_API
}
/**
- * Loads the DataTable from the Archive
- */
- protected function getDataTable($name, $idSite, $period, $date, $expanded, $idSubtable )
- {
- Piwik::checkUserHasViewAccess( $idSite );
- $archive = Piwik_Archive::build($idSite, $period, $date );
- if($idSubtable === false)
- {
- $idSubtable = null;
- }
-
- if($expanded)
- {
- $dataTable = $archive->getDataTableExpanded($name, $idSubtable);
- }
- else
- {
- $dataTable = $archive->getDataTable($name, $idSubtable);
- }
- return $dataTable;
- }
-
- /**
* Will search in the DataTable for a Label matching the searched string
* and return only the matching row, or an empty datatable
*/
@@ -133,7 +110,7 @@ class Piwik_Actions_API
{
if($table === false)
{
- $table = call_user_func_array(array($this, 'getDataTable'), $callBackParameters);
+ $table = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
}
if($searchTree === false)
{
@@ -170,7 +147,7 @@ class Piwik_Actions_API
$idSubTable = $row->getIdSubDataTable();
// Update the idSubtable in the callback parameter list, to fetch this subtable from the archive
$callBackParameters[5] = $idSubTable;
- $subTable = call_user_func_array(array($this, 'getDataTable'), $callBackParameters);
+ $subTable = call_user_func_array(array('Piwik_Archive', 'getDataTableFromArchive'), $callBackParameters);
$found = $this->getFilterPageDatatableSearch($callBackParameters, $search, $actionType, $subTable, $searchTree, $searchCurrentLevel+1);
if($found)
{
diff --git a/plugins/CoreHome/CoreHome.php b/plugins/CoreHome/CoreHome.php
index 953762a842..9624f102dc 100644
--- a/plugins/CoreHome/CoreHome.php
+++ b/plugins/CoreHome/CoreHome.php
@@ -70,6 +70,7 @@ class Piwik_CoreHome extends Piwik_Plugin
$jsFiles[] = "plugins/CoreHome/templates/calendar.js";
$jsFiles[] = "plugins/CoreHome/templates/date.js";
$jsFiles[] = "plugins/CoreHome/templates/autocomplete.js";
+ $jsFiles[] = "plugins/CoreHome/templates/sparkline.js";
}
}
diff --git a/plugins/CustomVariables/API.php b/plugins/CustomVariables/API.php
new file mode 100644
index 0000000000..e5af3bd21f
--- /dev/null
+++ b/plugins/CustomVariables/API.php
@@ -0,0 +1,50 @@
+<?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_Plugins
+ * @package Piwik_CustomVariables
+ */
+
+/**
+ *
+ * @package Piwik_CustomVariables
+ */
+class Piwik_CustomVariables_API
+{
+ static private $instance = null;
+
+ static public function getInstance()
+ {
+ if (self::$instance == null)
+ {
+ self::$instance = new self;
+ }
+ return self::$instance;
+ }
+
+ protected function getDataTable($idSite, $period, $date, $expanded, $idSubtable)
+ {
+ $dataTable = Piwik_Archive::getDataTableFromArchive('CustomVariables_valueByName', $idSite, $period, $date, $expanded, $idSubtable);
+ $dataTable->filter('Sort', array(Piwik_Archive::INDEX_NB_VISITS, 'desc', $naturalSort = false, $expanded));
+ $dataTable->queueFilter('ReplaceColumnNames', array($expanded));
+ return $dataTable;
+ }
+
+ public function getCustomVariables($idSite, $period, $date, $expanded = false)
+ {
+ $dataTable = $this->getDataTable($idSite, $period, $date, $expanded, $idSubtable = null);
+ return $dataTable;
+ }
+
+ public function getCustomVariablesValuesFromNameId($idSite, $period, $date, $idSubtable)
+ {
+ $dataTable = $this->getDataTable($idSite, $period, $date, $expanded = false, $idSubtable);
+ return $dataTable;
+ }
+}
+
diff --git a/plugins/CustomVariables/Controller.php b/plugins/CustomVariables/Controller.php
new file mode 100644
index 0000000000..182410d6bd
--- /dev/null
+++ b/plugins/CustomVariables/Controller.php
@@ -0,0 +1,51 @@
+<?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_Plugins
+ * @package Piwik_CustomVariables
+ */
+
+/**
+ *
+ * @package Piwik_CustomVariables
+ */
+class Piwik_CustomVariables_Controller extends Piwik_Controller
+{
+ /**
+ * CustomVariables
+ */
+ function getVisitCustomVariables($fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init( $this->pluginName, __FUNCTION__, "CustomVariables.getCustomVariables", "getCustomVariablesValuesFromNameId" );
+
+ $this->setPeriodVariablesView($view);
+ $view->enableShowGoals();
+
+ $view->setColumnsToDisplay( array('label','nb_visits') );
+ $view->setColumnTranslation('label', Piwik_Translate('CustomVariables_ColumnCustomVariableName'));
+ $view->setSortedColumn( 'nb_visits' );
+ $view->setLimit( 10 );
+ return $this->renderView($view, $fetch);
+ }
+
+ function getCustomVariablesValuesFromNameId( $fetch = false)
+ {
+ $view = Piwik_ViewDataTable::factory();
+ $view->init( $this->pluginName, __FUNCTION__, 'CustomVariables.getCustomVariablesValuesFromNameId' );
+
+ $view->disableSearchBox();
+ $view->disableExcludeLowPopulation();
+ $view->setColumnsToDisplay( array('label','nb_visits') );
+ $view->setColumnTranslation('label', Piwik_Translate('CustomVariables_ColumnCustomVariableValue'));
+
+ return $this->renderView($view, $fetch);
+ }
+
+}
+
diff --git a/plugins/CustomVariables/CustomVariables.php b/plugins/CustomVariables/CustomVariables.php
new file mode 100644
index 0000000000..ea21757031
--- /dev/null
+++ b/plugins/CustomVariables/CustomVariables.php
@@ -0,0 +1,171 @@
+<?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_Plugins
+ * @package Piwik_CustomVariables
+ */
+
+/**
+ * @package Piwik_CustomVariables
+ */
+class Piwik_CustomVariables extends Piwik_Plugin
+{
+ public $archiveProcessing;
+ protected $columnToSortByBeforeTruncation;
+ protected $maximumRowsInDataTableLevelZero;
+ protected $maximumRowsInSubDataTable;
+
+ public function getInformation()
+ {
+ $info = array(
+ 'description' => Piwik_Translate('CustomVariables_PluginDescription'),
+ 'author' => 'Piwik',
+ 'author_homepage' => 'http://piwik.org/',
+ 'version' => Piwik_Version::VERSION,
+ );
+
+ return $info;
+ }
+
+ function getListHooksRegistered()
+ {
+ $hooks = array(
+ 'ArchiveProcessing_Day.compute' => 'archiveDay',
+ 'ArchiveProcessing_Period.compute' => 'archivePeriod',
+ 'WidgetsList.add' => 'addWidgets',
+ 'Menu.add' => 'addMenus',
+ 'Goals.getReportsWithGoalMetrics' => 'getReportsWithGoalMetrics',
+ 'API.getReportMetadata' => 'getReportMetadata',
+ );
+ return $hooks;
+ }
+
+ function addWidgets()
+ {
+ Piwik_AddWidget( 'General_Visitors', 'CustomVariables_CustomVariables', 'CustomVariables', 'getVisitCustomVariables');
+ }
+
+ function addMenus()
+ {
+ Piwik_AddMenu('General_Visitors', 'CustomVariables_CustomVariables', array('module' => 'CustomVariables', 'action' => 'getVisitCustomVariables'), $display = true, $order = 50);
+ }
+
+ public function getReportMetadata($notification)
+ {
+ $reports = &$notification->getNotificationObject();
+ $reports = array_merge($reports, array(
+ array(
+ 'category' => Piwik_Translate('General_Visitors'),
+ 'name' => Piwik_Translate('CustomVariables_CustomVariables'),
+ 'module' => 'CustomVariables',
+ 'action' => 'getVisitCustomVariables',
+ 'dimension' => Piwik_Translate('CustomVariables_ColumnCustomVariableName'),
+ ),
+ ));
+ }
+ /**
+ * Adds Goal dimensions, so that the dimensions are displayed in the UI Goal Overview page
+ */
+ function getReportsWithGoalMetrics( $notification )
+ {
+ $dimensions =& $notification->getNotificationObject();
+ $dimensions = array_merge($dimensions, array(
+ array( 'category' => Piwik_Translate('General_Visit'),
+ 'name' => Piwik_Translate('CustomVariables_CustomVariables'),
+ 'module' => 'CustomVariables',
+ 'action' => 'getVisitCustomVariables',
+ ),
+ ));
+ }
+
+ function __construct()
+ {
+ //@todo
+ $this->maximumRowsInDataTableLevelZero = Zend_Registry::get('config')->General->datatable_archiving_maximum_rows_referers;
+ $this->maximumRowsInSubDataTable = Zend_Registry::get('config')->General->datatable_archiving_maximum_rows_subtable_referers;
+ }
+
+ function archivePeriod( $notification )
+ {
+ $archiveProcessing = $notification->getNotificationObject();
+
+ $dataTableToSum = 'CustomVariables_valueByName';
+ $nameToCount = $archiveProcessing->archiveDataTable($dataTableToSum, null, $this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable);
+ }
+
+ protected $interestByCustomVariables = array();
+ protected $interestByCustomVariablesAndValue = array();
+
+ /**
+ * Hooks on daily archive to trigger various log processing
+ *
+ * @param $notification
+ * @return void
+ */
+ public function archiveDay( $notification )
+ {
+ /**
+ * @var Piwik_ArchiveProcessing_Day
+ */
+ $this->archiveProcessing = $notification->getNotificationObject();
+ $this->archiveDayAggregate($this->archiveProcessing);
+ $this->archiveDayRecordInDatabase($this->archiveProcessing);
+ destroy($this->interestByCustomVariables);
+ destroy($this->interestByCustomVariablesAndValue);
+ }
+
+ /**
+ * @param $archiveProcessing
+ * @return void
+ */
+ protected function archiveDayAggregate(Piwik_ArchiveProcessing $archiveProcessing)
+ {
+ for($i = 1; $i <= Piwik_Tracker::MAX_CUSTOM_VARIABLES; $i++ )
+ {
+ $keyField = "custom_var_k".$i;
+ $valueField = "custom_var_v".$i;
+ $dimensions = array($keyField, $valueField);
+ $where = "$keyField IS NOT NULL AND $valueField IS NOT NULL";
+
+ // Custom Vars names and values metrics for visits
+ $query = $archiveProcessing->queryVisitsByDimension($dimensions, $where);
+ while($row = $query->fetch() )
+ {
+ if(!isset($this->interestByCustomVariables[$row[$keyField]])) $this->interestByCustomVariables[$row[$keyField]]= $archiveProcessing->getNewInterestRow();
+ if(!isset($this->interestByCustomVariablesAndValue[$row[$keyField]][$row[$valueField]])) $this->interestByCustomVariablesAndValue[$row[$keyField]][$row[$valueField]] = $archiveProcessing->getNewInterestRow();
+ $archiveProcessing->updateInterestStats( $row, $this->interestByCustomVariables[$row[$keyField]]);
+ $archiveProcessing->updateInterestStats( $row, $this->interestByCustomVariablesAndValue[$row[$keyField]][$row[$valueField]]);
+ }
+
+ // Custom Vars names and values metrics for Goals
+ $query = $archiveProcessing->queryConversionsByDimension($dimensions, $where);
+ while($row = $query->fetch() )
+ {
+ if(!isset($this->interestByCustomVariables[$row[$keyField]][Piwik_Archive::INDEX_GOALS][$row['idgoal']])) $this->interestByCustomVariables[$row[$keyField]][Piwik_Archive::INDEX_GOALS][$row['idgoal']] = $archiveProcessing->getNewGoalRow();
+ if(!isset($this->interestByCustomVariablesAndValue[$row[$keyField]][$row[$valueField]][Piwik_Archive::INDEX_GOALS][$row['idgoal']])) $this->interestByCustomVariablesAndValue[$row[$keyField]][$row[$valueField]][Piwik_Archive::INDEX_GOALS][$row['idgoal']] = $archiveProcessing->getNewGoalRow();
+
+ $archiveProcessing->updateGoalStats( $row, $this->interestByCustomVariables[$row[$keyField]][Piwik_Archive::INDEX_GOALS][$row['idgoal']]);
+ $archiveProcessing->updateGoalStats( $row, $this->interestByCustomVariablesAndValue[$row[$keyField]][$row[$valueField]][Piwik_Archive::INDEX_GOALS][$row['idgoal']]);
+ }
+ $archiveProcessing->enrichConversionsByLabelArrayHasTwoLevels($this->interestByCustomVariablesAndValue);
+ }
+ }
+
+ /**
+ * @param $archiveProcessing
+ * @return void
+ */
+ protected function archiveDayRecordInDatabase($archiveProcessing)
+ {
+ $recordName = 'CustomVariables_valueByName';
+ $table = $archiveProcessing->getDataTableWithSubtablesFromArraysIndexedByLabel($this->interestByCustomVariablesAndValue, $this->interestByCustomVariables);
+ $blob = $table->getSerialized($this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable);
+ $archiveProcessing->insertBlobRecord($recordName, $blob);
+ destroy($table);
+ }
+}
diff --git a/plugins/Goals/Controller.php b/plugins/Goals/Controller.php
index 2076507c5d..e799595d52 100644
--- a/plugins/Goals/Controller.php
+++ b/plugins/Goals/Controller.php
@@ -55,7 +55,7 @@ class Piwik_Goals_Controller extends Piwik_Controller
{
$view = $this->getGoalReportView();
$view->displayFullReport = true;
- $view->goalSegments = Piwik_Goals::getReportsWithGoalMetrics();
+ $view->goalDimensions = Piwik_Goals::getReportsWithGoalMetrics();
echo $view->render();
}
@@ -79,7 +79,7 @@ class Piwik_Goals_Controller extends Piwik_Controller
$view->goalName = $goalDefinition['name'];
$view->graphEvolution = $this->getEvolutionGraph(true, array('nb_conversions'), $idGoal);
$view->nameGraphEvolution = 'GoalsgetEvolutionGraph'.$idGoal;
- $view->topSegments = $this->getTopSegments($idGoal);
+ $view->topDimensions = $this->getTopDimensions($idGoal);
// conversion rate for new and returning visitors
$conversionRateReturning = $this->getConversionRateReturningVisitors($this->idSite, Piwik_Common::getRequestVar('period'), Piwik_Common::getRequestVar('date'), $idGoal);
@@ -93,7 +93,7 @@ class Piwik_Goals_Controller extends Piwik_Controller
{
$view = $this->getOverviewView();
$view->goalsJSON = json_encode($this->goals);
- $view->goalSegments = Piwik_Goals::getReportsWithGoalMetrics();
+ $view->goalDimensions = Piwik_Goals::getReportsWithGoalMetrics();
$view->userCanEditGoals = Piwik::isUserHasAdminAccess($this->idSite);
$view->displayFullReport = true;
echo $view->render();
@@ -207,19 +207,19 @@ class Piwik_Goals_Controller extends Piwik_Controller
}
- protected function getTopSegments($idGoal)
+ protected function getTopDimensions($idGoal)
{
$columnNbConversions = 'goal_'.$idGoal.'_nb_conversions';
$columnConversionRate = 'goal_'.$idGoal.'_conversion_rate';
- $topSegmentsToLoad = array(
+ $topDimensionsToLoad = array(
'country' => 'UserCountry.getCountry',
'keyword' => 'Referers.getKeywords',
'website' => 'Referers.getWebsites',
);
- $topSegments = array();
- foreach($topSegmentsToLoad as $segmentName => $apiMethod)
+ $topDimensions = array();
+ foreach($topDimensionsToLoad as $dimensionName => $apiMethod)
{
$request = new Piwik_API_Request("method=$apiMethod
&format=original
@@ -229,13 +229,13 @@ class Piwik_Goals_Controller extends Piwik_Controller
&filter_sort_column=$columnNbConversions
&filter_limit=3");
$datatable = $request->process();
- $topSegment = array();
+ $topDimension = array();
foreach($datatable->getRows() as $row)
{
$conversions = $row->getColumn($columnNbConversions);
if($conversions > 0)
{
- $topSegment[] = array (
+ $topDimension[] = array (
'name' => $row->getColumn('label'),
'nb_conversions' => $conversions,
'conversion_rate' => $this->formatConversionRate($row->getColumn($columnConversionRate)),
@@ -243,9 +243,9 @@ class Piwik_Goals_Controller extends Piwik_Controller
);
}
}
- $topSegments[$segmentName] = $topSegment;
+ $topDimensions[$dimensionName] = $topDimension;
}
- return $topSegments;
+ return $topDimensions;
}
protected function getMetricsForGoal($idGoal)
diff --git a/plugins/Goals/Goals.php b/plugins/Goals/Goals.php
index 51d8f97b27..8ec4b4983a 100644
--- a/plugins/Goals/Goals.php
+++ b/plugins/Goals/Goals.php
@@ -50,7 +50,7 @@ class Piwik_Goals extends Piwik_Plugin
* The API returns general Goal metrics: conv, conv rate and revenue globally
* and for each goal.
*
- * Also, this will update metadata of all other reports that have Goal segmentatation.
+ * Also, this will update metadata of all other reports that have Goal segmentation
*/
public function getReportMetadata($notification)
{
@@ -126,23 +126,22 @@ class Piwik_Goals extends Piwik_Plugin
static public function getReportsWithGoalMetrics()
{
- $segments = array();
- Piwik_PostEvent('Goals.getReportsWithGoalMetrics', $segments);
- $segmentsByGroup = array();
- foreach($segments as $segment)
+ $dimensions = array();
+ Piwik_PostEvent('Goals.getReportsWithGoalMetrics', $dimensions);
+ $dimensionsByGroup = array();
+ foreach($dimensions as $dimension)
{
- $group = $segment['category'];
- unset($segment['category']);
- $segmentsByGroup[$group][] = $segment;
+ $group = $dimension['category'];
+ unset($dimension['category']);
+ $dimensionsByGroup[$group][] = $dimension;
}
- return $segmentsByGroup;
+ return $dimensionsByGroup;
}
function getJsFiles( $notification )
{
$jsFiles = &$notification->getNotificationObject();
$jsFiles[] = "plugins/Goals/templates/GoalForm.js";
- $jsFiles[] = "plugins/CoreHome/templates/sparkline.js";
}
function getCssFiles( $notification )
@@ -268,13 +267,13 @@ class Piwik_Goals extends Piwik_Plugin
$archiveProcessing = $notification->getNotificationObject();
// by processing visitor_returning segment, we can also simply sum and get stats for all goals.
- $query = $archiveProcessing->queryConversionsBySegment('visitor_returning');
+ $query = $archiveProcessing->queryConversionsByDimension('visitor_returning');
$nb_conversions = $revenue = 0;
$goals = $goalsByVisitorReturning = array();
while($row = $query->fetch() )
{
- $goalsByVisitorReturning[$row['idgoal']][$row['visitor_returning']] = $archiveProcessing->getGoalRowFromQueryRow($row);
+ $goalsByVisitorReturning[$row['idgoal']][$row['label']] = $archiveProcessing->getGoalRowFromQueryRow($row);
if(!isset($goals[$row['idgoal']])) $goals[$row['idgoal']] = $archiveProcessing->getNewGoalRow();
$archiveProcessing->updateGoalStats($row, $goals[$row['idgoal']]);
diff --git a/plugins/Goals/templates/goals.css b/plugins/Goals/templates/goals.css
index 9746cc3aeb..8b781a2c26 100644
--- a/plugins/Goals/templates/goals.css
+++ b/plugins/Goals/templates/goals.css
@@ -8,8 +8,8 @@
width:614px;
}
-/* segment selector */
-#titleGoalsBySegment {
+/* dimension selector */
+#titleGoalsByDimension {
padding-top:30px;
}
ul.ulGoalTopElements {
@@ -22,11 +22,11 @@ ul.ulGoalTopElements {
border-bottom:1px dotted #0033CC;
line-height:2em;
}
-.goalSegments{
+.goalDimensions{
float: left;
width: 220px;
min-height:450px;
}
-.segmentCategory {
+.dimensionCategory {
margin-top:10px;
}
diff --git a/plugins/Goals/templates/list_top_segment.tpl b/plugins/Goals/templates/list_top_dimension.tpl
index 4b5b442c2b..50e86d9b4d 100644
--- a/plugins/Goals/templates/list_top_segment.tpl
+++ b/plugins/Goals/templates/list_top_dimension.tpl
@@ -1,5 +1,5 @@
-{foreach from=$topSegment item=element name=topGoalElements}
+{foreach from=$topDimension item=element name=topGoalElements}
{assign var=goal_nb_conversion value=$element.nb_conversions}
{assign var=goal_conversion_rate value=$element.conversion_rate}
<span class='goalTopElement' title='{'Goals_Conversions'|translate:"<b>$goal_nb_conversion</b>"},
diff --git a/plugins/Goals/templates/overview.tpl b/plugins/Goals/templates/overview.tpl
index 60c49b3a83..444fafa7c7 100644
--- a/plugins/Goals/templates/overview.tpl
+++ b/plugins/Goals/templates/overview.tpl
@@ -27,7 +27,7 @@
{if $displayFullReport}
- {include file="Goals/templates/table_by_segment.tpl"}
+ {include file="Goals/templates/table_by_dimension.tpl"}
{if $userCanEditGoals}
{include file=Goals/templates/add_edit_goal.tpl}
diff --git a/plugins/Goals/templates/single_goal.tpl b/plugins/Goals/templates/single_goal.tpl
index a83b430004..362c47313e 100644
--- a/plugins/Goals/templates/single_goal.tpl
+++ b/plugins/Goals/templates/single_goal.tpl
@@ -5,9 +5,9 @@
{if $nb_conversions > 0}
<h2>{'Goals_ConversionsOverview'|translate}</h2>
<ul class="ulGoalTopElements">
- <li>{'Goals_BestCountries'|translate} {include file='Goals/templates/list_top_segment.tpl' topSegment=$topSegments.country}</li>
- {if count($topSegments.keyword)>0}<li>{'Goals_BestKeywords'|translate} {include file='Goals/templates/list_top_segment.tpl' topSegment=$topSegments.keyword}</li>{/if}
- {if count($topSegments.website)>0}<li>{'Goals_BestReferers'|translate} {include file='Goals/templates/list_top_segment.tpl' topSegment=$topSegments.website}</li>{/if}
+ <li>{'Goals_BestCountries'|translate} {include file='Goals/templates/list_top_dimension.tpl' topDimension=$topDimensions.country}</li>
+ {if count($topDimensions.keyword)>0}<li>{'Goals_BestKeywords'|translate} {include file='Goals/templates/list_top_dimension.tpl' topDimension=$topDimensions.keyword}</li>{/if}
+ {if count($topDimensions.website)>0}<li>{'Goals_BestReferers'|translate} {include file='Goals/templates/list_top_dimension.tpl' topDimension=$topDimensions.website}</li>{/if}
<li>{'Goals_ReturningVisitorsConversionRateIs'|translate:"<b>$conversion_rate_returning</b>"}, {'Goals_NewVisitorsConversionRateIs'|translate:"<b>$conversion_rate_new</b>"}</li>
</ul>
{/if}
@@ -23,6 +23,6 @@ $(document).ready( function() {
{if $displayFullReport}
{if $nb_conversions > 0}
- {include file="Goals/templates/table_by_segment.tpl"}
+ {include file="Goals/templates/table_by_dimension.tpl"}
{/if}
{/if}
diff --git a/plugins/Goals/templates/table_by_segment.tpl b/plugins/Goals/templates/table_by_dimension.tpl
index 2f79dbfc22..80d2541a7b 100644
--- a/plugins/Goals/templates/table_by_segment.tpl
+++ b/plugins/Goals/templates/table_by_dimension.tpl
@@ -1,15 +1,15 @@
-<h2 id='titleGoalsBySegment'>{if isset($idGoal)}
- {'Goals_GoalConversionsBySegment'|translate:$goalName}
- {else}{'Goals_ConversionsOverviewBySegment'|translate}{/if}</h2>
+<h2 id='titleGoalsByDimension'>{if isset($idGoal)}
+ {'Goals_GoalConversionsBy'|translate:$goalName}
+ {else}{'Goals_ConversionsOverviewBy'|translate}{/if}</h2>
-<div class='entityList goalSegments'>
- {foreach from=$goalSegments key=segmentFamilyName item=segments}
- <div class='segmentCategory'>
- {'Goals_ViewGoalsBySegment'|translate:$segmentFamilyName}
+<div class='entityList goalDimensions'>
+ {foreach from=$goalDimensions key=dimensionFamilyName item=dimensions}
+ <div class='dimensionCategory'>
+ {'Goals_ViewGoalsBy'|translate:$dimensionFamilyName}
<ul class='listCircle'>
- {foreach from=$segments item=segment}
- <li title='{'Goals_ViewGoalsBySegment'|translate:$segment.name}' class='goalSegment' module='{$segment.module}' action='{$segment.action}'>
- <span class='segment'>{$segment.name}</span>
+ {foreach from=$dimensions item=dimension}
+ <li title='{'Goals_ViewGoalsBy'|translate:$dimension.name}' class='goalDimension' module='{$dimension.module}' action='{$dimension.action}'>
+ <span class='dimension'>{$dimension.name}</span>
</li>
{/foreach}
</ul>
@@ -20,7 +20,7 @@
<div style='float: left;'>
{ajaxLoadingDiv id=tableGoalsLoading}
- <div id='tableGoalsBySegment'></div>
+ <div id='tableGoalsByDimension'></div>
</div>
<div class="clear"></div>
{literal}
@@ -28,13 +28,13 @@
$(document).ready( function() {
var countLoaded = 0;
/*
- * For each 'segment' in the list, a click will trigger an ajax request to load the datatable
- * showing Goals metrics (conversion, conv. rates, revenue) for this segment
+ * For each 'dimension' in the list, a click will trigger an ajax request to load the datatable
+ * showing Goals metrics (conversion, conv. rates, revenue) for this dimension
*/
- $('.goalSegment').click( function() {
+ $('.goalDimension').click( function() {
var self = this;
- $('.goalSegment').removeClass('activeSegment');
- $(this).addClass('activeSegment');
+ $('.goalDimension').removeClass('activeDimension');
+ $(this).addClass('activeDimension');
var module = $(this).attr('module');
var action = $(this).attr('action');
widgetUniqueId = module+action;
@@ -51,24 +51,24 @@ $(document).ready( function() {
if(widgetUniqueId != self.expectedWidgetUniqueId) {
return;
}
- $('#tableGoalsBySegment').html($(response));
+ $('#tableGoalsByDimension').html($(response));
$('#tableGoalsLoading').hide();
- $('#tableGoalsBySegment').show();
+ $('#tableGoalsByDimension').show();
countLoaded++;
// only scroll down to the loaded datatable if this is not the first one
// otherwise, screen would jump down to the table when loading the report
if(countLoaded > 1)
{
- piwikHelper.lazyScrollTo("#titleGoalsBySegment", 400);
+ piwikHelper.lazyScrollTo("#titleGoalsByDimension", 400);
}
};
- $('#tableGoalsBySegment').hide();
+ $('#tableGoalsByDimension').hide();
$('#tableGoalsLoading').show();
ajaxRequest = widgetsHelper.getLoadWidgetAjaxRequest(widgetUniqueId, widgetParameters, onWidgetLoadedCallback);
$.ajax(ajaxRequest);
});
- $('.goalSegment').first().click();
+ $('.goalDimension').first().click();
});
</script>
{/literal}
diff --git a/plugins/Referers/API.php b/plugins/Referers/API.php
index 3b2991e97d..10a49a2b29 100644
--- a/plugins/Referers/API.php
+++ b/plugins/Referers/API.php
@@ -36,20 +36,10 @@ class Piwik_Referers_API
*/
protected function getDataTable($name, $idSite, $period, $date, $expanded, $idSubtable = null)
{
- Piwik::checkUserHasViewAccess( $idSite );
- $archive = Piwik_Archive::build($idSite, $period, $date );
+ $dataTable = Piwik_Archive::getDataTableFromArchive($name, $idSite, $period, $date, $expanded, $idSubtable = null);
- if($expanded)
- {
- $dataTable = $archive->getDataTableExpanded($name, $idSubtable);
- }
- else
- {
- $dataTable = $archive->getDataTable($name, $idSubtable);
- }
- $dataTable->filter('Sort', array(Piwik_Archive::INDEX_NB_VISITS, 'desc', $naturalSort = false, $expanded));
+ $dataTable->filter('Sort', array(Piwik_Archive::INDEX_NB_VISITS, 'desc', $naturalSort = false, $expanded));
$dataTable->queueFilter('ReplaceColumnNames', array($expanded));
- $dataTable->queueFilter('ReplaceSummaryRowLabel');
return $dataTable;
}
diff --git a/plugins/Referers/Controller.php b/plugins/Referers/Controller.php
index 4df6302d21..cf1e5318df 100644
--- a/plugins/Referers/Controller.php
+++ b/plugins/Referers/Controller.php
@@ -158,10 +158,9 @@ class Piwik_Referers_Controller extends Piwik_Controller
'getKeywordsFromCampaignId'
);
- $view->disableSearchBox();
$view->disableExcludeLowPopulation();
- $view->setLimit( 5 );
$view->enableShowGoals();
+ $view->setLimit( 5 );
$view->setColumnsToDisplay( array('label','nb_visits') );
$view->setColumnTranslation('label', Piwik_Translate('Referers_ColumnCampaign'));
return $this->renderView($view, $fetch);
diff --git a/plugins/Referers/Referers.php b/plugins/Referers/Referers.php
index c2fa26ccaa..aa0807fb2c 100644
--- a/plugins/Referers/Referers.php
+++ b/plugins/Referers/Referers.php
@@ -35,7 +35,6 @@ class Piwik_Referers extends Piwik_Plugin
function getListHooksRegistered()
{
$hooks = array(
- 'AssetManager.getJsFiles' => 'getJsFiles',
'ArchiveProcessing_Day.compute' => 'archiveDay',
'ArchiveProcessing_Period.compute' => 'archivePeriod',
'WidgetsList.add' => 'addWidgets',
@@ -114,15 +113,15 @@ class Piwik_Referers extends Piwik_Plugin
}
/**
- * Adds Goal segments, so that the segments are displayed in the UI Goal Overview page
+ * Adds Goal dimensions, so that the dimensions are displayed in the UI Goal Overview page
*
* @param $notification
* @return void
*/
function getReportsWithGoalMetrics( $notification )
{
- $segments =& $notification->getNotificationObject();
- $segments = array_merge($segments, array(
+ $dimensions =& $notification->getNotificationObject();
+ $dimensions = array_merge($dimensions, array(
array( 'category' => Piwik_Translate('Referers_Referers'),
'name' => Piwik_Translate('Referers_Keywords'),
'module' => 'Referers',
@@ -151,12 +150,6 @@ class Piwik_Referers extends Piwik_Plugin
));
}
- function getJsFiles( $notification )
- {
- $jsFiles = &$notification->getNotificationObject();
- $jsFiles[] = "plugins/CoreHome/templates/sparkline.js";
- }
-
function __construct()
{
$this->columnToSortByBeforeTruncation = Piwik_Archive::INDEX_NB_VISITS;
@@ -268,24 +261,8 @@ class Piwik_Referers extends Piwik_Plugin
*/
protected function archiveDayAggregateVisits(Piwik_ArchiveProcessing $archiveProcessing)
{
- $query = "SELECT referer_type,
- referer_name,
- referer_keyword,
- referer_url,
- count(distinct idvisitor) as `". Piwik_Archive::INDEX_NB_UNIQ_VISITORS ."`,
- count(*) as `". Piwik_Archive::INDEX_NB_VISITS ."`,
- sum(visit_total_actions) as `". Piwik_Archive::INDEX_NB_ACTIONS ."`,
- max(visit_total_actions) as `". Piwik_Archive::INDEX_MAX_ACTIONS ."`,
- sum(visit_total_time) as `". Piwik_Archive::INDEX_SUM_VISIT_LENGTH ."`,
- sum(case visit_total_actions when 1 then 1 else 0 end) as `". Piwik_Archive::INDEX_BOUNCE_COUNT ."`,
- sum(case visit_goal_converted when 1 then 1 else 0 end) as `". Piwik_Archive::INDEX_NB_VISITS_CONVERTED ."`
- FROM ".Piwik_Common::prefixTable('log_visit')."
- WHERE visit_last_action_time >= ?
- AND visit_last_action_time <= ?
- AND idsite = ?
- GROUP BY referer_type, referer_name, referer_url, referer_keyword
- ORDER BY `". Piwik_Archive::INDEX_NB_VISITS ."` DESC";
- $query = $archiveProcessing->db->query($query, array( $archiveProcessing->getStartDatetimeUTC(), $archiveProcessing->getEndDatetimeUTC(), $archiveProcessing->idsite ));
+ $dimension = array("referer_type", "referer_name", "referer_keyword", "referer_url");
+ $query = $archiveProcessing->queryVisitsByDimension($dimension);
$this->interestBySearchEngine =
$this->interestByKeyword =
@@ -368,7 +345,7 @@ class Piwik_Referers extends Piwik_Plugin
*/
protected function archiveDayAggregateGoals($archiveProcessing)
{
- $query = $archiveProcessing->queryConversionsBySegment("referer_type,referer_name,referer_keyword");
+ $query = $archiveProcessing->queryConversionsByDimension(array("referer_type","referer_name","referer_keyword"));
while($row = $query->fetch() )
{
if(empty($row['referer_type']))
diff --git a/plugins/UserCountry/UserCountry.php b/plugins/UserCountry/UserCountry.php
index d1f7e06741..226fe80026 100644
--- a/plugins/UserCountry/UserCountry.php
+++ b/plugins/UserCountry/UserCountry.php
@@ -30,7 +30,6 @@ class Piwik_UserCountry extends Piwik_Plugin
function getListHooksRegistered()
{
$hooks = array(
- 'AssetManager.getJsFiles' => 'getJsFiles',
'ArchiveProcessing_Day.compute' => 'archiveDay',
'ArchiveProcessing_Period.compute' => 'archivePeriod',
'WidgetsList.add' => 'addWidgets',
@@ -61,12 +60,6 @@ class Piwik_UserCountry extends Piwik_Plugin
);
}
- function getJsFiles( $notification )
- {
- $jsFiles = &$notification->getNotificationObject();
- $jsFiles[] = "plugins/CoreHome/templates/sparkline.js";
- }
-
function addWidgets()
{
Piwik_AddWidget( 'General_Visitors', 'UserCountry_WidgetContinents', 'UserCountry', 'getContinent');
@@ -80,14 +73,14 @@ class Piwik_UserCountry extends Piwik_Plugin
function getReportsWithGoalMetrics( $notification )
{
- $segments =& $notification->getNotificationObject();
- $segments = array_merge($segments, array(
- array( 'category' => Piwik_Translate('UserCountry_Location'),
+ $dimensions =& $notification->getNotificationObject();
+ $dimensions = array_merge($dimensions, array(
+ array( 'category' => Piwik_Translate('General_Visit'),
'name' => Piwik_Translate('UserCountry_Country'),
'module' => 'UserCountry',
'action' => 'getCountry',
),
- array( 'category' => Piwik_Translate('UserCountry_Location'),
+ array( 'category' => Piwik_Translate('General_Visit'),
'name' => Piwik_Translate('UserCountry_Continent'),
'module' => 'UserCountry',
'action' => 'getContinent',
@@ -128,7 +121,7 @@ class Piwik_UserCountry extends Piwik_Plugin
protected function archiveDayAggregateGoals($archiveProcessing)
{
- $query = $archiveProcessing->queryConversionsBySegment("location_continent,location_country");
+ $query = $archiveProcessing->queryConversionsByDimension(array("location_continent","location_country"));
while($row = $query->fetch() )
{
if(!isset($this->interestByCountry[$row['location_country']][Piwik_Archive::INDEX_GOALS][$row['idgoal']])) $this->interestByCountry[$row['location_country']][Piwik_Archive::INDEX_GOALS][$row['idgoal']] = $archiveProcessing->getNewGoalRow();
diff --git a/plugins/VisitFrequency/VisitFrequency.php b/plugins/VisitFrequency/VisitFrequency.php
index c092b8128b..82c4b63297 100644
--- a/plugins/VisitFrequency/VisitFrequency.php
+++ b/plugins/VisitFrequency/VisitFrequency.php
@@ -30,7 +30,6 @@ class Piwik_VisitFrequency extends Piwik_Plugin
function getListHooksRegistered()
{
$hooks = array(
- 'AssetManager.getJsFiles' => 'getJsFiles',
'ArchiveProcessing_Day.compute' => 'archiveDay',
'ArchiveProcessing_Period.compute' => 'archivePeriod',
'WidgetsList.add' => 'addWidgets',
@@ -71,12 +70,6 @@ class Piwik_VisitFrequency extends Piwik_Plugin
Piwik_AddWidget( 'General_Visitors', 'VisitFrequency_WidgetGraphReturning', 'VisitFrequency', 'getEvolutionGraph', array('columns' => array('nb_visits_returning')));
}
- function getJsFiles( $notification )
- {
- $jsFiles = &$notification->getNotificationObject();
- $jsFiles[] = "plugins/CoreHome/templates/sparkline.js";
- }
-
function addMenu()
{
Piwik_AddMenu('General_Visitors', 'VisitFrequency_SubmenuFrequency', array('module' => 'VisitFrequency', 'action' => 'index'));
diff --git a/plugins/VisitTime/VisitTime.php b/plugins/VisitTime/VisitTime.php
index 8ac0bcc73e..f173364bca 100644
--- a/plugins/VisitTime/VisitTime.php
+++ b/plugins/VisitTime/VisitTime.php
@@ -73,8 +73,8 @@ class Piwik_VisitTime extends Piwik_Plugin
function getReportsWithGoalMetrics( $notification )
{
- $segments =& $notification->getNotificationObject();
- $segments[] = array('category' => Piwik_Translate('VisitTime_ColumnServerTime'),
+ $dimensions =& $notification->getNotificationObject();
+ $dimensions[] = array('category' => Piwik_Translate('VisitTime_ColumnServerTime'),
'name' => Piwik_Translate('VisitTime_ColumnServerTime'),
'module' => 'VisitTime',
'action' => 'getVisitInformationPerServerTime',
@@ -125,7 +125,7 @@ class Piwik_VisitTime extends Piwik_Plugin
protected function archiveDayAggregateGoals($archiveProcessing)
{
- $query = $archiveProcessing->queryConversionsBySingleSegment("HOUR(server_time)");
+ $query = $archiveProcessing->queryConversionsByDimension("HOUR(server_time)");
$goalByServerTime = array();
while($row = $query->fetch())
{
diff --git a/plugins/VisitsSummary/VisitsSummary.php b/plugins/VisitsSummary/VisitsSummary.php
index f47c896c55..acbfd2d2e6 100644
--- a/plugins/VisitsSummary/VisitsSummary.php
+++ b/plugins/VisitsSummary/VisitsSummary.php
@@ -34,7 +34,6 @@ class Piwik_VisitsSummary extends Piwik_Plugin
function getListHooksRegistered()
{
return array(
- 'AssetManager.getJsFiles' => 'getJsFiles',
'API.getReportMetadata' => 'getReportMetadata',
'WidgetsList.add' => 'addWidgets',
'Menu.add' => 'addMenu',
@@ -65,12 +64,6 @@ class Piwik_VisitsSummary extends Piwik_Plugin
);
}
- function getJsFiles( $notification )
- {
- $jsFiles = &$notification->getNotificationObject();
- $jsFiles[] = "plugins/CoreHome/templates/sparkline.js";
- }
-
function addWidgets()
{
Piwik_AddWidget( 'VisitsSummary_VisitsSummary', 'VisitsSummary_WidgetLastVisits', 'VisitsSummary', 'getEvolutionGraph', array('columns' => array('nb_visits')));
diff --git a/tests/integration/Main.test.php b/tests/integration/Main.test.php
index 89ac84f9f0..208956860d 100644
--- a/tests/integration/Main.test.php
+++ b/tests/integration/Main.test.php
@@ -303,4 +303,55 @@ class Test_Piwik_Integration_Main extends Test_Integration
$this->callGetApiCompareOutput(__FUNCTION__, 'xml', $idSite = 'all', $dateTime, $periods, $setDateLastN = true);
}
+ function test_twoVisitsWithCustomVariables()
+ {
+ // Tests run in UTC, the Tracker in UTC
+ $dateTime = '2010-01-03 11:22:33';
+ $idSite = $this->createWebsite($dateTime);
+ $this->setApiToCall(array( 'VisitsSummary.get',
+ 'CustomVariables.getCustomVariables'
+ ));
+ ob_start();
+ $idGoal = Piwik_Goals_API::getInstance()->addGoal($idSite, 'triggered js', 'manually', '', '');
+ // -
+ $visitorA = $this->getTracker($idSite, $dateTime, $defaultInit = true);
+
+ // At first, visitor custom var is set to LoggedOut
+ $visitorA->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.1)->getDatetime());
+ $visitorA->setUrl('http://example.org/homepage');
+ $visitorA->setVisitorCustomVar($id = 1, $name = 'VisitorType', $value = 'LoggedOut');
+ $this->checkResponse($visitorA->doTrackPageView('Homepage'));
+
+ // After login, set to LoggedIn, should overwrite previous value
+ $visitorA->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.2)->getDatetime());
+ $visitorA->setUrl('http://example.org/profile');
+ $visitorA->setVisitorCustomVar($id = 1, $name = 'VisitorType', $value = 'LoggedIn');
+ $this->checkResponse($visitorA->doTrackPageView('Profile page'));
+
+ $visitorA->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(0.3)->getDatetime());
+ $visitorA->setVisitorCustomVar($id = 2, $name = 'NOTSETBECAUSE EMPTY VALUE', $value = '');
+ $this->checkResponse($visitorA->doTrackPageView('Profile page'));
+ $this->checkResponse($visitorA->doTrackGoal($idGoal));
+
+ // -
+ // Second new visitor on Idsite 1: one page view
+ $visitorB = $this->getTracker($idSite, $dateTime, $defaultInit = true);
+ $visitorB->setUserAgent('Mozilla/5.0 (Windows; U; Windows NT 5.1; en-GB; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6');
+ $visitorB->setForceVisitDateTime(Piwik_Date::factory($dateTime)->addHour(1)->getDatetime());
+ $visitorB->setVisitorCustomVar($id = 1, $name = 'VisitorType', $value = 'LoggedOut');
+ $visitorB->setVisitorCustomVar($id = 2, $name = 'Othercustom value which should be truncated abcdefghijklmnopqrstuvwxyz', $value = 'abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwxyz');
+ $visitorB->setVisitorCustomVar($id = -2, $name = 'not tracked', $value = 'not tracked');
+ $visitorB->setVisitorCustomVar($id = 6, $name = 'not tracked', $value = 'not tracked');
+ $visitorB->setVisitorCustomVar($id = 6, $name = array('not tracked'), $value = 'not tracked');
+ $visitorB->setUrl('http://example.org/homepage');
+ $this->checkResponse($visitorB->doTrackGoal($idGoal, 1000));
+
+ // Test Referer.get* methods in XML
+ $periods = array('day', 'week');
+ // Request data for both websites at once
+ $idSite = 'all';
+ // Request data for the last 6 periods
+ $this->callGetApiCompareOutput(__FUNCTION__, 'xml', $idSite = 'all', $dateTime, $periods, $setDateLastN = true);
+ }
+
}
diff --git a/tests/integration/expected/test_OneVisitorTwoVisits__CustomVariables.getCustomVariables_day.xml b/tests/integration/expected/test_OneVisitorTwoVisits__CustomVariables.getCustomVariables_day.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/integration/expected/test_OneVisitorTwoVisits__CustomVariables.getCustomVariables_day.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/integration/expected/test_OneVisitorTwoVisits__CustomVars.getCustomVariables_day.xml b/tests/integration/expected/test_OneVisitorTwoVisits__CustomVars.getCustomVariables_day.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/integration/expected/test_OneVisitorTwoVisits__CustomVars.getCustomVariables_day.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVariables.getCustomVariables_day.xml b/tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVariables.getCustomVariables_day.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVariables.getCustomVariables_day.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVars.getCustomVariables_day.xml b/tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVars.getCustomVariables_day.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/integration/expected/test_OneVisitorTwoVisits_withCookieSupport__CustomVars.getCustomVariables_day.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata.xml b/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata.xml
index eb0405b730..48c8d8b34d 100644
--- a/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata.xml
+++ b/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata.xml
@@ -515,6 +515,38 @@
</row>
<row>
+ <category>Visitors</category>
+ <name>Custom Variables</name>
+ <module>CustomVariables</module>
+ <action>getVisitCustomVariables</action>
+ <dimension>Custom Variable name</dimension>
+ <metrics>
+ <nb_visits>Visits</nb_visits>
+ <nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
+ <nb_actions>Actions</nb_actions>
+
+ </metrics>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ <conversion_rate>Conversion Rate</conversion_rate>
+
+ </processedMetrics>
+ <metricsGoal>
+ <nb_conversions>Conversions</nb_conversions>
+ <conversion_rate>Conversion Rate</conversion_rate>
+ <revenue>Revenue</revenue>
+
+ </metricsGoal>
+ <processedMetricsGoal>
+ <revenue_per_visit>Value per Visit</revenue_per_visit>
+
+ </processedMetricsGoal>
+ <uniqueId>CustomVariables_getVisitCustomVariables</uniqueId>
+
+ </row>
+ <row>
<category>Visits Summary</category>
<name>Visits Summary</name>
<module>VisitsSummary</module>
diff --git a/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml b/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml
index eb0405b730..48c8d8b34d 100644
--- a/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml
+++ b/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml
@@ -515,6 +515,38 @@
</row>
<row>
+ <category>Visitors</category>
+ <name>Custom Variables</name>
+ <module>CustomVariables</module>
+ <action>getVisitCustomVariables</action>
+ <dimension>Custom Variable name</dimension>
+ <metrics>
+ <nb_visits>Visits</nb_visits>
+ <nb_uniq_visitors>Unique visitors</nb_uniq_visitors>
+ <nb_actions>Actions</nb_actions>
+
+ </metrics>
+ <processedMetrics>
+ <nb_actions_per_visit>Actions per Visit</nb_actions_per_visit>
+ <avg_time_on_site>Avg. Time on Website</avg_time_on_site>
+ <bounce_rate>Bounce Rate</bounce_rate>
+ <conversion_rate>Conversion Rate</conversion_rate>
+
+ </processedMetrics>
+ <metricsGoal>
+ <nb_conversions>Conversions</nb_conversions>
+ <conversion_rate>Conversion Rate</conversion_rate>
+ <revenue>Revenue</revenue>
+
+ </metricsGoal>
+ <processedMetricsGoal>
+ <revenue_per_visit>Value per Visit</revenue_per_visit>
+
+ </processedMetricsGoal>
+ <uniqueId>CustomVariables_getVisitCustomVariables</uniqueId>
+
+ </row>
+ <row>
<category>Visits Summary</category>
<name>Visits Summary</name>
<module>VisitsSummary</module>
diff --git a/tests/integration/expected/test_noVisit__CustomVariables.getCustomVariables_day.xml b/tests/integration/expected/test_noVisit__CustomVariables.getCustomVariables_day.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/integration/expected/test_noVisit__CustomVariables.getCustomVariables_day.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/integration/expected/test_noVisit__CustomVars.getCustomVariables_day.xml b/tests/integration/expected/test_noVisit__CustomVars.getCustomVariables_day.xml
new file mode 100644
index 0000000000..c234bed59e
--- /dev/null
+++ b/tests/integration/expected/test_noVisit__CustomVars.getCustomVariables_day.xml
@@ -0,0 +1,2 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<result /> \ No newline at end of file
diff --git a/tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml b/tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml
new file mode 100644
index 0000000000..d685159cb4
--- /dev/null
+++ b/tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_day.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+ <result idSite="1">
+ <result date="2010-01-03">
+ <row>
+ <label>VisitorType</label>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_visits>2</nb_visits>
+ <nb_actions>4</nb_actions>
+ <max_actions>3</max_actions>
+ <sum_visit_length>720</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>2</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>2</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <subtable>
+ <row>
+ <label>LoggedOut</label>
+ <nb_uniq_visitors>1</nb_uniq_visitors>
+ <nb_visits>1</nb_visits>
+ <nb_actions>1</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ <row>
+ <label>LoggedIn</label>
+ <nb_uniq_visitors>1</nb_uniq_visitors>
+ <nb_visits>1</nb_visits>
+ <nb_actions>3</nb_actions>
+ <max_actions>3</max_actions>
+ <sum_visit_length>720</sum_visit_length>
+ <bounce_count>0</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>0</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>0</revenue>
+ </row>
+ </subtable>
+ </row>
+ <row>
+ <label>Othercustom value which should be truncated abcdef</label>
+ <nb_uniq_visitors>1</nb_uniq_visitors>
+ <nb_visits>1</nb_visits>
+ <nb_actions>1</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <subtable>
+ <row>
+ <label>abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx</label>
+ <nb_uniq_visitors>1</nb_uniq_visitors>
+ <nb_visits>1</nb_visits>
+ <nb_actions>1</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </subtable>
+ </row>
+ </result>
+ <result date="2010-01-04" />
+ <result date="2010-01-05" />
+ <result date="2010-01-06" />
+ <result date="2010-01-07" />
+ <result date="2010-01-08" />
+ <result date="2010-01-09" />
+ </result>
+</results> \ No newline at end of file
diff --git a/tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml b/tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml
new file mode 100644
index 0000000000..e022827596
--- /dev/null
+++ b/tests/integration/expected/test_twoVisitsWithCustomVariables__CustomVariables.getCustomVariables_week.xml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+ <result idSite="1">
+ <result date="2009-12-28 to 2010-01-03">
+ <row>
+ <label>VisitorType</label>
+ <nb_visits>2</nb_visits>
+ <nb_actions>4</nb_actions>
+ <max_actions>3</max_actions>
+ <sum_visit_length>720</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>2</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>2</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <sum_daily_nb_uniq_visitors>2</sum_daily_nb_uniq_visitors>
+ <subtable>
+ <row>
+ <label>LoggedOut</label>
+ <nb_visits>1</nb_visits>
+ <nb_actions>1</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors>
+ </row>
+ <row>
+ <label>LoggedIn</label>
+ <nb_visits>1</nb_visits>
+ <nb_actions>3</nb_actions>
+ <max_actions>3</max_actions>
+ <sum_visit_length>720</sum_visit_length>
+ <bounce_count>0</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>0</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>0</revenue>
+ <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors>
+ </row>
+ </subtable>
+ </row>
+ <row>
+ <label>Othercustom value which should be truncated abcdef</label>
+ <nb_visits>1</nb_visits>
+ <nb_actions>1</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors>
+ <subtable>
+ <row>
+ <label>abcdefghijklmnopqrstuvwxyzabcdefghijklmnopqrstuvwx</label>
+ <nb_visits>1</nb_visits>
+ <nb_actions>1</nb_actions>
+ <max_actions>1</max_actions>
+ <sum_visit_length>0</sum_visit_length>
+ <bounce_count>1</bounce_count>
+ <nb_visits_converted>1</nb_visits_converted>
+ <goals>
+ <row idgoal='1'>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ </row>
+ </goals>
+ <nb_conversions>1</nb_conversions>
+ <revenue>1000</revenue>
+ <sum_daily_nb_uniq_visitors>1</sum_daily_nb_uniq_visitors>
+ </row>
+ </subtable>
+ </row>
+ </result>
+ <result date="2010-01-04 to 2010-01-10" />
+ <result date="2010-01-11 to 2010-01-17" />
+ <result date="2010-01-18 to 2010-01-24" />
+ <result date="2010-01-25 to 2010-01-31" />
+ <result date="2010-02-01 to 2010-02-07" />
+ <result date="2010-02-08 to 2010-02-14" />
+ </result>
+</results> \ No newline at end of file
diff --git a/tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml b/tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml
new file mode 100644
index 0000000000..31a9143593
--- /dev/null
+++ b/tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_day.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+ <result idSite="1">
+ <result date="2010-01-03">
+ <bounce_count>1</bounce_count>
+ <max_actions>3</max_actions>
+ <nb_actions>4</nb_actions>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_visits>2</nb_visits>
+ <nb_visits_converted>2</nb_visits_converted>
+ <sum_visit_length>720</sum_visit_length>
+ <bounce_rate>50%</bounce_rate>
+ <nb_actions_per_visit>2</nb_actions_per_visit>
+ <avg_time_on_site>360</avg_time_on_site>
+ </result>
+ <result date="2010-01-04" />
+ <result date="2010-01-05" />
+ <result date="2010-01-06" />
+ <result date="2010-01-07" />
+ <result date="2010-01-08" />
+ <result date="2010-01-09" />
+ </result>
+</results> \ No newline at end of file
diff --git a/tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml b/tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml
new file mode 100644
index 0000000000..8619a5f02d
--- /dev/null
+++ b/tests/integration/expected/test_twoVisitsWithCustomVariables__VisitsSummary.get_week.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<results>
+ <result idSite="1">
+ <result date="2009-12-28 to 2010-01-03">
+ <bounce_count>1</bounce_count>
+ <max_actions>3</max_actions>
+ <nb_actions>4</nb_actions>
+ <nb_uniq_visitors>2</nb_uniq_visitors>
+ <nb_visits>2</nb_visits>
+ <nb_visits_converted>2</nb_visits_converted>
+ <sum_visit_length>720</sum_visit_length>
+ <bounce_rate>50%</bounce_rate>
+ <nb_actions_per_visit>2</nb_actions_per_visit>
+ <avg_time_on_site>360</avg_time_on_site>
+ </result>
+ <result date="2010-01-04 to 2010-01-10" />
+ <result date="2010-01-11 to 2010-01-17" />
+ <result date="2010-01-18 to 2010-01-24" />
+ <result date="2010-01-25 to 2010-01-31" />
+ <result date="2010-02-01 to 2010-02-07" />
+ <result date="2010-02-08 to 2010-02-14" />
+ </result>
+</results> \ No newline at end of file
diff --git a/themes/default/common.css b/themes/default/common.css
index 963aded562..ab798f341f 100644
--- a/themes/default/common.css
+++ b/themes/default/common.css
@@ -717,11 +717,11 @@ table.entityTable tr td a {
padding:0 0 0 21px;
line-height:22px;
}
-.entityList ul li .segment{
+.entityList ul li .dimension{
cursor:pointer;
border-bottom:1px solid #d0d0d0;
}
-.entityList ul li.activeSegment .segment {
+.entityList ul li.activeDimension .dimension {
font-weight: bold;
border:0;
}