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

Fixes #4878, use pre-piwik 2 data in VisitFrequency API if post-piwik 2 data...

Fixes #4878, use pre-piwik 2 data in VisitFrequency API if post-piwik 2 data cannot be found. Commit includes commented out tests for changes.
parent 12d78a18
Branches
Aucune étiquette associée trouvée
Aucune requête de fusion associée trouvée
...@@ -554,7 +554,6 @@ class Archive ...@@ -554,7 +554,6 @@ class Archive
// cache id archives for plugins we haven't processed yet // cache id archives for plugins we haven't processed yet
if (!empty($archiveGroups)) { if (!empty($archiveGroups)) {
if (!Rules::isArchivingDisabledFor($this->params->getIdSites(), $this->params->getSegment(), $this->getPeriodLabel())) { if (!Rules::isArchivingDisabledFor($this->params->getIdSites(), $this->params->getSegment(), $this->getPeriodLabel())) {
$this->cacheArchiveIdsAfterLaunching($archiveGroups, $plugins); $this->cacheArchiveIdsAfterLaunching($archiveGroups, $plugins);
} else { } else {
$this->cacheArchiveIdsWithoutLaunching($plugins); $this->cacheArchiveIdsWithoutLaunching($plugins);
...@@ -769,13 +768,16 @@ class Archive ...@@ -769,13 +768,16 @@ class Archive
} // Goal_* metrics are processed by the Goals plugin (HACK) } // Goal_* metrics are processed by the Goals plugin (HACK)
else if (strpos($report, 'Goal_') === 0) { else if (strpos($report, 'Goal_') === 0) {
$report = 'Goals_Metrics'; $report = 'Goals_Metrics';
} else if (strrpos($report, '_returning') === strlen($report) - strlen('_returning')) { // HACK
$report = 'VisitFrequency_Metrics';
} }
$plugin = substr($report, 0, strpos($report, '_')); $plugin = substr($report, 0, strpos($report, '_'));
if (empty($plugin) if (empty($plugin)
|| !\Piwik\Plugin\Manager::getInstance()->isPluginActivated($plugin) || !\Piwik\Plugin\Manager::getInstance()->isPluginActivated($plugin)
) { ) {
throw new \Exception("Error: The report '$report' was requested but it is not available at this stage. "); throw new \Exception("Error: The report '$report' was requested but it is not available at this stage."
. " (Plugin '$plugin' is not activated.)");
} }
return $plugin; return $plugin;
} }
......
...@@ -10,6 +10,8 @@ namespace Piwik\Plugins\VisitFrequency; ...@@ -10,6 +10,8 @@ namespace Piwik\Plugins\VisitFrequency;
use Piwik\API\Request; use Piwik\API\Request;
use Piwik\Piwik; use Piwik\Piwik;
use Piwik\Common;
use Piwik\Archive;
use Piwik\Plugins\VisitsSummary\API as APIVisitsSummary; use Piwik\Plugins\VisitsSummary\API as APIVisitsSummary;
use Piwik\SegmentExpression; use Piwik\SegmentExpression;
...@@ -33,23 +35,144 @@ class API extends \Piwik\Plugin\API ...@@ -33,23 +35,144 @@ class API extends \Piwik\Plugin\API
*/ */
public function get($idSite, $period, $date, $segment = false, $columns = false) public function get($idSite, $period, $date, $segment = false, $columns = false)
{ {
$segment = $this->appendReturningVisitorSegment($segment); $newSegment = $this->appendReturningVisitorSegment($segment);
$this->unprefixColumns($columns); $this->unsuffixColumns($columns);
$params = array( $params = array(
'idSite' => $idSite, 'idSite' => $idSite,
'period' => $period, 'period' => $period,
'date' => $date, 'date' => $date,
'segment' => $segment, 'segment' => $newSegment,
'columns' => implode(',', $columns), 'columns' => implode(',', $columns),
'format' => 'original', 'format' => 'original',
'serialize' => 0 // tests set this to 1 'serialize' => 0 // tests set this to 1
); );
$table = Request::processRequest('VisitsSummary.get', $params); $table = Request::processRequest('VisitsSummary.get', $params);
$this->prefixColumns($table, $period); $this->suffixColumns($table, $period);
$oldData = $this->getPrePiwik2Data($idSite, $period, $date, $segment, $columns);
if ($oldData->getRowsCount() > 0) {
$this->addPrePiwik2DataIfNewDataAbsent($oldData, $table);
}
Common::destroy($oldData);
return $table; return $table;
} }
/**
* Function body copied from Piwik 1.12.
*/
private function getPrePiwik2Data($idSite, $period, $date, $segment, $columns)
{
// TODO: possible optimization, only select for periods w/o new data
$archive = Archive::build($idSite, $period, $date, $segment);
// array values are comma separated
$columns = Piwik::getArrayFromApiParameter($columns);
$tempColumns = array();
$bounceRateReturningRequested = $averageVisitDurationReturningRequested = $actionsPerVisitReturningRequested = false;
if (!empty($columns)) {
// make sure base metrics are there for processed metrics
if (false !== ($bounceRateReturningRequested = array_search('bounce_rate_returning', $columns))) {
if (!in_array('nb_visits_returning', $columns)) {
$tempColumns[] = 'nb_visits_returning';
}
if (!in_array('bounce_count_returning', $columns)) {
$tempColumns[] = 'bounce_count_returning';
}
unset($columns[$bounceRateReturningRequested]);
}
if (false !== ($actionsPerVisitReturningRequested = array_search('nb_actions_per_visit_returning', $columns))) {
if (!in_array('nb_actions_returning', $columns)) {
$tempColumns[] = 'nb_actions_returning';
}
if (!in_array('nb_visits_returning', $columns)) {
$tempColumns[] = 'nb_visits_returning';
}
unset($columns[$actionsPerVisitReturningRequested]);
}
if (false !== ($averageVisitDurationReturningRequested = array_search('avg_time_on_site_returning', $columns))) {
if (!in_array('sum_visit_length_returning', $columns)) {
$tempColumns[] = 'sum_visit_length_returning';
}
if (!in_array('nb_visits_returning', $columns)) {
$tempColumns[] = 'nb_visits_returning';
}
unset($columns[$averageVisitDurationReturningRequested]);
}
$tempColumns = array_unique($tempColumns);
$columns = array_merge($columns, $tempColumns);
} else {
$bounceRateReturningRequested = $averageVisitDurationReturningRequested = $actionsPerVisitReturningRequested = true;
$columns = array(
'nb_visits_returning',
'nb_actions_returning',
'max_actions_returning',
'sum_visit_length_returning',
'bounce_count_returning',
'nb_visits_converted_returning',
);
if ($period == 'day') {
$columns = array_merge(array('nb_uniq_visitors_returning'), $columns);
}
}
$dataTable = $archive->getDataTableFromNumeric($columns);
// Process ratio metrics
if ($bounceRateReturningRequested !== false) {
$dataTable->filter('ColumnCallbackAddColumnPercentage', array('bounce_rate_returning', 'bounce_count_returning', 'nb_visits_returning', 0));
}
if ($actionsPerVisitReturningRequested !== false) {
$dataTable->filter('ColumnCallbackAddColumnQuotient', array('nb_actions_per_visit_returning', 'nb_actions_returning', 'nb_visits_returning', 1));
}
if ($averageVisitDurationReturningRequested !== false) {
$dataTable->filter('ColumnCallbackAddColumnQuotient', array('avg_time_on_site_returning', 'sum_visit_length_returning', 'nb_visits_returning', 0));
}
// remove temporary metrics that were used to compute processed metrics
$dataTable->deleteColumns($tempColumns);
return $dataTable;
}
private function addPrePiwik2DataIfNewDataAbsent($oldData, $newData)
{
if ($oldData instanceof DataTable\Map) {
$newArray = $pastData->getDataTables();
foreach ($oldData->getDataTables() as $subTable) {
$this->addPrePiwik2DataIfMissing($subTable, current($newArray));
next($newArray);
}
} else {
$newDataRow = $newData->getFirstRow();
$oldDataRow = $oldData->getFirstRow();
if ($oldDataRow) {
if (!$newDataRow) {
$newData->addRow($oldDataRow);
} else {
foreach ($oldDataRow->getColumns() as $name => $value) {
if ($newDataRow->getColumn($name) == 0) {
$newDataRow->setColumn($name, $value);
}
}
}
}
}
}
protected function appendReturningVisitorSegment($segment) protected function appendReturningVisitorSegment($segment)
{ {
if (empty($segment)) { if (empty($segment)) {
...@@ -61,7 +184,7 @@ class API extends \Piwik\Plugin\API ...@@ -61,7 +184,7 @@ class API extends \Piwik\Plugin\API
return $segment; return $segment;
} }
protected function unprefixColumns(&$columns) protected function unsuffixColumns(&$columns)
{ {
$columns = Piwik::getArrayFromApiParameter($columns); $columns = Piwik::getArrayFromApiParameter($columns);
foreach ($columns as &$column) { foreach ($columns as &$column) {
...@@ -69,7 +192,7 @@ class API extends \Piwik\Plugin\API ...@@ -69,7 +192,7 @@ class API extends \Piwik\Plugin\API
} }
} }
protected function prefixColumns($table, $period) protected function suffixColumns($table, $period)
{ {
$rename = array(); $rename = array();
foreach (APIVisitsSummary::getInstance()->getColumns($period) as $oldColumn) { foreach (APIVisitsSummary::getInstance()->getColumns($period) as $oldColumn) {
......
...@@ -9,6 +9,7 @@ use Piwik\ArchiveProcessor\Rules; ...@@ -9,6 +9,7 @@ use Piwik\ArchiveProcessor\Rules;
use Piwik\Config; use Piwik\Config;
use Piwik\Db; use Piwik\Db;
use Piwik\DbHelper; use Piwik\DbHelper;
use Piwik\Piwik;
/** /**
* Reusable fixture. Loads a SQL dump into the DB. * Reusable fixture. Loads a SQL dump into the DB.
...@@ -73,6 +74,16 @@ class Piwik_Test_Fixture_SqlDump extends Fixture ...@@ -73,6 +74,16 @@ class Piwik_Test_Fixture_SqlDump extends Fixture
// make sure archiving will be called // make sure archiving will be called
Rules::setBrowserTriggerArchiving(true); Rules::setBrowserTriggerArchiving(true);
// reload access
Piwik::setUserHasSuperUserAccess();
$this->getTestEnvironment()->configOverride = array(
'database' => array(
'tables_prefix' => $this->tablesPrefix
)
);
$this->getTestEnvironment()->save();
} }
public function tearDown() public function tearDown()
......
...@@ -6,8 +6,13 @@ ...@@ -6,8 +6,13 @@
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/ */
use Piwik\Date;
use Piwik\Piwik;
use Piwik\Plugins\VisitFrequency\API as VisitFrequencyApi;
use \Fixture;
/** /**
* Tests that Piwik 2.0 works w/ data from Piwik 1.13. * Tests that Piwik 2.0 works w/ data from Piwik 1.12.
*/ */
class Test_Piwik_Integration_BackwardsCompatibility1XTest extends IntegrationTestCase class Test_Piwik_Integration_BackwardsCompatibility1XTest extends IntegrationTestCase
{ {
...@@ -15,14 +20,35 @@ class Test_Piwik_Integration_BackwardsCompatibility1XTest extends IntegrationTes ...@@ -15,14 +20,35 @@ class Test_Piwik_Integration_BackwardsCompatibility1XTest extends IntegrationTes
public static $fixture = null; // initialized below class public static $fixture = null; // initialized below class
public static function setUpBeforeClass()
{
parent::setUpBeforeClass();
// FIXME:
// we should run tests to see if old data + new data can be mixed successfully if a period spans both
// old + new data, but we can't track visits w/ piwik 1.12 data. need to run the updater first.
// add two visits from same visitor on dec. 29
//$t = Fixture::getTracker(1, '2012-12-29 01:01:30', $defaultInit = true);
//$t->setUrl('http://site.com/index.htm');
//Fixture::checkResponse($t->doTrackPageView('incredible title!'));
//$t->setForceVisitDateTime('2012-12-29 03:01:30');
//$t->setUrl('http://site.com/other/index.htm');
//Fixture::checkResponse($t->doTrackPageView('other incredible title!'));
// launch archiving
//VisitFrequencyApi::getInstance()->get(1, 'month', '2012-12-29');
}
public function setUp() public function setUp()
{ {
parent::setUp(); parent::setUp();
// NOTE: VisitFrequency.get cannot be tested since it now uses a segment and thus requires archiving
// to be enabled.
$this->defaultApiNotToCall[] = 'Referrers'; $this->defaultApiNotToCall[] = 'Referrers';
$this->defaultApiNotToCall[] = 'VisitFrequency.get';
// changes made to test VisitFrequency
$this->defaultApiNotToCall[] = 'VisitTime.getByDayOfWeek';
} }
/** /**
...@@ -37,12 +63,21 @@ class Test_Piwik_Integration_BackwardsCompatibility1XTest extends IntegrationTes ...@@ -37,12 +63,21 @@ class Test_Piwik_Integration_BackwardsCompatibility1XTest extends IntegrationTes
public function getApiForTesting() public function getApiForTesting()
{ {
$idSite = 1; $idSite = 1;
$dateTime = '2010-03-06 11:22:33'; $dateTime = '2012-03-06 11:22:33';
return array( return array(
array('all', array('idSite' => $idSite, 'date' => $dateTime, array('all', array('idSite' => $idSite, 'date' => $dateTime,
'compareAgainst' => 'OneVisitorTwoVisits', 'compareAgainst' => 'OneVisitorTwoVisits',
'disableArchiving' => true)), 'disableArchiving' => true)),
/* cannot test this (see above)
array('VisitFrequency.get', array('idSite' => $idSite, 'date' => $dateTime, 'periods' => array('year'),
'compareAgainst' => 'OneVisitorTwoVisits',
'disableArchiving' => true)),
array('VisitFrequency.get', array('idSite' => $idSite, 'date' => '2012-03-06,2012-12-31',
'periods' => array('range'), 'disableArchiving' => true))
*/
); );
} }
} }
......
...@@ -132,7 +132,7 @@ class Piwik_TestingEnvironment ...@@ -132,7 +132,7 @@ class Piwik_TestingEnvironment
} }
if ($testingEnvironment->configOverride) { if ($testingEnvironment->configOverride) {
$cache = array_merge_recursive($cache, $testingEnvironment->configOverride); $cache = $testingEnvironment->arrayMergeRecursiveDistinct($cache, $testingEnvironment->configOverride);
} }
$testingEnvironment->logVariables(); $testingEnvironment->logVariables();
...@@ -176,6 +176,24 @@ class Piwik_TestingEnvironment ...@@ -176,6 +176,24 @@ class Piwik_TestingEnvironment
$testingEnvironment->executeSetupTestEnvHook(); $testingEnvironment->executeSetupTestEnvHook();
} }
public function arrayMergeRecursiveDistinct(array $array1, array $array2)
{
$result = $array1;
foreach ($array2 as $key => $value) {
if (is_array($value)) {
$result[$key] = is_array($result[$key])
? $this->arrayMergeRecursiveDistinct($result[$key], $value)
: $value
;
} else {
$result[$key] = $value;
}
}
return $result;
}
/** /**
* for plugins that need to inject special testing logic * for plugins that need to inject special testing logic
*/ */
......
Ce diff est replié.
0% Chargement en cours ou .
You are about to add 0 people to the discussion. Proceed with caution.
Veuillez vous inscrire ou vous pour commenter