Newer
Older
<?php
/**
* Piwik - Open source web analytics
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
* @version $Id$
*
* @category Piwik_Plugins
* @package Piwik_CoreHome
*/
/**
* ROW EVOLUTION
BeezyT
a validé
* The class handles the popover that shows the evolution of a singe row in a data table
BeezyT
a validé
class Piwik_CoreHome_DataTableRowAction_RowEvolution
{
/** The current site id */
protected $idSite;
/** The api method to get the data. Format: Plugin.apiAction */
protected $apiMethod;
/** The label of the requested row */
protected $label;
/** The requested period */
protected $period;
/** The requested date */
protected $date;
/** The metrics that are available for the requested report and period */
protected $availableMetrics;
/** The name of the dimension of the current report */
protected $dimension;
/**
* The data
* @var Piwik_DataTable_Array
*/
protected $dataTable;
/** The label of the current record */
protected $rowLabel;
/** The icon of the current record */
protected $rowIcon;
/** The type of graph that has been requested last */
protected $graphType;
/** The metrics for the graph that has been requested last */
protected $graphMetrics;
BeezyT
a validé
/** Whether or not to show all metrics in the evolution graph when to popover opens */
/**
* The constructor
* Initialize some local variables from the request
* @param int $idSite
* @param Piwik_Date $date ($this->date from controller)
* @throws Exception
*/
public function __construct($idSite, $date)
{
$this->apiMethod = Piwik_Common::getRequestVar('apiMethod', '', 'string');
if (empty($this->apiMethod)) throw new Exception("Parameter apiMethod not set.");
$this->label = Piwik_Common::getRequestVar('label', '', 'string');
BeezyT
a validé
$this->label = Piwik_Common::unsanitizeInputValue($this->label);
if ($this->label === '') throw new Exception("Parameter label not set.");
$this->period = Piwik_Common::getRequestVar('period', '', 'string');
if (empty($this->period)) throw new Exception("Parameter period not set.");
$this->idSite = $idSite;
if ($this->period != 'range')
// handle day, week, month and year: display last X periods
if ($this->period == 'year') $start = $date->subYear(10)->toString();
else if ($this->period == 'month') $start = $date->subMonth(30)->toString();
else if ($this->period == 'week') $start = $date->subWeek(30)->toString();
else $start = $date->subDay(30)->toString();
$this->date = $start.','.$end;
}
$this->segment = Piwik_Common::getRequestVar('segment', '', 'string');
$this->loadEvolutionReport();
BeezyT
a validé
* Render the popover
BeezyT
a validé
* @param Piwik_View (the popover_rowevolution template)
BeezyT
a validé
public function renderPopover($controller, $view)
{
// render main evolution graph
$this->graphType = 'graphEvolution';
$this->graphMetrics = $this->availableMetrics;
$view->graph = $controller->getRowEvolutionGraph(true);
// render metrics overview
$view->metrics = $this->getMetricsToggles($controller);
// available metrics text
$metricsText = Piwik_Translate('RowEvolution_AvailableMetrics');
BeezyT
a validé
$popoverTitle = '';
if ($this->rowLabel)
{
$icon = $this->rowIcon ? '<img src="'.$this->rowIcon.'" alt="">' : '';
BeezyT
a validé
$rowLabel = str_replace('/', '<wbr>/', str_replace('&', '<wbr>&', $this->rowLabel));
$metricsText = sprintf(Piwik_Translate('RowEvolution_MetricsFor'), $this->dimension.': '.$icon.' '.$rowLabel);
BeezyT
a validé
$popoverTitle = $icon.' '.$rowLabel;
BeezyT
a validé
$view->availableMetricsText = $metricsText;
$view->popoverTitle = $popoverTitle;
protected function loadEvolutionReport($column = false)
{
list($apiModule, $apiAction) = explode('.', $this->apiMethod);
$parameters = array(
'method' => 'API.getRowEvolution',
mattpiwik
a validé
'label' => urlencode($this->label),
'apiModule' => $apiModule,
'apiAction' => $apiAction,
'idSite' => $this->idSite,
'period' => $this->period,
'date' => $this->date,
'format' => 'original',
'serialize' => '0'
);
if(!empty($this->segment))
{
$parameters['segment'] = $this->segment;
}
if ($column !== false)
{
$parameters['column'] = $column;
}
$url = Piwik_Url::getQueryStringFromParameters($parameters);
$request = new Piwik_API_Request($url);
$report = $request->process();
$this->extractEvolutionReport($report);
}
protected function extractEvolutionReport($report)
{
$this->rowLabel = Piwik_Common::sanitizeInputValue($report['label']);
$this->rowIcon = !empty($report['logo']) ? $report['logo'] : false;
$this->availableMetrics = $report['metadata']['metrics'];
$this->dimension = $report['metadata']['dimension'];
}
BeezyT
a validé
* Generic method to get an evolution graph or a sparkline for the row evolution popover.
* Do as much as possible from outside the controller.
* @return Piwik_ViewDataTable
*/
public function getRowEvolutionGraph()
mattpiwik
a validé
{
// Not ideal to overwrite _GET FIXME
// Useful for "Export" buttons under graphs to export the data displayed in graph
if(!empty($this->date))
{
$_GET['date'] = $this->date;
}
// set up the view data table
$view = Piwik_ViewDataTable::factory($this->graphType);
$view->setDataTable($this->dataTable);
$view->init('CoreHome', 'getRowEvolutionGraph', $this->apiMethod);
$view->setColumnsToDisplay(array_keys($this->graphMetrics));
$view->hideAllViewsIcons();
foreach ($this->availableMetrics as $metric => $metadata)
{
$view->setColumnTranslation($metric, $metadata['name']);
}
if (method_exists($view, 'addRowEvolutionSeriesToggle'))
{
$view->addRowEvolutionSeriesToggle($this->initiallyShowAllMetrics);
}
return $view;
}
/**
* Prepare metrics toggles with spark lines
* @param $controller
* @return array
*/
protected function getMetricsToggles($controller)
{
$chart = new Piwik_Visualization_Chart_Evolution;
$colors = $chart->getSeriesColors();
$i = 0;
$metrics = array();
foreach ($this->availableMetrics as $metric => $metricData)
$max = isset($metricData['max']) ? $metricData['max'] : 0;
$min = isset($metricData['min']) ? $metricData['min'] : 0;
$change = isset($metricData['change']) ? $metricData['change'] : false;
$unit = Piwik_API_API::getUnit($metric, $this->idSite);
$min .= $unit;
$max .= $unit;
$details = Piwik_Translate('RowEvolution_MetricBetweenText', array($min, $max));
if ($change !== false)
$lowerIsBetter = Piwik_API_API::isLowerValueBetter($metric);
if (substr($change, 0, 1) == '+')
{
$changeClass = $lowerIsBetter ? 'bad' : 'good';
$changeImage = $lowerIsBetter ? 'arrow_up_red' : 'arrow_up';
}
else if (substr($change, 0, 1) == '-')
{
$changeClass = $lowerIsBetter ? 'good' : 'bad';
$changeImage = $lowerIsBetter ? 'arrow_down_green' : 'arrow_down';
}
else
$change = '<span class="'.$changeClass.'">'
.($changeImage ? '<img src="plugins/MultiSites/images/'.$changeImage.'.png" /> ' : '')
.$change.'</span>';
$details .= ', '.Piwik_Translate('RowEvolution_MetricChangeText', $change);
'label' => $metricData['name'],
'color' => $color,
'details' => $details,
'sparkline' => $this->getSparkline($metric, $controller),
// Multi Rows, each metric can be for a particular row and display an icon
if(!empty($metricData['logo']))
{
$newMetric['logo'] = $metricData['logo'];
}
$metrics[] = $newMetric;
return $metrics;
}
/** Get the img tag for a sparkline showing a single metric */
protected function getSparkline($metric, $controller)
{
$this->graphType = 'sparkline';
$this->graphMetrics = array($metric => $metric);
// sparkline is always echoed, so we need to buffer the output
ob_start();
$controller->getRowEvolutionGraph();
$spark = ob_get_contents();
ob_end_clean();
// undo header change by sparkline renderer
header('Content-type: text/html');
// base64 encode the image and put it in an img tag
$spark = base64_encode($spark);
return '<img src="data:image/png;base64,'.$spark.'" />';
}
}