Skip to content

Commit

Permalink
refs #57 some code improvements and tests, also some adjustments for …
Browse files Browse the repository at this point in the history
…sites having not many visits
  • Loading branch information
tsteur committed Mar 7, 2014
1 parent 68d0bdb commit 4165176
Show file tree
Hide file tree
Showing 18 changed files with 298 additions and 97 deletions.
27 changes: 18 additions & 9 deletions plugins/Insights/API.php
Original file line number Diff line number Diff line change
Expand Up @@ -56,8 +56,10 @@ protected function __construct()
$this->model = new Model();
}

public function canGenerateInsights($period, $date)
public function canGenerateInsights($date, $period)
{
Piwik::checkUserHasSomeViewAccess();

try {
$model = new Model();
$lastDate = $model->getLastDate($date, $period, 1);
Expand All @@ -74,12 +76,12 @@ public function canGenerateInsights($period, $date)

public function getInsightsOverview($idSite, $period, $date, $segment = false)
{
Piwik::checkUserHasViewAccess(array($idSite));
Piwik::checkUserHasViewAccess($idSite);

$defaultParams = array(
'limitIncreaser' => 3,
'limitDecreaser' => 3,
'minImpactPercent' => 2,
'minImpactPercent' => 1,
'minGrowthPercent' => 25,
);

Expand All @@ -90,7 +92,7 @@ public function getInsightsOverview($idSite, $period, $date, $segment = false)

public function getMoversAndShakersOverview($idSite, $period, $date, $segment = false)
{
Piwik::checkUserHasViewAccess(array($idSite));
Piwik::checkUserHasViewAccess($idSite);

$defaultParams = array(
'limitIncreaser' => 4,
Expand Down Expand Up @@ -164,16 +166,20 @@ public function getInsights(

$reportMetadata = $this->model->getReportByUniqueId($idSite, $reportUniqueId);

$totalValue = $this->model->getTotalValue($idSite, $period, $date, $metric);
$currentReport = $this->model->requestReport($idSite, $period, $date, $reportUniqueId, $metric, $segment);
$totalValue = $this->model->getRelevantTotalValue($currentReport, $idSite, $period, $date, $metric);

$lastDate = $this->model->getLastDate($date, $period, $comparedToXPeriods);
$lastTotalValue = $this->model->getTotalValue($idSite, $period, $lastDate, $metric);
$lastReport = $this->model->requestReport($idSite, $period, $lastDate, $reportUniqueId, $metric, $segment);

$minGrowthPercentPositive = abs($minGrowthPercent);
$minGrowthPercentNegative = -1 * $minGrowthPercentPositive;
$minMoversPercent = -1;
$minNewPercent = -1;

$relevantTotal = $this->model->getRelevantTotalValue($currentReport, $metric, $totalValue);

$minMoversPercent = -1;
$minNewPercent = -1;
$minDisappearedPercent = -1;

switch ($filterBy) {
Expand All @@ -193,7 +199,10 @@ public function getInsights(
}

$insight = new InsightReport();
return $insight->generateInsight($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $minMoversPercent, $minNewPercent, $minDisappearedPercent, $minGrowthPercentPositive, $minGrowthPercentNegative, $orderBy, $limitIncreaser, $limitDecreaser);
$table = $insight->generateInsight($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $relevantTotal, $minMoversPercent, $minNewPercent, $minDisappearedPercent, $minGrowthPercentPositive, $minGrowthPercentNegative, $orderBy, $limitIncreaser, $limitDecreaser);
$insight->markMoversAndShakers($table, $currentReport, $lastReport, $totalValue, $lastTotalValue);

return $table;
}

private function requestApiMethod($method, $idSite, $period, $date, $reportId, $segment, $additionalParams)
Expand All @@ -207,7 +216,7 @@ private function requestApiMethod($method, $idSite, $period, $date, $reportId, $
'reportUniqueId' => $reportId,
);

if ($segment) {
if (!empty($segment)) {
$params['segment'] = $segment;
}

Expand Down
47 changes: 35 additions & 12 deletions plugins/Insights/Controller.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,29 +19,32 @@
class Controller extends \Piwik\Plugin\Controller
{

public function __construct()
{
$idSite = Common::getRequestVar('idSite', null, 'int');

Piwik::checkUserHasViewAccess($idSite);
}

public function getInsightsOverview()
{
$view = $this->prepareWidget('insightsOverviewWidget.twig', $apiReport = 'getInsightsOverview');
$view = $this->prepareWidgetView('insightsOverviewWidget.twig');
$view->reports = $this->requestApiReport('getInsightsOverview');

return $view->render();
}

public function getOverallMoversAndShakers()
{
$view = $this->prepareWidget('moversAndShakersOverviewWidget.twig', $apiReport = 'getMoversAndShakersOverview');
$view = $this->prepareWidgetView('moversAndShakersOverviewWidget.twig');
$view->reports = $this->requestApiReport('getMoversAndShakersOverview');

return $view->render();
}

private function prepareWidget($template, $apiReport)
private function prepareWidgetView($template)
{
$idSite = Common::getRequestVar('idSite', null, 'int');
$period = Common::getRequestVar('period', null, 'string');
$date = Common::getRequestVar('date', null, 'string');

Piwik::checkUserHasViewAccess(array($idSite));

if (!API::getInstance()->canGenerateInsights($period, $date)) {
if (!$this->canGenerateInsights()) {

$view = new View('@Insights/cannotDisplayReport.twig');
$this->setBasicVariablesView($view);
Expand All @@ -51,11 +54,31 @@ private function prepareWidget($template, $apiReport)
$view = new View('@Insights/' . $template);
$this->setBasicVariablesView($view);

$view->reports = API::getInstance()->$apiReport($idSite, $period, $date);
$view->properties = array(
'order_by' => 'absolute'
'order_by' => InsightReport::ORDER_BY_ABSOLUTE
);

return $view;
}

private function requestApiReport($apiReport)
{
if (!$this->canGenerateInsights()) {
return;
}

$idSite = Common::getRequestVar('idSite', null, 'int');
$period = Common::getRequestVar('period', null, 'string');
$date = Common::getRequestVar('date', null, 'string');

return API::getInstance()->$apiReport($idSite, $period, $date);
}

private function canGenerateInsights()
{
$period = Common::getRequestVar('period', null, 'string');
$date = Common::getRequestVar('date', null, 'string');

return API::getInstance()->canGenerateInsights($date, $period);
}
}
54 changes: 48 additions & 6 deletions plugins/Insights/InsightReport.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,7 @@
use Piwik\Piwik;

/**
* API for plugin Insights
*
* @method static \Piwik\Plugins\Insights\API getInstance()
* Insight report generator
*/
class InsightReport
{
Expand All @@ -41,13 +39,13 @@ public function generateMoverAndShaker($reportMetadata, $period, $date, $lastDat
{
$totalEvolution = Piwik::getPercentageSafe($totalValue - $lastTotalValue, $lastTotalValue, 1);

$minMoversPercent = 0.5;
$minMoversPercent = 1;

if ($totalEvolution >= 100) {
// eg change from 50 to 150 = 200%
// $evolutionReverse = Piwik::getPercentageSafe($totalValue > $lastTotal ? $lastTotal : $totalValue, $totalValue > $lastTotal ? $totalValue : $lastTotal, 1);

$minGrowthPercentPositive = $totalEvolution + 40; // min +240%
$factor = (int) ceil($totalEvolution / 500);
$minGrowthPercentPositive = $totalEvolution + ($factor * 40); // min +240%
$minGrowthPercentNegative = -70; // min -70%
$minDisappearedPercent = 8; // min 12
$minNewPercent = min(($totalEvolution / 100) * 3, 10); // min 6% = min 10 of total visits up to max 10%
Expand All @@ -66,6 +64,13 @@ public function generateMoverAndShaker($reportMetadata, $period, $date, $lastDat
$minNewPercent = 5;
}

if ($totalValue < 100) {
// force at least a change of 2 visits
$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);

$dataTable->setMetadata('lastTotalValue', $lastTotalValue);
Expand All @@ -75,6 +80,41 @@ public function generateMoverAndShaker($reportMetadata, $period, $date, $lastDat
return $dataTable;
}

/**
* Extends an already generated insight report by adding a column "isMoverAndShaker" whether a row is also a
* "Mover and Shaker" or not.
*
* Avoids the need to fetch all reports again when we already have the currentReport/lastReport
*/
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);
}
}
}

/**
* @param array $reportMetadata
* @param string $period
Expand Down Expand Up @@ -186,6 +226,8 @@ public function generateInsight($reportMetadata, $period, $date, $lastDate, $met
'period' => $period,
'report' => $reportMetadata,
'totalValue' => $totalValue,
'orderBy' => $orderBy,
'metric' => $metric,
'minChangeMovers' => $minChangeMovers,
'minIncreaseNew' => $minIncreaseNew,
'minDecreaseDisappeared' => $minDecreaseDisappeared,
Expand Down
13 changes: 8 additions & 5 deletions plugins/Insights/Model.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,7 @@
namespace Piwik\Plugins\Insights;

use Piwik\DataTable;
use Piwik\Date;
use Piwik\Log;
use Piwik\Period\Range;
use Piwik\Piwik;
use Piwik\Plugins\API\ProcessedReport;
use Piwik\API\Request as ApiRequest;
use Piwik\Plugins\VisitsSummary\API as VisitsSummaryAPI;
Expand Down Expand Up @@ -64,10 +61,16 @@ public function getLastDate($date, $period, $comparedToXPeriods)
return $pastDate[0];
}

public function getRelevantTotalValue(DataTable $currentReport, $idSite, $period, $date, $metric)
/**
* Returns either the $totalValue (eg 5500 visits) or the total value of the report
* (eg 2500 visits of 5500 total visits as for instance only 2500 visits came to the website using a search engine).
*
* If the metric total (2500) is much lower than $totalValue, the metric total will be returned, otherwise the
* $totalValue
*/
public function getRelevantTotalValue(DataTable $currentReport, $metric, $totalValue)
{
$totalMetric = $this->getMetricTotalValue($currentReport, $metric);
$totalValue = $this->getTotalValue($idSite, $period, $date, $metric);

if ($totalMetric > $totalValue) {
return $totalMetric;
Expand Down
65 changes: 30 additions & 35 deletions plugins/Insights/Visualizations/Insight.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,39 +35,49 @@ public function beforeLoadDataTable()
return;
}

$report = $this->requestConfig->apiMethodToRequestDataTable;
$report = str_replace('.', '_', $report);

if (!$this->requestConfig->filter_limit) {
$this->requestConfig->filter_limit = 10;
}

$limit = $this->requestConfig->filter_limit;
$limitDecrease = 0;
$limitIncrease = 0;

if ($this->requestConfig->limit_increaser && !$this->requestConfig->limit_decreaser) {
$limitIncrease = $limit;
} elseif (!$this->requestConfig->limit_increaser && $this->requestConfig->limit_decreaser) {
$limitDecrease = $limit;
} elseif ($this->requestConfig->limit_increaser && $this->requestConfig->limit_decreaser) {
$limitIncrease = round($limit / 2);
$limitDecrease = $limit - $limitIncrease;
}
$report = $this->requestConfig->apiMethodToRequestDataTable;
$report = str_replace('.', '_', $report);

$this->requestConfig->apiMethodToRequestDataTable = 'Insights.getInsights';

$this->requestConfig->request_parameters_to_modify = array(
'reportUniqueId' => $report,
'minImpactPercent' => $this->requestConfig->min_impact_percent,
'minGrowthPercent' => $this->requestConfig->min_growth_percent,
'comparedToXPeriods' => $this->requestConfig->compared_to_x_periods_ago,
'orderBy' => $this->requestConfig->order_by,
'orderBy' => $this->requestConfig->order_by,
'filterBy' => $this->requestConfig->filter_by,
'limitIncreaser' => $limitIncrease,
'limitDecreaser' => $limitDecrease,
'limitIncreaser' => $this->getLimitIncrease(),
'limitDecreaser' => $this->getLimitDecrease(),
);
}

private function getLimitIncrease()
{
$filterLimit = $this->requestConfig->filter_limit;
$limitIncrease = 0;

if ($this->requestConfig->limit_increaser && !$this->requestConfig->limit_decreaser) {
$limitIncrease = $filterLimit;
} elseif ($this->requestConfig->limit_increaser && $this->requestConfig->limit_decreaser) {
$limitIncrease = round($filterLimit / 2);
}

return $limitIncrease;
}

private function getLimitDecrease()
{
$filterLimit = $this->requestConfig->filter_limit;
$limitDecrease = $filterLimit - $this->getLimitIncrease();

return abs($limitDecrease);
}

public static function getDefaultRequestConfig()
{
return new Insight\RequestConfig();
Expand All @@ -91,31 +101,16 @@ public function beforeRender()
return;
}

$period = Common::getRequestVar('period', null, 'string');
$date = Common::getRequestVar('date', null, 'string');
$idSite = Common::getRequestVar('idSite', null, 'string');
$segment = Common::getRequestVar('segment', false, 'string');

$period = Common::getRequestVar('period', null, 'string');
$this->assignTemplateVar('period', $period);

$reportId = $this->requestConfig->request_parameters_to_modify['reportUniqueId'];
$comparedToXPeriods = $this->requestConfig->compared_to_x_periods_ago;
$limitIncreaser = min($this->requestConfig->request_parameters_to_modify['limitIncreaser'], 2);
$limitDecreaser = min($this->requestConfig->request_parameters_to_modify['limitDecreaser'], 2);

$shaker = API::getInstance()->getMoversAndShakers(
$idSite, $period, $date, $reportId, $segment, $comparedToXPeriods, $limitIncreaser, $limitDecreaser
);

$this->assignTemplateVar('shaker', $shaker);
}

public static function canDisplayViewDataTable(ViewDataTable $view)
{
$period = Common::getRequestVar('period', null, 'string');
$date = Common::getRequestVar('date', null, 'string');

$canGenerateInsights = API::getInstance()->canGenerateInsights($period, $date);
$canGenerateInsights = API::getInstance()->canGenerateInsights($date, $period);

if (!$canGenerateInsights) {
return false;
Expand Down
Loading

0 comments on commit 4165176

Please sign in to comment.