diff options
author | mattab <matthieu.aubry@gmail.com> | 2013-07-20 08:53:58 +0400 |
---|---|---|
committer | mattab <matthieu.aubry@gmail.com> | 2013-07-20 08:53:58 +0400 |
commit | e79675330823b957fe9f8ffa462ad5317c14dbc9 (patch) | |
tree | 1cf0daee93c739911552b54c7dbbd14e194a8217 /core | |
parent | 6e38973acc12e9f7fa2d02edee3f8bbbfdbb9694 (diff) | |
parent | 0713062313967d940b8f5c34cb21d515c6b016b4 (diff) |
Merge remote-tracking branch 'origin/master' into php-5.3-namespaces
Conflicts:
core/AssetManager.php
core/JqplotDataGenerator/Evolution.php
core/ViewDataTable/GenerateGraphData.php
Diffstat (limited to 'core')
-rw-r--r-- | core/AssetManager.php | 115 | ||||
-rw-r--r-- | core/Controller.php | 21 | ||||
-rw-r--r-- | core/DataTable/Filter/AddSummaryRow.php | 7 | ||||
-rw-r--r-- | core/JqplotDataGenerator.php | 194 | ||||
-rw-r--r-- | core/JqplotDataGenerator/Evolution.php (renamed from core/ViewDataTable/GenerateGraphData/ChartEvolution.php) | 171 | ||||
-rw-r--r-- | core/ViewDataTable.php | 22 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphData.php | 287 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphData/ChartPie.php | 44 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php | 41 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphHTML.php | 208 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php | 50 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphHTML/ChartPie.php | 11 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php | 10 | ||||
-rw-r--r-- | core/testMinimumPhpVersion.php | 8 |
14 files changed, 530 insertions, 659 deletions
diff --git a/core/AssetManager.php b/core/AssetManager.php index 322ab4ab20..5d03dee430 100644 --- a/core/AssetManager.php +++ b/core/AssetManager.php @@ -65,7 +65,7 @@ class Piwik_AssetManager */ public static function getJsAssets() { - if (self::getDisableMergedAssets()) { + if (self::isMergedAssetsDisabled()) { // Individual includes mode self::removeMergedAsset(self::MERGED_JS_FILE); return self::getIndividualJsIncludes(); @@ -91,54 +91,110 @@ class Piwik_AssetManager * * @throws Exception if a file can not be opened in write mode */ - private static function generateMergedCssFile() + private static function prepareMergedCssFile() { - $mergedContent = ""; + $mergedCssAlreadyGenerated = self::isGenerated(self::MERGED_CSS_FILE); + $isDevelopingPiwik = self::isMergedAssetsDisabled(); - // absolute path to doc root - $rootDirectory = realpath(PIWIK_DOCUMENT_ROOT); - if ($rootDirectory != '/' && substr_compare($rootDirectory, '/', -1)) { - $rootDirectory .= '/'; + if ($mergedCssAlreadyGenerated + && !$isDevelopingPiwik + ) { + return; } - $rootDirectoryLen = strlen($rootDirectory); - if(!class_exists("lessc")) { - throw new Exception("Less was added to composer during 2.0. ==> Execute this command to update composer packages: \$ php composer.phar update"); - } - $less = new lessc; + $less = self::makeLess(); // Loop through each css file $files = self::getCssFiles(); + $mergedContent = ""; foreach ($files as $file) { self::validateCssFile($file); $fileLocation = self::getAbsoluteLocation($file); $less->addImportDir(dirname($fileLocation)); + $content = file_get_contents($fileLocation); - // Rewrite css url directives - // - assumes these are all relative paths - // - rewrite windows directory separator \\ to / - $baseDirectory = dirname($file); - $content = preg_replace_callback( - "/(url\(['\"]?)([^'\")]*)/", - create_function( - '$matches', - "return \$matches[1] . str_replace('\\\\', '/', substr(realpath(PIWIK_DOCUMENT_ROOT . '/$baseDirectory/' . \$matches[2]), $rootDirectoryLen));" - ), - $content - ); + $content = self::rewriteCssPathsDirectives($file, $content); + $mergedContent = $mergedContent . $content; } + $fileHash = md5($mergedContent); + $firstLineCompileHash = "/* compile_me_once=$fileHash */"; + + // Disable Merged Assets ==> Check on each request if file needs re-compiling + if ($mergedCssAlreadyGenerated + && $isDevelopingPiwik + ) { + $pathMerged = self::getAbsoluteMergedFileLocation(self::MERGED_CSS_FILE); + $f = fopen($pathMerged, 'r'); + $firstLine = fgets($f); + fclose($f); + if (!empty($firstLine) + && trim($firstLine) == trim($firstLineCompileHash)) { + return; + } + // Some CSS file in the merge, has changed since last merged asset was generated + // Note: we do not detect changes in @import'ed LESS files + } + $mergedContent = $less->compile($mergedContent); Piwik_PostEvent('AssetManager.filterMergedCss', array(&$mergedContent)); + $mergedContent = + $firstLineCompileHash . "\n" + . "/* Piwik CSS file is compiled with Less. You may be interested in writing a custom Theme for Piwik! */\n" + . $mergedContent; + self::writeAssetToFile($mergedContent, self::MERGED_CSS_FILE); } + protected static function makeLess() + { + if (!class_exists("lessc")) { + throw new Exception("Less was added to composer during 2.0. ==> Execute this command to update composer packages: \$ php composer.phar update"); + } + $less = new lessc; + return $less; + } + + /* + * Rewrite css url directives + * - assumes these are all relative paths + * - rewrite windows directory separator \\ to / + */ + protected static function rewriteCssPathsDirectives($relativePath, $content) + { + static $rootDirectoryLength = null; + if (is_null($rootDirectoryLength)) { + $rootDirectoryLength = self::countDirectoriesInPathToRoot(); + } + + $baseDirectory = dirname($relativePath); + $content = preg_replace_callback( + "/(url\(['\"]?)([^'\")]*)/", + create_function( + '$matches', + "return \$matches[1] . str_replace('\\\\', '/', substr(realpath(PIWIK_DOCUMENT_ROOT . '/$baseDirectory/' . \$matches[2]), $rootDirectoryLength));" + ), + $content + ); + return $content; + } + + protected static function countDirectoriesInPathToRoot() + { + $rootDirectory = realpath(PIWIK_DOCUMENT_ROOT); + if ($rootDirectory != '/' && substr_compare($rootDirectory, '/', -1)) { + $rootDirectory .= '/'; + } + $rootDirectoryLen = strlen($rootDirectory); + return $rootDirectoryLen; + } + private static function writeAssetToFile($mergedContent, $name) { // Remove the previous file @@ -323,9 +379,9 @@ class Piwik_AssetManager * * @return string */ - private static function getDisableMergedAssets() + private static function isMergedAssetsDisabled() { - return Config::getInstance()->Debug['disable_merged_assets']; + return Piwik_Config::getInstance()->Debug['disable_merged_assets']; } /** @@ -336,12 +392,7 @@ class Piwik_AssetManager */ public static function getMergedCssFileLocation() { - $isGenerated = self::isGenerated(self::MERGED_CSS_FILE); - - if (!$isGenerated) { - self::generateMergedCssFile(); - } - + self::prepareMergedCssFile(); return self::getAbsoluteMergedFileLocation(self::MERGED_CSS_FILE); } diff --git a/core/Controller.php b/core/Controller.php index 999e7488b3..84fe4734a9 100644 --- a/core/Controller.php +++ b/core/Controller.php @@ -604,29 +604,10 @@ abstract class Piwik_Controller $columns = array($firstColumn); } // displayed columns - if ($labelDisplayed - && !($view instanceof Piwik_ViewDataTable_GenerateGraphData) - ) { + if ($labelDisplayed) { array_unshift($columns, 'label'); } $view->setColumnsToDisplay($columns); - - - // Continue only for graphs - if (!($view instanceof Piwik_ViewDataTable_GenerateGraphData)) { - return; - } - // do not sort if sorted column was initially "label" or eg. it would make "Visits by Server time" not pretty - if ($view->getSortedColumn() != 'label') { - $view->setSortedColumn($firstColumn); - } - // selectable columns - if (isset($view->period) && $view->period == 'day') { - $selectableColumns = array_merge($metricsForDay, $metricsForAllPeriods); - } else { - $selectableColumns = $metricsForAllPeriods; - } - $view->setSelectableColumns($selectableColumns); } /** diff --git a/core/DataTable/Filter/AddSummaryRow.php b/core/DataTable/Filter/AddSummaryRow.php index 61958e6286..ca0cb1882f 100644 --- a/core/DataTable/Filter/AddSummaryRow.php +++ b/core/DataTable/Filter/AddSummaryRow.php @@ -56,12 +56,13 @@ class Piwik_DataTable_Filter_AddSummaryRow extends Piwik_DataTable_Filter */ public function filter($table) { - if ($table->getRowsCount() <= $this->startRowToSummarize + 1) { - return; - } $table->filter('Sort', array($this->columnToSortByBeforeTruncating, 'desc')); + if ($table->getRowsCount() <= $this->startRowToSummarize + 1) { + return; + } + $rows = $table->getRows(); $count = $table->getRowsCount(); $newRow = new Piwik_DataTable_Row(); diff --git a/core/JqplotDataGenerator.php b/core/JqplotDataGenerator.php new file mode 100644 index 0000000000..c6e9845e8b --- /dev/null +++ b/core/JqplotDataGenerator.php @@ -0,0 +1,194 @@ +<?php +/** + * Piwik - Open source web analytics + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + * + * @category Piwik + * @package Piwik + */ + +/** + * Generates JSON data used to configure and populate JQPlot graphs. + * + * Supports pie graphs, bar graphs and time serieses (aka, evolution graphs). + */ +class Piwik_JqplotDataGenerator +{ + /** + * View properties. @see Piwik_ViewDataTable for more info. + * + * @var array + */ + protected $properties; + + /** + * This object does most of the work in generating the JQPlot JSON data. + * + * @var Piwik_Visualization + */ + protected $visualization; + + /** + * Creates a new JqplotDataGenerator instance for a graph type and view properties. + * + * @param string $type 'pie', 'bar', or 'evolution' + * @param array $properties The view properties. + * @return Piwik_JqplotDataGenerator + */ + public static function factory($type, $properties) + { + switch ($type) { + case 'evolution': + return new Piwik_JqplotDataGenerator_Evolution($properties); + case 'pie': + $visualization = new Piwik_Visualization_Chart_Pie(); + return new Piwik_JqplotDataGenerator($visualization, $properties); + case 'bar': + $visualization = new Piwik_Visualization_Chart_VerticalBar(); + return new Piwik_JqplotDataGenerator($visualization, $properties); + default: + throw new Exception("Unknown JqplotDataGenerator type '$type'."); + } + } + + /** + * Constructor. + * + * @param Piwik_Visualization $visualization + * @param array $properties + */ + public function __construct($visualization, $properties) + { + $this->visualization = $visualization; + $this->properties = $properties; + } + + /** + * Generates JSON graph data and returns it. + * + * @param Piwik_DataTable|Piwik_DataTable_Array $dataTable + * @return string + */ + public function generate($dataTable) + { + if (!empty($this->properties['graph_limit'])) { + $offsetStartSummary = $this->properties['graph_limit'] - 1; + $sortColumn = !empty($this->properties['filter_sort_column']) + ? $this->properties['filter_sort_column'] + : Piwik_Metrics::INDEX_NB_VISITS; + + $dataTable->filter( + 'AddSummaryRow', array($offsetStartSummary, Piwik_Translate('General_Others'), $sortColumn)); + } + + if ($dataTable->getRowsCount() > 0) { + // if addTotalRow was called in GenerateGraphHTML, add a row containing totals of + // different metrics + if (!empty($this->properties['add_total_row'])) { + $dataTable->queueFilter('AddSummaryRow', array(0, Piwik_Translate('General_Total'), null, false)); + } + + $this->initChartObjectData($dataTable); + } + + $this->visualization->customizeChartProperties(); + + return $this->visualization->render(); + } + + protected function initChartObjectData($dataTable) + { + $dataTable->applyQueuedFilters(); + + // We apply a filter to the DataTable, decoding the label column (useful for keywords for example) + $dataTable->filter('ColumnCallbackReplace', array('label', 'urldecode')); + + $xLabels = $dataTable->getColumn('label'); + + $columnNames = $this->properties['columns_to_display']; + if (($labelColumnIndex = array_search('label', $columnNames)) !== false) { + unset($columnNames[$labelColumnIndex]); + } + + $columnNameToTranslation = $columnNameToValue = array(); + foreach ($columnNames as $columnName) { + $columnNameToTranslation[$columnName] = @$this->properties['translations'][$columnName]; + + $columnNameToValue[$columnName] = $dataTable->getColumn($columnName); + } + + $visualization = $this->visualization; + $visualization->setAxisXLabels($xLabels); + $visualization->setAxisYValues($columnNameToValue); + $visualization->setAxisYLabels($columnNameToTranslation); + $visualization->setAxisYUnit($this->properties['y_axis_unit']); + $visualization->setDisplayPercentageInTooltip($this->properties['display_percentage_in_tooltip']); + + // show_all_ticks is not real query param, it is set by GenerateGraphHTML. + if ($this->properties['show_all_ticks']) { + $visualization->showAllTicks(); + } + + $units = $this->getUnitsForColumnsToDisplay(); + $visualization->setAxisYUnits($units); + + $this->addSeriesPickerToView(); + } + + protected function getUnitsForColumnsToDisplay() + { + // derive units from column names + $units = $this->deriveUnitsFromRequestedColumnNames(); + if (!empty($this->properties['y_axis_unit'])) { + // force unit to the value set via $this->setAxisYUnit() + foreach ($units as &$unit) { + $unit = $this->properties['y_axis_unit']; + } + } + + // the bar charts contain the labels a first series + // this series has to be removed from the units + if ($this->visualization instanceof Piwik_Visualization_Chart_VerticalBar) { + array_shift($units); + } + + return $units; + } + + private function deriveUnitsFromRequestedColumnNames() + { + $idSite = Piwik_Common::getRequestVar('idSite', null, 'int'); + + $units = array(); + foreach ($this->properties['columns_to_display'] as $columnName) { + $derivedUnit = Piwik_Metrics::getUnit($columnName, $idSite); + $units[$columnName] = empty($derivedUnit) ? false : $derivedUnit; + } + return $units; + } + + /** + * Used in initChartObjectData to add the series picker config to the view object + * @param bool $multiSelect + */ + protected function addSeriesPickerToView() + { + if (count($this->properties['selectable_columns']) + && Piwik_Common::getRequestVar('showSeriesPicker', 1) == 1 + ) { + $selectableColumns = array(); + foreach ($this->properties['selectable_columns'] as $column) { + $selectableColumns[] = array( + 'column' => $column, + 'translation' => @$this->properties['translations'][$column], + 'displayed' => in_array($column, $this->properties['columns_to_display']) + ); + } + + $this->visualization->setSelectableColumns( + $selectableColumns, $this->properties['allow_multi_select_series_picker']); + } + } +} diff --git a/core/ViewDataTable/GenerateGraphData/ChartEvolution.php b/core/JqplotDataGenerator/Evolution.php index 3ce1de2d54..559ec589b5 100644 --- a/core/ViewDataTable/GenerateGraphData/ChartEvolution.php +++ b/core/JqplotDataGenerator/Evolution.php @@ -12,137 +12,53 @@ use Piwik\Piwik; use Piwik\Common; /** - * Piwik_ViewDataTable_GenerateGraphData for the Evolution graph (eg. Last 30 days visits) using Piwik_Visualization_Chart_Evolution - * - * @package Piwik - * @subpackage Piwik_ViewDataTable + * Generates JQPlot JSON data/config for evolution graphs. */ -class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDataTable_GenerateGraphData +class Piwik_JqplotDataGenerator_Evolution extends Piwik_JqplotDataGenerator { - - // used for the row picker - // (the series picker configuration resides in the parent class) - protected $rowPicker = false; - protected $visibleRows = array(); protected $rowPickerConfig = array(); - - protected function checkStandardDataTable() - { - // DataTable_Array and DataTable allowed for the evolution chart - Piwik::checkObjectTypeIs($this->dataTable, array('Piwik_DataTable_Array', 'Piwik_DataTable')); - } - - protected function getViewDataTableId() - { - return 'generateDataChartEvolution'; - } - - public function __construct() - { - parent::__construct(); - - $this->view = new Piwik_Visualization_Chart_Evolution(); - } - + /** - * Adds the same series picker as parent::setSelectableColumns but the selectable series are not - * columns of a single row but the same column across multiple rows, e.g. the number of visits - * for each referrer type. - * @param array $visibleRows the rows that are initially visible - * @param string $matchBy the way the items in $visibleRows are matched with the data. possible values: - * - label: matches the label of the row + * Constructor. */ - public function addRowPicker($visibleRows, $matchBy = 'label') - { - $this->rowPicker = $matchBy; - - if (!is_array($visibleRows)) { - $visibleRows = array($visibleRows); - } - $this->visibleRows = $visibleRows; - } - - /** - * This method is called for every row of every table in the DataTable_Array. - * It incrementally builds the row picker configuration and determines whether - * the row is initially visible or not. - * @param string $rowLabel - * @return bool - */ - protected function handleRowForRowPicker(&$rowLabel) - { - // determine whether row is visible - $isVisible = true; - switch ($this->rowPicker) { - case 'label': - $isVisible = in_array($rowLabel, $this->visibleRows); - break; - } - - // build config - if (!isset($this->rowPickerConfig[$rowLabel])) { - $this->rowPickerConfig[$rowLabel] = array( - 'label' => $rowLabel, - 'matcher' => $rowLabel, - 'displayed' => $isVisible - ); - } - - return $isVisible; - } - - protected function loadDataTableFromAPI() + public function __construct($properties) { - $period = Common::getRequestVar('period'); - // period will be overridden when 'range' is requested in the UI - // but the graph will display for each day of the range. - // Default 'range' behavior is to return the 'sum' for the range - if ($period == 'range') { - $_GET['period'] = 'day'; - } - // throws exception if no view access - parent::loadDataTableFromAPI(); - if ($period == 'range') { - $_GET['period'] = $period; - } + parent::__construct(new Piwik_Visualization_Chart_Evolution(), $properties); } - protected function initChartObjectData() + protected function initChartObjectData($dataTable) { // if the loaded datatable is a simple DataTable, it is most likely a plugin plotting some custom data // we don't expect plugin developers to return a well defined Piwik_DataTable_Array - if ($this->dataTable instanceof Piwik_DataTable) { - return parent::initChartObjectData(); + if ($dataTable instanceof Piwik_DataTable) { + return parent::initChartObjectData($dataTable); } - $this->dataTable->applyQueuedFilters(); - if (!($this->dataTable instanceof Piwik_DataTable_Array)) { - throw new Exception("Expecting a DataTable_Array with custom format to draw an evolution chart"); - } + $dataTable->applyQueuedFilters(); // the X label is extracted from the 'period' object in the table's metadata $xLabels = $uniqueIdsDataTable = array(); - foreach ($this->dataTable->getArray() as $idDataTable => $metadataDataTable) { + foreach ($dataTable->getArray() as $idDataTable => $metadataDataTable) { //eg. "Aug 2009" $xLabels[] = $metadataDataTable->getMetadata('period')->getLocalizedShortString(); // we keep track of all unique data table that we need to set a Y value for $uniqueIdsDataTable[] = $idDataTable; } - $idSite = Common::getRequestVar('idSite', null, 'int'); - $requestedColumnNames = $this->getColumnsToDisplay(); + $idSite = Piwik_Common::getRequestVar('idSite', null, 'int'); + $requestedColumnNames = $this->properties['columns_to_display']; $units = $this->getUnitsForColumnsToDisplay(); $yAxisLabelToUnit = array(); $yAxisLabelToValue = array(); - foreach ($this->dataTable->getArray() as $idDataTable => $dataTable) { - foreach ($dataTable->getRows() as $row) { + foreach ($dataTable->getArray() as $idDataTable => $childTable) { + foreach ($childTable->getRows() as $row) { $rowLabel = $row->getColumn('label'); // put together configuration for row picker. // do this for every data table in the array because rows do not // have to present for each date. - if ($this->rowPicker !== false) { + if ($this->properties['row_picker_mach_rows_by'] !== false) { $rowVisible = $this->handleRowForRowPicker($rowLabel); if (!$rowVisible) { continue; @@ -172,23 +88,24 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat $yAxisLabelToValueCleaned[$yAxisLabel][] = $columnValue; } } + + $visualization = $this->visualization; + $visualization->setAxisXLabels($xLabels); + $visualization->setAxisYValues($yAxisLabelToValueCleaned); + $visualization->setAxisYUnits($yAxisLabelToUnit); - $this->view->setAxisXLabels($xLabels); - $this->view->setAxisYValues($yAxisLabelToValueCleaned); - $this->view->setAxisYUnits($yAxisLabelToUnit); - - $countGraphElements = $this->dataTable->getRowsCount(); - $dataTables = $this->dataTable->getArray(); + $countGraphElements = $dataTable->getRowsCount(); + $dataTables = $dataTable->getArray(); $firstDatatable = reset($dataTables); $period = $firstDatatable->getMetadata('period'); $stepSize = $this->getXAxisStepSize($period->getLabel(), $countGraphElements); - $this->view->setXSteps($stepSize); + $visualization->setXSteps($stepSize); if ($this->isLinkEnabled()) { $axisXOnClick = array(); $queryStringAsHash = $this->getQueryStringAsHash(); - foreach ($this->dataTable->getArray() as $idDataTable => $metadataDataTable) { + foreach ($dataTable->getArray() as $idDataTable => $metadataDataTable) { $period = $metadataDataTable->getMetadata('period'); $dateInUrl = $period->getDateStart(); $parameters = array( @@ -209,17 +126,45 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat . $hash; $axisXOnClick[] = $link; } - $this->view->setAxisXOnClick($axisXOnClick); + $visualization->setAxisXOnClick($axisXOnClick); } $this->addSeriesPickerToView(); - if ($this->rowPicker !== false) { - // configure the row picker - $this->view->setSelectableRows(array_values($this->rowPickerConfig)); + + // configure the row picker + if ($this->properties['row_picker_mach_rows_by'] !== false) { + $visualization->setSelectableRows(array_values($this->rowPickerConfig)); } } /** + * This method is called for every row of every table in the DataTable_Array. + * It incrementally builds the row picker configuration and determines whether + * the row is initially visible or not. + * @param string $rowLabel + * @return bool + */ + private function handleRowForRowPicker(&$rowLabel) + { + // determine whether row is visible + $isVisible = true; + if ($this->properties['row_picker_mach_rows_by'] == 'label') { + $isVisible = in_array($rowLabel, $this->properties['row_picker_visible_rows']); + } + + // build config + if (!isset($this->rowPickerConfig[$rowLabel])) { + $this->rowPickerConfig[$rowLabel] = array( + 'label' => $rowLabel, + 'matcher' => $rowLabel, + 'displayed' => $isVisible + ); + } + + return $isVisible; + } + + /** * Derive the series label from the row label and the column name. * If the row label is set, both the label and the column name are displayed. * @param string $rowLabel @@ -228,7 +173,7 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat */ private function getSeriesLabel($rowLabel, $columnName) { - $metricLabel = $this->getColumnTranslation($columnName); + $metricLabel = @$this->properties['translations'][$columnName]; if ($rowLabel !== false) { // eg. "Yahoo! (Visits)" diff --git a/core/ViewDataTable.php b/core/ViewDataTable.php index b8195c5311..f4d0cbd3d8 100644 --- a/core/ViewDataTable.php +++ b/core/ViewDataTable.php @@ -247,18 +247,6 @@ abstract class Piwik_ViewDataTable $result = new Piwik_ViewDataTable_Sparkline(); break; - case 'generateDataChartVerticalBar': - $result = new Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar(); - break; - - case 'generateDataChartPie': - $result = new Piwik_ViewDataTable_GenerateGraphData_ChartPie(); - break; - - case 'generateDataChartEvolution': - $result = new Piwik_ViewDataTable_GenerateGraphData_ChartEvolution(); - break; - case 'tableAllColumns': $result = new Piwik_ViewDataTable_HtmlTable_AllColumns(); break; @@ -590,15 +578,13 @@ abstract class Piwik_ViewDataTable $filterParameters = $filter[1]; $this->dataTable->filter($filterName, $filterParameters); } - + if (!$this->areGenericFiltersDisabled()) { // Second, generic filters (Sort, Limit, Replace Column Names, etc.) $requestArray = $this->getRequestArray(); $request = Piwik_API_Request::getRequestArrayFromString($requestArray); - if (!empty($this->viewProperties['enable_sort']) - && $this->viewProperties['enable_sort'] === 'false' - ) { + if ($this->viewProperties['enable_sort'] === false) { $request['filter_sort_column'] = $request['filter_sort_order'] = ''; } @@ -937,7 +923,7 @@ abstract class Piwik_ViewDataTable */ public function setRequestParametersToModify($params) { - $this->viewProperties['request_parameters_to_modify'] = $params; + $this->viewProperties['request_parameters_to_modify'] += $params; } /** @@ -1003,7 +989,7 @@ abstract class Piwik_ViewDataTable */ public function disableSort() { - $this->viewProperties['enable_sort'] = 'false'; + $this->viewProperties['enable_sort'] = false; } /** diff --git a/core/ViewDataTable/GenerateGraphData.php b/core/ViewDataTable/GenerateGraphData.php deleted file mode 100644 index af5f9ef132..0000000000 --- a/core/ViewDataTable/GenerateGraphData.php +++ /dev/null @@ -1,287 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - * @category Piwik - * @package Piwik - */ -use Piwik\Piwik; -use Piwik\Common; - -/** - * Reads data from the API and prepares data to give to the renderer Piwik_Visualization_Chart. - * This class is used to generate the data for the graphs. - * You can set the number of elements to appear in the graph using: setGraphLimit(); - * Example: - * <pre> - * function getWebsites( $fetch = false) - * { - * $view = Piwik_ViewDataTable::factory(); - * $view->init( $this->pluginName, 'getWebsites', 'Referers.getWebsites', 'getUrlsFromWebsiteId' ); - * $view->setColumnsToDisplay( array('label','nb_visits') ); - * $view->setLimit(10); - * $view->setGraphLimit(12); - * return $this->renderView($view, $fetch); - * } - * </pre> - * - * @package Piwik - * @subpackage Piwik_ViewDataTable - */ -abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable -{ - protected $yAxisUnit = ''; - - // used for the series picker - protected $selectableColumns = array(); - - public function __construct() - { - parent::__construct(); - $this->viewProperties['graph_limit'] = null; - - $labelIdx = array_search('label', $this->viewProperties['columns_to_display']); - unset($this->viewProperties[$labelIdx]); - } - - public function init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable = null, - $defaultProperties = array()) - { - parent::init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable, - $defaultProperties); - - $columns = Common::getRequestVar('columns', false); - if ($columns !== false) { - $columns = Piwik::getArrayFromApiParameter($columns); - } else { - $columns = $this->viewProperties['columns_to_display']; - } - - // do not sort if sorted column was initially "label" or eg. it would make "Visits by Server time" not pretty - if ($this->getSortedColumn() != 'label') { - $firstColumn = reset($columns); - if ($firstColumn == 'label') { - $firstColumn = next($columns); - } - - $this->setSortedColumn($firstColumn); - } - - // selectable columns - if ($this->getViewDataTableId() != 'generateDataChartEvolution') { - $selectableColumns = array('nb_visits', 'nb_actions'); - if (Common::getRequestVar('period', false) == 'day') { - $selectableColumns[] = 'nb_uniq_visitors'; - } - $this->setSelectableColumns($selectableColumns); - } - } - - public function setAxisYUnit($unit) - { - $this->yAxisUnit = $unit; - } - - /** - * Sets the number max of elements to display (number of pie slice, vertical bars, etc.) - * If the data has more elements than $limit then the last part of the data will be the sum of all the remaining data. - * - * @param int $limit - */ - public function setGraphLimit($limit) - { - $this->viewProperties['graph_limit'] = $limit; - } - - /** - * Returns numbers of elemnts to display in the graph - * - * @return int - */ - public function getGraphLimit() - { - return $this->viewProperties['graph_limit']; - } - - protected $displayPercentageInTooltip = true; - - /** - * The percentage in tooltips is computed based on the sum of all values for the plotted column. - * If the sum of the column in the data set is not the number of elements in the data set, - * for example when plotting visits that have a given plugin enabled: - * one visit can have several plugins, hence the sum is much greater than the number of visits. - * In this case displaying the percentage doesn't make sense. - */ - public function disallowPercentageInGraphTooltip() - { - $this->displayPercentageInTooltip = false; - } - - /** - * Sets the columns that can be added/removed by the user - * This is done on data level (not html level) because the columns might change after reloading via sparklines - * @param array $columnsNames Array of column names eg. array('nb_visits','nb_hits') - */ - public function setSelectableColumns($columnsNames) - { - // the array contains values if enableShowGoals() has been used - // add $columnsNames to the beginning of the array - $this->selectableColumns = array_merge($columnsNames, $this->selectableColumns); - } - - /** - * The implementation of this method in Piwik_ViewDataTable passes to the graph whether the - * goals icon should be displayed or not. Here, we use it to implicitly add the goal metrics - * to the metrics picker. - */ - public function enableShowGoals() - { - parent::enableShowGoals(); - - $goalMetrics = array('nb_conversions', 'revenue'); - $this->selectableColumns = array_merge($this->selectableColumns, $goalMetrics); - - $this->setColumnTranslation('nb_conversions', Piwik_Translate('Goals_ColumnConversions')); - $this->setColumnTranslation('revenue', Piwik_Translate('General_TotalRevenue')); - } - - /** - * Used in initChartObjectData to add the series picker config to the view object - * @param bool $multiSelect - */ - protected function addSeriesPickerToView($multiSelect = true) - { - if (count($this->selectableColumns) - && Common::getRequestVar('showSeriesPicker', 1) == 1 - ) { - // build the final configuration for the series picker - $columnsToDisplay = $this->getColumnsToDisplay(); - $selectableColumns = array(); - - foreach ($this->selectableColumns as $column) { - $selectableColumns[] = array( - 'column' => $column, - 'translation' => $this->getColumnTranslation($column), - 'displayed' => in_array($column, $columnsToDisplay) - ); - } - $this->view->setSelectableColumns($selectableColumns, $multiSelect); - } - } - - protected function getUnitsForColumnsToDisplay() - { - // derive units from column names - $idSite = Common::getRequestVar('idSite', null, 'int'); - $units = $this->deriveUnitsFromRequestedColumnNames($this->getColumnsToDisplay(), $idSite); - if (!empty($this->yAxisUnit)) { - // force unit to the value set via $this->setAxisYUnit() - foreach ($units as &$unit) { - $unit = $this->yAxisUnit; - } - } - - return $units; - } - - protected function deriveUnitsFromRequestedColumnNames($requestedColumnNames, $idSite) - { - $units = array(); - foreach ($requestedColumnNames as $columnName) { - $derivedUnit = Piwik_Metrics::getUnit($columnName, $idSite); - $units[$columnName] = empty($derivedUnit) ? false : $derivedUnit; - } - return $units; - } - - public function main() - { - if ($this->mainAlreadyExecuted) { - return; - } - $this->mainAlreadyExecuted = true; - - // Graphs require the full dataset, setting limit to null (same as 'no limit') - $this->setLimit(null); - - // the queued filters will be manually applied later. This is to ensure that filtering using search - // will be done on the table before the labels are enhanced (see ReplaceColumnNames) - $this->disableQueuedFilters(); - - // throws exception if no view access - $this->loadDataTableFromAPI(); - $this->checkStandardDataTable(); - $this->postDataTableLoadedFromAPI(); - - $graphLimit = $this->getGraphLimit(); - if (!empty($graphLimit)) { - $offsetStartSummary = $this->getGraphLimit() - 1; - $this->dataTable->filter('AddSummaryRow', - array($offsetStartSummary, - Piwik_Translate('General_Others'), - - // Column to sort by, before truncation - $this->dataTable->getSortedByColumnName() - ? $this->dataTable->getSortedByColumnName() - : Piwik_Metrics::INDEX_NB_VISITS - ) - ); - } - $this->isDataAvailable = $this->dataTable->getRowsCount() != 0; - - // if addTotalRow was called in GenerateGraphHTML, add a row containing totals of - // different metrics - if (Common::getRequestVar('add_total_row', 0) == 1) { - $this->dataTable->queueFilter('AddSummaryRow', array(0, Piwik_Translate('General_Total'), null, false)); - } - - if ($this->isDataAvailable) { - $this->initChartObjectData(); - } - $this->view->customizeChartProperties(); - } - - protected function initChartObjectData() - { - $this->dataTable->applyQueuedFilters(); - - // We apply a filter to the DataTable, decoding the label column (useful for keywords for example) - $this->dataTable->filter('ColumnCallbackReplace', array('label', 'urldecode')); - - $xLabels = $this->dataTable->getColumn('label'); - $columnNames = parent::getColumnsToDisplay(); - if (($labelColumnFound = array_search('label', $columnNames)) !== false) { - unset($columnNames[$labelColumnFound]); - } - - $columnNameToTranslation = $columnNameToValue = array(); - foreach ($columnNames as $columnName) { - $columnNameToTranslation[$columnName] = $this->getColumnTranslation($columnName); - $columnNameToValue[$columnName] = $this->dataTable->getColumn($columnName); - } - $this->view->setAxisXLabels($xLabels); - $this->view->setAxisYValues($columnNameToValue); - $this->view->setAxisYLabels($columnNameToTranslation); - $this->view->setAxisYUnit($this->yAxisUnit); - $this->view->setDisplayPercentageInTooltip($this->displayPercentageInTooltip); - - // show_all_ticks is not real query param, it is set by GenerateGraphHTML. - if (Common::getRequestVar('show_all_ticks', 0) == 1) { - $this->view->showAllTicks(); - } - - $units = $this->getUnitsForColumnsToDisplay(); - $this->view->setAxisYUnits($units); - - $this->addSeriesPickerToView(); - } -} diff --git a/core/ViewDataTable/GenerateGraphData/ChartPie.php b/core/ViewDataTable/GenerateGraphData/ChartPie.php deleted file mode 100644 index 5f8d61a264..0000000000 --- a/core/ViewDataTable/GenerateGraphData/ChartPie.php +++ /dev/null @@ -1,44 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - * @category Piwik - * @package Piwik - */ - -/** - * Piwik_ViewDataTable_GenerateGraphData for the pie chart, using Piwik_Visualization_Chart_Pie - * - * @package Piwik - * @subpackage Piwik_ViewDataTable - */ -class Piwik_ViewDataTable_GenerateGraphData_ChartPie extends Piwik_ViewDataTable_GenerateGraphData -{ - protected function getViewDataTableId() - { - return 'generateDataChartPie'; - } - - public function __construct() - { - parent::__construct(); - - $this->view = new Piwik_Visualization_Chart_Pie(); - $this->viewProperties['graph_limit'] = 6; - } - - /** - * Manipulate the configuration of the series picker since only one metric is selectable - * for pie charts - * @param bool $multiSelect - */ - protected function addSeriesPickerToView($multiSelect = false) - { - // force $multiSelect=false - parent::addSeriesPickerToView(false); - } - -} diff --git a/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php b/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php deleted file mode 100644 index ca9dd94bf0..0000000000 --- a/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php +++ /dev/null @@ -1,41 +0,0 @@ -<?php -/** - * Piwik - Open source web analytics - * - * @link http://piwik.org - * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later - * - * @category Piwik - * @package Piwik - */ - -/** - * Piwik_ViewDataTable_GenerateGraphData for the vertical bar graph, using Piwik_Visualization_Chart_VerticalBar - * - * @package Piwik - * @subpackage Piwik_ViewDataTable - */ -class Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar extends Piwik_ViewDataTable_GenerateGraphData -{ - protected function getViewDataTableId() - { - return 'generateDataChartVerticalBar'; - } - - public function __construct() - { - parent::__construct(); - - $this->view = new Piwik_Visualization_Chart_VerticalBar(); - $this->viewProperties['graph_limit'] = 6; - } - - protected function getUnitsForColumnsToDisplay() - { - // the bar charts contain the labels a first series - // this series has to be removed from the units - $units = parent::getUnitsForColumnsToDisplay(); - array_shift($units); - return $units; - } -} diff --git a/core/ViewDataTable/GenerateGraphHTML.php b/core/ViewDataTable/GenerateGraphHTML.php index dc7eacdc04..71a7787cb6 100644 --- a/core/ViewDataTable/GenerateGraphHTML.php +++ b/core/ViewDataTable/GenerateGraphHTML.php @@ -20,14 +20,10 @@ use Piwik\Common; */ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable { - protected $width = '100%'; protected $height = 250; - protected $graphType = 'unknown'; + protected $graphType; - /** - * Default constructor. - */ public function __construct() { parent::__construct(); @@ -37,6 +33,75 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable $this->disableExcludeLowPopulation(); $this->disableSearchBox(); $this->enableShowExportAsImageIcon(); + + $this->viewProperties['display_percentage_in_tooltip'] = true; + $this->viewProperties['y_axis_unit'] = ''; + $this->viewProperties['show_all_ticks'] = 0; + $this->viewProperties['add_total_row'] = 0; + $this->viewProperties['graph_limit'] = null; + $this->viewProperties['allow_multi_select_series_picker'] = true; + $this->viewProperties['row_picker_mach_rows_by'] = false; + $this->viewProperties['row_picker_visible_rows'] = array(); + $this->viewProperties['selectable_columns'] = array(); + } + + /** + * Default constructor. + */ + public function setAxisYUnit($unit) + { + $this->viewProperties['y_axis_unit'] = $unit; + } + + /** + * Sets the number max of elements to display (number of pie slice, vertical bars, etc.) + * If the data has more elements than $limit then the last part of the data will be the sum of all the remaining data. + * + * @param int $limit + */ + public function setGraphLimit($limit) + { + $this->viewProperties['graph_limit'] = $limit; + } + + /** + * The percentage in tooltips is computed based on the sum of all values for the plotted column. + * If the sum of the column in the data set is not the number of elements in the data set, + * for example when plotting visits that have a given plugin enabled: + * one visit can have several plugins, hence the sum is much greater than the number of visits. + * In this case displaying the percentage doesn't make sense. + */ + public function disallowPercentageInGraphTooltip() + { + $this->viewProperties['display_percentage_in_tooltip'] = false; + } + + /** + * Sets the columns that can be added/removed by the user + * This is done on data level (not html level) because the columns might change after reloading via sparklines + * @param array $columnsNames Array of column names eg. array('nb_visits','nb_hits') + */ + public function setSelectableColumns($columnsNames) + { + // the array contains values if enableShowGoals() has been used + // add $columnsNames to the beginning of the array + $this->viewProperties['selectable_columns'] = array_merge($columnsNames, $this->viewProperties['selectable_columns']); + } + + /** + * The implementation of this method in Piwik_ViewDataTable passes to the graph whether the + * goals icon should be displayed or not. Here, we use it to implicitly add the goal metrics + * to the metrics picker. + */ + public function enableShowGoals() + { + parent::enableShowGoals(); + + $goalMetrics = array('nb_conversions', 'revenue'); + $this->viewProperties['selectable_columns'] = array_merge($this->viewProperties['selectable_columns'], $goalMetrics); + + $this->setColumnTranslation('nb_conversions', Piwik_Translate('Goals_ColumnConversions')); + $this->setColumnTranslation('revenue', Piwik_Translate('General_TotalRevenue')); } public function init($currentControllerName, @@ -48,14 +113,32 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable parent::init($currentControllerName, $currentControllerAction, $apiMethodToRequestDataTable, $controllerActionCalledWhenRequestSubTable, $defaultProperties); - $this->parametersToModify = array( - 'viewDataTable' => $this->getViewDataTableIdToLoad(), - // in the case this controller is being executed by another controller - // eg. when being widgetized in an IFRAME - // we need to put in the URL of the graph data the real module and action - 'module' => $currentControllerName, - 'action' => $currentControllerAction, - ); + // in the case this controller is being executed by another controller + // eg. when being widgetized in an IFRAME + // we need to put in the URL of the graph data the real module and action + $this->viewProperties['request_parameters_to_modify']['module'] = $currentControllerName; + $this->viewProperties['request_parameters_to_modify']['action'] = $currentControllerAction; + + // do not sort if sorted column was initially "label" or eg. it would make "Visits by Server time" not pretty + if ($this->getSortedColumn() != 'label') { + $columns = $this->viewProperties['columns_to_display']; + + $firstColumn = reset($columns); + if ($firstColumn == 'label') { + $firstColumn = next($columns); + } + + $this->setSortedColumn($firstColumn); + } + + // selectable columns + if ($this->graphType != 'evolution') { + $selectableColumns = array('nb_visits', 'nb_actions'); + if (Piwik_Common::getRequestVar('period', false) == 'day') { + $selectableColumns[] = 'nb_uniq_visitors'; + } + $this->viewProperties['selectable_columns'] = $selectableColumns; + } } public function enableShowExportAsImageIcon() @@ -70,26 +153,6 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable } /** - * Sets parameters to modify in the future generated URL - * @param array $array array('nameParameter' => $newValue, ...) - */ - public function setParametersToModify($array) - { - $this->parametersToModify = array_merge($this->parametersToModify, $array); - } - - /** - * Returns the names of the view properties to send to GenerateGraphData instance. - * Properties are passed via the $_GET array. - * - * @return array - */ - public function getViewPropertiesToForward() - { - return array('show_all_ticks', 'add_total_row'); - } - - /** * Show every x-axis tick instead of just every other one. */ public function showAllTicks() @@ -107,7 +170,21 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable } /** - * We persist the parametersToModify values in the javascript footer. + * Adds the same series picker as parent::setSelectableColumns but the selectable series are not + * columns of a single row but the same column across multiple rows, e.g. the number of visits + * for each referrer type. + * @param array $visibleRows the rows that are initially visible + * @param string $matchBy the way the items in $visibleRows are matched with the data. possible values: + * - label: matches the label of the row + */ + public function addRowPicker($visibleRows, $matchBy = 'label') + { + $this->viewProperties['row_picker_mach_rows_by'] = $matchBy; + $this->viewProperties['row_picker_visible_rows'] = is_array($visibleRows) ? $visibleRows : array($visibleRows); + } + + /** + * We persist the 'request_parameters_to_modify' values in the javascript footer. * This is used by the "export links" that use the "date" attribute * from the json properties array in the datatable footer. * @return array @@ -117,7 +194,7 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable $original = parent::getJavascriptVariablesToSet(); $originalViewDataTable = $original['viewDataTable']; - $result = $this->parametersToModify + $original; + $result = $this->viewProperties['request_parameters_to_modify'] + $original; $result['viewDataTable'] = $originalViewDataTable; return $result; @@ -134,9 +211,27 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable } $this->mainAlreadyExecuted = true; + // Graphs require the full dataset, so no filters + $this->disableGenericFilters(); + + // the queued filters will be manually applied later. This is to ensure that filtering using search + // will be done on the table before the labels are enhanced (see ReplaceColumnNames) + $this->disableQueuedFilters(); + + // throws exception if no view access + $this->loadDataTableFromAPI(); + if ($this->graphType != 'evolution') { + $this->checkStandardDataTable(); + } + $this->postDataTableLoadedFromAPI(); + + // re-enable generic & queued filters so they do not appear in JS output + $this->viewProperties['disable_generic_filters'] = false; + $this->viewProperties['disable_queued_filters'] = false; + $this->view = $this->buildView(); } - + protected function buildView() { // access control @@ -147,8 +242,7 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable } // collect data - $this->parametersToModify['action'] = $this->currentControllerAction; - $this->graphData = $this->getGraphData(); + $this->graphData = $this->getGraphData($this->dataTable); // build view $view = new Piwik_View($this->dataTableTemplate); @@ -173,38 +267,12 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable return $view; } - protected function getGraphData() - { - $saveGet = $_GET; - - $params = array_merge($this->getGenerateGraphDataParams(), $this->parametersToModify); - foreach ($params as $key => $val) { - // We do not forward filter data to the graph controller. - // This would cause the graph to have filter_limit=5 set by default, - // which would break them (graphs need the full dataset to build the "Others" aggregate value) - if (strpos($key, 'filter_') !== false) { - continue; - } - if (is_array($val)) { - $val = implode(',', $val); - } - $_GET[$key] = $val; - } - $content = Piwik_FrontController::getInstance()->fetchDispatch($this->currentControllerName, $this->currentControllerAction, array()); - - $_GET = $saveGet; - - return str_replace(array("\r", "\n"), '', $content); - } - - private function getGenerateGraphDataParams() + protected function getGraphData($dataTable) { - $result = array(); - foreach ($this->getViewPropertiesToForward() as $name) { - if (isset($this->viewProperties[$name])) { - $result[$name] = $this->viewProperties[$name]; - } - } - return $result; + $properties = array_merge($this->viewProperties, $this->viewProperties['request_parameters_to_modify']); + $dataGenerator = Piwik_JqplotDataGenerator::factory($this->graphType, $properties); + + $jsonData = $dataGenerator->generate($dataTable); + return str_replace(array("\r", "\n"), '', $jsonData); } } diff --git a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php index 638937dc05..0c316f84ad 100644 --- a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php +++ b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php @@ -20,7 +20,6 @@ use Piwik\Common; class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDataTable_GenerateGraphHTML { protected $height = 170; - protected $graphType = 'evolution'; /** * The value of the date query parameter (or a default value) before it is turned @@ -30,6 +29,12 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat * @var string */ private $originalDate; + + public function __construct() + { + parent::__construct(); + $this->graphType = 'evolution'; + } protected function getViewDataTableId() { @@ -76,25 +81,6 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat } /** - * Sets the columns that will be displayed on output evolution chart - * By default all columns are displayed ($columnsNames = array() will display all columns) - * - * @param array $columnsNames Array of column names eg. array('nb_visits','nb_hits') - */ - public function setColumnsToDisplay($columnsNames) - { - if (!is_array($columnsNames)) { - if (strpos($columnsNames, ',') !== false) { - // array values are comma separated - $columnsNames = explode(',', $columnsNames); - } else { - $columnsNames = array($columnsNames); - } - } - $this->setParametersToModify(array('columns' => $columnsNames)); - } - - /** * Based on the period, date and evolution_{$period}_last_n query parameters, * calculates the date range this evolution chart will display data for. */ @@ -118,10 +104,10 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat } else // if not a multiple period { list($newDate, $lastN) = self::getDateRangeAndLastN($period, $this->originalDate, $defaultLastN); - $this->setParametersToModify(array('date' => $newDate)); + $this->viewProperties['request_parameters_to_modify']['date'] = $newDate; } $lastNParamName = self::getLastNParamName($period); - $this->setParametersToModify(array($lastNParamName => $lastN)); + $this->viewProperties['request_parameters_to_modify'][$lastNParamName] = $lastN; } } @@ -184,4 +170,24 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat { return "evolution_{$period}_last_n"; } + + protected function getRequestArray() + { + // period will be overridden when 'range' is requested in the UI // TODO: this code probably shouldn't be here... + // but the graph will display for each day of the range. + // Default 'range' behavior is to return the 'sum' for the range + if (Piwik_Common::getRequestVar('period', false) == 'range') { + $this->viewProperties['request_parameters_to_modify']['period'] = 'day'; + } + + // FIXME: This appears to be a hack used to ensure a graph is plotted even if there is no data. there's probably + // a less complicated way of doing it... (this is complicated because it modifies the request used to get + // data so a loop is entered in JqplotDataGenerator_Evolution::initChartObjectData) + if (!empty($this->viewProperties['columns_to_display'])) { + $columns = implode(',', $this->viewProperties['columns_to_display']); + $this->viewProperties['request_parameters_to_modify']['columns'] = $columns; + } + + return parent::getRequestArray(); + } } diff --git a/core/ViewDataTable/GenerateGraphHTML/ChartPie.php b/core/ViewDataTable/GenerateGraphHTML/ChartPie.php index ccc40d0c3f..35d99f2bac 100644 --- a/core/ViewDataTable/GenerateGraphHTML/ChartPie.php +++ b/core/ViewDataTable/GenerateGraphHTML/ChartPie.php @@ -18,9 +18,14 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartPie extends Piwik_ViewDataTable_GenerateGraphHTML { - - protected $graphType = 'pie'; - + public function __construct() + { + parent::__construct(); + $this->graphType = 'pie'; + $this->viewProperties['graph_limit'] = 6; + $this->viewProperties['allow_multi_select_series_picker'] = false; + } + protected function getViewDataTableId() { return 'graphPie'; diff --git a/core/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php b/core/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php index 3ee015f3e5..e8efa53230 100644 --- a/core/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php +++ b/core/ViewDataTable/GenerateGraphHTML/ChartVerticalBar.php @@ -19,9 +19,13 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartVerticalBar extends Piwik_ViewDataTable_GenerateGraphHTML { - - protected $graphType = 'bar'; - + public function __construct() + { + parent::__construct(); + $this->graphType = 'bar'; + $this->viewProperties['graph_limit'] = 6; + } + protected function getViewDataTableId() { return 'graphVerticalBar'; diff --git a/core/testMinimumPhpVersion.php b/core/testMinimumPhpVersion.php index 0f9b8b0529..e44c39ea1e 100644 --- a/core/testMinimumPhpVersion.php +++ b/core/testMinimumPhpVersion.php @@ -58,9 +58,11 @@ if ($minimumPhpInvalid) { if(!file_exists($autoloader)) { $piwik_errorMessage .= "<p>It appears the <a href='https://getcomposer.org/' target='_blank'>composer</a> tool is not yet installed. You can install Composer in a few easy steps. In the piwik directory, run in the command line the following (eg. via ssh): - <pre>curl -sS https://getcomposer.org/installer | php". - "\nphp composer.phar install</pre> </p><p>This will download and install composer, and initialize composer for Piwik (eg. download the twig library in vendor/twig). - <br/>Then reload this page to access your analytics reports.</p>"; + <pre> curl -sS https://getcomposer.org/installer | php". + "\n php composer.phar install</pre> </p><p>This will download and install composer, and initialize composer for Piwik (eg. download the twig library in vendor/twig). + <br/>Then reload this page to access your analytics reports. + <br/><br/>Note: if for some reasons you cannot execute this command, install the latest Piwik release from <a + href='http://builds.piwik.org/latest.zip'>builds.piwik.org</a>.</p>"; } } |