From 727da1b3cbb5a7e95be430a6cce22e9b34ce5453 Mon Sep 17 00:00:00 2001 From: Thomas Steur Date: Mon, 3 Mar 2014 06:06:29 +0100 Subject: [PATCH] refs #57 some bugfixes and started to work on insights widget --- plugins/Insights/API.php | 230 +++++++++++------- plugins/Insights/Controller.php | 3 +- plugins/Insights/DataTable/Filter/Average.php | 36 +++ plugins/Insights/DataTable/Filter/Insight.php | 2 +- plugins/Insights/Visualizations/Insight.php | 1 - .../Visualizations/Insight/Config.php | 1 - .../Visualizations/Insight/RequestConfig.php | 2 - .../Insights/javascripts/insightsDataTable.js | 8 - plugins/Insights/tests/ApiTest.php | 8 - 9 files changed, 187 insertions(+), 104 deletions(-) create mode 100644 plugins/Insights/DataTable/Filter/Average.php diff --git a/plugins/Insights/API.php b/plugins/Insights/API.php index e69f494f0d4..85cf2ce0602 100644 --- a/plugins/Insights/API.php +++ b/plugins/Insights/API.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\Insights; use Piwik\DataTable; +use Piwik\Date; use Piwik\Period\Range; use Piwik\Piwik; use Piwik\Plugins\API\ProcessedReport; @@ -33,15 +34,14 @@ public function getInsightsOverview($idSite, $period, $date) { /** @var DataTable[] $tables */ $tables = array( - $this->getInsights($idSite, $period, $date, 'Actions_getPageUrls', 4, 4), - $this->getInsights($idSite, $period, $date, 'Actions_getPageTitles', 4, 4), - $this->getInsights($idSite, $period, $date, 'Referrers_getKeywords', 4, 4), - $this->getInsights($idSite, $period, $date, 'Referrers_getCampaigns', 4, 4), - $this->getInsights($idSite, $period, $date, 'Referrers_getAll', 4, 4), + $this->getInsightOverview($idSite, $period, $date, 'Actions_getPageUrls'), + $this->getInsightOverview($idSite, $period, $date, 'Actions_getPageTitles'), + $this->getInsightOverview($idSite, $period, $date, 'Referrers_getKeywords'), + $this->getInsightOverview($idSite, $period, $date, 'Referrers_getCampaigns'), + $this->getInsightOverview($idSite, $period, $date, 'Referrers_getAll'), ); // post event to add other reports? - // display new and disappeared only if very high impact $map = new DataTable\Map(); @@ -52,25 +52,67 @@ public function getInsightsOverview($idSite, $period, $date) return $map; } + protected function getInsightOverview($idSite, $period, $date, $reportUniqueId, $segment = false) + { + Piwik::checkUserHasViewAccess(array($idSite)); + + $minVisitsPercent = 2; + $metric = 'nb_visits'; + $limitIncreaser = 4; + $limitDecreaser = 4; + $minGrowthPercent = 20; + $orderBy = 'absolute'; + $considerMovers = true; + $considerNew = true; + $considerDisappeared = false; + // TODO consider disappeared if impact > 10%? + + $report = $this->getReportByUniqueId($idSite, $reportUniqueId); + + $currentReport = $this->requestReport($idSite, $period, $date, $report, $metric, $segment); + + if ($period == 'day') { + // if website is too young, than use website creation date + // for faster performance just compare against last week? + $pastDate = Date::factory($date); + $pastDate = $pastDate->subDay(7); + $lastReport = $this->requestReport($idSite, 'week', $pastDate->toString(), $report, $metric, $segment); + $lastReport->filter('Piwik\Plugins\Insights\DataTable\Filter\Average', array($metric, 7)); + } else { + $pastDate = Range::getLastDate($date, $period); + $pastDate = $pastDate[0]; + if (empty($pastDate)) { + return new DataTable(); + } + + $lastReport = $this->requestReport($idSite, $period, $pastDate, $report, $metric, $segment); + } + + $totalValue = $this->getTotalValue($idSite, $period, $date, $metric); + $minVisits = $this->getMinVisits($totalValue, $minVisitsPercent); + + $lastDate = $pastDate; + + return $this->buildInsightsReport($period, $date, $limitIncreaser, $limitDecreaser, $minGrowthPercent, $orderBy, $currentReport, $lastReport, $metric, $considerMovers, $considerNew, $considerDisappeared, $minVisits, $report, $lastDate, $totalValue); + } + // force $limitX and ignore minVisitsPercent, minGrowthPercent public function getInsights( $idSite, $period, $date, $reportUniqueId, $limitIncreaser = 5, $limitDecreaser = 5, - $filterBy = '', $basedOnTotalMetric = false, $minVisitsPercent = 2, $minGrowthPercent = 20, + $filterBy = '', $minVisitsPercent = 2, $minGrowthPercent = 20, $comparedToXPeriods = 1, $orderBy = 'absolute', $segment = false) { Piwik::checkUserHasViewAccess(array($idSite)); $metric = 'nb_visits'; - - $processedReport = new ProcessedReport(); - $report = $processedReport->getReportMetadataByUniqueId($idSite, $reportUniqueId); + $report = $this->getReportByUniqueId($idSite, $reportUniqueId); $lastDate = Range::getDateXPeriodsAgo(abs($comparedToXPeriods), $date, $period); $currentReport = $this->requestReport($idSite, $period, $date, $report, $metric, $segment); $lastReport = $this->requestReport($idSite, $period, $lastDate[0], $report, $metric, $segment); - $totalValue = $this->getTotalValue($idSite, $period, $date, $basedOnTotalMetric, $currentReport, $metric); + $totalValue = $this->getRelevantTotalValue($idSite, $period, $date, $currentReport, $metric); $minVisits = $this->getMinVisits($totalValue, $minVisitsPercent); $considerMovers = false; @@ -93,6 +135,92 @@ public function getInsights( $considerDisappeared = true; } + return $this->buildInsightsReport($period, $date, $limitIncreaser, $limitDecreaser, $minGrowthPercent, $orderBy, $currentReport, $lastReport, $metric, $considerMovers, $considerNew, $considerDisappeared, $minVisits, $report, $lastDate[0], $totalValue); + } + + private function requestReport($idSite, $period, $date, $report, $metric, $segment) + { + $params = array( + 'method' => $report['module'] . '.' . $report['action'], + 'format' => 'original', + 'idSite' => $idSite, + 'period' => $period, + 'date' => $date, + 'flat' => 1, + 'filter_limit' => 10000, + 'showColumns' => $metric + ); + + if (!empty($segment)) { + $params['segment'] = $segment; + } + + if (!empty($report['parameters']) && is_array($report['parameters'])) { + $params = array_merge($params, $report['parameters']); + } + + $request = new ApiRequest($params); + $table = $request->process(); + + return $table; + } + + 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, $minVisitsPercent) + { + $minVisits = ceil(($totalValue / 100) * $minVisitsPercent); + + return (int) $minVisits; + } + + private function getRelevantTotalValue($idSite, $period, $date, DataTable $currentReport, $metric) + { + $totalMetric = $this->getMetricTotalValue($currentReport, $metric); + $totalValue = $this->getTotalValue($idSite, $period, $date, $metric); + + if (($totalMetric * 2) < $totalValue) { + return $totalMetric; + } + + return $totalValue; + } + + private function getTotalValue($idSite, $period, $date, $metric) + { + $visits = VisitsSummaryAPI::getInstance()->get($idSite, $period, $date, false, array($metric)); + $totalValue = $visits->getFirstRow()->getColumn($metric); + return $totalValue; + } + + private function getMetricTotalValue(DataTable $currentReport, $metric) + { + $totals = $currentReport->getMetadata('totals'); + + if (!empty($totals[$metric])) { + $totalValue = (int) $totals[$metric]; + } else { + $totalValue = 0; + } + + return $totalValue; + } + + private function buildInsightsReport($period, $date, $limitIncreaser, $limitDecreaser, $minGrowthPercent, $orderBy, $currentReport, $lastReport, $metric, $considerMovers, $considerNew, $considerDisappeared, $minVisits, $report, $lastDate, $totalValue) + { $dataTable = new DataTable(); $dataTable->filter( 'Piwik\Plugins\Insights\DataTable\Filter\Insight', @@ -141,83 +269,21 @@ public function getInsights( $dataTable->setMetadataValues(array( 'reportName' => $report['name'], 'metricName' => $report['metrics'][$metric], - 'date' => $date, - 'lastDate' => $lastDate[0], - 'period' => $period, - 'report' => $report, + 'date' => $date, + 'lastDate' => $lastDate, + 'period' => $period, + 'report' => $report, 'totalValue' => $totalValue, - 'minVisits' => $minVisits + 'minVisits' => $minVisits )); return $dataTable; } - private function requestReport($idSite, $period, $date, $report, $metric, $segment) - { - $params = array( - 'method' => $report['module'] . '.' . $report['action'], - 'format' => 'original', - 'idSite' => $idSite, - 'period' => $period, - 'date' => $date, - 'flat' => 1, - 'filter_limit' => 10000, - 'showColumns' => $metric - ); - - if (!empty($segment)) { - $params['segment'] = $segment; - } - - if (!empty($report['parameters']) && is_array($report['parameters'])) { - $params = array_merge($params, $report['parameters']); - } - - $request = new ApiRequest($params); - $table = $request->process(); - - return $table; - } - - private function getMinVisits($totalValue, $minVisitsPercent) - { - $minVisits = ceil(($totalValue / 100) * $minVisitsPercent); - - return (int) $minVisits; - } - - private function getTotalValue($idSite, $period, $date, $basedOnTotalMetric, DataTable $currentReport, $metric) - { - if ($basedOnTotalMetric) { - $totals = $currentReport->getMetadata('totals'); - - if (!empty($totals[$metric])) { - $totalValue = $totals[$metric]; - } else { - $totalValue = 0; - } - - return (int) $totalValue; - } - - $visits = VisitsSummaryAPI::getInstance()->get($idSite, $period, $date, false, array($metric)); - $totalValue = $visits->getFirstRow()->getColumn($metric); - - return $totalValue; - } - - private function getOrderByColumn($orderBy) + private function getReportByUniqueId($idSite, $reportUniqueId) { - 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; + $processedReport = new ProcessedReport(); + $report = $processedReport->getReportMetadataByUniqueId($idSite, $reportUniqueId); + return $report; } } diff --git a/plugins/Insights/Controller.php b/plugins/Insights/Controller.php index eede85ea356..7f0c58f8c3e 100644 --- a/plugins/Insights/Controller.php +++ b/plugins/Insights/Controller.php @@ -31,7 +31,8 @@ public function getInsightOverview() $view->showInsightsControls = false; $view->properties = array( 'show_increase' => true, - 'show_decrease' => true + 'show_decrease' => true, + 'order_by' => 'absolute' ); return $view->render(); diff --git a/plugins/Insights/DataTable/Filter/Average.php b/plugins/Insights/DataTable/Filter/Average.php new file mode 100644 index 00000000000..69138e294d3 --- /dev/null +++ b/plugins/Insights/DataTable/Filter/Average.php @@ -0,0 +1,36 @@ +columnToRead = $columnToRead; + $this->divisor = $divisor; + } + + public function filter($table) + { + if (!$this->divisor) { + return; + } + + foreach ($table->getRows() as $key => $row) { + + $value = $row->getColumn($this->columnToRead); + + $row->setColumn($this->columnToRead, round($value / $this->divisor)); + } + } +} \ No newline at end of file diff --git a/plugins/Insights/DataTable/Filter/Insight.php b/plugins/Insights/DataTable/Filter/Insight.php index 5736d3ea6fe..a72a9e2f4e7 100644 --- a/plugins/Insights/DataTable/Filter/Insight.php +++ b/plugins/Insights/DataTable/Filter/Insight.php @@ -85,7 +85,7 @@ private function addRow(DataTable $table, DataTable\Row $row, $growthPercentage, $columns = $row->getColumns(); $columns['growth_percent'] = $growthPercentage; $columns['growth_percent_numeric'] = str_replace('%', '', $growthPercentage); - $columns['grown'] = $newValue >= $oldValue; + $columns['grown'] = '-' != substr($growthPercentage, 0 , 1); $columns['value_old'] = $oldValue; $columns['value_new'] = $newValue; $columns['difference'] = $difference; diff --git a/plugins/Insights/Visualizations/Insight.php b/plugins/Insights/Visualizations/Insight.php index eaa89954912..f16c913b0fb 100644 --- a/plugins/Insights/Visualizations/Insight.php +++ b/plugins/Insights/Visualizations/Insight.php @@ -55,7 +55,6 @@ public function beforeLoadDataTable() 'reportUniqueId' => $report, 'minVisitsPercent' => $this->requestConfig->min_visits_percent, 'minGrowthPercent' => $this->requestConfig->min_growth_percent, - 'basedOnTotalMetric' => $this->requestConfig->based_on_total_metric, 'comparedToXPeriods' => $this->requestConfig->compared_to_x_periods_ago, 'orderBy' => $this->requestConfig->order_by, 'filterBy' => $this->requestConfig->filter_by, diff --git a/plugins/Insights/Visualizations/Insight/Config.php b/plugins/Insights/Visualizations/Insight/Config.php index 15c5f1cd2e3..327572aaf45 100644 --- a/plugins/Insights/Visualizations/Insight/Config.php +++ b/plugins/Insights/Visualizations/Insight/Config.php @@ -13,6 +13,5 @@ class Config extends VisualizationConfig { - public $show_based_on_total_metric = true; public $show_filter_by = true; } diff --git a/plugins/Insights/Visualizations/Insight/RequestConfig.php b/plugins/Insights/Visualizations/Insight/RequestConfig.php index 7cd4e21bf0e..93f52a96870 100644 --- a/plugins/Insights/Visualizations/Insight/RequestConfig.php +++ b/plugins/Insights/Visualizations/Insight/RequestConfig.php @@ -15,7 +15,6 @@ class RequestConfig extends VisualizationRequestConfig { public $min_visits_percent = 2; public $min_growth_percent = 20; - public $based_on_total_metric = 1; public $compared_to_x_periods_ago = 1; public $order_by = 'absolute'; public $filter_by = ''; @@ -30,7 +29,6 @@ public function __construct() $properties = array( 'min_growth_percent', 'min_visits_percent', - 'based_on_total_metric', 'order_by', 'compared_to_x_periods_ago', 'filter_by', diff --git a/plugins/Insights/javascripts/insightsDataTable.js b/plugins/Insights/javascripts/insightsDataTable.js index 3e39b669ef4..c031ade4b74 100644 --- a/plugins/Insights/javascripts/insightsDataTable.js +++ b/plugins/Insights/javascripts/insightsDataTable.js @@ -36,7 +36,6 @@ _init: function (domElem) { this.initMinGrowthPercentage(domElem); this.initMinVisitsPercent(domElem); - this.initBasedOnTotalMetric(domElem); this.initShowIncreaseOrDecrease(domElem); this.initOrderBy(domElem); this.initComparedToXPeriodsAgo(domElem); @@ -98,13 +97,6 @@ }); }, - initBasedOnTotalMetric: function (domElem) { - var self = this; - $('[name=basedOnTotalMetric]', domElem).bind('change', function (event) { - self._changeParameterAndReload({based_on_total_metric: getValueFromEvent(event)}); - }); - }, - initComparedToXPeriodsAgo: function (domElem) { var self = this; $('[name=comparedToXPeriodsAgo]', domElem).bind('change', function (event) { diff --git a/plugins/Insights/tests/ApiTest.php b/plugins/Insights/tests/ApiTest.php index 52dc3377919..e73623fb800 100644 --- a/plugins/Insights/tests/ApiTest.php +++ b/plugins/Insights/tests/ApiTest.php @@ -89,14 +89,6 @@ public function test_getInsights_ShouldGoBackInPastDependingOnPeriod() $this->assertEquals('2010-11-14', $metadata['lastDate']); } - public function test_getInsights_ShouldBeAbleToUseTheTotalMetricValueInsteadOfTotalVisits() - { - $insights = $this->requestInsights(array('basedOnTotalMetric' => 1)); - $metadata = $insights->getAllTableMetadata(); - - $this->assertEquals(50, $metadata['totalValue']); - } - public function test_getInsights_ShouldReturnAllRowsIfMinValuesArelow() { $insights = $this->requestInsights(array('minVisitsPercent' => 0, 'minGrowthPercent' => 1));