diff options
author | Benaka Moorthi <benaka.moorthi@gmail.com> | 2013-07-12 10:31:39 +0400 |
---|---|---|
committer | Benaka Moorthi <benaka.moorthi@gmail.com> | 2013-07-12 10:31:39 +0400 |
commit | 01057779046dd67923bd34d123628ab60ed263bc (patch) | |
tree | 94353df4f7848f2de63f3eeb0c9eeed2020965c8 /core | |
parent | 98e6c9b8874ffc8c18570ed4cc062cc5f0eb80c0 (diff) |
Refs #4040, #4041, move all ViewDataTable properties to the viewProperties array and allow these properties to be specified through new display metadata. Converted the Actions, Goals, UserSettings and VisitTime controllers.
Notes:
- Includes refactoring of ExcludeLowPopulation filter.
Diffstat (limited to 'core')
-rw-r--r-- | core/API/Request.php | 21 | ||||
-rw-r--r-- | core/DataTable/Filter/ExcludeLowPopulation.php | 40 | ||||
-rw-r--r-- | core/ViewDataTable.php | 469 | ||||
-rw-r--r-- | core/ViewDataTable/Cloud.php | 20 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphData.php | 56 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphData/ChartEvolution.php | 4 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphData/ChartPie.php | 7 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php | 7 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphHTML.php | 73 | ||||
-rw-r--r-- | core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php | 6 | ||||
-rw-r--r-- | core/ViewDataTable/HtmlTable.php | 40 |
11 files changed, 481 insertions, 262 deletions
diff --git a/core/API/Request.php b/core/API/Request.php index 838df1610a..ac066be7c2 100644 --- a/core/API/Request.php +++ b/core/API/Request.php @@ -218,5 +218,26 @@ class Piwik_API_Request $GET = Piwik_Common::getArrayFromQueryString($_SERVER['QUERY_STRING']); return $GET; } + + /** + * Returns the current URL without generic filter query parameters. + * + * @param array $params Query parameter values to override in the new URL. + * @return string + */ + public static function getCurrentUrlWithoutGenericFilters($params) + { + // unset all filter query params so the related report will show up in its default state, + // unless the filter param was in $queryParams + $genericFiltersInfo = Piwik_API_DataTableGenericFilter::getGenericFiltersInformation(); + foreach ($genericFiltersInfo as $filter) { + foreach ($filter as $queryParamName => $queryParamInfo) { + if (!isset($params[$queryParamName])) { + $params[$queryParamName] = null; + } + } + } + return Piwik_Url::getCurrentQueryStringWithParametersModified($params); + } } diff --git a/core/DataTable/Filter/ExcludeLowPopulation.php b/core/DataTable/Filter/ExcludeLowPopulation.php index c5d6369d6c..9f4d5c723c 100644 --- a/core/DataTable/Filter/ExcludeLowPopulation.php +++ b/core/DataTable/Filter/ExcludeLowPopulation.php @@ -21,22 +21,29 @@ */ class Piwik_DataTable_Filter_ExcludeLowPopulation extends Piwik_DataTable_Filter { - static public $minimumValue; const MINIMUM_SIGNIFICANT_PERCENTAGE_THRESHOLD = 0.02; + + /** + * The minimum value to enforce in a datatable for a specified column. Rows found with + * a value less than this are removed. + * + * @var number + */ + private $minimumValue; /** * Constructor * * @param Piwik_DataTable $table * @param string $columnToFilter column to filter - * @param number $minimumValue minimum value + * @param number|Closure $minimumValue minimum value * @param bool $minimumPercentageThreshold */ public function __construct($table, $columnToFilter, $minimumValue, $minimumPercentageThreshold = false) { parent::__construct($table); $this->columnToFilter = $columnToFilter; - + if ($minimumValue == 0) { if ($minimumPercentageThreshold === false) { $minimumPercentageThreshold = self::MINIMUM_SIGNIFICANT_PERCENTAGE_THRESHOLD; @@ -45,7 +52,8 @@ class Piwik_DataTable_Filter_ExcludeLowPopulation extends Piwik_DataTable_Filter $sumValues = array_sum($allValues); $minimumValue = $sumValues * $minimumPercentageThreshold; } - self::$minimumValue = $minimumValue; + + $this->minimumValue = $minimumValue; } /** @@ -53,23 +61,13 @@ class Piwik_DataTable_Filter_ExcludeLowPopulation extends Piwik_DataTable_Filter * * @param Piwik_DataTable $table */ - function filter($table) - { - $table->filter('ColumnCallbackDeleteRow', - array($this->columnToFilter, - array("Piwik_DataTable_Filter_ExcludeLowPopulation", "excludeLowPopulation") - ) - ); - } - - /** - * Checks whether the given value is below the defined minimum - * - * @param number $value value to check - * @return bool - */ - static public function excludeLowPopulation($value) + public function filter($table) { - return $value >= self::$minimumValue; + $minimumValue = $this->minimumValue; + $isValueHighPopulation = function ($value) use ($minimumValue) { + return $value >= $minimumValue; + }; + + $table->filter('ColumnCallbackDeleteRow', array($this->columnToFilter, $isValueHighPopulation)); } } diff --git a/core/ViewDataTable.php b/core/ViewDataTable.php index a60bdb2208..886082ad24 100644 --- a/core/ViewDataTable.php +++ b/core/ViewDataTable.php @@ -58,21 +58,13 @@ abstract class Piwik_ViewDataTable protected $mainAlreadyExecuted = false; /** - * Contains the values set for the parameters - * - * @see getJavascriptVariablesToSet() - * @var array - */ - protected $variablesDefault = array(); - - /** * Array of properties that are available in the view * Used to store UI properties, eg. "show_footer", "show_search", etc. * * @var array */ protected $viewProperties = array(); - + /** * If the current dataTable refers to a subDataTable (eg. keywordsBySearchEngineId for id=X) this variable is set to the Id * @@ -87,7 +79,6 @@ abstract class Piwik_ViewDataTable */ protected $dataTable = null; - /** * List of filters to apply after the data has been loaded from the API * @@ -121,12 +112,6 @@ abstract class Piwik_ViewDataTable protected $controllerActionCalledWhenRequestSubTable = null; /** - * @see init() - * @var string - */ - protected $apiMethodToRequestDataTable; - - /** * This view should be an implementation of the Interface Piwik_View_Interface * The $view object should be created in the main() method. * @@ -135,34 +120,72 @@ abstract class Piwik_ViewDataTable protected $view = null; /** - * Array of columns names translations - * - * @var array - */ - protected $columnsTranslations = array(); - - /** - * Documentation for the metrics used in the current report. - * Received from the Plugin API, used for inline help. - * - * @var array - */ - protected $metricsDocumentation = false; - - /** * Documentation for the report. * Received from the Plugin API, used for inline help. * * @var array */ protected $documentation = false; - + /** - * Array of columns set to display - * - * @var array + * Default constructor. */ - protected $columnsToDisplay = array(); + public function __construct() + { + $this->viewProperties['show_goals'] = false; + $this->viewProperties['show_ecommerce'] = false; + $this->viewProperties['show_search'] = true; + $this->viewProperties['show_table'] = true; + $this->viewProperties['show_table_all_columns'] = true; + $this->viewProperties['show_all_views_icons'] = true; + $this->viewProperties['hide_all_views_icons'] = false; + $this->viewProperties['hide_annotations_view'] = true; + $this->viewProperties['show_bar_chart'] = true; + $this->viewProperties['show_pie_chart'] = true; + $this->viewProperties['show_tag_cloud'] = true; + $this->viewProperties['show_export_as_image_icon'] = false; + $this->viewProperties['show_export_as_rss_feed'] = true; + $this->viewProperties['show_exclude_low_population'] = true; + $this->viewProperties['show_offset_information'] = true; + $this->viewProperties['show_pagination_control'] = true; + $this->viewProperties['show_limit_control'] = false; + $this->viewProperties['show_footer'] = true; + $this->viewProperties['show_related_reports'] = true; + $this->viewProperties['exportLimit'] = Piwik_Config::getInstance()->General['API_datatable_default_limit']; + $this->viewProperties['highlight_summary_row'] = false; + $this->viewProperties['metadata'] = array(); + $this->viewProperties['relatedReports'] = array(); + $this->viewProperties['title'] = 'unknown'; + $this->viewProperties['tooltip_metadata_name'] = false; + $this->viewProperties['enable_sort'] = true; + $this->viewProperties['disable_generic_filters'] = false; + $this->viewProperties['disable_queued_filters'] = false; + $this->viewProperties['keep_summary_row'] = false; + $this->viewProperties['filter_excludelowpop'] = false; + $this->viewProperties['filter_excludelowpop_value'] = false; + $this->viewProperties['filter_pattern'] = false; + $this->viewProperties['filter_column'] = false; + $this->viewProperties['filter_limit'] = false; + $this->viewProperties['filter_sort_column'] = false; + $this->viewProperties['filter_sort_order'] = false; + $this->viewProperties['custom_parameters'] = array(); + $this->viewProperties['translations'] = array_merge( + Piwik_Metrics::getDefaultMetrics(), + Piwik_Metrics::getDefaultProcessedMetrics() + ); + + $this->viewProperties['columns_to_display'][] = 'label'; + + $columns = Piwik_Common::getRequestVar('columns', false); + if ($columns !== false) { + $this->viewProperties['columns_to_display'] = array_merge( + $this->viewProperties['columns_to_display'], Piwik::getArrayFromApiParameter($columns)); + } else if (Piwik_Common::getRequestVar('period', false) == 'day') { + $this->viewProperties['columns_to_display'][] = 'nb_uniq_visitors'; + } else { + $this->viewProperties['columns_to_display'][] = 'nb_visits'; + } + } /** * Method to be implemented by the ViewDataTable_*. @@ -187,66 +210,132 @@ abstract class Piwik_ViewDataTable * If force is set to true, a ViewDataTable of the $defaultType will be returned in all cases. * * @param string $defaultType Any of these: table, cloud, graphPie, graphVerticalBar, graphEvolution, sparkline, generateDataChart* - * @param bool $force If set to true, returns a ViewDataTable of the $defaultType * @return Piwik_ViewDataTable */ - static public function factory($defaultType = null, $force = false) + static public function factory($defaultType = null, $action = false) { - if (is_null($defaultType)) { + if ($action !== false) { + $defaultProperties = self::getDefaultPropertiesForReport($action); + if (isset($defaultProperties['default_view_type'])) { + $defaultType = $defaultProperties['default_view_type']; + } + } + + if ($defaultType === null) { $defaultType = 'table'; } - if ($force === true) { - $type = $defaultType; - } else { - $type = Piwik_Common::getRequestVar('viewDataTable', $defaultType, 'string'); - } + $type = Piwik_Common::getRequestVar('viewDataTable', $defaultType, 'string'); switch ($type) { case 'cloud': - return new Piwik_ViewDataTable_Cloud(); + $result = new Piwik_ViewDataTable_Cloud(); break; case 'graphPie': - return new Piwik_ViewDataTable_GenerateGraphHTML_ChartPie(); + $result = new Piwik_ViewDataTable_GenerateGraphHTML_ChartPie(); break; case 'graphVerticalBar': - return new Piwik_ViewDataTable_GenerateGraphHTML_ChartVerticalBar(); + $result = new Piwik_ViewDataTable_GenerateGraphHTML_ChartVerticalBar(); break; case 'graphEvolution': - return new Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution(); + $result = new Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution(); break; case 'sparkline': - return new Piwik_ViewDataTable_Sparkline(); + $result = new Piwik_ViewDataTable_Sparkline(); break; case 'generateDataChartVerticalBar': - return new Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar(); + $result = new Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar(); break; case 'generateDataChartPie': - return new Piwik_ViewDataTable_GenerateGraphData_ChartPie(); + $result = new Piwik_ViewDataTable_GenerateGraphData_ChartPie(); break; case 'generateDataChartEvolution': - return new Piwik_ViewDataTable_GenerateGraphData_ChartEvolution(); + $result = new Piwik_ViewDataTable_GenerateGraphData_ChartEvolution(); break; case 'tableAllColumns': - return new Piwik_ViewDataTable_HtmlTable_AllColumns(); + $result = new Piwik_ViewDataTable_HtmlTable_AllColumns(); break; case 'tableGoals': - return new Piwik_ViewDataTable_HtmlTable_Goals(); + $result = new Piwik_ViewDataTable_HtmlTable_Goals(); break; case 'table': default: - return new Piwik_ViewDataTable_HtmlTable(); + $result = new Piwik_ViewDataTable_HtmlTable(); break; } + + if ($action !== false) { + list($plugin, $controllerAction) = explode('.', $action); + + $subtableAction = $controllerAction; + if (isset($defaultProperties['subtable_action'])) { + $subtableAction = $defaultProperties['subtable_action']; + } + + $result->init($plugin, $controllerAction, $action, $subtableAction, $defaultProperties); + } + + return $result; + } + + /** + * Returns the list of view properties that can be overridden by query parameters. + * + * @return array + */ + public function getOverridableProperties() + { + return array( + 'show_search', + 'show_table', + 'show_table_all_columns', + 'show_all_views_icons', + 'hide_all_views_icons', + 'hide_annotations_view', + 'show_barchart', + 'show_piechart', + 'show_tag_cloud', + 'show_export_as_image_icon', + 'show_export_as_rss_feed', + 'show_exclude_low_population', + 'show_offset_information', + 'show_pagination_control', + 'show_footer', + 'show_related_reports', + 'columns' + ); + } + + /** + * Returns the list of view properties that should be sent with the HTML response + * as JSON. These properties can be manipulated via the ViewDataTable UI. + * + * @return array + */ + public function getJavaScriptProperties() + { + return array( + 'enable_sort', + 'disable_generic_filters', + 'disable_queued_filters', + 'keep_summary_row', + 'filter_excludelowpop', + 'filter_excludelowpop_value', + 'filter_pattern', + 'filter_column', + 'filter_limit', + 'filter_sort_column', + 'filter_sort_order', + ); } /** @@ -270,53 +359,46 @@ abstract class Piwik_ViewDataTable public function init($currentControllerName, $currentControllerAction, $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable = null) + $controllerActionCalledWhenRequestSubTable = null, + $defaultProperties = array()) { $this->currentControllerName = $currentControllerName; $this->currentControllerAction = $currentControllerAction; - $this->apiMethodToRequestDataTable = $apiMethodToRequestDataTable; $this->controllerActionCalledWhenRequestSubTable = $controllerActionCalledWhenRequestSubTable; $this->idSubtable = Piwik_Common::getRequestVar('idSubtable', false, 'int'); - - $this->viewProperties['report_id'] = $currentControllerName . '.' . $currentControllerAction; - $this->viewProperties['show_goals'] = false; - $this->viewProperties['show_ecommerce'] = false; - $this->viewProperties['show_search'] = Piwik_Common::getRequestVar('show_search', true); - $this->viewProperties['show_table'] = Piwik_Common::getRequestVar('show_table', true); - $this->viewProperties['show_table_all_columns'] = Piwik_Common::getRequestVar('show_table_all_columns', true); - $this->viewProperties['show_all_views_icons'] = Piwik_Common::getRequestVar('show_all_views_icons', true); - $this->viewProperties['hide_all_views_icons'] = Piwik_Common::getRequestVar('hide_all_views_icons', false); - $this->viewProperties['hide_annotations_view'] = Piwik_Common::getRequestVar('hide_annotations_view', true); - $this->viewProperties['show_bar_chart'] = Piwik_Common::getRequestVar('show_barchart', true); - $this->viewProperties['show_pie_chart'] = Piwik_Common::getRequestVar('show_piechart', true); - $this->viewProperties['show_tag_cloud'] = Piwik_Common::getRequestVar('show_tag_cloud', true); - $this->viewProperties['show_export_as_image_icon'] = Piwik_Common::getRequestVar('show_export_as_image_icon', false); - $this->viewProperties['show_export_as_rss_feed'] = Piwik_Common::getRequestVar('show_export_as_rss_feed', true); - $this->viewProperties['show_exclude_low_population'] = Piwik_Common::getRequestVar('show_exclude_low_population', true); - $this->viewProperties['show_offset_information'] = Piwik_Common::getRequestVar('show_offset_information', true); - $this->viewProperties['show_pagination_control'] = Piwik_Common::getRequestVar('show_pagination_control', true); - $this->viewProperties['show_limit_control'] = false; - $this->viewProperties['show_footer'] = Piwik_Common::getRequestVar('show_footer', true); + + foreach ($defaultProperties as $name => $value) { + $this->setViewProperty($name, $value); + } + + $queryParams = Piwik_Url::getArrayFromCurrentQueryString(); + foreach ($this->getOverridableProperties() as $name) { + if (isset($queryParams[$name])) { + $this->setViewProperty($name, $queryParams[$name]); + } + } + $this->viewProperties['show_footer_icons'] = ($this->idSubtable == false); - $this->viewProperties['show_related_reports'] = Piwik_Common::getRequestVar('show_related_reports', true); - $this->viewProperties['apiMethodToRequestDataTable'] = $this->apiMethodToRequestDataTable; - $this->viewProperties['exportLimit'] = Piwik_Config::getInstance()->General['API_datatable_default_limit']; - - $this->viewProperties['highlight_summary_row'] = false; - $this->viewProperties['metadata'] = array(); - - $this->viewProperties['relatedReports'] = array(); - $this->viewProperties['title'] = 'unknown'; + $this->viewProperties['apiMethodToRequestDataTable'] = $apiMethodToRequestDataTable; + + $this->viewProperties['report_id'] = $currentControllerName . '.' . $currentControllerAction; $this->viewProperties['self_url'] = $this->getBaseReportUrl($currentControllerName, $currentControllerAction); - $this->viewProperties['tooltip_metadata_name'] = false; - - $standardColumnNameToTranslation = array_merge( - Piwik_Metrics::getDefaultMetrics(), - Piwik_Metrics::getDefaultProcessedMetrics() - ); - $this->setColumnsTranslations($standardColumnNameToTranslation); + + if (!Piwik_PluginsManager::getInstance()->isPluginActivated('Goals')) { + $this->viewProperties['show_goals'] = false; + } + + // the exclude low population threshold value is sometimes obtained by requesting data. + // to avoid issuing unecessary requests when display properties are determined by metadata, + // we allow it to be a closure. + if (isset($this->viewProperties['filter_excludelowpop_value']) + && $this->viewProperties['filter_excludelowpop_value'] instanceof Closure + ) { + $function = $this->viewProperties['filter_excludelowpop_value']; + $this->viewProperties['filter_excludelowpop_value'] = $function(); + } } - + /** * Forces the View to use a given template. * Usually the template to use is set in the specific ViewDataTable_* @@ -358,7 +440,7 @@ abstract class Piwik_ViewDataTable public function getApiMethodToRequestDataTable() { - return $this->apiMethodToRequestDataTable; + return $this->viewProperties['apiMethodToRequestDataTable']; } public function getControllerActionCalledWhenRequestSubTable() @@ -393,6 +475,56 @@ abstract class Piwik_ViewDataTable } /** + * Returns the defaut view properties for a report, if any. + * + * Plugins can associate callbacks with the ViewDataTable.getReportDisplayProperties + * event to set the default properties of reports. + * + * @return array + */ + private static function getDefaultPropertiesForReport($apiAction) + { + $properties = array(); + Piwik_PostEvent('ViewDataTable.getReportDisplayProperties', array(&$properties, $apiAction)); + + return $properties; + } + + /** + * Sets a view property by name. This function handles special view properties + * like 'translations' & 'relatedReports' that store arrays. + * + * @param string $name + * @param mixed $value For array properties, $value can be a comma separated string. + */ + private function setViewProperty($name, $value) + { + if (isset($this->viewProperties[$name]) + && is_array($this->viewProperties[$name]) + && is_string($value) + ) { + $value = Piwik::getArrayFromApiParameter($value); + } + + if ($name == 'translations') { + $this->viewProperties[$name] = array_merge($this->viewProperties[$name], $value); + } else if ($name == 'relatedReports') { + $this->addRelatedReports($reportTitle = false, $value); + } else if ($name == 'filters') { + foreach ($value as $filterInfo) { + if (!is_array($filterInfo)) { + $this->queueFilter($filterInfo); + } else { + @list($filter, $params, $isPriority) = $filterInfo; + $this->queueFilter($filter, $params, $isPriority); + } + } + } else { + $this->viewProperties[$name] = $value; + } + } + + /** * Function called by the ViewDataTable objects in order to fetch data from the API. * The function init() must have been called before, so that the object knows which API module and action to call. * It builds the API request string and uses Piwik_API_Request to call the API. @@ -462,8 +594,8 @@ abstract class Piwik_ViewDataTable $requestString = $this->getRequestString(); $request = Piwik_API_Request::getRequestArrayFromString($requestString); - if (!empty($this->variablesDefault['enable_sort']) - && $this->variablesDefault['enable_sort'] === 'false' + if (!empty($this->viewProperties['enable_sort']) + && $this->viewProperties['enable_sort'] === 'false' ) { $request['filter_sort_column'] = $request['filter_sort_order'] = ''; } @@ -497,8 +629,8 @@ abstract class Piwik_ViewDataTable } // if $this->disableGenericFilters() was called, generic filters are disabled - if (isset($this->variablesDefault['disable_generic_filters']) - && $this->variablesDefault['disable_generic_filters'] === true + if (isset($this->viewProperties['disable_generic_filters']) + && $this->viewProperties['disable_generic_filters'] === true ) { return true; } @@ -513,8 +645,8 @@ abstract class Piwik_ViewDataTable */ private function areQueuedFiltersDisabled() { - return isset($this->variablesDefault['disable_queued_filters']) - && $this->variablesDefault['disable_queued_filters']; + return isset($this->viewProperties['disable_queued_filters']) + && $this->viewProperties['disable_queued_filters']; } /** @@ -547,7 +679,7 @@ abstract class Piwik_ViewDataTable // we setup the method and format variable // - we request the method to call to get this specific DataTable // - the format = original specifies that we want to get the original DataTable structure itself, not rendered - $requestString = 'method=' . $this->apiMethodToRequestDataTable; + $requestString = 'method=' . $this->viewProperties['apiMethodToRequestDataTable']; $requestString .= '&format=original'; $requestString .= '&disable_generic_filters=' . Piwik_Common::getRequestVar('disable_generic_filters', 1, 'int'); @@ -683,9 +815,17 @@ abstract class Piwik_ViewDataTable // at this point there are some filters values we may have not set, // case of the filter without default values and parameters set directly in this class // for example setExcludeLowPopulation - // we go through all the $this->variablesDefault array and set the variables not set yet - foreach ($this->variablesDefault as $name => $value) { - if (!isset($javascriptVariablesToSet[$name])) { + // we go through all the $this->viewProperties array and set the variables not set yet + foreach ($this->getJavaScriptProperties() as $name) { + if (!isset($javascriptVariablesToSet[$name]) + && !empty($this->viewProperties[$name]) + ) { + $javascriptVariablesToSet[$name] = $this->viewProperties[$name]; + } + } + + foreach ($this->viewProperties['custom_parameters'] as $name => $value) { + if (!empty($value)) { $javascriptVariablesToSet[$name] = $value; } } @@ -741,7 +881,6 @@ abstract class Piwik_ViewDataTable $javascriptVariablesToSet['segment'] = $rawSegment; } - return $javascriptVariablesToSet; } @@ -770,10 +909,10 @@ abstract class Piwik_ViewDataTable */ protected function getDefault($nameVar) { - if (!isset($this->variablesDefault[$nameVar])) { + if (!isset($this->viewProperties[$nameVar])) { return false; } - return $this->variablesDefault[$nameVar]; + return $this->viewProperties[$nameVar]; } /** @@ -791,7 +930,7 @@ abstract class Piwik_ViewDataTable */ public function disableGenericFilters() { - $this->variablesDefault['disable_generic_filters'] = true; + $this->viewProperties['disable_generic_filters'] = true; } /** @@ -800,7 +939,7 @@ abstract class Piwik_ViewDataTable */ public function disableQueuedFilters() { - $this->variablesDefault['disable_queued_filters'] = true; + $this->viewProperties['disable_queued_filters'] = true; } /** @@ -849,7 +988,7 @@ abstract class Piwik_ViewDataTable */ public function disableSort() { - $this->variablesDefault['enable_sort'] = 'false'; + $this->viewProperties['enable_sort'] = 'false'; } /** @@ -988,7 +1127,7 @@ abstract class Piwik_ViewDataTable */ public function alwaysShowSummaryRow() { - $this->variablesDefault['keep_summary_row'] = true; + $this->viewProperties['keep_summary_row'] = true; } /** @@ -1002,8 +1141,8 @@ abstract class Piwik_ViewDataTable if (is_null($columnName)) { $columnName = 'nb_visits'; } - $this->variablesDefault['filter_excludelowpop'] = $columnName; - $this->variablesDefault['filter_excludelowpop_value'] = $minValue; + $this->viewProperties['filter_excludelowpop'] = $columnName; + $this->viewProperties['filter_excludelowpop_value'] = $minValue; } /** @@ -1014,8 +1153,8 @@ abstract class Piwik_ViewDataTable */ public function setSearchPattern($pattern, $column) { - $this->variablesDefault['filter_pattern'] = $pattern; - $this->variablesDefault['filter_column'] = $column; + $this->viewProperties['filter_pattern'] = $pattern; + $this->viewProperties['filter_column'] = $column; } /** @@ -1026,7 +1165,7 @@ abstract class Piwik_ViewDataTable public function setLimit($limit) { if ($limit !== 0) { - $this->variablesDefault['filter_limit'] = $limit; + $this->viewProperties['filter_limit'] = $limit; } } @@ -1048,9 +1187,8 @@ abstract class Piwik_ViewDataTable */ public function setSortedColumn($columnId, $order = 'desc') { -// debug_print_backtrace(); - $this->variablesDefault['filter_sort_column'] = $columnId; - $this->variablesDefault['filter_sort_order'] = $order; + $this->viewProperties['filter_sort_column'] = $columnId; + $this->viewProperties['filter_sort_order'] = $order; } /** @@ -1060,7 +1198,7 @@ abstract class Piwik_ViewDataTable */ public function getSortedColumn() { - return isset($this->variablesDefault['filter_sort_column']) ? $this->variablesDefault['filter_sort_column'] : false; + return isset($this->viewProperties['filter_sort_column']) ? $this->viewProperties['filter_sort_column'] : false; } /** @@ -1072,11 +1210,7 @@ abstract class Piwik_ViewDataTable */ public function setColumnTranslation($columnName, $columnTranslation) { - if (empty($columnTranslation)) { - throw new Exception('Unknown column: ' . $columnName); - } - - $this->columnsTranslations[$columnName] = $columnTranslation; + $this->viewProperties['translations'][$columnName] = $columnTranslation; } /** @@ -1087,8 +1221,8 @@ abstract class Piwik_ViewDataTable */ public function getColumnTranslation($columnName) { - if (isset($this->columnsTranslations[$columnName])) { - return $this->columnsTranslations[$columnName]; + if (isset($this->viewProperties['translations'][$columnName])) { + return $this->viewProperties['translations'][$columnName]; } return $columnName; } @@ -1106,7 +1240,7 @@ abstract class Piwik_ViewDataTable */ public function setMetricDocumentation($metricIdentifier, $documentation) { - $this->metricsDocumentation[$metricIdentifier] = $documentation; + $this->viewProperties['metrics_documentation'][$metricIdentifier] = $documentation; } /** @@ -1117,12 +1251,12 @@ abstract class Piwik_ViewDataTable */ public function getMetricDocumentation($columnName) { - if ($this->metricsDocumentation === false) { + if (empty($this->viewProperties['metrics_documentation'])) { $this->loadDocumentation(); } - if (!empty($this->metricsDocumentation[$columnName])) { - return $this->metricsDocumentation[$columnName]; + if (!empty($this->viewProperties['metrics_documentation'][$columnName])) { + return $this->viewProperties['metrics_documentation'][$columnName]; } return false; @@ -1148,7 +1282,7 @@ abstract class Piwik_ViewDataTable */ public function getReportDocumentation() { - if ($this->metricsDocumentation === false) { + if ($this->documentation === false) { $this->loadDocumentation(); } @@ -1158,13 +1292,13 @@ abstract class Piwik_ViewDataTable /** Load documentation from the API */ private function loadDocumentation() { - $this->metricsDocumentation = array(); + $this->viewProperties['metrics_documentation'] = array(); $report = Piwik_API_API::getInstance()->getMetadata(0, $this->currentControllerName, $this->currentControllerAction); $report = $report[0]; if (isset($report['metricsDocumentation'])) { - $this->metricsDocumentation = $report['metricsDocumentation']; + $this->viewProperties['metrics_documentation'] = $report['metricsDocumentation']; } if (isset($report['documentation'])) { @@ -1188,7 +1322,7 @@ abstract class Piwik_ViewDataTable $columnsNames = array($columnsNames); } } - $this->columnsToDisplay = array_filter($columnsNames); + $this->viewProperties['columns_to_display'] = array_filter($columnsNames); } /** @@ -1200,7 +1334,7 @@ abstract class Piwik_ViewDataTable */ public function getColumnsToDisplay() { - if (empty($this->columnsToDisplay)) { + if (empty($this->viewProperties['columns_to_display'])) { $row = $this->dataTable->getFirstRow(); if (empty($row)) { return array(); @@ -1209,11 +1343,11 @@ abstract class Piwik_ViewDataTable return array_keys($row->getColumns()); } - $this->columnsToDisplay = array_filter($this->columnsToDisplay); + $this->viewProperties['columns_to_display'] = array_filter($this->viewProperties['columns_to_display']); $this->removeEmptyColumnsFromDisplay(); - return $this->columnsToDisplay; + return $this->viewProperties['columns_to_display']; } private function removeEmptyColumnsFromDisplay() @@ -1228,12 +1362,12 @@ abstract class Piwik_ViewDataTable } if (is_array($emptyColumns)) { foreach ($emptyColumns as $emptyColumn) { - $key = array_search($emptyColumn, $this->columnsToDisplay); + $key = array_search($emptyColumn, $this->viewProperties['columns_to_display']); if ($key !== false) { - unset($this->columnsToDisplay[$key]); + unset($this->viewProperties['columns_to_display'][$key]); } } - $this->columnsToDisplay = array_values($this->columnsToDisplay); + $this->viewProperties['columns_to_display'] = array_values($this->viewProperties['columns_to_display']); } } @@ -1261,7 +1395,7 @@ abstract class Piwik_ViewDataTable */ public function setColumnsTranslations($columnsTranslations) { - $this->columnsTranslations += $columnsTranslations; + $this->viewProperties['translations'] += $columnsTranslations; } /** @@ -1273,10 +1407,10 @@ abstract class Piwik_ViewDataTable */ public function setCustomParameter($parameter, $value) { - if (isset($this->variablesDefault[$parameter])) { + if (isset($this->viewProperties['custom_parameters'][$parameter])) { throw new Exception("$parameter is already defined for this DataTable."); } - $this->variablesDefault[$parameter] = $value; + $this->viewProperties['custom_parameters'][$parameter] = $value; } /** @@ -1337,7 +1471,10 @@ abstract class Piwik_ViewDataTable */ public function addRelatedReports($thisReportTitle, $relatedReports) { - $this->setReportTitle($thisReportTitle); + if (!empty($thisReportTitle)) { + $this->setReportTitle($thisReportTitle); + } + foreach ($relatedReports as $report => $title) { list($module, $action) = explode('.', $report); $this->addRelatedReport($module, $action, $title); @@ -1429,21 +1566,33 @@ abstract class Piwik_ViewDataTable private function getBaseReportUrl($module, $action, $queryParams = array()) { $params = array_merge($queryParams, array('module' => $module, 'action' => $action)); - - // unset all filter query params so the related report will show up in its default state, - // unless the filter param was in $queryParams - $genericFiltersInfo = Piwik_API_DataTableGenericFilter::getGenericFiltersInformation(); - foreach ($genericFiltersInfo as $filter) { - foreach ($filter as $queryParamName => $queryParamInfo) { - if (!isset($params[$queryParamName])) { - $params[$queryParamName] = null; - } - } + return Piwik_API_Request::getCurrentUrlWithoutGenericFilters($params); + } + + /** + * Convenience method that creates and renders a ViewDataTable for a API method. + * + * @param string $pluginName The name of the plugin (eg, UserSettings). + * @param string $apiAction The name of the API action (eg, getResolution). + * @param bool $fetch If true, the result is returned, if false it is echo'd. + * @return string|null See $fetch. + */ + static public function render($pluginName, $apiAction, $fetch = true) + { + $apiClassName = 'Piwik_'.$pluginName.'_API'; + if (!method_exists($apiClassName::getInstance(), $apiAction)) { + throw new Exception("Invalid action name '$apiAction' for '$pluginName' plugin."); + } + + $view = self::factory(null, $pluginName.'.'.$apiAction); + $view->main(); + $rendered = $view->getView()->render(); + + if ($fetch) { + return $rendered; + } else { + echo $rendered; } - - // add the related report - $url = Piwik_Url::getCurrentQueryStringWithParametersModified($params); - return $url; } /** diff --git a/core/ViewDataTable/Cloud.php b/core/ViewDataTable/Cloud.php index a0f4d48c56..bc2377b4e7 100644 --- a/core/ViewDataTable/Cloud.php +++ b/core/ViewDataTable/Cloud.php @@ -29,23 +29,11 @@ class Piwik_ViewDataTable_Cloud extends Piwik_ViewDataTable { return 'cloud'; } - - /** - * @see Piwik_ViewDataTable::init() - * @param string $currentControllerName - * @param string $currentControllerAction - * @param string $apiMethodToRequestDataTable - * @param null|string $controllerActionCalledWhenRequestSubTable - */ - function init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable = null) + + public function __construct() { - parent::init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable); + parent::__construct(); + $this->dataTableTemplate = '@CoreHome/_dataTableCloud'; $this->disableOffsetInformation(); $this->disableExcludeLowPopulation(); diff --git a/core/ViewDataTable/GenerateGraphData.php b/core/ViewDataTable/GenerateGraphData.php index ddd8f23f69..e80405cf54 100644 --- a/core/ViewDataTable/GenerateGraphData.php +++ b/core/ViewDataTable/GenerateGraphData.php @@ -31,16 +31,58 @@ */ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable { - /** - * Number of elements to display in the graph. - * @var int - */ - protected $graphLimit = null; 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 = Piwik_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 + $selectableColumns = array('nb_visits', 'nb_actions'); + if (Piwik_Common::getRequestVar('period', false) == 'day') { + $selectableColumns[] = 'nb_uniq_visitors'; + } + + $this->setSelectableColumns($selectableColumns); + } + public function setAxisYUnit($unit) { $this->yAxisUnit = $unit; @@ -54,7 +96,7 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable */ public function setGraphLimit($limit) { - $this->graphLimit = $limit; + $this->viewProperties['graph_limit'] = $limit; } /** @@ -64,7 +106,7 @@ abstract class Piwik_ViewDataTable_GenerateGraphData extends Piwik_ViewDataTable */ public function getGraphLimit() { - return $this->graphLimit; + return $this->viewProperties['graph_limit']; } protected $displayPercentageInTooltip = true; diff --git a/core/ViewDataTable/GenerateGraphData/ChartEvolution.php b/core/ViewDataTable/GenerateGraphData/ChartEvolution.php index cbcf93d7be..4249d7cca8 100644 --- a/core/ViewDataTable/GenerateGraphData/ChartEvolution.php +++ b/core/ViewDataTable/GenerateGraphData/ChartEvolution.php @@ -35,8 +35,10 @@ class Piwik_ViewDataTable_GenerateGraphData_ChartEvolution extends Piwik_ViewDat return 'generateDataChartEvolution'; } - function __construct() + public function __construct() { + parent::__construct(); + $this->view = new Piwik_Visualization_Chart_Evolution(); } diff --git a/core/ViewDataTable/GenerateGraphData/ChartPie.php b/core/ViewDataTable/GenerateGraphData/ChartPie.php index 6acd8f440e..5f8d61a264 100644 --- a/core/ViewDataTable/GenerateGraphData/ChartPie.php +++ b/core/ViewDataTable/GenerateGraphData/ChartPie.php @@ -17,16 +17,17 @@ */ class Piwik_ViewDataTable_GenerateGraphData_ChartPie extends Piwik_ViewDataTable_GenerateGraphData { - protected $graphLimit = 6; - protected function getViewDataTableId() { return 'generateDataChartPie'; } - function __construct() + public function __construct() { + parent::__construct(); + $this->view = new Piwik_Visualization_Chart_Pie(); + $this->viewProperties['graph_limit'] = 6; } /** diff --git a/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php b/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php index b4c462b7ba..ca9dd94bf0 100644 --- a/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php +++ b/core/ViewDataTable/GenerateGraphData/ChartVerticalBar.php @@ -17,16 +17,17 @@ */ class Piwik_ViewDataTable_GenerateGraphData_ChartVerticalBar extends Piwik_ViewDataTable_GenerateGraphData { - protected $graphLimit = 6; - protected function getViewDataTableId() { return 'generateDataChartVerticalBar'; } - function __construct() + public function __construct() { + parent::__construct(); + $this->view = new Piwik_Visualization_Chart_VerticalBar(); + $this->viewProperties['graph_limit'] = 6; } protected function getUnitsForColumnsToDisplay() diff --git a/core/ViewDataTable/GenerateGraphHTML.php b/core/ViewDataTable/GenerateGraphHTML.php index 8c17e37d8d..2c4da0652c 100644 --- a/core/ViewDataTable/GenerateGraphHTML.php +++ b/core/ViewDataTable/GenerateGraphHTML.php @@ -24,37 +24,28 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable protected $graphType = 'unknown'; /** - * Parameters to send to GenerateGraphData instance. Parameters are passed - * via the $_GET array. - * - * @var array + * Default constructor. */ - protected $generateGraphDataParams = array(); - - /** - * @see Piwik_ViewDataTable::init() - * @param string $currentControllerName - * @param string $currentControllerAction - * @param string $apiMethodToRequestDataTable - * @param null $controllerActionCalledWhenRequestSubTable - */ - function init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable = null) + public function __construct() { - parent::init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable); - + parent::__construct(); + $this->dataTableTemplate = '@CoreHome/_dataTableGraph'; - $this->disableOffsetInformationAndPaginationControls(); $this->disableExcludeLowPopulation(); $this->disableSearchBox(); $this->enableShowExportAsImageIcon(); - + } + + public function init($currentControllerName, + $currentControllerAction, + $apiMethodToRequestDataTable, + $controllerActionCalledWhenRequestSubTable = null, + $defaultProperties = array()) + { + parent::init($currentControllerName, $currentControllerAction, $apiMethodToRequestDataTable, + $controllerActionCalledWhenRequestSubTable, $defaultProperties); + $this->parametersToModify = array( 'viewDataTable' => $this->getViewDataTableIdToLoad(), // in the case this controller is being executed by another controller @@ -84,13 +75,24 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable { $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() { - $this->generateGraphDataParams['show_all_ticks'] = 1; + $this->viewProperties['show_all_ticks'] = 1; } /** @@ -99,7 +101,7 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable */ public function addTotalRow() { - $this->generateGraphDataParams['add_total_row'] = 1; + $this->viewProperties['add_total_row'] = 1; } /** @@ -143,8 +145,12 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable } // collect data + $jsonParameters = array(); + foreach ($this->getJavaScriptProperties() as $name) { + $jsonParameters[$name] = $this->viewProperties[$name]; + } $this->parametersToModify['action'] = $this->currentControllerAction; - $this->parametersToModify = array_merge($this->variablesDefault, $this->parametersToModify); + $this->parametersToModify = array_merge($jsonParameters, $this->parametersToModify); $this->graphData = $this->getGraphData(); // build view @@ -174,7 +180,7 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable { $saveGet = $_GET; - $params = array_merge($this->generateGraphDataParams, $this->parametersToModify); + $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, @@ -193,4 +199,15 @@ abstract class Piwik_ViewDataTable_GenerateGraphHTML extends Piwik_ViewDataTable return str_replace(array("\r", "\n"), '', $content); } + + private function getGenerateGraphDataParams() + { + $result = array(); + foreach ($this->getViewPropertiesToForward() as $name) { + if (isset($this->viewProperties[$name])) { + $result[$name] = $this->viewProperties[$name]; + } + } + return $result; + } } diff --git a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php index 4381b75855..73d0f3a167 100644 --- a/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php +++ b/core/ViewDataTable/GenerateGraphHTML/ChartEvolution.php @@ -43,12 +43,14 @@ class Piwik_ViewDataTable_GenerateGraphHTML_ChartEvolution extends Piwik_ViewDat function init($currentControllerName, $currentControllerAction, $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable = null) + $controllerActionCalledWhenRequestSubTable = null, + $defaultProperties = array()) { parent::init($currentControllerName, $currentControllerAction, $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable); + $controllerActionCalledWhenRequestSubTable, + $defaultProperties); $this->calculateEvolutionDateRange(); $this->disableShowAllViewsIcons(); diff --git a/core/ViewDataTable/HtmlTable.php b/core/ViewDataTable/HtmlTable.php index c8677b9643..2d6505db85 100644 --- a/core/ViewDataTable/HtmlTable.php +++ b/core/ViewDataTable/HtmlTable.php @@ -25,25 +25,16 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable * @var array */ public $arrayDataTable; // phpArray + + public function __construct() + { + parent::__construct(); - /** - * @see Piwik_ViewDataTable::init() - * @param string $currentControllerName - * @param string $currentControllerAction - * @param string $apiMethodToRequestDataTable - * @param null|string $controllerActionCalledWhenRequestSubTable - */ - function init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable = null) - { - parent::init($currentControllerName, - $currentControllerAction, - $apiMethodToRequestDataTable, - $controllerActionCalledWhenRequestSubTable); $this->dataTableTemplate = '@CoreHome/_dataTable'; - $this->variablesDefault['enable_sort'] = '1'; + $this->viewProperties['enable_sort'] = '1'; + $this->viewProperties['disable_row_evolution'] = false; + $this->viewProperties['disable_row_actions'] = false; + $this->setSortedColumn('nb_visits', 'desc'); $this->setLimit(Piwik_Config::getInstance()->General['datatable_default_limit']); $this->handleLowPopulation(); @@ -51,6 +42,13 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable $this->viewProperties['datatable_js_type'] = 'dataTable'; $this->viewProperties['datatable_css_class'] = $this->getDefaultDataTableCssClass(); } + + public function getJavaScriptProperties() + { + $result = parent::getJavaScriptProperties(); + $result[] = 'search_recursive'; + return $result; + } protected function getViewDataTableId() { @@ -190,7 +188,7 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable */ public function addColumnToDisplay($columnName) { - $this->columnsToDisplay[] = $columnName; + $this->viewProperties['columns_to_display'][] = $columnName; } /** @@ -199,7 +197,7 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable */ public function setSearchRecursive() { - $this->variablesDefault['search_recursive'] = true; + $this->viewProperties['search_recursive'] = true; } protected function getRequestString() @@ -216,7 +214,7 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable */ public function disableRowEvolution() { - $this->variablesDefault['disable_row_evolution'] = true; + $this->viewProperties['disable_row_evolution'] = true; } /** @@ -224,7 +222,7 @@ class Piwik_ViewDataTable_HtmlTable extends Piwik_ViewDataTable */ public function disableRowActions() { - $this->variablesDefault['disable_row_actions'] = true; + $this->viewProperties['disable_row_actions'] = true; } } |