Skip to content
Extraits de code Groupes Projets
Valider 1c921c50 rédigé par diosmosis's avatar diosmosis
Parcourir les fichiers

Rewrite AddColumnsProcessedMetricsGoal filter to use processed metrics DataTable metadata.

parent c1264ec0
Aucune branche associée trouvée
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
Affichage de
avec 437 ajouts et 146 suppressions
......@@ -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
......@@ -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;
}
/**
......
......@@ -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,
......
......@@ -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;
......
<?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
<?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
<?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
<?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
<?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
<?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
<?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
<?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
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Terminez d'abord l'édition de ce message.
Veuillez vous inscrire ou vous pour commenter