diff options
Diffstat (limited to 'plugins/CustomDimensions/Dao/LogTable.php')
m--------- | plugins/CustomDimensions | 0 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dao/LogTable.php | 202 |
2 files changed, 202 insertions, 0 deletions
diff --git a/plugins/CustomDimensions b/plugins/CustomDimensions deleted file mode 160000 -Subproject 318661a2fb1ef3b3e5d6d999ae8b9628cb5a113 diff --git a/plugins/CustomDimensions/Dao/LogTable.php b/plugins/CustomDimensions/Dao/LogTable.php new file mode 100644 index 0000000000..57b0e29575 --- /dev/null +++ b/plugins/CustomDimensions/Dao/LogTable.php @@ -0,0 +1,202 @@ +<?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\CustomDimensions\Dao; + +use Piwik\Common; +use Piwik\DataAccess\TableMetadata; +use Piwik\DataTable; +use Piwik\Db; +use Piwik\DbHelper; +use Piwik\Plugins\CustomDimensions\CustomDimensions; +use Exception; + +class LogTable +{ + const DEFAULT_CUSTOM_DIMENSION_COUNT = 5; + + private $scope = null; + private $table = null; + + public function __construct($scope) + { + $this->scope = $scope; + $this->table = Common::prefixTable($this->getTableNameFromScope($scope)); + } + + private function getTableNameFromScope($scope) + { + // actually we should have a class for each scope but don't want to overengineer it for now + switch ($scope) { + case CustomDimensions::SCOPE_ACTION: + return 'log_link_visit_action'; + case CustomDimensions::SCOPE_VISIT: + return 'log_visit'; + case CustomDimensions::SCOPE_CONVERSION: + return 'log_conversion'; + default: + throw new Exception('Unsupported scope ' . $scope); + } + } + + /** + * @see getHighestCustomDimensionIndex() + * @return int + */ + public function getNumInstalledIndexes() + { + $indexes = $this->getInstalledIndexes(); + + return count($indexes); + } + + public function getInstalledIndexes() + { + $columns = $this->getCustomDimensionColumnNames(); + + if (empty($columns)) { + return array(); + } + + $indexes = array_map(function ($column) { + $onlyNumber = str_replace('custom_dimension_', '', $column); + + if (is_numeric($onlyNumber)) { + return (int) $onlyNumber; + } + }, $columns); + + return array_values(array_unique($indexes)); + } + + private function getCustomDimensionColumnNames() + { + $tableMetadataAccess = new TableMetadata(); + $columns = $tableMetadataAccess->getColumns($this->table); + + $dimensionColumns = array_filter($columns, function ($column) { + return LogTable::isCustomDimensionColumn($column); + }); + + return $dimensionColumns; + } + + public static function isCustomDimensionColumn($column) + { + return (bool) preg_match('/^custom_dimension_(\d+)$/', '' . $column); + } + + public static function buildCustomDimensionColumnName($indexOrDimension) + { + if (is_array($indexOrDimension) && isset($indexOrDimension['index'])) { + $indexOrDimension = $indexOrDimension['index']; + } + + $indexOrDimension = (int) $indexOrDimension; + + if ($indexOrDimension >= 1) { + return 'custom_dimension_' . (int) $indexOrDimension; + } + } + + public function removeCustomDimension($index) + { + if ($index < 1) { + return; + } + + $field = self::buildCustomDimensionColumnName($index); + + $this->dropColumn($field); + } + + public function addManyCustomDimensions($count, $extraAlter = null) + { + if ($count < 0) { + return; + } + + $indexes = $this->getInstalledIndexes(); + + if (empty($indexes)) { + $highestIndex = 0; + } else { + $highestIndex = max($indexes); + } + + $total = $highestIndex + $count; + + $queries = array(); + + if (isset($extraAlter)) { + // we make sure to install needed tracker request processor columns first, before installing custom dimensions + // if something fails custom dimensions can be added later any time + $queries[] = $extraAlter; + } + + for ($index = $highestIndex; $index < $total; $index++) { + $queries[] = $this->getAddColumnQueryToAddCustomDimension($index + 1); + } + + if (!empty($queries)) { + $sql = 'ALTER TABLE ' . $this->table . ' ' . implode(', ', $queries) . ';'; + Db::exec($sql); + } + } + + private function getAddColumnQueryToAddCustomDimension($index) + { + $field = self::buildCustomDimensionColumnName($index); + + return sprintf('ADD COLUMN %s VARCHAR(255) DEFAULT NULL', $field); + } + + public function install() + { + $numDimensionsInstalled = $this->getNumInstalledIndexes(); + $numDimensionsToAdd = self::DEFAULT_CUSTOM_DIMENSION_COUNT - $numDimensionsInstalled; + + $query = null; + if ($this->scope === CustomDimensions::SCOPE_VISIT && !$this->hasColumn('last_idlink_va')) { + $query = 'ADD COLUMN last_idlink_va BIGINT UNSIGNED DEFAULT NULL'; + } elseif ($this->scope === CustomDimensions::SCOPE_ACTION && !$this->hasColumn('time_spent')) { + $query = 'ADD COLUMN time_spent INT UNSIGNED DEFAULT NULL'; + } + + $this->addManyCustomDimensions($numDimensionsToAdd, $query); + } + + public function uninstall() + { + foreach ($this->getInstalledIndexes() as $index) { + $this->removeCustomDimension($index); + } + + if ($this->scope === CustomDimensions::SCOPE_VISIT) { + $this->dropColumn('last_idlink_va'); + } elseif ($this->scope === CustomDimensions::SCOPE_ACTION) { + $this->dropColumn('time_spent'); + } + } + + private function hasColumn($field) + { + $columns = DbHelper::getTableColumns($this->table); + return array_key_exists($field, $columns); + } + + private function dropColumn($field) + { + if ($this->hasColumn($field)) { + $sql = sprintf('ALTER TABLE %s DROP COLUMN %s;', $this->table, $field); + Db::exec($sql); + } + } + +} + |