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:
-rw-r--r--CHANGELOG.md3
-rw-r--r--config/global.php4
-rw-r--r--core/Columns/Dimension.php182
-rw-r--r--core/Columns/DimensionSegmentFactory.php178
-rw-r--r--core/Plugin/Segment.php24
-rw-r--r--core/Segment/SegmentsList.php140
-rw-r--r--plugins/API/SegmentMetadata.php48
-rw-r--r--plugins/Actions/Columns/ActionUrl.php7
m---------plugins/Bandwidth0
-rw-r--r--plugins/CoreHome/Columns/LinkVisitActionIdPages.php4
-rw-r--r--plugins/CoreHome/Columns/VisitId.php6
-rw-r--r--plugins/CoreHome/Columns/VisitIp.php6
m---------plugins/CustomDimensions0
-rw-r--r--plugins/CustomVariables/Columns/Base.php12
-rw-r--r--plugins/CustomVariables/Columns/CustomVariableName.php6
-rw-r--r--plugins/CustomVariables/Columns/CustomVariableValue.php6
-rw-r--r--plugins/DevicesDetection/Columns/BrowserName.php8
-rw-r--r--plugins/DevicesDetection/Columns/Os.php8
-rw-r--r--plugins/Ecommerce/Columns/ProductCategory.php8
m---------plugins/MarketingCampaignsReporting0
m---------plugins/QueuedTracking0
-rw-r--r--plugins/SegmentEditor/SegmentFormatter.php12
-rw-r--r--plugins/SegmentEditor/SegmentList.php33
-rw-r--r--plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php8
-rw-r--r--plugins/SegmentEditor/tests/Integration/SegmentListTest.php73
-rw-r--r--plugins/UserCountry/Columns/Country.php8
-rw-r--r--tests/PHPUnit/Integration/CacheIdTest.php1
-rw-r--r--tests/PHPUnit/Integration/Columns/DimensionSegmentFactoryTest.php71
-rw-r--r--tests/PHPUnit/Integration/Columns/DimensionTest.php10
-rw-r--r--tests/PHPUnit/Integration/Plugin/Dimension/ActionDimensionTest.php23
-rw-r--r--tests/PHPUnit/Integration/Plugin/Dimension/ConversionDimensionTest.php23
-rw-r--r--tests/PHPUnit/Integration/Plugin/Dimension/VisitDimensionTest.php8
-rw-r--r--tests/PHPUnit/Integration/Segment/SegmentsListTest.php79
-rw-r--r--tests/PHPUnit/Integration/SegmentTest.php4
-rw-r--r--tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml24
m---------tests/travis0
36 files changed, 674 insertions, 353 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 29179bea35..52463d8476 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -48,6 +48,9 @@ The Product Changelog at **[matomo.org/changelog](https://matomo.org/changelog)*
* The parameter `alias` from the API methods `UsersManager.addUser` and `UsersManager.updateUser` has been removed.
* The dimension and `log_link_visit_action` column interaction_position has been renamed to pageview_position. If your database queries rely on the column you can simply replace the name.
* The metric (avg.) page generation time has been deprecated. It is no longer possible to track it. Already tracked values will still be shown in old reports. More detailed performance metrics are now available in PagePerformance plugin.
+* The signature of `Dimension::configureSegments()` has been changed. Similar to configuring Metrics it now takes two parameters `SegmentsList $segmentsList` and `DimensionSegmentFactory $dimensionSegmentFactory`.
+* The method `Dimension::addSegment()` has been removed. See new implementation of `DimensionSegmentFactory::createSegment` for a replacement
+* The signature of the event `Segment.addSegments` has been changed. It now has one parameter `SegmentsList $list`, which allows adding new segments to the list
## Matomo 3.13.5
diff --git a/config/global.php b/config/global.php
index e6c489fe56..a7ad1c083b 100644
--- a/config/global.php
+++ b/config/global.php
@@ -219,4 +219,8 @@ return array(
\Piwik\CronArchive\Performance\Logger::class => DI\object()->constructorParameter('logger', DI\get('archiving.performance.logger')),
\Piwik\Concurrency\LockBackend::class => \DI\get(\Piwik\Concurrency\LockBackend\MySqlLockBackend::class),
+
+ \Piwik\Segment\SegmentsList::class => function(){
+ return \Piwik\Segment\SegmentsList::get();
+ }
);
diff --git a/core/Columns/Dimension.php b/core/Columns/Dimension.php
index af5ccd6838..714fe50c9b 100644
--- a/core/Columns/Dimension.php
+++ b/core/Columns/Dimension.php
@@ -19,6 +19,7 @@ use Piwik\CacheId;
use Piwik\Cache as PiwikCache;
use Piwik\Plugin\Manager as PluginManager;
use Piwik\Metrics\Formatter;
+use Piwik\Segment\SegmentsList;
/**
* @api
@@ -475,16 +476,20 @@ abstract class Dimension
* $segment->setSegment('exitPageUrl');
* $segment->setName('Actions_ColumnExitPageURL');
* $segment->setCategory('General_Visit');
- * $this->addSegment($segment);
+ * $segmentsList->addSegment($segment);
* ```
+ *
+ * @param SegmentsList $segmentsList
+ * @param DimensionSegmentFactory $dimensionSegmentFactory
+ * @throws Exception
*/
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
if ($this->segmentName && $this->category
&& ($this->sqlSegment || ($this->columnName && $this->dbTableName))
&& $this->nameSingular) {
- $segment = new Segment();
- $this->addSegment($segment);
+ $segment = $dimensionSegmentFactory->createSegment(null);
+ $segmentsList->addSegment($segment);
}
}
@@ -533,131 +538,17 @@ abstract class Dimension
}
/**
- * Adds a new segment. It automatically sets the SQL segment depending on the column name in case none is set
- * already.
- * @see \Piwik\Columns\Dimension::addSegment()
- * @param Segment $segment
- * @api
- */
- protected function addSegment(Segment $segment)
- {
- if (!$segment->getSegment() && $this->segmentName) {
- $segment->setSegment($this->segmentName);
- }
-
- if (!$segment->getType()) {
- $metricTypes = array(self::TYPE_NUMBER, self::TYPE_FLOAT, self::TYPE_MONEY, self::TYPE_DURATION_S, self::TYPE_DURATION_MS);
- if (in_array($this->getType(), $metricTypes, $strict = true)) {
- $segment->setType(Segment::TYPE_METRIC);
- } else {
- $segment->setType(Segment::TYPE_DIMENSION);
- }
- }
-
- if (!$segment->getCategoryId() && $this->category) {
- $segment->setCategory($this->category);
- }
-
- if (!$segment->getName() && $this->nameSingular) {
- $segment->setName($this->nameSingular);
- }
-
- $sqlSegment = $segment->getSqlSegment();
-
- if (empty($sqlSegment) && !$segment->getUnionOfSegments()) {
- if (!empty($this->sqlSegment)) {
- $segment->setSqlSegment($this->sqlSegment);
- } elseif ($this->dbTableName && $this->columnName) {
- $segment->setSqlSegment($this->dbTableName . '.' . $this->columnName);
- } else {
- throw new Exception('Segment cannot be added because no sql segment is set');
- }
- }
-
- if (!$this->suggestedValuesCallback) {
- // we can generate efficient value callback for enums automatically
- $enum = $this->getEnumColumnValues();
- if (!empty($enum)) {
- $this->suggestedValuesCallback = function ($idSite, $maxValuesToReturn) use ($enum) {
- $values = array_values($enum);
- return array_slice($values, 0, $maxValuesToReturn);
- };
- }
- }
-
- if (!$this->acceptValues) {
- // we can generate accept values for enums automatically
- $enum = $this->getEnumColumnValues();
- if (!empty($enum)) {
- $enumValues = array_values($enum);
- $enumValues = array_slice($enumValues, 0, 20);
- $this->acceptValues = 'Eg. ' . implode(', ', $enumValues);
- };
- }
-
- if ($this->acceptValues && !$segment->getAcceptValues()) {
- $segment->setAcceptedValues($this->acceptValues);
- }
-
- if (!$this->sqlFilterValue && !$segment->getSqlFilter() && !$segment->getSqlFilterValue()) {
- // no sql filter configured, we try to configure automatically for enums
- $enum = $this->getEnumColumnValues();
- if (!empty($enum)) {
- $this->sqlFilterValue = function ($value, $sqlSegmentName) use ($enum) {
- if (isset($enum[$value])) {
- return $value;
- }
-
- $id = array_search($value, $enum);
-
- if ($id === false) {
- $id = array_search(strtolower(trim(urldecode($value))), $enum);
-
- if ($id === false) {
- throw new \Exception("Invalid '$sqlSegmentName' segment value $value");
- }
- }
-
- return $id;
- };
- };
- }
-
- if ($this->suggestedValuesCallback && !$segment->getSuggestedValuesCallback()) {
- $segment->setSuggestedValuesCallback($this->suggestedValuesCallback);
- }
-
- if ($this->suggestedValuesApi) {
- $segment->setSuggestedValuesApi($this->suggestedValuesApi);
- }
-
- if ($this->sqlFilterValue && !$segment->getSqlFilterValue()) {
- $segment->setSqlFilterValue($this->sqlFilterValue);
- }
-
- if ($this->sqlFilter && !$segment->getSqlFilter()) {
- $segment->setSqlFilter($this->sqlFilter);
- }
-
- if (!$this->allowAnonymous) {
- $segment->setRequiresAtLeastViewAccess(true);
- }
-
- $this->segments[] = $segment;
- }
-
- /**
* Get the list of configured segments.
+ *
* @return Segment[]
+ * @throws Exception
* @ignore
*/
public function getSegments()
{
- if (empty($this->segments)) {
- $this->configureSegments();
- }
-
- return $this->segments;
+ $list = new SegmentsList();
+ $this->configureSegments($list, new DimensionSegmentFactory($this));
+ return $list->getSegments();
}
/**
@@ -697,6 +588,51 @@ abstract class Dimension
}
/**
+ * @return null|callable
+ * @ignore
+ */
+ public function getSuggestedValuesCallback()
+ {
+ return $this->suggestedValuesCallback;
+ }
+
+ /**
+ * @return null|string
+ * @ignore
+ */
+ public function getSuggestedValuesApi()
+ {
+ return $this->suggestedValuesApi;
+ }
+
+ /**
+ * @return null|string
+ * @ignore
+ */
+ public function getAcceptValues()
+ {
+ return $this->acceptValues;
+ }
+
+ /**
+ * @return \Closure|string|null
+ * @ignore
+ */
+ public function getSqlFilter()
+ {
+ return $this->sqlFilter;
+ }
+
+ /**
+ * @return array|string|null
+ * @ignore
+ */
+ public function getSqlFilterValue()
+ {
+ return $this->sqlFilterValue;
+ }
+
+ /**
* Check whether the dimension has a column type configured
* @return bool
* @ignore
diff --git a/core/Columns/DimensionSegmentFactory.php b/core/Columns/DimensionSegmentFactory.php
new file mode 100644
index 0000000000..1c29123a25
--- /dev/null
+++ b/core/Columns/DimensionSegmentFactory.php
@@ -0,0 +1,178 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ *
+ */
+namespace Piwik\Columns;
+
+use Piwik\Plugin\Segment;
+
+
+/**
+ * A factory to create segments from a dimension.
+ *
+ * @api since Matomo 4.0.0
+ */
+class DimensionSegmentFactory
+{
+ /**
+ * @var Dimension
+ */
+ private $dimension = null;
+
+ /**
+ * Generates a new dimension segment factory.
+ * @param Dimension $dimension A dimension instance the created segments should be based on.
+ */
+ public function __construct(Dimension $dimension)
+ {
+ $this->dimension = $dimension;
+ }
+
+ /**
+ * Creates a segment based on the dimension properties
+ *
+ * @param Segment|null $segment optional Segment to enrich with dimension data (if properties not already set)
+ * @return Segment
+ * @throws \Exception
+ */
+ public function createSegment(Segment $segment = null)
+ {
+ $dimension = $this->dimension;
+
+ if (!$segment instanceof Segment) {
+ $segment = new Segment();
+ }
+
+ if (!$segment->getSegment() && $dimension->getSegmentName()) {
+ $segment->setSegment($dimension->getSegmentName());
+ }
+
+ if (!$segment->getType()) {
+ $metricTypes = array(Dimension::TYPE_NUMBER, Dimension::TYPE_FLOAT, Dimension::TYPE_MONEY, Dimension::TYPE_DURATION_S, Dimension::TYPE_DURATION_MS);
+ if (in_array($dimension->getType(), $metricTypes, $strict = true)) {
+ $segment->setType(Segment::TYPE_METRIC);
+ } else {
+ $segment->setType(Segment::TYPE_DIMENSION);
+ }
+ }
+
+ if (!$segment->getCategoryId() && $dimension->getCategoryId()) {
+ $segment->setCategory($dimension->getCategoryId());
+ }
+
+ if (!$segment->getName() && $dimension->getName()) {
+ $segment->setName($dimension->getName());
+ }
+
+ $sqlSegment = $segment->getSqlSegment();
+
+ if (empty($sqlSegment) && !$segment->getUnionOfSegments()) {
+ if (!empty($dimension->getSqlSegment())) {
+ $segment->setSqlSegment($dimension->getSqlSegment());
+ } elseif ($dimension->getDbTableName() && $dimension->getColumnName()) {
+ $segment->setSqlSegment($dimension->getDbTableName() . '.' . $dimension->getColumnName());
+ } else {
+ throw new \Exception('Segment cannot be added because no sql segment is set');
+ }
+ }
+
+ $acceptValues = $dimension->getAcceptValues() ?: $this->guessAcceptValues();
+
+ if ($acceptValues && !$segment->getAcceptValues()) {
+ $segment->setAcceptedValues($acceptValues);
+ }
+
+ $suggestedValuesCallback = $dimension->getSuggestedValuesCallback() ?: $this->guessSuggestedValuesCallback();
+
+ if ($suggestedValuesCallback && !$segment->getSuggestedValuesCallback()) {
+ $segment->setSuggestedValuesCallback($suggestedValuesCallback);
+ }
+
+ if ($dimension->getSuggestedValuesApi()) {
+ $segment->setSuggestedValuesApi($dimension->getSuggestedValuesApi());
+ }
+
+ $sqlFilter = $dimension->getSqlFilter();
+
+ if (!$sqlFilter && !$dimension->getSqlFilterValue() && !$segment->getSqlFilter() && !$segment->getSqlFilterValue()) {
+ $sqlFilter = $this->guessSqlFilter();
+ }
+
+ if ($dimension->getSqlFilterValue() && !$segment->getSqlFilterValue()) {
+ $segment->setSqlFilterValue($dimension->getSqlFilterValue());
+ }
+
+ if ($sqlFilter && !$segment->getSqlFilter()) {
+ $segment->setSqlFilter($sqlFilter);
+ }
+
+ if (!$dimension->isAnonymousAllowed()) {
+ $segment->setRequiresRegisteredUser(true);
+ }
+
+ return $segment;
+ }
+
+ protected function guessSqlFilter()
+ {
+ $sqlFilterValue = null;
+
+ $enum = $this->dimension->getEnumColumnValues();
+ if (!empty($enum)) {
+ $sqlFilterValue = function ($value, $sqlSegmentName) use ($enum) {
+ if (isset($enum[$value])) {
+ return $value;
+ }
+
+ $id = array_search($value, $enum);
+
+ if ($id === false) {
+ $id = array_search(strtolower(trim(urldecode($value))), $enum);
+
+ if ($id === false) {
+ throw new \Exception("Invalid '$sqlSegmentName' segment value $value");
+ }
+ }
+
+ return $id;
+ };
+ }
+
+ return $sqlFilterValue;
+ }
+
+ protected function guessAcceptValues()
+ {
+ $acceptValues = null;
+
+ // we can generate accept values for enums automatically
+ $enum = $this->dimension->getEnumColumnValues();
+ if (!empty($enum)) {
+ $enumValues = array_values($enum);
+ $enumValues = array_slice($enumValues, 0, 20);
+ $acceptValues = 'Eg. ' . implode(', ', $enumValues);
+ }
+
+ return $acceptValues;
+ }
+
+ protected function guessSuggestedValuesCallback()
+ {
+ $suggestedValuesCallback = null;
+
+ // we can generate efficient value callback for enums automatically
+ $enum = $this->dimension->getEnumColumnValues();
+ if (!empty($enum)) {
+ $suggestedValuesCallback = function ($idSite, $maxValuesToReturn) use ($enum) {
+ $values = array_values($enum);
+ return array_slice($values, 0, $maxValuesToReturn);
+ };
+ }
+
+ return $suggestedValuesCallback;
+ }
+} \ No newline at end of file
diff --git a/core/Plugin/Segment.php b/core/Plugin/Segment.php
index 5e09c409c1..122833835a 100644
--- a/core/Plugin/Segment.php
+++ b/core/Plugin/Segment.php
@@ -58,12 +58,11 @@ class Segment
private $suggestedValuesApi = '';
/**
- * If true, this segment will only be visible to the user if the user has view access
- * to one of the requested sites (see API.getSegmentsMetadata).
+ * If true, this segment will only be visible to a registered user (see API.getSegmentsMetadata).
*
* @var bool
*/
- private $requiresAtLeastViewAccess = false;
+ private $requiresRegisteredUser = false;
/**
* @ignore
@@ -382,28 +381,27 @@ class Segment
}
/**
- * Returns true if this segment should only be visible to the user if the user has view access
- * to one of the requested sites (see API.getSegmentsMetadata), false if it should always be
- * visible to the user (even the anonymous user).
+ * Returns true if this segment should only be visible to registered users (see API.getSegmentsMetadata),
+ * false if it should always be visible to any user (even the anonymous user).
*
* @return boolean
* @ignore
*/
- public function isRequiresAtLeastViewAccess()
+ public function isRequiresRegisteredUser()
{
- return $this->requiresAtLeastViewAccess;
+ return $this->requiresRegisteredUser;
}
/**
- * Sets whether the segment should only be visible if the user requesting it has view access
- * to one of the requested sites and if the user is not the anonymous user.
+ * Sets whether the segment should only be visible to registered users. If set to false it will be even visible to
+ * the anonymous user
*
- * @param boolean $requiresAtLeastViewAccess
+ * @param boolean $requiresRegisteredUser
* @ignore
*/
- public function setRequiresAtLeastViewAccess($requiresAtLeastViewAccess)
+ public function setRequiresRegisteredUser($requiresRegisteredUser)
{
- $this->requiresAtLeastViewAccess = $requiresAtLeastViewAccess;
+ $this->requiresRegisteredUser = $requiresRegisteredUser;
}
/**
diff --git a/core/Segment/SegmentsList.php b/core/Segment/SegmentsList.php
new file mode 100644
index 0000000000..82ea86065e
--- /dev/null
+++ b/core/Segment/SegmentsList.php
@@ -0,0 +1,140 @@
+<?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\Segment;
+
+use Piwik\Cache;
+use Piwik\CacheId;
+use Piwik\Columns\Dimension;
+use Piwik\Columns\DimensionSegmentFactory;
+use Piwik\Piwik;
+use Piwik\Plugin\Segment;
+
+/**
+ * Manages the global list of segments that can be used.
+ *
+ * Segments are added automatically by dimensions as well as through the {@hook Segment.addSegments} event.
+ * Observers for this event should call the {@link addSegment()} method to add segments or use any of the other
+ * methods to remove segments.
+ *
+ * @api since Piwik 4.0.0
+ */
+class SegmentsList
+{
+ /**
+ * List of segments
+ *
+ * @var Segment[]
+ */
+ private $segments = array();
+
+ private $segmentsByNameCache = array();
+
+ /**
+ * @param Segment $segment
+ */
+ public function addSegment(Segment $segment)
+ {
+ $this->segments[] = $segment;
+ $this->segmentsByNameCache = array();
+ }
+
+ /**
+ * Get all available segments.
+ *
+ * @return Segment[]
+ */
+ public function getSegments()
+ {
+ return $this->segments;
+ }
+
+ /**
+ * Removes one or more segments from the segments list.
+ *
+ * @param string $segmentCategory The segment category id. Can be a translation token eg 'General_Visits'
+ * see {@link Segment::getCategoryId()}.
+ * @param string|false $segmentExpression The segment expression name to remove eg 'pageUrl'.
+ * If not supplied, all segments within that category will be removed.
+ */
+ public function remove($segmentCategory, $segmentExpression = false)
+ {
+ foreach ($this->segments as $index => $segment) {
+ if ($segment->getCategoryId() === $segmentCategory) {
+ if (!$segmentExpression || $segment->getSegment() === $segmentExpression) {
+ unset($this->segments[$index]);
+ $this->segmentsByNameCache = array();
+ }
+ }
+ }
+ }
+
+ /**
+ * @param string $segmentExpression Name of the segment expression. eg `pageUrl`
+ * @return Segment|null
+ */
+ public function getSegment($segmentExpression)
+ {
+ if (empty($this->segmentsByNameCache)) {
+ foreach ($this->segments as $index => $segment) {
+ $this->segmentsByNameCache[$segment->getSegment()] = $segment;
+ }
+ }
+
+ if (!empty($this->segmentsByNameCache[$segmentExpression])) {
+ return $this->segmentsByNameCache[$segmentExpression];
+ }
+
+ return null;
+ }
+
+ /**
+ * Get all metrics defined in the Piwik platform.
+ * @ignore
+ * @return static
+ */
+ public static function get()
+ {
+ $cache = Cache::getTransientCache();
+ $cacheKey = CacheId::siteAware('SegmentsList');
+
+ if ($cache->contains($cacheKey)) {
+ return $cache->fetch($cacheKey);
+ }
+
+ $list = new static;
+
+ /**
+ * Triggered to add custom segment definitions.
+ *
+ * **Example**
+ *
+ * public function addSegments(&$segments)
+ * {
+ * $segment = new Segment();
+ * $segment->setSegment('my_segment_name');
+ * $segment->setType(Segment::TYPE_DIMENSION);
+ * $segment->setName('My Segment Name');
+ * $segment->setSqlSegment('log_table.my_segment_name');
+ * $segments[] = $segment;
+ * }
+ *
+ * @param SegmentsList $list An instance of the SegmentsList. You can add segments to the list this way.
+ */
+ Piwik::postEvent('Segment.addSegments', array($list));
+
+ foreach (Dimension::getAllDimensions() as $dimension) {
+ $dimension->configureSegments($list, new DimensionSegmentFactory($dimension));
+ }
+
+ $cache->save($cacheKey, $list);
+
+ return $list;
+ }
+
+}
diff --git a/plugins/API/SegmentMetadata.php b/plugins/API/SegmentMetadata.php
index ca6cf0e470..28a05b06de 100644
--- a/plugins/API/SegmentMetadata.php
+++ b/plugins/API/SegmentMetadata.php
@@ -12,6 +12,7 @@ use Piwik\Category\CategoryList;
use Piwik\Columns\Dimension;
use Piwik\Piwik;
use Piwik\Plugin\Segment;
+use Piwik\Segment\SegmentsList;
class SegmentMetadata
{
@@ -21,48 +22,21 @@ class SegmentMetadata
*/
private $categoryOrder = array();
- public function getSegmentsMetadata($idSites = array(), $_hideImplementationData = true, $isAuthenticatedWithViewAccess, $_showAllSegments = false)
+ public function getSegmentsMetadata($idSites, $_hideImplementationData, $isRegisteredUser, $_showAllSegments = false)
{
- $segments = array();
-
- /**
- * Triggered to add custom segment definitions.
- *
- * **Example**
- *
- * public function addSegments(&$segments)
- * {
- * $segment = new Segment();
- * $segment->setSegment('my_segment_name');
- * $segment->setType(Segment::TYPE_DIMENSION);
- * $segment->setName('My Segment Name');
- * $segment->setSqlSegment('log_table.my_segment_name');
- * $segments[] = $segment;
- * }
- *
- * @param array &$segments An array containing a list of segment entries.
- */
- Piwik::postEvent('Segment.addSegments', array(&$segments));
-
- foreach (Dimension::getAllDimensions() as $dimension) {
- foreach ($dimension->getSegments() as $segment) {
- if (!$_showAllSegments
- && $segment->isInternal()
- ) {
- continue;
- }
-
- $segments[] = $segment;
- }
- }
-
/** @var Segment[] $dimensionSegments */
- $dimensionSegments = $segments;
+ $dimensionSegments = SegmentsList::get()->getSegments();
$segments = array();
foreach ($dimensionSegments as $segment) {
- if ($segment->isRequiresAtLeastViewAccess()) {
- $segment->setPermission($isAuthenticatedWithViewAccess);
+ if (!$_showAllSegments
+ && $segment->isInternal()
+ ) {
+ continue;
+ }
+
+ if ($segment->isRequiresRegisteredUser()) {
+ $segment->setPermission($isRegisteredUser);
}
$segments[] = $segment->toArray();
diff --git a/plugins/Actions/Columns/ActionUrl.php b/plugins/Actions/Columns/ActionUrl.php
index df6705be23..9a591bbbfa 100644
--- a/plugins/Actions/Columns/ActionUrl.php
+++ b/plugins/Actions/Columns/ActionUrl.php
@@ -8,22 +8,23 @@
*/
namespace Piwik\Plugins\Actions\Columns;
-use Piwik\Piwik;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Plugin\Dimension\ActionDimension;
use Piwik\Plugins\Actions\Segment;
+use Piwik\Segment\SegmentsList;
class ActionUrl extends ActionDimension
{
protected $nameSingular = 'Actions_ColumnActionURL';
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setSegment('actionUrl');
$segment->setName('Actions_ColumnActionURL');
$segment->setUnionOfSegments(array('pageUrl', 'downloadUrl', 'outlinkUrl', 'eventUrl'));
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
}
diff --git a/plugins/Bandwidth b/plugins/Bandwidth
-Subproject 7565711c862896ddfdde766aa5fce3080294dbf
+Subproject 7d2d569d6f7b1411ba7bbd8a2df28b897f832ea
diff --git a/plugins/CoreHome/Columns/LinkVisitActionIdPages.php b/plugins/CoreHome/Columns/LinkVisitActionIdPages.php
index fe8355f2f8..c218ce7090 100644
--- a/plugins/CoreHome/Columns/LinkVisitActionIdPages.php
+++ b/plugins/CoreHome/Columns/LinkVisitActionIdPages.php
@@ -9,11 +9,13 @@
namespace Piwik\Plugins\CoreHome\Columns;
use Piwik\Columns\DimensionMetricFactory;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Columns\Discriminator;
use Piwik\Columns\MetricsList;
use Piwik\Piwik;
use Piwik\Plugin\ArchivedMetric;
use Piwik\Plugin\Dimension\ActionDimension;
+use Piwik\Segment\SegmentsList;
use Piwik\Tracker\Action;
class LinkVisitActionIdPages extends ActionDimension
@@ -23,7 +25,7 @@ class LinkVisitActionIdPages extends ActionDimension
protected $nameSingular = 'General_Actions';
protected $type = self::TYPE_NUMBER;
- public function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
// empty so we don't auto-generate a segment
}
diff --git a/plugins/CoreHome/Columns/VisitId.php b/plugins/CoreHome/Columns/VisitId.php
index b55501a9f2..cea3a1f1cf 100644
--- a/plugins/CoreHome/Columns/VisitId.php
+++ b/plugins/CoreHome/Columns/VisitId.php
@@ -9,11 +9,13 @@
namespace Piwik\Plugins\CoreHome\Columns;
use Piwik\Columns\DimensionMetricFactory;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Columns\MetricsList;
use Piwik\Piwik;
use Piwik\Plugin\ArchivedMetric;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugin\Segment;
+use Piwik\Segment\SegmentsList;
/**
* Dimension for the log_visit.idvisit column. This column is added in the CREATE TABLE
@@ -30,11 +32,11 @@ class VisitId extends VisitDimension
protected $metricId = 'visits';
protected $type = self::TYPE_TEXT;
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setName('General_VisitId');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
public function configureMetrics(MetricsList $metricsList, DimensionMetricFactory $dimensionMetricFactory)
diff --git a/plugins/CoreHome/Columns/VisitIp.php b/plugins/CoreHome/Columns/VisitIp.php
index f7f09e56f4..9a75b5856f 100644
--- a/plugins/CoreHome/Columns/VisitIp.php
+++ b/plugins/CoreHome/Columns/VisitIp.php
@@ -8,11 +8,13 @@
namespace Piwik\Plugins\CoreHome\Columns;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Common;
use Piwik\Metrics\Formatter;
use Matomo\Network\IPUtils;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugin\Segment;
+use Piwik\Segment\SegmentsList;
/**
* Dimension for the log_visit.location_ip column. This column is added in the CREATE TABLE
@@ -36,10 +38,10 @@ class VisitIp extends VisitDimension
return $value;
}
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setType(Segment::TYPE_METRIC); // we cannot remove this for now as it would assign dimension based on text type
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
}
diff --git a/plugins/CustomDimensions b/plugins/CustomDimensions
-Subproject e86b861b843491384be107f5d474af87fe10b41
+Subproject 3e8dad6798e272e6e38de421d7fa2f49cfd2170
diff --git a/plugins/CustomVariables/Columns/Base.php b/plugins/CustomVariables/Columns/Base.php
index 070aaeed98..928de6f91e 100644
--- a/plugins/CustomVariables/Columns/Base.php
+++ b/plugins/CustomVariables/Columns/Base.php
@@ -8,14 +8,16 @@
namespace Piwik\Plugins\CustomVariables\Columns;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Piwik;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\CustomVariables\Segment;
use Piwik\Plugins\CustomVariables\CustomVariables;
+use Piwik\Segment\SegmentsList;
class Base extends VisitDimension
{
- protected function configureSegmentsFor($segmentNameSuffix)
+ protected function configureSegmentsFor($segmentNameSuffix, SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$numCustomVariables = CustomVariables::getNumUsableCustomVariables();
@@ -24,14 +26,14 @@ class Base extends VisitDimension
$segment->setSegment('customVariable' . $segmentNameSuffix);
$segment->setName($this->getName() . ' (' . Piwik::translate('CustomVariables_ScopeVisit') . ')');
$segment->setUnionOfSegments($this->getSegmentColumns('customVariable' . $segmentNameSuffix, $numCustomVariables));
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
$segment = new Segment();
$segment->setType('dimension');
$segment->setSegment('customVariablePage' . $segmentNameSuffix);
$segment->setName($this->getName() . ' (' . Piwik::translate('CustomVariables_ScopePage') . ')');
$segment->setUnionOfSegments($this->getSegmentColumns('customVariablePage' . $segmentNameSuffix, $numCustomVariables));
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
$segmentSuffix = 'v';
if (strtolower($segmentNameSuffix) === 'name') {
@@ -44,14 +46,14 @@ class Base extends VisitDimension
$segment->setSqlSegment('log_visit.custom_var_' . $segmentSuffix . $i);
$segment->setName(Piwik::translate('CustomVariables_ColumnCustomVariable' . $segmentNameSuffix) . ' ' . $i
. ' (' . Piwik::translate('CustomVariables_ScopeVisit') . ')');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
$segment = new Segment();
$segment->setSegment('customVariablePage' . $segmentNameSuffix . $i);
$segment->setSqlSegment('log_link_visit_action.custom_var_' . $segmentSuffix . $i);
$segment->setName(Piwik::translate('CustomVariables_ColumnCustomVariable' . $segmentNameSuffix) . ' ' . $i
. ' (' . Piwik::translate('CustomVariables_ScopePage') . ')');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
}
diff --git a/plugins/CustomVariables/Columns/CustomVariableName.php b/plugins/CustomVariables/Columns/CustomVariableName.php
index d094bd0588..8e03352f94 100644
--- a/plugins/CustomVariables/Columns/CustomVariableName.php
+++ b/plugins/CustomVariables/Columns/CustomVariableName.php
@@ -8,13 +8,15 @@
*/
namespace Piwik\Plugins\CustomVariables\Columns;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Piwik;
+use Piwik\Segment\SegmentsList;
class CustomVariableName extends Base
{
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
- $this->configureSegmentsFor('Name');
+ $this->configureSegmentsFor('Name', $segmentsList, $dimensionSegmentFactory);
}
public function getName()
diff --git a/plugins/CustomVariables/Columns/CustomVariableValue.php b/plugins/CustomVariables/Columns/CustomVariableValue.php
index dafd3c87ba..74d44f35d4 100644
--- a/plugins/CustomVariables/Columns/CustomVariableValue.php
+++ b/plugins/CustomVariables/Columns/CustomVariableValue.php
@@ -8,13 +8,15 @@
*/
namespace Piwik\Plugins\CustomVariables\Columns;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Piwik;
+use Piwik\Segment\SegmentsList;
class CustomVariableValue extends Base
{
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
- $this->configureSegmentsFor('Value');
+ $this->configureSegmentsFor('Value', $segmentsList, $dimensionSegmentFactory);
}
public function getName()
diff --git a/plugins/DevicesDetection/Columns/BrowserName.php b/plugins/DevicesDetection/Columns/BrowserName.php
index 9a1e59ee23..58df84ba6f 100644
--- a/plugins/DevicesDetection/Columns/BrowserName.php
+++ b/plugins/DevicesDetection/Columns/BrowserName.php
@@ -9,9 +9,11 @@
namespace Piwik\Plugins\DevicesDetection\Columns;
use DeviceDetector\Parser\Client\Browser;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Common;
use Piwik\Metrics\Formatter;
use Piwik\Plugin\Segment;
+use Piwik\Segment\SegmentsList;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
@@ -26,11 +28,11 @@ class BrowserName extends Base
protected $acceptValues = 'FF, IE, CH, SF, OP etc.';
protected $type = self::TYPE_TEXT;
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setName('DevicesDetection_BrowserCode');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
$segment = new Segment();
$segment->setSegment('browserName');
@@ -52,7 +54,7 @@ class BrowserName extends Base
$segment->setSuggestedValuesCallback(function ($idSite, $maxValuesToReturn) {
return array_values(Browser::getAvailableBrowsers() + ['Unknown']);
});
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
public function formatValue($value, $idSite, Formatter $formatter)
diff --git a/plugins/DevicesDetection/Columns/Os.php b/plugins/DevicesDetection/Columns/Os.php
index 947a35490c..200f93b055 100644
--- a/plugins/DevicesDetection/Columns/Os.php
+++ b/plugins/DevicesDetection/Columns/Os.php
@@ -9,10 +9,12 @@
namespace Piwik\Plugins\DevicesDetection\Columns;
use DeviceDetector\Parser\OperatingSystem;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Common;
use Piwik\Metrics\Formatter;
use Piwik\Piwik;
use Piwik\Plugin\Segment;
+use Piwik\Segment\SegmentsList;
use Piwik\Tracker\Request;
use Piwik\Tracker\Settings;
use Piwik\Tracker\Visitor;
@@ -28,11 +30,11 @@ class Os extends Base
protected $acceptValues = 'WIN, LIN, MAX, AND, IOS etc.';
protected $type = self::TYPE_TEXT;
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setName('DevicesDetection_OperatingSystemCode');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
$segment = new Segment();
$segment->setSegment('operatingSystemName');
@@ -54,7 +56,7 @@ class Os extends Base
$segment->setSuggestedValuesCallback(function ($idSite, $maxValuesToReturn) {
return array_values(OperatingSystem::getAvailableOperatingSystems() + ['Unknown']);
});
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
public function formatValue($value, $idSite, Formatter $formatter)
diff --git a/plugins/Ecommerce/Columns/ProductCategory.php b/plugins/Ecommerce/Columns/ProductCategory.php
index 6ec80b649e..bd4c0d07a6 100644
--- a/plugins/Ecommerce/Columns/ProductCategory.php
+++ b/plugins/Ecommerce/Columns/ProductCategory.php
@@ -9,8 +9,10 @@
namespace Piwik\Plugins\Ecommerce\Columns;
use Piwik\Columns\Dimension;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Piwik;
use Piwik\Plugin\Segment;
+use Piwik\Segment\SegmentsList;
class ProductCategory extends Dimension
{
@@ -20,7 +22,7 @@ class ProductCategory extends Dimension
protected $category = 'Goals_Ecommerce';
protected $nameSingular = 'Goals_ProductCategory';
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$individualProductCategorySegments = $this->getProductCategorySegments(self::PRODUCT_CATEGORY_COUNT);
@@ -39,7 +41,7 @@ class ProductCategory extends Dimension
$segment->setSqlFilter('\\Piwik\\Tracker\\TableLogAction::getIdActionFromSegment');
$segment->setSqlSegment('log_conversion_item.' . $productCategoryColumnName);
$segment->setIsInternal(true);
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
// add a union of these individual columns as productCategory
@@ -49,7 +51,7 @@ class ProductCategory extends Dimension
$segment->setSegment('productCategory');
$segment->setName($this->getName());
$segment->setUnionOfSegments($individualProductCategorySegments);
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
private function getProductCategorySegments($categoryCount)
diff --git a/plugins/MarketingCampaignsReporting b/plugins/MarketingCampaignsReporting
-Subproject 9cddfd243873665a88b7b68deaa700af38988b2
+Subproject 49d063b0869fa3440be9b34b07079a7ef3bb2c9
diff --git a/plugins/QueuedTracking b/plugins/QueuedTracking
-Subproject 8fa9104c2899a83ace185864c02d942b8f9e359
+Subproject 6f334d26951db3fdac572aa79247e1ce133290b
diff --git a/plugins/SegmentEditor/SegmentFormatter.php b/plugins/SegmentEditor/SegmentFormatter.php
index 15de12372c..2825efb738 100644
--- a/plugins/SegmentEditor/SegmentFormatter.php
+++ b/plugins/SegmentEditor/SegmentFormatter.php
@@ -10,8 +10,6 @@ namespace Piwik\Plugins\SegmentEditor;
use Exception;
use Piwik\Common;
-use Piwik\Config;
-use Piwik\Db;
use Piwik\Piwik;
use Piwik\Segment;
use Piwik\Segment\SegmentExpression;
@@ -21,7 +19,7 @@ use Piwik\Segment\SegmentExpression;
class SegmentFormatter
{
/**
- * @var SegmentList
+ * @var Segment\SegmentsList
*/
private $segmentList;
@@ -49,7 +47,7 @@ class SegmentFormatter
SegmentExpression::BOOL_OPERATOR_END => '',
);
- public function __construct(SegmentList $segmentList)
+ public function __construct(Segment\SegmentsList $segmentList)
{
$this->segmentList = $segmentList;
}
@@ -74,14 +72,14 @@ class SegmentFormatter
$operand = $expression[SegmentExpression::INDEX_OPERAND];
$name = $operand[SegmentExpression::INDEX_OPERAND_NAME];
- $segment = $this->segmentList->findSegment($name, $idSite);
+ $segment = $this->segmentList->getSegment($name);
if (empty($segment)) {
throw new Exception(sprintf("The segment '%s' does not exist.", $name));
}
- $readable .= $segment['name'] . ' ';
- $readable .= $this->getTranslationForComparison($operand, $segment['type']) . ' ';
+ $readable .= Piwik::translate($segment->getName()) . ' ';
+ $readable .= $this->getTranslationForComparison($operand, $segment->getType()) . ' ';
$readable .= $this->getFormattedValue($operand);
$readable .= $this->getTranslationForBoolOperator($operator) . ' ';
}
diff --git a/plugins/SegmentEditor/SegmentList.php b/plugins/SegmentEditor/SegmentList.php
deleted file mode 100644
index 32bbaf5375..0000000000
--- a/plugins/SegmentEditor/SegmentList.php
+++ /dev/null
@@ -1,33 +0,0 @@
-<?php
-/**
- * Piwik - 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\SegmentEditor;
-
-use Piwik\API\Request;
-use Piwik\Config;
-use Piwik\Db;
-
-/**
- */
-class SegmentList
-{
- public function findSegment($segmentName, $idSite)
- {
- $segments = Request::processRequest('API.getSegmentsMetadata', array(
- 'idSites' => array($idSite),
- 'filter_limit' => '-1'
- ));
-
- foreach ($segments as $segment) {
- if ($segment['segment'] == $segmentName && !empty($segmentName)) {
- return $segment;
- }
- }
- }
-
-}
diff --git a/plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php b/plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php
index a7db9f6666..0e0f250351 100644
--- a/plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php
+++ b/plugins/SegmentEditor/tests/Integration/SegmentFormatterTest.php
@@ -9,7 +9,7 @@
namespace Piwik\Plugins\SegmentEditor\tests\Integration;
use Piwik\Plugins\SegmentEditor\SegmentFormatter;
-use Piwik\Plugins\SegmentEditor\SegmentList;
+use Piwik\Segment\SegmentsList;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
@@ -32,10 +32,10 @@ class SegmentFormatterTest extends IntegrationTestCase
{
parent::setUp();
- $this->idSite = Fixture::createWebsite('2012-01-01 00:00:00');
- $this->formatter = new SegmentFormatter(new SegmentList());
-
Fixture::loadAllTranslations();
+
+ $this->idSite = Fixture::createWebsite('2012-01-01 00:00:00');
+ $this->formatter = new SegmentFormatter(SegmentsList::get());
}
public function tearDown(): void
diff --git a/plugins/SegmentEditor/tests/Integration/SegmentListTest.php b/plugins/SegmentEditor/tests/Integration/SegmentListTest.php
deleted file mode 100644
index 3a66a4bd4e..0000000000
--- a/plugins/SegmentEditor/tests/Integration/SegmentListTest.php
+++ /dev/null
@@ -1,73 +0,0 @@
-<?php
-/**
- * Piwik - 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\SegmentEditor\tests\Integration;
-
-use Piwik\Plugins\SegmentEditor\SegmentList;
-use Piwik\Tests\Framework\Fixture;
-use Piwik\Tests\Framework\Mock\FakeAccess;
-use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
-use Exception;
-
-/**
- * @group SegmentListTest
- * @group SegmentList
- * @group SegmentEditor
- * @group Plugins
- */
-class SegmentListTest extends IntegrationTestCase
-{
- /**
- * @var SegmentList
- */
- private $list;
-
- private $idSite;
-
- public function setUp(): void
- {
- parent::setUp();
-
- $this->idSite = Fixture::createWebsite('2012-01-01 00:00:00');
- $this->list = new SegmentList();
- }
-
- public function test_findSegment_shouldFindSegmentByName_IfNameExists()
- {
- $segmentName = 'pageUrl';
-
- $segment = $this->list->findSegment($segmentName, $this->idSite);
- self::assertIsArray($segment);
- $this->assertSame($segmentName, $segment['segment']);
- }
-
- public function test_findSegment_shouldNotFindSegmentByName_IfNameDoesNotExist()
- {
- $segment = $this->list->findSegment('aNyNotExisTinGSegmEnt', $this->idSite);
- $this->assertNull($segment);
- }
-
- public function test_findSegment_ShouldThrowException_IfNotEnoughPermission()
- {
- $this->expectException(\Exception::class);
- $this->expectExceptionMessage('checkUserHasViewAccess');
-
- FakeAccess::clearAccess($superUser = false, array(1));
-
- $segment = $this->list->findSegment('pageUrl', 999);
- $this->assertNull($segment);
- }
-
- public function provideContainerConfig()
- {
- return array(
- 'Piwik\Access' => new FakeAccess()
- );
- }
-
-}
diff --git a/plugins/UserCountry/Columns/Country.php b/plugins/UserCountry/Columns/Country.php
index 139e987746..f61151a1ae 100644
--- a/plugins/UserCountry/Columns/Country.php
+++ b/plugins/UserCountry/Columns/Country.php
@@ -8,6 +8,7 @@
*/
namespace Piwik\Plugins\UserCountry\Columns;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Common;
use Piwik\Config;
use Piwik\Container\StaticContainer;
@@ -19,6 +20,7 @@ use Piwik\Plugin\Manager;
use Piwik\Plugin\Segment;
use Piwik\Plugins\Provider\Provider as ProviderProvider;
use Piwik\Plugins\UserCountry\LocationProvider;
+use Piwik\Segment\SegmentsList;
use Piwik\Tracker\Visit;
use Piwik\Tracker\Visitor;
use Piwik\Tracker\Action;
@@ -38,11 +40,11 @@ class Country extends Base
protected $segmentName = 'countryCode';
protected $acceptValues = 'ISO 3166-1 alpha-2 country codes (de, us, fr, in, es, etc.)';
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setName('UserCountry_CountryCode');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
$segment = new Segment();
$segment->setSegment('countryName');
@@ -64,7 +66,7 @@ class Country extends Base
$segment->setSuggestedValuesCallback(function ($idSite, $maxValuesToReturn) use ($countryList) {
return array_values($countryList + ['Unknown']);
});
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
diff --git a/tests/PHPUnit/Integration/CacheIdTest.php b/tests/PHPUnit/Integration/CacheIdTest.php
index 7865d8d11c..0aed730921 100644
--- a/tests/PHPUnit/Integration/CacheIdTest.php
+++ b/tests/PHPUnit/Integration/CacheIdTest.php
@@ -133,7 +133,6 @@ class CacheIdTest extends IntegrationTestCase
],
// must support $_GET/$_POST values being arrays and not strings
- // because of, eg, SegmentList::findSegment
[
['idSite' => ['1', '2'], 'idSites' => ['9', '9'], 'idsite' => ['12', '13']],
['idSite' => ['4', '5'], 'idSites' => ['9', '8'], 'idsite' => ['14', '15']],
diff --git a/tests/PHPUnit/Integration/Columns/DimensionSegmentFactoryTest.php b/tests/PHPUnit/Integration/Columns/DimensionSegmentFactoryTest.php
new file mode 100644
index 0000000000..174ca5a978
--- /dev/null
+++ b/tests/PHPUnit/Integration/Columns/DimensionSegmentFactoryTest.php
@@ -0,0 +1,71 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Tests\Integration\Columns;
+
+use Piwik\Columns\Dimension;
+use Piwik\Columns\DimensionSegmentFactory;
+use Piwik\Plugin\Segment;
+use Piwik\Plugins\UserCountry\Columns\Country;
+use Piwik\Tests\Framework\Fixture;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+
+/**
+ * @group Core
+ * @group DimensionSegmentFactory
+ */
+class DimensionSegmentFactoryTest extends IntegrationTestCase
+{
+ /** @var Dimension */
+ private $country;
+
+ public function setUp(): void
+ {
+ parent::setUp();
+
+ Fixture::loadAllTranslations();
+
+ $this->country = new Country();
+ }
+
+ public function tearDown(): void
+ {
+ Fixture::resetTranslations();
+ parent::tearDown();
+ }
+
+ private function makeFactory($dimension)
+ {
+ return new DimensionSegmentFactory($dimension);
+ }
+
+ public function test_createSegment()
+ {
+ $factory = $this->makeFactory($this->country);
+ $segment = $factory->createSegment();
+
+ $this->assertSame('countryCode', $segment->getSegment());
+ $this->assertSame('Country', $segment->getName());
+ $this->assertSame('UserCountry_VisitLocation', $segment->getCategoryId());
+ $this->assertSame(Dimension::TYPE_DIMENSION, $segment->getType());
+ }
+
+ public function test_createSegment_predefined()
+ {
+ $factory = $this->makeFactory($this->country);
+ $segment = new Segment();
+ $segment->setName('My Name');
+ $segment->setCategory('My Category');
+ $segment = $factory->createSegment($segment);
+
+ $this->assertSame('countryCode', $segment->getSegment());
+ $this->assertSame('My Name', $segment->getName());
+ $this->assertSame('My Category', $segment->getCategoryId());
+ $this->assertSame(Dimension::TYPE_DIMENSION, $segment->getType());
+ }
+} \ No newline at end of file
diff --git a/tests/PHPUnit/Integration/Columns/DimensionTest.php b/tests/PHPUnit/Integration/Columns/DimensionTest.php
index 551da965d8..46db4c945e 100644
--- a/tests/PHPUnit/Integration/Columns/DimensionTest.php
+++ b/tests/PHPUnit/Integration/Columns/DimensionTest.php
@@ -8,15 +8,17 @@
namespace Piwik\Tests\Integration\Columns;
- // there is a test that requires the class to be defined in a plugin
+// there is a test that requires the class to be defined in a plugin
use Piwik\Columns\Dimension;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Plugin\Segment;
use Piwik\Metrics\Formatter;
use Piwik\Plugin\Dimension\ActionDimension;
use Piwik\Plugin\Dimension\ConversionDimension;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugin\Manager;
+use Piwik\Segment\SegmentsList;
use Piwik\Tests\Framework\Fixture;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
@@ -49,13 +51,13 @@ class CustomDimensionTest extends Dimension
$this->columnType = $columnType;
}
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setSegment('exitPageUrl');
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
// custom type and sqlSegment
$segment = new Segment();
@@ -64,7 +66,7 @@ class CustomDimensionTest extends Dimension
$segment->setType(Segment::TYPE_METRIC);
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
}
diff --git a/tests/PHPUnit/Integration/Plugin/Dimension/ActionDimensionTest.php b/tests/PHPUnit/Integration/Plugin/Dimension/ActionDimensionTest.php
index 68c2ede8e5..76b09529df 100644
--- a/tests/PHPUnit/Integration/Plugin/Dimension/ActionDimensionTest.php
+++ b/tests/PHPUnit/Integration/Plugin/Dimension/ActionDimensionTest.php
@@ -9,9 +9,11 @@
// there is a test that requires the class to be defined in a plugin
namespace Piwik\Plugins\Test;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Plugin\Dimension\ActionDimension;
use Piwik\Plugin\Segment;
use Piwik\Plugin\Manager;
+use Piwik\Segment\SegmentsList;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
class FakeActionDimension extends ActionDimension
@@ -24,13 +26,13 @@ class FakeActionDimension extends ActionDimension
$this->$param = $value;
}
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setSegment('exitPageUrl');
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
// custom type and sqlSegment
$segment = new Segment();
@@ -39,7 +41,7 @@ class FakeActionDimension extends ActionDimension
$segment->setType(Segment::TYPE_METRIC);
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
}
@@ -104,7 +106,10 @@ class ActionDimensionTest extends IntegrationTestCase
public function test_getSegment_ShouldReturnConfiguredSegments()
{
- $segments = $this->dimension->getSegments();
+ $list = new SegmentsList();
+ $this->dimension->configureSegments($list, new DimensionSegmentFactory($this->dimension));
+
+ $segments = $list->getSegments();
$this->assertCount(2, $segments);
$this->assertInstanceOf('\Piwik\Plugin\Segment', $segments[0]);
@@ -113,7 +118,10 @@ class ActionDimensionTest extends IntegrationTestCase
public function test_addSegment_ShouldPrefilSomeSegmentValuesIfNotDefinedYet()
{
- $segments = $this->dimension->getSegments();
+ $list = new SegmentsList();
+ $this->dimension->configureSegments($list, new DimensionSegmentFactory($this->dimension));
+
+ $segments = $list->getSegments();
$this->assertEquals('log_link_visit_action.fake_action_dimension_column', $segments[0]->getSqlSegment());
$this->assertEquals(Segment::TYPE_DIMENSION, $segments[0]->getType());
@@ -121,7 +129,10 @@ class ActionDimensionTest extends IntegrationTestCase
public function test_addSegment_ShouldNotOverwritePreAssignedValues()
{
- $segments = $this->dimension->getSegments();
+ $list = new SegmentsList();
+ $this->dimension->configureSegments($list, new DimensionSegmentFactory($this->dimension));
+
+ $segments = $list->getSegments();
$this->assertEquals('customValue', $segments[1]->getSqlSegment());
$this->assertEquals(Segment::TYPE_METRIC, $segments[1]->getType());
diff --git a/tests/PHPUnit/Integration/Plugin/Dimension/ConversionDimensionTest.php b/tests/PHPUnit/Integration/Plugin/Dimension/ConversionDimensionTest.php
index f4b40e2b28..68e8ca37dc 100644
--- a/tests/PHPUnit/Integration/Plugin/Dimension/ConversionDimensionTest.php
+++ b/tests/PHPUnit/Integration/Plugin/Dimension/ConversionDimensionTest.php
@@ -9,9 +9,11 @@
// there is a test that requires the class to be defined in a plugin
namespace Piwik\Plugins\Test;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Plugin\Dimension\ConversionDimension;
use Piwik\Plugin\Segment;
use Piwik\Plugin\Manager;
+use Piwik\Segment\SegmentsList;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
class FakeConversionDimension extends ConversionDimension
@@ -24,13 +26,13 @@ class FakeConversionDimension extends ConversionDimension
$this->$param = $value;
}
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setSegment('exitPageUrl');
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
// custom type and sqlSegment
$segment = new Segment();
@@ -39,7 +41,7 @@ class FakeConversionDimension extends ConversionDimension
$segment->setType(Segment::TYPE_METRIC);
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
}
@@ -104,7 +106,10 @@ class ConversionDimensionTest extends IntegrationTestCase
public function test_getSegment_ShouldReturnConfiguredSegments()
{
- $segments = $this->dimension->getSegments();
+ $list = new SegmentsList();
+ $this->dimension->configureSegments($list, new DimensionSegmentFactory($this->dimension));
+
+ $segments = $list->getSegments();
$this->assertCount(2, $segments);
$this->assertInstanceOf('\Piwik\Plugin\Segment', $segments[0]);
@@ -113,7 +118,10 @@ class ConversionDimensionTest extends IntegrationTestCase
public function test_addSegment_ShouldPrefilSomeSegmentValuesIfNotDefinedYet()
{
- $segments = $this->dimension->getSegments();
+ $list = new SegmentsList();
+ $this->dimension->configureSegments($list, new DimensionSegmentFactory($this->dimension));
+
+ $segments = $list->getSegments();
$this->assertEquals('log_conversion.fake_conversion_dimension_column', $segments[0]->getSqlSegment());
$this->assertEquals(Segment::TYPE_DIMENSION, $segments[0]->getType());
@@ -121,7 +129,10 @@ class ConversionDimensionTest extends IntegrationTestCase
public function test_addSegment_ShouldNotOverwritePreAssignedValues()
{
- $segments = $this->dimension->getSegments();
+ $list = new SegmentsList();
+ $this->dimension->configureSegments($list, new DimensionSegmentFactory($this->dimension));
+
+ $segments = $list->getSegments();
$this->assertEquals('customValue', $segments[1]->getSqlSegment());
$this->assertEquals(Segment::TYPE_METRIC, $segments[1]->getType());
diff --git a/tests/PHPUnit/Integration/Plugin/Dimension/VisitDimensionTest.php b/tests/PHPUnit/Integration/Plugin/Dimension/VisitDimensionTest.php
index 4ca8550d7d..56939657d9 100644
--- a/tests/PHPUnit/Integration/Plugin/Dimension/VisitDimensionTest.php
+++ b/tests/PHPUnit/Integration/Plugin/Dimension/VisitDimensionTest.php
@@ -9,9 +9,11 @@
// there is a test that requires the class to be defined in a plugin
namespace Piwik\Plugins\Test;
+use Piwik\Columns\DimensionSegmentFactory;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugin\Segment;
use Piwik\Plugin\Manager;
+use Piwik\Segment\SegmentsList;
use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
use Piwik\Tracker\Request;
use Piwik\Tracker\Visitor;
@@ -40,13 +42,13 @@ class FakeConversionVisitDimension extends FakeVisitDimension
return false;
}
- protected function configureSegments()
+ public function configureSegments(SegmentsList $segmentsList, DimensionSegmentFactory $dimensionSegmentFactory)
{
$segment = new Segment();
$segment->setSegment('exitPageUrl');
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
// custom type and sqlSegment
$segment = new Segment();
@@ -55,7 +57,7 @@ class FakeConversionVisitDimension extends FakeVisitDimension
$segment->setType(Segment::TYPE_METRIC);
$segment->setName('Actions_ColumnExitPageURL');
$segment->setCategory('General_Visit');
- $this->addSegment($segment);
+ $segmentsList->addSegment($dimensionSegmentFactory->createSegment($segment));
}
}
diff --git a/tests/PHPUnit/Integration/Segment/SegmentsListTest.php b/tests/PHPUnit/Integration/Segment/SegmentsListTest.php
new file mode 100644
index 0000000000..2066bb4de7
--- /dev/null
+++ b/tests/PHPUnit/Integration/Segment/SegmentsListTest.php
@@ -0,0 +1,79 @@
+<?php
+/**
+ * Piwik - free/libre analytics platform
+ *
+ * @link https://matomo.org
+ * @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
+ */
+
+namespace Piwik\Tests\Integration;
+
+use Piwik\Plugin\Segment;
+use Piwik\Segment\SegmentsList;
+use Piwik\Tests\Framework\TestCase\IntegrationTestCase;
+
+/**
+ * @group SegmentsListTest
+ * @group Segment
+ */
+class SegmentsListTest extends IntegrationTestCase
+{
+ public function testSegmentsList()
+ {
+ $list = new SegmentsList();
+
+ // add a segment
+ $segment = $this->getDummySegment('seg1');
+ $list->addSegment($segment);
+ $this->assertEquals([$segment], $list->getSegments());
+ $this->assertEquals($segment, $list->getSegment('seg1'));
+
+ // add another segment
+ $segment2 = $this->getDummySegment('seg2');
+ $list->addSegment($segment2);
+ $this->assertEquals([$segment, $segment2], $list->getSegments());
+ $this->assertEquals($segment, $list->getSegment('seg1'));
+ $this->assertEquals($segment2, $list->getSegment('seg2'));
+
+ // remove a segment
+ $list->remove($segment->getCategoryId(), $segment->getSegment());
+ $this->assertEquals([1 => $segment2], $list->getSegments());
+ $this->assertNull($list->getSegment('seg1'));
+ $this->assertEquals($segment2, $list->getSegment('seg2'));
+
+ // remove segment by category
+ $list->remove($segment2->getCategoryId());
+ $this->assertEquals([], $list->getSegments());
+ $this->assertNull($list->getSegment('seg1'));
+ $this->assertNull($list->getSegment('seg2'));
+ }
+
+ public function testGlobalSegmentsList()
+ {
+
+ $list = SegmentsList::get();
+ $segments = $list->getSegments();
+
+ // there should be at least 100 segments in core
+ $this->assertGreaterThan(100, count($segments));
+
+ // check some specific segments exists
+ $this->assertNotNull($list->getSegment('pageUrl'));
+ $this->assertNotNull($list->getSegment('countryCode'));
+ $this->assertNotNull($list->getSegment('countryName'));
+ $this->assertNotNull($list->getSegment('actions'));
+ }
+
+ /**
+ * @param $expr
+ * @return Segment
+ */
+ protected function getDummySegment($expr)
+ {
+ $segment = new Segment();
+ $segment->setName('Dummy');
+ $segment->setCategory('Dummy Cat');
+ $segment->setSegment($expr);
+ return $segment;
+ }
+}
diff --git a/tests/PHPUnit/Integration/SegmentTest.php b/tests/PHPUnit/Integration/SegmentTest.php
index 22586fa147..48698064bd 100644
--- a/tests/PHPUnit/Integration/SegmentTest.php
+++ b/tests/PHPUnit/Integration/SegmentTest.php
@@ -1883,13 +1883,13 @@ log_visit.visit_total_actions
{
return [
'observers.global' => [
- ['Segment.addSegments', function (&$segments) {
+ ['Segment.addSegments', function (Segment\SegmentsList $list) {
$segment = new \Piwik\Plugin\Segment();
$segment->setSegment('customSegment');
$segment->setType(\Piwik\Plugin\Segment::TYPE_DIMENSION);
$segment->setName('Custom Segment');
$segment->setSqlSegment('(UNIX_TIMESTAMP(log_visit.visit_first_action_time) - log_visit.visitor_days_since_first * 86400)');
- $segments[] = $segment;
+ $list->addSegment($segment);
}],
],
];
diff --git a/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml b/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
index dafd3e0a87..d9884a28d7 100644
--- a/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
+++ b/tests/PHPUnit/System/expected/test_apiGetReportMetadata__API.getSegmentsMetadata.xml
@@ -21,12 +21,6 @@
<row>
<type>metric</type>
<category>Visitors</category>
- <name>Days since last visit</name>
- <segment>daysSinceLastVisit</segment>
- </row>
- <row>
- <type>metric</type>
- <category>Visitors</category>
<name>Events</name>
<segment>events</segment>
<acceptedValues>To select all visits who triggered an Event, use: &amp;segment=events&gt;0</acceptedValues>
@@ -73,6 +67,12 @@
<permission>1</permission>
</row>
<row>
+ <type>metric</type>
+ <category>Visitors</category>
+ <name>Visits by days since last visit</name>
+ <segment>daysSinceLastVisit</segment>
+ </row>
+ <row>
<type>dimension</type>
<category>Visitors</category>
<name>Browser</name>
@@ -565,12 +565,6 @@
<row>
<type>dimension</type>
<category>Actions</category>
- <name>Category (Site Search)</name>
- <segment>siteSearchCategory</segment>
- </row>
- <row>
- <type>dimension</type>
- <category>Actions</category>
<name>Clicked Outlink</name>
<segment>outlinkUrl</segment>
</row>
@@ -660,6 +654,12 @@
<row>
<type>dimension</type>
<category>Actions</category>
+ <name>Search Category</name>
+ <segment>siteSearchCategory</segment>
+ </row>
+ <row>
+ <type>dimension</type>
+ <category>Actions</category>
<name>Server time - hour</name>
<segment>actionServerHour</segment>
</row>
diff --git a/tests/travis b/tests/travis
-Subproject ca0dfcfa2ca0e552fc65b77649dffbf101a6a17
+Subproject 99f5d4b992681e147f745165e34aec99da62df6