PluginProbe ʕ •ᴥ•ʔ
Matomo Analytics – Powerful, Privacy-First Insights for WordPress / 1.3.1
Matomo Analytics – Powerful, Privacy-First Insights for WordPress v1.3.1
5.11.1 5.11.0 5.10.2 5.10.1 trunk 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.1.0 1.1.1 1.1.2 1.1.3 1.2.0 1.3.0 1.3.1 1.3.2 4.0.0 4.0.1 4.0.2 4.0.3 4.0.4 4.1.0 4.1.1 4.1.2 4.1.3 4.10.0 4.11.0 4.12.0 4.13.0 4.13.2 4.13.3 4.13.4 4.13.5 4.14.0 4.14.1 4.14.2 4.15.0 4.15.1 4.15.2 4.15.3 4.2.0 4.3.0 4.3.1 4.4.1 4.4.2 4.5.0 4.6.0 5.0.1 5.0.2 5.0.3 5.0.4 5.0.5 5.0.6 5.0.7 5.0.8 5.1.0 5.1.1 5.1.2 5.1.3 5.1.4 5.1.5 5.1.6 5.1.7 5.10.0 5.2.0 5.2.1 5.2.2 5.3.0 5.3.1 5.3.2 5.3.3 5.6.0 5.6.1 5.7.0 5.7.1 5.8.0 5.8.1 5.8.2
matomo / app / core / Plugin / ComputedMetric.php
matomo / app / core / Plugin Last commit date
Dimension 6 years ago API.php 6 years ago AggregatedMetric.php 6 years ago ArchivedMetric.php 6 years ago Archiver.php 6 years ago Categories.php 6 years ago ComponentFactory.php 6 years ago ComputedMetric.php 6 years ago ConsoleCommand.php 6 years ago Controller.php 6 years ago ControllerAdmin.php 6 years ago Dependency.php 6 years ago LogTablesProvider.php 6 years ago Manager.php 6 years ago Menu.php 6 years ago MetadataLoader.php 6 years ago Metric.php 6 years ago PluginException.php 6 years ago ProcessedMetric.php 6 years ago ReleaseChannels.php 6 years ago Report.php 6 years ago ReportsProvider.php 6 years ago RequestProcessors.php 6 years ago Segment.php 6 years ago SettingsProvider.php 6 years ago Tasks.php 6 years ago ThemeStyles.php 6 years ago ViewDataTable.php 6 years ago Visualization.php 6 years ago WidgetsProvider.php 6 years ago
ComputedMetric.php
266 lines
1 <?php
2 /**
3 * Piwik - free/libre analytics platform
4 *
5 * @link https://matomo.org
6 * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
7 */
8 namespace Piwik\Plugin;
9
10 use Piwik\Archive\DataTableFactory;
11 use Piwik\Columns\Dimension;
12 use Piwik\Columns\MetricsList;
13 use Piwik\Common;
14 use Piwik\DataTable;
15 use Piwik\DataTable\Row;
16 use Piwik\Metrics\Formatter;
17 use Piwik\Piwik;
18
19 class ComputedMetric extends ProcessedMetric
20 {
21 const AGGREGATION_AVG = 'avg';
22 const AGGREGATION_RATE = 'rate';
23
24 /**
25 * @var string
26 */
27 private $aggregation;
28
29 /**
30 * @var int
31 */
32 protected $idSite;
33
34 private $name = '';
35 private $type = '';
36 private $translatedName = '';
37 private $documentation = '';
38 private $metric1 = '';
39 private $metric2 = '';
40 private $category = '';
41
42 private $metricsList;
43
44 public function __construct($metric1, $metric2, $aggregation = 'avg')
45 {
46 $nameShort1 = str_replace(array('nb_'), '', $metric1);
47 $nameShort2 = str_replace(array('nb_'), '', $metric2);
48
49 if ($aggregation === ComputedMetric::AGGREGATION_AVG) {
50 $this->name = 'avg_' . $nameShort1 . '_per_' . $nameShort2;
51 } elseif ($aggregation === ComputedMetric::AGGREGATION_RATE) {
52 $this->name = $nameShort1 . '_' . $nameShort2 . '_rate';
53 } else {
54 throw new \Exception('Not supported aggregation type');
55 }
56
57 $this->setMetric1($metric1);
58 $this->setMetric2($metric2);
59 $this->aggregation = $aggregation;
60 }
61
62 public function getDependentMetrics()
63 {
64 return array($this->metric1, $this->metric2);
65 }
66
67 public function setCategory($category)
68 {
69 $this->category = $category;
70 return $this;
71 }
72
73 public function getCategoryId()
74 {
75 return $this->category;
76 }
77
78 public function setMetric1($metric1)
79 {
80 $this->metric1 = $metric1;
81 return $this;
82 }
83
84 public function setMetric2($metric2)
85 {
86 $this->metric2 = $metric2;
87 return $this;
88 }
89
90 public function setDocumentation($documentation)
91 {
92 $this->documentation = $documentation;
93 return $this;
94 }
95
96 public function setTranslatedName($name)
97 {
98 $this->translatedName = $name;
99 return $this;
100 }
101
102 public function setType($type)
103 {
104 $this->type = $type;
105 return $this;
106 }
107
108 public function setName($name)
109 {
110 $this->name = $name;
111 return $this;
112 }
113
114 public function getName()
115 {
116 return $this->name;
117 }
118
119 public function compute(Row $row)
120 {
121 $metric1 = $this->getMetric($row, $this->metric1);
122 $metric2 = $this->getMetric($row, $this->metric2);
123
124 $precision = 2;
125 if ($this->aggregation === self::AGGREGATION_RATE) {
126 $precision = 3;
127 }
128
129 return Piwik::getQuotientSafe($metric1, $metric2, $precision);
130 }
131
132 private function getDetectedType()
133 {
134 if (!$this->type) {
135 if ($this->aggregation === self::AGGREGATION_RATE) {
136 $this->type = Dimension::TYPE_PERCENT;
137 } else {
138 $this->type = Dimension::TYPE_NUMBER; // default to number
139 $metric1 = $this->getMetricsList()->getMetric($this->metric1);
140 if ($metric1) {
141 $dimension = $metric1->getDimension();
142 if ($dimension) {
143 $this->type = $dimension->getType();
144 }
145 }
146 }
147 }
148
149 return $this->type;
150 }
151
152 public function format($value, Formatter $formatter)
153 {
154 if ($this->aggregation === self::AGGREGATION_RATE) {
155 return $formatter->getPrettyPercentFromQuotient($value);
156 }
157
158 $type = $this->getDetectedType();
159
160 switch ($type) {
161 case Dimension::TYPE_MONEY:
162 return $formatter->getPrettyMoney($value, $this->idSite);
163 case Dimension::TYPE_FLOAT:
164 return $formatter->getPrettyNumber($value, $precision = 2);
165 case Dimension::TYPE_NUMBER:
166 return $formatter->getPrettyNumber($value, 1); // we still need to round to have somewhat more accurate result
167 case Dimension::TYPE_DURATION_S:
168 return $formatter->getPrettyTimeFromSeconds(round($value), $displayAsSentence = true);
169 case Dimension::TYPE_DURATION_MS:
170 $val = number_format($value / 1000, 2);
171 if ($val > 60) {
172 $val = round($val);
173 }
174 return $formatter->getPrettyTimeFromSeconds($val, $displayAsSentence = true);
175 case Dimension::TYPE_PERCENT:
176 return $formatter->getPrettyPercentFromQuotient($value);
177 case Dimension::TYPE_BYTE:
178 return $formatter->getPrettySizeFromBytes($value);
179 }
180
181 return $value;
182 }
183
184 public function getTranslatedName()
185 {
186 if (!$this->translatedName) {
187 $metric = $this->getMetricsList();
188 $metric1 = $metric->getMetric($this->metric1);
189 $metric2 = $metric->getMetric($this->metric2);
190
191 if ($this->aggregation === self::AGGREGATION_AVG) {
192 if ($metric1 && $metric1 instanceof ArchivedMetric && $metric2 && $metric2 instanceof ArchivedMetric) {
193
194 $metric1Name = $metric1->getDimension()->getName();
195 $metric2Name = $metric2->getDimension()->getName();
196 return Piwik::translate('General_ComputedMetricAverage', array($metric1Name, $metric2Name));
197 }
198
199 if ($metric1 && $metric1 instanceof ArchivedMetric) {
200 $metric1Name = $metric1->getDimension()->getName();
201 return Piwik::translate('General_AverageX', array($metric1Name));
202 }
203
204 if ($metric1 && $metric2) {
205 return $metric1->getTranslatedName() . ' per ' . $metric2->getTranslatedName();
206 }
207
208 return $this->metric1 . ' per ' . $this->metric2;
209 } else if ($this->aggregation === self::AGGREGATION_RATE) {
210 if ($metric1 && $metric1 instanceof ArchivedMetric) {
211 return Piwik::translate('General_ComputedMetricRate', array($metric1->getTranslatedName()));
212 } else {
213 return Piwik::translate('General_ComputedMetricRate', array($this->metric1));
214 }
215 }
216 }
217 return $this->translatedName;
218 }
219
220 public function getDocumentation()
221 {
222 if (!$this->documentation) {
223 $metric = $this->getMetricsList();
224 $metric1 = $metric->getMetric($this->metric1);
225 $metric2 = $metric->getMetric($this->metric2);
226
227 if ($this->aggregation === self::AGGREGATION_AVG) {
228 if ($metric1 && $metric1 instanceof ArchivedMetric && $metric2 && $metric2 instanceof ArchivedMetric) {
229 return Piwik::translate('General_ComputedMetricAverageDocumentation', array($metric1->getDimension()->getName(), $metric2->getTranslatedName()));
230 }
231
232 if ($metric1 && $metric1 instanceof ArchivedMetric) {
233 return Piwik::translate('General_ComputedMetricAverageShortDocumentation', array($metric1->getDimension()->getName()));
234 }
235
236 return Piwik::translate('General_ComputedMetricAverageDocumentation', array($this->metric1, $this->metric2));
237
238 } else if ($this->aggregation === self::AGGREGATION_RATE) {
239 if ($metric1 && $metric1 instanceof ArchivedMetric) {
240 return Piwik::translate('General_ComputedMetricRateDocumentation', array($metric1->getDimension()->getNamePlural(), $metric2->getDimension()->getNamePlural()));
241 } else {
242 return Piwik::translate('General_ComputedMetricRateShortDocumentation', array($this->metric1));
243 }
244 }
245 }
246 return $this->documentation;
247 }
248
249 private function getMetricsList()
250 {
251 if (!$this->metricsList) {
252 $this->metricsList = MetricsList::get();
253 }
254 return $this->metricsList;
255 }
256
257 public function beforeFormat($report, DataTable $table)
258 {
259 $this->idSite = DataTableFactory::getSiteIdFromMetadata($table);
260 if (empty($this->idSite)) {
261 $this->idSite = Common::getRequestVar('idSite', 0, 'int');
262 }
263 return !empty($this->idSite); // skip formatting if there is no site to get currency info from
264 }
265 }
266