diff options
author | Matthieu Aubry <matt@piwik.org> | 2015-04-24 06:40:25 +0300 |
---|---|---|
committer | Matthieu Aubry <matt@piwik.org> | 2015-04-24 06:40:25 +0300 |
commit | 1a8351b4942a1e45aa3e65313ec86fe26a94db29 (patch) | |
tree | edd018e4153fd6a76477981a39ae5e90e8194865 /plugins/Goals | |
parent | b3737fa2e10b27cdebd8bfb5b3fba6525cbc2a61 (diff) | |
parent | 232bbf385495960cbf8bec95f0230d5f6578a1fb (diff) |
Merge pull request #7751 from piwik/6986
Archiving of aggregated ecommerce metrics
Diffstat (limited to 'plugins/Goals')
-rw-r--r-- | plugins/Goals/API.php | 75 | ||||
-rw-r--r-- | plugins/Goals/Controller.php | 15 | ||||
-rw-r--r-- | plugins/Goals/DataTable/Filter/AppendNameToColumnNames.php | 57 | ||||
-rw-r--r-- | plugins/Goals/Reports/Get.php | 3 | ||||
-rw-r--r-- | plugins/Goals/Reports/GetMetrics.php | 32 | ||||
-rw-r--r-- | plugins/Goals/tests/Unit/AppendNameToColumnNamesTest.php | 100 |
6 files changed, 268 insertions, 14 deletions
diff --git a/plugins/Goals/API.php b/plugins/Goals/API.php index e4ecb322e5..2cb2366c34 100644 --- a/plugins/Goals/API.php +++ b/plugins/Goals/API.php @@ -9,6 +9,7 @@ namespace Piwik\Plugins\Goals; use Exception; +use Piwik\API\Request; use Piwik\Archive; use Piwik\CacheId; use Piwik\Cache as PiwikCache; @@ -18,11 +19,14 @@ use Piwik\Db; use Piwik\Metrics; use Piwik\Piwik; use Piwik\Plugin\Report; +use Piwik\Plugins\API\DataTable\MergeDataTables; use Piwik\Plugins\CoreHome\Columns\Metrics\ConversionRate; use Piwik\Plugins\Goals\Columns\Metrics\AverageOrderRevenue; +use Piwik\Segment\SegmentExpression; use Piwik\Site; use Piwik\Tracker\Cache; use Piwik\Tracker\GoalManager; +use Piwik\Plugins\VisitFrequency\API as VisitFrequencyAPI; /** * Goals API lets you Manage existing goals, via "updateGoal" and "deleteGoal", create new Goals via "addGoal", @@ -327,7 +331,7 @@ class API extends \Piwik\Plugin\API } /** - * Returns Goals data + * Returns Goals data. * * @param int $idSite * @param string $period @@ -340,6 +344,55 @@ class API extends \Piwik\Plugin\API public function get($idSite, $period, $date, $segment = false, $idGoal = false, $columns = array()) { Piwik::checkUserHasViewAccess($idSite); + + /** @var DataTable|DataTable\Map $table */ + $table = null; + + $segments = array( + '' => false, + '_new_visit' => 'visitorType%3D%3Dnew', // visitorType==new + '_returning_visit' => VisitFrequencyAPI::RETURNING_VISITOR_SEGMENT + ); + + foreach ($segments as $appendToMetricName => $predefinedSegment) { + $segmentToUse = $this->appendSegment($predefinedSegment, $segment); + + /** @var DataTable|DataTable\Map $tableSegmented */ + $tableSegmented = Request::processRequest('Goals.getMetrics', array( + 'segment' => $segmentToUse, + 'idSite' => $idSite, + 'period' => $period, + 'date' => $date, + 'idGoal' => $idGoal, + 'columns' => $columns, + 'serialize' => '0' + )); + + $tableSegmented->filter('Piwik\Plugins\Goals\DataTable\Filter\AppendNameToColumnNames', + array($appendToMetricName)); + + if (!isset($table)) { + $table = $tableSegmented; + } else { + $merger = new MergeDataTables(); + $merger->mergeDataTables($table, $tableSegmented); + } + } + + return $table; + } + + /** + * Similar to {@link get()} but does not return any metrics for new and returning visitors. It won't apply + * any segment by default. This method is deprecated from the API as it is only there to make the implementation of + * the actual {@link get()} method easy. + * + * @deprecated + * @internal + */ + public function getMetrics($idSite, $period, $date, $segment = false, $idGoal = false, $columns = array()) + { + Piwik::checkUserHasViewAccess($idSite); $archive = Archive::build($idSite, $period, $date, $segment); // Mapping string idGoal to internal ID @@ -349,7 +402,7 @@ class API extends \Piwik\Plugin\API $allMetrics = Goals::getGoalColumns($idGoal); $requestedColumns = Piwik::getArrayFromApiParameter($columns); - $report = Report::factory("Goals", "get"); + $report = Report::factory('Goals', 'getMetrics'); $columnsToGet = $report->getMetricsRequiredForReport($allMetrics, $requestedColumns); $inDbMetricNames = array_map(function ($name) use ($idGoal) { @@ -368,7 +421,7 @@ class API extends \Piwik\Plugin\API // it's not in ProcessedReport.php). more refactoring must be done to report class before this can be // corrected. if ((in_array('avg_order_revenue', $requestedColumns) - || empty($requestedColumns)) + || empty($requestedColumns)) && $isEcommerceGoal ) { $dataTable->filter(function (DataTable $table) { @@ -391,6 +444,22 @@ class API extends \Piwik\Plugin\API return $dataTable; } + protected function appendSegment($segment, $segmentToAppend) + { + if (empty($segment)) { + return $segmentToAppend; + } + + if (empty($segmentToAppend)) { + return $segment; + } + + $segment .= urlencode(SegmentExpression::AND_DELIMITER); + $segment .= $segmentToAppend; + + return $segment; + } + protected function getNumeric($idSite, $period, $date, $segment, $toFetch) { Piwik::checkUserHasViewAccess($idSite); diff --git a/plugins/Goals/Controller.php b/plugins/Goals/Controller.php index 356a4aafcc..f7775262a3 100644 --- a/plugins/Goals/Controller.php +++ b/plugins/Goals/Controller.php @@ -48,13 +48,13 @@ class Controller extends \Piwik\Plugin\Controller */ private $translator; - private function formatConversionRate($conversionRate) + private function formatConversionRate($conversionRate, $columnName = 'conversion_rate') { if ($conversionRate instanceof DataTable) { if ($conversionRate->getRowsCount() == 0) { $conversionRate = 0; } else { - $conversionRate = $conversionRate->getFirstRow()->getColumn('conversion_rate'); + $conversionRate = $conversionRate->getFirstRow()->getColumn($columnName); } } @@ -128,14 +128,11 @@ class Controller extends \Piwik\Plugin\Controller $view->nameGraphEvolution = 'Goals.getEvolutionGraph' . $idGoal; $view->topDimensions = $this->getTopDimensions($idGoal); - // conversion rate for new and returning visitors - $segment = urldecode(\Piwik\Plugins\VisitFrequency\API::RETURNING_VISITOR_SEGMENT); - $conversionRateReturning = Request::processRequest("Goals.get", array('segment' => $segment, 'idGoal' => $idGoal)); - $view->conversion_rate_returning = $this->formatConversionRate($conversionRateReturning); + $goalMetrics = Request::processRequest('Goals.get', array('idGoal' => $idGoal)); - $segment = 'visitorType==new'; - $conversionRateNew = Request::processRequest("Goals.get", array('segment' => $segment, 'idGoal' => $idGoal)); - $view->conversion_rate_new = $this->formatConversionRate($conversionRateNew); + // conversion rate for new and returning visitors + $view->conversion_rate_returning = $this->formatConversionRate($goalMetrics, 'conversion_rate_returning_visit'); + $view->conversion_rate_new = $this->formatConversionRate($goalMetrics, 'conversion_rate_new_visit'); $view->goalReportsByDimension = $this->getGoalReportsByDimensionTable( $view->nb_conversions, isset($ecommerce), !empty($view->cart_nb_conversions)); diff --git a/plugins/Goals/DataTable/Filter/AppendNameToColumnNames.php b/plugins/Goals/DataTable/Filter/AppendNameToColumnNames.php new file mode 100644 index 0000000000..70c2542892 --- /dev/null +++ b/plugins/Goals/DataTable/Filter/AppendNameToColumnNames.php @@ -0,0 +1,57 @@ +<?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\DataTable\Filter; + +use Piwik\DataTable\BaseFilter; +use Piwik\DataTable; +use Piwik\Metrics; + +/** + * Appends a string to each column name in each row of a table. Please note this filter even appends the name to a + * 'label' column. If you do not need this behaviour feel free to add a check to ignore label columns. + */ +class AppendNameToColumnNames extends BaseFilter +{ + protected $nameToAppend; + + /** + * Constructor. + * + * @param DataTable $table The table that will be eventually filtered. + * @param string $nameToAppend The name that will be appended to each column + */ + public function __construct($table, $nameToAppend) + { + parent::__construct($table); + $this->nameToAppend = $nameToAppend; + } + + /** + * See {@link ReplaceColumnNames}. + * + * @param DataTable $table + */ + public function filter($table) + { + if (!isset($this->nameToAppend) || '' === $this->nameToAppend || false === $this->nameToAppend) { + return; + } + + foreach ($table->getRows() as $row) { + $columns = $row->getColumns(); + + foreach ($columns as $column => $value) { + $row->deleteColumn($column); + $row->setColumn($column . $this->nameToAppend, $value); + } + + $this->filterSubTable($row); + } + } +} diff --git a/plugins/Goals/Reports/Get.php b/plugins/Goals/Reports/Get.php index 163d9fe236..bccecda146 100644 --- a/plugins/Goals/Reports/Get.php +++ b/plugins/Goals/Reports/Get.php @@ -9,7 +9,6 @@ namespace Piwik\Plugins\Goals\Reports; use Piwik\Piwik; -use Piwik\Plugins\CoreHome\Columns\Metrics\ConversionRate; class Get extends Base { @@ -18,7 +17,7 @@ class Get extends Base parent::init(); $this->name = Piwik::translate('Goals_Goals'); - $this->processedMetrics = array(new ConversionRate()); + $this->processedMetrics = array('conversion_rate'); $this->documentation = ''; // TODO $this->order = 1; $this->orderGoal = 50; diff --git a/plugins/Goals/Reports/GetMetrics.php b/plugins/Goals/Reports/GetMetrics.php new file mode 100644 index 0000000000..a2104823db --- /dev/null +++ b/plugins/Goals/Reports/GetMetrics.php @@ -0,0 +1,32 @@ +<?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\Reports; + +use Piwik\Piwik; +use Piwik\Plugins\CoreHome\Columns\Metrics\ConversionRate; + +class GetMetrics extends Base +{ + protected function init() + { + parent::init(); + + $this->name = Piwik::translate('Goals_Goals'); + $this->processedMetrics = array(new ConversionRate()); + $this->documentation = ''; // TODO + $this->order = 1; + $this->orderGoal = 50; + $this->metrics = array( 'nb_conversions', 'nb_visits_converted', 'revenue'); + $this->parameters = null; + } + + public function configureReportMetadata(&$availableReports, $infos) + { + } +} diff --git a/plugins/Goals/tests/Unit/AppendNameToColumnNamesTest.php b/plugins/Goals/tests/Unit/AppendNameToColumnNamesTest.php new file mode 100644 index 0000000000..b409ae1fbb --- /dev/null +++ b/plugins/Goals/tests/Unit/AppendNameToColumnNamesTest.php @@ -0,0 +1,100 @@ +<?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\tests\Unit; + +use Piwik\DataTable; +use Piwik\DataTable\Row; +use Piwik\Tests\Framework\TestCase\UnitTestCase; + +/** + * @group AppendNameToColumnNamesTest + * @group AppendNameToColumnNames + * @group DataTable + * @group Filter + * @group Goals + */ +class AppendNameToColumnNamesTest extends UnitTestCase +{ + private $filter = 'Piwik\Plugins\Goals\DataTable\Filter\AppendNameToColumnNames'; + + /** + * @var DataTable + */ + private $table; + + public function setUp() + { + $this->table = new DataTable\Simple(); + $this->addRow(array('nb_visits' => 1, 'nb_conversions' => 5, 'revenue' => 10, 'conversion_rate' => 20)); + } + + private function addRow($columns) + { + $this->table->addRow($this->buildRow($columns)); + } + + private function buildRow($columns) + { + return new Row(array(Row::COLUMNS => $columns)); + } + + public function test_filter_shouldNotAppendAnything_IfNameToReplaceIsEmpty() + { + $columnNamesBefore = array('nb_visits', 'nb_conversions', 'revenue', 'conversion_rate'); + + $this->table->filter($this->filter, array('')); + $this->table->filter($this->filter, array(null)); + $this->table->filter($this->filter, array(false)); + + $columnNamesAfter = array_keys($this->table->getFirstRow()->getColumns()); + $this->assertSame($columnNamesBefore, $columnNamesAfter); + } + + public function test_filter_shoulAppendGivenStringToAllColumns_IfSet() + { + $nameToAppend = '_new_visit'; + $this->table->filter($this->filter, array($nameToAppend)); + + $expected = array( + 'nb_visits' . $nameToAppend => 1, + 'nb_conversions' . $nameToAppend => 5, + 'revenue' . $nameToAppend => 10, + 'conversion_rate' . $nameToAppend => 20 + ); + + $this->assertColumnsOfRowIdEquals($expected, $rowId = 0); + } + + public function test_filter_shoulAppendGivenStringToAllColumnsOfAllRows_EvenIfTheyHaveDifferentColumns() + { + $this->addRow(array('nb_visits' => 49)); + + $nameToAppend = '_new_visit'; + $this->table->filter($this->filter, array($nameToAppend)); + + $expectedRow1 = array( + 'nb_visits' . $nameToAppend => 1, + 'nb_conversions' . $nameToAppend => 5, + 'revenue' . $nameToAppend => 10, + 'conversion_rate' . $nameToAppend => 20 + ); + + $expectedRow2 = array( + 'nb_visits' . $nameToAppend => 49, + ); + + $this->assertColumnsOfRowIdEquals($expectedRow1, $rowId = 0); + $this->assertColumnsOfRowIdEquals($expectedRow2, $rowId = 1); + } + + private function assertColumnsOfRowIdEquals($expectedColumns, $rowId) + { + $this->assertSame($expectedColumns, $this->table->getRowFromId($rowId)->getColumns()); + } +}
\ No newline at end of file |