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:
authorThomas Steur <thomas.steur@googlemail.com>2014-04-03 03:11:18 +0400
committerThomas Steur <thomas.steur@googlemail.com>2014-04-03 03:11:18 +0400
commit98bc277a08af76e7f498b37b13dada76be727e8f (patch)
treeea046a63621a8c4caddaae248ef6d29f61bc5228 /plugins
parent23bf6195a3cd3bdb1c24d76690336914f384da0f (diff)
started to work on command to set number of available custom variables
Diffstat (limited to 'plugins')
-rw-r--r--plugins/CustomVariables/Commands/SetNumberOfCustomVariables.php190
-rw-r--r--plugins/CustomVariables/CustomVariables.php11
-rw-r--r--plugins/CustomVariables/Model.php124
-rw-r--r--plugins/CustomVariables/tests/ModelTest.php113
4 files changed, 438 insertions, 0 deletions
diff --git a/plugins/CustomVariables/Commands/SetNumberOfCustomVariables.php b/plugins/CustomVariables/Commands/SetNumberOfCustomVariables.php
new file mode 100644
index 0000000000..57fa3f174d
--- /dev/null
+++ b/plugins/CustomVariables/Commands/SetNumberOfCustomVariables.php
@@ -0,0 +1,190 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+
+namespace Piwik\Plugins\CustomVariables\Commands;
+
+use Piwik\Plugin\ConsoleCommand;
+use Piwik\Plugins\CustomVariables\Model;
+use Symfony\Component\Console\Input\InputArgument;
+use Symfony\Component\Console\Input\InputInterface;
+use Symfony\Component\Console\Output\OutputInterface;
+
+/**
+ */
+class SetNumberOfCustomVariables extends ConsoleCommand
+{
+ /**
+ * @var \Symfony\Component\Console\Helper\ProgressHelper
+ */
+ private $progress;
+
+ protected function configure()
+ {
+ $this->setName('customvariables:set-number-available-custom-variables');
+ $this->setDescription('Change the number of available custom variables');
+ $this->setHelp("Example:
+./console customvariables:set-number-available-custom-variables 10
+=> 10 custom variables will be available in total
+");
+ $this->addArgument('maxCustomVars', InputArgument::REQUIRED, 'The number of available custom variables');
+ }
+
+ protected function execute(InputInterface $input, OutputInterface $output)
+ {
+ $numVarsToSet = $this->getNumVariablesToSet($input);
+ $numChangesToPerform = $this->getNumberOfChangesToPerform($numVarsToSet);
+
+ if (0 === $numChangesToPerform) {
+ $this->writeSuccessMessage($output, array(
+ 'Your Piwik is already configured for ' . $numVarsToSet . ' custom variables.'
+ ));
+ return;
+ }
+
+ foreach (Model::getScopes() as $scope) {
+ $this->printChanges($scope, $numVarsToSet, $output);
+ }
+
+ if (!$this->confirmChange($output)) {
+ return;
+ }
+
+ $output->writeln('');
+ $output->writeln('Starting to apply changes');
+ $output->writeln('');
+
+ $this->progress = $this->initProgress($numChangesToPerform, $output);
+
+ foreach (Model::getScopes() as $scope) {
+ $this->performChange($scope, $numVarsToSet, $output);
+ }
+
+ $this->progress->finish();
+
+ $this->writeSuccessMessage($output, array(
+ 'Your Piwik is now configured for ' . $numVarsToSet . ' custom variables.'
+ ));
+ }
+
+ private function initProgress($numChangesToPerform, OutputInterface $output)
+ {
+ /** @var \Symfony\Component\Console\Helper\ProgressHelper $progress */
+ $progress = $this->getHelperSet()->get('progress');
+ $progress->start($output, $numChangesToPerform);
+
+ return $progress;
+ }
+
+ private function performChange($scope, $numVarsToSet, OutputInterface $output)
+ {
+ $model = new Model($scope);
+ $numCurrentVars = $model->getCurrentNumCustomVars();
+ $numDifference = $this->getAbsoluteDifference($numCurrentVars, $numVarsToSet);
+
+ if ($numVarsToSet > $numCurrentVars) {
+ $this->addCustomVariables($model, $numDifference, $output);
+ return;
+ }
+
+ $this->removeCustomVariables($model, $numDifference, $output);
+ }
+
+ private function getNumVariablesToSet(InputInterface $input)
+ {
+ $maxCustomVars = $input->getArgument('maxCustomVars');
+
+ if (!is_numeric($maxCustomVars)) {
+ throw new \Exception('The number of available custom variables has to be number');
+ }
+
+ $maxCustomVars = (int) $maxCustomVars;
+
+ if ($maxCustomVars <= 0) {
+ throw new \Exception('There has to be at least 1 custom variable');
+ }
+
+ return $maxCustomVars;
+ }
+
+ private function confirmChange(OutputInterface $output)
+ {
+ $output->writeln('');
+
+ $dialog = $this->getHelperSet()->get('dialog');
+ return $dialog->askConfirmation(
+ $output,
+ '<question>Are you sure you want to perform these actions? (y/N)</question>',
+ false
+ );
+ }
+
+ private function printChanges($scope, $numVarsToSet, OutputInterface $output)
+ {
+ $model = new Model($scope);
+ $scopeName = $model->getScopeName();
+ $highestIndex = $model->getHighestCustomVarIndex();
+ $numCurrentCustomVars = $model->getCurrentNumCustomVars();
+ $numVarsDifference = $this->getAbsoluteDifference($numCurrentCustomVars, $numVarsToSet);
+
+ $output->writeln('');
+ $output->writeln(sprintf('Scope "%s"', $scopeName));
+
+ if ($numVarsToSet > $numCurrentCustomVars) {
+
+ $indexes = implode(',', range($highestIndex + 1, $highestIndex + $numVarsDifference));
+ $output->writeln(
+ sprintf('%s new custom variables having the index(es) %s will be ADDED', $numVarsDifference, $indexes)
+ );
+
+ } elseif ($numVarsToSet < $numCurrentCustomVars) {
+
+ $indexes = implode(',', range($highestIndex - $numVarsDifference + 1, $highestIndex));
+ $output->writeln(
+ sprintf("%s existing custom variables having the index(es) %s will be REMOVED.", $numVarsDifference, $indexes)
+ );
+ $output->writeln('<comment>This is an irreversible change</comment>');
+ }
+ }
+
+ private function getAbsoluteDifference($currentNumber, $numberToSet)
+ {
+ return abs($numberToSet - $currentNumber);
+ }
+
+ private function removeCustomVariables(Model $model, $numberOfVarsToRemove, OutputInterface $output)
+ {
+ for ($index = 0; $index < $numberOfVarsToRemove; $index++) {
+ $indexRemoved = $model->removeCustomVariable();
+ $this->progress->advance();
+ $output->writeln(' <info>Removed a variable in scope "' . $model->getScopeName() . '" having the index ' . $indexRemoved . '</info>');
+ }
+ }
+
+ private function addCustomVariables(Model $model, $numberOfVarsToAdd, OutputInterface $output)
+ {
+ for ($index = 0; $index < $numberOfVarsToAdd; $index++) {
+ $indexAdded = $model->addCustomVariable();
+ $this->progress->advance();
+ $output->writeln(' <info>Added a variable in scope "' . $model->getScopeName() . '" having the index ' . $indexAdded . '</info>');
+ }
+ }
+
+ private function getNumberOfChangesToPerform($numVarsToSet)
+ {
+ $numChangesToPerform = 0;
+
+ foreach (Model::getScopes() as $scope) {
+ $model = new Model($scope);
+ $numCurrentCustomVars = $model->getCurrentNumCustomVars();
+ $numChangesToPerform += $this->getAbsoluteDifference($numCurrentCustomVars, $numVarsToSet);
+ }
+
+ return $numChangesToPerform;
+ }
+}
diff --git a/plugins/CustomVariables/CustomVariables.php b/plugins/CustomVariables/CustomVariables.php
index 12bc5b007b..c7e47f08e1 100644
--- a/plugins/CustomVariables/CustomVariables.php
+++ b/plugins/CustomVariables/CustomVariables.php
@@ -38,6 +38,7 @@ class CustomVariables extends \Piwik\Plugin
'API.getReportMetadata' => 'getReportMetadata',
'API.getSegmentDimensionMetadata' => 'getSegmentsMetadata',
'ViewDataTable.configure' => 'configureViewDataTable',
+ 'Console.addCommands' => 'addConsoleCommands'
);
return $hooks;
}
@@ -52,6 +53,16 @@ class CustomVariables extends \Piwik\Plugin
MenuMain::getInstance()->add('General_Visitors', 'CustomVariables_CustomVariables', array('module' => 'CustomVariables', 'action' => 'index'), $display = true, $order = 50);
}
+ public function install()
+ {
+ Model::install();
+ }
+
+ public function addConsoleCommands(&$commands)
+ {
+ $commands[] = __NAMESPACE__ . '\\Commands\\SetNumberOfCustomVariables';
+ }
+
/**
* Returns metadata for available reports
*/
diff --git a/plugins/CustomVariables/Model.php b/plugins/CustomVariables/Model.php
new file mode 100644
index 0000000000..992be895e5
--- /dev/null
+++ b/plugins/CustomVariables/Model.php
@@ -0,0 +1,124 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Plugins\CustomVariables;
+
+use Piwik\Common;
+use Piwik\DataTable;
+use Piwik\Db;
+
+class Model
+{
+ const SCOPE_PAGE = 'log_link_visit_action';
+ const SCOPE_VISIT = 'log_visit';
+ const SCOPE_CONVERSION = 'log_conversion';
+
+ private $scope = null;
+
+ public function __construct($scope)
+ {
+ if (empty($scope) || !in_array($scope, $this->getScopes())) {
+ throw new \Exception('Invalid custom variable scope');
+ }
+
+ $this->scope = $scope;
+ }
+
+ public function getScopeName()
+ {
+ // actually we should have a class for each scope but don't want to overengineer it for now
+ switch ($this->scope) {
+ case self::SCOPE_PAGE:
+ return 'Page';
+ case self::SCOPE_VISIT:
+ return 'Visit';
+ case self::SCOPE_CONVERSION:
+ return 'Conversion';
+ }
+ }
+
+ public function getCurrentNumCustomVars()
+ {
+ $customVarColumns = $this->getCustomVarColumnNames();
+
+ $currentNumCustomVars = count($customVarColumns) / 2;
+
+ return (int) $currentNumCustomVars;
+ }
+
+ public function getHighestCustomVarIndex()
+ {
+ $columns = $this->getCustomVarColumnNames();
+
+ if (empty($columns)) {
+ return 0;
+ }
+
+ $indexes = array_map(function ($column) {
+ $onlyNumber = str_replace(array('custom_var_k', 'custom_var_v'), '', $column);
+ return (int) $onlyNumber;
+ }, $columns);
+
+ return max($indexes);
+ }
+
+ private function getCustomVarColumnNames()
+ {
+ $dbTable = Common::prefixTable($this->scope);
+ $columns = Db::getColumnNamesFromTable($dbTable);
+
+ $customVarColumns = array_filter($columns, function ($column) {
+ return false !== strpos($column, 'custom_var_');
+ });
+
+ return $customVarColumns;
+ }
+
+ public function removeCustomVariable()
+ {
+ $dbTable = Common::prefixTable($this->scope);
+ $index = $this->getHighestCustomVarIndex();
+
+ if ($index < 1) {
+ return null;
+ }
+
+ Db::exec(sprintf('ALTER TABLE %s DROP COLUMN custom_var_k%d', $dbTable, $index));
+ Db::exec(sprintf('ALTER TABLE %s DROP COLUMN custom_var_v%d', $dbTable, $index));
+
+ return $index;
+ }
+
+ public function addCustomVariable()
+ {
+ $dbTable = Common::prefixTable($this->scope);
+ $index = $this->getHighestCustomVarIndex() + 1;
+
+ Db::exec(sprintf('ALTER TABLE %s ADD COLUMN custom_var_k%d VARCHAR(200) DEFAULT NULL', $dbTable, $index));
+ Db::exec(sprintf('ALTER TABLE %s ADD COLUMN custom_var_v%d VARCHAR(200) DEFAULT NULL', $dbTable, $index));
+
+ return $index;
+ }
+
+ public static function getScopes()
+ {
+ return array(self::SCOPE_PAGE, self::SCOPE_VISIT, self::SCOPE_CONVERSION);
+ }
+
+ public static function install()
+ {
+ foreach (self::getScopes() as $scope) {
+ $model = new Model($scope);
+ for ($index = 0; $index < 5; $index++) {
+ $model->addCustomVariable();
+ }
+ }
+ }
+
+}
+
diff --git a/plugins/CustomVariables/tests/ModelTest.php b/plugins/CustomVariables/tests/ModelTest.php
new file mode 100644
index 0000000000..b141cb4f5d
--- /dev/null
+++ b/plugins/CustomVariables/tests/ModelTest.php
@@ -0,0 +1,113 @@
+<?php
+/**
+ * Piwik - Open source web analytics
+ *
+ * @link http://piwik.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Plugins\CustomVariables\tests;
+use Piwik\Db;
+use Piwik\Plugins\CustomVariables\Model;
+
+/**
+ * @group CustomVariables
+ * @group ModelTest
+ * @group Database
+ */
+class ModelTest extends \DatabaseTestCase
+{
+ public function testGetAllScopes()
+ {
+ $this->assertEquals(array('log_link_visit_action', 'log_visit', 'log_conversion'), Model::getScopes());
+ }
+
+ public function testGetScopeName()
+ {
+ $this->assertEquals('Page', $this->getPageScope()->getScopeName());
+ $this->assertEquals('Visit', $this->getVisitScope()->getScopeName());
+ $this->assertEquals('Conversion', $this->getConversionScope()->getScopeName());
+ }
+
+ public function test_getCurrentNumCustomVars()
+ {
+ $this->assertEquals(5, $this->getPageScope()->getCurrentNumCustomVars());
+ $this->assertEquals(5, $this->getVisitScope()->getCurrentNumCustomVars());
+ $this->assertEquals(5, $this->getConversionScope()->getCurrentNumCustomVars());
+
+ $this->getPageScope()->addCustomVariable();
+ $this->getConversionScope()->removeCustomVariable();
+
+ $this->assertEquals(6, $this->getPageScope()->getCurrentNumCustomVars());
+ $this->assertEquals(5, $this->getVisitScope()->getCurrentNumCustomVars());
+ $this->assertEquals(4, $this->getConversionScope()->getCurrentNumCustomVars());
+ }
+
+ public function test_getHighestCustomVarIndex_addCustomVariable_removeCustomVariable()
+ {
+ $this->assertEquals(5, $this->getPageScope()->getHighestCustomVarIndex());
+ $this->assertEquals(5, $this->getVisitScope()->getHighestCustomVarIndex());
+ $this->assertEquals(5, $this->getConversionScope()->getHighestCustomVarIndex());
+
+ $this->getPageScope()->addCustomVariable();
+ $this->getConversionScope()->removeCustomVariable();
+
+ $this->assertEquals(6, $this->getPageScope()->getHighestCustomVarIndex());
+ $this->assertEquals(5, $this->getVisitScope()->getHighestCustomVarIndex());
+ $this->assertEquals(4, $this->getConversionScope()->getHighestCustomVarIndex());
+
+ $this->getConversionScope()->removeCustomVariable();
+ $this->getPageScope()->addCustomVariable();
+ $this->getVisitScope()->addCustomVariable();
+ $this->getPageScope()->addCustomVariable();
+ $this->getConversionScope()->removeCustomVariable();
+
+ $this->assertEquals(8, $this->getPageScope()->getHighestCustomVarIndex());
+ $this->assertEquals(6, $this->getVisitScope()->getHighestCustomVarIndex());
+ $this->assertEquals(2, $this->getConversionScope()->getHighestCustomVarIndex());
+ }
+
+ public function test_removeCustomVariable_shouldNotFailIfRemovesMoreThanExist()
+ {
+ $scope = $this->getPageScope();
+
+ $this->assertEquals(5, $scope->getHighestCustomVarIndex());
+
+ for ($index = 0; $index < 5; $index++) {
+ $scope->removeCustomVariable();
+ $this->assertEquals(4 - $index, $scope->getHighestCustomVarIndex());
+ }
+
+ $this->assertNull($scope->removeCustomVariable());
+ $this->assertEquals(0, $scope->getHighestCustomVarIndex());
+ $this->assertEquals(0, $scope->getCurrentNumCustomVars());
+ }
+
+ public function test_removeCustomVariable_addCustomVariable_ReturnsIndex()
+ {
+ $scopeToAdd = $this->getPageScope();
+ $scopeToRemove = $this->getVisitScope();
+
+ for ($index = 0; $index < 5; $index++) {
+ $this->assertEquals(5 - $index, $scopeToRemove->removeCustomVariable());
+ $this->assertEquals(6 + $index, $scopeToAdd->addCustomVariable());
+ }
+ }
+
+ private function getPageScope()
+ {
+ return new Model(Model::SCOPE_PAGE);
+ }
+
+ private function getVisitScope()
+ {
+ return new Model(Model::SCOPE_VISIT);
+ }
+
+ private function getConversionScope()
+ {
+ return new Model(Model::SCOPE_CONVERSION);
+ }
+
+
+}