Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/matomo-org/matomo.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKate Butler <kate@innocraft.com>2019-12-17 00:15:11 +0300
committerThomas Steur <tsteur@users.noreply.github.com>2019-12-17 00:15:11 +0300
commit72eece3fbbb9df81f941a4cdbe83a928679daa18 (patch)
tree7d6e7c0cc0f81512891de2ab691a5c07cfdab45b /plugins/VisitFrequency
parent76102d2c9b21cd7317ed9d4e6ea7879f83b01474 (diff)
Show 'new' metrics on visitor engagement report/sparklines (#15128)
Diffstat (limited to 'plugins/VisitFrequency')
-rw-r--r--plugins/VisitFrequency/API.php82
-rw-r--r--plugins/VisitFrequency/Columns/Metrics/ReturningMetric.php12
-rw-r--r--plugins/VisitFrequency/Controller.php38
-rw-r--r--plugins/VisitFrequency/Reports/Get.php45
-rw-r--r--plugins/VisitFrequency/VisitFrequency.php10
-rw-r--r--plugins/VisitFrequency/lang/en.json12
-rw-r--r--plugins/VisitFrequency/tests/Integration/APITest.php84
7 files changed, 224 insertions, 59 deletions
diff --git a/plugins/VisitFrequency/API.php b/plugins/VisitFrequency/API.php
index 9ecb6b4157..e4155b28ff 100644
--- a/plugins/VisitFrequency/API.php
+++ b/plugins/VisitFrequency/API.php
@@ -12,6 +12,7 @@ use Piwik\API\Request;
use Piwik\Archive;
use Piwik\DataTable;
use Piwik\Piwik;
+use Piwik\Plugins\API\DataTable\MergeDataTables;
use Piwik\Plugins\VisitsSummary\API as APIVisitsSummary;
use Piwik\Segment\SegmentExpression;
@@ -23,7 +24,10 @@ class API extends \Piwik\Plugin\API
{
// visitorType==returning,visitorType==returningCustomer
const RETURNING_VISITOR_SEGMENT = "visitorType%3D%3Dreturning%2CvisitorType%3D%3DreturningCustomer";
- const COLUMN_SUFFIX = "_returning";
+ const RETURNING_COLUMN_SUFFIX = "_returning";
+
+ const NEW_VISITOR_SEGMENT = 'visitorType%3D%3Dnew';
+ const NEW_COLUMN_SUFFIX = "_new";
/**
* @param int $idSite
@@ -36,48 +40,80 @@ class API extends \Piwik\Plugin\API
public function get($idSite, $period, $date, $segment = false, $columns = false)
{
Piwik::checkUserHasViewAccess($idSite);
- $segment = $this->appendReturningVisitorSegment($segment);
-
- $this->unprefixColumns($columns);
- $params = array(
- 'idSite' => $idSite,
- 'period' => $period,
- 'date' => $date,
- 'segment' => $segment,
- 'columns' => implode(',', $columns),
- 'format' => 'original',
- 'format_metrics' => 0
+
+ $visitTypes = array(
+ self::NEW_COLUMN_SUFFIX => self::NEW_VISITOR_SEGMENT,
+ self::RETURNING_COLUMN_SUFFIX => self::RETURNING_VISITOR_SEGMENT
);
- $table = Request::processRequest('VisitsSummary.get', $params);
- $this->prefixColumns($table, $period);
- return $table;
+ $columns = Piwik::getArrayFromApiParameter($columns);
+
+ /** @var \Piwik\DataTable\DataTableInterface $resultSet */
+ $resultSet = new DataTable();
+
+ foreach ($visitTypes as $columnSuffix => $visitorTypeSegment) {
+ $modifiedSegment = $this->appendVisitorTypeSegment($segment, $visitorTypeSegment);
+
+ $columnsForVisitType = empty($columns) ? array() : $this->unprefixColumns($columns, $columnSuffix);
+
+ // Only make the API call if either $columns is empty (i.e. no list of columns was passed in, so we
+ // should fetch all columns) or if one of the columns that was passed in is for this visitor type
+ if (!empty($columns) && empty($columnsForVisitType)) {
+ continue;
+ }
+
+ $params = array(
+ 'idSite' => $idSite,
+ 'period' => $period,
+ 'date' => $date,
+ 'segment' => $modifiedSegment,
+ 'columns' => implode(',', $columnsForVisitType),
+ 'format' => 'original',
+ 'format_metrics' => 0
+ );
+
+ /** @var \Piwik\DataTable\Map $response */
+ $response = Request::processRequest('VisitsSummary.get', $params);
+ $this->prefixColumns($response, $period, $columnSuffix);
+
+ if ($resultSet === null) {
+ $resultSet = $response;
+ } else {
+ $merger = new MergeDataTables();
+ $merger->mergeDataTables($resultSet, $response);
+ }
+ }
+
+ return $resultSet;
}
- protected function appendReturningVisitorSegment($segment)
+ protected function appendVisitorTypeSegment($segment, $toAppend)
{
if (empty($segment)) {
$segment = '';
} else {
$segment .= urlencode(SegmentExpression::AND_DELIMITER);
}
- $segment .= self::RETURNING_VISITOR_SEGMENT;
+ $segment .= $toAppend;
return $segment;
}
- protected function unprefixColumns(&$columns)
+ protected function unprefixColumns(array $requestedColumns, $suffix)
{
- $columns = Piwik::getArrayFromApiParameter($columns);
- foreach ($columns as &$column) {
- $column = str_replace(self::COLUMN_SUFFIX, "", $column);
+ $result = array();
+ foreach ($requestedColumns as $column) {
+ if (strpos($column, $suffix) !== false) {
+ $result[] = str_replace($suffix, '', $column);
+ }
}
+ return $result;
}
- protected function prefixColumns($table, $period)
+ protected function prefixColumns($table, $period, $suffix)
{
$rename = array();
foreach (APIVisitsSummary::getInstance()->getColumns($period) as $oldColumn) {
- $rename[$oldColumn] = $oldColumn . self::COLUMN_SUFFIX;
+ $rename[$oldColumn] = $oldColumn . $suffix;
}
$table->filter('ReplaceColumnNames', array($rename));
}
diff --git a/plugins/VisitFrequency/Columns/Metrics/ReturningMetric.php b/plugins/VisitFrequency/Columns/Metrics/ReturningMetric.php
index e0ebe49738..8c1806f9f6 100644
--- a/plugins/VisitFrequency/Columns/Metrics/ReturningMetric.php
+++ b/plugins/VisitFrequency/Columns/Metrics/ReturningMetric.php
@@ -23,8 +23,13 @@ class ReturningMetric extends ProcessedMetric
{
private static $translations = array(
'avg_time_on_site_returning' => 'VisitFrequency_ColumnAverageVisitDurationForReturningVisitors',
+ 'avg_time_on_site_new' => 'VisitFrequency_ColumnAverageVisitDurationForNewVisitors',
'nb_actions_per_visit_returning' => 'VisitFrequency_ColumnAvgActionsPerReturningVisit',
+ 'nb_actions_per_visit_new' => 'VisitFrequency_ColumnAvgActionsPerNewVisit',
'bounce_rate_returning' => 'VisitFrequency_ColumnBounceRateForReturningVisits',
+ 'bounce_rate_new' => 'VisitFrequency_ColumnBounceRateForNewVisits',
+ 'nb_users_returning' => 'VisitFrequency_ColumnReturningUsers',
+ 'nb_users_new' => 'VisitFrequency_ColumnNewUsers'
);
/**
@@ -32,14 +37,17 @@ class ReturningMetric extends ProcessedMetric
*/
private $wrapped;
- public function __construct(ProcessedMetric $wrapped)
+ private $suffix;
+
+ public function __construct(ProcessedMetric $wrapped, $suffix = '_returning')
{
$this->wrapped = $wrapped;
+ $this->suffix = $suffix;
}
public function getName()
{
- return $this->wrapped->getName() . '_returning';
+ return $this->wrapped->getName() . $this->suffix;
}
public function getTranslatedName()
diff --git a/plugins/VisitFrequency/Controller.php b/plugins/VisitFrequency/Controller.php
index 479a91da5b..b4d7c4f88d 100644
--- a/plugins/VisitFrequency/Controller.php
+++ b/plugins/VisitFrequency/Controller.php
@@ -52,32 +52,24 @@ class Controller extends \Piwik\Plugin\Controller
. $this->translator->translate('General_BrokenDownReportDocumentation') . '<br />'
. $this->translator->translate('VisitFrequency_ReturningVisitDocumentation');
- // Note: if you edit this array, maybe edit the code below as well
- $selectableColumns = array(
- // columns from VisitFrequency.get
- 'nb_visits_returning',
- 'nb_actions_returning',
- 'nb_actions_per_visit_returning',
- 'bounce_rate_returning',
- 'avg_time_on_site_returning',
- // columns from VisitsSummary.get
- 'nb_visits',
- 'nb_actions',
- 'nb_actions_per_visit',
- 'bounce_rate',
- 'avg_time_on_site'
- );
-
$period = Common::getRequestVar('period', false);
+ $columnNames = array('nb_visits');
if (SettingsPiwik::isUniqueVisitorsEnabled($period)) {
- // add number of unique (returning) visitors for period=day
- $selectableColumns = array_merge(
- array($selectableColumns[0]),
- array('nb_uniq_visitors_returning'),
- array_slice($selectableColumns, 1, -4),
- array('nb_uniq_visitors'),
- array_slice($selectableColumns, -4));
+ $columnNames[] = 'nb_uniq_visitors';
+ }
+ $columnNames[] = 'nb_actions';
+ $columnNames[] = 'nb_actions_per_visit';
+ $columnNames[] = 'bounce_rate';
+ $columnNames[] = 'avg_time_on_site';
+
+ $suffixes = array('_returning', '_new', '');
+
+ $selectableColumns = array();
+ foreach ($suffixes as $suffix) {
+ foreach ($columnNames as $column) {
+ $selectableColumns[] = $column . $suffix;
+ }
}
$view = $this->getLastUnitGraphAcrossPlugins($this->pluginName, __FUNCTION__, $columns,
diff --git a/plugins/VisitFrequency/Reports/Get.php b/plugins/VisitFrequency/Reports/Get.php
index 97d671e5d5..0599e1cb41 100644
--- a/plugins/VisitFrequency/Reports/Get.php
+++ b/plugins/VisitFrequency/Reports/Get.php
@@ -17,6 +17,7 @@ use Piwik\Plugins\CoreHome\Columns\Metrics\AverageTimeOnSite;
use Piwik\Plugins\CoreHome\Columns\Metrics\BounceRate;
use Piwik\Plugins\CoreVisualizations\Visualizations\JqplotGraph\Evolution;
use Piwik\Plugins\CoreVisualizations\Visualizations\Sparklines;
+use Piwik\Plugins\VisitFrequency\API;
use Piwik\Plugins\VisitFrequency\Columns\Metrics\ReturningMetric;
use Piwik\Report\ReportWidgetFactory;
use Piwik\Widget\WidgetsList;
@@ -30,16 +31,25 @@ class Get extends \Piwik\Plugin\Report
$this->name = Piwik::translate('VisitFrequency_ColumnReturningVisits');
$this->documentation = ''; // TODO
$this->processedMetrics = array(
- new ReturningMetric(new AverageTimeOnSite()),
- new ReturningMetric(new ActionsPerVisit()),
- new ReturningMetric(new BounceRate())
+ new ReturningMetric(new AverageTimeOnSite(), API::RETURNING_COLUMN_SUFFIX),
+ new ReturningMetric(new ActionsPerVisit(), API::RETURNING_COLUMN_SUFFIX),
+ new ReturningMetric(new BounceRate(), API::RETURNING_COLUMN_SUFFIX),
+ new ReturningMetric(new AverageTimeOnSite(), API::NEW_COLUMN_SUFFIX),
+ new ReturningMetric(new ActionsPerVisit(), API::NEW_COLUMN_SUFFIX),
+ new ReturningMetric(new BounceRate(), API::NEW_COLUMN_SUFFIX)
);
$this->metrics = array(
'nb_visits_returning',
'nb_actions_returning',
'nb_uniq_visitors_returning',
'nb_users_returning',
- 'max_actions_returning'
+ 'max_actions_returning',
+
+ 'nb_visits_new',
+ 'nb_actions_new',
+ 'nb_uniq_visitors_new',
+ 'nb_users_new',
+ 'max_actions_new',
);
$this->order = 40;
$this->subcategoryId = 'VisitorInterest_Engagement';
@@ -106,6 +116,12 @@ class Get extends \Piwik\Plugin\Report
'nb_actions_per_visit_returning' => 'ReturnAvgActions',
'avg_time_on_site_returning' => 'ReturnAverageVisitDuration',
'bounce_rate_returning' => 'ReturnBounceRate',
+
+ 'nb_visits_new' => 'NewVisits',
+ 'nb_actions_new' => 'NewActions',
+ 'nb_actions_per_visit_new' => 'NewAvgActions',
+ 'avg_time_on_site_new' => 'NewAverageVisitDuration',
+ 'bounce_rate_new' => 'NewBounceRate',
);
foreach ($translations as $metric => $key) {
@@ -117,11 +133,20 @@ class Get extends \Piwik\Plugin\Report
private function addSparklineColumns(Sparklines $view)
{
- $view->config->addSparklineMetric(array('nb_visits_returning'));
- $view->config->addSparklineMetric(array('avg_time_on_site_returning'));
- $view->config->addSparklineMetric(array('nb_actions_per_visit_returning'));
- $view->config->addSparklineMetric(array('bounce_rate_returning'));
- $view->config->addSparklineMetric(array('nb_actions_returning'));
- }
+ $metrics = array(
+ 'nb_visits',
+ 'avg_time_on_site',
+ 'nb_actions_per_visit',
+ 'bounce_rate',
+ 'nb_actions'
+ );
+ $i = 1;
+ foreach ($metrics as $metric) {
+ foreach (array('_returning', '_new') as $suffix) {
+ $view->config->addSparklineMetric(array($metric . $suffix), $i++);
+ }
+ }
+
+ }
}
diff --git a/plugins/VisitFrequency/VisitFrequency.php b/plugins/VisitFrequency/VisitFrequency.php
index f6f5ccbcd0..9e64e5a08d 100644
--- a/plugins/VisitFrequency/VisitFrequency.php
+++ b/plugins/VisitFrequency/VisitFrequency.php
@@ -32,7 +32,15 @@ class VisitFrequency extends \Piwik\Plugin
'bounce_rate_returning' => 'VisitFrequency_ColumnBounceRateForReturningVisits',
'nb_actions_per_visit_returning' => 'VisitFrequency_ColumnAvgActionsPerReturningVisit',
'nb_uniq_visitors_returning' => 'VisitFrequency_ColumnUniqueReturningVisitors',
- 'nb_users_returning' => 'VisitFrequency_ColumnReturningUsers'
+ 'nb_users_returning' => 'VisitFrequency_ColumnReturningUsers',
+
+ 'nb_visits_new' => 'VisitFrequency_ColumnNewVisits',
+ 'nb_actions_new' => 'VisitFrequency_ColumnActionsByNewVisits',
+ 'avg_time_on_site_new' => 'VisitFrequency_ColumnAverageVisitDurationForNewVisitors',
+ 'bounce_rate_new' => 'VisitFrequency_ColumnBounceRateForNewVisits',
+ 'nb_actions_per_visit_new' => 'VisitFrequency_ColumnAvgActionsPerNewVisit',
+ 'nb_uniq_visitors_new' => 'VisitFrequency_ColumnUniqueNewVisitors',
+ 'nb_users_new' => 'VisitFrequency_ColumnNewUsers'
);
$translations = array_merge($translations, $metrics);
diff --git a/plugins/VisitFrequency/lang/en.json b/plugins/VisitFrequency/lang/en.json
index 39b1879852..6cdd0764cf 100644
--- a/plugins/VisitFrequency/lang/en.json
+++ b/plugins/VisitFrequency/lang/en.json
@@ -1,16 +1,28 @@
{
"VisitFrequency": {
+ "ColumnActionsByNewVisits": "Actions by New Visits",
"ColumnActionsByReturningVisits": "Actions by Returning Visits",
+ "ColumnAverageVisitDurationForNewVisitors": "Avg. Duration of a New Visit (in sec)",
"ColumnAverageVisitDurationForReturningVisitors": "Avg. Duration of a Returning Visit (in sec)",
+ "ColumnAvgActionsPerNewVisit": "Avg. Actions per New Visit",
"ColumnAvgActionsPerReturningVisit": "Avg. Actions per Returning Visit",
"ColumnBounceCountForReturningVisits": "Bounce Count for Returning Visits",
+ "ColumnBounceRateForNewVisits": "Bounce Rate for New Visits",
"ColumnBounceRateForReturningVisits": "Bounce Rate for Returning Visits",
"ColumnMaxActionsInReturningVisit": "Maximum actions in one returning visit",
"ColumnNbReturningVisitsConverted": "Number of converted returning visits",
+ "ColumnNewVisits": "New Visits",
"ColumnReturningVisits": "Returning Visits",
"ColumnSumVisitLengthReturning": "Total time spent by returning visitors (in seconds)",
+ "ColumnUniqueNewVisitors": "Unique new visitors",
"ColumnUniqueReturningVisitors": "Unique returning visitors",
+ "ColumnNewUsers": "New Users",
"ColumnReturningUsers": "Returning Users",
+ "NewActions": "actions by the new visits",
+ "NewAverageVisitDuration": "average visit duration for new visitors",
+ "NewAvgActions": "actions per new visit",
+ "NewBounceRate": "new visits have bounced (left the website after one page)",
+ "NewVisits": "new visits",
"PluginDescription": "Reports metrics about your first time new visitors and returning visitors.",
"ReturnActions": "actions by the returning visits",
"ReturnAverageVisitDuration": "average visit duration for returning visitors",
diff --git a/plugins/VisitFrequency/tests/Integration/APITest.php b/plugins/VisitFrequency/tests/Integration/APITest.php
new file mode 100644
index 0000000000..dfba727d4f
--- /dev/null
+++ b/plugins/VisitFrequency/tests/Integration/APITest.php
@@ -0,0 +1,84 @@
+<?php
+/**
+ * Matomo - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Plugins\VisitFrequency\tests;
+
+use Piwik\DataTable\DataTableInterface;
+use Piwik\Plugins\VisitFrequency\API;
+use Piwik\Tests\Framework\Fixture;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+
+class APITest extends IntegrationTestCase
+{
+ private $api;
+
+ private $idSite;
+
+ public function setUp()
+ {
+ parent::setUp();
+ $this->api = API::getInstance();
+
+ $this->idSite = Fixture::createWebsite('2018-12-01');
+ }
+
+ public function testNewMetricsOnly()
+ {
+ $columns = array('nb_visits_new', 'nb_actions_new');
+
+ /** @var DataTableInterface $dataTable */
+ $dataTable = $this->api->get($this->idSite, 'week', '2019-01-01', false, $columns);
+ $this->assertEquals($dataTable->getRowsCount(), 1);
+ $columnsReturned = array_keys($dataTable->getFirstRow()->getArrayCopy());
+
+ $this->assertEquals($columns, $columnsReturned);
+ }
+
+ public function testReturningMetricsOnly()
+ {
+ $columns = array('nb_visits_returning', 'nb_uniq_visitors_returning');
+
+ /** @var DataTableInterface $dataTable */
+ $dataTable = $this->api->get($this->idSite, 'week', '2019-01-01', false, $columns);
+ $this->assertEquals($dataTable->getRowsCount(), 1);
+ $columnsReturned = array_keys($dataTable->getFirstRow()->getArrayCopy());
+
+ $this->assertEquals($columns, $columnsReturned);
+ }
+
+ public function testNoNewOrReturningMetrics()
+ {
+ $columns = array('nb_visits');
+
+ /** @var DataTableInterface $dataTable */
+ $dataTable = $this->api->get($this->idSite, 'week', '2019-01-01', false, $columns);
+ $this->assertEquals($dataTable->getRowsCount(), 0);
+ }
+
+ public function testDifferentNewAndReturningMetrics()
+ {
+ $columns = array('nb_visits_new', 'nb_actions_per_visit_new', 'nb_actions_returning', 'avg_time_on_site_returning');
+
+ /** @var DataTableInterface $dataTable */
+ $dataTable = $this->api->get($this->idSite, 'week', '2019-01-01', false, $columns);
+ $this->assertEquals($dataTable->getRowsCount(), 1);
+ $columnsReturned = array_keys($dataTable->getFirstRow()->getArrayCopy());
+
+ $this->assertEquals($columns, $columnsReturned);
+ }
+
+ public function testNoColumnsPassed()
+ {
+ /** @var DataTableInterface $dataTable */
+ $dataTable = $this->api->get($this->idSite, 'week', '2019-01-01');
+ $this->assertEquals($dataTable->getRowsCount(), 1);
+ $columnsReturned = array_keys($dataTable->getFirstRow()->getArrayCopy());
+
+ $this->assertCount(22, $columnsReturned);
+ }
+} \ No newline at end of file