From 1c921c50f28581e239133bce76dda0955bc11027 Mon Sep 17 00:00:00 2001 From: diosmosis <benaka@piwik.pro> Date: Thu, 6 Nov 2014 13:01:09 -0800 Subject: [PATCH] Rewrite AddColumnsProcessedMetricsGoal filter to use processed metrics DataTable metadata. --- .../Filter/AddColumnsProcessedMetricsGoal.php | 104 ++++++++---------- core/Metrics.php | 17 ++- core/Metrics/ProcessedGoals.php | 77 ------------- core/Plugin/Metric.php | 22 +++- .../GoalSpecific/AverageOrderRevenue.php | 47 ++++++++ .../Metrics/GoalSpecific/ConversionRate.php | 50 +++++++++ .../Metrics/GoalSpecific/Conversions.php | 39 +++++++ .../Goals/Metrics/GoalSpecific/ItemsCount.php | 39 +++++++ .../Goals/Metrics/GoalSpecific/Revenue.php | 39 +++++++ .../Metrics/GoalSpecific/RevenuePerVisit.php | 47 ++++++++ .../Metrics/GoalSpecificProcessedMetric.php | 38 +++++++ plugins/Goals/Metrics/RevenuePerVisit.php | 64 +++++++++++ 12 files changed, 437 insertions(+), 146 deletions(-) create mode 100644 plugins/Goals/Metrics/GoalSpecific/AverageOrderRevenue.php create mode 100644 plugins/Goals/Metrics/GoalSpecific/ConversionRate.php create mode 100644 plugins/Goals/Metrics/GoalSpecific/Conversions.php create mode 100644 plugins/Goals/Metrics/GoalSpecific/ItemsCount.php create mode 100644 plugins/Goals/Metrics/GoalSpecific/Revenue.php create mode 100644 plugins/Goals/Metrics/GoalSpecific/RevenuePerVisit.php create mode 100644 plugins/Goals/Metrics/GoalSpecificProcessedMetric.php create mode 100644 plugins/Goals/Metrics/RevenuePerVisit.php diff --git a/core/DataTable/Filter/AddColumnsProcessedMetricsGoal.php b/core/DataTable/Filter/AddColumnsProcessedMetricsGoal.php index 963ac9acbd..aed53e3d30 100644 --- a/core/DataTable/Filter/AddColumnsProcessedMetricsGoal.php +++ b/core/DataTable/Filter/AddColumnsProcessedMetricsGoal.php @@ -12,6 +12,13 @@ use Piwik\DataTable; use Piwik\DataTable\Row; use Piwik\Metrics; use Piwik\Piwik; +use Piwik\Plugins\Goals\Metrics\GoalSpecific\AverageOrderRevenue; +use Piwik\Plugins\Goals\Metrics\GoalSpecific\ConversionRate; +use Piwik\Plugins\Goals\Metrics\GoalSpecific\Conversions; +use Piwik\Plugins\Goals\Metrics\GoalSpecific\ItemsCount; +use Piwik\Plugins\Goals\Metrics\GoalSpecific\Revenue; +use Piwik\Plugins\Goals\Metrics\GoalSpecific\RevenuePerVisit as GoalSpecificRevenuePerVisit; +use Piwik\Plugins\Goals\Metrics\RevenuePerVisit; /** * Adds goal related metrics to a {@link DataTable} using metrics that already exist. @@ -87,12 +94,6 @@ class AddColumnsProcessedMetricsGoal extends AddColumnsProcessedMetrics $this->deleteRowsWithNoVisit = false; } - private function addColumn(Row $row, $columnName, $callback) - { - $this->expectedColumns[$columnName] = true; - $row->addColumn($columnName, $callback); - } - /** * Adds the processed metrics. See {@link AddColumnsProcessedMetrics} for * more information. @@ -104,40 +105,22 @@ class AddColumnsProcessedMetricsGoal extends AddColumnsProcessedMetrics // Add standard processed metrics parent::filter($table); - $this->expectedColumns = array(); - - $metrics = new Metrics\ProcessedGoals(); - - foreach ($table->getRows() as $row) { - $goals = $metrics->getColumn($row, Metrics::INDEX_GOALS); + $extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME); - if (!$goals) { - continue; - } - - $this->addColumn($row, 'revenue_per_visit', function (Row $row) use ($metrics) { - return $metrics->getRevenuePerVisit($row); - }); - - if ($this->processOnlyIdGoal == self::GOALS_MINIMAL_REPORT) { - continue; - } - - foreach ($goals as $goalId => $goalMetrics) { - $goalId = str_replace("idgoal=", "", $goalId); + $goals = $this->getGoalsInTable($table); + // TODO: all metrics depend on 'goals' row paremter + $extraProcessedMetrics[] = new RevenuePerVisit(); + if ($this->processOnlyIdGoal != self::GOALS_MINIMAL_REPORT) { + foreach ($goals as $idGoal) { if (($this->processOnlyIdGoal > self::GOALS_FULL_TABLE || $this->isEcommerce) - && $this->processOnlyIdGoal != $goalId + && $this->processOnlyIdGoal != $idGoal ) { continue; } - $columnPrefix = 'goal_' . $goalId; - - $this->addColumn($row, $columnPrefix . '_conversion_rate', function (Row $row) use ($metrics, $goalMetrics) { - return $metrics->getConversionRate($row, $goalMetrics); - }); + $extraProcessedMetrics[] = new ConversionRate($idGoal); // PerGoal\ConversionRate // When the table is displayed by clicking on the flag icon, we only display the columns // Visits, Conversions, Per goal conversion rate, Revenue @@ -145,38 +128,20 @@ class AddColumnsProcessedMetricsGoal extends AddColumnsProcessedMetrics continue; } - // Goal Conversions - $this->addColumn($row, $columnPrefix . '_nb_conversions', function () use ($metrics, $goalMetrics) { - return $metrics->getNbConversions($goalMetrics); - }); - - // Goal Revenue per visit - $this->addColumn($row, $columnPrefix . '_revenue_per_visit', function (Row $row) use ($metrics, $goalMetrics) { - return $metrics->getRevenuePerVisitForGoal($row, $goalMetrics); - }); - - // Total revenue - $this->addColumn($row, $columnPrefix . '_revenue', function () use ($metrics, $goalMetrics) { - return $metrics->getRevenue($goalMetrics); - }); + $extraProcessedMetrics[] = new Conversions($idGoal); // PerGoal\Conversions or GoalSpecific\ + $extraProcessedMetrics[] = new GoalSpecificRevenuePerVisit($idGoal); // PerGoal\Revenue + $extraProcessedMetrics[] = new Revenue($idGoal); // PerGoal\Revenue if ($this->isEcommerce) { - - // AOV Average Order Value - $this->addColumn($row, $columnPrefix . '_avg_order_revenue', function () use ($metrics, $goalMetrics) { - return $metrics->getAvgOrderRevenue($goalMetrics); - }); - - // Items qty - $this->addColumn($row, $columnPrefix . '_items', function () use ($metrics, $goalMetrics) { - return $metrics->getItems($goalMetrics); - }); - + $extraProcessedMetrics[] = new AverageOrderRevenue($idGoal); + $extraProcessedMetrics[] = new ItemsCount($idGoal); } } } - $expectedColumns = array_keys($this->expectedColumns); + $table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics); + + /*$expectedColumns = array_keys($this->expectedColumns); $rows = $table->getRows(); foreach ($rows as $row) { foreach ($expectedColumns as $name) { @@ -190,6 +155,27 @@ class AddColumnsProcessedMetricsGoal extends AddColumnsProcessedMetrics } } } + }*/ + } + + private function getGoalsInTable(DataTable $table) + { + $metrics = new Metrics\Base(); // TODO: should probably get rid of Base too... + + $result = array(); + foreach ($table->getRows() as $row) { + $goals = $metrics->getColumn($row, Metrics::INDEX_GOALS); + if (!$goals) { + continue; + } + + foreach ($goals as $goalId => $goalMetrics) { + $goalId = str_replace("idgoal=", "", $goalId); + $result[] = $goalId; + } + + break; } + return $result; } -} +} \ No newline at end of file diff --git a/core/Metrics.php b/core/Metrics.php index 01e2e66ca2..4614cf2d0d 100644 --- a/core/Metrics.php +++ b/core/Metrics.php @@ -185,11 +185,20 @@ class Metrics public static function getMappingFromNameToId() { - static $idToName = null; - if ($idToName === null) { - $idToName = array_flip(self::$mappingFromIdToName); + static $nameToId = null; + if ($nameToId === null) { + $nameToId = array_flip(self::$mappingFromIdToName); } - return $idToName; + return $nameToId; + } + + public static function getMappingFromNameToIdGoal() + { + static $nameToId = null; + if ($nameToId === null) { + $nameToId = array_flip(self::$mappingFromIdToNameGoal); + } + return $nameToId; } /** diff --git a/core/Metrics/ProcessedGoals.php b/core/Metrics/ProcessedGoals.php index 6fb62231f3..eb981cb4c9 100644 --- a/core/Metrics/ProcessedGoals.php +++ b/core/Metrics/ProcessedGoals.php @@ -16,61 +16,6 @@ use Piwik\Tracker\GoalManager; class ProcessedGoals extends Base { - - public function getRevenuePerVisit(Row $row) - { - $goals = $this->getColumn($row, Metrics::INDEX_GOALS); - - $revenue = 0; - foreach ($goals as $goalId => $goalMetrics) { - if ($goalId == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) { - continue; - } - if ($goalId >= GoalManager::IDGOAL_ORDER - || $goalId == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER - ) { - $revenue += (int) $this->getColumn($goalMetrics, Metrics::INDEX_GOAL_REVENUE, Metrics::$mappingFromIdToNameGoal); - } - } - - if ($revenue == 0) { - $revenue = (int) $this->getColumn($row, Metrics::INDEX_REVENUE); - } - - $nbVisits = $this->getNumVisits($row); - $conversions = (int) $this->getColumn($row, Metrics::INDEX_NB_CONVERSIONS); - - // If no visit for this metric, but some conversions, we still want to display some kind of "revenue per visit" - // even though it will actually be in this edge case "Revenue per conversion" - $revenuePerVisit = $this->invalidDivision; - - if ($nbVisits > 0 - || $conversions > 0 - ) { - $revenuePerVisit = round($revenue / ($nbVisits == 0 ? $conversions : $nbVisits), GoalManager::REVENUE_PRECISION); - } - - return $revenuePerVisit; - } - - public function getConversionRate(Row $row, $goalMetrics) - { - $nbVisits = $this->getNumVisits($row); - - if ($nbVisits == 0) { - $value = $this->invalidDivision; - } else { - $conversions = $this->getNbConversions($goalMetrics); - $value = round(100 * $conversions / $nbVisits, GoalManager::REVENUE_PRECISION); - } - - if (empty($value)) { - return '0%'; - } - - return $value . "%"; - } - public function getNbConversions($goalMetrics) { return (int) $this->getColumn($goalMetrics, @@ -85,28 +30,6 @@ class ProcessedGoals extends Base Metrics::$mappingFromIdToNameGoal); } - public function getRevenuePerVisitForGoal(Row $row, $goalMetrics) - { - $nbVisits = $this->getNumVisits($row); - - $div = $nbVisits; - if ($nbVisits == 0) { - $div = $this->getNbConversions($goalMetrics); - } - - $goalRevenue = $this->getRevenue($goalMetrics); - - return round($goalRevenue / $div, GoalManager::REVENUE_PRECISION); - } - - public function getAvgOrderRevenue($goalMetrics) - { - $goalRevenue = $this->getRevenue($goalMetrics); - $conversions = $this->getNbConversions($goalMetrics); - - return $goalRevenue / $conversions; - } - public function getItems($goalMetrics) { $items = $this->getColumn($goalMetrics, diff --git a/core/Plugin/Metric.php b/core/Plugin/Metric.php index 3728dacac5..7a6033e8b7 100644 --- a/core/Plugin/Metric.php +++ b/core/Plugin/Metric.php @@ -63,17 +63,27 @@ abstract class Metric /** * TODO */ - public function getColumn(Row $row, $columnName, $mappingIdToName = null) + public function getColumn($row, $columnName, $mappingIdToName = null) { if (empty($mappingIdToName)) { $mappingIdToName = Metrics::getMappingFromNameToId(); } - $value = $row->getColumn($columnName); - if ($value === false - && isset($mappingIdToName[$columnName]) - ) { - $value = $row->getColumn($mappingIdToName[$columnName]); + if ($row instanceof Row) { + $value = $row->getColumn($columnName); + if ($value === false + && isset($mappingIdToName[$columnName]) + ) { + $value = $row->getColumn($mappingIdToName[$columnName]); + } + } else { + $value = $row[$columnName]; + if ($value === false + && isset($mappingIdToName[$columnName]) + ) { + $value = $row[$mappingIdToName[$columnName]]; + } + return $value; } return $value; diff --git a/plugins/Goals/Metrics/GoalSpecific/AverageOrderRevenue.php b/plugins/Goals/Metrics/GoalSpecific/AverageOrderRevenue.php new file mode 100644 index 0000000000..ed2b0b1e09 --- /dev/null +++ b/plugins/Goals/Metrics/GoalSpecific/AverageOrderRevenue.php @@ -0,0 +1,47 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics\GoalSpecific; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Piwik; +use Piwik\Plugins\Goals\Metrics\GoalSpecificProcessedMetric; +use Piwik\Tracker\GoalManager; + +/** + * TODO + */ +class AverageOrderRevenue extends GoalSpecificProcessedMetric +{ + public function getName() + { + return $this->getColumnPrefix() . '_avg_order_revenue'; + } + + public function getTranslatedName() + { + return self::getName(); // TODO??? + } + + public function getDependenctMetrics() + { + return array('goals'); + } + + public function compute(Row $row) + { + $mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal(); + + $goalMetrics = $row->getColumn($row, 'goals'); + + $goalRevenue = $this->getColumn($goalMetrics, 'revenue', $mappingFromNameToIdGoal); + $conversions = $this->getColumn($goalMetrics, 'nb_conversions', $mappingFromNameToIdGoal); + + return Piwik::getQuotientSafe($goalRevenue, $conversions, GoalManager::REVENUE_PRECISION); + } +} \ No newline at end of file diff --git a/plugins/Goals/Metrics/GoalSpecific/ConversionRate.php b/plugins/Goals/Metrics/GoalSpecific/ConversionRate.php new file mode 100644 index 0000000000..c65e88fc6b --- /dev/null +++ b/plugins/Goals/Metrics/GoalSpecific/ConversionRate.php @@ -0,0 +1,50 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics\GoalSpecific; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Piwik; +use Piwik\Plugins\Goals\Metrics\GoalSpecificProcessedMetric; +use Piwik\Tracker\GoalManager; + +/** + * TODO + */ +class ConversionRate extends GoalSpecificProcessedMetric +{ + public function getName() + { + return $this->getColumnPrefix() . '_conversion_rate'; + } + + public function getTranslatedName() + { + return self::getName(); // TODO??? + } + + public function getDependenctMetrics() + { + return array('goals'); + } + + public function format($value) + { + return ($value * 100) . '%'; + } + + public function compute(Row $row) + { + $goalMetrics = $this->getColumn($row, 'goals'); + + $nbVisits = $this->getColumn($row, 'nb_visits'); + $conversions = $this->getColumn($goalMetrics, 'nb_conversions'); + + return Piwik::getQuotientSafe($conversions, $nbVisits, GoalManager::REVENUE_PRECISION); + } +} \ No newline at end of file diff --git a/plugins/Goals/Metrics/GoalSpecific/Conversions.php b/plugins/Goals/Metrics/GoalSpecific/Conversions.php new file mode 100644 index 0000000000..a4ff02aeb2 --- /dev/null +++ b/plugins/Goals/Metrics/GoalSpecific/Conversions.php @@ -0,0 +1,39 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics\GoalSpecific; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Plugins\Goals\Metrics\GoalSpecificProcessedMetric; + +/** + * TODO + */ +class Conversions extends GoalSpecificProcessedMetric +{ + public function getName() + { + return $this->getColumnPrefix() . '_nb_conversions'; + } + + public function getTranslatedName() + { + return self::getName(); // TODO??? + } + + public function getDependenctMetrics() + { + return array('goals'); + } + + public function compute(Row $row) + { + $goalMetrics = $this->getColumn($row, 'goals'); + return (int) $this->getCOlumn($goalMetrics, 'nb_conversions'); + } +} \ No newline at end of file diff --git a/plugins/Goals/Metrics/GoalSpecific/ItemsCount.php b/plugins/Goals/Metrics/GoalSpecific/ItemsCount.php new file mode 100644 index 0000000000..d7265e3a08 --- /dev/null +++ b/plugins/Goals/Metrics/GoalSpecific/ItemsCount.php @@ -0,0 +1,39 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics\GoalSpecific; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Plugins\Goals\Metrics\GoalSpecificProcessedMetric; + +/** + * TODO + */ +class ItemsCount extends GoalSpecificProcessedMetric +{ + public function getName() + { + return $this->getColumnPrefix() . '_items'; + } + + public function getTranslatedName() + { + return self::getName(); // TODO??? + } + + public function getDependenctMetrics() + { + return array('goals'); + } + + public function compute(Row $row) + { + $goalMetrics = $this->getColumn($row, 'goals'); + return (int) $this->getCOlumn($goalMetrics, 'items'); + } +} \ No newline at end of file diff --git a/plugins/Goals/Metrics/GoalSpecific/Revenue.php b/plugins/Goals/Metrics/GoalSpecific/Revenue.php new file mode 100644 index 0000000000..1658425bbb --- /dev/null +++ b/plugins/Goals/Metrics/GoalSpecific/Revenue.php @@ -0,0 +1,39 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics\GoalSpecific; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Plugins\Goals\Metrics\GoalSpecificProcessedMetric; + +/** + * TODO + */ +class Revenue extends GoalSpecificProcessedMetric +{ + public function getName() + { + return $this->getColumnPrefix() . '_revenue'; + } + + public function getTranslatedName() + { + return self::getName(); // TODO??? + } + + public function getDependenctMetrics() + { + return array('goals'); + } + + public function compute(Row $row) + { + $goalMetrics = $this->getColumn($row, 'goals'); + return (float) $this->getCOlumn($goalMetrics, 'revenue'); + } +} \ No newline at end of file diff --git a/plugins/Goals/Metrics/GoalSpecific/RevenuePerVisit.php b/plugins/Goals/Metrics/GoalSpecific/RevenuePerVisit.php new file mode 100644 index 0000000000..403f415f8b --- /dev/null +++ b/plugins/Goals/Metrics/GoalSpecific/RevenuePerVisit.php @@ -0,0 +1,47 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics\GoalSpecific; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Piwik; +use Piwik\Plugins\Goals\Metrics\GoalSpecificProcessedMetric; +use Piwik\Tracker\GoalManager; + +/** + * TODO + */ +class RevenuePerVisit extends GoalSpecificProcessedMetric +{ + public function getName() + { + return $this->getColumnPrefix() . '_revenue_per_visit'; + } + + public function getTranslatedName() + { + return self::getName(); // TODO??? + } + + public function getDependenctMetrics() + { + return array('goals', 'nb_visits'); + } + + public function compute(Row $row) + { + $goalMetrics = $this->getColumn($row, 'goals'); + + $nbVisits = $this->getColumn($row, 'nb_visits'); + $conversions = $this->getColumn($goalMetrics, 'nb_conversions'); + + $goalRevenue = (float) $this->getColumn($goalMetrics, 'revenue'); + + return Piwik::getQuotientSafe($goalRevenue, $nbVisits == 0 ? $conversions : $nbVisits, GoalManager::REVENUE_PRECISION); + } +} \ No newline at end of file diff --git a/plugins/Goals/Metrics/GoalSpecificProcessedMetric.php b/plugins/Goals/Metrics/GoalSpecificProcessedMetric.php new file mode 100644 index 0000000000..e75cec74fa --- /dev/null +++ b/plugins/Goals/Metrics/GoalSpecificProcessedMetric.php @@ -0,0 +1,38 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Piwik; +use Piwik\Plugin\ProcessedMetric; +use Piwik\Tracker\GoalManager; + +/** + * TODO + */ +abstract class GoalSpecificProcessedMetric extends ProcessedMetric +{ + /** + * TODO + */ + protected $idGoal; + + /** + * TODO + */ + public function __construct($idGoal) + { + $this->idGoal = $idGoal; + } + + protected function getColumnPrefix() + { + return 'goal_' . $this->idGoal; + } +} \ No newline at end of file diff --git a/plugins/Goals/Metrics/RevenuePerVisit.php b/plugins/Goals/Metrics/RevenuePerVisit.php new file mode 100644 index 0000000000..d20af74d4e --- /dev/null +++ b/plugins/Goals/Metrics/RevenuePerVisit.php @@ -0,0 +1,64 @@ +<?php +/** + * Piwik - free/libre analytics platform + * + * @link http://piwik.org + * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later + */ +namespace Piwik\Plugins\Goals\Metrics; + +use Piwik\DataTable\Row; +use Piwik\Metrics; +use Piwik\Piwik; +use Piwik\Plugin\ProcessedMetric; +use Piwik\Tracker\GoalManager; + +/** + * TODO + */ +class RevenuePerVisit extends ProcessedMetric +{ + public function getName() + { + return 'revenue_per_visit'; + } + + public function getTranslatedName() + { + return Piwik::translate('General_ColumnValuePerVisit'); + } + + public function getDependenctMetrics() + { + return array('revenue', 'nb_visits', 'nb_conversions','goals'); + } + + public function compute(Row $row) + { + $mappingFromNameToIdGoal = Metrics::getMappingFromNameToIdGoal(); + $goals = $this->getColumn($row, 'goals'); + + $revenue = 0; + foreach ($goals as $goalId => $goalMetrics) { + if ($goalId == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_CART) { + continue; + } + if ($goalId >= GoalManager::IDGOAL_ORDER + || $goalId == Piwik::LABEL_ID_GOAL_IS_ECOMMERCE_ORDER + ) { + $revenue += (int) $this->getColumn($goalMetrics, 'revenue', $mappingFromNameToIdGoal); + } + } + + if ($revenue == 0) { + $revenue = (int) $this->getColumn($row, 'revenue'); + } + + $nbVisits = (int) $this->getColumn($row, 'nb_visits'); + $conversions = (int) $this->getColumn($row, 'nb_conversions'); + + // If no visit for this metric, but some conversions, we still want to display some kind of "revenue per visit" + // even though it will actually be in this edge case "Revenue per conversion" + return Piwik::getQuotientSafe($revenue, $nbVisits == 0 ? $conversions : $nbVisits, GoalManager::REVENUE_PRECISION); + } +} \ No newline at end of file -- GitLab