From 6e8ae94fc44bb42b34e5ed9070cbd10dcf01a3d4 Mon Sep 17 00:00:00 2001 From: benakamoorthi <benaka.moorthi@gmail.com> Date: Sun, 25 Dec 2011 23:44:45 +0000 Subject: [PATCH] Fixes #2810. Refactored MultiSites plugin: * Created MultiSites API w/ getAll method that gets visit/action/revenue & related evolution data for all sites. * Modified MultiSites Controller to use aforementioned API. * Fixed bug I introduced in integration tests, method doTest_TwoVisitors_twoWebsites_differentDays shouldn't allow tests to skip the API.getProcessedReport test. * Added mergeChildren & related unit test to Piwik_DataTable_Array. * Added static methods to Piwik_Site to get site data using an ID. Using it avoids having to create a new Piwik_Site instance. * Modified ColumnCallbackAddColumnQuotient so it can be better extended and so it's possible to avoid processing rows if desired. git-svn-id: http://dev.piwik.org/svn/trunk@5626 59fd770c-687e-43c8-a1e3-f5a4ff64c105 --- core/DataTable/Array.php | 121 ++++++++++ .../ColumnCallbackAddColumnQuotient.php | 50 +++- core/Site.php | 114 ++++++++- plugins/MultiSites/API.php | 191 +++++++++++++++ .../MultiSites/CalculateEvolutionFilter.php | 148 ++++++++++++ plugins/MultiSites/Controller.php | 219 +++++++----------- plugins/MultiSites/MultiSites.php | 25 ++ plugins/MultiSites/templates/index.tpl | 4 +- tests/core/DataTable/Array.test.php | 131 +++++++++++ tests/integration/Integration.php | 4 +- tests/integration/Main.test.php | 34 +-- ...isitorTwoVisits__MultiSites.getAll_day.xml | 13 ++ ...Site_lastN__API.getProcessedReport_day.xml | 2 +- ...Site_lastN__API.getProcessedReport_day.xml | 2 +- ...Site_lastN__API.getProcessedReport_day.xml | 2 +- ...Site_lastN__API.getProcessedReport_day.xml | 195 ++++++++++++++++ ...Site_lastN__API.getProcessedReport_day.xml | 102 ++++++++ ...ersions_NotLastNPeriods__Goals.get_day.xml | 1 + ...sions_NotLastNPeriods__Goals.get_month.xml | 1 + ...ays_Conversions__MultiSites.getAll_day.xml | 50 ++++ ...s_Conversions__MultiSites.getAll_month.xml | 29 +++ ...ys_Conversions__MultiSites.getAll_week.xml | 40 ++++ ...ys_Conversions__MultiSites.getAll_year.xml | 29 +++ ...ions_idSiteOne___MultiSites.getAll_day.xml | 50 ++++ ...ns_idSiteOne___MultiSites.getAll_month.xml | 29 +++ ...ons_idSiteOne___MultiSites.getAll_week.xml | 40 ++++ ...ons_idSiteOne___MultiSites.getAll_year.xml | 29 +++ ...Site_lastN__API.getProcessedReport_day.xml | 2 +- ...Site_lastN__API.getProcessedReport_day.xml | 2 +- ...Site_lastN__API.getProcessedReport_day.xml | 2 +- ...Site_lastN__API.getProcessedReport_day.xml | 2 +- ...ortMetadata__API.getReportMetadata_day.xml | 29 +++ ...adata_year__API.getReportMetadata_year.xml | 29 +++ ...it_PeriodIsLast__MultiSites.getAll_day.xml | 10 + ...t_PeriodIsLast__MultiSites.getAll_week.xml | 10 + .../test_noVisit__MultiSites.getAll_day.xml | 2 + ...e_IndexedByDate__MultiSites.getAll_day.xml | 28 +++ ...ays_DateRange__MultiSites.getAll_range.xml | 10 + 38 files changed, 1610 insertions(+), 171 deletions(-) create mode 100755 plugins/MultiSites/API.php create mode 100755 plugins/MultiSites/CalculateEvolutionFilter.php create mode 100755 tests/core/DataTable/Array.test.php create mode 100755 tests/integration/expected/test_OneVisitorTwoVisits__MultiSites.getAll_day.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml create mode 100755 tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml create mode 100755 tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml create mode 100755 tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml create mode 100755 tests/integration/expected/test_noVisit__MultiSites.getAll_day.xml create mode 100755 tests/integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml create mode 100755 tests/integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml diff --git a/core/DataTable/Array.php b/core/DataTable/Array.php index a32288fada..067f6219a2 100644 --- a/core/DataTable/Array.php +++ b/core/DataTable/Array.php @@ -126,6 +126,17 @@ class Piwik_DataTable_Array return $this->array; } + /** + * Returns the table with the specified label. + * + * @param string $label + * @return Piwik_DataTable + */ + public function getTable($label) + { + return $this->array[$label]; + } + /** * Adds a new DataTable to the DataTable_Array * @@ -198,4 +209,114 @@ class Piwik_DataTable_Array return $newTableArray; } + /** + * Merges the rows of every child DataTable into a new DataTable and + * returns it. This function will also set the label of the merged rows + * to the label of the DataTable they were originally from. + * + * The result of this function is determined by the type of DataTable + * this instance holds. If this DataTable_Array instance holds an array + * of DataTables, this function will transform it from: + * <code> + * Label 0: + * DataTable(row1) + * Label 1: + * DataTable(row2) + * </code> + * to: + * <code> + * DataTable(row1[label = 'Label 0'], row2[label = 'Label 1']) + * </code> + * + * If this instance holds an array of DataTable_Arrays, this function will + * transform it from: + * <code> + * Outer Label 0: // the outer DataTable_Array + * Inner Label 0: // one of the inner DataTable_Arrays + * DataTable(row1) + * Inner Label 1: + * DataTable(row2) + * Outer Label 1: + * Inner Label 0: + * DataTable(row3) + * Inner Label 1: + * DataTable(row4) + * </code> + * to: + * <code> + * Inner Label 0: + * DataTable(row1[label = 'Outer Label 0'], row3[label = 'Outer Label 1']) + * Inner Label 1: + * DataTable(row2[label = 'Outer Label 0'], row4[label = 'Outer Label 1']) + * </code> + * + * In addition, if this instance holds an array of DataTable_Arrays, the + * metadata of the first child is used as the metadata of the result. + * + * This function can be used, for example, to smoosh IndexedBySite archive + * query results into one DataTable w/ different rows differentiated by site ID. + * + * @return Piwik_DataTable|Piwik_DataTable_Array + */ + public function mergeChildren() + { + $firstChild = reset($this->array); + + if ($firstChild instanceof Piwik_DataTable_Array) + { + $result = new Piwik_DataTable_Array(); + $result->setKeyName($firstChild->getKeyName()); + $result->metadata = $firstChild->metadata; + + foreach ($this->array as $label => $subTableArray) + { + foreach ($subTableArray->array as $innerLabel => $subTable) + { + if (!isset($result->array[$innerLabel])) + { + $result->addTable(new Piwik_DataTable(), $innerLabel); + } + + $this->copyRowsAndSetLabel($result->array[$innerLabel], $subTable, $label); + } + } + } + else + { + $result = new Piwik_DataTable(); + + foreach ($this->array as $label => $subTable) + { + $this->copyRowsAndSetLabel($result, $subTable, $label); + } + } + + return $result; + } + + /** + * Utility function used by mergeChildren. Copies the rows from one table, + * sets their 'label' columns to a value and adds them to another table. + * + * @param Piwik_DataTable $toTable The table to copy rows to. + * @param Piwik_DataTable $fromTable The table to copy rows from. + * @param string $label The value to set the 'label' column of every copied + * row. + */ + private function copyRowsAndSetLabel($toTable, $fromTable, $label) + { + foreach ($fromTable->getRows() as $fromRow) + { + $oldColumns = $fromRow->getColumns(); + unset($oldColumns['label']); + + $columns = array_merge(array('label' => $label), $oldColumns); + $row = new Piwik_DataTable_Row(array( + Piwik_DataTable_Row::COLUMNS => $columns, + Piwik_DataTable_Row::METADATA => $fromRow->getMetadata(), + Piwik_DataTable_Row::DATATABLE_ASSOCIATED => $fromRow->getIdSubDataTable() + )); + $toTable->addRow($row); + } + } } diff --git a/core/DataTable/Filter/ColumnCallbackAddColumnQuotient.php b/core/DataTable/Filter/ColumnCallbackAddColumnQuotient.php index 22f157b447..7476111f36 100644 --- a/core/DataTable/Filter/ColumnCallbackAddColumnQuotient.php +++ b/core/DataTable/Filter/ColumnCallbackAddColumnQuotient.php @@ -24,6 +24,7 @@ class Piwik_DataTable_Filter_ColumnCallbackAddColumnQuotient extends Piwik_DataT protected $columnNameUsedAsDivisor; protected $totalValueUsedAsDivisor; protected $quotientPrecision; + protected $shouldSkipRows; /** * @param Piwik_DataTable $table @@ -33,8 +34,9 @@ class Piwik_DataTable_Filter_ColumnCallbackAddColumnQuotient extends Piwik_DataT * if a numeric value is given, we use this value as the divisor to process the percentage. * if a string is given, this string is the column name's value used as the divisor. * @param numeric $quotientPrecision Division precision + * @param numeric $shouldSkipRows Whether rows w/o the column to read should be skipped. */ - public function __construct( $table, $columnNameToAdd, $columnValueToRead, $divisorValueOrDivisorColumnName, $quotientPrecision = 0) + public function __construct( $table, $columnNameToAdd, $columnValueToRead, $divisorValueOrDivisorColumnName, $quotientPrecision = 0, $shouldSkipRows = false) { parent::__construct($table); $this->columnValueToRead = $columnValueToRead; @@ -48,6 +50,7 @@ class Piwik_DataTable_Filter_ColumnCallbackAddColumnQuotient extends Piwik_DataT $this->columnNameUsedAsDivisor = $divisorValueOrDivisorColumnName; } $this->quotientPrecision = $quotientPrecision; + $this->shouldSkipRows = $shouldSkipRows; } public function filter($table) @@ -59,15 +62,15 @@ class Piwik_DataTable_Filter_ColumnCallbackAddColumnQuotient extends Piwik_DataT { continue; } - $value = $row->getColumn($this->columnValueToRead); - if(!is_null($this->totalValueUsedAsDivisor)) - { - $divisor = $this->totalValueUsedAsDivisor; - } - else + + $value = $this->getDividend($row); + if ($value === false && $this->shouldSkipRows) { - $divisor = $row->getColumn($this->columnNameUsedAsDivisor); + continue; } + + $divisor = $this->getDivisor($row); + $formattedValue = $this->formatValue($value, $divisor); $row->addColumn($this->columnNameToAdd, $formattedValue); @@ -84,4 +87,35 @@ class Piwik_DataTable_Filter_ColumnCallbackAddColumnQuotient extends Piwik_DataT } return $quotient; } + + /** + * Returns the dividend to use when calculating the new column value. Can + * be overridden by descendent classes to customize behavior. + * + * @param Piwik_DataTable_Row $row The row being modified. + * @return int|float + */ + protected function getDividend($row) + { + return $row->getColumn($this->columnValueToRead); + } + + /** + * Returns the divisor to use when calculating the new column value. Can + * be overridden by descendent classes to customize behavior. + * + * @param Piwik_DataTable_Row $row The row being modified. + * @return int|float + */ + protected function getDivisor($row) + { + if(!is_null($this->totalValueUsedAsDivisor)) + { + return $this->totalValueUsedAsDivisor; + } + else + { + return $row->getColumn($this->columnNameUsedAsDivisor); + } + } } diff --git a/core/Site.php b/core/Site.php index 5619458934..8989c0123c 100644 --- a/core/Site.php +++ b/core/Site.php @@ -22,10 +22,10 @@ class Piwik_Site function __construct($idsite) { - $this->id = $idsite; + $this->id = (int)$idsite; if(!isset(self::$infoSites[$this->id])) { - self::$infoSites[$this->id] = Piwik_SitesManager_API::getInstance()->getSiteFromId($idsite); + self::$infoSites[$this->id] = Piwik_SitesManager_API::getInstance()->getSiteFromId($this->id); } } @@ -147,4 +147,114 @@ class Piwik_Site { self::$infoSites = array(); } + + /** + * Utility function. Returns the value of the specified field for the + * site with the specified ID. + * + * @param int|string $idsite The ID of the site whose data is being + * accessed. + * @param string $field The name of the field to get. + * @return mixed + */ + static protected function getFor($idsite, $field) + { + $idsite = (int)$idsite; + + if (!isset(self::$infoSites[$idsite])) + { + self::$infoSites[$idsite] = Piwik_SitesManager_API::getInstance()->getSiteFromId($idsite); + } + + return self::$infoSites[$idsite][$field]; + } + + /** + * Returns the name of the site with the specified ID. + * + * @param int $idsite The site ID. + * @return string + */ + static public function getNameFor($idsite) + { + return self::getFor($idsite, 'name'); + } + + /** + * Returns the timezone of the site with the specified ID. + * + * @param int $idsite The site ID. + * @return string + */ + static public function getTimezoneFor($idsite) + { + return self::getFor($idsite, 'timezone'); + } + + /** + * Returns the creation date of the site with the specified ID. + * + * @param int $idsite The site ID. + * @return string + */ + static public function getCreationDateFor($idsite) + { + return self::getFor($idsite, 'ts_created'); + } + + /** + * Returns the url for the site with the specified ID. + * + * @param int $idsite The site ID. + * @return string + */ + static public function getMainUrlFor($idsite) + { + return self::getFor($idsite, 'main_url'); + } + + /** + * Returns whether the site with the specified ID is ecommerce enabled + * + * @param int $idsite The site ID. + * @return string + */ + static public function isEcommerceEnabledFor($idsite) + { + return self::getFor($idsite, 'ecommerce') == 1; + } + + /** + * Returns the currency of the site with the specified ID. + * + * @param int $idsite The site ID. + * @return string + */ + static public function getCurrencyFor($idsite) + { + return self::getFor($idsite, 'currency'); + } + + /** + * Returns the excluded IP addresses of the site with the specified ID. + * + * @param int $idsite The site ID. + * @return string + */ + static public function getExcludedIpsFor($idsite) + { + return self::getFor($idsite, 'excluded_ips'); + } + + /** + * Returns the excluded query parameters for the site with the specified + * ID. + * + * @param int $idsite The site ID. + * @return string + */ + static public function getExcludedQueryParametersFor($idsite) + { + return self::getFor($idsite, 'excluded_parameters'); + } } diff --git a/plugins/MultiSites/API.php b/plugins/MultiSites/API.php new file mode 100755 index 0000000000..d252b41a61 --- /dev/null +++ b/plugins/MultiSites/API.php @@ -0,0 +1,191 @@ +<?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: API.php$ + * + * @category Piwik_Plugins + * @package Piwik_Goals + */ + +/** + * @see plugins/MultiSites/CalculateEvolutionFilter.php + */ +require_once PIWIK_INCLUDE_PATH . '/plugins/MultiSites/CalculateEvolutionFilter.php'; + +/** + * The API class for the MultiSites plugin. + */ +class Piwik_MultiSites_API +{ + /** + * The singleton instance of this class. + */ + static private $instance = null; + + /** + * Returns the singleton instance of this class. The instance is created + * if it hasn't been already. + * + * @return Piwik_Goals_API + */ + static public function getInstance() + { + if (self::$instance == null) + { + self::$instance = new self; + } + + return self::$instance; + } + + /** + * Mapping of metric names to the names of their 'evolution' metric + * counterparts. Used by getAll. + */ + private $evolutionColumnNames = null; + + /** + * Constructor. + */ + function __construct() + { + $this->evolutionColumnNames = array( + 'nb_visits' => 'visits_evolution', + 'nb_actions' => 'actions_evolution' + ); + + if (Piwik_Common::isGoalPluginEnabled()) + { + $this->evolutionColumnNames[Piwik_Goals::getRecordName('revenue')] = 'revenue_evolution'; + } + } + + /** + * Returns a report displaying the total visits, actions and revenue, as + * well as the evolution of these values, of all existing sites over a + * specified period of time. + * + * If the specified period is not a 'range', this function will calculcate + * evolution metrics. Evolution metrics are metrics that display the + * percent increase/decrease of another metric since the last period. + * + * This function will merge the result of the archive query so each + * row in the result DataTable will correspond to the metrics of a single + * site. If a date range is specified, the result will be a + * DataTable_Array, but it will still be merged. + * + * @param string $period The period type to get data for. + * @param string $date The date(s) to get data for. + * @param string $segment The segments to get data for. + */ + public function getAll($period, $date, $segment = false) + { + Piwik::checkUserHasSomeViewAccess(); + $isGoalPluginEnabled = Piwik_Common::isGoalPluginEnabled(); + + // get site data for every viewable site and cache them + if (Piwik::isUserIsSuperUser()) + { + $sites = Piwik_SitesManager_API::getInstance()->getAllSites(); + Piwik_Site::setSites($sites); + } + else + { + $sites = Piwik_SitesManager_API::getInstance()->getSitesWithAtLeastViewAccess(); + Piwik_Site::setSitesFromArray($sites); + } + + // build the archive type used to query archive data + $archive = Piwik_Archive::build('all', $period, $date, $segment); + + // determine what data will be displayed + $fieldsToGet = array('nb_visits', 'nb_actions'); + if ($isGoalPluginEnabled) + { + $revenueMetric = Piwik_Goals::getRecordName('revenue'); + $fieldsToGet[] = $revenueMetric; + } + + // get the data + $dataTable = $archive->getDataTableFromNumeric($fieldsToGet); + + // get rid of the DataTable_Array that is created by the IndexedBySite archive type + $dataTable = $dataTable->mergeChildren(); + + // if the period isn't a range & a lastN/previousN date isn't used, we get the same + // data for the last period to show the evolution of visits/actions/revenue + if ($period != 'range' && !preg_match('/(last|previous)([0-9]*)/', $date, $regs)) + { + if (strpos($date, ',')) // date in the form of 2011-01-01,2011-02-02 + { + $rangePeriod = new Piwik_Period_Range($period, $date); + + $lastStartDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateStart(), $n = 1); + $lastEndDate = Piwik_Period_Range::removePeriod($period, $rangePeriod->getDateEnd(), $n = 1); + + $strLastDate = "$lastStartDate,$lastEndDate"; + } + else + { + $strLastDate = (string)Piwik_Period_Range::removePeriod($period, Piwik_Date::factory($date), $n = 1); + } + + $pastArchive = Piwik_Archive::build('all', $period, $strLastDate, $segment); + $pastData = $pastArchive->getDataTableFromNumeric($fieldsToGet); + + $pastData = $pastData->mergeChildren(); + + // use past data to calculate evolution percentages + $this->calculateEvolutionPercentages($dataTable, $pastData, $fieldsToGet); + } + + // move the site id to a metadata column + $dataTable->filter('ColumnCallbackAddMetadata', array('label', 'idsite')); + + // set the label of each row to the site name + $getNameFor = array('Piwik_Site', 'getNameFor'); + $dataTable->filter('ColumnCallbackReplace', array('label', $getNameFor)); + + // rename the revenue column from the metric name to 'revenue' + if ($isGoalPluginEnabled) + { + $mapping = array($revenueMetric => 'revenue'); + $dataTable->filter('ReplaceColumnNames', array($mapping)); + } + + return $dataTable; + } + + /** + * Utility function used by getAll. Performs a binary filter of two + * DataTables in order to correctly calculate evolution metrics. + * + * @param Piwik_DataTable|Piwik_DataTable_Array $currentData + * @param Piwik_DataTable|Piwik_DataTable_Array $pastData + * @param array $fields The array of string fields to calculate evolution + * metrics for. + */ + private function calculateEvolutionPercentages($currentData, $pastData, $fields) + { + if ($currentData instanceof Piwik_DataTable_Array) + { + $pastArray = &$pastData->getArray(); + foreach ($currentData->getArray() as $label => $subTable) + { + $this->calculateEvolutionPercentages($subTable, current($pastArray), $fields); + next($pastArray); + } + } + else + { + foreach ($fields as $field) + { + $currentData->filter('Piwik_MultiSites_CalculateEvolutionFilter', + array($pastData, $this->evolutionColumnNames[$field], $field, $quotientPrecision = 2)); + } + } + } +} diff --git a/plugins/MultiSites/CalculateEvolutionFilter.php b/plugins/MultiSites/CalculateEvolutionFilter.php new file mode 100755 index 0000000000..20d64c9221 --- /dev/null +++ b/plugins/MultiSites/CalculateEvolutionFilter.php @@ -0,0 +1,148 @@ +<?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: CalculateEvolutionFilter.php$ + * + * @category Piwik_Plugins + * @package Piwik_Goals + */ + +/** + * A DataTable filter that calculates the evolution of a metric and adds + * it to each row as a percentage. + * + * This filter cannot be used as a normal filter since it requires + * corresponding data from another datatable. Instead, to use it, + * you must manually perform a binary filter (see the MultiSites API). + * + * The evolution metric is calculated as: + * <code>((currentValue - pastValue) / pastValue) * 100</code> + */ +class Piwik_MultiSites_CalculateEvolutionFilter extends Piwik_DataTable_Filter_ColumnCallbackAddColumnPercentage +{ + /** + * The rows of the DataTable that contains past data. + */ + private $pastDataTableRows; + + /** + * The current row in the past DataTable. Set and reset as the filter + * executes. + */ + private $pastRow = null; + + /** + * Tells if column being added is the revenue evolution column. + */ + private $isRevenueEvolution = null; + + /** + * Constructor. + * + * @param Piwik_DataTable $table The DataTable being filtered. + * @param string $columnToAdd + * @param string $columnToRead + * @param int $quotientPrecision + */ + function __construct($table, $pastDataTable, $columnToAdd, $columnToRead, $quotientPrecision = 0) + { + parent::__construct( + $table, $columnToAdd, $columnToRead, $columnToRead, $quotientPrecision, $shouldSkipRows = true); + + $this->pastDataTableRows = $pastDataTable->getRows(); + reset($this->pastDataTableRows); + + $this->isRevenueEvolution = $columnToAdd == 'revenue_evolution'; + } + + /** + * Returns the difference between the column in the specific row and its + * sister column in the past DataTable. + * + * @param Piwik_DataTable_Row $row + * @return int|float + */ + protected function getDividend($row) + { + $currentValue = $row->getColumn($this->columnValueToRead); + + // if the site this is for doesn't support ecommerce & this is for the revenue_evolution column, + // we don't add the new column + if ($currentValue === false + && $this->isRevenueEvolution + && !Piwik_Site::isEcommerceEnabledFor($row->getColumn('label'))) + { + return false; + } + + $this->pastRow = $this->getCurrentPastRowAndAdvance(); + if ($this->pastRow) + { + $pastValue = $this->pastRow->getColumn($this->columnValueToRead); + } + else + { + $pastValue = 0; + } + + return $currentValue - $pastValue; + } + + /** + * Returns the value of the column in $row's sister row in the past + * DataTable. + * + * @param Piwik_DataTable_Row $row + * @return int|float + */ + protected function getDivisor($row) + { + if (!$this->pastRow) return 0; + + return $this->pastRow->getColumn($this->columnNameUsedAsDivisor); + } + + /** + * Calculates and formats a quotient based on a divisor and dividend. + * + * Unlike Piwik_DataTable_Filter_ColumnCallbackAddColumnPercentage's, + * version of this method, this method will return 100% if the past + * value of a metric is 0, and the current value is not 0. For a + * value representative of an evolution, this makes sense. + * + * @param int|float $value The dividend. + * @param int|float $divisor + * @return string + */ + protected function formatValue($value, $divisor) + { + if($value == 0) + { + $evolution = 0; + } + elseif($divisor == 0) + { + $evolution = 100; + } + else + { + $evolution = ($value / $divisor) * 100; + } + + return round($evolution, $this->quotientPrecision).'%'; + } + + /** + * Utility function. Returns the current row in the past DataTable and + * increments the pastDataTableRows' internal iterator. + */ + private function getCurrentPastRowAndAdvance() + { + $result = current($this->pastDataTableRows); + next($this->pastDataTableRows); + return $result; + } +} diff --git a/plugins/MultiSites/Controller.php b/plugins/MultiSites/Controller.php index c85a23a19b..fdcd2e5bc9 100644 --- a/plugins/MultiSites/Controller.php +++ b/plugins/MultiSites/Controller.php @@ -19,7 +19,6 @@ class Piwik_MultiSites_Controller extends Piwik_Controller protected $orderBy = 'visits'; protected $order = 'desc'; protected $evolutionBy = 'visits'; - protected $mySites = array(); protected $page = 1; protected $limit = 0; protected $period; @@ -55,85 +54,81 @@ class Piwik_MultiSites_Controller extends Piwik_Controller $date = $this->getDateParameterInTimezone($dateRequest, $piwikDefaultTimezone); $date = $date->toString(); } - - if (Piwik::isUserIsSuperUser()) - { - $mySites = Piwik_SitesManager_API::getInstance()->getAllSites(); - Piwik_Site::setSites($mySites); - - $mySites = array_values($mySites); - } - else - { - $mySites = Piwik_SitesManager_API::getInstance()->getSitesWithAtLeastViewAccess(); - Piwik_Site::setSitesFromArray($mySites); - } + $siteIds = Piwik_SitesManager_API::getInstance()->getSitesIdWithAtLeastViewAccess(); + $dataTable = Piwik_MultiSites_API::getInstance()->getAll($period, $date, $segment = false); - $ids = 'all'; + list($minDate, $maxDate) = $this->getMinMaxDateAcrossWebsites($siteIds); - // Current date - select metrics - $dataTableArray = Piwik_VisitsSummary_API::getInstance()->get($ids, $period, $date, $segment = false, $columns = array('nb_visits', 'nb_actions')); - $currentVisits = $this->getArrayFromAPI($dataTableArray, 'nb_visits'); - $currentActions = $this->getArrayFromAPI($dataTableArray, 'nb_actions'); - if($displayRevenueColumn) - { - $dataTableArray = Piwik_Goals_API::getInstance()->get($ids, $period, $date, $segment = false, $idGoal = false, $columns = array('revenue')); - $currentRevenue = $this->getArrayFromAPI($dataTableArray, 'revenue'); - } - // Previous date - $lastVisits = $lastActions = $lastRevenue = array(); - if($period != 'range') + $totalVisits = $totalActions = $totalRevenue = 0; + + // put data into a form the template will understand better + $digestableData = array(); + foreach($siteIds as $idSite) { - $lastDate = Piwik_Period_Range::removePeriod($period, Piwik_Date::factory($date), $n = 1 ); - $dataTableArray = Piwik_VisitsSummary_API::getInstance()->get($ids, $period, $lastDate, $segment = false, $columns = array('nb_visits', 'nb_actions')); - $lastVisits = $this->getArrayFromAPI($dataTableArray, 'nb_visits'); - $lastActions = $this->getArrayFromAPI($dataTableArray, 'nb_actions'); - if($displayRevenueColumn) + $isEcommerceEnabled = Piwik_Site::isEcommerceEnabledFor($idSite); + + $digestableData[$idSite] = array( + 'idsite' => $idSite, + 'main_url' => Piwik_Site::getMainUrlFor($idSite), + 'name' => Piwik_Site::getNameFor($idSite), + 'visits' => 0, + 'actions' => 0 + ); + + if ($period != 'range') { - $dataTableArray = Piwik_Goals_API::getInstance()->get($ids, $period, $lastDate, $segment = false, $idGoal = false, $columns = array('revenue')); - $lastRevenue = $this->getArrayFromAPI($dataTableArray, 'revenue'); + $digestableData[$idSite]['visits_evolution'] = 0; + $digestableData[$idSite]['actions_evolution'] = 0; } - } - - $visitsSummary = $this->getChangeCurrentVsLast($currentVisits, $lastVisits); - $actionsSummary = $this->getChangeCurrentVsLast($currentActions, $lastActions); - if($displayRevenueColumn) - { - $revenueSummary = $this->getChangeCurrentVsLast($currentRevenue, $lastRevenue); - } - $totalVisits = $totalActions = $totalRevenue = 0; - - foreach($mySites as &$site) - { - $idSite = $site['idsite']; - if($period != 'range') + + if ($displayRevenueColumn) { - $site['lastVisits'] = $lastVisits[$idSite]; - $site['lastActions'] = $lastActions[$idSite]; - if($displayRevenueColumn) + $revenueDefault = $isEcommerceEnabled ? 0 : "'-'"; + + if ($period != 'range') { - $site['lastRevenue'] = $lastRevenue[$idSite]; + $digestableData[$idSite]['revenue_evolution'] = $revenueDefault; } } + } + + foreach($dataTable->getRows() as $row) + { + $idsite = (int)$row->getMetadata('idsite'); + + $site = &$digestableData[$idsite]; - $site['visits'] = $currentVisits[$idSite]; - $site['actions'] = $currentActions[$idSite]; + $site['visits'] = $row->getColumn('nb_visits'); $totalVisits += $site['visits']; + + $site['actions'] = $row->getColumn('nb_actions'); $totalActions += $site['actions']; - $site['visitsSummaryValue'] = $visitsSummary[$idSite]; - $site['actionsSummaryValue'] = $actionsSummary[$idSite]; - $site['revenue'] = $site['revenueSummaryValue'] = 0; - if($displayRevenueColumn) + + if ($displayRevenueColumn) + { + if ($row->getColumn('revenue') !== false) + { + $site['revenue'] = $row->getColumn('revenue'); + $totalRevenue += $site['revenue']; + } + } + + if ($period != 'range') { - $site['revenue'] = $currentRevenue[$idSite]; - $totalRevenue += $site['revenue']; - $site['revenueSummaryValue'] = $revenueSummary[$idSite]; + $site['visits_evolution'] = $row->getColumn('visits_evolution'); + $site['actions_evolution'] = $row->getColumn('actions_evolution'); + + if ($displayRevenueColumn) + { + $site['revenue_evolution'] = $row->getColumn('revenue_evolution'); + } } } - $mySites = $this->applyPrettyMoney($mySites); + $this->applyPrettyMoney($digestableData); + $view = new Piwik_View("MultiSites/templates/index.tpl"); - $view->mySites = $mySites; + $view->sitesData = array_values($digestableData); $view->evolutionBy = $this->evolutionBy; $view->period = $period; $view->dateRequest = $dateRequest; @@ -160,93 +155,30 @@ class Piwik_MultiSites_Controller extends Piwik_Controller $view->autoRefreshTodayReport = Zend_Registry::get('config')->General->multisites_refresh_after_seconds; } $this->setGeneralVariablesView($view); - $this->setMinMaxDateAcrossWebsites($mySites, $view); + $this->setMinDateView($minDate, $view); + $this->setMaxDateView($maxDate, $view); $view->show_sparklines = Zend_Registry::get('config')->General->show_multisites_sparklines; echo $view->render(); } - protected function applyPrettyMoney($sites) - { - foreach($sites as &$site) - { - $revenue = "-"; - if(!empty($site['revenue'])) - { - $revenue = Piwik::getPrettyMoney($site['revenue'], $site['idsite'], $htmlAllowed = false); - } - $site['revenue'] = '"'. $revenue . '"'; - } - return $sites; - } - - protected function getChangeCurrentVsLast($current, $last) - { - $evolution = array(); - foreach($current as $idSite => $value) - { - $evolution[$idSite] = $this->getEvolutionPercentage($value, isset($last[$idSite]) ? $last[$idSite] : 0); - } - return $evolution; - } - - private function getEvolutionPercentage($current, $last) - { - if($current == 0 && $last == 0) - { - $evolution = 0; - } - elseif($last == 0) - { - $evolution = 100; - } - else - { - $evolution = (($current - $last) / $last) * 100; - } - - $output = round($evolution,2); - - return $output; - } - - protected function getArrayFromAPI($dataTableArray, $column) - { - $values = array(); - foreach($dataTableArray->getArray() as $id => $row) - { - $firstRow = $row->getFirstRow(); - $value = 0; - if($firstRow) - { - $value = $firstRow->getColumn($column); - } - if($column == 'revenue') - { - $value = round($value); - } - $values[$id] = $value; - } - return $values; - } - /** * The Multisites reports displays the first calendar date as the earliest day available for all websites. * Also, today is the later "today" available across all timezones. - * @param array $mySites - * @param Piwik_View $view - * @return void + * @param array $siteIds Array of IDs for each site being displayed. + * @return array of two Piwik_Date instances. First is the min-date & the second + * is the max date. */ - private function setMinMaxDateAcrossWebsites($mySites, $view) + private function getMinMaxDateAcrossWebsites($siteIds) { $now = Piwik_Date::now(); $minDate = null; $maxDate = $now->subDay(1)->getTimestamp(); - foreach($mySites as &$site) + foreach($siteIds as $idsite) { // look for 'now' in the website's timezone - $timezone = $site['timezone']; + $timezone = Piwik_Site::getTimezoneFor($idsite); $date = Piwik_Date::adjustForTimezone($now->getTimestamp(), $timezone); if($date > $maxDate) { @@ -254,17 +186,30 @@ class Piwik_MultiSites_Controller extends Piwik_Controller } // look for the absolute minimum date - $creationDate = $site['ts_created']; + $creationDate = Piwik_Site::getCreationDateFor($idsite); $date = Piwik_Date::adjustForTimezone(strtotime($creationDate), $timezone); if(is_null($minDate) || $date < $minDate) { $minDate = $date; } } - $this->setMinDateView(Piwik_Date::factory($minDate), $view); - $this->setMaxDateView(Piwik_Date::factory($maxDate), $view); + + return array(Piwik_Date::factory($minDate), Piwik_Date::factory($maxDate)); } + protected function applyPrettyMoney(&$sites) + { + foreach($sites as $idsite => &$site) + { + $revenue = "-"; + if(!empty($site['revenue'])) + { + $revenue = Piwik::getPrettyMoney($site['revenue'], $site['idsite'], $htmlAllowed = false); + } + $site['revenue'] = '"'. $revenue . '"'; + } + } + public function getEvolutionGraph( $fetch = false, $columns = false) { if(empty($columns)) diff --git a/plugins/MultiSites/MultiSites.php b/plugins/MultiSites/MultiSites.php index f682c55e1d..ba24d351fa 100644 --- a/plugins/MultiSites/MultiSites.php +++ b/plugins/MultiSites/MultiSites.php @@ -32,6 +32,31 @@ class Piwik_MultiSites extends Piwik_Plugin 'AssetManager.getCssFiles' => 'getCssFiles', 'AssetManager.getJsFiles' => 'getJsFiles', 'TopMenu.add' => 'addTopMenu', + 'API.getReportMetadata' => 'getReportMetadata', + ); + } + + public function getReportMetadata($notification) + { + $isGoalPluginEnabled = Piwik_Common::isGoalPluginEnabled(); + + $metrics = array( 'nb_visits', 'nb_actions' ); + if ($isGoalPluginEnabled) + { + $metrics['revenue'] = Piwik_Translate('Goals_ColumnRevenue'); + } + + $reports = &$notification->getNotificationObject(); + $reports[] = array( + 'category' => Piwik_Translate('General_MultiSitesSummary'), + 'name' => Piwik_Translate('Referers_WidgetOverview'), // re-using translation + 'module' => 'MultiSites', + 'action' => 'getAll', + 'dimension' => Piwik_Translate('General_Website'), // re-using translation + 'metrics' => $metrics, + 'processedMetrics' => false, + 'constantRowsCount' => false, + 'order' => 5 ); } diff --git a/plugins/MultiSites/templates/index.tpl b/plugins/MultiSites/templates/index.tpl index 8dd48b7c7d..143b819ae2 100644 --- a/plugins/MultiSites/templates/index.tpl +++ b/plugins/MultiSites/templates/index.tpl @@ -7,8 +7,8 @@ <script type="text/javascript"> var allSites = new Array(); var params = new Array(); - {foreach from=$mySites key=i item=site} - allSites[{$i}] = new setRowData({$site.idsite}, {$site.visits}, {$site.actions}, {$site.revenue}, '{$site.name|escape:"javascript"}', '{$site.main_url|escape:"javascript"}', '{$site.visitsSummaryValue|replace:",":"."}', '{$site.actionsSummaryValue|replace:",":"."}', '{$site.revenueSummaryValue|replace:",":"."}'); + {foreach from=$sitesData key=i item=site} + allSites[{$i}] = new setRowData({$site.idsite}, {$site.visits}, {$site.actions}, {$site.revenue}, '{$site.name|escape:"javascript"}', '{$site.main_url|escape:"javascript"}', '{$site.visits_evolution|replace:",":"."}', '{$site.actions_evolution|replace:",":"."}', '{$site.revenue_evolution|replace:",":"."}'); {/foreach} params['period'] = '{$period}'; params['date'] = '{$dateRequest}'; diff --git a/tests/core/DataTable/Array.test.php b/tests/core/DataTable/Array.test.php new file mode 100755 index 0000000000..cd918bea94 --- /dev/null +++ b/tests/core/DataTable/Array.test.php @@ -0,0 +1,131 @@ +<?php +if(!defined('PIWIK_CONFIG_TEST_INCLUDED')) +{ + require_once dirname(__FILE__)."/../../../tests/config_test.php"; +} + +require_once 'DataTable.php'; +require_once 'DataTable/Array.php'; + +class Test_Piwik_DataTable_Array extends UnitTestCase +{ + public function setUp() + { + parent::setUp(); + Piwik::createConfigObject(); + Zend_Registry::get('config')->setTestEnvironment(); + Piwik_DataTable_Manager::getInstance()->deleteAll(); + } + + public function tearDown() + { + parent::tearDown(); + } + + private function createTestDataTable() + { + $result = new Piwik_DataTable(); + + $result->addRowsFromArray(array( + array(Piwik_DataTable_Row::COLUMNS => array('label'=>'row1', 'col1' => 1)), + array(Piwik_DataTable_Row::COLUMNS => array('label'=>'row2', 'col1' => 2)) + )); + + return $result; + } + + private function createInstanceWithDataTables() + { + $dataTable = new Piwik_DataTable_Array(); + + $subDataTable1 = $this->createTestDataTable(); + $dataTable->addTable($subDataTable1, 'subDataTable1'); + + $subDataTable2 = $this->createTestDataTable(); + $dataTable->addTable($subDataTable2, 'subDataTable2'); + + return $dataTable; + } + + private function createInstanceWithDataTableArrays() + { + $dataTable = new Piwik_DataTable_Array(); + + $subDataTableArray1 = $this->createInstanceWithDataTables(); + $subDataTableArray1->metadata['metadataKey1'] = 'metadataValue1'; + $dataTable->addTable($subDataTableArray1, 'subArray1'); + + $subDataTableArray2 = $this->createInstanceWithDataTables(); + $dataTable->addTable($subDataTableArray2, 'subArray2'); + + return $dataTable; + } + + /** Tests that Piwik_DataTable_Array::mergeChildren works when the DataTable_Array contains DataTables. */ + public function test_mergeChildren_DataTable() + { + $dataTable = $this->createInstanceWithDataTables(); + + $result = $dataTable->mergeChildren(); + + // check that the result is a DataTable w/ 4 rows + $this->assertTrue($result instanceof Piwik_DataTable); + $this->assertEqual(4, $result->getRowsCount()); + + // check that the first two rows have 'subDataTable1' as the label + $this->mergeChildren_checkRow($result->getRowFromId(0), 'subDataTable1', 1); + $this->mergeChildren_checkRow($result->getRowFromId(1), 'subDataTable1', 2); + + // check that the last two rows have 'subDataTable2' as the label + $this->mergeChildren_checkRow($result->getRowFromId(2), 'subDataTable2', 1); + $this->mergeChildren_checkRow($result->getRowFromId(3), 'subDataTable2', 2); + } + + private function mergeChildren_checkRow($row, $expectedLabel, $expectedColumnValue) + { + $this->assertEqual($expectedLabel, $row->getColumn('label')); + $this->assertEqual($expectedColumnValue, $row->getColumn('col1')); + } + + /** Tests that Piwik_DataTable_Array::mergeChildren works when the DataTable_Array contains DataTable_Arrays. */ + public function test_mergeChildren_DataTableArray() + { + $dataTable = $this->createInstanceWithDataTableArrays(); + + $result = $dataTable->mergeChildren(); + + // check that the result is a DataTable_Array w/ two DataTable children + $this->assertTrue($result instanceof Piwik_DataTable_Array); + $this->assertEqual(2, $result->getRowsCount()); + + // check that the result has one metadata, 'metadataKey1' => 'metadataValue1' + $this->assertEqual(1, count($result->metadata)); + $this->assertEqual('metadataValue1', $result->metadata['metadataKey1']); + + // check that the first sub-DataTable is a DataTable with 4 rows + $subDataTable1 = $result->getTable('subDataTable1'); + $this->assertTrue($subDataTable1 instanceof Piwik_DataTable); + $this->assertEqual(4, $subDataTable1->getRowsCount()); + + // check that the first two rows of the first sub-table have 'subArray1' as the label + $this->mergeChildren_checkRow($subDataTable1->getRowFromId(0), 'subArray1', 1); + $this->mergeChildren_checkRow($subDataTable1->getRowFromId(1), 'subArray1', 2); + + // check that the last two rows of the first sub-table have 'subArray2' as the label + $this->mergeChildren_checkRow($subDataTable1->getRowFromId(2), 'subArray2', 1); + $this->mergeChildren_checkRow($subDataTable1->getRowFromId(3), 'subArray2', 2); + + // check that the second sub-DataTable is a DataTable with 4 rows + $subDataTable2 = $result->getTable('subDataTable2'); + $this->assertTrue($subDataTable2 instanceof Piwik_DataTable); + $this->assertEqual(4, $subDataTable2->getRowsCount()); + + // check that the first two rows of the second sub-table have 'subArray1' as the label + $this->mergeChildren_checkRow($subDataTable2->getRowFromId(0), 'subArray1', 1); + $this->mergeChildren_checkRow($subDataTable2->getRowFromId(1), 'subArray1', 2); + + // check that the last two rows of the second sub-table have 'subArray2' as the label + $this->mergeChildren_checkRow($subDataTable2->getRowFromId(2), 'subArray2', 1); + $this->mergeChildren_checkRow($subDataTable2->getRowFromId(3), 'subArray2', 2); + } +} diff --git a/tests/integration/Integration.php b/tests/integration/Integration.php index 258fe1b4e5..4a997620b7 100644 --- a/tests/integration/Integration.php +++ b/tests/integration/Integration.php @@ -127,10 +127,10 @@ abstract class Test_Integration extends Test_Database * @param $dateTime eg '2010-01-01 12:34:56' * @return $idSite of website created */ - protected function createWebsite( $dateTime, $ecommerce = 0 ) + protected function createWebsite( $dateTime, $ecommerce = 0, $siteName = 'Piwik test' ) { $idSite = Piwik_SitesManager_API::getInstance()->addSite( - "Piwik test", + $siteName, "http://piwik.net/", $ecommerce, $ips = null, diff --git a/tests/integration/Main.test.php b/tests/integration/Main.test.php index f200daf227..9c53ea3fff 100644 --- a/tests/integration/Main.test.php +++ b/tests/integration/Main.test.php @@ -574,8 +574,8 @@ class Test_Piwik_Integration_Main extends Test_Integration public function test_TwoVisitors_twoWebsites_differentDays_Conversions() { - $apiToCall = array('Goals.getDaysToConversion'); - $this->doTest_TwoVisitors_twoWebsites_differentDays(__FUNCTION__, $apiToCall, true, false); + $apiToCall = array('Goals.getDaysToConversion', 'MultiSites.getAll'); + $this->doTest_TwoVisitors_twoWebsites_differentDays(__FUNCTION__, $apiToCall, true); // Tests that getting a visits summary metric (nb_visits) & a Goal's metric (Goal_revenue) // at the same time works. @@ -590,7 +590,7 @@ class Test_Piwik_Integration_Main extends Test_Integration } private function doTest_TwoVisitors_twoWebsites_differentDays( - $function, $apiToCall, $allowConversions = false, $testGetProcessedReport = true) + $function, $apiToCall, $allowConversions = false) { $dateTime = '2010-01-03 11:22:33'; $idSites = $this->setup_TwoVisitors_twoWebsites_differentDays($dateTime, $allowConversions); @@ -609,10 +609,7 @@ class Test_Piwik_Integration_Main extends Test_Integration // testing metadata API for multiple periods $this->setApiNotToCall(array()); - if ($testGetProcessedReport) - { - $this->setApiToCall( array('API.getProcessedReport' ) ); - } + $this->setApiToCall( array('API.getProcessedReport' ) ); $apiToCall = array_diff($apiToCall, array('Actions.getPageTitle', 'Actions.getPageUrl')); foreach($apiToCall as $api) { @@ -624,11 +621,12 @@ class Test_Piwik_Integration_Main extends Test_Integration private function setup_TwoVisitors_twoWebsites_differentDays($dateTime, $allowConversions = false) { // tests run in UTC, the Tracker in UTC - $idSite = $this->createWebsite($dateTime); - $idSite2 = $this->createWebsite($dateTime); + $ecommerce = $allowConversions ? 1 : 0; + $idSite = $this->createWebsite($dateTime, $ecommerce, "Site 1"); + $idSite2 = $this->createWebsite($dateTime, 0, "Site 2"); if ($allowConversions) { - Piwik_Goals_API::getInstance()->addGoal($idSite, 'all', 'url', 'http', 'contains'); + Piwik_Goals_API::getInstance()->addGoal($idSite, 'all', 'url', 'http', 'contains', false, 5); Piwik_Goals_API::getInstance()->addGoal($idSite2, 'all', 'url', 'http', 'contains'); } // - @@ -1000,7 +998,7 @@ class Test_Piwik_Integration_Main extends Test_Integration 'VisitsSummary.get', 'UserSettings.getResolution', 'VisitFrequency.get', - 'VisitTime.getVisitInformationPerServerTime', + 'VisitTime.getVisitInformationPerServerTime' )); $this->callGetApiCompareOutput(__FUNCTION__, 'xml', $idSite, @@ -1016,7 +1014,7 @@ class Test_Piwik_Integration_Main extends Test_Integration // Check that requesting period "Range" means // only processing the requested Plugin blob (Actions in this case), not all Plugins blobs $tests = array( - // 4 blobs for the Actions plugin, 7 blogs for UserSettings, 2 blobs VisitTime + // 4 blobs for the Actions plugin, 7 blobs for UserSettings, 2 blobs VisitTime 'archive_blob_2010_12' => (4 + 7 + 2) * 3, // (VisitsSummary 5 metrics + 1 flag - no Unique visitors for range) // + 1 flag archive UserSettings @@ -1034,8 +1032,18 @@ class Test_Piwik_Integration_Main extends Test_Integration { $sql = "SELECT count(*) FROM " . Piwik_Common::prefixTable($table) . " WHERE period = ".Piwik::$idPeriods['range']; $countBlobs = Zend_Registry::get('db')->fetchOne($sql); - $this->assertEqual( $expectedRows, $countBlobs, "$table expected $countBlobs" ); + $this->assertEqual( $expectedRows, $countBlobs, "$table expected $expectedRows, got $countBlobs" ); } + + // perform other tests AFTER above blob/numeric count checks are done + // first test is same range test + $this->setApiToCall(array('MultiSites.getAll')); + $this->callGetApiCompareOutput(__FUNCTION__, 'xml', $idSite, '2010-12-15,2011-01-15', array('range')); + + // test several dates (tests use of IndexedByDate w/ 'date1,date2,etc.') + $this->setApiToCall(array('MultiSites.getAll')); + $this->callGetApiCompareOutput( + __FUNCTION__ . '_IndexedByDate', 'xml', $idSite, '2010-12-10', array('day'), $setDateLastN = true); } // test Metadata API + period=range&date=lastN diff --git a/tests/integration/expected/test_OneVisitorTwoVisits__MultiSites.getAll_day.xml b/tests/integration/expected/test_OneVisitorTwoVisits__MultiSites.getAll_day.xml new file mode 100755 index 0000000000..4fa2d13b1e --- /dev/null +++ b/tests/integration/expected/test_OneVisitorTwoVisits__MultiSites.getAll_day.xml @@ -0,0 +1,13 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <label>new name</label> + <nb_visits>2</nb_visits> + <nb_actions>6</nb_actions> + <revenue>43</revenue> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml index 2e1b76ca1d..5239c8595c 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getOutlinks_firstSite_lastN__API.getProcessedReport_day.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <website>Piwik test</website> + <website>Site 1</website> <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> <metadata> <category>Actions</category> diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml index 33d5f8a4aa..967dec8793 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageTitles_firstSite_lastN__API.getProcessedReport_day.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <website>Piwik test</website> + <website>Site 1</website> <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> <metadata> <category>Actions</category> diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml index 6f73ceb45f..332f938fd9 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Actions.getPageUrls_firstSite_lastN__API.getProcessedReport_day.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <website>Piwik test</website> + <website>Site 1</website> <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> <metadata> <category>Actions</category> diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml new file mode 100755 index 0000000000..62da929335 --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_Goals.getDaysToConversion_firstSite_lastN__API.getProcessedReport_day.xml @@ -0,0 +1,195 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <website>Site 1</website> + <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> + <metadata> + <category>Goals</category> + <name>Days to Conversion</name> + <module>Goals</module> + <action>getDaysToConversion</action> + <dimension>Days to Conversion</dimension> + <metrics> + <nb_conversions>Conversions</nb_conversions> + + </metrics> + <metricsGoal> + <nb_conversions>Conversions</nb_conversions> + <revenue>Revenue</revenue> + + </metricsGoal> + <processedMetricsGoal> + <revenue_per_visit>Revenue per Visit</revenue_per_visit> + + </processedMetricsGoal> + <imageGraphUrl>index.php?module=API&method=ImageGraph.get&idSite=1&apiModule=Goals&apiAction=getDaysToConversion&period=range&date=2010-01-03,2010-01-09</imageGraphUrl> + <uniqueId>Goals_getDaysToConversion</uniqueId> + + </metadata> + <columns> + <label>Days to Conversion</label> + <nb_conversions>Conversions</nb_conversions> + <revenue>Revenue</revenue> + + </columns> + <reportData> + <result prettyDate="Sunday 3 January 2010"> + <row> + <label>0 days</label> + <nb_conversions>2</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>1 day</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>2 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>3 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>4 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>5 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>6 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>7 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>8-14 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>15-30 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>31-60 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>61-120 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>121-364 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>365+ days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + </result> + <result prettyDate="Monday 4 January 2010" /> + <result prettyDate="Tuesday 5 January 2010"> + <row> + <label>0 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>1 day</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>2 days</label> + <nb_conversions>1</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>3 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>4 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>5 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>6 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>7 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>8-14 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>15-30 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>31-60 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>61-120 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>121-364 days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + <row> + <label>365+ days</label> + <nb_conversions>0</nb_conversions> + <revenue>$ 0</revenue> + </row> + </result> + <result prettyDate="Wednesday 6 January 2010" /> + <result prettyDate="Thursday 7 January 2010" /> + <result prettyDate="Friday 8 January 2010" /> + <result prettyDate="Saturday 9 January 2010" /> + </reportData> + <reportMetadata> + <result prettyDate="Sunday 3 January 2010" /> + <result prettyDate="Monday 4 January 2010" /> + <result prettyDate="Tuesday 5 January 2010" /> + <result prettyDate="Wednesday 6 January 2010" /> + <result prettyDate="Thursday 7 January 2010" /> + <result prettyDate="Friday 8 January 2010" /> + <result prettyDate="Saturday 9 January 2010" /> + </reportMetadata> + +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml new file mode 100755 index 0000000000..63db7b7ed6 --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_MultiSites.getAll_firstSite_lastN__API.getProcessedReport_day.xml @@ -0,0 +1,102 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <website>Site 1</website> + <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> + <metadata> + <category>All Websites</category> + <name>Overview</name> + <module>MultiSites</module> + <action>getAll</action> + <dimension>Website</dimension> + <metrics> + <nb_visits>Visits</nb_visits> + <nb_actions>Actions</nb_actions> + <revenue>Revenue</revenue> + + </metrics> + <metricsDocumentation> + <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits> + <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors> + <nb_actions>The number of actions performed by your visitors. Actions can be page views, downloads or outlinks.</nb_actions> + <nb_actions_per_visit>The average number of actions (page views, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit> + <avg_time_on_site>The average duration of a visit.</avg_time_on_site> + <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate> + <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate> + <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page> + <nb_hits>The number of times this page was visited.</nb_hits> + <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate> + + </metricsDocumentation> + <imageGraphUrl>index.php?module=API&method=ImageGraph.get&idSite=1&apiModule=MultiSites&apiAction=getAll&period=range&date=2010-01-03,2010-01-09</imageGraphUrl> + <uniqueId>MultiSites_getAll</uniqueId> + + </metadata> + <columns> + <label>Website</label> + <nb_visits>Visits</nb_visits> + <nb_actions>Actions</nb_actions> + <revenue>Revenue</revenue> + + </columns> + <reportData> + <result prettyDate="Sunday 3 January 2010"> + <row> + <label>Site 1</label> + <revenue>$ 10</revenue> + <nb_actions>1</nb_actions> + <nb_visits>1</nb_visits> + </row> + </result> + <result prettyDate="Monday 4 January 2010"> + <row> + <label>Site 1</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <revenue>$ 0</revenue> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <revenue>$ 0</revenue> + </row> + </result> + <result prettyDate="Tuesday 5 January 2010"> + <row> + <label>Site 1</label> + <revenue>$ 5</revenue> + <nb_actions>5</nb_actions> + <nb_visits>1</nb_visits> + </row> + </result> + <result prettyDate="Wednesday 6 January 2010" /> + <result prettyDate="Thursday 7 January 2010" /> + <result prettyDate="Friday 8 January 2010" /> + <result prettyDate="Saturday 9 January 2010" /> + </reportData> + <reportMetadata> + <result prettyDate="Sunday 3 January 2010"> + <row> + <idsite>1</idsite> + </row> + </result> + <result prettyDate="Monday 4 January 2010"> + <row> + <idsite>1</idsite> + </row> + <row> + <idsite>2</idsite> + </row> + </result> + <result prettyDate="Tuesday 5 January 2010"> + <row> + <idsite>1</idsite> + </row> + </result> + <result prettyDate="Wednesday 6 January 2010" /> + <result prettyDate="Thursday 7 January 2010" /> + <result prettyDate="Friday 8 January 2010" /> + <result prettyDate="Saturday 9 January 2010" /> + </reportMetadata> + +</result> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_day.xml index 186811ea2b..6dc2190ded 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_day.xml @@ -4,6 +4,7 @@ <nb_conversions>2</nb_conversions> <nb_visits_converted>1</nb_visits_converted> <conversion_rate>100</conversion_rate> + <revenue>10</revenue> </result> <result idSite="2" /> </results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml index 01b35fd8e1..5fee61a930 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_NotLastNPeriods__Goals.get_month.xml @@ -4,6 +4,7 @@ <nb_conversions>3</nb_conversions> <nb_visits_converted>3</nb_visits_converted> <conversion_rate>100</conversion_rate> + <revenue>15</revenue> </result> <result idSite="2"> <nb_conversions>1</nb_conversions> diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml new file mode 100755 index 0000000000..9e1aefe6a0 --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_day.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2010-01-03"> + <row> + <label>Site 1</label> + <revenue>10</revenue> + <nb_actions>1</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="2010-01-04"> + <row> + <label>Site 1</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>0%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>-100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="2010-01-05"> + <row> + <label>Site 1</label> + <revenue>5</revenue> + <nb_actions>5</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>0%</visits_evolution> + <actions_evolution>150%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="2010-01-06" /> + <result date="2010-01-07" /> + <result date="2010-01-08" /> + <result date="2010-01-09" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml new file mode 100755 index 0000000000..0ef57b143f --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_month.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2010-01"> + <row> + <label>Site 1</label> + <revenue>15</revenue> + <nb_actions>8</nb_actions> + <nb_visits>3</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="2010-02" /> + <result date="2010-03" /> + <result date="2010-04" /> + <result date="2010-05" /> + <result date="2010-06" /> + <result date="2010-07" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml new file mode 100755 index 0000000000..c36276fb0e --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_week.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="From 2009-12-28 to 2010-01-03"> + <row> + <label>Site 1</label> + <revenue>10</revenue> + <nb_actions>1</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="From 2010-01-04 to 2010-01-10"> + <row> + <label>Site 1</label> + <revenue>5</revenue> + <nb_actions>7</nb_actions> + <nb_visits>2</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="From 2010-01-11 to 2010-01-17" /> + <result date="From 2010-01-18 to 2010-01-24" /> + <result date="From 2010-01-25 to 2010-01-31" /> + <result date="From 2010-02-01 to 2010-02-07" /> + <result date="From 2010-02-08 to 2010-02-14" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml new file mode 100755 index 0000000000..399ae9b238 --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions__MultiSites.getAll_year.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2010"> + <row> + <label>Site 1</label> + <revenue>15</revenue> + <nb_actions>8</nb_actions> + <nb_visits>3</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="2011" /> + <result date="2012" /> + <result date="2013" /> + <result date="2014" /> + <result date="2015" /> + <result date="2016" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml new file mode 100755 index 0000000000..9e1aefe6a0 --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_day.xml @@ -0,0 +1,50 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2010-01-03"> + <row> + <label>Site 1</label> + <revenue>10</revenue> + <nb_actions>1</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="2010-01-04"> + <row> + <label>Site 1</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>0%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>-100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="2010-01-05"> + <row> + <label>Site 1</label> + <revenue>5</revenue> + <nb_actions>5</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>0%</visits_evolution> + <actions_evolution>150%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="2010-01-06" /> + <result date="2010-01-07" /> + <result date="2010-01-08" /> + <result date="2010-01-09" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml new file mode 100755 index 0000000000..0ef57b143f --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_month.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2010-01"> + <row> + <label>Site 1</label> + <revenue>15</revenue> + <nb_actions>8</nb_actions> + <nb_visits>3</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="2010-02" /> + <result date="2010-03" /> + <result date="2010-04" /> + <result date="2010-05" /> + <result date="2010-06" /> + <result date="2010-07" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml new file mode 100755 index 0000000000..c36276fb0e --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_week.xml @@ -0,0 +1,40 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="From 2009-12-28 to 2010-01-03"> + <row> + <label>Site 1</label> + <revenue>10</revenue> + <nb_actions>1</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="From 2010-01-04 to 2010-01-10"> + <row> + <label>Site 1</label> + <revenue>5</revenue> + <nb_actions>7</nb_actions> + <nb_visits>2</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="From 2010-01-11 to 2010-01-17" /> + <result date="From 2010-01-18 to 2010-01-24" /> + <result date="From 2010-01-25 to 2010-01-31" /> + <result date="From 2010-02-01 to 2010-02-07" /> + <result date="From 2010-02-08 to 2010-02-14" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml new file mode 100755 index 0000000000..399ae9b238 --- /dev/null +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Conversions_idSiteOne___MultiSites.getAll_year.xml @@ -0,0 +1,29 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2010"> + <row> + <label>Site 1</label> + <revenue>15</revenue> + <nb_actions>8</nb_actions> + <nb_visits>3</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <revenue_evolution>100%</revenue_evolution> + <idsite>1</idsite> + </row> + <row> + <label>Site 2</label> + <nb_actions>2</nb_actions> + <nb_visits>1</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>2</idsite> + </row> + </result> + <result date="2011" /> + <result date="2012" /> + <result date="2013" /> + <result date="2014" /> + <result date="2015" /> + <result date="2016" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml index 4f7484ec5d..bdc174de11 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_Referers.getWebsites_firstSite_lastN__API.getProcessedReport_day.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <website>Piwik test</website> + <website>Site 1</website> <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> <metadata> <category>Referrers</category> diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml index 0e10138e51..698f8cd640 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitFrequency.get_firstSite_lastN__API.getProcessedReport_day.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <website>Piwik test</website> + <website>Site 1</website> <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> <metadata> <category>Visitors</category> diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml index e6e5fe319d..308d06105d 100755 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitorInterest.getNumberOfVisitsByDaysSinceLast_firstSite_lastN__API.getProcessedReport_day.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <website>Piwik test</website> + <website>Site 1</website> <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> <metadata> <category>Visitors</category> diff --git a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml index 7fad82b100..5bfbfdca4a 100644 --- a/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml +++ b/tests/integration/expected/test_TwoVisitors_twoWebsites_differentDays_VisitsSummary.get_firstSite_lastN__API.getProcessedReport_day.xml @@ -1,6 +1,6 @@ <?xml version="1.0" encoding="utf-8" ?> <result> - <website>Piwik test</website> + <website>Site 1</website> <prettyDate>3 Jan 10 - 9 Jan 10</prettyDate> <metadata> <category>Visits Summary</category> diff --git a/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml b/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml index 8689a4dea1..c90365bb79 100644 --- a/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml +++ b/tests/integration/expected/test_apiGetReportMetadata__API.getReportMetadata_day.xml @@ -1,5 +1,34 @@ <?xml version="1.0" encoding="utf-8" ?> <result> + <row> + <category>All Websites</category> + <name>Overview</name> + <module>MultiSites</module> + <action>getAll</action> + <dimension>Website</dimension> + <metrics> + <nb_visits>Visits</nb_visits> + <nb_actions>Actions</nb_actions> + <revenue>Revenue</revenue> + + </metrics> + <metricsDocumentation> + <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits> + <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors> + <nb_actions>The number of actions performed by your visitors. Actions can be page views, downloads or outlinks.</nb_actions> + <nb_actions_per_visit>The average number of actions (page views, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit> + <avg_time_on_site>The average duration of a visit.</avg_time_on_site> + <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate> + <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate> + <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page> + <nb_hits>The number of times this page was visited.</nb_hits> + <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate> + + </metricsDocumentation> + <imageGraphUrl>index.php?module=API&method=ImageGraph.get&idSite=1&apiModule=MultiSites&apiAction=getAll&period=day&date=2009-01-04</imageGraphUrl> + <uniqueId>MultiSites_getAll</uniqueId> + + </row> <row> <category>Visits Summary</category> <name>Visits Summary</name> diff --git a/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata_year.xml b/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata_year.xml index 858a359ebf..639173c61a 100644 --- a/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata_year.xml +++ b/tests/integration/expected/test_apiGetReportMetadata_year__API.getReportMetadata_year.xml @@ -1,5 +1,34 @@ <?xml version="1.0" encoding="utf-8" ?> <result> + <row> + <category>All Websites</category> + <name>Overview</name> + <module>MultiSites</module> + <action>getAll</action> + <dimension>Website</dimension> + <metrics> + <nb_visits>Visits</nb_visits> + <nb_actions>Actions</nb_actions> + <revenue>Revenue</revenue> + + </metrics> + <metricsDocumentation> + <nb_visits>If a visitor comes to your website for the first time or if he visits a page more than 30 minutes after his last page view, this will be recorded as a new visit.</nb_visits> + <nb_uniq_visitors>The number of unduplicated visitors coming to your website. Every user is only counted once, even if he visits the website multiple times a day.</nb_uniq_visitors> + <nb_actions>The number of actions performed by your visitors. Actions can be page views, downloads or outlinks.</nb_actions> + <nb_actions_per_visit>The average number of actions (page views, downloads or outlinks) that were performed during the visits.</nb_actions_per_visit> + <avg_time_on_site>The average duration of a visit.</avg_time_on_site> + <bounce_rate>The percentage of visits that only had a single pageview. This means, that the visitor left the website directly from the entrance page.</bounce_rate> + <conversion_rate>The percentage of visits that triggered a goal conversion.</conversion_rate> + <avg_time_on_page>The average amount of time visitors spent on this page (only the page, not the entire website).</avg_time_on_page> + <nb_hits>The number of times this page was visited.</nb_hits> + <exit_rate>The percentage of visits that left the website after viewing this page.</exit_rate> + + </metricsDocumentation> + <imageGraphUrl>index.php?module=API&method=ImageGraph.get&idSite=1&apiModule=MultiSites&apiAction=getAll&period=year&date=2009-01-04</imageGraphUrl> + <uniqueId>MultiSites_getAll</uniqueId> + + </row> <row> <category>Visits Summary</category> <name>Visits Summary</name> diff --git a/tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml b/tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml new file mode 100755 index 0000000000..106f23f16b --- /dev/null +++ b/tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_day.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2009-01-04" /> + <result date="2009-01-05" /> + <result date="2009-01-06" /> + <result date="2009-01-07" /> + <result date="2009-01-08" /> + <result date="2009-01-09" /> + <result date="2009-01-10" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml b/tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml new file mode 100755 index 0000000000..5cfb246edc --- /dev/null +++ b/tests/integration/expected/test_noVisit_PeriodIsLast__MultiSites.getAll_week.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="From 2008-12-29 to 2009-01-04" /> + <result date="From 2009-01-05 to 2009-01-11" /> + <result date="From 2009-01-12 to 2009-01-18" /> + <result date="From 2009-01-19 to 2009-01-25" /> + <result date="From 2009-01-26 to 2009-02-01" /> + <result date="From 2009-02-02 to 2009-02-08" /> + <result date="From 2009-02-09 to 2009-02-15" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_noVisit__MultiSites.getAll_day.xml b/tests/integration/expected/test_noVisit__MultiSites.getAll_day.xml new file mode 100755 index 0000000000..c234bed59e --- /dev/null +++ b/tests/integration/expected/test_noVisit__MultiSites.getAll_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_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml b/tests/integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml new file mode 100755 index 0000000000..0240fd4129 --- /dev/null +++ b/tests/integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange_IndexedByDate__MultiSites.getAll_day.xml @@ -0,0 +1,28 @@ +<?xml version="1.0" encoding="utf-8" ?> +<results> + <result date="2010-12-10" /> + <result date="2010-12-11" /> + <result date="2010-12-12" /> + <result date="2010-12-13" /> + <result date="2010-12-14"> + <row> + <label>Piwik test</label> + <nb_actions>3</nb_actions> + <nb_visits>2</nb_visits> + <visits_evolution>100%</visits_evolution> + <actions_evolution>100%</actions_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="2010-12-15"> + <row> + <label>Piwik test</label> + <nb_actions>3</nb_actions> + <nb_visits>2</nb_visits> + <visits_evolution>0%</visits_evolution> + <actions_evolution>0%</actions_evolution> + <idsite>1</idsite> + </row> + </result> + <result date="2010-12-16" /> +</results> \ No newline at end of file diff --git a/tests/integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml b/tests/integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml new file mode 100755 index 0000000000..8abf0c1d77 --- /dev/null +++ b/tests/integration/expected/test_oneVisitor_oneWebsite_severalDays_DateRange__MultiSites.getAll_range.xml @@ -0,0 +1,10 @@ +<?xml version="1.0" encoding="utf-8" ?> +<result> + <row> + <label>Piwik test</label> + <nb_visits>6</nb_visits> + <nb_actions>9</nb_actions> + <revenue /> + <idsite>1</idsite> + </row> +</result> \ No newline at end of file -- GitLab