protected function execute(InputInterface $input, OutputInterface $output)
 {
     foreach (CustomDimensions::getScopes() as $scope) {
         $tracking = new LogTable($scope);
         $output->writeln(sprintf('%s Custom Dimensions available in scope "%s"', $tracking->getNumInstalledIndexes(), $scope));
         if ($scope === CustomDimensions::SCOPE_CONVERSION) {
             $output->writeln(sprintf('Custom Dimensions are automatically added via the scope "%s" and cannot be added manually', CustomDimensions::SCOPE_VISIT));
         } else {
             $output->writeln(sprintf('To add a Custom Dimension execute "<comment>./console customdimensions:add-custom-dimension --scope=%s</comment>"', $scope));
         }
         $output->writeln('Installed indexes are:');
         foreach ($tracking->getInstalledIndexes() as $index) {
             $output->writeln(sprintf('%d to remove this Custom Dimension execute <comment>./console customdimensions:remove-custom-dimension --scope=%s --index=%d</comment>', $index, $scope, $index));
         }
         $output->writeln('');
     }
     $visit = new LogTable(CustomDimensions::SCOPE_VISIT);
     $numVisit = $visit->getNumInstalledIndexes();
     $conversion = new LogTable(CustomDimensions::SCOPE_CONVERSION);
     $numConversions = $conversion->getNumInstalledIndexes();
     if ($numConversions < $numVisit) {
         $output->writeln('');
         $output->writeln('<error>We found an error, Custom Dimensions in scope "conversion" are not correctly installed. Execute the following command to repair it:</error>');
         $output->writeln(sprintf('<comment>./console customdimensions:add-custom-dimension --scope=%s --count=%d</comment>', CustomDimensions::SCOPE_CONVERSION, $numVisit - $numConversions));
     }
 }
    public function testExecute_ShouldOutputErrorMessage_IfColumnsDoNotMatch()
    {
        $model = new LogTable(CustomDimensions::SCOPE_CONVERSION);
        $model->removeCustomDimension(5);
        $this->assertContains('We found an error, Custom Dimensions in scope "conversion" are not correctly installed. Execute the following command to repair it:
./console customdimensions:add-custom-dimension --scope=conversion --count=1', $this->executeCommand());
    }
 public function test_getCachedCustomDimensionIndexes()
 {
     $logTable = new LogTable(CustomDimensions::SCOPE_ACTION);
     $logTable->removeCustomDimension(1);
     $indexes = Processor::getCachedCustomDimensionIndexes(CustomDimensions::SCOPE_VISIT);
     $this->assertSame(range(1, 5), $indexes);
     $indexes = Processor::getCachedCustomDimensionIndexes(CustomDimensions::SCOPE_ACTION);
     $this->assertSame(range(2, 5), $indexes);
 }
 public function uninstall()
 {
     $this->configuration->uninstall();
     foreach (self::getScopes() as $scope) {
         $tracking = new Dao\LogTable($scope);
         $tracking->uninstall();
     }
     Cache::clearCacheGeneral();
     $this->isInstalled = false;
 }
 private function getCustomDimensionsInScope($scope, Request $request)
 {
     $dimensions = self::getCachedCustomDimensions($request);
     $params = $request->getParams();
     $values = array();
     foreach ($dimensions as $dimension) {
         if ($dimension['scope'] !== $scope) {
             continue;
         }
         $field = self::buildCustomDimensionTrackingApiName($dimension);
         $dbField = Dao\LogTable::buildCustomDimensionColumnName($dimension);
         $value = Common::getRequestVar($field, '', 'string', $params);
         if ($value !== '') {
             $values[$dbField] = $value;
             continue;
         }
         $extractions = $dimension['extractions'];
         if (is_array($extractions)) {
             foreach ($extractions as $extraction) {
                 if (!array_key_exists('dimension', $extraction) || !array_key_exists('pattern', $extraction) || empty($extraction['pattern'])) {
                     continue;
                 }
                 $extraction = new Extraction($extraction['dimension'], $extraction['pattern']);
                 $extraction->setCaseSensitive($dimension['case_sensitive']);
                 $value = $extraction->extract($request);
                 if (!isset($value) || '' === $value) {
                     continue;
                 }
                 $values[$dbField] = $value;
                 break;
             }
         }
     }
     return $values;
 }
 protected function configureSegments()
 {
     $idSite = Common::getRequestVar('idSite', 0, 'int');
     if (empty($idSite)) {
         return array();
     }
     $configuration = StaticContainer::get('Piwik\\Plugins\\CustomDimensions\\Dao\\Configuration');
     $dimensions = $configuration->getCustomDimensionsForSite($idSite);
     foreach ($dimensions as $dimension) {
         if (!$dimension['active']) {
             continue;
         }
         $segment = new Segment();
         $segment->setSegment(CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($dimension));
         $segment->setType(Segment::TYPE_DIMENSION);
         $segment->setName($dimension['name']);
         $columnName = LogTable::buildCustomDimensionColumnName($dimension);
         if ($dimension['scope'] === CustomDimensions::SCOPE_ACTION) {
             $segment->setSqlSegment('log_link_visit_action. ' . $columnName);
             $segment->setCategory('General_Actions');
             $segment->setSuggestedValuesCallback(function ($idSite, $maxValuesToReturn) use($dimension) {
                 $autoSuggest = new AutoSuggest();
                 return $autoSuggest->getMostUsedActionDimensionValues($dimension, $idSite, $maxValuesToReturn);
             });
         } elseif ($dimension['scope'] === CustomDimensions::SCOPE_VISIT) {
             $segment->setSqlSegment('log_visit. ' . $columnName);
             $segment->setCategory('General_Visit');
         } else {
             continue;
         }
         $this->addSegment($segment);
     }
 }
 private function getCustomDimensionColumnNames()
 {
     $tableMetadataAccess = new TableMetadata();
     $columns = $tableMetadataAccess->getColumns($this->table);
     $dimensionColumns = array_filter($columns, function ($column) {
         return LogTable::isCustomDimensionColumn($column);
     });
     return $dimensionColumns;
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $scope = $this->getScope($input);
     $tracking = new LogTable($scope);
     $installedIndexes = $tracking->getInstalledIndexes();
     $index = $this->getIndex($input, $installedIndexes);
     $output->writeln(sprintf('Remove Custom Dimension at index %d in scope %s.', $index, $scope));
     $configuration = new Configuration();
     $configs = $configuration->getCustomDimensionsHavingIndex($scope, $index);
     $names = array();
     foreach ($configs as $config) {
         $names[] = $config['name'];
     }
     if (empty($names)) {
         $output->writeln('This index is currently not used by any website');
     } else {
         $output->writeln(sprintf('This index is used by %d websites and used for the following Custom Dimensions: "%s"', count($names), implode('", "', $names)));
     }
     $output->writeln('');
     $output->writeln('<comment>This causes schema changes in the database and may take a very long time.</comment>');
     $output->writeln('<comment>Removing tracked Custom Dimension data cannot be undone unless you have a backup.</comment>');
     $noInteraction = $input->getOption('no-interaction');
     if (!$noInteraction && !$this->confirmChange($output)) {
         return;
     }
     $output->writeln('');
     $output->writeln('Starting to remove this Custom Dimension.');
     $output->writeln('');
     $tracking = new LogTable($scope);
     $tracking->removeCustomDimension($index);
     $configuration->deleteConfigurationsForIndex($index);
     if ($scope === CustomDimensions::SCOPE_VISIT) {
         $tracking = new LogTable(CustomDimensions::SCOPE_CONVERSION);
         $tracking->removeCustomDimension($index);
     }
     Cache::clearCacheGeneral();
     $numDimensionsAvailable = $tracking->getNumInstalledIndexes();
     $this->writeSuccessMessage($output, array(sprintf('Your Piwik is now configured for up to %d Custom Dimensions in scope %s.', $numDimensionsAvailable, $scope)));
 }
 protected function execute(InputInterface $input, OutputInterface $output)
 {
     $scope = $this->getScope($input);
     $count = $this->getCount($input);
     $output->writeln(sprintf('Adding %d Custom Dimension(s) in scope %s.', $count, $scope));
     $output->writeln('<info>This causes schema changes in the database and may take a very long time.</info>');
     $noInteraction = $input->getOption('no-interaction');
     if (!$noInteraction && !$this->confirmChange($output)) {
         return;
     }
     $output->writeln('');
     $output->writeln('Starting to add Custom Dimension(s)');
     $output->writeln('');
     $tracking = new LogTable($scope);
     $tracking->addManyCustomDimensions($count);
     if ($scope === CustomDimensions::SCOPE_VISIT) {
         $tracking = new LogTable(CustomDimensions::SCOPE_CONVERSION);
         $tracking->addManyCustomDimensions($count);
     }
     Cache::clearCacheGeneral();
     $numDimensionsAvailable = $tracking->getNumInstalledIndexes();
     $this->writeSuccessMessage($output, array(sprintf('Your Piwik is now configured for up to %d Custom Dimensions in scope %s.', $numDimensionsAvailable, $scope)));
 }
 /**
  * @param array $dimension
  * @param int $idSite
  * @param int $maxValuesToReturn
  * @return array
  */
 public function getMostUsedActionDimensionValues($dimension, $idSite, $maxValuesToReturn)
 {
     $maxValuesToReturn = (int) $maxValuesToReturn;
     $idSite = (int) $idSite;
     $startDate = Date::now()->subDay(60)->toString();
     $name = LogTable::buildCustomDimensionColumnName($dimension);
     $table = Common::prefixTable('log_link_visit_action');
     $query = "SELECT {$name}, count({$name}) as countName FROM {$table}\n                  WHERE idsite = ? and server_time > {$startDate} and {$name} is not null\n                  GROUP by {$name}\n                  ORDER BY countName DESC LIMIT {$maxValuesToReturn}";
     $rows = Db::get()->fetchAll($query, array($idSite));
     $values = array();
     foreach ($rows as $row) {
         $values[] = $row[$name];
     }
     return $values;
 }
 public function getCustomDimensionValues($configuredVisitDimensions)
 {
     $values = array();
     foreach ($configuredVisitDimensions as $dimension) {
         if ($dimension['active'] && $dimension['scope'] === CustomDimensions::SCOPE_VISIT) {
             // field in DB, eg custom_dimension_1
             $field = LogTable::buildCustomDimensionColumnName($dimension);
             // field for user, eg dimension1
             $column = CustomDimensionsRequestProcessor::buildCustomDimensionTrackingApiName($dimension);
             if (array_key_exists($field, $this->details)) {
                 $values[$column] = $this->details[$field];
             } else {
                 $values[$column] = null;
             }
         }
     }
     return $values;
 }
 public function aggregateDayReport()
 {
     $dimensions = $this->getActiveCustomDimensions();
     foreach ($dimensions as $dimension) {
         $this->dataArray = new DataArray();
         $valueField = LogTable::buildCustomDimensionColumnName($dimension);
         $dimensions = array($valueField);
         if ($dimension['scope'] === CustomDimensions::SCOPE_VISIT) {
             $this->aggregateFromVisits($valueField, $dimensions, " log_visit.{$valueField} is not null");
             $this->aggregateFromConversions($valueField, $dimensions, " log_conversion.{$valueField} is not null");
         } elseif ($dimension['scope'] === CustomDimensions::SCOPE_ACTION) {
             $this->aggregateFromActions($valueField);
         }
         $this->dataArray->enrichMetricsWithConversions();
         $table = $this->dataArray->asDataTable();
         $blob = $table->getSerialized($this->maximumRowsInDataTableLevelZero, $this->maximumRowsInSubDataTable, $columnToSort = Metrics::INDEX_NB_VISITS);
         $recordName = self::buildRecordNameForCustomDimensionId($dimension['idcustomdimension']);
         $this->getProcessor()->insertBlobRecord($recordName, $blob);
     }
 }
 public function setTrackerCacheGeneral(&$cacheContent)
 {
     foreach (self::getScopes() as $scope) {
         $tracking = new LogTable($scope);
         $cacheContent['custom_dimension_indexes_installed_' . $scope] = $tracking->getInstalledIndexes();
     }
 }
 public function testExecute_ShouldAddSpecifiedCount_IfScopeIsVisitShouldAlsoUpdateConversion()
 {
     $logVisit = new LogTable(CustomDimensions::SCOPE_VISIT);
     $this->assertSame(range(1, 5), $logVisit->getInstalledIndexes());
     $logConversion = new LogTable(CustomDimensions::SCOPE_CONVERSION);
     $this->assertSame(range(1, 5), $logConversion->getInstalledIndexes());
     $result = $this->executeCommand(CustomDimensions::SCOPE_VISIT, $index = 2);
     $this->assertContains('Remove Custom Dimension at index 2 in scope visit', $result);
     $this->assertContains('Are you sure you want to perform this action?', $result);
     $this->assertContains('Starting to remove this Custom Dimension', $result);
     $this->assertContains('Your Piwik is now configured for up to 4 Custom Dimensions in scope visit.', $result);
     $logVisit = new LogTable(CustomDimensions::SCOPE_VISIT);
     $this->assertSame(array(1, 3, 4, 5), $logVisit->getInstalledIndexes());
     $logConversion = new LogTable(CustomDimensions::SCOPE_CONVERSION);
     $this->assertSame(array(1, 3, 4, 5), $logConversion->getInstalledIndexes());
     $logAction = new LogTable(CustomDimensions::SCOPE_ACTION);
     $this->assertSame(array(1, 2, 4, 5), $logAction->getInstalledIndexes());
 }
 public function test_addConversionInformation_shouldIgnoreAnIndexIfTheIndexIsMissingInConversionTable()
 {
     $this->configureSomeDimensions();
     $logTable = new LogTable(CustomDimensions::SCOPE_CONVERSION);
     $logTable->removeCustomDimension(1);
     $conversion = array();
     $request = new Request(array('idsite' => 1));
     $visit = array('custom_dimension_1' => 'value 1', 'custom_dimension_4' => 'value 4');
     $this->plugin->addConversionInformation($conversion, $visit, $request);
     $this->assertSame(array('custom_dimension_4' => 'value 4'), $conversion);
 }
 /**
  * @dataProvider getDimensionColumnTestNames
  */
 public function test_isCustomDimensionColumn($expected, $name)
 {
     $this->assertSame($expected, LogTable::isCustomDimensionColumn($name));
 }