diff --git a/.coveralls.yml b/.coveralls.yml new file mode 100644 index 00000000000..dc27e4c6ea4 --- /dev/null +++ b/.coveralls.yml @@ -0,0 +1,3 @@ +service_name: travis-ci +src_dir: . +coverage_clover: build/logs/clover-*.xml diff --git a/core/Plugin/Visualization.php b/core/Plugin/Visualization.php index 7e6aec2eaa1..8c843806deb 100644 --- a/core/Plugin/Visualization.php +++ b/core/Plugin/Visualization.php @@ -374,11 +374,13 @@ private function applyFilters() $this->dataTable->applyQueuedFilters(); } - $formatter = $this->metricsFormatter; - $report = $this->report; - $this->dataTable->filter(function (DataTable $table) use ($formatter, $report) { - $formatter->formatMetrics($table, $report); - }); + if ($this->requestConfig->shouldFormatMetrics()) { + $formatter = $this->metricsFormatter; + $report = $this->report; + $this->dataTable->filter(function (DataTable $table) use ($formatter, $report) { + $formatter->formatMetrics($table, $report); + }); + } } private function removeEmptyColumnsFromDisplay() diff --git a/core/ViewDataTable/RequestConfig.php b/core/ViewDataTable/RequestConfig.php index 5ea6b623f4f..753ee55b989 100644 --- a/core/ViewDataTable/RequestConfig.php +++ b/core/ViewDataTable/RequestConfig.php @@ -356,4 +356,9 @@ public function getApiMethodToRequest() return $method; } + + public function shouldFormatMetrics() + { + return Common::getRequestVar('format_metrics', '1', 'string', $this->request_parameters_to_modify) != 0; + } } diff --git a/plugins/API/RowEvolution.php b/plugins/API/RowEvolution.php index c4d96fb9126..a326b5022fd 100644 --- a/plugins/API/RowEvolution.php +++ b/plugins/API/RowEvolution.php @@ -280,9 +280,10 @@ private function loadRowEvolutionDataFromAPI($metadata, $idSite, $period, $date, // note: some reports should not be filtered with AddColumnProcessedMetrics // specifically, reports without the Metrics::INDEX_NB_VISITS metric such as Goals.getVisitsUntilConversion & Goal.getDaysToConversion // this is because the AddColumnProcessedMetrics filter removes all datable rows lacking this metric - if ( isset($metadata['metrics']['nb_visits']) - && !empty($label)) { - $parameters['filter_add_columns_when_show_all_columns'] = '1'; + if (isset($metadata['metrics']['nb_visits']) + && !empty($label) + ) { + $parameters['filter_add_columns_when_show_all_columns'] = '0'; } $url = Url::getQueryStringFromParameters($parameters); diff --git a/plugins/CoreHome/javascripts/dataTable.js b/plugins/CoreHome/javascripts/dataTable.js index 99607433481..5b37493a609 100644 --- a/plugins/CoreHome/javascripts/dataTable.js +++ b/plugins/CoreHome/javascripts/dataTable.js @@ -1890,11 +1890,26 @@ var switchToHtmlTable = function (dataTable, viewDataTable) { dataTable.notifyWidgetParametersChange(dataTable.$element, {viewDataTable: viewDataTable}); }; +var switchToEcommerceView = function (dataTable, viewDataTable) { + if (viewDataTable == 'ecommerceOrder') { + dataTable.param.abandonedCarts = '0'; + } else { + dataTable.param.abandonedCarts = '1'; + } + + var viewDataTable = dataTable.param.viewDataTable; + if (viewDataTable == 'ecommerceOrder' || viewDataTable == 'ecommerceAbandonedCart') { + viewDataTable = 'table'; + } + + switchToHtmlTable(dataTable, viewDataTable); +}; + DataTable.registerFooterIconHandler('table', switchToHtmlTable); DataTable.registerFooterIconHandler('tableAllColumns', switchToHtmlTable); DataTable.registerFooterIconHandler('tableGoals', switchToHtmlTable); -DataTable.registerFooterIconHandler('ecommerceOrder', switchToHtmlTable); -DataTable.registerFooterIconHandler('ecommerceAbandonedCart', switchToHtmlTable); +DataTable.registerFooterIconHandler('ecommerceOrder', switchToEcommerceView); +DataTable.registerFooterIconHandler('ecommerceAbandonedCart', switchToEcommerceView); // generic function to handle switch to graph visualizations DataTable.switchToGraph = function (dataTable, viewDataTable) { diff --git a/plugins/CoreHome/javascripts/dataTable_rowactions.js b/plugins/CoreHome/javascripts/dataTable_rowactions.js index 2ce31bf5db5..ac8554593ee 100644 --- a/plugins/CoreHome/javascripts/dataTable_rowactions.js +++ b/plugins/CoreHome/javascripts/dataTable_rowactions.js @@ -274,16 +274,22 @@ DataTable_RowActions_RowEvolution.prototype.performAction = function (label, tr, return; } - // check whether we have rows marked for multi row evolution - var isMultiRowEvolution = '0'; this.addMultiEvolutionRow(label); + + // check whether we have rows marked for multi row evolution + var extraParams = {}; if (this.multiEvolutionRows.length > 1) { - isMultiRowEvolution = '1'; + extraParams.action = 'getMultiRowEvolutionPopover'; label = this.multiEvolutionRows.join(','); } + // check if abandonedCarts is in the dataTable params and if so, propagate to row evolution request + if (this.dataTable.param.abandonedCarts !== undefined) { + extraParams['abandonedCarts'] = this.dataTable.param.abandonedCarts; + } + var apiMethod = this.dataTable.param.module + '.' + this.dataTable.param.action; - this.openPopover(apiMethod, isMultiRowEvolution, label); + this.openPopover(apiMethod, extraParams, label); }; DataTable_RowActions_RowEvolution.prototype.addMultiEvolutionRow = function (label) { @@ -292,27 +298,37 @@ DataTable_RowActions_RowEvolution.prototype.addMultiEvolutionRow = function (lab } }; -DataTable_RowActions_RowEvolution.prototype.openPopover = function (apiMethod, multiRowEvolutionParam, label) { - var urlParam = apiMethod + ':' + multiRowEvolutionParam + ':' + label; +DataTable_RowActions_RowEvolution.prototype.openPopover = function (apiMethod, extraParams, label) { + var urlParam = apiMethod + ':' + encodeURIComponent(JSON.stringify(extraParams)) + ':' + label; DataTable_RowAction.prototype.openPopover.apply(this, [urlParam]); }; DataTable_RowActions_RowEvolution.prototype.doOpenPopover = function (urlParam) { var urlParamParts = urlParam.split(':'); - var apiMethod = urlParamParts[0]; - urlParamParts.shift(); - - var multiRowEvolutionParam = urlParamParts[0]; - urlParamParts.shift(); + var apiMethod = urlParamParts.shift(); + + var extraParamsString = urlParamParts.shift(), + extraParams = {}; // 0/1 or "0"/"1" + try { + extraParams = JSON.parse(decodeURIComponent(extraParamsString)); + } catch (e) { + // assume the parameter is an int/string describing whether to use multi row evolution + if (extraParamsString == '1') { + extraParams.action = 'getMultiRowEvolutionPopover'; + } else if (extraParamsString != '0') { + extraParams.action = 'getMultiRowEvolutionPopover'; + extraParams.column = extraParamsString; + } + } var label = urlParamParts.join(':'); - this.showRowEvolution(apiMethod, label, multiRowEvolutionParam); + this.showRowEvolution(apiMethod, label, extraParams); }; /** Open the row evolution popover */ -DataTable_RowActions_RowEvolution.prototype.showRowEvolution = function (apiMethod, label, multiRowEvolutionParam) { +DataTable_RowActions_RowEvolution.prototype.showRowEvolution = function (apiMethod, label, extraParams) { var self = this; @@ -327,17 +343,6 @@ DataTable_RowActions_RowEvolution.prototype.showRowEvolution = function (apiMeth disableLink: 1 }; - // derive api action and requested column from multiRowEvolutionParam - var action; - if (multiRowEvolutionParam == '0') { - action = 'getRowEvolutionPopover'; - } else if (multiRowEvolutionParam == '1') { - action = 'getMultiRowEvolutionPopover'; - } else { - action = 'getMultiRowEvolutionPopover'; - requestParams.column = multiRowEvolutionParam; - } - var callback = function (html) { Piwik_Popover.setContent(html); @@ -371,15 +376,18 @@ DataTable_RowActions_RowEvolution.prototype.showRowEvolution = function (apiMeth box.find('select.multirowevoltion-metric').change(function () { var metric = $(this).val(); Piwik_Popover.onClose(false); // unbind listener that resets multiEvolutionRows - self.openPopover(apiMethod, metric, label); + var extraParams = {action: 'getMultiRowEvolutionPopover', column: metric}; + self.openPopover(apiMethod, extraParams, label); return true; }); }; requestParams.module = 'CoreHome'; - requestParams.action = action; + requestParams.action = 'getRowEvolutionPopover'; requestParams.colors = JSON.stringify(piwik.getSparklineColors()); + $.extend(requestParams, extraParams); + var ajaxRequest = new ajaxHelper(); ajaxRequest.addParams(requestParams, 'get'); ajaxRequest.setCallback(callback); diff --git a/plugins/CoreHome/templates/_dataTableFooter.twig b/plugins/CoreHome/templates/_dataTableFooter.twig index 0f673aa2a25..ec2b9fd21cf 100644 --- a/plugins/CoreHome/templates/_dataTableFooter.twig +++ b/plugins/CoreHome/templates/_dataTableFooter.twig @@ -31,11 +31,14 @@
{% for footerIcon in footerIconGroup.buttons %} + {% set isActiveEcommerceView = clientSideParameters.abandonedCarts is defined and + ((footerIcon.id == 'ecommerceOrder' and clientSideParameters.abandonedCarts == 0) or + (footerIcon.id == 'ecommerceAbandonedCart' and clientSideParameters.abandonedCarts == 1)) %} - {% if properties.show_active_view_icon and clientSideParameters.viewDataTable == footerIcon.id %} + {% if properties.show_active_view_icon and (clientSideParameters.viewDataTable == footerIcon.id or isActiveEcommerceView) %} {% endif %} - + {% if footerIcon.text is defined %}{{ footerIcon.text }}{% endif %} diff --git a/plugins/CoreVisualizations/Visualizations/Graph.php b/plugins/CoreVisualizations/Visualizations/Graph.php index dbb1942d2a5..d1a8ccd6b75 100644 --- a/plugins/CoreVisualizations/Visualizations/Graph.php +++ b/plugins/CoreVisualizations/Visualizations/Graph.php @@ -59,6 +59,7 @@ public function beforeLoadDataTable() } $this->requestConfig->request_parameters_to_modify['disable_queued_filters'] = 1; + $this->requestConfig->request_parameters_to_modify['format_metrics'] = 0; } /** diff --git a/plugins/Goals/Controller.php b/plugins/Goals/Controller.php index dee8fb0d4c1..78715426759 100644 --- a/plugins/Goals/Controller.php +++ b/plugins/Goals/Controller.php @@ -430,7 +430,9 @@ private function getGoalReportsByDimensionTable($conversions, $ecommerce = false $ecommerceCustomParams = array(); if ($ecommerce) { if ($preloadAbandonedCart) { - $ecommerceCustomParams['viewDataTable'] = 'ecommerceAbandonedCart'; + $ecommerceCustomParams['abandonedCarts'] = '1'; + } else { + $ecommerceCustomParams['abandonedCarts'] = '0'; } $goalReportsByDimension->addReport( @@ -457,7 +459,9 @@ private function getGoalReportsByDimensionTable($conversions, $ecommerce = false foreach ($allReports as $category => $reports) { $categoryText = Piwik::translate('Goals_ViewGoalsBy', $category); foreach ($reports as $report) { - if (empty($report['viewDataTable'])) { + if (empty($report['viewDataTable']) + && empty($report['abandonedCarts']) + ) { $report['viewDataTable'] = 'tableGoals'; } $customParams['viewDataTable'] = $report['viewDataTable']; diff --git a/plugins/Goals/Reports/BaseEcommerceItem.php b/plugins/Goals/Reports/BaseEcommerceItem.php index 32b2fff7709..bfc93fcdd57 100644 --- a/plugins/Goals/Reports/BaseEcommerceItem.php +++ b/plugins/Goals/Reports/BaseEcommerceItem.php @@ -13,6 +13,7 @@ use Piwik\Piwik; use Piwik\Plugin\Report; use Piwik\Plugin\ViewDataTable; +use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution; use Piwik\Plugins\Goals\Goals; use Piwik\Plugins\Goals\Columns\Metrics\AveragePrice; use Piwik\Plugins\Goals\Columns\Metrics\AverageQuantity; @@ -69,9 +70,11 @@ public function configureView(ViewDataTable $view) $view->config->show_exclude_low_population = false; $view->config->show_table_all_columns = false; - $moneyColumns = array('revenue'); - $formatter = array(new Formatter(), 'getPrettyMoney'); - $view->config->filters[] = array('ColumnCallbackReplace', array($moneyColumns, $formatter, array($idSite))); + if (!($view instanceof Evolution)) { + $moneyColumns = array('revenue'); + $formatter = array(new Formatter(), 'getPrettyMoney'); + $view->config->filters[] = array('ColumnCallbackReplace', array($moneyColumns, $formatter, array($idSite))); + } $view->requestConfig->filter_limit = 10; $view->requestConfig->filter_sort_column = 'revenue'; @@ -85,7 +88,19 @@ public function configureView(ViewDataTable $view) $columnsOrdered = array('label', 'revenue', 'quantity', 'orders', 'avg_price', 'avg_quantity', 'nb_visits', 'conversion_rate'); - $abandonedCart = $this->isAbandonedCart(); + // handle old case where viewDataTable is set to ecommerceOrder/ecommerceAbandonedCart. in this case, we + // set abandonedCarts accordingly and remove the ecommerceOrder/ecommerceAbandonedCart as viewDataTable. + $viewDataTable = Common::getRequestVar('viewDataTable', ''); + if ($viewDataTable == 'ecommerceOrder') { + $view->config->custom_parameters['viewDataTable'] = 'table'; + $abandonedCart = false; + } else if ($viewDataTable == 'ecommerceAbandonedCart') { + $view->config->custom_parameters['viewDataTable'] = 'table'; + $abandonedCart = true; + } else { + $abandonedCart = $this->isAbandonedCart(); + } + if ($abandonedCart) { $columns['abandoned_carts'] = Piwik::translate('General_AbandonedCarts'); $columns['revenue'] = Piwik::translate('Goals_LeftInCart', $columns['revenue']); @@ -94,23 +109,24 @@ public function configureView(ViewDataTable $view) unset($columns['orders']); unset($columns['conversion_rate']); - $view->requestConfig->request_parameters_to_modify['abandonedCarts'] = '1'; - $columnsOrdered = array('label', 'revenue', 'quantity', 'avg_price', 'avg_quantity', 'nb_visits', 'abandoned_carts'); + + $view->config->custom_parameters['abandonedCarts'] = '1'; + } else { + $view->config->custom_parameters['abandonedCarts'] = '0'; } + $view->requestConfig->request_parameters_to_modify['abandonedCarts'] = $view->config->custom_parameters['abandonedCarts']; + $translations = array_merge(array('label' => $this->name), $columns); $view->config->addTranslations($translations); $view->config->columns_to_display = $columnsOrdered; - - $view->config->custom_parameters['viewDataTable'] = - $abandonedCart ? Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART : Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER; } private function isAbandonedCart() { - return Common::getRequestVar('viewDataTable', 'ecommerceOrder', 'string') == 'ecommerceAbandonedCart'; + return Common::getRequestVar('abandonedCarts', '0', 'string') == 1; } } diff --git a/tests/PHPUnit/UI b/tests/PHPUnit/UI index 2931569c091..e1361bab91d 160000 --- a/tests/PHPUnit/UI +++ b/tests/PHPUnit/UI @@ -1 +1 @@ -Subproject commit 2931569c0914636fcf121525c8f83877208d6247 +Subproject commit e1361bab91dc28ac92beaea94383a8ecb97f63eb