public function filter($table) { // Add standard processed metrics parent::filter($table); $roundingPrecision = Piwik_Tracker_GoalManager::REVENUE_PRECISION; $expectedColumns = array(); foreach ($table->getRows() as $key => $row) { $currentColumns = $row->getColumns(); $newColumns = array(); // visits could be undefined when there is a conversion but no visit $nbVisits = (int) $this->getColumn($row, Piwik_Archive::INDEX_NB_VISITS); $conversions = (int) $this->getColumn($row, Piwik_Archive::INDEX_NB_CONVERSIONS); $goals = $this->getColumn($currentColumns, Piwik_Archive::INDEX_GOALS); if ($goals) { $revenue = 0; foreach ($goals as $goalId => $columnValue) { if ($goalId == Piwik_Archive::LABEL_ECOMMERCE_CART) { continue; } if ($goalId >= Piwik_Tracker_GoalManager::IDGOAL_ORDER || $goalId == Piwik_Archive::LABEL_ECOMMERCE_ORDER) { $revenue += (int) $this->getColumn($columnValue, Piwik_Archive::INDEX_GOAL_REVENUE, Piwik_Archive::$mappingFromIdToNameGoal); } } if ($revenue == 0) { $revenue = (int) $this->getColumn($currentColumns, Piwik_Archive::INDEX_REVENUE); } if (!isset($currentColumns['revenue_per_visit'])) { // 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), $roundingPrecision); } $newColumns['revenue_per_visit'] = $revenuePerVisit; } if ($this->processOnlyIdGoal == self::GOALS_MINIMAL_REPORT) { $row->addColumns($newColumns); continue; } // Display per goal metrics // - conversion rate // - conversions // - revenue per visit foreach ($goals as $goalId => $columnValue) { $goalId = str_replace("idgoal=", "", $goalId); if (($this->processOnlyIdGoal > self::GOALS_FULL_TABLE || $this->isEcommerce) && $this->processOnlyIdGoal != $goalId) { continue; } $conversions = (int) $this->getColumn($columnValue, Piwik_Archive::INDEX_GOAL_NB_CONVERSIONS, Piwik_Archive::$mappingFromIdToNameGoal); // Goal Conversion rate $name = 'goal_' . $goalId . '_conversion_rate'; if ($nbVisits == 0) { $value = $this->invalidDivision; } else { $value = round(100 * $conversions / $nbVisits, $roundingPrecision); } $newColumns[$name] = $value . "%"; $expectedColumns[$name] = true; // When the table is displayed by clicking on the flag icon, we only display the columns // Visits, Conversions, Per goal conversion rate, Revenue if ($this->processOnlyIdGoal == self::GOALS_OVERVIEW) { continue; } // Goal Conversions $name = 'goal_' . $goalId . '_nb_conversions'; $newColumns[$name] = $conversions; $expectedColumns[$name] = true; // Goal Revenue per visit $name = 'goal_' . $goalId . '_revenue_per_visit'; // See comment above for $revenuePerVisit $goalRevenue = (double) $this->getColumn($columnValue, Piwik_Archive::INDEX_GOAL_REVENUE, Piwik_Archive::$mappingFromIdToNameGoal); $revenuePerVisit = round($goalRevenue / ($nbVisits == 0 ? $conversions : $nbVisits), $roundingPrecision); $newColumns[$name] = $revenuePerVisit; $expectedColumns[$name] = true; // Total revenue $name = 'goal_' . $goalId . '_revenue'; $newColumns[$name] = $goalRevenue; $expectedColumns[$name] = true; if ($this->isEcommerce) { // AOV Average Order Value $name = 'goal_' . $goalId . '_avg_order_revenue'; $newColumns[$name] = $goalRevenue / $conversions; $expectedColumns[$name] = true; // Items qty $name = 'goal_' . $goalId . '_items'; $newColumns[$name] = $this->getColumn($columnValue, Piwik_Archive::INDEX_GOAL_ECOMMERCE_ITEMS, Piwik_Archive::$mappingFromIdToNameGoal); $expectedColumns[$name] = true; } } } $row->addColumns($newColumns); } $expectedColumns['revenue_per_visit'] = true; // make sure all goals values are set, 0 by default // if no value then sorting would put at the end $expectedColumns = array_keys($expectedColumns); $rows = $table->getRows(); foreach ($rows as &$row) { foreach ($expectedColumns as $name) { if (false === $row->getColumn($name)) { $value = 0; if (strpos($name, 'conversion_rate') !== false) { $value = '0%'; } $row->addColumn($name, $value); } } } }