Skip to content

Commit

Permalink
refs #57 started to work on displaying Insights. Added a widget for t…
Browse files Browse the repository at this point in the history
…he dashboard and a new Insights visualization. More to come... still early version so expect a lot of things to change but I am still happy about feedback
  • Loading branch information
tsteur committed Feb 28, 2014
1 parent db6199d commit 3055a65
Show file tree
Hide file tree
Showing 23 changed files with 1,063 additions and 9 deletions.
6 changes: 3 additions & 3 deletions core/DataTable/Filter/CalculateEvolutionFilter.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,12 +34,12 @@ class CalculateEvolutionFilter extends ColumnCallbackAddColumnPercentage
*
* @var DataTable
*/
private $pastDataTable;
protected $pastDataTable;

/**
* Tells if column being added is the revenue evolution column.
*/
private $isRevenueEvolution = null;
protected $isRevenueEvolution = null;

/**
* Constructor.
Expand Down Expand Up @@ -130,7 +130,7 @@ protected function formatValue($value, $divisor)
* @param Row $row The row in the 'current' DataTable.
* @return bool|Row
*/
private function getPastRowFromCurrent($row)
protected function getPastRowFromCurrent($row)
{
return $this->pastDataTable->getRowFromLabel($row->getColumn('label'));
}
Expand Down
30 changes: 26 additions & 4 deletions core/Period/Range.php
Original file line number Diff line number Diff line change
Expand Up @@ -365,6 +365,24 @@ protected function fillArraySubPeriods($startDate, $endDate, $period)
* @api
*/
public static function getLastDate($date = false, $period = false)
{
return self::getDateXPeriodsAgo(1, $date, $period);
}

/**
* Returns the date that is X periods before the supplied date.
*
* @param bool|string $date The date to get the last date of.
* @param bool|string $period The period to use (either 'day', 'week', 'month', 'year');
* @param int $subXPeriods How many periods in the past the date should be, for instance 1 or 7.
* If sub period is 365 days and the current year is a leap year we assume you want to get the
* day one year ago and change the value to 366 days therefore.
*
* @return array An array with two elements, a string for the date before $date and
* a Period instance for the period before $date.
* @api
*/
public static function getDateXPeriodsAgo($subXPeriods, $date = false, $period = false)
{
if ($date === false) {
$date = Common::getRequestVar('date');
Expand All @@ -374,20 +392,24 @@ public static function getLastDate($date = false, $period = false)
$period = Common::getRequestVar('period');
}

if (365 == $subXPeriods && 'day' == $period && Date::today()->isLeapYear()) {
$subXPeriods = 366;
}

// can't get the last date for range periods & dates that use lastN/previousN
$strLastDate = false;
$lastPeriod = false;
$lastPeriod = false;
if ($period != 'range' && !preg_match('/(last|previous)([0-9]*)/', $date, $regs)) {
if (strpos($date, ',')) // date in the form of 2011-01-01,2011-02-02
{
$rangePeriod = new Range($period, $date);

$lastStartDate = $rangePeriod->getDateStart()->addPeriod(-1, $period);
$lastEndDate = $rangePeriod->getDateEnd()->addPeriod(-1, $period);
$lastStartDate = $rangePeriod->getDateStart()->subPeriod($subXPeriods, $period);
$lastEndDate = $rangePeriod->getDateEnd()->subPeriod($subXPeriods, $period);

$strLastDate = "$lastStartDate,$lastEndDate";
} else {
$lastPeriod = Date::factory($date)->addPeriod(-1, $period);
$lastPeriod = Date::factory($date)->subPeriod($subXPeriods, $period);
$strLastDate = $lastPeriod->toString();
}
}
Expand Down
2 changes: 1 addition & 1 deletion core/Plugin/Visualization.php
Original file line number Diff line number Diff line change
Expand Up @@ -255,7 +255,7 @@ public function assignTemplateVar($vars, $value = null)
*/
protected function isThereDataToDisplay()
{
return true;
return !empty($this->dataTable) && 0 < $this->dataTable->getRowsCount();
}

/**
Expand Down
5 changes: 5 additions & 0 deletions plugins/CoreHome/javascripts/dataTable.js
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,10 @@ DataTable.getDataTableByReport = function (report) {

$.extend(DataTable.prototype, UIControl.prototype, {

_init: function (domElem) {
// initialize your dataTable in your plugin
},

//initialisation function
init: function () {
var domElem = this.$element;
Expand All @@ -91,6 +95,7 @@ $.extend(DataTable.prototype, UIControl.prototype, {
this.loadedSubDataTable = {};
this.isEmpty = $('.pk-emptyDataTable', domElem).length > 0;
this.bindEventsAndApplyStyle(domElem);
this._init(domElem);
this.initialized = true;
},

Expand Down
2 changes: 1 addition & 1 deletion plugins/CoreHome/templates/_dataTable.twig
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
{% if error is defined %}
{{ error.message }}
{% else %}
{% if dataTable is empty or dataTable.getRowsCount() == 0 or dataTableHasNoData|default(false) %}
{% if dataTable is empty or dataTableHasNoData|default(false) %}
<div class="pk-emptyDataTable">
{% if showReportDataWasPurgedMessage is defined and showReportDataWasPurgedMessage %}
{{ 'CoreHome_DataForThisReportHasBeenPurged'|translate(deleteReportsOlderThan) }}
Expand Down
212 changes: 212 additions & 0 deletions plugins/Insights/API.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,212 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Insights;

use Piwik\DataTable;
use Piwik\Period\Range;
use Piwik\Plugins\API\ProcessedReport;
use Piwik\API\Request as ApiRequest;
use Piwik\Plugins\VisitsSummary\API as VisitsSummaryAPI;

/**
* API for plugin Insights
*
* @method static \Piwik\Plugins\Insights\API getInstance()
*/
class API extends \Piwik\Plugin\API
{

public function getOverallMoversAndShakers($idSite, $period, $date)
{
/** @var DataTable[] $tables */
$tables = array(
$this->getMoversAndShakers($idSite, $period, $date, 'Actions_getPageUrls', 4, 4),
$this->getMoversAndShakers($idSite, $period, $date, 'Actions_getPageTitles', 4, 4),
$this->getMoversAndShakers($idSite, $period, $date, 'Referrers_getKeywords', 4, 4),
$this->getMoversAndShakers($idSite, $period, $date, 'Referrers_getCampaigns', 4, 4),
$this->getMoversAndShakers($idSite, $period, $date, 'Referrers_getAll', 4, 4),
$this->getMoversAndShakers($idSite, $period, $date, 'MultiSites_getAll', 4, 4),
);

$map = new DataTable\Map();

foreach ($tables as $table) {
$map->addTable($table, $table->getMetadata('reportName'));
}

return $map;
}

// force $limitX and ignore minVisitsPercent, minGrowthPercent
// segment
public function getMoversAndShakers(
$idSite, $period, $date, $reportUniqueId = '', $limitIncreaser = 5, $limitDecreaser = 5, $basedOnTotalMetric = false,
$minVisitsPercent = 2, $minGrowthPercent = 20, $orderBy = 'absolute',
$comparedToXPeriods = 1, $filterBy = '')
{
$metric = 'nb_visits';

$processedReport = new ProcessedReport();
$report = $processedReport->getReportMetadataByUniqueId($idSite, $reportUniqueId);

$lastDate = Range::getDateXPeriodsAgo(abs($comparedToXPeriods), $date, $period);

$currentReport = $this->requestReport($idSite, $period, $date, $report, $metric);
$lastReport = $this->requestReport($idSite, $period, $lastDate[0], $report, $metric);

$totalValue = $this->getTotalValue($idSite, $period, $date, $basedOnTotalMetric, $currentReport, $metric);
$minVisits = $this->getMinVisits($totalValue, $minVisitsPercent);

$considerMovers = false;
$considerNew = false;
$considerDisappeared = false;

switch ($filterBy) {
case '':
$considerMovers = true;
$considerNew = true;
$considerDisappeared = true;
break;
case 'movers':
$considerMovers = true;
break;
case 'new':
$considerNew = true;
break;
case 'disappeared':
$considerDisappeared = true;
break;
}

$dataTable = new DataTable();
$dataTable->filter(
'Piwik\Plugins\Insights\DataTable\Filter\Insight',
array(
$currentReport,
$lastReport,
$metric,
$totalValue,
$filterBy,
$considerMovers,
$considerNew,
$considerDisappeared
)
);

$dataTable->filter(
'Piwik\Plugins\Insights\DataTable\Filter\MinGrowth',
array(
'growth_percent_numeric',
$minGrowthPercent
)
);

$dataTable->filter(
'Piwik\Plugins\Insights\DataTable\Filter\RemoveIrrelevant',
array(
$metric,
$minVisits
)
);

$dataTable->filter(
'Piwik\Plugins\Insights\DataTable\Filter\OrderBy',
array(
$this->getOrderByColumn($orderBy)
)
);

$dataTable->filter(
'Piwik\Plugins\Insights\DataTable\Filter\Limit',
array(
'growth_percent_numeric',
$limitIncreaser,
$limitDecreaser
)
);

$dataTable->setMetadataValues(array(
'reportName' => $report['name'],
'metricName' => $report['metrics'][$metric],
'date' => $date,
'lastDate' => $lastDate[0],
'period' => $period,
'report' => $report,
'totalValue' => $totalValue,
'minVisits' => $minVisits
));

return $dataTable;
}

private function requestReport($idSite, $period, $date, $report, $metric)
{
$params = array(
'method' => $report['module'] . '.' . $report['action'],
'format' => 'original',
'idSite' => $idSite,
'period' => $period,
'date' => $date,
'flat' => 1,
'filter_limit' => 10000,
'showColumns' => $metric
);

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 = (int) ceil(($totalValue / 100) * $minVisitsPercent);

return $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 $totalValue;
}

$visits = VisitsSummaryAPI::getInstance()->get($idSite, $period, $date, false, array($metric));
$totalValue = $visits->getFirstRow()->getColumn($metric);

return $totalValue;
}

private function getOrderByColumn($orderBy)
{
if ('relative' == $orderBy) {
$orderByColumn = 'growth_percent_numeric';
} elseif ('absolute' == $orderBy) {
$orderByColumn = 'difference';
} elseif ('importance' == $orderBy) {
$orderByColumn = 'importance';
} else {
throw new \Exception('Unsupported orderBy');
}

return $orderByColumn;
}
}
39 changes: 39 additions & 0 deletions plugins/Insights/Controller.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\Insights;

use Piwik\Common;
use Piwik\View;

/**
*
*/
class Controller extends \Piwik\Plugin\Controller
{

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

$view = new View('@Insights/index.twig');
$this->setBasicVariablesView($view);

$view->moversAndShakers = API::getInstance()->getOverallMoversAndShakers($idSite, $period, $date);
$view->showNoDataMessage = false;
$view->showInsightsControls = false;
$view->properties = array(
'show_increase' => true,
'show_decrease' => true
);

return $view->render();
}
}
Loading

0 comments on commit 3055a65

Please sign in to comment.