Skip to content
Extraits de code Groupes Projets
RowEvolution.php 8,28 ko
Newer Older
  • Learn to ignore specific revisions
  • <?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
    
     * The class handles the popover that shows the evolution of a singe row in a data table
    
     * @package Piwik_CoreHome
     */
    
    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;
    	
    
    mattpiwik's avatar
    mattpiwik a validé
    	/** The request segment */
    	protected $segment;
    	
    
    	/** 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;
    	
    
    	/** Whether or not to show all metrics in the evolution graph when to popover opens */
    
    	protected $initiallyShowAllMetrics = false;
    
    	/**
    	 * 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');
    
    		$this->label = Piwik_Common::unsanitizeInputValue($this->label);
    
    mattpiwik's avatar
    mattpiwik a validé
    		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
    
    			$end = $date->toString();
    
    mattpiwik's avatar
    mattpiwik a validé
    			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;
    		}
    
    mattpiwik's avatar
    mattpiwik a validé
    		$this->segment = Piwik_Common::getRequestVar('segment', '', 'string');
    
    	 * @param Piwik_CoreHome_Controller
    
    	 * @param Piwik_View (the popover_rowevolution template)
    
    	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');
    
    		if ($this->rowLabel)
    		{
    			$icon = $this->rowIcon ? '<img src="'.$this->rowIcon.'" alt="">' : '';
    
    			$rowLabel = str_replace('/', '<wbr>/', str_replace('&', '<wbr>&', $this->rowLabel));
    
    			$metricsText = sprintf(Piwik_Translate('RowEvolution_MetricsFor'), $this->dimension.': '.$icon.' '.$rowLabel);
    
    		$view->availableMetricsText = $metricsText;
    		$view->popoverTitle = $popoverTitle;
    
    		
    		return $view->render();
    	}
    	
    
    	protected function loadEvolutionReport($column = false)
    
    	{
    		list($apiModule, $apiAction) = explode('.', $this->apiMethod);
    		
    		$parameters = array(
    			'method' => 'API.getRowEvolution',
    			'label' => $this->label,
    			'apiModule' => $apiModule,
    			'apiAction' => $apiAction,
    			'idSite' => $this->idSite,
    			'period' => $this->period,
    			'date' => $this->date,
    			'format' => 'original',
    			'serialize' => '0'
    		);
    
    mattpiwik's avatar
    mattpiwik a validé
    		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)
    	{
    
    BeezyT's avatar
    BeezyT a validé
    		$this->dataTable = $report['reportData'];
    
    		$this->rowLabel = Piwik_Common::sanitizeInputValue($report['label']);
    
    		$this->rowIcon = $report['logo'];
    		$this->availableMetrics = $report['metadata']['metrics'];
    		$this->dimension = $report['metadata']['dimension'];
    	}
    	
    
    	 * 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()
    
    	{
    		// 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)
    
    BeezyT's avatar
    BeezyT a validé
    			$max = isset($metricData['max']) ? $metricData['max'] : 0;
    			$min = isset($metricData['min']) ? $metricData['min'] : 0;
    			$change = isset($metricData['change']) ? $metricData['change'] : false;
    
    BeezyT's avatar
    BeezyT a validé
    			if ($min == $max)
    
    BeezyT's avatar
    BeezyT a validé
    				$details = false;
    
    BeezyT's avatar
    BeezyT a validé
    				$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
    					{
    						$changeClass = 'neutral';
    						$changeImage = false;
    					}
    					
    					$change = '<span class="'.$changeClass.'">'
    						.($changeImage ? '<img src="plugins/MultiSites/images/'.$changeImage.'.png" /> ' : '')
    						.$change.'</span>';
    					
    					$details .= ', '.Piwik_Translate('RowEvolution_MetricChangeText', $change);
    				}
    
    			}
    			
    			$color = $colors[ $i % count($colors) ];
    			
    			$metrics[] = array(
    
    				'label' => $metricData['name'],
    
    				'color' => $color,
    				'details' => $details,
    				'sparkline' => $this->getSparkline($metric, $controller) 
    			);
    			
    			$i++;
    		}
    
    		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.'" />';
    	}
    	
    }