diff options
Diffstat (limited to 'plugins/CustomDimensions/Dimension')
m--------- | plugins/CustomDimensions | 0 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/Active.php | 31 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/CaseSensitive.php | 31 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/CustomActionDimension.php | 42 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/CustomVisitDimension.php | 43 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/Dimension.php | 77 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/Extraction.php | 125 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/Extractions.php | 47 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/Index.php | 52 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/Name.php | 51 | ||||
-rw-r--r-- | plugins/CustomDimensions/Dimension/Scope.php | 35 |
11 files changed, 534 insertions, 0 deletions
diff --git a/plugins/CustomDimensions b/plugins/CustomDimensions deleted file mode 160000 -Subproject 318661a2fb1ef3b3e5d6d999ae8b9628cb5a113 diff --git a/plugins/CustomDimensions/Dimension/Active.php b/plugins/CustomDimensions/Dimension/Active.php new file mode 100644 index 0000000000..7de60dbd38 --- /dev/null +++ b/plugins/CustomDimensions/Dimension/Active.php @@ -0,0 +1,31 @@ +<?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\Dimension; + +use \Exception; + +class Active +{ + private $active; + + public function __construct($active) + { + $this->active = $active; + } + + public function check() + { + if (!is_bool($this->active) && !in_array($this->active, array('0', '1', 0, 1), true)) { + $active = $this->active; + throw new Exception("Invalid value '$active' for 'active' specified. Allowed values: '0' or '1'"); + } + } + +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/CaseSensitive.php b/plugins/CustomDimensions/Dimension/CaseSensitive.php new file mode 100644 index 0000000000..c43bcdfbd8 --- /dev/null +++ b/plugins/CustomDimensions/Dimension/CaseSensitive.php @@ -0,0 +1,31 @@ +<?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\Dimension; + +use \Exception; + +class CaseSensitive +{ + private $caseSensitive; + + public function __construct($caseSensitive) + { + $this->caseSensitive = $caseSensitive; + } + + public function check() + { + if (!is_bool($this->caseSensitive) && !in_array($this->caseSensitive, array('0', '1', 0, 1), true)) { + $caseSensitive = $this->caseSensitive; + throw new Exception("Invalid value '$caseSensitive' for 'caseSensitive' specified. Allowed values: '0' or '1'"); + } + } + +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/CustomActionDimension.php b/plugins/CustomDimensions/Dimension/CustomActionDimension.php new file mode 100644 index 0000000000..02ea214842 --- /dev/null +++ b/plugins/CustomDimensions/Dimension/CustomActionDimension.php @@ -0,0 +1,42 @@ +<?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\Dimension; + +use Piwik\Plugin\Dimension\ActionDimension; +use Piwik\Plugins\CustomDimensions\Tracker\CustomDimensionsRequestProcessor; + +/** + * We do not put this one in columns directory of the plugin since we do not want to have it automatically detected. + * We create instances of it dynamically when needed instead. + */ +class CustomActionDimension extends ActionDimension +{ + public function __construct($column, $name, $idDimension) + { + $this->columnName = $column; + $this->actualName = $name; + $this->nameSingular = $name; + $this->idDimension = $idDimension; + $this->segmentName = CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($idDimension); + } + + /** + * The name of the dimension which will be visible for instance in the UI of a related report and in the mobile app. + * @return string + */ + public function getName() + { + return $this->actualName; + } + + public function getId() + { + return 'CustomDimension.CustomDimension' . $this->idDimension; + } +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/CustomVisitDimension.php b/plugins/CustomDimensions/Dimension/CustomVisitDimension.php new file mode 100644 index 0000000000..372e961cfa --- /dev/null +++ b/plugins/CustomDimensions/Dimension/CustomVisitDimension.php @@ -0,0 +1,43 @@ +<?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\Dimension; + +use Piwik\Plugin\Dimension\VisitDimension; +use Piwik\Plugins\CustomDimensions\Tracker\CustomDimensionsRequestProcessor; + +/** + * We do not put this one in columns directory of the plugin since we do not want to have it automatically detected. + * We create instances of it dynamically when needed instead. + */ +class CustomVisitDimension extends VisitDimension +{ + public function __construct($column, $name, $idDimension) + { + $this->columnName = $column; + $this->actualName = $name; + $this->nameSingular = $name; + $this->idDimension = $idDimension; + $this->segmentName = CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($idDimension); + } + + /** + * The name of the dimension which will be visible for instance in the UI of a related report and in the mobile app. + * @return string + */ + public function getName() + { + return $this->actualName; + } + + public function getId() + { + return 'CustomDimension.CustomDimension' . $this->idDimension; + } + +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/Dimension.php b/plugins/CustomDimensions/Dimension/Dimension.php new file mode 100644 index 0000000000..294fdff4c8 --- /dev/null +++ b/plugins/CustomDimensions/Dimension/Dimension.php @@ -0,0 +1,77 @@ +<?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\Dimension; + +use \Exception; +use Piwik\Piwik; +use Piwik\Plugins\CustomDimensions\Dao\Configuration; + +class Dimension +{ + /** + * @var int + */ + private $idDimension; + + /** + * @var int + */ + private $idSite; + + /** + * @var array + */ + private $dimension; + + public function __construct($idDimension, $idSite) + { + $this->idDimension = $idDimension; + $this->idSite = $idSite; + $this->dimension = $this->getConfiguration()->getCustomDimension($idDimension, $idSite); + } + + public function checkExists() + { + if (empty($this->dimension)) { + $msg = Piwik::translate('CustomDimensions_ExceptionDimensionDoesNotExist', array($this->idDimension, $this->idSite)); + throw new Exception($msg); + } + } + + public function checkActive() + { + $this->checkExists(); + + if (empty($this->dimension['active'])) { + $msg = Piwik::translate('CustomDimensions_ExceptionDimensionIsNotActive', array($this->idDimension, $this->idSite)); + throw new Exception($msg); + } + } + + public function getScope() + { + $this->checkExists(); + + return $this->dimension['scope']; + } + + public function getCaseSensitive() + { + $this->checkExists(); + + return $this->dimension['case_sensitive']; + } + + private function getConfiguration() + { + return new Configuration(); + } + +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/Extraction.php b/plugins/CustomDimensions/Dimension/Extraction.php new file mode 100644 index 0000000000..040992fd1a --- /dev/null +++ b/plugins/CustomDimensions/Dimension/Extraction.php @@ -0,0 +1,125 @@ +<?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\Dimension; + +use Piwik\Common; +use Piwik\Tracker\Request; +use Piwik\Tracker\Action; +use Piwik\Url; +use Piwik\UrlHelper; +use Piwik\Piwik; +use Exception; + +class Extraction +{ + private $dimension = ''; + private $pattern = ''; + private $caseSensitive = true; + + public function __construct($dimension, $pattern) + { + $this->dimension = $dimension; + $this->pattern = $pattern; + } + + public function toArray() + { + return array('dimension' => $this->dimension, 'pattern' => $this->pattern); + } + + public function check() + { + $dimensions = $this->getSupportedDimensions(); + if (!array_key_exists($this->dimension, $dimensions)) { + $dimensions = implode(', ', array_keys($dimensions)); + throw new Exception("Invald dimension '$this->dimension' used in an extraction. Available dimensions are: " . $dimensions); + } + + if (!empty($this->pattern) && $this->dimension !== 'urlparam') { + // make sure there is exactly one ( followed by one ) + if (1 !== substr_count($this->pattern, '(') || + 1 !== substr_count($this->pattern, ')') || + 1 !== substr_count($this->pattern, ')', strpos($this->pattern, '('))) { + throw new Exception("You need to group exactly one part of the regular expression inside round brackets, eg 'index_(.+).html'"); + } + } + } + + public static function getSupportedDimensions() + { + return array( + 'url' => Piwik::translate('Actions_ColumnPageURL'), + 'urlparam' => Piwik::translate('CustomDimensions_PageUrlParam'), + 'action_name' => Piwik::translate('Goals_PageTitle') + ); + } + + public function setCaseSensitive($caseSensitive) + { + $this->caseSensitive = (bool) $caseSensitive; + } + + public function extract(Request $request) + { + $value = $this->getValueForDimension($request); + $value = $this->extractValue($value); + + return $value; + } + + private function getValueForDimension(Request $request) + { + /** @var Action $action */ + $action = $request->getMetadata('Actions', 'action'); + + if (in_array($this->dimension, array('url', 'urlparam'))) { + if (!empty($action)) { + $dimension = $action->getActionUrlRaw(); + } else { + $dimension = $request->getParam('url'); + } + } elseif ($this->dimension === 'action_name' && !empty($action)) { + $dimension = $action->getActionName(); + } else { + $dimension = $request->getParam($this->dimension); + } + + if (!empty($dimension)) { + $dimension = Common::unsanitizeInputValue($dimension); + } + + return $dimension; + } + + private function extractValue($value) + { + if (!isset($value) || '' === $value) { + return null; + } + + $pattern = $this->pattern; + if ($this->dimension === 'urlparam') { + $pattern = '\?.*' . $pattern . '=([^&]*)'; + } + + $regex = '/' . str_replace('/', '\/', $pattern) . '/'; + if (!$this->caseSensitive) { + $regex .= 'i'; + } + + if (preg_match($regex, (string) $value, $matches)) { + // we could improve performance here I reckon by combining all patterns of all configs see eg http://nikic.github.io/2014/02/18/Fast-request-routing-using-regular-expressions.html + + if (array_key_exists(1, $matches)) { + return $matches[1]; + } + } + } +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/Extractions.php b/plugins/CustomDimensions/Dimension/Extractions.php new file mode 100644 index 0000000000..acc885f90d --- /dev/null +++ b/plugins/CustomDimensions/Dimension/Extractions.php @@ -0,0 +1,47 @@ +<?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\Dimension; + +use Exception; + +class Extractions +{ + private $extractions = array(); + + public function __construct($extractions) + { + $this->extractions = $extractions; + } + + public function check() + { + if (!is_array($this->extractions)) { + throw new Exception('extractions has to be an array'); + } + + foreach ($this->extractions as $extraction) { + + if (!is_array($extraction)) { + throw new \Exception('Each extraction within extractions has to be an array'); + } + + if (count($extraction) !== 2 + || !array_key_exists('dimension', $extraction) + || !array_key_exists('pattern', $extraction)) { + + throw new \Exception('Each extraction within extractions must have a key "dimension" and "pattern" only'); + } + + $extraction = new Extraction($extraction['dimension'], $extraction['pattern']); + $extraction->check(); + } + } + +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/Index.php b/plugins/CustomDimensions/Dimension/Index.php new file mode 100644 index 0000000000..4ad3ed0a58 --- /dev/null +++ b/plugins/CustomDimensions/Dimension/Index.php @@ -0,0 +1,52 @@ +<?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\Dimension; + +use \Exception; +use Piwik\API\Request; +use Piwik\Plugins\CustomDimensions\Dao\Configuration; +use Piwik\Plugins\CustomDimensions\Dao\LogTable; + +class Index +{ + public function getNextIndex($idSite, $scope) + { + $indexes = $this->getTracking($scope)->getInstalledIndexes(); + + $configs = Request::processRequest('CustomDimensions.getConfiguredCustomDimensionsHavingScope', [ + 'idSite' => $idSite, + 'scope' => $scope, + ]); + foreach ($configs as $config) { + $key = array_search($config['index'], $indexes); + if ($key !== false) { + unset($indexes[$key]); + } + } + + if (empty($indexes)) { + throw new Exception("All Custom Dimensions for website $idSite in scope '$scope' are already used."); + } + + $index = array_shift($indexes); + + return $index; + } + + private function getTracking($scope) + { + return new LogTable($scope); + } + + private function getConfiguration() + { + return new Configuration(); + } +}
\ No newline at end of file diff --git a/plugins/CustomDimensions/Dimension/Name.php b/plugins/CustomDimensions/Dimension/Name.php new file mode 100644 index 0000000000..246ba92a71 --- /dev/null +++ b/plugins/CustomDimensions/Dimension/Name.php @@ -0,0 +1,51 @@ +<?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\Dimension; + +use \Exception; +use Piwik\Piwik; + +class Name +{ + public function __construct($name) + { + $this->name = $name; + } + + public function check() + { + $maxLen = 255; + + if (empty($this->name)) { + throw new Exception(Piwik::translate('CustomDimensions_NameIsRequired')); + } + + if (strlen($this->name) > $maxLen) { + throw new Exception(Piwik::translate('CustomDimensions_NameIsTooLong', $maxLen)); + } + + $blockedCharacters = self::getBlockedCharacters(); + + // we do not really have to do this and it is not very effective for preventing XSS but doesn't hurt to have + if (strip_tags($this->name) !== $this->name || str_replace($blockedCharacters, '', $this->name) !== $this->name) { + throw new Exception(Piwik::translate('CustomDimensions_NameAllowedCharacters')); + } + } + + /** + * @api + */ + public static function getBlockedCharacters() + { + return [ + '/', '\\', '&', '.', '<', '>', + ]; + } +} diff --git a/plugins/CustomDimensions/Dimension/Scope.php b/plugins/CustomDimensions/Dimension/Scope.php new file mode 100644 index 0000000000..affea4b25b --- /dev/null +++ b/plugins/CustomDimensions/Dimension/Scope.php @@ -0,0 +1,35 @@ +<?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\Dimension; + +use \Exception; +use Piwik\Plugins\CustomDimensions\CustomDimensions; + +class Scope +{ + private $scope; + + public function __construct($scope) + { + $this->scope = $scope; + } + + public function check() + { + $scopes = CustomDimensions::getScopes(); + + if (empty($this->scope) || !in_array($this->scope, $scopes, true)) { + $scopes = implode(', ', $scopes); + $scope = $this->scope; + + throw new \Exception("Invalid value '$scope' for 'scope' specified. Available scopes are: $scopes"); + } + } +}
\ No newline at end of file |