/** * Adds the processed metrics. See {@link AddColumnsProcessedMetrics} for * more information. * * @param DataTable $table */ public function filter($table) { // 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); 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); if (($this->processOnlyIdGoal > self::GOALS_FULL_TABLE || $this->isEcommerce) && $this->processOnlyIdGoal != $goalId) { continue; } $columnPrefix = 'goal_' . $goalId; $this->addColumn($row, $columnPrefix . '_conversion_rate', function (Row $row) use($metrics, $goalMetrics) { return $metrics->getConversionRate($row, $goalMetrics); }); // 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 $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); }); 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); }); } } } $expectedColumns = array_keys($this->expectedColumns); $rows = $table->getRows(); foreach ($rows as $row) { foreach ($expectedColumns as $name) { if (!$row->hasColumn($name)) { if (strpos($name, 'conversion_rate') !== false) { $row->addColumn($name, function () { return '0%'; }); } else { $row->addColumn($name, 0); } } } } }
/** * Adds the processed metrics. See {@link AddColumnsProcessedMetrics} for * more information. * * @param DataTable $table */ public function filter($table) { // Add standard processed metrics parent::filter($table); $goals = $this->getGoalsInTable($table); if (!empty($this->goalsToProcess)) { $goals = array_unique(array_merge($goals, $this->goalsToProcess)); sort($goals); } $idSite = DataTableFactory::getSiteIdFromMetadata($table); $extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME); $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 != $idGoal) { continue; } $extraProcessedMetrics[] = new ConversionRate($idSite, $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 if ($this->processOnlyIdGoal == self::GOALS_OVERVIEW) { continue; } $extraProcessedMetrics[] = new Conversions($idSite, $idGoal); // PerGoal\Conversions or GoalSpecific\ $extraProcessedMetrics[] = new GoalSpecificRevenuePerVisit($idSite, $idGoal); // PerGoal\Revenue $extraProcessedMetrics[] = new Revenue($idSite, $idGoal); // PerGoal\Revenue if ($this->isEcommerce) { $extraProcessedMetrics[] = new AverageOrderRevenue($idSite, $idGoal); $extraProcessedMetrics[] = new ItemsCount($idSite, $idGoal); } } } $table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics); }
/** * Adds the processed metrics. See {@link AddColumnsProcessedMetrics} for * more information. * * @param DataTable $table */ public function filter($table) { // Add standard processed metrics parent::filter($table); $roundingPrecision = 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, Metrics::INDEX_NB_VISITS); $conversions = (int) $this->getColumn($row, Metrics::INDEX_NB_CONVERSIONS); $goals = $this->getColumn($currentColumns, Metrics::INDEX_GOALS); if ($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($currentColumns, Metrics::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 => $goalMetrics) { $goalId = str_replace("idgoal=", "", $goalId); if (($this->processOnlyIdGoal > self::GOALS_FULL_TABLE || $this->isEcommerce) && $this->processOnlyIdGoal != $goalId) { continue; } $conversions = (int) $this->getColumn($goalMetrics, Metrics::INDEX_GOAL_NB_CONVERSIONS, Metrics::$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($goalMetrics, Metrics::INDEX_GOAL_REVENUE, Metrics::$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($goalMetrics, Metrics::INDEX_GOAL_ECOMMERCE_ITEMS, Metrics::$mappingFromIdToNameGoal); $expectedColumns[$name] = true; } } } // conversion_rate can be defined upstream apparently? FIXME try { $row->addColumns($newColumns); } catch (Exception $e) { } } $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); } } } }