diff --git a/core/Archive.php b/core/Archive.php index 120f4b05bbe9c22cb0ba654e3128f9a293be03c9..ebf416019714d9e53081fb81d0134c7d2b5feeae 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 031a572a55b2794ccf33c9e35fbbde7413ed31fe..8b28feb63c336a2f01934b7ba9f8144b3b92a319 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 829d8fc6c97256cdaa155dbfe273495181e8934f..f5ff53f31eaed4f2a3e904d4ef93167e6bb79934 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 7be3b734ac196bf57a0081fb12ef94ab710b2934..d06529bf3db5e27d62ab6354f391d87ca7f5163e 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 611e031a52dca58d690c72b83afcd397c5bab3c3..0d6959af907dfa014f0eb5fe3b3877230f434e55 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 1eff39b518ebba1c8481ed1d8d16fff7042aec6f..d2ff3dccebd7accdeaa0828d5d6bf9a2303a76bc 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 c67cc44828437e15174da28131f1aca9cc025a57..549adbffc0157094d309938969463b93a2a24a30 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 fbb3b8bc153c015ba39d0bd2665501b3ba9af12e..dd6cac3a7f82b1950353e778d5bd37719177cd9f 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 826d10b44a46148a6cf1416381b23c1de07cd5e9..541a8785394c0f5766aee8771e7c2785fc541848 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; @@ -80,6 +81,18 @@ class PiwikTracker $this->urlReferer = $url; } + /** + * 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 abc2fcded0fbb17770fe2b1bf8354b06948c042b..9100104a269db6cb3636d26b3db36af3d4caf839 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; } @@ -102,29 +102,6 @@ class Piwik_Actions_API return $dataTable; } - /** - * 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 953762a84288f6caf88dab8bf66e2c2f83e69a97..9624f102dcf5cb0faf83613a2d1a9717c314517c 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 0000000000000000000000000000000000000000..e5af3bd21fdc6ebc42b9cce72eec7eb3424e7126 --- /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 0000000000000000000000000000000000000000..182410d6bd1e47250aba90121b6bc88359665b0f --- /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 0000000000000000000000000000000000000000..ea21757031b21cdf335a5a67678bd30bdaa32940 --- /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 2076507c5db67975a0b34556fd5c614ca6021fb0..e799595d52ac0f780369b269bb7845032a449ae6 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 51d8f97b270ab2298b312bd281c9fdb56f25bcfb..8ec4b4983a4afebff2f25beefa27e994b23a042f 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 9746cc3aeb9ad5bb8d862b836197e072d5c419bf..8b781a2c26d2bc8940547f20ada7add103f04f02 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 similarity index 90% rename from plugins/Goals/templates/list_top_segment.tpl rename to plugins/Goals/templates/list_top_dimension.tpl index 4b5b442c2b23dd7fc2c6871df2e3c4ab45bfc755..50e86d9b4d3e1c9d279c62d0be203b47b1f0998a 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 60c49b3a834e47fdbc9fd5eb99362f83b4f21046..444fafa7c76c2059afa2a9a47f53d58b91671b3d 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 a83b43000490042456053cb431308e72da1eb822..362c47313e8013d9dce061120aae2bea9d07e958 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 similarity index 55% rename from plugins/Goals/templates/table_by_segment.tpl rename to plugins/Goals/templates/table_by_dimension.tpl index 2f79dbfc220ae47e25ad75e4d7c952e04b07c992..80d2541a7b822f693bceec16bfcf137bfd18d9a9 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 3b2991e97df94394182e6bd1e6494e840a85c3b7..10a49a2b293b2a46e9f4d066cdfadb8b64f2248b 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 4df6302d21d4813485baac4f2bca0d5525dd89b1..cf1e5318df82b54a6348ca87d3b00c8fc5d82cc7 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 c2fa26ccaaa2f7cc460c5dae1e6091e08fb1ca80..aa0807fb2cb4aad703720f84850da4f0d5717720 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 d1f7e06741be2383b191f2edcb0015ae1464f821..226fe80026f905f4c4650703a254a14bd4ea069b 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 c092b8128b567d23a7ca17d8a31cd11bed11148a..82c4b63297de025acdf412c7d8497d3e1a43bcc9 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 8ac0bcc73edb5fe0d1e143a5b8330c31ebf5b84d..f173364bca25ccf39750f3abca3d78b395c1ae7b 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 f47c896c559de0bba577ded5741d4fd60c1d5d58..acbfd2d2e6d32e2b6343ad4f54ec157afa81a813 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 89ac84f9f0fe41f954a083b0dea67c182526988c..208956860db5564543026834465e6a79f561a9c0 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 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /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 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /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 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /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 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /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 eb0405b730b6c55034e8fea1c467abdaae5ce58e..48c8d8b34d959289f94c592add2e1ad450c84e8d 100644 --- a/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata.xml +++ b/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata.xml @@ -513,6 +513,38 @@ </metrics> <uniqueId>VisitorInterest_getNumberOfVisitsPerVisitDuration</uniqueId> + </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> diff --git a/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml b/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml index eb0405b730b6c55034e8fea1c467abdaae5ce58e..48c8d8b34d959289f94c592add2e1ad450c84e8d 100644 --- a/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml +++ b/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata.xml @@ -513,6 +513,38 @@ </metrics> <uniqueId>VisitorInterest_getNumberOfVisitsPerVisitDuration</uniqueId> + </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> 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 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /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 0000000000000000000000000000000000000000..c234bed59e963e268d7a9bc05348d941758c4aa9 --- /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 0000000000000000000000000000000000000000..d685159cb4539a2b76c37416c328a9af121275d6 --- /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 0000000000000000000000000000000000000000..e02282759694ba2d947acadda4dfde6a1fabcd3a --- /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 0000000000000000000000000000000000000000..31a91435930fc8d04b551fc9bcb68ee3bbb8ec27 --- /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 0000000000000000000000000000000000000000..8619a5f02d1a30076823a2b6f61f7e3fd76dc542 --- /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 963aded5623144694646fd1bf5140de3ca1cf8a8..ab798f341f2a8c966862e2c934f4487d0e703f94 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; }