From 1196447c73918b41a61bb38e17044067ca9d88a6 Mon Sep 17 00:00:00 2001 From: Thomas Steur <thomas.steur@gmail.com> Date: Sat, 29 Aug 2015 11:02:01 +0000 Subject: [PATCH] return min amount of available custom variables across tables instead of maximum --- core/Tracker/GoalManager.php | 2 +- core/Tracker/Request.php | 2 +- core/Tracker/TrackerCodeGenerator.php | 2 +- core/Tracker/VisitorRecognizer.php | 2 +- plugins/CoreAdminHome/Controller.php | 2 +- plugins/CustomVariables/Archiver.php | 2 +- plugins/CustomVariables/Commands/Info.php | 2 +- plugins/CustomVariables/CustomVariables.php | 32 ++++++-- .../SetNumberOfCustomVariablesTest.php | 14 ++-- .../tests/Integration/CustomVariablesTest.php | 75 +++++++++++++++++-- plugins/Live/Model.php | 2 +- plugins/Live/Visitor.php | 2 +- 12 files changed, 107 insertions(+), 32 deletions(-) diff --git a/core/Tracker/GoalManager.php b/core/Tracker/GoalManager.php index 7bd5e97f1e..95779e0a76 100644 --- a/core/Tracker/GoalManager.php +++ b/core/Tracker/GoalManager.php @@ -216,7 +216,7 @@ class GoalManager // Copy Custom Variables from Visit row to the Goal conversion // Otherwise, set the Custom Variables found in the cookie sent with this request $goal += $visitCustomVariables; - $maxCustomVariables = CustomVariables::getMaxCustomVariables(); + $maxCustomVariables = CustomVariables::getNumUsableCustomVariables(); for ($i = 1; $i <= $maxCustomVariables; $i++) { if (isset($visitorInformation['custom_var_k' . $i]) diff --git a/core/Tracker/Request.php b/core/Tracker/Request.php index b5d358f25d..489ee313e7 100644 --- a/core/Tracker/Request.php +++ b/core/Tracker/Request.php @@ -540,7 +540,7 @@ class Request } $customVariables = array(); - $maxCustomVars = CustomVariables::getMaxCustomVariables(); + $maxCustomVars = CustomVariables::getNumUsableCustomVariables(); foreach ($customVar as $id => $keyValue) { $id = (int)$id; diff --git a/core/Tracker/TrackerCodeGenerator.php b/core/Tracker/TrackerCodeGenerator.php index 7a0204dbda..ceca8a3e71 100644 --- a/core/Tracker/TrackerCodeGenerator.php +++ b/core/Tracker/TrackerCodeGenerator.php @@ -63,7 +63,7 @@ class TrackerCodeGenerator if ($mergeSubdomains || $mergeAliasUrls) { $options .= $this->getJavascriptTagOptions($idSite, $mergeSubdomains, $mergeAliasUrls); } - $maxCustomVars = CustomVariables::getMaxCustomVariables(); + $maxCustomVars = CustomVariables::getNumUsableCustomVariables(); if ($visitorCustomVariables && count($visitorCustomVariables) > 0) { $options .= ' // you can set up to ' . $maxCustomVars . ' custom variables for each visitor' . PHP_EOL; diff --git a/core/Tracker/VisitorRecognizer.php b/core/Tracker/VisitorRecognizer.php index ff91f57d7e..d5f5e3c502 100644 --- a/core/Tracker/VisitorRecognizer.php +++ b/core/Tracker/VisitorRecognizer.php @@ -256,7 +256,7 @@ class VisitorRecognizer array_unshift($fields, 'visit_first_action_time'); array_unshift($fields, 'visit_last_action_time'); - for ($index = 1; $index <= CustomVariables::getMaxCustomVariables(); $index++) { + for ($index = 1; $index <= CustomVariables::getNumUsableCustomVariables(); $index++) { $fields[] = 'custom_var_k' . $index; $fields[] = 'custom_var_v' . $index; } diff --git a/plugins/CoreAdminHome/Controller.php b/plugins/CoreAdminHome/Controller.php index cb8f862643..ea8b42da33 100644 --- a/plugins/CoreAdminHome/Controller.php +++ b/plugins/CoreAdminHome/Controller.php @@ -292,7 +292,7 @@ class Controller extends ControllerAdmin $view->defaultReportSiteName = Site::getNameFor($view->idSite); $view->defaultSiteRevenue = \Piwik\Metrics\Formatter::getCurrencySymbol($view->idSite); - $view->maxCustomVariables = CustomVariables::getMaxCustomVariables(); + $view->maxCustomVariables = CustomVariables::getNumUsableCustomVariables(); $allUrls = APISitesManager::getInstance()->getSiteUrlsFromId($view->idSite); if (isset($allUrls[1])) { diff --git a/plugins/CustomVariables/Archiver.php b/plugins/CustomVariables/Archiver.php index b613f65d02..bc43cbc8dd 100644 --- a/plugins/CustomVariables/Archiver.php +++ b/plugins/CustomVariables/Archiver.php @@ -66,7 +66,7 @@ class Archiver extends \Piwik\Plugin\Archiver { $this->dataArray = new DataArray(); - $maxCustomVariables = CustomVariables::getMaxCustomVariables(); + $maxCustomVariables = CustomVariables::getNumUsableCustomVariables(); for ($i = 1; $i <= $maxCustomVariables; $i++) { $this->aggregateCustomVariable($i); } diff --git a/plugins/CustomVariables/Commands/Info.php b/plugins/CustomVariables/Commands/Info.php index bf300e357a..e5dfce5d5b 100644 --- a/plugins/CustomVariables/Commands/Info.php +++ b/plugins/CustomVariables/Commands/Info.php @@ -28,7 +28,7 @@ class Info extends ConsoleCommand protected function execute(InputInterface $input, OutputInterface $output) { - $maxVars = CustomVariables::getMaxCustomVariables(); + $maxVars = CustomVariables::getNumUsableCustomVariables(); if ($this->hasEverywhereSameAmountOfVariables()) { $this->writeSuccessMessage($output, array( diff --git a/plugins/CustomVariables/CustomVariables.php b/plugins/CustomVariables/CustomVariables.php index 64a7c9ea05..7a37808909 100644 --- a/plugins/CustomVariables/CustomVariables.php +++ b/plugins/CustomVariables/CustomVariables.php @@ -40,7 +40,7 @@ class CustomVariables extends \Piwik\Plugin { $customVariables = array(); - $maxCustomVariables = self::getMaxCustomVariables(); + $maxCustomVariables = self::getNumUsableCustomVariables(); for ($i = 1; $i <= $maxCustomVariables; $i++) { if (!empty($details['custom_var_k' . $i])) { @@ -63,25 +63,41 @@ class CustomVariables extends \Piwik\Plugin return 200; } - public static function getMaxCustomVariables() + /** + * Returns the number of available custom variables that can be used. + * + * "Can be used" is identifed by the minimum number of available custom variables across all relevant tables. Eg + * if there are 6 custom variables installed in log_visit but only 5 in log_conversion, we consider only 5 custom + * variables as usable. + * @return int + */ + public static function getNumUsableCustomVariables() { $cache = Cache::getCacheGeneral(); - $cacheKey = 'CustomVariables.MaxNumCustomVariables'; + $cacheKey = 'CustomVariables.NumUsableCustomVariables'; if (!array_key_exists($cacheKey, $cache)) { - $maxCustomVar = 0; + $minCustomVar = null; foreach (Model::getScopes() as $scope) { $model = new Model($scope); $highestIndex = $model->getHighestCustomVarIndex(); - if ($highestIndex > $maxCustomVar) { - $maxCustomVar = $highestIndex; + if (!isset($minCustomVar)) { + $minCustomVar = $highestIndex; } + + if ($highestIndex < $minCustomVar) { + $minCustomVar = $highestIndex; + } + } + + if (!isset($minCustomVar)) { + $minCustomVar = 0; } - $cache[$cacheKey] = $maxCustomVar; + $cache[$cacheKey] = $minCustomVar; Cache::setCacheGeneral($cache); } @@ -90,7 +106,7 @@ class CustomVariables extends \Piwik\Plugin public function getSegmentsMetadata(&$segments) { - $maxCustomVariables = self::getMaxCustomVariables(); + $maxCustomVariables = self::getNumUsableCustomVariables(); for ($i = 1; $i <= $maxCustomVariables; $i++) { $segments[] = array( diff --git a/plugins/CustomVariables/tests/Commands/SetNumberOfCustomVariablesTest.php b/plugins/CustomVariables/tests/Commands/SetNumberOfCustomVariablesTest.php index e70c3515bb..a17a0683a5 100644 --- a/plugins/CustomVariables/tests/Commands/SetNumberOfCustomVariablesTest.php +++ b/plugins/CustomVariables/tests/Commands/SetNumberOfCustomVariablesTest.php @@ -65,7 +65,7 @@ class SetNumberOfCustomVariablesTest extends IntegrationTestCase public function testExecute_ShouldAddMaxCustomVars_IfNumberIsHigherThanActual() { - $this->assertEquals(5, CustomVariables::getMaxCustomVariables()); + $this->assertEquals(5, CustomVariables::getNumUsableCustomVariables()); $result = $this->executeCommand(6); @@ -77,13 +77,13 @@ class SetNumberOfCustomVariablesTest extends IntegrationTestCase $this->assertContains('Added a variable in scope "Conversion" having the index 6', $result); $this->assertContains('Your Piwik is now configured for 6 custom variables.', $result); - $this->assertEquals(6, CustomVariables::getMaxCustomVariables()); + $this->assertEquals(6, CustomVariables::getNumUsableCustomVariables()); } public function testExecute_ShouldRemoveMaxCustomVars_IfNumberIsLessThanActual() { $this->executeCommand(6, true); - $this->assertEquals(6, CustomVariables::getMaxCustomVariables()); + $this->assertEquals(6, CustomVariables::getNumUsableCustomVariables()); $result = $this->executeCommand(5); @@ -95,18 +95,18 @@ class SetNumberOfCustomVariablesTest extends IntegrationTestCase $this->assertContains('Removed a variable in scope "Conversion" having the index 6', $result); $this->assertContains('Your Piwik is now configured for 5 custom variables.', $result); - $this->assertEquals(5, CustomVariables::getMaxCustomVariables()); + $this->assertEquals(5, CustomVariables::getNumUsableCustomVariables()); } public function testExecute_AddMultiple_RemoveMultiple() { - $this->assertEquals(5, CustomVariables::getMaxCustomVariables()); + $this->assertEquals(5, CustomVariables::getNumUsableCustomVariables()); $this->executeCommand(9); - $this->assertEquals(9, CustomVariables::getMaxCustomVariables()); + $this->assertEquals(9, CustomVariables::getNumUsableCustomVariables()); $this->executeCommand(6); - $this->assertEquals(6, CustomVariables::getMaxCustomVariables()); + $this->assertEquals(6, CustomVariables::getNumUsableCustomVariables()); } /** diff --git a/plugins/CustomVariables/tests/Integration/CustomVariablesTest.php b/plugins/CustomVariables/tests/Integration/CustomVariablesTest.php index 75832efe37..e24bbf0090 100644 --- a/plugins/CustomVariables/tests/Integration/CustomVariablesTest.php +++ b/plugins/CustomVariables/tests/Integration/CustomVariablesTest.php @@ -8,6 +8,7 @@ namespace Piwik\Plugins\CustomVariables\tests; use Piwik\Plugins\CustomVariables\CustomVariables; +use Piwik\Plugins\CustomVariables\Model; use Piwik\Tracker\Cache; use Piwik\Tests\Framework\TestCase\IntegrationTestCase; @@ -18,27 +19,85 @@ use Piwik\Tests\Framework\TestCase\IntegrationTestCase; */ class CustomVariablesTest extends IntegrationTestCase { - public function testGetMaxCustomVariables_ShouldDetectCorrectNumberOfVariables() + public function test_getNumUsableCustomVariables_ShouldDetectCorrectNumberOfVariables() { Cache::clearCacheGeneral(); - $this->assertSame(5, CustomVariables::getMaxCustomVariables()); + $this->assertSame(5, CustomVariables::getNumUsableCustomVariables()); } - public function testGetMaxCustomVariables_ShouldCacheTheResult() + public function test_getNumUsableCustomVariables_ShouldCacheTheResult() { - CustomVariables::getMaxCustomVariables(); + CustomVariables::getNumUsableCustomVariables(); $cache = Cache::getCacheGeneral(); - $this->assertSame(5, $cache['CustomVariables.MaxNumCustomVariables']); + $this->assertSame(5, $cache['CustomVariables.NumUsableCustomVariables']); } - public function testGetMaxCustomVariables_ShouldReadFromCacheIfPossible() + public function test_getNumUsableCustomVariables_ShouldReadFromCacheIfPossible() { $cache = Cache::getCacheGeneral(); - $cache['CustomVariables.MaxNumCustomVariables'] = 10; + $cache['CustomVariables.NumUsableCustomVariables'] = 10; Cache::setCacheGeneral($cache); - $this->assertSame(10, CustomVariables::getMaxCustomVariables()); + $this->assertSame(10, CustomVariables::getNumUsableCustomVariables()); } + public function test_getNumUsableCustomVariables_ShouldReturnMinVariables_IfOneTableHasLessEntriesThanOthers() + { + $this->assertEquals(5, CustomVariables::getNumUsableCustomVariables()); + + $scopes = Model::getScopes(); + + // removing custom vars step by step... as soon as one custom var is removed, + // it should return the min count of available variables + for ($i = 4; $i != -1; $i--) { + foreach ($scopes as $scope) { + $this->dropCustomVar($scope); + $this->assertSame($i, CustomVariables::getNumUsableCustomVariables()); + } + } + + $this->assertEquals(0, CustomVariables::getNumUsableCustomVariables()); + + // add custom var, only once all custom vars are written it should write return a higher custom var number + for ($i = 1; $i != 7; $i++) { + foreach ($scopes as $index => $scope) { + $isLastIndex = $index === (count($scopes) - 1); + + $this->addCustomVar($scope); + + if ($isLastIndex) { + $this->assertSame($i, CustomVariables::getNumUsableCustomVariables()); + // all scopes have been added, it should consider all custom var counts + } else { + $this->assertSame($i - 1, CustomVariables::getNumUsableCustomVariables()); + // at least one scope is not added and should therefore return the old custom var count until all + // tables have been updated + } + } + } + + $this->assertEquals(6, CustomVariables::getNumUsableCustomVariables()); + } + + private function dropCustomVar($scope) + { + $this->clearCache(); + $model = new Model($scope); + $model->removeCustomVariable(); + } + + private function addCustomVar($scope) + { + $this->clearCache(); + $model = new Model($scope); + $model->addCustomVariable(); + } + + private function clearCache() + { + Cache::clearCacheGeneral(); + } + + } diff --git a/plugins/Live/Model.php b/plugins/Live/Model.php index 3a06c58d45..8f7087405e 100644 --- a/plugins/Live/Model.php +++ b/plugins/Live/Model.php @@ -33,7 +33,7 @@ class Model */ public function queryActionsForVisit($idVisit, $actionsLimit) { - $maxCustomVariables = CustomVariables::getMaxCustomVariables(); + $maxCustomVariables = CustomVariables::getNumUsableCustomVariables(); $sqlCustomVariables = ''; for ($i = 1; $i <= $maxCustomVariables; $i++) { diff --git a/plugins/Live/Visitor.php b/plugins/Live/Visitor.php index dae839cd9a..edafacd896 100644 --- a/plugins/Live/Visitor.php +++ b/plugins/Live/Visitor.php @@ -250,7 +250,7 @@ class Visitor implements VisitorInterface $actionDetails = $model->queryActionsForVisit($idVisit, $actionsLimit); $formatter = new Formatter(); - $maxCustomVariables = CustomVariables::getMaxCustomVariables(); + $maxCustomVariables = CustomVariables::getNumUsableCustomVariables(); foreach ($actionDetails as $actionIdx => &$actionDetail) { $actionDetail =& $actionDetails[$actionIdx]; -- GitLab