PageRenderTime 37ms CodeModel.GetById 13ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/CustomVariables/Model.php

https://github.com/CodeYellowBV/piwik
PHP | 186 lines | 125 code | 36 blank | 25 comment | 9 complexity | eeb1b1169c55ef98aae21e95017bfbc9 MD5 | raw file
Possible License(s): LGPL-3.0, JSON, MIT, GPL-3.0, LGPL-2.1, GPL-2.0, AGPL-1.0, BSD-2-Clause, BSD-3-Clause
  1. <?php
  2. /**
  3. * Piwik - free/libre analytics platform
  4. *
  5. * @link http://piwik.org
  6. * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
  7. *
  8. */
  9. namespace Piwik\Plugins\CustomVariables;
  10. use Piwik\Common;
  11. use Piwik\DataTable;
  12. use Piwik\Db;
  13. use Piwik\Log;
  14. class Model
  15. {
  16. const SCOPE_PAGE = 'log_link_visit_action';
  17. const SCOPE_VISIT = 'log_visit';
  18. const SCOPE_CONVERSION = 'log_conversion';
  19. private $scope = null;
  20. public function __construct($scope)
  21. {
  22. if (empty($scope) || !in_array($scope, $this->getScopes())) {
  23. throw new \Exception('Invalid custom variable scope');
  24. }
  25. $this->scope = $scope;
  26. }
  27. public function getScopeName()
  28. {
  29. // actually we should have a class for each scope but don't want to overengineer it for now
  30. switch ($this->scope) {
  31. case self::SCOPE_PAGE:
  32. return 'Page';
  33. case self::SCOPE_VISIT:
  34. return 'Visit';
  35. case self::SCOPE_CONVERSION:
  36. return 'Conversion';
  37. }
  38. }
  39. /**
  40. * @see getHighestCustomVarIndex()
  41. * @return int
  42. */
  43. public function getCurrentNumCustomVars()
  44. {
  45. $indexes = $this->getCustomVarIndexes();
  46. return count($indexes);
  47. }
  48. /**
  49. * result of getHighestCustomVarIndex() can be different to getCurrentNumCustomVars() in case there are some missing
  50. * custom variable indexes. For instance in case of manual changes on the DB
  51. *
  52. * custom_var_v1
  53. * custom_var_v2
  54. * custom_var_v4
  55. *
  56. * getHighestCustomVarIndex() -> returns 4
  57. * getCurrentNumCustomVars() -> returns 3
  58. *
  59. * @return int
  60. */
  61. public function getHighestCustomVarIndex()
  62. {
  63. $indexes = $this->getCustomVarIndexes();
  64. if (empty($indexes)) {
  65. return 0;
  66. }
  67. return max($indexes);
  68. }
  69. public function getCustomVarIndexes()
  70. {
  71. $columns = $this->getCustomVarColumnNames();
  72. if (empty($columns)) {
  73. return array();
  74. }
  75. $indexes = array_map(function ($column) {
  76. return Model::getCustomVariableIndexFromFieldName($column);
  77. }, $columns);
  78. return array_values(array_unique($indexes));
  79. }
  80. private function getCustomVarColumnNames()
  81. {
  82. $dbTable = $this->getDbTableName();
  83. $columns = Db::getColumnNamesFromTable($dbTable);
  84. $customVarColumns = array_filter($columns, function ($column) {
  85. return false !== strpos($column, 'custom_var_');
  86. });
  87. return $customVarColumns;
  88. }
  89. public function removeCustomVariable()
  90. {
  91. $dbTable = $this->getDbTableName();
  92. $index = $this->getHighestCustomVarIndex();
  93. if ($index < 1) {
  94. return null;
  95. }
  96. Db::exec(sprintf('ALTER TABLE %s ', $dbTable)
  97. . sprintf('DROP COLUMN custom_var_k%d,', $index)
  98. . sprintf('DROP COLUMN custom_var_v%d;', $index));
  99. return $index;
  100. }
  101. public function addCustomVariable()
  102. {
  103. $dbTable = $this->getDbTableName();
  104. $index = $this->getHighestCustomVarIndex() + 1;
  105. $maxLen = CustomVariables::getMaxLengthCustomVariables();
  106. Db::exec(sprintf('ALTER TABLE %s ', $dbTable)
  107. . sprintf('ADD COLUMN custom_var_k%d VARCHAR(%d) DEFAULT NULL,', $index, $maxLen)
  108. . sprintf('ADD COLUMN custom_var_v%d VARCHAR(%d) DEFAULT NULL;', $index, $maxLen));
  109. return $index;
  110. }
  111. private function getDbTableName()
  112. {
  113. return Common::prefixTable($this->scope);
  114. }
  115. public static function getCustomVariableIndexFromFieldName($fieldName)
  116. {
  117. $onlyNumber = str_replace(array('custom_var_k', 'custom_var_v'), '', $fieldName);
  118. if (is_numeric($onlyNumber)) {
  119. return (int) $onlyNumber;
  120. }
  121. }
  122. public static function getScopes()
  123. {
  124. return array(self::SCOPE_PAGE, self::SCOPE_VISIT, self::SCOPE_CONVERSION);
  125. }
  126. public static function install()
  127. {
  128. foreach (self::getScopes() as $scope) {
  129. $model = new Model($scope);
  130. try {
  131. $maxCustomVars = 5;
  132. $customVarsToAdd = $maxCustomVars - $model->getCurrentNumCustomVars();
  133. for ($index = 0; $index < $customVarsToAdd; $index++) {
  134. $model->addCustomVariable();
  135. }
  136. } catch (\Exception $e) {
  137. Log::warning('Failed to add custom variable: ' . $e->getMessage());
  138. }
  139. }
  140. }
  141. public static function uninstall()
  142. {
  143. foreach (self::getScopes() as $scope) {
  144. $model = new Model($scope);
  145. while ($model->getHighestCustomVarIndex()) {
  146. $model->removeCustomVariable();
  147. }
  148. }
  149. }
  150. }