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

ColumnCallbackAddColumnQuotient.php « Filter « DataTable « core - github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
blob: 57451675871a4ddadb5ca635457c1b548cb9b2aa (plain)
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
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
<?php
/**
 * Piwik - free/libre analytics platform
 *
 * @link http://piwik.org
 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
 *
 */
namespace Piwik\DataTable\Filter;

use Piwik\DataTable\BaseFilter;
use Piwik\DataTable;
use Piwik\DataTable\Row;

/**
 * Calculates the quotient of two columns and adds the result as a new column
 * for each row of a DataTable.
 *
 * This filter is used to calculate rate values (eg, `'bounce_rate'`), averages
 * (eg, `'avg_time_on_page'`) and other types of values.
 *
 * **Basic usage example**
 *
 *     $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('bounce_rate', 'bounce_count', 'nb_visits', $precision = 2));
 *
 * @api
 */
class ColumnCallbackAddColumnQuotient extends BaseFilter
{
    protected $table;
    protected $columnValueToRead;
    protected $columnNameToAdd;
    protected $columnNameUsedAsDivisor;
    protected $totalValueUsedAsDivisor;
    protected $quotientPrecision;
    protected $shouldSkipRows;
    protected $getDivisorFromSummaryRow;

    /**
     * Constructor.
     *
     * @param DataTable $table The DataTable that will eventually be filtered.
     * @param string $columnNameToAdd The name of the column to add the quotient value to.
     * @param string $columnValueToRead The name of the column that holds the dividend.
     * @param number|string $divisorValueOrDivisorColumnName
     *                           Either numeric value to use as the divisor for every row,
     *                           or the name of the column whose value should be used as the
     *                           divisor.
     * @param int $quotientPrecision The precision to use when rounding the quotient.
     * @param bool|number $shouldSkipRows Whether rows w/o the column to read should be skipped or not.
     * @param bool $getDivisorFromSummaryRow Whether to get the divisor from the summary row or the current
     *                                       row iteration.
     */
    public function __construct($table, $columnNameToAdd, $columnValueToRead, $divisorValueOrDivisorColumnName,
                                $quotientPrecision = 0, $shouldSkipRows = false, $getDivisorFromSummaryRow = false)
    {
        parent::__construct($table);
        $this->table = $table;
        $this->columnValueToRead = $columnValueToRead;
        $this->columnNameToAdd = $columnNameToAdd;
        if (is_numeric($divisorValueOrDivisorColumnName)) {
            $this->totalValueUsedAsDivisor = $divisorValueOrDivisorColumnName;
        } else {
            $this->columnNameUsedAsDivisor = $divisorValueOrDivisorColumnName;
        }
        $this->quotientPrecision = $quotientPrecision;
        $this->shouldSkipRows = $shouldSkipRows;
        $this->getDivisorFromSummaryRow = $getDivisorFromSummaryRow;
    }

    /**
     * See {@link ColumnCallbackAddColumnQuotient}.
     *
     * @param DataTable $table
     */
    public function filter($table)
    {
        foreach ($table->getRows() as $row) {
            $value = $this->getDividend($row);
            if ($value === false && $this->shouldSkipRows) {
                continue;
            }

            // Delete existing column if it exists
            $existingValue = $row->getColumn($this->columnNameToAdd);
            if ($existingValue !== false) {
                continue;
            }

            $divisor = $this->getDivisor($row);

            $formattedValue = $this->formatValue($value, $divisor);
            $row->addColumn($this->columnNameToAdd, $formattedValue);

            $this->filterSubTable($row);
        }
    }

    /**
     * Formats the given value
     *
     * @param number $value
     * @param number $divisor
     * @return float|int
     */
    protected function formatValue($value, $divisor)
    {
        $quotient = 0;
        if ($divisor > 0 && $value > 0) {
            $quotient = round($value / $divisor, $this->quotientPrecision);
        }

        return $quotient;
    }

    /**
     * Returns the dividend to use when calculating the new column value. Can
     * be overridden by descendent classes to customize behavior.
     *
     * @param 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 Row $row The row being modified.
     * @return int|float
     */
    protected function getDivisor($row)
    {
        if (!is_null($this->totalValueUsedAsDivisor)) {
            return $this->totalValueUsedAsDivisor;
        } elseif ($this->getDivisorFromSummaryRow) {
            $summaryRow = $this->table->getRowFromId(DataTable::ID_SUMMARY_ROW);
            return $summaryRow->getColumn($this->columnNameUsedAsDivisor);
        } else {
            return $row->getColumn($this->columnNameUsedAsDivisor);
        }
    }
}