1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
|
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
* @version $Id$
*
* @category Piwik
* @package Piwik
*/
/**
* @package Piwik
* @subpackage Piwik_DataTable
*/
class Piwik_DataTable_Filter_AddColumnsProcessedMetrics extends Piwik_DataTable_Filter
{
protected $invalidDivision = 0;
protected $roundPrecision = 2;
protected $deleteRowsWithNoVisit = true;
/**
* @param Piwik_DataTable $table
* @param bool $deleteRowsWithNoVisit Automatically set to true when filter_add_columns_when_show_all_columns is found in the API request
* @return Piwik_DataTable_Filter_AddColumnsProcessedMetrics
*/
public function __construct( $table, $deleteRowsWithNoVisit = true )
{
$this->deleteRowsWithNoVisit = $deleteRowsWithNoVisit;
parent::__construct($table);
}
public function filter($table)
{
$rowsIdToDelete = array();
foreach($table->getRows() as $key => $row)
{
$nbVisits = $this->getColumn($row, Piwik_Archive::INDEX_NB_VISITS);
$nbActions = $this->getColumn($row, Piwik_Archive::INDEX_NB_ACTIONS);
if($nbVisits == 0
&& $nbActions == 0
&& $this->deleteRowsWithNoVisit)
{
// case of keyword/website/campaign with a conversion for this day,
// but no visit, we don't show it
$rowsIdToDelete[] = $key;
continue;
}
$nbVisitsConverted = (int)$this->getColumn($row, Piwik_Archive::INDEX_NB_VISITS_CONVERTED);
if($nbVisitsConverted > 0)
{
$conversionRate = round(100 * $nbVisitsConverted / $nbVisits, $this->roundPrecision);
$row->addColumn('conversion_rate', $conversionRate."%");
}
if($nbVisits == 0)
{
$actionsPerVisit = $averageTimeOnSite = $bounceRate = $this->invalidDivision;
}
else
{
// nb_actions / nb_visits => Actions/visit
// sum_visit_length / nb_visits => Avg. Time on Site
// bounce_count / nb_visits => Bounce Rate
$actionsPerVisit = round($nbActions / $nbVisits, $this->roundPrecision);
$averageTimeOnSite = round($this->getColumn($row, Piwik_Archive::INDEX_SUM_VISIT_LENGTH) / $nbVisits, $rounding = 0);
$bounceRate = round(100 * $this->getColumn($row, Piwik_Archive::INDEX_BOUNCE_COUNT) / $nbVisits, $this->roundPrecision);
}
try {
$row->addColumn('nb_actions_per_visit', $actionsPerVisit);
$row->addColumn('avg_time_on_site', $averageTimeOnSite);
} catch(Exception $e) {}
try {
$row->addColumn('bounce_rate', $bounceRate."%");
} catch(Exception $e) {}
$this->filterSubTable($row);
}
$table->deleteRows($rowsIdToDelete);
}
/**
* Returns column from a given row.
* Will work with 2 types of datatable
* - raw datatables coming from the archive DB, which columns are int indexed
* - datatables processed resulting of API calls, which columns have human readable english names
*
* @param Piwik_DataTable_Row $row
* @param int $columnIdRaw see consts in Piwik_Archive::
* @param bool $mappingIdToName
* @return mixed Value of column, false if not found
*/
protected function getColumn($row, $columnIdRaw, $mappingIdToName = false)
{
if(empty($mappingIdToName))
{
$mappingIdToName = Piwik_Archive::$mappingFromIdToName;
}
$columnIdReadable = $mappingIdToName[$columnIdRaw];
if($row instanceof Piwik_DataTable_Row)
{
$raw = $row->getColumn($columnIdRaw);
if($raw !== false)
{
return $raw;
}
return $row->getColumn($columnIdReadable);
}
if(isset($row[$columnIdRaw]))
{
return $row[$columnIdRaw];
}
if(isset($row[$columnIdReadable]))
{
return $row[$columnIdReadable];
}
return false;
}
}
|