| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugins\Insights; |
|
|
| use Piwik\DataTable; |
| use Piwik\Piwik; |
|
|
| |
| |
| |
| class InsightReport |
| { |
| public const ORDER_BY_RELATIVE = 'relative'; |
| public const ORDER_BY_ABSOLUTE = 'absolute'; |
| public const ORDER_BY_IMPORTANCE = 'importance'; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function generateMoverAndShaker($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $lastTotalValue, $orderBy, $limitIncreaser, $limitDecreaser) |
| { |
| $totalEvolution = $this->getTotalEvolution($totalValue, $lastTotalValue); |
|
|
| $minMoversPercent = 1; |
|
|
| if ($totalEvolution >= 100) { |
| |
| $factor = (int) ceil($totalEvolution / 500); |
| $minGrowthPercentPositive = $totalEvolution + ($factor * 40); |
| $minGrowthPercentNegative = -70; |
| $minDisappearedPercent = 8; |
| $minNewPercent = min(($totalEvolution / 100) * 3, 10); |
| } elseif ($totalEvolution >= 0) { |
| |
| $minGrowthPercentPositive = $totalEvolution + 20; |
| $minGrowthPercentNegative = -1 * $minGrowthPercentPositive; |
| $minDisappearedPercent = 7; |
| $minNewPercent = 5; |
| } else { |
| |
| $minGrowthPercentNegative = $totalEvolution - 20; |
| $minGrowthPercentPositive = abs($minGrowthPercentNegative); |
| $minDisappearedPercent = 7; |
| $minNewPercent = 5; |
| } |
|
|
| if ($totalValue < 200 && $totalValue != 0) { |
| |
| $minMoversPercent = (int) ceil(2 / ($totalValue / 100)); |
| $minNewPercent = max($minNewPercent, $minMoversPercent); |
| $minDisappearedPercent = max($minDisappearedPercent, $minMoversPercent); |
| } |
|
|
| $dataTable = $this->generateInsight($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $minMoversPercent, $minNewPercent, $minDisappearedPercent, $minGrowthPercentPositive, $minGrowthPercentNegative, $orderBy, $limitIncreaser, $limitDecreaser); |
|
|
| $this->addMoversAndShakersMetadata($dataTable, $totalValue, $lastTotalValue); |
|
|
| return $dataTable; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| public function markMoversAndShakers(DataTable $insight, $currentReport, $lastReport, $totalValue, $lastTotalValue) |
| { |
| if (!$insight->getRowsCount()) { |
| return; |
| } |
|
|
| $limitIncreaser = max($insight->getRowsCount(), 3); |
| $limitDecreaser = max($insight->getRowsCount(), 3); |
|
|
| $lastDate = $insight->getMetadata('lastDate'); |
| $date = $insight->getMetadata('date'); |
| $period = $insight->getMetadata('period'); |
| $metric = $insight->getMetadata('metric'); |
| $orderBy = $insight->getMetadata('orderBy'); |
| $reportMetadata = $insight->getMetadata('report'); |
|
|
| $shakers = $this->generateMoverAndShaker($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $lastTotalValue, $orderBy, $limitIncreaser, $limitDecreaser); |
|
|
| foreach ($insight->getRows() as $row) { |
| $label = $row->getColumn('label'); |
|
|
| if ($shakers->getRowFromLabel($label)) { |
| $row->setColumn('isMoverAndShaker', true); |
| } else { |
| $row->setColumn('isMoverAndShaker', false); |
| } |
| } |
|
|
| $this->addMoversAndShakersMetadata($insight, $totalValue, $lastTotalValue); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function generateInsight($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $minMoversPercent, $minNewPercent, $minDisappearedPercent, $minGrowthPercentPositive, $minGrowthPercentNegative, $orderBy, $limitIncreaser, $limitDecreaser) |
| { |
| $minChangeMovers = $this->getMinVisits($totalValue, $minMoversPercent); |
| $minIncreaseNew = $this->getMinVisits($totalValue, $minNewPercent); |
| $minDecreaseDisappeared = $this->getMinVisits($totalValue, $minDisappearedPercent); |
|
|
| $dataTable = new DataTable(); |
| $dataTable->filter( |
| 'Piwik\Plugins\Insights\DataTable\Filter\Insight', |
| array( |
| $currentReport, |
| $lastReport, |
| $metric, |
| $considerMovers = (-1 !== $minMoversPercent), |
| $considerNew = (-1 !== $minNewPercent), |
| $considerDisappeared = (-1 !== $minDisappearedPercent), |
| ) |
| ); |
|
|
| $dataTable->filter( |
| 'Piwik\Plugins\Insights\DataTable\Filter\MinGrowth', |
| array( |
| 'growth_percent_numeric', |
| $minGrowthPercentPositive, |
| $minGrowthPercentNegative, |
| ) |
| ); |
|
|
| if ($minIncreaseNew) { |
| $dataTable->filter( |
| 'Piwik\Plugins\Insights\DataTable\Filter\ExcludeLowValue', |
| array( |
| 'difference', |
| $minIncreaseNew, |
| 'isNew', |
| ) |
| ); |
| } |
|
|
| if ($minChangeMovers) { |
| $dataTable->filter( |
| 'Piwik\Plugins\Insights\DataTable\Filter\ExcludeLowValue', |
| array( |
| 'difference', |
| $minChangeMovers, |
| 'isMover', |
| ) |
| ); |
| } |
|
|
| if ($minDecreaseDisappeared) { |
| $dataTable->filter( |
| 'Piwik\Plugins\Insights\DataTable\Filter\ExcludeLowValue', |
| array( |
| 'difference', |
| $minDecreaseDisappeared, |
| 'isDisappeared', |
| ) |
| ); |
| } |
|
|
| $dataTable->filter( |
| 'Piwik\Plugins\Insights\DataTable\Filter\OrderBy', |
| array( |
| $this->getOrderByColumn($orderBy), |
| $orderBy === self::ORDER_BY_RELATIVE ? $this->getOrderByColumn(self::ORDER_BY_ABSOLUTE) : $this->getOrderByColumn(self::ORDER_BY_RELATIVE), |
| $metric, |
| ) |
| ); |
|
|
| $dataTable->filter( |
| 'Piwik\Plugins\Insights\DataTable\Filter\Limit', |
| array( |
| 'growth_percent_numeric', |
| $limitIncreaser, |
| $limitDecreaser, |
| ) |
| ); |
|
|
| $metricName = $metric; |
| if (!empty($reportMetadata['metrics'][$metric])) { |
| $metricName = $reportMetadata['metrics'][$metric]; |
| } |
|
|
| $dataTable->setMetadataValues(array( |
| 'reportName' => $reportMetadata['name'], |
| 'metricName' => $metricName, |
| 'date' => $date, |
| 'lastDate' => $lastDate, |
| 'period' => $period, |
| 'report' => $reportMetadata, |
| 'totalValue' => $totalValue, |
| 'orderBy' => $orderBy, |
| 'metric' => $metric, |
| 'minChangeMovers' => $minChangeMovers, |
| 'minIncreaseNew' => $minIncreaseNew, |
| 'minDecreaseDisappeared' => $minDecreaseDisappeared, |
| 'minGrowthPercentPositive' => $minGrowthPercentPositive, |
| 'minGrowthPercentNegative' => $minGrowthPercentNegative, |
| 'minMoversPercent' => $minMoversPercent, |
| 'minNewPercent' => $minNewPercent, |
| 'minDisappearedPercent' => $minDisappearedPercent, |
| )); |
|
|
| return $dataTable; |
| } |
|
|
| private function getOrderByColumn($orderBy) |
| { |
| if (self::ORDER_BY_RELATIVE == $orderBy) { |
| $orderByColumn = 'growth_percent_numeric'; |
| } elseif (self::ORDER_BY_ABSOLUTE == $orderBy) { |
| $orderByColumn = 'difference'; |
| } elseif (self::ORDER_BY_IMPORTANCE == $orderBy) { |
| $orderByColumn = 'importance'; |
| } else { |
| throw new \Exception('Unsupported orderBy'); |
| } |
|
|
| return $orderByColumn; |
| } |
|
|
| private function getMinVisits($totalValue, $percent) |
| { |
| if ($percent <= 0) { |
| return 0; |
| } |
|
|
| $minVisits = ceil(($totalValue / 100) * $percent); |
|
|
| return (int) $minVisits; |
| } |
|
|
| private function addMoversAndShakersMetadata(DataTable $dataTable, $totalValue, $lastTotalValue) |
| { |
| $totalEvolution = $this->getTotalEvolution($totalValue, $lastTotalValue); |
|
|
| $dataTable->setMetadata('lastTotalValue', $lastTotalValue); |
| $dataTable->setMetadata('evolutionTotal', $totalEvolution); |
| $dataTable->setMetadata('evolutionDifference', $totalValue - $lastTotalValue); |
| } |
|
|
| private function getTotalEvolution($totalValue, $lastTotalValue) |
| { |
| return Piwik::getPercentageSafe($totalValue - $lastTotalValue, $lastTotalValue, 1); |
| } |
| } |
|
|