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

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authormatt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2009-04-03 09:41:53 +0400
committermatt <matt@59fd770c-687e-43c8-a1e3-f5a4ff64c105>2009-04-03 09:41:53 +0400
commit3412d1bdc71e9d5f3eed2c22df3cc4e2913af629 (patch)
tree7916751e658eef18ce8cb99e121c0f3cc1c0f935 /core
parent81c7a6b063622e46b7e941e02bdd1419f3f59e81 (diff)
- changing ways of applying filters to a datatable, now $table->filter('Piwik_DataTable_Filter_Sort', array ('nb_visits', 'desc'));
- refs #640 now accurately reporting nb_uniq_visitors in all reports - adding tests
Diffstat (limited to 'core')
-rw-r--r--core/Archive.php3
-rw-r--r--core/ArchiveProcessing/Period.php23
-rw-r--r--core/DataTable.php88
-rw-r--r--core/DataTable/Array.php13
-rw-r--r--core/DataTable/Filter/AddSummaryRow.php7
-rw-r--r--core/DataTable/Filter/ExcludeLowPopulation.php23
-rw-r--r--core/DataTable/Row.php26
-rw-r--r--core/FrontController.php2
-rw-r--r--core/ViewDataTable/GenerateGraphData.php22
-rw-r--r--core/ViewDataTable/HtmlTable/AllColumns.php4
-rw-r--r--core/ViewDataTable/HtmlTable/Goals.php4
11 files changed, 154 insertions, 61 deletions
diff --git a/core/Archive.php b/core/Archive.php
index f6ca63c2b6..a07d0ef9d4 100644
--- a/core/Archive.php
+++ b/core/Archive.php
@@ -55,6 +55,7 @@ abstract class Piwik_Archive
const INDEX_NB_CONVERSIONS = 8;
const INDEX_REVENUE = 9;
const INDEX_GOALS = 10;
+ const INDEX_SUM_DAILY_NB_UNIQ_VISITORS = 11;
const INDEX_GOAL_NB_CONVERSIONS = 1;
const INDEX_GOAL_REVENUE = 2;
@@ -70,6 +71,7 @@ abstract class Piwik_Archive
Piwik_Archive::INDEX_NB_CONVERSIONS => 'nb_conversions',
Piwik_Archive::INDEX_REVENUE => 'revenue',
Piwik_Archive::INDEX_GOALS => 'goals',
+ Piwik_Archive::INDEX_SUM_DAILY_NB_UNIQ_VISITORS => 'sum_daily_nb_uniq_visitors',
);
public static $mappingFromIdToNameGoal = array(
@@ -91,6 +93,7 @@ abstract class Piwik_Archive
'nb_conversions' => Piwik_Archive::INDEX_NB_CONVERSIONS,
'revenue' => Piwik_Archive::INDEX_REVENUE,
'goals' => Piwik_Archive::INDEX_GOALS,
+ 'sum_daily_nb_uniq_visitors' => Piwik_Archive::INDEX_SUM_DAILY_NB_UNIQ_VISITORS,
);
/**
diff --git a/core/ArchiveProcessing/Period.php b/core/ArchiveProcessing/Period.php
index 2a5fae2e93..d1e60db76e 100644
--- a/core/ArchiveProcessing/Period.php
+++ b/core/ArchiveProcessing/Period.php
@@ -21,6 +21,14 @@
*/
class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
{
+ /*
+ * Array of (column name before => column name renamed) of the columns for which sum operation is invalid.
+ * The summed value is not accurate and these columns will be renamed accordingly.
+ */
+ static public $invalidSummedColumnNameToRenamedName = array(
+ Piwik_Archive::INDEX_NB_UNIQ_VISITORS => Piwik_Archive::INDEX_SUM_DAILY_NB_UNIQ_VISITORS
+ );
+
public function __construct()
{
parent::__construct();
@@ -148,6 +156,7 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
* )
*/
public function archiveDataTable( $aRecordName,
+ $invalidSummedColumnNameToRenamedName = null,
$maximumRowsInDataTableLevelZero = null,
$maximumRowsInSubDataTable = null,
$columnToSortByBeforeTruncation = null )
@@ -160,7 +169,7 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
$nameToCount = array();
foreach($aRecordName as $recordName)
{
- $table = $this->getRecordDataTableSum($recordName);
+ $table = $this->getRecordDataTableSum($recordName, $invalidSummedColumnNameToRenamedName);
$nameToCount[$recordName]['level0'] = $table->getRowsCount();
$nameToCount[$recordName]['recursive'] = $table->getRowsCountRecursive();
@@ -180,9 +189,10 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
* The resulting DataTable is returned.
*
* @param string $name
+ * @param array columns in the array (old name, new name) to be renamed as the sum operation is not valid on them (eg. nb_uniq_visitors->sum_daily_nb_uniq_visitors)
* @return Piwik_DataTable
*/
- protected function getRecordDataTableSum( $name )
+ protected function getRecordDataTableSum( $name, $invalidSummedColumnNameToRenamedName )
{
$table = new Piwik_DataTable;
foreach($this->archives as $archive)
@@ -193,6 +203,15 @@ class Piwik_ArchiveProcessing_Period extends Piwik_ArchiveProcessing
$table->addDataTable($datatableToSum);
$archive->freeBlob($name);
}
+
+ if(is_null($invalidSummedColumnNameToRenamedName))
+ {
+ $invalidSummedColumnNameToRenamedName = self::$invalidSummedColumnNameToRenamedName;
+ }
+ foreach($invalidSummedColumnNameToRenamedName as $oldName => $newName)
+ {
+ $table->renameColumn($oldName, $newName);
+ }
return $table;
}
diff --git a/core/DataTable.php b/core/DataTable.php
index b195d64480..5a4b727380 100644
--- a/core/DataTable.php
+++ b/core/DataTable.php
@@ -214,7 +214,7 @@ class Piwik_DataTable
const ID_SUMMARY_ROW = -1;
const LABEL_SUMMARY_ROW = -1;
-
+
/**
* Maximum nesting level
*
@@ -320,6 +320,23 @@ class Piwik_DataTable
}
/**
+ * Apply a filter to this datatable
+ *
+ * @param $className eg. Piwik_DataTable_Filter_Sort
+ * @param $parameters eg. array('nb_visits', 'asc')
+ */
+ public function filter( $className, $parameters = array() )
+ {
+ $reflectionObj = new ReflectionClass($className);
+
+ // the first parameter of a filter is the DataTable
+ // we add the current datatable as the parameter
+ $parameters = array_merge(array($this), $parameters);
+
+ $filter = $reflectionObj->newInstanceArgs($parameters);
+ }
+
+ /**
* Queue a DataTable_Filter that will be applied when applyQueuedFilters() is called.
* (just before sending the datatable back to the browser (or API, etc.)
*
@@ -349,13 +366,7 @@ class Piwik_DataTable
$this->setRowsCountBeforeLimitFilter();
}
- $reflectionObj = new ReflectionClass($filter['className']);
-
- // the first parameter of a filter is the DataTable
- // we add the current datatable as the parameter
- $filter['parameters'] = array_merge(array($this), $filter['parameters']);
-
- $filter = $reflectionObj->newInstanceArgs($filter['parameters']);
+ $this->filter($filter['className'], $filter['parameters']);
}
$this->queuedFilters = array();
}
@@ -649,16 +660,57 @@ class Piwik_DataTable
*/
public function deleteColumn( $name )
{
+ $this->deleteColumns(array($name));
+ }
+
+ /**
+ * Rename a column in all rows
+ * @param $oldName
+ * @param $newName
+ */
+ public function renameColumn( $oldName, $newName )
+ {
foreach($this->getRows() as $row)
{
- $row->deleteColumn($name);
+ $row->renameColumn($oldName, $newName);
+ if(($idSubDataTable = $row->getIdSubDataTable()) !== null)
+ {
+ Piwik_DataTable_Manager::getInstance()->getTable($idSubDataTable)->renameColumn($oldName, $newName);
+ }
}
if(!is_null($this->summaryRow))
+ {
+ $this->summaryRow->renameColumn($oldName, $newName);
+ }
+ }
+
+ /**
+ * Delete columns by name in all rows
+ *
+ * @param string $name
+ */
+ public function deleteColumns($names, $deleteRecursiveInSubtables = false)
+ {
+ foreach($this->getRows() as $row)
{
- $this->summaryRow->deleteColumn($name);
+ foreach($names as $name)
+ {
+ $row->deleteColumn($name);
+ }
+ if(($idSubDataTable = $row->getIdSubDataTable()) !== null)
+ {
+ Piwik_DataTable_Manager::getInstance()->getTable($idSubDataTable)->deleteColumns($names, $deleteRecursiveInSubtables);
+ }
+ }
+ if(!is_null($this->summaryRow))
+ {
+ foreach($names as $name)
+ {
+ $this->summaryRow->deleteColumn($name);
+ }
}
}
-
+
/**
* Deletes the ith row
*
@@ -826,11 +878,16 @@ class Piwik_DataTable
if($depth > self::MAXIMUM_DEPTH_LEVEL_ALLOWED)
{
+ $depth = 0;
throw new Exception("Maximum recursion level of ".self::MAXIMUM_DEPTH_LEVEL_ALLOWED. " reached. You have probably set a DataTable_Row with an associated DataTable which belongs already to its parent hierarchy.");
}
if( !is_null($maximumRowsInDataTable) )
{
- $filter = new Piwik_DataTable_Filter_AddSummaryRow($this, $maximumRowsInDataTable - 1, Piwik_DataTable::LABEL_SUMMARY_ROW, $columnToSortByBeforeTruncation);
+ $this->filter('Piwik_DataTable_Filter_AddSummaryRow',
+ array( $maximumRowsInDataTable - 1,
+ Piwik_DataTable::LABEL_SUMMARY_ROW,
+ $columnToSortByBeforeTruncation)
+ );
}
// For each row, get the serialized row
@@ -1056,13 +1113,8 @@ class Piwik_DataTable
$cleanRow = array();
foreach($array as $label => $row)
{
- // TODO I think this requirement is not true anymore:
- // we make sure that the label column is first in the list!
- // important for the UI javascript mainly...
-
- // array_merge doesn't work here as it reindex the numeric value
- // see the test testMergeArray in PHP_Related.test.php
$cleanRow[Piwik_DataTable_Row::DATATABLE_ASSOCIATED] = null;
+ // we put the 'label' column first as it looks prettier in API results
$cleanRow[Piwik_DataTable_Row::COLUMNS] = array('label' => $label) + $row;
if(!is_null($subtablePerLabel)
// some rows of this table don't have subtables
diff --git a/core/DataTable/Array.php b/core/DataTable/Array.php
index 891b47ff1b..63bbd6704b 100644
--- a/core/DataTable/Array.php
+++ b/core/DataTable/Array.php
@@ -105,6 +105,19 @@ class Piwik_DataTable_Array
}
/**
+ * Apply a filter to all tables in the array
+ * @param $className
+ * @param $parameters
+ */
+ public function filter($className, $parameters = array())
+ {
+ foreach($this->array as $table)
+ {
+ $table->filter($className, $parameters);
+ }
+ }
+
+ /**
* Returns the array of DataTable
*
* @return array of Piwik_DataTable
diff --git a/core/DataTable/Filter/AddSummaryRow.php b/core/DataTable/Filter/AddSummaryRow.php
index e98133f026..95b90198e9 100644
--- a/core/DataTable/Filter/AddSummaryRow.php
+++ b/core/DataTable/Filter/AddSummaryRow.php
@@ -45,9 +45,8 @@ class Piwik_DataTable_Filter_AddSummaryRow extends Piwik_DataTable_Filter
protected function filter()
{
- $filter = new Piwik_DataTable_Filter_Sort($this->table,
- $this->columnToSortByBeforeTruncating,
- 'desc');
+ $this->table->filter('Piwik_DataTable_Filter_Sort',
+ array( $this->columnToSortByBeforeTruncating, 'desc'));
$rows = $this->table->getRows();
$count = $this->table->getRowsCount();
@@ -67,7 +66,7 @@ class Piwik_DataTable_Filter_AddSummaryRow extends Piwik_DataTable_Filter
}
$newRow->addColumn('label', $this->labelSummaryRow);
- $filter = new Piwik_DataTable_Filter_Limit($this->table, 0, $this->startRowToSummarize);
+ $this->table->filter('Piwik_DataTable_Filter_Limit', array(0, $this->startRowToSummarize));
$this->table->addSummaryRow($newRow);
}
}
diff --git a/core/DataTable/Filter/ExcludeLowPopulation.php b/core/DataTable/Filter/ExcludeLowPopulation.php
index 94acd0baea..8479d24202 100644
--- a/core/DataTable/Filter/ExcludeLowPopulation.php
+++ b/core/DataTable/Filter/ExcludeLowPopulation.php
@@ -22,32 +22,33 @@
class Piwik_DataTable_Filter_ExcludeLowPopulation extends Piwik_DataTable_Filter
{
static public $minimumValue;
- public function __construct( $table, $columnToFilter, $minimumValue )
+ const MINIMUM_SIGNIFICANT_PERCENTAGE_THRESHOLD = 0.02;
+ public function __construct( $table, $columnToFilter, $minimumValue, $minimumPercentageThreshold = false )
{
parent::__construct($table);
$this->columnToFilter = $columnToFilter;
if($minimumValue == 0)
{
- $minimumPercentageThreshold = 0.02;
+ if($minimumPercentageThreshold === false)
+ {
+ $minimumPercentageThreshold = self::MINIMUM_SIGNIFICANT_PERCENTAGE_THRESHOLD;
+ }
$allValues = $this->table->getColumn($this->columnToFilter);
$sumValues = array_sum($allValues);
$minimumValue = $sumValues * $minimumPercentageThreshold;
}
self::$minimumValue = $minimumValue;
- if(self::$minimumValue > 1)
- {
- $this->filter();
- }
+ $this->filter();
}
function filter()
{
- $filter = new Piwik_DataTable_Filter_ColumnCallbackDeleteRow(
- $this->table,
- $this->columnToFilter,
- array("Piwik_DataTable_Filter_ExcludeLowPopulation", "excludeLowPopulation")
- );
+ $this->table->filter('Piwik_DataTable_Filter_ColumnCallbackDeleteRow',
+ array($this->columnToFilter,
+ array("Piwik_DataTable_Filter_ExcludeLowPopulation", "excludeLowPopulation")
+ )
+ );
}
static public function excludeLowPopulation($value)
diff --git a/core/DataTable/Row.php b/core/DataTable/Row.php
index 2a26327b38..d29b70f5e1 100644
--- a/core/DataTable/Row.php
+++ b/core/DataTable/Row.php
@@ -19,9 +19,12 @@
* - idSubtable: a row can be linked to a SubTable
*
* IMPORTANT: Make sure that the column named 'label' contains at least one non-numeric character.
- * Otherwise the method addDataTable() or sumRow() would fail because they would consider
- * the 'label' as being a numeric column to sum.
+ * Otherwise the method addDataTable() or sumRow() would fail because they would consider
+ * the 'label' as being a numeric column to sum.
*
+ * PERFORMANCE: Do *not* add new fields except if necessary in this object. New fields will be
+ * serialized and recorded in the DB millions of times. This object size is critical and must be under control.
+ *
* @package Piwik_DataTable
* @subpackage Piwik_DataTable_Row
*
@@ -139,6 +142,15 @@ class Piwik_DataTable_Row
return true;
}
+ public function renameColumn($oldName, $newName)
+ {
+ if(isset($this->c[self::COLUMNS][$oldName]))
+ {
+ $this->c[self::COLUMNS][$newName] = $this->c[self::COLUMNS][$oldName];
+ unset($this->c[self::COLUMNS][$oldName]);
+ }
+ }
+
/**
* Returns the given column
*
@@ -308,14 +320,6 @@ class Piwik_DataTable_Row
}
$this->c[self::METADATA][$name] = $value;
}
-
- //TODO this should not be hardcoded here
- protected $columnsExcludedFromSum = array(
- 'label' => true,
- 'nb_uniq_visitors' => true,
- 'entry_nb_uniq_visitors' => true,
- 'exit_nb_uniq_visitors' => true,
- );
/**
* Sums the given $row columns values to the existing row' columns values.
@@ -330,7 +334,7 @@ class Piwik_DataTable_Row
{
foreach($rowToSum->getColumns() as $columnToSumName => $columnToSumValue)
{
- if(!isset($this->columnsExcludedFromSum[$columnToSumName]))
+ if($columnToSumName != 'label')
{
$thisColumnValue = $this->getColumn($columnToSumName);
$newValue = $this->sumRowArray($thisColumnValue, $columnToSumValue);
diff --git a/core/FrontController.php b/core/FrontController.php
index 7e804f0938..bccd477520 100644
--- a/core/FrontController.php
+++ b/core/FrontController.php
@@ -299,6 +299,8 @@ class Exception_PluginDeactivated extends Exception
}
}
+
+// for more information see http://dev.piwik.org/trac/ticket/374
function destroy(&$var)
{
if (is_object($var)) $var->__destruct();
diff --git a/core/ViewDataTable/GenerateGraphData.php b/core/ViewDataTable/GenerateGraphData.php
index d259d9e76b..1267a728c8 100644
--- a/core/ViewDataTable/GenerateGraphData.php
+++ b/core/ViewDataTable/GenerateGraphData.php
@@ -66,8 +66,8 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable
}
$this->mainAlreadyExecuted = true;
- // we load the data with the filters applied
- $this->disableGenericFilters();
+ // the queued filters will be manually applied later. This is to ensure that filtering using search
+ // will be done on the table before the labels are enhanced (see ReplaceColumnNames)
$this->disableQueuedFilters();
$this->loadDataTableFromAPI();
@@ -75,10 +75,12 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable
if(!empty($graphLimit))
{
$offsetStartSummary = $this->getGraphLimit() - 1;
- $filter = new Piwik_DataTable_Filter_AddSummaryRow($this->dataTable,
- $offsetStartSummary,
- Piwik_Translate('General_Others'),
- Piwik_Archive::INDEX_NB_VISITS);
+ $this->dataTable->filter('Piwik_DataTable_Filter_AddSummaryRow',
+ array($offsetStartSummary,
+ Piwik_Translate('General_Others'),
+ Piwik_Archive::INDEX_NB_VISITS
+ )
+ );
}
$this->dataAvailable = $this->dataTable->getRowsCount() != 0;
@@ -104,11 +106,9 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable
{
$this->dataTable->applyQueuedFilters();
// We apply a filter to the DataTable, decoding the label column (useful for keywords for example)
- $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace(
- $this->dataTable,
- 'label',
- 'urldecode'
- );
+ $this->dataTable->filter('Piwik_DataTable_Filter_ColumnCallbackReplace',
+ array('label','urldecode')
+ );
$data = array();
foreach($this->dataTable->getRows() as $row)
{
diff --git a/core/ViewDataTable/HtmlTable/AllColumns.php b/core/ViewDataTable/HtmlTable/AllColumns.php
index 2a83c9ae80..59327d7071 100644
--- a/core/ViewDataTable/HtmlTable/AllColumns.php
+++ b/core/ViewDataTable/HtmlTable/AllColumns.php
@@ -29,8 +29,8 @@ class Piwik_ViewDataTable_HtmlTable_AllColumns extends Piwik_ViewDataTable_HtmlT
'nb_actions_per_visit',
'avg_time_on_site',
'bounce_rate'));
- $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace($this->dataTable, 'avg_time_on_site', create_function('$averageTimeOnSite', 'return Piwik::getPrettyTimeFromSeconds($averageTimeOnSite);'));
- $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace($this->dataTable, 'bounce_rate', create_function('$bounceRate', 'return $bounceRate."%";'));
+ $this->dataTable->filter('Piwik_DataTable_Filter_ColumnCallbackReplace', array('avg_time_on_site', create_function('$averageTimeOnSite', 'return Piwik::getPrettyTimeFromSeconds($averageTimeOnSite);')));
+ $this->dataTable->filter('Piwik_DataTable_Filter_ColumnCallbackReplace', array('bounce_rate', create_function('$bounceRate', 'return $bounceRate."%";')));
$this->setColumnTranslation('nb_actions_per_visit', Piwik_Translate('General_ColumnActionsPerVisit'));
$this->setColumnTranslation('avg_time_on_site', Piwik_Translate('General_ColumnAvgTimeOnSite'));
$this->setColumnTranslation('bounce_rate', Piwik_Translate('General_ColumnBounceRate'));
diff --git a/core/ViewDataTable/HtmlTable/Goals.php b/core/ViewDataTable/HtmlTable/Goals.php
index 6711f7602c..cf025bc173 100644
--- a/core/ViewDataTable/HtmlTable/Goals.php
+++ b/core/ViewDataTable/HtmlTable/Goals.php
@@ -75,8 +75,8 @@ class Piwik_ViewDataTable_HtmlTable_Goals extends Piwik_ViewDataTable_HtmlTable
$this->columnsToPercentageFilter[] = 'goals_conversion_rate';
foreach($this->columnsToPercentageFilter as $columnName)
{
- $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace($this->dataTable, $columnName, create_function('$rate', 'return $rate."%";'));
+ $this->dataTable->filter('Piwik_DataTable_Filter_ColumnCallbackReplace', array($columnName, create_function('$rate', 'return $rate."%";')));
}
- $filter = new Piwik_DataTable_Filter_ColumnCallbackReplace($this->dataTable, 'revenue_per_visit', array("Piwik", "getPrettyMoney"));
+ $this->dataTable->filter('Piwik_DataTable_Filter_ColumnCallbackReplace', array('revenue_per_visit', array("Piwik", "getPrettyMoney")));
}
}