PDF rausgenommen

This commit is contained in:
aschwarz
2023-01-23 11:03:31 +01:00
parent 82d562a322
commit a6523903eb
28078 changed files with 4247552 additions and 2 deletions

View File

@ -0,0 +1,180 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\API\Request;
use Piwik\Archive;
use Piwik\Container\StaticContainer;
use Piwik\DataTable;
use Piwik\Date;
use Piwik\Metrics;
use Piwik\Piwik;
use Piwik\Plugins\Actions\Actions\ActionSiteSearch;
/**
* The Custom Variables API lets you access reports for your <a href='http://matomo.org/docs/custom-variables/' rel='noreferrer' target='_blank'>Custom Variables</a> names and values.
*
* @method static \Piwik\Plugins\CustomVariables\API getInstance()
*/
class API extends \Piwik\Plugin\API
{
/**
* @param int $idSite
* @param string $period
* @param Date $date
* @param string $segment
* @param bool $expanded
* @param int $idSubtable
*
* @return DataTable|DataTable\Map
*/
protected function getDataTable($idSite, $period, $date, $segment, $expanded, $flat, $idSubtable)
{
$dataTable = Archive::createDataTableFromArchive(Archiver::CUSTOM_VARIABLE_RECORD_NAME, $idSite, $period, $date, $segment, $expanded, $flat, $idSubtable);
$dataTable->queueFilter('ColumnDelete', 'nb_uniq_visitors');
if ($flat) {
$dataTable->filterSubtables('Sort', array(Metrics::INDEX_NB_ACTIONS, 'desc', $naturalSort = false, $expanded));
$dataTable->queueFilterSubtables('ColumnDelete', 'nb_uniq_visitors');
}
return $dataTable;
}
/**
* @param int $idSite
* @param string $period
* @param Date $date
* @param string|bool $segment
* @param bool $expanded
* @param bool $_leavePiwikCoreVariables
* @param bool $flat
*
* @return DataTable|DataTable\Map
*/
public function getCustomVariables($idSite, $period, $date, $segment = false, $expanded = false, $_leavePiwikCoreVariables = false, $flat = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getDataTable($idSite, $period, $date, $segment, $expanded, $flat, $idSubtable = null);
if ($dataTable instanceof DataTable
&& !$_leavePiwikCoreVariables
) {
$mapping = self::getReservedCustomVariableKeys();
foreach ($mapping as $name) {
$row = $dataTable->getRowFromLabel($name);
if ($row) {
$dataTable->deleteRow($dataTable->getRowIdFromLabel($name));
}
}
}
if ($flat) {
$dataTable->filterSubtables('Piwik\Plugins\CustomVariables\DataTable\Filter\CustomVariablesValuesFromNameId');
} else {
$dataTable->filter('AddSegmentByLabel', array('customVariableName'));
}
return $dataTable;
}
/**
* @ignore
* @return array
*/
public static function getReservedCustomVariableKeys()
{
return array('_pks', '_pkn', '_pkc', '_pkp', ActionSiteSearch::CVAR_KEY_SEARCH_COUNT, ActionSiteSearch::CVAR_KEY_SEARCH_CATEGORY);
}
/**
* @param int $idSite
* @param string $period
* @param Date $date
* @param int $idSubtable
* @param string|bool $segment
* @param bool $_leavePriceViewedColumn
*
* @return DataTable|DataTable\Map
*/
public function getCustomVariablesValuesFromNameId($idSite, $period, $date, $idSubtable, $segment = false, $_leavePriceViewedColumn = false)
{
Piwik::checkUserHasViewAccess($idSite);
$dataTable = $this->getDataTable($idSite, $period, $date, $segment, $expanded = false, $flat = false, $idSubtable);
if (!$_leavePriceViewedColumn) {
$dataTable->deleteColumn('price_viewed');
} else {
// Hack Ecommerce product price tracking to display correctly
$dataTable->renameColumn('price_viewed', 'price');
}
$dataTable->filter('Piwik\Plugins\CustomVariables\DataTable\Filter\CustomVariablesValuesFromNameId');
return $dataTable;
}
/**
* Get a list of all available custom variable slots (scope + index) and which names have been used so far in
* each slot since the beginning of the website.
*
* @param int $idSite
* @return array
*/
public function getUsagesOfSlots($idSite)
{
Piwik::checkUserHasAdminAccess($idSite);
$numVars = CustomVariables::getNumUsableCustomVariables();
$usedCustomVariables = array(
'visit' => array_fill(1, $numVars, array()),
'page' => array_fill(1, $numVars, array()),
);
/** @var DataTable $customVarUsages */
$today = StaticContainer::get('CustomVariables.today');
$date = '2008-12-12,' . $today;
$customVarUsages = Request::processRequest('CustomVariables.getCustomVariables',
array('idSite' => $idSite, 'period' => 'range', 'date' => $date,
'format' => 'original')
);
foreach ($customVarUsages->getRows() as $row) {
$slots = $row->getMetadata('slots');
if (!empty($slots)) {
foreach ($slots as $slot) {
$usedCustomVariables[$slot['scope']][$slot['index']][] = array(
'name' => $row->getColumn('label'),
'nb_visits' => $row->getColumn('nb_visits'),
'nb_actions' => $row->getColumn('nb_actions'),
);
}
}
}
$grouped = array();
foreach ($usedCustomVariables as $scope => $scopes) {
foreach ($scopes as $index => $cvars) {
$grouped[] = array(
'scope' => $scope,
'index' => $index,
'usages' => $cvars
);
}
}
return $grouped;
}
}

View File

@ -0,0 +1,275 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\Config;
use Piwik\DataAccess\LogAggregator;
use Piwik\DataArray;
use Piwik\DataTable;
use Piwik\Metrics;
use Piwik\Tracker\GoalManager;
use Piwik\Tracker;
require_once PIWIK_INCLUDE_PATH . '/libs/PiwikTracker/PiwikTracker.php';
class Archiver extends \Piwik\Plugin\Archiver
{
const LABEL_CUSTOM_VALUE_NOT_DEFINED = "Value not defined";
const CUSTOM_VARIABLE_RECORD_NAME = 'CustomVariables_valueByName';
// Ecommerce reports use custom variables.
// We specifically set the limits high to get accurate Ecommerce reports
const MAX_ROWS_WHEN_ECOMMERCE = 50000;
/**
* @var DataArray
*/
protected $dataArray;
protected $maximumRowsInDataTableLevelZero;
protected $maximumRowsInSubDataTable;
protected $newEmptyRow;
private $metadata = array();
private $metadataFlat = array();
function __construct($processor)
{
parent::__construct($processor);
if ($processor->getParams()->getSite()->isEcommerceEnabled()) {
$this->maximumRowsInDataTableLevelZero = self::MAX_ROWS_WHEN_ECOMMERCE;
$this->maximumRowsInSubDataTable = self::MAX_ROWS_WHEN_ECOMMERCE;
} else {
$this->maximumRowsInDataTableLevelZero = Config::getInstance()->General['datatable_archiving_maximum_rows_custom_variables'];
$this->maximumRowsInSubDataTable = Config::getInstance()->General['datatable_archiving_maximum_rows_subtable_custom_variables'];
}
}
public function aggregateMultipleReports()
{
$columnsAggregationOperation = array('slots' => 'uniquearraymerge');
$this->getProcessor()->aggregateDataTableRecords(
self::CUSTOM_VARIABLE_RECORD_NAME,
$this->maximumRowsInDataTableLevelZero,
$this->maximumRowsInSubDataTable,
$columnToSort = Metrics::INDEX_NB_VISITS,
$columnsAggregationOperation,
$columnsToRenameAfterAggregation = null,
$countRowsRecursive = array());
}
public function aggregateDayReport()
{
$this->dataArray = new DataArray();
$maxCustomVariables = CustomVariables::getNumUsableCustomVariables();
for ($i = 1; $i <= $maxCustomVariables; $i++) {
$this->aggregateCustomVariable($i);
}
$this->removeVisitsMetricsFromActionsAggregate();
$this->dataArray->enrichMetricsWithConversions();
$table = $this->dataArray->asDataTable();
foreach ($table->getRows() as $row) {
$label = $row->getColumn('label');
if (!empty($this->metadata[$label])) {
foreach ($this->metadata[$label] as $name => $value) {
$row->addMetadata($name, $value);
}
}
}
$blob = $table->getSerialized(
$this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable,
$columnToSort = Metrics::INDEX_NB_VISITS
);
$this->getProcessor()->insertBlobRecord(self::CUSTOM_VARIABLE_RECORD_NAME, $blob);
}
protected function aggregateCustomVariable($slot)
{
$keyField = "custom_var_k" . $slot;
$valueField = "custom_var_v" . $slot;
$where = "%s.$keyField != ''";
$dimensions = array($keyField, $valueField);
$query = $this->getLogAggregator()->queryVisitsByDimension($dimensions, $where);
$this->aggregateFromVisits($query, $keyField, $valueField);
// IF we query Custom Variables scope "page" either: Product SKU, Product Name,
// then we also query the "Product page view" price which was possibly recorded.
$additionalSelects = false;
if (in_array($slot, array(\PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_SKU, \PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_NAME, \PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_CATEGORY))) {
$additionalSelects = array($this->getSelectAveragePrice());
}
$query = $this->getLogAggregator()->queryActionsByDimension($dimensions, $where, $additionalSelects);
$this->aggregateFromActions($query, $keyField, $valueField);
$query = $this->getLogAggregator()->queryConversionsByDimension($dimensions, $where);
$this->aggregateFromConversions($query, $keyField, $valueField);
}
protected function getSelectAveragePrice()
{
$field = "custom_var_v" . \PiwikTracker::CVAR_INDEX_ECOMMERCE_ITEM_PRICE;
return LogAggregator::getSqlRevenue("AVG(log_link_visit_action." . $field . ")") . " as `" . Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED . "`";
}
protected function aggregateFromVisits($query, $keyField, $valueField)
{
while ($row = $query->fetch()) {
$key = $row[$keyField];
$value = $this->cleanCustomVarValue($row[$valueField]);
$this->addMetadata($keyField, $key, Model::SCOPE_VISIT);
$this->dataArray->sumMetricsVisits($key, $row);
$this->dataArray->sumMetricsVisitsPivot($key, $value, $row);
}
}
protected function cleanCustomVarValue($value)
{
if (strlen($value)) {
return $value;
}
return self::LABEL_CUSTOM_VALUE_NOT_DEFINED;
}
protected function aggregateFromActions($query, $keyField, $valueField)
{
while ($row = $query->fetch()) {
$key = $row[$keyField];
$value = $this->cleanCustomVarValue($row[$valueField]);
$this->addMetadata($keyField, $key, Model::SCOPE_PAGE);
$alreadyAggregated = $this->aggregateEcommerceCategories($key, $value, $row);
if (!$alreadyAggregated) {
$this->aggregateActionByKeyAndValue($key, $value, $row);
$this->dataArray->sumMetricsActions($key, $row);
}
}
}
private function addMetadata($keyField, $label, $scope)
{
$index = (int) str_replace('custom_var_k', '', $keyField);
if (!array_key_exists($label, $this->metadata)) {
$this->metadata[$label] = array('slots' => array());
}
$uniqueId = $label . 'scope' . $scope . 'index' . $index;
if (!isset($this->metadataFlat[$uniqueId])) {
$this->metadata[$label]['slots'][] = array('scope' => $scope, 'index' => $index);
$this->metadataFlat[$uniqueId] = true;
}
}
/**
* @param string $key
* @param string $value
* @param $row
* @return bool True if the $row metrics were already added to the ->metrics
*/
protected function aggregateEcommerceCategories($key, $value, $row)
{
$ecommerceCategoriesAggregated = false;
if ($key == '_pkc'
&& $value[0] == '[' && $value[1] == '"'
) {
// In case categories were truncated, try closing the array
if (substr($value, -2) != '"]') {
$value .= '"]';
}
$decoded = json_decode($value);
if (is_array($decoded)) {
$count = 0;
foreach ($decoded as $category) {
if (empty($category)
|| $count >= GoalManager::MAXIMUM_PRODUCT_CATEGORIES
) {
continue;
}
$this->aggregateActionByKeyAndValue($key, $category, $row);
$ecommerceCategoriesAggregated = true;
$count++;
}
}
}
return $ecommerceCategoriesAggregated;
}
protected function aggregateActionByKeyAndValue($key, $value, $row)
{
$this->dataArray->sumMetricsActionsPivot($key, $value, $row);
if ($this->isReservedKey($key)) {
// Price tracking on Ecommerce product/category pages:
// the average is returned from the SQL query so the price is not "summed" like other metrics
$index = Metrics::INDEX_ECOMMERCE_ITEM_PRICE_VIEWED;
if (!empty($row[$index])) {
$this->dataArray->setRowColumnPivot($key, $value, $index, (float)$row[$index]);
}
}
}
protected static function isReservedKey($key)
{
return in_array($key, API::getReservedCustomVariableKeys());
}
protected function aggregateFromConversions($query, $keyField, $valueField)
{
if ($query === false) {
return;
}
while ($row = $query->fetch()) {
$key = $row[$keyField];
$value = $this->cleanCustomVarValue($row[$valueField]);
$this->dataArray->sumMetricsGoals($key, $row);
$this->dataArray->sumMetricsGoalsPivot($key, $value, $row);
}
}
/**
* Delete Visit, Unique Visitor and Users metric from 'page' scope custom variables.
*
* - Custom variables of 'visit' scope: it is expected that these ones have the "visit" column set.
* - Custom variables of 'page' scope: we cannot process "Visits" count for these.
* Why?
* "Actions" column is processed with a SELECT count(*).
* A same visit can set the same custom variable of 'page' scope multiple times.
* We cannot sum the values of count(*) as it would be incorrect.
* The way we could process "Visits" Metric for 'page' scope variable is to issue a count(Distinct *) or so,
* but it is no implemented yet (this would likely be very slow for high traffic sites).
*
*/
protected function removeVisitsMetricsFromActionsAggregate()
{
$dataArray = & $this->dataArray->getDataArray();
foreach ($dataArray as $key => &$row) {
if (!self::isReservedKey($key)
&& DataArray::isRowActions($row)
) {
unset($row[Metrics::INDEX_NB_UNIQ_VISITORS]);
unset($row[Metrics::INDEX_NB_VISITS]);
unset($row[Metrics::INDEX_NB_USERS]);
}
}
}
}

View File

@ -0,0 +1,18 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Categories;
use Piwik\Category\Category;
class CustomVariablesCategory extends Category
{
protected $id = 'CustomVariables_CustomVariables';
protected $order = 8;
}

View File

@ -0,0 +1,19 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Categories;
use Piwik\Category\Subcategory;
class CustomVariablesSubcategory extends Subcategory
{
protected $categoryId = 'General_Visitors';
protected $id = 'CustomVariables_CustomVariables';
protected $order = 45;
}

View File

@ -0,0 +1,66 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\CustomVariables\Columns;
use Piwik\Piwik;
use Piwik\Plugin\Dimension\VisitDimension;
use Piwik\Plugins\CustomVariables\Segment;
use Piwik\Plugins\CustomVariables\CustomVariables;
class Base extends VisitDimension
{
protected function configureSegmentsFor($segmentNameSuffix)
{
$numCustomVariables = CustomVariables::getNumUsableCustomVariables();
$segment = new Segment();
$segment->setType('dimension');
$segment->setSegment('customVariable' . $segmentNameSuffix);
$segment->setName($this->getName() . ' (' . Piwik::translate('CustomVariables_ScopeVisit') . ')');
$segment->setUnionOfSegments($this->getSegmentColumns('customVariable' . $segmentNameSuffix, $numCustomVariables));
$this->addSegment($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);
$segmentSuffix = 'v';
if (strtolower($segmentNameSuffix) === 'name') {
$segmentSuffix = 'k';
}
for ($i = 1; $i <= $numCustomVariables; $i++) {
$segment = new Segment();
$segment->setSegment('customVariable' . $segmentNameSuffix . $i);
$segment->setSqlSegment('log_visit.custom_var_' . $segmentSuffix . $i);
$segment->setName(Piwik::translate('CustomVariables_ColumnCustomVariable' . $segmentNameSuffix) . ' ' . $i
. ' (' . Piwik::translate('CustomVariables_ScopeVisit') . ')');
$this->addSegment($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);
}
}
private function getSegmentColumns($column, $numCustomVariables)
{
$columns = array();
for ($i = 1; $i <= $numCustomVariables; ++$i) {
$columns[] = $column . $i;
}
return $columns;
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Columns;
use Piwik\Piwik;
class CustomVariableName extends Base
{
protected function configureSegments()
{
$this->configureSegmentsFor('Name');
}
public function getName()
{
return Piwik::translate('CustomVariables_ColumnCustomVariableName');
}
}

View File

@ -0,0 +1,25 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Columns;
use Piwik\Piwik;
class CustomVariableValue extends Base
{
protected function configureSegments()
{
$this->configureSegmentsFor('Value');
}
public function getName()
{
return Piwik::translate('CustomVariables_ColumnCustomVariableValue');
}
}

View File

@ -0,0 +1,26 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Columns;
use Piwik\Columns\Discriminator;
use Piwik\Plugin\Dimension\ActionDimension;
use Piwik\Plugins\Actions\Actions\ActionSiteSearch;
class SearchCategory extends ActionDimension
{
protected $type = self::TYPE_TEXT;
protected $columnName = 'custom_var_v4';
protected $nameSingular = 'Actions_SiteSearchCategory';
protected $namePlural = 'Actions_SiteSearchCategories';
public function getDbDiscriminator()
{
return new Discriminator($this->dbTableName, 'custom_var_k4', ActionSiteSearch::CVAR_KEY_SEARCH_CATEGORY);
}
}

View File

@ -0,0 +1,68 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Commands;
use Piwik\Common;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\CustomVariables\CustomVariables;
use Piwik\Plugins\CustomVariables\Model;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class Info extends ConsoleCommand
{
protected function configure()
{
$this->setName('customvariables:info');
$this->setDescription('Get info about configured custom variables');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$maxVars = CustomVariables::getNumUsableCustomVariables();
if ($this->hasEverywhereSameAmountOfVariables()) {
$this->writeSuccessMessage($output, array(
'Your Piwik is configured for ' . $maxVars . ' custom variables.'
));
return;
}
$output->writeln('<error>There is a problem with your custom variables configuration:</error>');
$output->writeln('<error>Some database tables miss custom variables columns.</error>');
$output->writeln('');
$output->writeln('Your Piwik seems to be configured for ' . $maxVars . ' custom variables.');
$output->writeln('Executing "<comment>./console customvariables:set-max-custom-variables ' . $maxVars . '</comment>" might fix this issue.');
$output->writeln('If not check the following tables whether they have the same columns starting with <comment>custom_var_</comment>: ');
foreach (Model::getScopes() as $scope) {
$output->writeln(Common::prefixTable($scope));
}
}
private function hasEverywhereSameAmountOfVariables()
{
$indexesBefore = null;
foreach (Model::getScopes() as $scope) {
$model = new Model($scope);
$indexes = $model->getCustomVarIndexes();
if (is_null($indexesBefore)) {
$indexesBefore = $indexes;
} elseif ($indexes != $indexesBefore) {
return false;
}
}
return true;
}
}

View File

@ -0,0 +1,204 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Commands;
use Piwik\Plugin\ConsoleCommand;
use Piwik\Plugins\CustomVariables\Model;
use Piwik\Tracker\Cache;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
/**
*/
class SetNumberOfCustomVariables extends ConsoleCommand
{
/**
* @var \Symfony\Component\Console\Helper\ProgressHelper
*/
private $progress;
protected function configure()
{
$this->setName('customvariables:set-max-custom-variables');
$this->setDescription('Change the number of available custom variables');
$this->setHelp("Example:
./console customvariables:set-max-custom-variables 10
=> 10 custom variables will be available in total
");
$this->addArgument('maxCustomVars', InputArgument::REQUIRED, 'Set the number of max available custom variables');
}
protected function execute(InputInterface $input, OutputInterface $output)
{
$numVarsToSet = $this->getNumVariablesToSet($input);
$numChangesToPerform = $this->getNumberOfChangesToPerform($numVarsToSet);
if (0 === $numChangesToPerform) {
$this->writeSuccessMessage($output, array(
'Your Piwik is already configured for ' . $numVarsToSet . ' custom variables.'
));
return;
}
$output->writeln('');
$output->writeln(sprintf('Configuring Piwik for %d custom variables', $numVarsToSet));
foreach (Model::getScopes() as $scope) {
$this->printChanges($scope, $numVarsToSet, $output);
}
if ($input->isInteractive() && !$this->confirmChange($output)) {
return;
}
$output->writeln('');
$output->writeln('Starting to apply changes');
$output->writeln('');
$this->progress = $this->initProgress($numChangesToPerform, $output);
foreach (Model::getScopes() as $scope) {
$this->performChange($scope, $numVarsToSet, $output);
}
Cache::clearCacheGeneral();
$this->progress->finish();
$this->writeSuccessMessage($output, array(
'Your Piwik is now configured for ' . $numVarsToSet . ' custom variables.'
));
}
private function initProgress($numChangesToPerform, OutputInterface $output)
{
/** @var \Symfony\Component\Console\Helper\ProgressHelper $progress */
$progress = $this->getHelperSet()->get('progress');
$progress->start($output, $numChangesToPerform);
return $progress;
}
private function performChange($scope, $numVarsToSet, OutputInterface $output)
{
$model = new Model($scope);
$numCurrentVars = $model->getCurrentNumCustomVars();
$numDifference = $this->getAbsoluteDifference($numCurrentVars, $numVarsToSet);
if ($numVarsToSet > $numCurrentVars) {
$this->addCustomVariables($model, $numDifference, $output);
return;
}
$this->removeCustomVariables($model, $numDifference, $output);
}
private function getNumVariablesToSet(InputInterface $input)
{
$maxCustomVars = $input->getArgument('maxCustomVars');
if (!is_numeric($maxCustomVars)) {
throw new \InvalidArgumentException('The number of available custom variables has to be a number');
}
$maxCustomVars = (int) $maxCustomVars;
if ($maxCustomVars < 5) {
throw new \InvalidArgumentException('There has to be at least five custom variables');
}
return $maxCustomVars;
}
private function confirmChange(OutputInterface $output)
{
$output->writeln('');
$dialog = $this->getHelperSet()->get('dialog');
return $dialog->askConfirmation(
$output,
'<question>Are you sure you want to perform these actions? (y/N)</question>',
false
);
}
private function printChanges($scope, $numVarsToSet, OutputInterface $output)
{
$model = new Model($scope);
$scopeName = $model->getScopeName();
$highestIndex = $model->getHighestCustomVarIndex();
$numCurrentCustomVars = $model->getCurrentNumCustomVars();
$numVarsDifference = $this->getAbsoluteDifference($numCurrentCustomVars, $numVarsToSet);
$output->writeln('');
$output->writeln(sprintf('Scope "%s"', $scopeName));
if ($numVarsToSet > $numCurrentCustomVars) {
$indexes = $highestIndex + 1;
if (1 !== $numVarsDifference) {
$indexes .= ' - ' . ($highestIndex + $numVarsDifference);
}
$output->writeln(
sprintf('%s new custom variables having the index(es) %s will be ADDED', $numVarsDifference, $indexes)
);
} elseif ($numVarsToSet < $numCurrentCustomVars) {
$indexes = $highestIndex - $numVarsDifference + 1;
if (1 !== $numVarsDifference) {
$indexes .= ' - ' . $highestIndex;
}
$output->writeln(
sprintf("%s existing custom variables having the index(es) %s will be REMOVED.", $numVarsDifference, $indexes)
);
$output->writeln('<comment>This is an irreversible change</comment>');
}
}
private function getAbsoluteDifference($currentNumber, $numberToSet)
{
return abs($numberToSet - $currentNumber);
}
private function removeCustomVariables(Model $model, $numberOfVarsToRemove, OutputInterface $output)
{
for ($index = 0; $index < $numberOfVarsToRemove; $index++) {
$indexRemoved = $model->removeCustomVariable();
$this->progress->advance();
$output->writeln(' <info>Removed a variable in scope "' . $model->getScopeName() . '" having the index ' . $indexRemoved . '</info>');
}
}
private function addCustomVariables(Model $model, $numberOfVarsToAdd, OutputInterface $output)
{
for ($index = 0; $index < $numberOfVarsToAdd; $index++) {
$indexAdded = $model->addCustomVariable();
$this->progress->advance();
$output->writeln(' <info>Added a variable in scope "' . $model->getScopeName() . '" having the index ' . $indexAdded . '</info>');
}
}
private function getNumberOfChangesToPerform($numVarsToSet)
{
$numChangesToPerform = 0;
foreach (Model::getScopes() as $scope) {
$model = new Model($scope);
$numCurrentCustomVars = $model->getCurrentNumCustomVars();
$numChangesToPerform += $this->getAbsoluteDifference($numCurrentCustomVars, $numVarsToSet);
}
return $numChangesToPerform;
}
}

View File

@ -0,0 +1,27 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\Common;
use Piwik\DataTable;
use Piwik\Piwik;
use Piwik\Site;
class Controller extends \Piwik\Plugin\Controller
{
public function manage()
{
$this->checkSitePermission();
Piwik::checkUserHasAdminAccess($this->idSite);
return $this->renderTemplate('manage', array());
}
}

View File

@ -0,0 +1,36 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\Columns\Dimension;
use Piwik\Piwik;
class CustomDimension extends Dimension
{
protected $type = self::TYPE_TEXT;
private $id;
public function getId()
{
return $this->id;
}
public function initCustomDimension($index, Model $scope)
{
$category = $scope->getScopeDescription();
$this->id = 'CustomVariables.CustomVariable' . ucfirst($scope->getScope()) . $index;
$this->nameSingular = Piwik::translate('CustomVariables_ColumnCustomVariableValue') . ' ' . $index . ' (' . $category .')';
$this->columnName = 'custom_var_v' . (int) $index;
$this->category = 'CustomVariables_CustomVariables';
$this->dbTableName = $scope->getUnprefixedTableName();
}
}

View File

@ -0,0 +1,149 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\Tracker\Cache;
class CustomVariables extends \Piwik\Plugin
{
const MAX_NUM_CUSTOMVARS_CACHEKEY = 'CustomVariables.MaxNumCustomVariables';
/**
* @see \Piwik\Plugin::registerEvents
*/
public function registerEvents()
{
return array(
'AssetManager.getJavaScriptFiles' => 'getJsFiles',
'Translate.getClientSideTranslationKeys' => 'getClientSideTranslationKeys',
'AssetManager.getStylesheetFiles' => 'getStylesheetFiles',
'Dimension.addDimensions' => 'addDimensions',
'Actions.getCustomActionDimensionFieldsAndJoins' => 'provideActionDimensionFields'
);
}
public function install()
{
Model::install();
}
public function uninstall()
{
Model::uninstall();
}
public function addDimensions(&$instances)
{
foreach (Model::getScopes() as $scope) {
$model = new Model($scope);
try {
$highestIndex = $model->getHighestCustomVarIndex();
} catch (\Exception $e) {
continue; // ignore error for tests to work as this might be executed before Piwik tables are installed
}
foreach (range(1, $highestIndex) as $index) {
$custom = new CustomDimension();
$custom->initCustomDimension($index, $model);
$instances[] = $custom;
}
}
}
/**
* There are also some hardcoded places in JavaScript
* @return int
*/
public static function getMaxLengthCustomVariables()
{
return 200;
}
/**
* Returns the number of available custom variables that can be used.
*
* "Can be used" is identifed by the minimum number of available custom variables across all relevant tables. Eg
* if there are 6 custom variables installed in log_visit but only 5 in log_conversion, we consider only 5 custom
* variables as usable.
* @return int
*/
public static function getNumUsableCustomVariables()
{
$cache = Cache::getCacheGeneral();
$cacheKey = self::MAX_NUM_CUSTOMVARS_CACHEKEY;
if (!array_key_exists($cacheKey, $cache)) {
$minCustomVar = null;
foreach (Model::getScopes() as $scope) {
$model = new Model($scope);
$highestIndex = $model->getHighestCustomVarIndex();
if (!isset($minCustomVar)) {
$minCustomVar = $highestIndex;
}
if ($highestIndex < $minCustomVar) {
$minCustomVar = $highestIndex;
}
}
if (!isset($minCustomVar)) {
$minCustomVar = 0;
}
$cache[$cacheKey] = $minCustomVar;
Cache::setCacheGeneral($cache);
}
return $cache[$cacheKey];
}
public function getClientSideTranslationKeys(&$translationKeys)
{
$translationKeys[] = 'CustomVariables_CustomVariables';
$translationKeys[] = 'CustomVariables_ManageDescription';
$translationKeys[] = 'CustomVariables_ScopeX';
$translationKeys[] = 'CustomVariables_Index';
$translationKeys[] = 'CustomVariables_Usages';
$translationKeys[] = 'CustomVariables_Unused';
$translationKeys[] = 'CustomVariables_CreateNewSlot';
$translationKeys[] = 'CustomVariables_UsageDetails';
$translationKeys[] = 'CustomVariables_CurrentAvailableCustomVariables';
$translationKeys[] = 'CustomVariables_ToCreateCustomVarExecute';
$translationKeys[] = 'CustomVariables_CreatingCustomVariableTakesTime';
$translationKeys[] = 'CustomVariables_SlotsReportIsGeneratedOverTime';
$translationKeys[] = 'General_Loading';
$translationKeys[] = 'General_TrackingScopeVisit';
$translationKeys[] = 'General_TrackingScopePage';
}
public function getStylesheetFiles(&$stylesheets)
{
$stylesheets[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.less";
}
public function getJsFiles(&$jsFiles)
{
$jsFiles[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.model.js";
$jsFiles[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.controller.js";
$jsFiles[] = "plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.js";
}
public function provideActionDimensionFields(&$fields, &$joins)
{
$maxCustomVariables = CustomVariables::getNumUsableCustomVariables();
for ($i = 1; $i <= $maxCustomVariables; $i++) {
$fields[] = 'custom_var_k' . $i;
$fields[] = 'custom_var_v' . $i;
}
}
}

View File

@ -0,0 +1,42 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\DataTable\Filter;
use Piwik\DataTable\BaseFilter;
use Piwik\DataTable\Row;
use Piwik\DataTable;
use Piwik\Piwik;
class CustomVariablesValuesFromNameId extends BaseFilter
{
/**
* Constructor.
*
* @param DataTable $table The table to eventually filter.
*/
public function __construct($table)
{
parent::__construct($table);
}
/**
* @param DataTable $table
*/
public function filter($table)
{
$notDefinedLabel = Piwik::translate('General_NotDefined', Piwik::translate('CustomVariables_ColumnCustomVariableValue'));
$table->queueFilter('ColumnCallbackReplace', array('label', function ($label) use ($notDefinedLabel) {
return $label === \Piwik\Plugins\CustomVariables\Archiver::LABEL_CUSTOM_VALUE_NOT_DEFINED
? $notDefinedLabel
: strval($label);
}));
}
}

View File

@ -0,0 +1,33 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\Common;
use Piwik\Menu\MenuAdmin;
use Piwik\Piwik;
use Piwik\Plugins\UsersManager\UserPreferences;
/**
* This class allows you to add, remove or rename menu items.
* To configure a menu (such as Admin Menu, Reporting Menu, User Menu...) simply call the corresponding methods as
* described in the API-Reference http://developer.piwik.org/api-reference/Piwik/Menu/MenuAbstract
*/
class Menu extends \Piwik\Plugin\Menu
{
public function configureAdminMenu(MenuAdmin $menu)
{
$userPreferences = new UserPreferences();
$default = $userPreferences->getDefaultWebsiteId();
$idSite = Common::getRequestVar('idSite', $default, 'int');
if (Piwik::isUserHasAdminAccess($idSite)) {
$menu->addDiagnosticItem('CustomVariables_CustomVariables', $this->urlForAction('manage'), $orderId = 20);
}
}
}

View File

@ -0,0 +1,219 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\Common;
use Piwik\Container\StaticContainer;
use Piwik\DataTable;
use Piwik\Db;
use Piwik\Log;
use Piwik\Piwik;
use Psr\Log\LoggerInterface;
class Model
{
const DEFAULT_CUSTOM_VAR_COUNT = 5;
const SCOPE_PAGE = 'page';
const SCOPE_VISIT = 'visit';
const SCOPE_CONVERSION = 'conversion';
private $scope = null;
private $table = null;
private $tableUnprefixed = null;
public function __construct($scope)
{
if (empty($scope) || !in_array($scope, $this->getScopes())) {
throw new \Exception('Invalid custom variable scope');
}
$this->scope = $scope;
$this->tableUnprefixed = $this->getTableNameFromScope($scope);
$this->table = Common::prefixTable($this->tableUnprefixed);
}
public function getUnprefixedTableName()
{
return $this->tableUnprefixed;
}
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 self::SCOPE_PAGE:
return 'log_link_visit_action';
case self::SCOPE_VISIT:
return 'log_visit';
case self::SCOPE_CONVERSION:
return 'log_conversion';
}
}
public function getScope()
{
return $this->scope;
}
public function getScopeName()
{
return ucfirst($this->scope);
}
public function getScopeDescription()
{
switch ($this->scope) {
case Model::SCOPE_PAGE:
return Piwik::translate('CustomVariables_ScopePage');
case Model::SCOPE_VISIT:
return Piwik::translate('CustomVariables_ScopeVisit');
case Model::SCOPE_CONVERSION:
return Piwik::translate('CustomVariables_ScopeConversion');
}
return ucfirst($this->scope);
}
/**
* @see getHighestCustomVarIndex()
* @return int
*/
public function getCurrentNumCustomVars()
{
$indexes = $this->getCustomVarIndexes();
return count($indexes);
}
/**
* result of getHighestCustomVarIndex() can be different to getCurrentNumCustomVars() in case there are some missing
* custom variable indexes. For instance in case of manual changes on the DB
*
* custom_var_v1
* custom_var_v2
* custom_var_v4
*
* getHighestCustomVarIndex() -> returns 4
* getCurrentNumCustomVars() -> returns 3
*
* @return int
*/
public function getHighestCustomVarIndex()
{
$indexes = $this->getCustomVarIndexes();
if (empty($indexes)) {
return 0;
}
return max($indexes);
}
public function getCustomVarIndexes()
{
$columns = $this->getCustomVarColumnNames();
if (empty($columns)) {
return array();
}
$indexes = array_map(function ($column) {
return Model::getCustomVariableIndexFromFieldName($column);
}, $columns);
return array_values(array_unique($indexes));
}
private function getCustomVarColumnNames()
{
$columns = Db::getColumnNamesFromTable($this->table);
$customVarColumns = array_filter($columns, function ($column) {
return false !== strpos($column, 'custom_var_');
});
return $customVarColumns;
}
public function removeCustomVariable()
{
$index = $this->getHighestCustomVarIndex();
if ($index < 1) {
return null;
}
Db::exec(sprintf('ALTER TABLE %s ', $this->table)
. sprintf('DROP COLUMN custom_var_k%d,', $index)
. sprintf('DROP COLUMN custom_var_v%d;', $index));
return $index;
}
public function addCustomVariable()
{
$index = $this->getHighestCustomVarIndex() + 1;
$maxLen = CustomVariables::getMaxLengthCustomVariables();
Db::exec(sprintf('ALTER TABLE %s ', $this->table)
. sprintf('ADD COLUMN custom_var_k%d VARCHAR(%d) DEFAULT NULL,', $index, $maxLen)
. sprintf('ADD COLUMN custom_var_v%d VARCHAR(%d) DEFAULT NULL;', $index, $maxLen));
return $index;
}
public static function getCustomVariableIndexFromFieldName($fieldName)
{
$onlyNumber = str_replace(array('custom_var_k', 'custom_var_v'), '', $fieldName);
if (is_numeric($onlyNumber)) {
return (int) $onlyNumber;
}
}
public static function getScopes()
{
return array(self::SCOPE_PAGE, self::SCOPE_VISIT, self::SCOPE_CONVERSION);
}
public static function install()
{
foreach (self::getScopes() as $scope) {
$model = new Model($scope);
try {
$maxCustomVars = self::DEFAULT_CUSTOM_VAR_COUNT;
$customVarsToAdd = $maxCustomVars - $model->getCurrentNumCustomVars();
for ($index = 0; $index < $customVarsToAdd; $index++) {
$model->addCustomVariable();
}
} catch (\Exception $e) {
StaticContainer::get(LoggerInterface::class)->error('Failed to add custom variable: {exception}', [
'exception' => $e,
'ignoreInScreenWriter' => true,
]);
}
}
}
public static function uninstall()
{
foreach (self::getScopes() as $scope) {
$model = new Model($scope);
while ($model->getHighestCustomVarIndex()) {
$model->removeCustomVariable();
}
}
}
}

View File

@ -0,0 +1,56 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\ProfileSummary;
use Piwik\Common;
use Piwik\Piwik;
use Piwik\Plugins\CustomVariables\Model;
use Piwik\Plugins\Live\ProfileSummary\ProfileSummaryAbstract;
use Piwik\View;
/**
* Class VisitScopeSummary
*
* @api
*/
class VisitScopeSummary extends ProfileSummaryAbstract
{
/**
* @inheritdoc
*/
public function getName()
{
return Piwik::translate('CustomVariables_CustomVariables') . ' ' . Piwik::translate('General_TrackingScopeVisit');
}
/**
* @inheritdoc
*/
public function render()
{
if (empty($this->profile['customVariables']) || empty($this->profile['customVariables'][Model::SCOPE_VISIT])) {
return '';
}
$view = new View('@CustomVariables/_profileSummary.twig');
$view->visitorData = $this->profile;
$view->scopeName = Piwik::translate('General_TrackingScopeVisit');
$view->variables = $this->profile['customVariables'][Model::SCOPE_VISIT];
return $view->render();
}
/**
* @inheritdoc
*/
public function getOrder()
{
return 15;
}
}

View File

@ -0,0 +1,20 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Reports;
abstract class Base extends \Piwik\Plugin\Report
{
protected $defaultSortColumn = 'nb_actions';
protected function init()
{
$this->categoryId = 'General_Visitors';
}
}

View File

@ -0,0 +1,86 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Reports;
use Piwik\DataTable;
use Piwik\Piwik;
use Piwik\Plugin\ViewDataTable;
use Piwik\Plugins\CustomVariables\Columns\CustomVariableName;
class GetCustomVariables extends Base
{
protected function init()
{
parent::init();
$this->dimension = new CustomVariableName();
$this->name = Piwik::translate('CustomVariables_CustomVariables');
$this->documentation = Piwik::translate('CustomVariables_CustomVariablesReportDocumentation',
array('<br />', '<a href="https://matomo.org/docs/custom-variables/" rel="noreferrer noopener" target="_blank">', '</a>'));
$this->actionToLoadSubTables = 'getCustomVariablesValuesFromNameId';
$this->order = 10;
$this->subcategoryId = 'CustomVariables_CustomVariables';
$this->hasGoalMetrics = true;
}
public function configureView(ViewDataTable $view)
{
$view->config->columns_to_display = array('label', 'nb_actions', 'nb_visits');
$view->config->addTranslation('label', Piwik::translate('CustomVariables_ColumnCustomVariableName'));
$view->requestConfig->filter_sort_column = 'nb_actions';
$view->requestConfig->filter_sort_order = 'desc';
$that = $this;
$view->config->filters[] = function (DataTable $table) use ($view, $that) {
if($that->isReportContainsUnsetVisitsColumns($table)) {
$message = $that->getFooterMessageExplanationMissingMetrics();
$view->config->show_footer_message = $message;
}
};
}
/**
* @return string
*/
public function getFooterMessageExplanationMissingMetrics()
{
$metrics = sprintf("'%s', '%s' %s '%s'",
Piwik::translate('General_ColumnNbVisits'),
Piwik::translate('General_ColumnNbUniqVisitors'),
Piwik::translate('General_And'),
Piwik::translate('General_ColumnNbUsers')
);
$messageStart = Piwik::translate('CustomVariables_MetricsAreOnlyAvailableForVisitScope', array($metrics, "'visit'"));
$messageEnd = Piwik::translate('CustomVariables_MetricsNotAvailableForPageScope', array("'page'", '\'-\''));
$message = $messageStart . ' ' . $messageEnd;
if (!$this->isSubtableReport) {
// no footer message for subtables
$out = '';
Piwik::postEvent('Template.afterCustomVariablesReport', array(&$out));
if (!empty($message)) {
$message .= $out;
}
}
return $message;
}
/**
* @return bool
*/
public function isReportContainsUnsetVisitsColumns(DataTable $report)
{
$visits = $report->getColumn('nb_visits');
$isVisitsMetricsSometimesUnset = in_array(false, $visits);
return $isVisitsMetricsSometimesUnset;
}
}

View File

@ -0,0 +1,39 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables\Reports;
use Piwik\Piwik;
use Piwik\Plugin\ViewDataTable;
use Piwik\Plugins\CustomVariables\Columns\CustomVariableValue;
class GetCustomVariablesValuesFromNameId extends Base
{
protected function init()
{
parent::init();
$this->dimension = new CustomVariableValue();
$this->name = Piwik::translate('CustomVariables_CustomVariables');
$this->documentation = Piwik::translate('CustomVariables_CustomVariablesReportDocumentation',
array('<br />', '<a href="https://matomo.org/docs/custom-variables/" rel="noreferrer noopener" target="_blank">', '</a>'));
$this->isSubtableReport = true;
$this->order = 15;
}
public function configureView(ViewDataTable $view)
{
$view->config->columns_to_display = array('label', 'nb_actions', 'nb_visits');
$view->config->show_goals = true;
$view->config->show_search = false;
$view->config->show_exclude_low_population = false;
$view->config->addTranslation('label', Piwik::translate('CustomVariables_ColumnCustomVariableValue'));
$view->requestConfig->filter_sort_column = 'nb_actions';
$view->requestConfig->filter_sort_order = 'desc';
}
}

View File

@ -0,0 +1,21 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
/**
* CustomVariables segment base class
*/
class Segment extends \Piwik\Plugin\Segment
{
protected function init()
{
$this->setCategory('CustomVariables_CustomVariables');
}
}

View File

@ -0,0 +1,88 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
namespace Piwik\Plugins\CustomVariables\Tracker;
use Piwik\Common;
use Piwik\Plugins\CustomVariables\Model;
use Piwik\Tracker\Action;
use Piwik\Tracker\Request;
use Piwik\Tracker\RequestProcessor;
use Piwik\Tracker\Visit\VisitProperties;
/**
* Handles tracking of visit level custom variables.
*
* ### Request Metadata
*
* Defines the following request metadata for the **CustomVariables** plugin:
*
* * **visitCustomVariables**: An array of custom variable names & values. The data is stored
* as log_visit column name/value pairs, eg,
*
* ```
* array(
* 'custom_var_k1' => 'the name',
* 'custom_var_v1' => 'the value',
* ...
* )
* ```
*/
class CustomVariablesRequestProcessor extends RequestProcessor
{
public function processRequestParams(VisitProperties $visitProperties, Request $request)
{
// TODO: re-add optimization where if custom variables exist in request, don't bother selecting them in Visitor
$visitorCustomVariables = $request->getCustomVariables($scope = Model::SCOPE_VISIT);
if (!empty($visitorCustomVariables)) {
Common::printDebug("Visit level Custom Variables: ");
Common::printDebug($visitorCustomVariables);
}
$request->setMetadata('CustomVariables', 'visitCustomVariables', $visitorCustomVariables);
}
public function onNewVisit(VisitProperties $visitProperties, Request $request)
{
$visitCustomVariables = $request->getMetadata('CustomVariables', 'visitCustomVariables');
if (!empty($visitCustomVariables)) {
$visitProperties->setProperties(array_merge($visitProperties->getProperties(), $visitCustomVariables));
}
}
public function onExistingVisit(&$valuesToUpdate, VisitProperties $visitProperties, Request $request)
{
$visitCustomVariables = $request->getMetadata('CustomVariables', 'visitCustomVariables');
if (!empty($visitCustomVariables)) {
$valuesToUpdate = array_merge($valuesToUpdate, $visitCustomVariables);
}
}
public function afterRequestProcessed(VisitProperties $visitProperties, Request $request)
{
$action = $request->getMetadata('Actions', 'action');
if (empty($action) || !($action instanceof Action)) {
return;
}
$customVariables = $action->getCustomVariables();
if (!empty($customVariables)) {
Common::printDebug("Page level Custom Variables: ");
Common::printDebug($customVariables);
foreach ($customVariables as $field => $value) {
$action->setCustomField($field, $value);
}
}
}
}

View File

@ -0,0 +1,207 @@
<?php
/**
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*
*/
namespace Piwik\Plugins\CustomVariables;
use Piwik\Piwik;
use Piwik\Plugins\Actions\Actions\ActionSiteSearch;
use Piwik\Plugins\Live\VisitorDetailsAbstract;
use Piwik\View;
class VisitorDetails extends VisitorDetailsAbstract
{
public function extendVisitorDetails(&$visitor)
{
$customVariables = array();
$maxCustomVariables = CustomVariables::getNumUsableCustomVariables();
for ($i = 1; $i <= $maxCustomVariables; $i++) {
if (!empty($this->details['custom_var_k' . $i])) {
$customVariables[$i] = array(
'customVariableName' . $i => $this->details['custom_var_k' . $i],
'customVariableValue' . $i => $this->details['custom_var_v' . $i],
);
}
}
$visitor['customVariables'] = $customVariables;
}
public function extendActionDetails(&$action, $nextAction, $visitorDetails)
{
$maxCustomVariables = CustomVariables::getNumUsableCustomVariables();
$customVariablesPage = array();
for ($i = 1; $i <= $maxCustomVariables; $i++) {
if (!empty($action['custom_var_k' . $i])) {
$cvarKey = $action['custom_var_k' . $i];
$cvarKey = static::getCustomVariablePrettyKey($cvarKey);
$customVariablesPage[$i] = array(
'customVariablePageName' . $i => $cvarKey,
'customVariablePageValue' . $i => $action['custom_var_v' . $i],
);
}
unset($action['custom_var_k' . $i]);
unset($action['custom_var_v' . $i]);
}
if (!empty($customVariablesPage)) {
$action['customVariables'] = $customVariablesPage;
}
}
public function renderActionTooltip($action, $visitInfo)
{
if (empty($action['customVariables'])) {
return [];
}
$view = new View('@CustomVariables/_actionTooltip');
$view->action = $action;
return [[ 40, $view->render() ]];
}
public function renderVisitorDetails($visitInfo)
{
if (empty($visitInfo['customVariables'])) {
return [];
}
$view = new View('@CustomVariables/_visitorDetails');
$view->visitInfo = $visitInfo;
return [[ 50, $view->render() ]];
}
private static function getCustomVariablePrettyKey($key)
{
$rename = array(
ActionSiteSearch::CVAR_KEY_SEARCH_CATEGORY => Piwik::translate('Actions_ColumnSearchCategory'),
ActionSiteSearch::CVAR_KEY_SEARCH_COUNT => Piwik::translate('Actions_ColumnSearchResultsCount'),
);
if (isset($rename[$key])) {
return $rename[$key];
}
return $key;
}
protected $customVariables = [];
public function initProfile($visits, &$profile)
{
$this->customVariables = [
Model::SCOPE_PAGE => [],
Model::SCOPE_VISIT => [],
];
}
public function handleProfileAction($action, &$profile)
{
if (empty($action['customVariables'])) {
return;
}
foreach ($action['customVariables'] as $index => $customVariable) {
$scope = Model::SCOPE_PAGE;
$name = $customVariable['customVariablePageName'.$index];
$value = $customVariable['customVariablePageValue'.$index];
if (empty($value)) {
continue;
}
if (!array_key_exists($name, $this->customVariables[$scope])) {
$this->customVariables[$scope][$name] = [];
}
if (!array_key_exists($value, $this->customVariables[$scope][$name])) {
$this->customVariables[$scope][$name][$value] = 0;
}
$this->customVariables[$scope][$name][$value]++;
}
}
public function handleProfileVisit($visit, &$profile)
{
if (empty($visit['customVariables'])) {
return;
}
foreach ($visit['customVariables'] as $index => $customVariable) {
$scope = Model::SCOPE_VISIT;
$name = $customVariable['customVariableName'.$index];
$value = $customVariable['customVariableValue'.$index];
if (empty($value)) {
continue;
}
if (!array_key_exists($name, $this->customVariables[$scope])) {
$this->customVariables[$scope][$name] = [];
}
if (!array_key_exists($value, $this->customVariables[$scope][$name])) {
$this->customVariables[$scope][$name][$value] = 0;
}
$this->customVariables[$scope][$name][$value]++;
}
}
public function finalizeProfile($visits, &$profile)
{
$customVariables = $this->customVariables;
foreach ($customVariables as $scope => &$variables) {
if (empty($variables)) {
unset($customVariables[$scope]);
continue;
}
foreach ($variables AS $name => &$values) {
arsort($values);
}
}
if (!empty($customVariables)) {
$profile['customVariables'] = $this->convertForProfile($customVariables);
}
}
protected function convertForProfile($customVariables)
{
$convertedVariables = [];
foreach ($customVariables as $scope => $scopeVariables) {
$convertedVariables[$scope] = [];
foreach ($scopeVariables as $name => $values) {
$variable = [
'name' => $name,
'values' => []
];
foreach ($values as $value => $count) {
$variable['values'][] = [
'value' => $value,
'count' => $count
];
}
$convertedVariables[$scope][] = $variable;
}
}
return $convertedVariables;
}
}

View File

@ -0,0 +1,22 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
angular.module('piwikApp').controller('ManageCustomVarsController', ManageCustomVarsController);
ManageCustomVarsController.$inject = ['manageCustomVarsModel', 'piwik', '$filter'];
function ManageCustomVarsController(manageCustomVarsModel, piwik, $filter) {
manageCustomVarsModel.fetchUsages();
this.model = manageCustomVarsModel;
this.siteName = piwik.siteName;
this.scopes = [
{value: 'visit', name: _pk_translate('General_TrackingScopeVisit')},
{value: 'page', name: _pk_translate('General_TrackingScopePage')}
];
}
})();

View File

@ -0,0 +1,63 @@
<div class="manageCustomVars">
<div piwik-content-intro>
<h2 piwik-enriched-headline
help-url="https://matomo.org/docs/custom-variables/">
{{ 'CustomVariables_CustomVariables'|translate }}
</h2>
<p>
<span ng-bind-html="'CustomVariables_ManageDescription'|translate:manageCustomVars.siteName"></span>
</p>
</div>
<div class="alert alert-info" ng-show="!manageCustomVars.model.isLoading && manageCustomVars.model.hasCustomVariablesInGeneral && !manageCustomVars.model.hasAtLeastOneUsage">
{{ 'CustomVariables_SlotsReportIsGeneratedOverTime'|translate }}
</div>
<div ng-repeat="scope in manageCustomVars.scopes">
<div piwik-content-block content-title="{{ 'CustomVariables_ScopeX'|translate:(scope.name) }}">
<table piwik-content-table>
<thead>
<tr>
<th>{{'CustomVariables_Index'|translate }}</th>
<th>{{'CustomVariables_Usages'|translate }}</th>
</tr>
</thead>
<tbody>
<tr>
<td colspan="3" ng-show="manageCustomVars.model.isLoading">{{ 'General_Loading'|translate }}</td>
</tr>
<tr ng-repeat="customVariables in manageCustomVars.model.customVariables|filter:{scope: scope.value}">
<td class="index">{{ customVariables.index }}</td>
<td>
<span ng-show="(customVariables.usages|length) === 0"
class="unused">{{'CustomVariables_Unused'|translate }}</span>
<span ng-show="customVariables.usages|length" ng-repeat="cvar in customVariables.usages|orderBy:'-nb_actions'">
<span title="{{ 'CustomVariables_UsageDetails'|translate:(cvar.nb_visits ? cvar.nb_visits : 0):(cvar.nb_actions ? cvar.nb_actions : 0) }}">{{ cvar.name }}</span><span ng-show="!$last">, </span>
</span>
</td>
</tr>
</tbody>
</table>
</div>
</div>
<div ng-show="!manageCustomVars.model.isLoading"
piwik-content-block
id="CustomVariablesCreateNewSlot"
content-title="{{ 'CustomVariables_CreateNewSlot'|translate }}">
<p ng-show="!manageCustomVars.model.isLoading">
{{ 'CustomVariables_CreatingCustomVariableTakesTime'|translate }}
<br /><br />
<span ng-bind-html="'CustomVariables_CurrentAvailableCustomVariables'|translate:('<strong>'+manageCustomVars.model.numSlotsAvailable+'</strong>')"></span>
<br />
<br />
{{ 'CustomVariables_ToCreateCustomVarExecute'|translate }}
<br />
<pre piwik-select-on-focus><code>./console customvariables:set-max-custom-variables {{ manageCustomVars.model.numSlotsAvailable + 1 }}</code></pre>
</p>
</div>
</div>

View File

@ -0,0 +1,26 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
/**
* Usage:
* <div piwik-manage-custom-vars>
*/
(function () {
angular.module('piwikApp').directive('piwikManageCustomVars', piwikManageCustomVars);
piwikManageCustomVars.$inject = ['piwik'];
function piwikManageCustomVars(piwik){
return {
restrict: 'A',
scope: {},
templateUrl: 'plugins/CustomVariables/angularjs/manage-custom-vars/manage-custom-vars.directive.html?cb=' + piwik.cacheBuster,
controller: 'ManageCustomVarsController',
controllerAs: 'manageCustomVars'
};
}
})();

View File

@ -0,0 +1,18 @@
.manageCustomVars {
.unused {
color: @color-silver;
}
table, p {
width: 900px;
}
.alert-info {
margin-top: 15px;
}
.scope, .index {
width: 90px;
max-width: 90px;
}
}

View File

@ -0,0 +1,59 @@
/*!
* Piwik - free/libre analytics platform
*
* @link http://piwik.org
* @license http://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later
*/
(function () {
angular.module('piwikApp').factory('manageCustomVarsModel', manageCustomVarsModel);
manageCustomVarsModel.$inject = ['piwikApi'];
function manageCustomVarsModel(piwikApi) {
var model = {
customVariables : [],
extractions : [],
isLoading: false,
fetchUsages: fetchUsages,
hasCustomVariablesInGeneral: false,
hasAtLeastOneUsage: false,
numSlotsAvailable: 5,
};
return model;
function fetchCustomVariables() {
return piwikApi.fetch({method: 'CustomVariables.getCustomVariables', period: 'year', date: 'today', filter_limit: 1})
.then(function (customVariables) {
model.hasCustomVariablesInGeneral = (customVariables && customVariables.length > 0);
});
}
function fetchUsages() {
model.isLoading = true;
fetchCustomVariables().then(function () {
return piwikApi.fetch({method: 'CustomVariables.getUsagesOfSlots', filter_limit: '-1'});
}).then(function (customVariables) {
model.customVariables = customVariables;
angular.forEach(customVariables, function (customVar) {
if (customVar.index > model.numSlotsAvailable) {
model.numSlotsAvailable = customVar.index;
}
if (customVar.usages && customVar.usages.length > 0) {
model.hasAtLeastOneUsage = true;
}
});
})['finally'](function () { // .finally() is not IE8 compatible see https://github.com/angular/angular.js/commit/f078762d48d0d5d9796dcdf2cb0241198677582c
model.isLoading = false;
});
}
}
})();

View File

@ -0,0 +1,6 @@
<?php
return array(
// in tests we do not use 'today' to make tests results deterministic
'CustomVariables.today' => 'today',
);

View File

@ -0,0 +1,4 @@
<?php
return array(
'CustomVariables.today' => '2015-01-01'
);

View File

@ -0,0 +1,7 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "اسم المتغير المخصص",
"ColumnCustomVariableValue": "قيمة المتغير المخصص",
"CustomVariables": "المتغيرات المخصصة"
}
}

View File

@ -0,0 +1,7 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Назва карыстацкай зменнай",
"ColumnCustomVariableValue": "Значэнне карыстацкай зменнай",
"CustomVariables": "Карыстацкія зменныя"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Име на променлива",
"ColumnCustomVariableValue": "Съдържание на променлива",
"CustomVariables": "Променливи",
"CustomVariablesReportDocumentation": "Този отчет съдържа информация за вашите Персонални променливи. Кликнете върху името на променлива, за да видите разпределението на стойностите. %1$s За повече информация отностно Персоналните Променливи в общ план, прочетете Документацията за %2$sПерсонални промеливи на matomo.org%3$s",
"ScopePage": "Разгледай страница",
"ScopeVisit": "Разгледай посещение"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nom de la variable personalitzada",
"ColumnCustomVariableValue": "Valor de la variable personalitzada",
"CustomVariables": "Variables personalitzades",
"CustomVariablesReportDocumentation": "Aquest informe conté informació sobre les variables personaltizades. Feu click al nom d'una variable per veure la distribució dels valors. %1$s Per més informació sobre les variables personalitzades, podeu llegir la %2$sdocumentació sobre variables peronalitzades a matomo.org%3$s",
"ScopePage": "àmbit de la pàgina",
"ScopeVisit": "àmbit de la visita"
}
}

View File

@ -0,0 +1,23 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Název vlastní proměnné",
"ColumnCustomVariableValue": "Hodnota vlastní proměnné",
"CustomVariables": "Vlastní proměnné",
"CustomVariablesReportDocumentation": "Toto hlášení obsahuje informace o vašich vlastních proměnných. Klikněte na proměnnou pro zobrazení distribuce hodnot. %1$s Pro více informací si přečtěte %2$sdokumentaci o vlastních proměnných na matomo.org%3$s",
"ScopePage": "rozsah stránky",
"ScopeVisit": "rozsah návštěvy",
"ScopeConversion": "rozsah konverze",
"ManageDescription": "Tento přehled zobrazuje všechny sloty vlastních proměnných a jejich využití pro stránku '%s'. Jména v každém ze slotů jsou seřazena dle jejich celkového využití.",
"ScopeX": "Rozsah %s",
"Index": "Index",
"Usages": "Využití",
"Unused": "Nevyužito",
"CreateNewSlot": "Navýšit počet dostupných slotů vlastních proměnných",
"UsageDetails": "%1$s návštěv a %2$s akcí od založení tohoto webu.",
"CreatingCustomVariableTakesTime": "Vytvoření nové vlastní proměnné hodnoty může trvat déle v závislosti na velikosti vaší databáze. Proto je toto možné provést pouze pomocí příkazu spuštěnému v příkazové řádce.",
"CurrentAvailableCustomVariables": "Aktuálně můžete použít až %s vlastních proměnných na stránku.",
"SlotsReportIsGeneratedOverTime": "Data pro toto hlášení budou dostupná později. Než budou data vidět, může to den nebo dva trvat a poté několik týdnů než bude hlášení plně vypovídající.",
"MetricsAreOnlyAvailableForVisitScope": "Poznámka: Metriky %1$s jsou k dispozici pro vlastní proměnné pouze v rozsahu %2$s.",
"MetricsNotAvailableForPageScope": "Pro vlastní proměnné v rozsahu %1$s je hodnota sloupce s těmito metrikami %2$s"
}
}

View File

@ -0,0 +1,12 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Brugerdefineret variabelnavn",
"ColumnCustomVariableValue": "Brugerdefineret variabelværdi",
"CustomVariables": "Brugerdefinerede variabler",
"CustomVariablesReportDocumentation": "Rapporten indeholder oplysninger om brugerdefinerede variabler. Klik på et variabelnavn se fordeling af værdier. %1$s Yderligere oplysninger om brugerdefinerede variabler generelt, læs %2$sBrugerdefinerede variabel dokumentation på matomo.org%3$s",
"ScopePage": "virkefelt side",
"ScopeVisit": "virkefelt besøg",
"Index": "Indeks",
"Unused": "Ubrugt"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Name der benutzerdefinierten Variable",
"ColumnCustomVariableValue": "Wert der benutzerdefinierten Variable",
"CustomVariables": "Benutzerdefinierte Variablen",
"CustomVariablesReportDocumentation": "Dieser Bericht enthält Informationen über Ihre benutzerdefinierten Variablen. Klicken Sie auf einen Variablennamen, um die Verteilung der Werte zu sehen. %1$s Für mehr Informationen über benutzerdefinierte Variablen, lesen Sie die %2$sDokumentation auf matomo.org%3$s",
"PluginDescription": "Benutzerdefinierte Variablen sind (Name, Wert)-Paare, welche Sie mit Hilfe der Javascript API Besuchern oder deren Aktionen zuweisen können. Matomo wird dann Besuche, Seiten, Konversionen für jede dieser benutzerdefinierten Namen und Werte protokollieren. Die detaillierten benutzerdefinierten Variablen lassen sich für jeden Benutzer und jede Aktion im Besucher Log anzeigen. Dieses Plugin wird benötigt für das Ecommerce Analytics Feature!",
"ScopePage": "Anwendungsbereich Seite",
"ScopeVisit": "Anwendungsbereich Besuch",
"ScopeConversion": "Anwendungsbereichkonversion",
"ManageDescription": "Diese Übersicht zeigt alle benutzerdefinierten Variablen und deren Gebrauch für Webseite %s. Die Namen auf jeder Position sind danach sortiert, wie oft sie insgesamt benützt wurden.",
"ScopeX": "Anwendungsbereich %s",
"Index": "Index",
"Usages": "Verwendungen",
"Unused": "Unbenutzt",
"CreateNewSlot": "Die Anzahl verfügbarer benutzerdefinierter Variablen erhöhen",
"UsageDetails": "%1$s Besuche und %2$s Aktionen seit der Erstellung dieser Website.",
"CreatingCustomVariableTakesTime": "Neue benutzerdefinierte Variablen zu erstellen kann viel Zeit beanspruchen, abhängig von der Größe Ihrer Datenbank. Deshalb ist dieser Vorgang nur über Kommandozeilen verfügbar.",
"CurrentAvailableCustomVariables": "Aktuell können Sie bis zu %s benutzerdefinierte Variablen pro Seite einsetzen.",
"ToCreateCustomVarExecute": "Um eine neue benutzerdefinierte Variable zu erstellen, führen Sie in Ihrer Matomo Installation folgenden Befehl aus:",
"SlotsReportIsGeneratedOverTime": "Daten für diesen Bericht werden periodisch veröffentlicht. Es mag ein oder zwei Tage dauern, bis Daten sichtbar sind und einige Wochen bis der Bericht vollständig aussagekräftig ist.",
"MetricsAreOnlyAvailableForVisitScope": "Hinweis: Die Metriken %1$s sind nur für benutzerdefinierte Variablen mit Geltungsbereich %2$s verfügbar.",
"MetricsNotAvailableForPageScope": "Für benutzerdefinierte Variablen mit Geltungsbereich %1$s ist der Wert für diese Metriken %2$s."
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Ονομασία Προσαρμοσμένης Μεταβλητής",
"ColumnCustomVariableValue": "Τιμή Προσαρμοσμένης Μεταβλητής",
"CustomVariables": "Προσαρμοσμένες Μεταβλητές",
"CustomVariablesReportDocumentation": "Η αναφορά περιέχει πληροφορίες σχετικά με τις Προσαρμοσμένες Μεταβλητές. Κάντε κλικ στο όνομα μιας μεταβλητής για να δείτε την κατανομή των τιμών. %1$sΓια περισσότερες πληροφορίες σχετικά με τις Προσαρμοσμένες Μεταβλητές γενικά, διαβάστε την %2$sτεκμηρίωση για τις Προσαρμοσμένες Μεταβλητές στο matomo.org%3$s",
"PluginDescription": "Οι Προσαρμοσμένες Μεταβλητές είναι ζεύγη (όνομα, τιμή) που μπορείτε να ορίσετε με χρήση του Javascript API σε επισκέπτες ή σε οποιαδήποτε ενέργειά τους. Το Matomo θα αναφέρει τότε τον αριθμό των επισκέψεων, σελίδων, μετατροπών για κάθε ένα από αυτά τα ονόματα και τιμές. Δείτε τις λεπτομερείς Προσαρμοσμένες Μεταβλητές για κάθε χρήστη και ενέργεια στο Ημερολόγιο Επιοκεπτών. Το πρόσθετο απαιτείται για τη χρήση του χαρακτηριστικού Αναλυτικών Ηλεκτρονικού Εμπορίου!",
"ScopePage": "σελίδα σκοπού",
"ScopeVisit": "επίσκεψη σκοπού",
"ScopeConversion": "εύρος μετατροπής",
"ManageDescription": "Η σύνοψη αυτή δείχνει όλες τις σχισμές προσαρμοσμένων μεταβλητών και τις χρήσεις τους για τον ιστοτόπο '%s'. Τα ονόματα σε κάθε σχισμή ταξινομούνται με βάση το πόσο συχνά χρησιμοποιούνται στο σύνολο.",
"ScopeX": "Εμβέλεια %s",
"Index": "Ευρετήριο",
"Usages": "Χρήσεις",
"Unused": "Δεν χρησιμοποιούνται",
"CreateNewSlot": "Αυξήστε τον αριθμό των σχισμών Προσαρμοσμένων Μεταβλητών",
"UsageDetails": "%1$s επισκέψεις και %2$s ενέργειες από την στιγμή δημιουργίας του ιστοτόπου.",
"CreatingCustomVariableTakesTime": "Η δημιουργία σχισμής προσαρμοσμένης μεταβλητής μπορεί να διαρκέσει αρκετή ώρα ανάλογα με το μέγεθος της βάσης. Οπότε, αυτό είναι πρέπει να γίνεται από εντολή που χρειάζεται να εκτελεστεί από την γραμμή εντολών.",
"CurrentAvailableCustomVariables": "Αυτή τη στιγμή μπορείτε να χρησιμοποιήσετε %s Προσαρμοσμένες Μεταβλητές ανά ιστοτόπο.",
"ToCreateCustomVarExecute": "Για να δημιουργήσετε μια σχισμή προσαρμοσμένης μεταβλητής πρέπει να εκτελέσετε την παρακάτω εντολή στην εγκατάσταση του Matomo σας:",
"SlotsReportIsGeneratedOverTime": "Τα δεδομένα για αυτή την αναφορά θα συμπληρώνονται με το πέρασμα του χρόνου. Μπορεί να χρειαστούν μία ή δύο μέρες για να δείτε δεδομένα και μερικές εβδομάδες μέχρι η αναφορά να είναι ακριβής.",
"MetricsAreOnlyAvailableForVisitScope": "Σημείωση: %1$s μετρικές είναι διαθέσιμες για τις Προσαρμοσμένες Μεταβλητές εμβέλειας %2$s μόνο.",
"MetricsNotAvailableForPageScope": "Για Προσαρμοσμένες Μεταβλητές εμβέλειας %1$s, η τιμή στήλης για τις μετρικές αυτές είναι %2$s"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Custom Variable name",
"ColumnCustomVariableValue": "Custom Variable value",
"CustomVariables": "Custom Variables",
"CustomVariablesReportDocumentation": "This report contains information about your Custom Variables. Click on a variable name to see the distribution of the values. %1$s For more information about Custom Variables in general, read the %2$sCustom Variables documentation on matomo.org%3$s",
"PluginDescription": "Custom Variables are (name, value) pairs that you can assign using the Javascript API to visitors or any of their action. Matomo will then report how many visits, pages, conversions for each of these custom names and values. View the detailed Custom Variables for each user and action in the Visitor Log. This plugin is required to use Ecommerce Analytics feature!",
"ScopePage": "scope page",
"ScopeVisit": "scope visit",
"ScopeConversion": "scope conversion",
"ManageDescription": "This overview shows all custom variable slots and their usages for website '%s'. The names within each slot are ordered by how often they were used in total.",
"ScopeX": "Scope %s",
"Index": "Index",
"Usages": "Usages",
"Unused": "Unused",
"CreateNewSlot": "Increase the number of available Custom Variables slots",
"UsageDetails": "%1$s visits and %2$s actions since creation of this website.",
"CreatingCustomVariableTakesTime": "Creating a new custom variable slot can take a long time depending on the size of your database. Therefore it is only possible to do this via a command which needs to be executed on the command line.",
"CurrentAvailableCustomVariables": "Currently you can use up to %s Custom Variables per site.",
"ToCreateCustomVarExecute": "To create a new custom variable slot execute the following command within your Matomo installation: ",
"SlotsReportIsGeneratedOverTime": "Data for this report will be populated over time. It may take a day or two to see any data and a few weeks until the report is fully accurate.",
"MetricsAreOnlyAvailableForVisitScope": "Note: %1$s metrics are available for Custom Variables of scope %2$s only.",
"MetricsNotAvailableForPageScope": "For Custom Variables of scope %1$s, the column value for these metrics is %2$s"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nombre de la Variable Personalizada",
"ColumnCustomVariableValue": "Valor de la Variable Personalizada",
"CustomVariables": "Variables Personalizadas",
"CustomVariablesReportDocumentation": "Este reporte contiene información sobre sus Variables Personalizadas. Haga clic en el nombre de una variable para ver la distribución de los valores. %1$s Para más información sobre las Variables Personalizadas en general, lea la %2$sdocumentación de Variables Personalizadas en matomo.org%3$s",
"ScopePage": "ámbito de la página",
"ScopeVisit": "ámbito de la visita"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nombre de la Variable Personalizada",
"ColumnCustomVariableValue": "Valor de la Variable Personalizada",
"CustomVariables": "Variables Personalizadas",
"CustomVariablesReportDocumentation": "Este informe contiene información sobre sus Variables Personalizadas. Haga clic en el nombre de una variable para ver la distribución de los valores. %1$s Para más información sobre las Variables Personalizadas en general, lea la %2$sdocumentación de Variables Personalizadas en matomo.org%3$s",
"PluginDescription": "Variables Personalizadas (nombre, valor) son pares que puede atribuir mediante la Javascript API a sus visitantes o a cualquiera de sus acciones. Matomo luego informará el número de visitas, páginas, las conversiones para cada uno de estos nombres y valores personalizados. Vea las variables personalizadas detalladas para cada usuario y sus acciones en el registro de visitantes. Este módulo es necesario para usar la función Ecommerce Analytics!",
"ScopePage": "ámbito de la página",
"ScopeVisit": "alcance de la visita",
"ScopeConversion": "alcance de la conversión",
"ManageDescription": "Esta visión general muestra todas las variantes personalizadas y su uso en los sitios '%s'. Los nombres dentro de cada espacio están clasificados por la frecuencia con que se utilizaron en su totalidad.",
"ScopeX": "Ambito %s",
"Index": "Índice",
"Usages": "Usos",
"Unused": "No usado",
"CreateNewSlot": "Aumente el número de variables personalizadas disponibles",
"UsageDetails": "%1$s visitas y %2$s acciones desde la creación de este sitio.",
"CreatingCustomVariableTakesTime": "Crear una nueva variable personalizada puede tomar un cierto tiempo dependiendo del tamaño de su base de datos. Por lo tanto, sólo es posible hacerlo vía un comando que necesita ser ejecutado desde la línea de comando.",
"CurrentAvailableCustomVariables": "Actualmente puede usar hasta %s variables personalizadas por sitio.",
"ToCreateCustomVarExecute": "Para crear una nueva variable personalizada ejecute el siguiente comando dentro de su instalación Matomo:",
"SlotsReportIsGeneratedOverTime": "Los datos de este informe irán aumentando con el tiempo. Puede tomar un día o dos para ver cualquier dato y unas pocas semanas hasta que el informe sea totalmente exacto.",
"MetricsAreOnlyAvailableForVisitScope": "Nota: Solo %1$s métricas están disponibles para las variables personalizadas de ámbito %2$s.",
"MetricsNotAvailableForPageScope": "Para variables personalizadas de ámbito %1$s, el valor de estas métricas es %2$s"
}
}

View File

@ -0,0 +1,11 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Kohandatud muutuja nimi",
"ColumnCustomVariableValue": "Kohandatud muutuja väärtus",
"CustomVariables": "Kohandatud muutujad",
"ScopePage": "skoop: lehekülg",
"ScopeVisit": "skoop: külastus",
"Index": "Indeks",
"Usages": "Kasutamised"
}
}

View File

@ -0,0 +1,9 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "نام متغیر سفارشی",
"ColumnCustomVariableValue": "مقدار متغیر سفارشی",
"CustomVariables": "متغیرهای سفارشی",
"ScopePage": "حوزه صفحه",
"ScopeVisit": "بازدید دامنه"
}
}

View File

@ -0,0 +1,14 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Kustomoidun muuttujan nimi",
"ColumnCustomVariableValue": "Kustomoidun muuttujan arvo",
"CustomVariables": "Kustomoidut muuttujat",
"CustomVariablesReportDocumentation": "Tämä raportti sisältää tietoa kustomoiduista muuttujastasi. Voit tarkastella eri arvojen määrää klikkaamalla muuttujan nimeä. %1$s Saat lisätietoa kustomoiduista muuttujista %2$sCustom Variables%3$s-sivulta matomo.orgista (englanninkielinen)",
"ScopePage": "alueena sivu",
"ScopeVisit": "alueena käynti",
"ManageDescription": "Tämä on yleiskatsaus kaikista kustomoiduista muuttujista ja niiden käytöstä verkkosivulla '%s'. Nimet on järjestetty käyttömäärien mukaan.",
"Index": "Indeksi",
"Usages": "Käytöt",
"Unused": "Käyttämätön"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nom de la variable personnalisée",
"ColumnCustomVariableValue": "Valeur de la variable personnalisée",
"CustomVariables": "Variables personnalisées",
"CustomVariablesReportDocumentation": "Ce rapport contient des informations à propos de vos Variables Personnalisées. Cliquez sur un nom de variable pour voir la répartition de la valeur. %1$s Pour plus d'informations à propos des variables personnalisées en général, lisez la %2$s documentation sur les variables personnalisées sur matomo.org%3$s",
"PluginDescription": "Les Variables Personnalisées sont des paires (nom, valeur) que vous pouvez assigner aux visiteurs, n'importe quelle de leurs actions en utilisant l'API JavaScript. Matomo rapportera ensuite combien de visites, pages, conversions pour chacun des ces noms et valeurs personnalisés. Consultez le détail des variables personnalisées pour chaque utilisateur et action dans le journal des visiteurs. Ce composant est requis afin d'utilise les fonctionnalités d'analyse e-commerce!",
"ScopePage": "Étendue page",
"ScopeVisit": "Étendue visite",
"ScopeConversion": "conversion de portée",
"ManageDescription": "Cette vue d'ensemble affiche tous les emplacements de variables personnalisées et leur utilisation pour le site web \"%s\". Les noms dans chacun des emplacements sont ordonnés par le nombre de fois qu'elles ont été utilisées au total.",
"ScopeX": "Etendue %s",
"Index": "Index",
"Usages": "Usages",
"Unused": "Inutilisé",
"CreateNewSlot": "Augmenter le nombre d'emplacement de variables personnalisées disponibles",
"UsageDetails": "%1$s visites et %2$s actions depuis la création de ce site web.",
"CreatingCustomVariableTakesTime": "La création de nouveaux emplacement de variable personnalisée peut prendre du temps dépendamment de la taille de votre base de données. De ce fait il est possible d'effectuer cela uniquement via une commande qui doit être exécutée dans la console.",
"CurrentAvailableCustomVariables": "Pour l'instant vous pouvez utiliser jusqu'à %s Variables personnalisées par site.",
"ToCreateCustomVarExecute": "Pour créer un nouvel emplacement de variable personnalisée exécutez la commande suivante dans votre installation de Matamo :",
"SlotsReportIsGeneratedOverTime": "Les données pour ce rapport vont être peuplées avec le temps. Il se peut que cela prenne un jour ou deux pour voir des informations et quelques semaines avant que le rapport ne soit précis.",
"MetricsAreOnlyAvailableForVisitScope": "Note: %1$s les métriques sont disponibles pour les variables personnalisées de la portée %2$s uniquement.",
"MetricsNotAvailableForPageScope": "Pour les variables personnalisées de la portée %1$s, la valeur de colonne pour ces métriques est %2$s"
}
}

View File

@ -0,0 +1,7 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "שם המשתנה",
"ColumnCustomVariableValue": "ערך המשתנה",
"CustomVariables": "משתנים מותאמים אישים"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "विशेष चर नाम",
"ColumnCustomVariableValue": "विशेष चर मूल्य",
"CustomVariables": "विशेष चर",
"CustomVariablesReportDocumentation": "यह रिपोर्ट आपके कस्टम चर के बारे में जानकारी शामिल हैं. मूल्यों के वितरण को देखने के लिए एक चर के नाम पर क्लिक करें. %1$sसामान्य रूप में %2$sकस्टम चर के बारे में अधिक जानकारी के लिए, matomo.org %3$s पर कस्टम चर दस्तावेज़ पढ़ें",
"ScopePage": "प्रसार पृष्ठ",
"ScopeVisit": "प्रसार यात्रा"
}
}

View File

@ -0,0 +1,13 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nama Variabel Kustom",
"ColumnCustomVariableValue": "Nilai Variabel Kustom",
"CustomVariables": "Variabel Kustom",
"CustomVariablesReportDocumentation": "Laporan ini mengandung informasi tentang Variabel Kustom Anda. Klik di nama variabel untuk melihat distribusi nilai. %1$s Informasi lebih lengkap tentang Vabiabel Kustom, baca %2$sdokumentasi Vabiabel Kustom di matomo.org%3$s",
"ScopePage": "cakupan halaman",
"ScopeVisit": "cakupan kunjungan",
"Index": "Indeks",
"Usages": "Penggunaan",
"Unused": "Tidak digunakan"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nome Variabile Personalizzata",
"ColumnCustomVariableValue": "Valore Variabile Personalizzata",
"CustomVariables": "Variabile Personalizzata",
"CustomVariablesReportDocumentation": "Questo report contiene informazioni sulle variabili personalizzate. Clicca sul nome di una variabile per vedere la distribuzione dei valori. %1$s Per ulteriori informazioni sulle Variabili Personalizzate in generale, leggi la %2$sdocumentazione sulle Variabili Personalizzate su matomo.org%3$s",
"PluginDescription": "Le Variabili Personalizzate sono coppie (nome, valore) che è possibile assegnare utilizzando l'API di Javascript ai visitatori o una qualsiasi delle loro azioni. Matomo segnalerà quindi quante visite, pagine, conversioni per ciascuno di questi nomi e valori personalizzati. Visualizza le variabili personalizzate dettagliate per ogni utente e azione nel Registro Visitatori. Questo plug-in è necessario per utilizzare la funzione di Analisi Ecommerce!",
"ScopePage": "ambito pagina",
"ScopeVisit": "ambito visita",
"ScopeConversion": "conversione scope",
"ManageDescription": "Questa panoramica mostra tutti gli slot di variabili personali e il loro utilizzo nel sito '%s'. I nomi in ciascuno slot vengono ordinati a seconda di quanto sono stati utilizzati in totale.",
"ScopeX": "Ambito %s",
"Index": "Indice",
"Usages": "Usi",
"Unused": "Inutilizzate",
"CreateNewSlot": "Aumenta il numero degli slot di variabili personali disponibili",
"UsageDetails": "%1$s visite e %2$s azioni dalla creazione di questo sito web.",
"CreatingCustomVariableTakesTime": "La creazione di un nuovo slot di variabili personali può richiedere un tempo lungo che dipende dalla dimensione del tuo database. Pertanto è possibile fare ciò solo tramite un comando che deve essere eseguito da riga di comando.",
"CurrentAvailableCustomVariables": "Attualmente puoi utilizzare fino a %s variabili personali per sito.",
"ToCreateCustomVarExecute": "Per creare un nuovo slot di variabili personalizzate esegui il comando seguente nella tua installazione di Matomo:",
"SlotsReportIsGeneratedOverTime": "I dati per questo report saranno popolati nel tempo. Ciò può richiedere un giorno o due per vedere dei dati, e qualche settimana perché il report sia totalmente accurato.",
"MetricsAreOnlyAvailableForVisitScope": "Nota: Sono disponibili %1$s metriche per le Variabili Speciali solo per l'ambito %2$s.",
"MetricsNotAvailableForPageScope": "Per le Variabili Speciali dell'ambito %1$s, il valore colonna è %2$s"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "カスタム変数名",
"ColumnCustomVariableValue": "カスタム変数値",
"CustomVariables": "カスタム変数",
"CustomVariablesReportDocumentation": "このレポートには、カスタム変数に関する情報が含まれています。値の分布を表示するには、変数名をクリックして下さい。%s 一般的なカスタム変数の詳細については、%sCustom Variables documentation on piwik.org%s をお読み下さい。",
"ScopePage": "スコープはページ",
"ScopeVisit": "スコープはビジット"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "맞춤 변수 이름",
"ColumnCustomVariableValue": "맞춤 변수 값",
"CustomVariables": "맞춤 변수",
"CustomVariablesReportDocumentation": "이 보고서는 맞춤 변수에 대한 정보를 포함합니다. 변수 이름을 클릭하여 값의 분포를 확인할 수 있습니다. %1$s 맞춤 변수에 대한 자세한 내용은 %2$smatomo.org의 맞춤 변수 설명서%3$s를 참조하세요.",
"ScopePage": "페이지 범위",
"ScopeVisit": "방문 범위"
}
}

View File

@ -0,0 +1,22 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Navn på egendefinert variabel",
"ColumnCustomVariableValue": "Verdi på egendefinert variabel",
"CustomVariables": "Egendefinerte variabler",
"CustomVariablesReportDocumentation": "Denne rapporten inneholder informasjon om dine egendefinerte variabler. Klikk på et variabelnavn for å se fordelingen av verdier. %1$sFor mer informasjon om egendefinerte variabler, les %2$sdokumentasjonen om egendefinerte variabler på matomo.org%3$s",
"ScopePage": "gjelder side",
"ScopeVisit": "gjelder besøk",
"ManageDescription": "Dette sammendraget viser alle mulige egendefinerte variabler og deres bruk for nettstedet «%s». Navnene i hver «luke» er sortert etter hvor ofte de blir brukt.",
"ScopeX": "Gjelder %s",
"Index": "Indeks",
"Usages": "Bruk",
"Unused": "Ubrukt",
"CreateNewSlot": "Øk antallet tilgjengelige egendefinerte variabler",
"UsageDetails": "%1$s besøk og %2$s handlinger siden dette nettstedet ble laget.",
"CreatingCustomVariableTakesTime": "Å lage en ny luke for en egendefinert variabel kan ta lang tid avhengig av størrelsen på databasen din. Derfor er det kun mulig å gjøre dette via en kommando som må kjøres fra kommandolinjen.",
"CurrentAvailableCustomVariables": "Nå kan du bruke opp til %s egendefinerte variabler per nettsted.",
"SlotsReportIsGeneratedOverTime": "Data for denne rapporten vil bli synlige over tid. Det kan ta en dag eller to før du kan se data, og noen uker før rapportene er helt nøyaktige.",
"MetricsAreOnlyAvailableForVisitScope": "Merk: %1$s-måltall er kun tilgjengelige for egendefinerte variabler som gjelder %2$s.",
"MetricsNotAvailableForPageScope": "For egendefinerte variabler som gjelder %1$s, er kolonneverdien for disse måltallene %2$s"
}
}

View File

@ -0,0 +1,22 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Naam aangepaste variabele",
"ColumnCustomVariableValue": "Waarde aangepaste variabele",
"CustomVariables": "Aangepaste variabelen",
"CustomVariablesReportDocumentation": "Dit rapport bevat informatie over uw aangepaste variabelen. Klik op de naam van een variabele om de verdeling van de waarden te zien. %1$s voor meer informatie over aangepaste variabelen in het algemeen, lees de %2$sCustom variabelen documentatie over matomo.org%3$s",
"ScopePage": "omvang pagina",
"ScopeVisit": "omvang bezoek",
"ManageDescription": "Dit overzicht toont alle slots van custom variabelen en het gebruik voor websites '%s'. De namen in elk slot zijn gesorteerd op hoe vaak ze in totaal zijn gebruikt.",
"ScopeX": "Scope %s",
"Index": "Index",
"Usages": "Gebruikt",
"Unused": "Ongebruikt",
"CreateNewSlot": "Verhoog het aantal van beschikbare Custom Variabelen slots",
"UsageDetails": "%1$s bezoeken en %2$s acties sinds het maken van deze website.",
"CreatingCustomVariableTakesTime": "Het maken van een nieuw custom variabele slot kan een lange tijd in beslag nemen afhankelijk van de grote van de database. Om deze reden is het alleen mogelijk om dit via een commando op de command line uit te voeren.",
"CurrentAvailableCustomVariables": "Op dit moment kan je in totaal %s Custom Variables per website gebruiken.",
"SlotsReportIsGeneratedOverTime": "De data voor dit verslag wordt na verloop van tijd gegenereerd. Het kan een dag of twee duren voordat je de data ziet en een paar weken tot het rapport helemaal nauwkeurig is.",
"MetricsAreOnlyAvailableForVisitScope": "Opmerking: %1$s metrics zijn beeschikbaar voor Custom Variables alleen voor bereik %2$s .",
"MetricsNotAvailableForPageScope": "Voor Custom Variabelen met bereik %1$s, de kolom waarde deze metriek is %2$s"
}
}

View File

@ -0,0 +1,24 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nazwa Zmiennej Niestandardowej",
"ColumnCustomVariableValue": "Wartość Zmiennej Niestandardowej",
"CustomVariables": "Zmienne Niestandardowe",
"CustomVariablesReportDocumentation": "Raport ten zawiera informacje na temat Zmiennych Niestandardowych. Kliknij na nazwę zmiennej, aby zobaczyć rozkład wartości. %1$sAby uzyskać więcej informacji na temat Zmiennych Niestandardowych, przeczytaj dokumentację %2$sZmienne Niestandardowe na matomo.org%3$s",
"ScopePage": "zakres stron",
"ScopeVisit": "zakres wizyt",
"ScopeConversion": "zakres konwersji",
"ManageDescription": "Ten przegląd pokazuje wszystkie pola Zmiennych Niestandardowych i ich wykorzystanie w serwisie '%s'. Każdy przedział zawiera nazwy uporządkowane według częstości ich łącznego wykorzystanie.",
"ScopeX": "Zakres %s",
"Index": "Indeks",
"Usages": "Wykorzystanie",
"Unused": "Niewykorzystane",
"CreateNewSlot": "Zwiększ liczbę dostępnych pól Zmiennych Niestandardowych",
"UsageDetails": "%1$s wizyt i %2$s akcji od utworzenia tego serwisu.",
"CreatingCustomVariableTakesTime": "Utworzenie nowego pola Zmiennej Niestandardowej może zająć sporo czasu w zależności od wielkości Twojej bazy danych. Z tego powodu operacja ta możliwa jest jedynie z poziomu linii poleceń po wydaniu odpowiedniego polecenia.",
"CurrentAvailableCustomVariables": "Obecnie możesz wykorzystać do %s Zmiennych Niestandardowych per serwis.",
"ToCreateCustomVarExecute": "Aby utworzyć nowe pole Zmiennej Niestandardowej wykonaj następujące polecenie w ramach swojej instalacji Matomo:",
"SlotsReportIsGeneratedOverTime": "Dane dla tego raportu pojawią się po jakimś czasie. Dzień lub dwa może potrwać zanim zobaczysz jakiekolwiek dane a uzyskanie dokładnego raportu może potrwać nawet parę tygodni.",
"MetricsAreOnlyAvailableForVisitScope": "NOTKA: wskaźniki %1$s są dostępne jedynie dla Zmiennych Niestandardowych tylko w zakresie %2$s.",
"MetricsNotAvailableForPageScope": "Dla Zmiennych Niestandardowych z zakresu %1$s, kolumna wartość dla tych wskaźników to %2$s"
}
}

View File

@ -0,0 +1,24 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nome da Variável Personalizada",
"ColumnCustomVariableValue": "Valor de variável personalizado",
"CustomVariables": "Variáveis personalizadas",
"CustomVariablesReportDocumentation": "Este relatório contém informações sobre as suas variáveis personalizadas. Clique em um nome de variável para ver a distribuição dos valores. %1$s para mais informações sobre variáveis personalizadas em geral, leia a documentação %2$sCustom Variáveis em matomo.org%3$s",
"ScopePage": "página escopo",
"ScopeVisit": "visita escopo",
"ScopeConversion": "conversão de escopo",
"ManageDescription": "Esta visão geral mostra todos os compartimentos personalizados de variáveis e seus usos para o website '%s'. Os nomes dentro de cada compartimento são ordenados por quantas vezes foram utilizados no total.",
"ScopeX": "Escopo %s",
"Index": "Índice",
"Usages": "Utilizações",
"Unused": "Não utilizado",
"CreateNewSlot": "Aumentar o número de compartimentos de Variáveis Personalizadas disponíveis",
"UsageDetails": "%1$s visitas e %2$s ações desde a criação deste website.",
"CreatingCustomVariableTakesTime": "Criar um novo compartimento de variável personalizada pode levar um longo tempo, dependendo do tamanho do seu banco de dados. Por isso, só é possível fazer isso através de um comando que deve ser executado na linha de comando.",
"CurrentAvailableCustomVariables": "Atualmente você pode usar até %s Variáveis Personalizadas por site.",
"ToCreateCustomVarExecute": "Para criar uma nova variável personalizada execute o seguinte comando dentro da sua instalação Matomo:",
"SlotsReportIsGeneratedOverTime": "Os dados para este relatório serão preenchidos ao longo do tempo. Pode demorar um dia ou dois para ver todos os dados e algumas semanas até que o relatório seja totalmente preciso.",
"MetricsAreOnlyAvailableForVisitScope": "Nota: %1$s métricas estão disponíveis apenas para as Variáveis Personalizadas de alcance %2$s.",
"MetricsNotAvailableForPageScope": "Para as Variáveis Personalizadas de alcance %1$s, o valor da coluna para essas métricas é %2$s"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Nome da variável personalizada",
"ColumnCustomVariableValue": "Valor da variável personalizada",
"CustomVariables": "Variáveis personalizadas",
"CustomVariablesReportDocumentation": "Este relatório contém informações sobre as Variáveis personalizadas. Clique no nome de uma variável para ver a distribuição dos valores. %1$s Para mais informações sobre Variáveis personalizadas em geral, deve consultar a %2$sdocumentação sobre Variáveis personalizadas em matomo.org %3$s",
"PluginDescription": "As variáveis personalizadas são pares (nome, valor) que pode, com recurso à API JavaScript, atribuir a visitantes ou qualquer uma das suas ações. O Matomo irá depois reportar quantas visitas, páginas, conversões para cada um destes nomes e valores personalizados. Consulte os detalhes das Variáveis personalizadas para cada utilizar e ação no Registo de visitantes. Esta extensão é necessária para utilizar a funcionalidade de Análise de comércio eletrónico!",
"ScopePage": "âmbito da página",
"ScopeVisit": "âmbito da visita",
"ScopeConversion": "âmbito da conversão",
"ManageDescription": "Esta visão geral mostra todos os espaços para variáveis personalizadas e as respetivas utilizações para o site '%s'. Os nomes em cada espaço são ordenados pelo total da frequência de utilização.",
"ScopeX": "Âmbito da %s",
"Index": "Índice",
"Usages": "Utilizações",
"Unused": "Não utilizado",
"CreateNewSlot": "Aumentar o número de espaços disponíveis para Variáveis personalizadas",
"UsageDetails": "%1$s visitas e %2$s ações desde a criação deste site.",
"CreatingCustomVariableTakesTime": "A criação de um novo espaço para uma variável personalizada pode demorar muito tempo, dependendo do tamanho da sua base de dados. Assim sendo, apenas é possível fazer isto via um comando que necessita de ser executado na linha de comandos.",
"CurrentAvailableCustomVariables": "Atualmente pode utilizar até %s variáveis personalizadas por site.",
"ToCreateCustomVarExecute": "Para criar um novo espaço para uma variável personalizada, execute o seguinte comando na sua instalação do Matomo:",
"SlotsReportIsGeneratedOverTime": "Os dados para este relatório serão apurados ao longo do tempo. Pode demorar um dia ou dois até serem apresentados alguns dados e algumas semanas até o relatório ser completamente fidedigno.",
"MetricsAreOnlyAvailableForVisitScope": "Nota: estão disponíveis %1$s métricas para Variáveis personalizadas especificamente de âmbito %2$s",
"MetricsNotAvailableForPageScope": "Para variáveis personalizadas de âmbito %1$s, o valor da coluna para estas métricas é %2$s"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Denumirea variabilei personalizate",
"ColumnCustomVariableValue": "Valoarea variabilei personalizate",
"CustomVariables": "Variabile personalizate",
"CustomVariablesReportDocumentation": "Acest raport conține informații despre Variabilele Personalizate. Faceți clic pe un nume de variabilă pentru a vedea distribuția valorilor. %1$s Pentru mai multe informații despre variabile personalizate, în general, citiți %2$sdocumentatia Variabilelor Personalizate matomo.org%3$s",
"ScopePage": "scop pagină",
"ScopeVisit": "scop vizită"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Имя пользовательской переменной",
"ColumnCustomVariableValue": "Значение пользовательской переменной",
"CustomVariables": "Пользовательские переменные",
"CustomVariablesReportDocumentation": "Этот отчет отображает информацию по вашим Пользовательским Переменным. Кликните по переменной, чтобы увидеть распределение значений. %1$s Для большей информации о Пользов. Переменных в общих чертах ознакомьтесь с %2$sдокументацией по Пользов. переменных на сайте matomo.org%3$s",
"PluginDescription": "Пользовательские переменные — это пара (имя, значение), которую вы можете назначить с помощью Javascript API посетителям или любым их действиям. Затем Matomo сообщит, сколько посещений, страниц, конверсий для каждого из этих пользовательских имён и значений. Просмотрите подробные пользовательские переменные для каждого пользователя и действия в журнале посещений. Этот плагин необходим для использования функции Ecommerce Analytics!",
"ScopePage": "область страницы",
"ScopeVisit": "область визита",
"ScopeConversion": "область конверсии",
"ManageDescription": "Этот обзор показывает все слоты для пользовательских переменных и их использование для вебсайта «%s». Названия в пределах одного слота распределены по общей частоте использования.",
"ScopeX": "Область %s",
"Index": "Индекс",
"Usages": "Использование",
"Unused": "Не использовано",
"CreateNewSlot": "Увеличить количество доступных слотов Пользовательских переменных",
"UsageDetails": "%1$s посещений и %2$s действий с момента создания этого вебсайта.",
"CreatingCustomVariableTakesTime": "Создание нового слота пользовательских переменных может занять долгое время в зависимости от размера вашей базы данных. Поэтому, это возможно сделать только с помощью команды, которая должна выполняться в командной строке.",
"CurrentAvailableCustomVariables": "В данный момент вы можете использовать до %s Пользовательских переменных на сайт.",
"ToCreateCustomVarExecute": "Чтобы создать новый пользовательский слот переменной, выполните следующую команду в вашей установке Matomo:",
"SlotsReportIsGeneratedOverTime": "Информация для этого отчета будет заполнена со временем. Это может занять день или два, чтобы увидеть какую-либо информацию, и несколько недель, чтобы получить точный отчет.",
"MetricsAreOnlyAvailableForVisitScope": "Замечание: %1$s метрика доступна только для Пользовательских переменных выборки %2$s.",
"MetricsNotAvailableForPageScope": "Для выборки Пользовательских переменных %1$s, значение столбца для этих метрик — %2$s"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Názov vlastnej premennej",
"ColumnCustomVariableValue": "Hodnota vlastnej premennej",
"CustomVariables": "Vlastné premenné",
"ScopeX": "Rozsah %s",
"Index": "Index",
"Unused": "Nepoužité"
}
}

View File

@ -0,0 +1,5 @@
{
"CustomVariables": {
"CustomVariables": "Dodatni parametri"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Emër Ndryshoreje Vetjake",
"ColumnCustomVariableValue": "Vlerë Ndryshoreje Vetjake",
"CustomVariables": "Ndryshore Vetjake",
"CustomVariablesReportDocumentation": "Ky raport përmban të dhëna rreth Ndryshoreve tuaja Vetjake. Klikoni mbi një emër ndryshoreje që të shihni shpërndarjen e vlerave. %1$s Për më tepër të dhëna rreth Ndryshoresh Vetjake në përgjithësi, lexoni %2$sdokumentimin e Ndryshoreve Vetjake te matomo.org%3$s",
"PluginDescription": "Ndryshoret Vetjake janë çifte (emër, vlerë) që duke përdorur API-n Javascript mund tua përshoqëroni vizitorëve apo cilitdo veprimi të tyre. Matomo mandej do të raportojë sa vizita, faqe, shndërrime për secilin nga këto emra dhe vlera. Shihni në hollësi Ndryshore Vetjake për çdo përdorues dhe veprim te Regjistri i Vizitorëve.<br \/>E domosdoshme për të përdorur veçorinë <a href=\\\"https:\/\/matomo.org\/docs\/ecommerce-analytics\/\">Analiza E-tregtie<\/a>!",
"ScopePage": "faqe me qëllim",
"ScopeVisit": "vizitë me qëllim",
"ScopeConversion": "shndërrim me qëllim",
"ManageDescription": "Kjo përmbledhje tregon krejt vendet e ndryshoreve vetjake dhe përdorimin e tyre për sajtin '%s'. Emrat brenda secilit vend renditen sipas shpeshtisë së përdorimit të tyre gjithsej.",
"ScopeX": "Fusha %s",
"Index": "Tregues",
"Usages": "Përdorime",
"Unused": "I papërdorur",
"CreateNewSlot": "Rrite numrin e vendeve të mundshme të Ndryshoreve Vetjake",
"UsageDetails": "%1$s vizita dhe %2$s veprime që nga krijimi i sajtit.",
"CreatingCustomVariableTakesTime": "Krijimi i një vendi të ri ndryshoreje vetjake mund të dojë një kohë të gjatë, në varësi të madhësisë së bazës suaj të të dhënave. Ndaj kjo është e mundur të bëhet vetëm përmes një urdhri që lypset të xhirohet te rreshti i urdhrave.",
"CurrentAvailableCustomVariables": "Hëpërhë mund të përdorni deri në %s Ndryshore Vetjake për sajt.",
"ToCreateCustomVarExecute": "Për krijimin e një vendi të ri ndryshoreje vetjake përmbushni urdhrin vijues brenda instalimit tuaj të Matomo-s:",
"SlotsReportIsGeneratedOverTime": "Të dhënat për këtë raport do të mblidhen me kalimin e kohës. Mund të duhen një a dy ditë që të shihni çfarëdo të dhënash dhe ca javë përpara se raporti të jetë plotësisht i saktë.",
"MetricsAreOnlyAvailableForVisitScope": "Shënim: Vlerat %1$s janë të passhme vetëm për Ndryshore Vetjake të fushës %2$s.",
"MetricsNotAvailableForPageScope": "Për Ndryshore Vetjake të fushës %1$s, vlera e shtyllës për këto të dhëna është %2$s"
}
}

View File

@ -0,0 +1,22 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Ime dodatnog parametra",
"ColumnCustomVariableValue": "Vrednost dodatnog parametra",
"CustomVariables": "Dodatni parametri",
"CustomVariablesReportDocumentation": "Ovaj izveštaj sadrži informacije o dodatnim parametrima. Kliknite na ime parametra kako biste videli distribuciju vrednosti. %1$s Za više informacija o dodatnim parametrima pogledajte %2$sCustom Variables na matomo.org%3$s",
"ScopePage": "oblast strana",
"ScopeVisit": "oblast poseta",
"ManageDescription": "Ovaj pregled prikazuje sve dodatne parametre i njihovu upotrebu za sajt '%s'. Nazivi su poređani po tome koliko često je koja upotrebljena.",
"ScopeX": "Oblast %s",
"Index": "Indeks",
"Usages": "Upotrebe",
"Unused": "Neiskorišćeno",
"CreateNewSlot": "Povećajte broj raspoloživih dodatnih parametara.",
"UsageDetails": "%1$s poseta i %2$sakcija od kreiranja ovog sajta.",
"CreatingCustomVariableTakesTime": "Kreiranje novog dodatnog parametra može da uzme dosta vremena u zavisnosti od veličine vaše baze. Zbog toga je to moguće uraditi samo iz komandne linije.",
"CurrentAvailableCustomVariables": "Trenutno možete da koristite do %s dodatnih parametara po sajtu.",
"SlotsReportIsGeneratedOverTime": "Podaci za ovaj izveštaj će biti pripremani tokom vremena. Može proći dan ili dva pre nego što budete videli bilo kakve podatke i nekoliko nedelja pre nego što izveštaj bude bio potpuno precizan.",
"MetricsAreOnlyAvailableForVisitScope": "Pažnja: samo %1$s metrika je na raspolaganju za dodatne parametre u opsegu %2$s.",
"MetricsNotAvailableForPageScope": "Za dodatne parametre iz oblasti %1$s, vrednost kolone za te metrike je %2$s."
}
}

View File

@ -0,0 +1,24 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Anpassat variabelnamn",
"ColumnCustomVariableValue": "Anpassat variabelvärde",
"CustomVariables": "Anpassade variabler",
"CustomVariablesReportDocumentation": "Denna rapport innehåller information om din anpassade variabler. Klicka på ett variabelnamn för att se fördelningen av värdena. %1$s För mer information om anpassade variabler i allmänhet, läs %2$sdokumentationen om anpassade variabler på matomo.org%3$s",
"ScopePage": "omfattning sida",
"ScopeVisit": "omfattning besök",
"ScopeConversion": "Omfattning av konvertering",
"ManageDescription": "Denna översikt visar alla anpassade variabler och dess användande för webbplatsen '%s'. Namnen för varje slot sorteras på hur ofta dom har använts totalt.",
"ScopeX": "Omfattning %s",
"Index": "Index",
"Usages": "Användningar",
"Unused": "Oanvänd",
"CreateNewSlot": "Öka antalet tillgängliga anpassade variabelspår",
"UsageDetails": "%1$s besök och %2$s händelser sedan webbplatsen skapandet av denna webbplats.",
"CreatingCustomVariableTakesTime": "Att skapa en ny anpassad variabel kan ta lång tid beroende på storleken på din databas. Därför är det bara möjligt att göra detta via ett kommando som måste köras genom kommandoraden.",
"CurrentAvailableCustomVariables": "För tillfället kan du använda upp till %s anpassade variabler per webbsida.",
"ToCreateCustomVarExecute": "För att skapa en ny anpassad variabel använd följande kommando i din Matomo miljö:",
"SlotsReportIsGeneratedOverTime": "Data för den här rapporten kommer att samlas in allt eftersom. Det kan ta en dag eller två innan du ser någon data och ett par veckor innan rapporten är helt tillförlitlig.",
"MetricsAreOnlyAvailableForVisitScope": "Notering: %1$s mätvärden finns endast tillgängliga för Anpassade Variabler av omfattningen %2$s.",
"MetricsNotAvailableForPageScope": "För Anpassade Variabler av omfattningen %1$s är kolumnvärdet för dessa mätvärden %2$s"
}
}

View File

@ -0,0 +1,9 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "தனிபயன் மாறியின் பெயர்",
"ColumnCustomVariableValue": "தனிப்பயன் மாறி அளவுரு",
"CustomVariables": "தனிபயன் மாறி",
"ScopePage": "நோக்க பக்கம்",
"ScopeVisit": "வருகை நோக்கம்"
}
}

View File

@ -0,0 +1,7 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "ชื่อตัวแปรที่กำหนดเอง",
"ColumnCustomVariableValue": "ค่าตัวแปรที่กำหนดเอง",
"CustomVariables": "ตัวแปรที่กำหนดเอง"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Pangalan ng Custom na Variable",
"ColumnCustomVariableValue": "Halaga ng Custom na Variable",
"CustomVariables": "Mga Custom na Variable",
"CustomVariablesReportDocumentation": "Ang ulat na ito ay naglalaman ng mga impormasyon tunkol sa iyong mga Custom Variable. E-click ang pangalan ng variable upang makita ang pagkakabahagi ng mga laman nito. %1$s Upang makita ang pangkalahatang impormasyon tungkol sa Custom Variables basahin ang %2$sCustom Variables documentation sa matomo.org%3$s.",
"ScopePage": "saklaw na pahina",
"ScopeVisit": "Saklaw ng pagbisita"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Özel Değişken Adı",
"ColumnCustomVariableValue": "Özel Değişken Değeri",
"CustomVariables": "Özel Değişkenler",
"CustomVariablesReportDocumentation": "Bu rapor özel değişkenler hakkında bilgileri görüntüler. Değerlerinin dağılımını görüntülemek istediğiniz değişken adının üzerine tıklayın. %1$sGenel olarak özel değişkenlar hakkında ayrıntılı bilgi almak için %2$smatomo.org sitesindeki Özel Değişkenler belgesini okuyun%3$s",
"PluginDescription": "Özel değişkenler çiftler şeklinde (ad, değer) bulunur ve JavaScript API kullanılarak ziyaretçiler ve ziyaretçi işlemlerine atanabilir. Matomo böylece her bir özel ad ve değer için ziyaret sayısını, tutturulan hedefleri raporlar. Ziyaretçi günlüğünde her kullanıcı ve işlem için özel değişkenlerin ayrıntıları görüntülenir. E-ticaret istatistikleri özelliği için bu uygulama ekinin kullanılması gereklidir!",
"ScopePage": "aralık sayfası",
"ScopeVisit": "aralık ziyareti",
"ScopeConversion": "aralıkta hedef tutturma",
"ManageDescription": "Bu özette tüm özel değişken aralıkları ve '%s' web sitesindeki kullanımları görüntülenir. Her bir aralıktaki adlar toplam içinde ne kadar sık kullanıldıklarına göre sıralanır.",
"ScopeX": "%s aralığı",
"Index": "Dizin",
"Usages": "Kullanılan",
"Unused": "Kullanılmayan",
"CreateNewSlot": "Kullanılabilecek Özel Değişken aralıklarının sayısını arttır",
"UsageDetails": "Sitenin kuruluşundan beri %1$s ziyaret ve %2$s işlem.",
"CreatingCustomVariableTakesTime": "Yeni bir özel değişken aralığının oluşturulması veritabanınızın boyutuna göre uzun zaman alabilir. Bu nedenle bu işlem yalnız komut satırından yürütülmesi gereken bir komut ile yapılabilir.",
"CurrentAvailableCustomVariables": "Şu anda her site için en çok %s Özel Değişken kullanabilirsiniz.",
"ToCreateCustomVarExecute": "Yeni bir özel değişken aralığı eklemek için Matomo kopyanız üzerinde şu komutu yürütün:",
"SlotsReportIsGeneratedOverTime": "Bu raporun verileri zaman içinde oluşacak. Raporda verilerin görüntülenmesi 1 - 2 gün, bilgilerin tam doğru görüntülenmesi bir kaç hafta sürebilir.",
"MetricsAreOnlyAvailableForVisitScope": "Not: %1$s ölçütleri yalnız %2$s aralığındaki Özel Değişkenler için kullanılabilir.",
"MetricsNotAvailableForPageScope": "%1$s aralığındaki Özel Değişkenler için bu ölçütlerin sütun değeri %2$s"
}
}

View File

@ -0,0 +1,24 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Ім'я користувача змінної",
"ColumnCustomVariableValue": "Значення для користувцької змінної",
"CustomVariables": "Користувальницькі змінні",
"CustomVariablesReportDocumentation": "Цей звіт відображає інформацію по вашим Користувацьким змінним. Натисніть по змінній, щоб побачити розподіл значень. %1$s Для більшої інформації про користувальницькі змінні в загальних рисах ознайомтеся з %2$sдокументацією по Користувацьким змінним на сайті matomo.org%3$s",
"ScopePage": "область видимості сторінки",
"ScopeVisit": "область видимості візиту",
"ScopeConversion": "конверсія сфери",
"ManageDescription": "Цей огляд показує всі слоти для користувальницьких змінних і їх використання для вебсайту '%s'. Назви в межах одного слота розподілені по загальній частоті використання.",
"ScopeX": "Вибірка %s",
"Index": "Індекс",
"Usages": "Використання",
"Unused": "Не використано",
"CreateNewSlot": "Збільшити кількість доступних слотів для користувальницьких змінних",
"UsageDetails": "%1$s відвідувань і %2$s дій з моменту створення цього вебсайту.",
"CreatingCustomVariableTakesTime": "Створення нового слоту для користувальницьких змінних може зайняти тривалий час в залежності від розміру вашої бази даних. Тому, це можливо зробити тільки за допомогою команди, яка повинна виконуватися в командному рядку на сервері.",
"CurrentAvailableCustomVariables": "В даний момент ви можете використовувати до %s користувальницьких змінних на сайт.",
"ToCreateCustomVarExecute": "Щоб створити новий користувальницький слот для змінної, виконайте наступну команду у вашій установці Matomo:",
"SlotsReportIsGeneratedOverTime": "Інформація для цього звіту буде заповнена з часом. Це може зайняти день або два, щоб побачити будь-яку інформацію, і кілька тижнів, щоб отримати точний звіт.",
"MetricsAreOnlyAvailableForVisitScope": "Увага: %1$s метрика доступна тільки для користувальницьких змінних вибірки %2$s.",
"MetricsNotAvailableForPageScope": "Для вибірки користувальницьких змінних %1$s, значення стовпця для цих метрик - %2$s"
}
}

View File

@ -0,0 +1,10 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "Tên biến tùy chọn",
"ColumnCustomVariableValue": "Giá trị của biến tùy chọn",
"CustomVariables": "Các biến tùy chọn",
"CustomVariablesReportDocumentation": "Báo cáo này chứa thông tin về các biến tùy chỉnh. Vui lòng chọn tên biến để xem phân bố của các giá trị. %1$s Để tìm hiểu thêm thông tin chung về các biến tùy chỉnh, đọc %2$s Tài liệu hướng dẫn về biến tùy chỉnh trên matomo.org %3$s",
"ScopePage": "Trang phạm vi",
"ScopeVisit": "sự viếng thăm trong phạm vi nào đó"
}
}

View File

@ -0,0 +1,22 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "自定义变量名称",
"ColumnCustomVariableValue": "自定义变量值",
"CustomVariables": "自定义变量",
"CustomVariablesReportDocumentation": "本报表包含您的自定义变量的资料,点击变量名查看数据。%1$s 关于自定义变量的详情,请阅读 %2$smatomo.org 上的自定义变量文档%3$s",
"ScopePage": "页面范围",
"ScopeVisit": "访问范围",
"ManageDescription": "这个概览显示了所有的自定义变量位置和它们在各个站点“%s”的使用方法。各个位置的变量名字按总的使用频率进行排序。",
"ScopeX": "范围 %s",
"Index": "主页",
"Usages": "用法",
"Unused": "未使用",
"CreateNewSlot": "增加可用自定义变量的数量",
"UsageDetails": "本站建立开始共计有%1$s访问记录和%2$s 笔互动记录。",
"CreatingCustomVariableTakesTime": "创建新的自定义变量根据你的数据库的大小可能需要很长的时间。因此,这是唯一可能经由其需要在命令行上执行的命令来做到这一点。",
"CurrentAvailableCustomVariables": "目前你可以在每个站点里使用高达 %s条自定义变量。",
"SlotsReportIsGeneratedOverTime": "本报告的数据将随着时间的推移被填充。这可能需要一两天看到任何数据,并在几个星期之前,该报告是完全准确的。",
"MetricsAreOnlyAvailableForVisitScope": "注意:自定义变量%1$s只能用于 %2$s范围。",
"MetricsNotAvailableForPageScope": "自定义变量%1$s的列值范围为%2$s"
}
}

View File

@ -0,0 +1,25 @@
{
"CustomVariables": {
"ColumnCustomVariableName": "自訂變數名稱",
"ColumnCustomVariableValue": "自訂變數值",
"CustomVariables": "自訂變數",
"CustomVariablesReportDocumentation": "這份報表包含你的自訂變數資訊。點擊變數名稱來查看分配的值。%1$s更多關於自訂變數的資訊請查看 %2$smatomo.org 上的自訂變數說明文件%3$s",
"PluginDescription": "自訂變數是透過 Javascript API 為訪客或他們的活動以 [名稱 => 值] 來配對。Matomo 接著會產生這些自訂名稱與值有多少訪問、頁面及轉換的報表。可以在訪客紀錄中查看每位使用者和活動的自定變數詳情。這個外掛必須要使用電子商務分析功能!",
"ScopePage": "網頁範圍",
"ScopeVisit": "訪客範圍",
"ScopeConversion": "範圍轉換",
"ManageDescription": "這個總覽顯示「%s」的所有自訂變數和它們的用途。每個欄位中的名稱將以總使用次數來排序。",
"ScopeX": "%s 範圍",
"Index": "索引",
"Usages": "用途",
"Unused": "未使用",
"CreateNewSlot": "增加自訂變數可用的欄位",
"UsageDetails": "自從此網站建立後已有 %1$s 次訪問數和 %2$s 個活動。",
"CreatingCustomVariableTakesTime": "建立新的自訂變數欄位可能會花上較久的時間,取決於你的資料庫大小。因此這只可能透過指令列執行指令來達成。",
"CurrentAvailableCustomVariables": "目前每個網站最多可以建立 %s 個自訂變數。",
"ToCreateCustomVarExecute": "要建立新的自訂變數欄位請在 Matomo 安裝路徑執行以下指令:",
"SlotsReportIsGeneratedOverTime": "這份報表的資料將會被補充。可能會花上一到兩天來產生資料,並且花上數周才會有完整準確的報表。",
"MetricsAreOnlyAvailableForVisitScope": "注意:%1$s只有自訂變數的範圍有數據%2$s。",
"MetricsNotAvailableForPageScope": "自訂變數範圍 %1$s 中,欄位數據的值為 %2$s。"
}
}

View File

@ -0,0 +1,10 @@
{% if action.customVariables is defined %}
{{ 'CustomVariables_CustomVariables'|translate }}:{% for id,customVariable in action.customVariables %}
{% set name = 'customVariablePageName' ~ id %}
{% set value = 'customVariablePageValue' ~ id %}
{# line break above is important #}
- {{ customVariable[name]|rawSafeDecoded }} {% if customVariable[value]|length > 0 %} = {{ customVariable[value]|rawSafeDecoded }}{% endif %}
{% endfor %}
{% endif -%}

View File

@ -0,0 +1,13 @@
<div class="visitor-profile-summary visitor-profile-customvariables">
<h1>{{ 'CustomVariables_CustomVariables'|translate }} ({{ scopeName }})</h1>
<div>
{%- for variable in variables -%}
<p>
<span>{{ variable.name }}: </span>
{%- for value in variable.values -%}
<strong title="{{ value.count }}x">{{ value.value }}</strong>{% if not loop.last %}, {% endif %}
{%- endfor -%}
</p>
{%- endfor -%}
</div>
</div>

View File

@ -0,0 +1,11 @@
<div class="visitorCustomVariables">
{% for id,customVariable in visitInfo.getColumn('customVariables') %}
{% set name='customVariableName' ~ id %}
{% set value='customVariableValue' ~ id %}
<br/>
<abbr class="visitorLogTooltip" title="{{ 'CustomVariables_CustomVariables'|translate }} ({{ 'CustomVariables_Index'|translate }} {{ id }})">
{{ customVariable[name]|truncate(30) }}
</abbr>
{% if customVariable[value]|length > 0 %}: {{ customVariable[value]|truncate(50) }}{% endif %}
{% endfor %}
</div>

View File

@ -0,0 +1,11 @@
{% extends 'admin.twig' %}
{% block topcontrols %}
<div class="top_bar_sites_selector piwikTopControl">
<div piwik-siteselector show-selected-site="true" class="sites_autocomplete"></div>
</div>
{% endblock %}
{% block content %}
<div piwik-manage-custom-vars>
{% endblock %}