forked from vergnet/site-accueil-insa
178 lines
No EOL
5.5 KiB
PHP
178 lines
No EOL
5.5 KiB
PHP
<?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\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;
|
|
}
|
|
} |