| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\Plugins\API; |
|
|
| use Exception; |
| use Piwik\API\Request; |
| use Piwik\Archive\DataTableFactory; |
| use Piwik\CacheId; |
| use Piwik\Cache as PiwikCache; |
| use Piwik\Category\CategoryList; |
| use Piwik\Common; |
| use Piwik\Container\StaticContainer; |
| use Piwik\DataTable; |
| use Piwik\DataTable\DataTableInterface; |
| use Piwik\DataTable\Filter\AddColumnsProcessedMetricsGoal; |
| use Piwik\DataTable\Row; |
| use Piwik\DataTable\Simple; |
| use Piwik\Date; |
| use Piwik\Metrics; |
| use Piwik\Metrics\Formatter; |
| use Piwik\Period; |
| use Piwik\Piwik; |
| use Piwik\Plugin\ReportsProvider; |
| use Piwik\Site; |
| use Piwik\Timer; |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| class ProcessedReport |
| { |
| |
| |
| |
| private $reportsProvider; |
|
|
| private const PERFORMANCE_METRICS_TO_FORMAT = [ |
| 'avg_time_network', |
| 'avg_time_server', |
| 'avg_time_transfer', |
| 'avg_time_dom_processing', |
| 'avg_time_dom_completion', |
| 'avg_time_on_load', |
| 'avg_page_load_time', |
| ]; |
|
|
| public function __construct(ReportsProvider $reportsProvider) |
| { |
| $this->reportsProvider = $reportsProvider; |
| } |
|
|
| |
| |
| |
| |
| public function getMetadata( |
| $idSite, |
| $apiModule, |
| $apiAction, |
| $apiParameters = array(), |
| $language = false, |
| $period = false, |
| $date = false, |
| $hideMetricsDoc = false, |
| $showSubtableReports = false |
| ) { |
| $reportsMetadata = $this->getReportMetadata($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports); |
|
|
| |
| $entityNames = StaticContainer::get('entities.idNames'); |
| foreach ($entityNames as $entityName) { |
| if ($entityName === 'idGoal' || $entityName === 'idDimension') { |
| continue; |
| |
| } |
| $idEntity = \Piwik\Request::fromRequest()->getIntegerParameter($entityName, 0); |
| if ($idEntity > 0) { |
| $apiParameters[$entityName] = $idEntity; |
| } |
| } |
|
|
| foreach ($reportsMetadata as $report) { |
| |
| |
| if (($period && $period != 'day') && !($apiModule == 'VisitsSummary' && $apiAction == 'get')) { |
| unset($report['metrics']['nb_uniq_visitors']); |
| unset($report['metrics']['nb_users']); |
| } |
| if ( |
| $report['module'] == $apiModule |
| && $report['action'] == $apiAction |
| ) { |
| |
| if ( |
| empty($apiParameters) |
| && empty($report['parameters']) |
| ) { |
| return array($report); |
| } |
| if (empty($report['parameters'])) { |
| continue; |
| } |
| $diff = array_diff($report['parameters'], $apiParameters); |
| if (empty($diff)) { |
| return array($report); |
| } |
| } |
| } |
|
|
| return false; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function isValidReportForSite($idSite, $apiMethodUniqueId) |
| { |
| $report = $this->getReportMetadataByUniqueId($idSite, $apiMethodUniqueId); |
|
|
| return !empty($report); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function isValidMetricForReport($metric, $idSite, $apiMethodUniqueId) |
| { |
| $translation = $this->translateMetric($metric, $idSite, $apiMethodUniqueId); |
|
|
| return !empty($translation); |
| } |
|
|
| public function getReportMetadataByUniqueId($idSite, $apiMethodUniqueId) |
| { |
| $metadata = $this->getReportMetadata($idSite); |
|
|
| foreach ($metadata as $report) { |
| if ($report['uniqueId'] == $apiMethodUniqueId) { |
| return $report; |
| } |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function translateMetric($metric, $idSite, $apiMethodUniqueId) |
| { |
| $report = $this->getReportMetadataByUniqueId($idSite, $apiMethodUniqueId); |
|
|
| if (empty($report)) { |
| return null; |
| } |
|
|
| $properties = array('metrics', 'processedMetrics', 'processedMetricsGoal'); |
|
|
| foreach ($properties as $prop) { |
| if (!empty($report[$prop]) && is_array($report[$prop]) && array_key_exists($metric, $report[$prop])) { |
| return $report[$prop][$metric]; |
| } |
| } |
|
|
| return null; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getReportMetadata($idSite, $period = false, $date = false, $hideMetricsDoc = false, $showSubtableReports = false) |
| { |
| Piwik::checkUserHasViewAccess($idSite); |
|
|
| |
| |
| $key = $this->buildReportMetadataCacheKey($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports); |
| $key = CacheId::pluginAware($key); |
| $cache = PiwikCache::getTransientCache(); |
|
|
| if ($cache->contains($key)) { |
| return $cache->fetch($key); |
| } |
|
|
| $parameters = array('idSite' => $idSite, 'period' => $period, 'date' => $date); |
|
|
| $availableReports = array(); |
|
|
| foreach ($this->reportsProvider->getAllReports() as $report) { |
| $report->configureReportMetadata($availableReports, $parameters); |
| } |
|
|
| foreach ($availableReports as &$availableReport) { |
| if ($hideMetricsDoc) { |
| unset($availableReport['metricsDocumentation']); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Piwik::postEvent('API.getReportMetadata.end', array(&$availableReports, $parameters)); |
|
|
| |
| usort($availableReports, array($this, 'sortReports')); |
|
|
| $knownMetrics = array_merge(Metrics::getDefaultMetrics(), Metrics::getDefaultProcessedMetrics()); |
| $columnsToKeep = $this->getColumnsToKeep(); |
| $columnsToRemove = $this->getColumnsToRemove(); |
|
|
| $categoryList = CategoryList::get(); |
| foreach ($availableReports as &$availableReport) { |
| $categoryId = $availableReport['category']; |
| $categoryObj = $categoryList->getCategory($categoryId); |
| if ($categoryObj) { |
| $availableReport['category'] = $categoryObj->getDisplayName(); |
| } else { |
| $availableReport['category'] = Piwik::translate($categoryId); |
| } |
|
|
| $availableReport['subcategory'] = Piwik::translate($availableReport['subcategory']); |
|
|
| |
| $metrics = $availableReport['metrics']; |
| $cleanedMetrics = array(); |
| |
| foreach ($metrics as $metricId => $metricTranslation) { |
| |
| |
| if ( |
| is_numeric($metricId) |
| && isset($knownMetrics[$metricTranslation]) |
| ) { |
| $metricId = $metricTranslation; |
| $metricTranslation = $knownMetrics[$metricTranslation]; |
| } |
| $cleanedMetrics[$metricId] = $metricTranslation; |
| } |
| $availableReport['metrics'] = $cleanedMetrics; |
|
|
| |
| $availableReport['metrics'] = $this->hideShowMetricsWithParams($availableReport['metrics'], $columnsToRemove, $columnsToKeep); |
| if (isset($availableReport['processedMetrics'])) { |
| $availableReport['processedMetrics'] = $this->hideShowMetricsWithParams($availableReport['processedMetrics'], $columnsToRemove, $columnsToKeep); |
| } |
| if (isset($availableReport['metricsDocumentation'])) { |
| $availableReport['metricsDocumentation'] = |
| $this->hideShowMetricsWithParams($availableReport['metricsDocumentation'], $columnsToRemove, $columnsToKeep); |
| } |
| if (isset($availableReport['metricTypes'])) { |
| $availableReport['metricTypes'] = $this->hideShowMetricsWithParams($availableReport['metricTypes'], $columnsToRemove, $columnsToKeep); |
| } |
|
|
| |
| foreach ($availableReport as $attributeName => $attributeValue) { |
| if (empty($attributeValue)) { |
| unset($availableReport[$attributeName]); |
| } |
| } |
| |
| |
| |
| |
| $requestingGoalMetrics = \Piwik\Request::fromRequest()->getBoolParameter('filter_update_columns_when_show_all_goals', false); |
| if ( |
| isset($availableReport['metricsGoal']) |
| && !$requestingGoalMetrics |
| ) { |
| unset($availableReport['processedMetrics']['conversion_rate']); |
| unset($availableReport['metricsGoal']['conversion_rate']); |
| } |
|
|
| |
| |
| $uniqueId = $availableReport['module'] . '_' . $availableReport['action']; |
| if (!empty($availableReport['parameters'])) { |
| foreach ($availableReport['parameters'] as $key => $value) { |
| $value = urlencode($value); |
| $value = str_replace('%', '', $value); |
| $uniqueId .= '_' . $key . '--' . $value; |
| } |
| } |
| $availableReport['uniqueId'] = $uniqueId; |
|
|
| |
| unset($availableReport['order']); |
| } |
|
|
| |
| if (!$showSubtableReports) { |
| foreach ($availableReports as $idx => $report) { |
| if (isset($report['isSubtableReport']) && $report['isSubtableReport']) { |
| unset($availableReports[$idx]); |
| } |
| } |
| } |
|
|
| $actualReports = array_values($availableReports); |
| $cache->save($key, $actualReports); |
|
|
| return $actualReports; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public function sortReports($a, $b) |
| { |
| return $this->reportsProvider->compareCategories($a['category'], $a['subcategory'], $a['order'], $b['category'], $b['subcategory'], $b['order']); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| public function getProcessedReport( |
| $idSite, |
| $period, |
| $date, |
| $apiModule, |
| $apiAction, |
| $segment = false, |
| $apiParameters = false, |
| $idGoal = false, |
| $language = false, |
| $showTimer = true, |
| $hideMetricsDoc = false, |
| $idSubtable = false, |
| $showRawMetrics = false, |
| $formatMetrics = null, |
| $idDimension = false |
| ) { |
| $timer = new Timer(); |
| if (empty($apiParameters)) { |
| $apiParameters = array(); |
| } |
|
|
| if ( |
| !empty($idGoal) |
| && empty($apiParameters['idGoal']) |
| ) { |
| $apiParameters['idGoal'] = $idGoal; |
| } |
|
|
| if ( |
| !empty($idDimension) |
| && empty($apiParameters['idDimension']) |
| ) { |
| $apiParameters['idDimension'] = (int) $idDimension; |
| } |
|
|
| |
| $reportMetadata = $this->getMetadata( |
| $idSite, |
| $apiModule, |
| $apiAction, |
| $apiParameters, |
| $language, |
| $period, |
| $date, |
| $hideMetricsDoc, |
| $showSubtableReports = true |
| ); |
| if (empty($reportMetadata)) { |
| throw new Exception("Requested report $apiModule.$apiAction for Website id=$idSite not found in the list of available reports. \n"); |
| } |
|
|
| $reportMetadata = reset($reportMetadata); |
|
|
| |
| $parameters = array_merge($apiParameters, array( |
| 'method' => $apiModule . '.' . $apiAction, |
| 'idSite' => $idSite, |
| 'period' => $period, |
| 'date' => $date, |
| 'format' => 'original', |
| 'serialize' => '0', |
| 'language' => $language, |
| 'idSubtable' => $idSubtable, |
| )); |
|
|
| if (!empty($segment)) { |
| $parameters['segment'] = $segment; |
| } |
|
|
| $actionsIdGoalOverride = $this->getIdGoalToUseForActionsReports($idGoal, $apiModule . '.' . $apiAction); |
| if ($actionsIdGoalOverride) { |
| $parameters['idGoal'] = $actionsIdGoalOverride; |
| } |
|
|
| if ( |
| !empty($reportMetadata['processedMetrics']) |
| && !empty($reportMetadata['metrics']['nb_visits']) |
| && @$reportMetadata['category'] != Piwik::translate('Goals_Ecommerce') |
| && $apiModule !== 'MultiSites' |
| ) { |
| $deleteRowsWithNoVisits = empty($reportMetadata['constantRowsCount']) ? '1' : '0'; |
| $parameters['filter_add_columns_when_show_all_columns'] = $deleteRowsWithNoVisits; |
| } |
|
|
| $parameters = array_filter($parameters, function ($value) { |
| return $value !== null && $value !== false; |
| }); |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Piwik::postEvent('API.getProcessedReport.inner.before', [&$parameters]); |
|
|
| $request = new Request($parameters); |
| try { |
| |
| $dataTable = $request->process(); |
| } catch (Exception $e) { |
| throw new Exception("API returned an error: " . $e->getMessage() . " at " . basename($e->getFile()) . ":" . $e->getLine() . "\n"); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| Piwik::postEvent('API.getProcessedReport.inner.after', [$parameters, $dataTable]); |
|
|
| [$newReport, $columns, $rowsMetadata, $totals] = $this->handleTableReport($idSite, $dataTable, $reportMetadata, $showRawMetrics, $formatMetrics); |
|
|
| if (function_exists('mb_substr')) { |
| foreach ($columns as &$name) { |
| if (substr($name, 0, 1) === mb_substr($name, 0, 1)) { |
| $name = ucfirst($name); |
| } |
| } |
| } |
|
|
| $website = new Site($idSite); |
|
|
| $period = Period\Factory::build($period, $date); |
| $period = $period->getLocalizedLongString(); |
|
|
| $return = array( |
| 'website' => $website->getName(), |
| 'prettyDate' => $period, |
| 'metadata' => $reportMetadata, |
| 'columns' => $columns, |
| 'reportData' => $newReport, |
| 'reportMetadata' => $rowsMetadata, |
| 'reportTotal' => $totals, |
| ); |
| if ($showTimer) { |
| $return['timerMillis'] = $timer->getTimeMs(0); |
| } |
| return $return; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| private function handleTableReport($idSite, $dataTable, &$reportMetadata, $showRawMetrics = false, $formatMetrics = null): array |
| { |
| $hasDimension = isset($reportMetadata['dimension']); |
| $columns = @$reportMetadata['metrics'] ?: array(); |
|
|
| if ($hasDimension) { |
| $columns = array_merge( |
| array('label' => $reportMetadata['dimension']), |
| $columns |
| ); |
| } |
|
|
| if (isset($reportMetadata['processedMetrics']) && is_array($reportMetadata['processedMetrics'])) { |
| $processedMetricsAdded = Metrics::getDefaultProcessedMetrics(); |
| foreach ($reportMetadata['processedMetrics'] as $processedMetricId => $processedMetricTranslation) { |
| |
|
|
| if ($processedMetricTranslation && $processedMetricId !== $processedMetricTranslation) { |
| $columns[$processedMetricId] = $processedMetricTranslation; |
| } elseif (isset($processedMetricsAdded[$processedMetricId])) { |
| |
| $columns[$processedMetricId] = $processedMetricsAdded[$processedMetricId]; |
| } |
| } |
| } |
|
|
| |
| if (isset($reportMetadata['metricsGoal'])) { |
| $metricsGoalDisplay = array('revenue'); |
| |
| foreach ($metricsGoalDisplay as $goalMetricId) { |
| if (isset($reportMetadata['metricsGoal'][$goalMetricId])) { |
| $columns[$goalMetricId] = $reportMetadata['metricsGoal'][$goalMetricId]; |
| } |
| } |
| } |
|
|
| $columns = $this->hideShowMetrics($columns); |
| $totals = []; |
|
|
| |
| if ($dataTable instanceof DataTable\Map) { |
| |
| $newReport = new DataTable\Map(); |
| $newReport->setKeyName("prettyDate"); |
|
|
| |
| $rowsMetadata = new DataTable\Map(); |
| $rowsMetadata->setKeyName("prettyDate"); |
|
|
| |
| foreach ($dataTable->getDataTables() as $simpleDataTable) { |
| $this->removeEmptyColumns($columns, $reportMetadata, $simpleDataTable); |
|
|
| [$enhancedSimpleDataTable, $rowMetadata] = $this->handleSimpleDataTable($idSite, $simpleDataTable, $columns, $hasDimension, $showRawMetrics, $formatMetrics); |
| $enhancedSimpleDataTable->setAllTableMetadata($simpleDataTable->getAllTableMetadata()); |
|
|
| $period = $simpleDataTable->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX)->getLocalizedLongString(); |
| $newReport->addTable($enhancedSimpleDataTable, $period); |
| $rowsMetadata->addTable($rowMetadata, $period); |
|
|
| $totals = $this->aggregateReportTotalValues($simpleDataTable, $totals); |
| } |
| } else { |
| $this->removeEmptyColumns($columns, $reportMetadata, $dataTable); |
| [$newReport, $rowsMetadata] = $this->handleSimpleDataTable($idSite, $dataTable, $columns, $hasDimension, $showRawMetrics, $formatMetrics); |
| $newReport->setAllTableMetadata($dataTable->getAllTableMetadata()); |
|
|
| $totals = $this->aggregateReportTotalValues($dataTable, $totals); |
| } |
|
|
| return [ |
| $newReport, |
| $columns, |
| $rowsMetadata, |
| $totals, |
| ]; |
| } |
|
|
| |
| |
| |
| |
| private function removeEmptyColumns(&$columns, &$reportMetadata, $dataTable) |
| { |
| $emptyColumns = $dataTable->getMetadata(DataTable::EMPTY_COLUMNS_METADATA_NAME); |
|
|
| if (!is_array($emptyColumns)) { |
| return; |
| } |
|
|
| $columnsToRemove = $this->getColumnsToRemove(); |
| $columnsToKeep = $this->getColumnsToKeep(); |
|
|
| $columns = $this->hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns); |
|
|
| if (isset($reportMetadata['metrics'])) { |
| $reportMetadata['metrics'] = $this->hideShowMetricsWithParams($reportMetadata['metrics'], $columnsToRemove, $columnsToKeep, $emptyColumns); |
| } |
|
|
| if (isset($reportMetadata['metricsDocumentation'])) { |
| $reportMetadata['metricsDocumentation'] = $this->hideShowMetricsWithParams($reportMetadata['metricsDocumentation'], $columnsToRemove, $columnsToKeep, $emptyColumns); |
| } |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| private function hideShowMetrics($columns, $emptyColumns = array()) |
| { |
| if (!is_array($columns)) { |
| return $columns; |
| } |
|
|
| |
| $columnsToRemove = $this->getColumnsToRemove(); |
|
|
| |
| $columnsToKeep = $this->getColumnsToKeep(); |
|
|
| return $this->hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns); |
| } |
|
|
| private function hideShowMetricsWithParams($columns, $columnsToRemove, $columnsToKeep, $emptyColumns = array()) |
| { |
| if (!is_array($columns)) { |
| return $columns; |
| } |
|
|
| if (null !== $columnsToRemove) { |
| foreach ($columnsToRemove as $name) { |
| |
| if (isset($columns[$name])) { |
| unset($columns[$name]); |
| } |
| } |
| } |
|
|
| if (null !== $columnsToKeep) { |
| foreach ($columns as $name => $ignore) { |
| |
| $idx = array_search($name, $columnsToKeep); |
| if ($idx === false) { |
| unset($columns[$name]); |
| } |
| } |
| } |
|
|
| |
| if (is_array($emptyColumns)) { |
| foreach ($emptyColumns as $column) { |
| if (isset($columns[$column])) { |
| unset($columns[$column]); |
| } |
| } |
| } |
|
|
| return $columns; |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| private function handleSimpleDataTable($idSite, $simpleDataTable, $metadataColumns, $hasDimension, $returnRawMetrics = false, $formatMetrics = null, $keepMetadata = false) |
| { |
| $comparisonColumns = $this->getComparisonColumns($metadataColumns); |
|
|
| |
| $rowsMetadata = new DataTable(); |
|
|
| |
| if ($hasDimension) { |
| $enhancedDataTable = new DataTable(); |
| } else { |
| $enhancedDataTable = new Simple(); |
| } |
|
|
| $formatter = new Formatter(); |
|
|
| $hasNonEmptyRowData = false; |
|
|
| foreach ($simpleDataTable->getRows() as $row) { |
| $rowMetrics = $row->getColumns(); |
|
|
| |
| foreach ($metadataColumns as $id => $name) { |
| if (!isset($rowMetrics[$id])) { |
| $row->setColumn($id, 0); |
| $rowMetrics[$id] = 0; |
| } |
| } |
|
|
| $c = []; |
| if ($keepMetadata) { |
| $c[Row::METADATA] = $row->getMetadata(); |
| } |
| $enhancedRow = new Row($c); |
| $enhancedDataTable->addRow($enhancedRow); |
|
|
| foreach ($rowMetrics as $columnName => $columnValue) { |
| |
| if ( |
| isset($metadataColumns[$columnName]) |
| || preg_match('/^goal_[0-9]+_/', $columnName) |
| ) { |
| |
|
|
| |
| |
| $idSiteForRow = $idSite; |
| $idSiteMetadata = $row->getMetadata('idsite'); |
| if ($idSiteMetadata && is_numeric($idSiteMetadata)) { |
| $idSiteForRow = (int) $idSiteMetadata; |
| } |
|
|
| |
| |
| if ( |
| $formatMetrics === null |
| || $formatMetrics == 'bc' |
| ) { |
| $prettyValue = self::getPrettyValue($formatter, $idSiteForRow, $columnName, $columnValue); |
| } else { |
| $prettyValue = $columnValue; |
| } |
| $enhancedRow->addColumn($columnName, $prettyValue); |
| } elseif ($returnRawMetrics) { |
| |
| if (!isset($columnValue)) { |
| $columnValue = 0; |
| } |
| $enhancedRow->addColumn($columnName, $columnValue); |
| } |
| } |
|
|
| $comparisons = $row->getComparisons(); |
|
|
| if ( |
| !empty($comparisons) |
| && $comparisons->getRowsCount() > 0 |
| ) { |
| [$newComparisons, $ignore] = $this->handleSimpleDataTable($idSite, $comparisons, $comparisonColumns, true, $returnRawMetrics, $formatMetrics, $keepMetadata = true); |
| $enhancedRow->setComparisons($newComparisons); |
| } |
|
|
| |
| if ($hasDimension) { |
| $rowMetadata = $row->getMetadata(); |
| $idSubDataTable = $row->getIdSubDataTable(); |
|
|
| unset($rowMetadata[Row::COMPARISONS_METADATA_NAME]); |
|
|
| |
| $metadataRow = new Row(); |
| $rowsMetadata->addRow($metadataRow); |
|
|
| if (count($rowMetadata) > 0 || !is_null($idSubDataTable)) { |
| $hasNonEmptyRowData = true; |
|
|
| foreach ($rowMetadata as $metadataKey => $metadataValue) { |
| $metadataRow->addColumn($metadataKey, $metadataValue); |
| } |
|
|
| if (!is_null($idSubDataTable)) { |
| $metadataRow->addColumn('idsubdatatable', $idSubDataTable); |
| } |
| } |
| } |
| } |
|
|
| |
| if ($hasNonEmptyRowData === false) { |
| $rowsMetadata = new DataTable(); |
| } |
|
|
| return array( |
| $enhancedDataTable, |
| $rowsMetadata, |
| ); |
| } |
|
|
| private function aggregateReportTotalValues($simpleDataTable, $totals) |
| { |
| $metadataTotals = $simpleDataTable->getMetadata('totals'); |
|
|
| if (empty($metadataTotals)) { |
| return $totals; |
| } |
|
|
| $simpleTotals = $this->hideShowMetrics($metadataTotals); |
|
|
| return $this->calculateTotals($simpleTotals, $totals); |
| } |
|
|
| private function calculateTotals($simpleTotals, $totals) |
| { |
| foreach ($simpleTotals as $metric => $value) { |
| if (0 === strpos($metric, 'avg_') || '_rate' === substr($metric, -5) || '_evolution' === substr($metric, -10)) { |
| continue; |
| } |
|
|
| if (!is_numeric($value) && !is_array($value)) { |
| continue; |
| } |
|
|
| if (is_array($value)) { |
| $currentValue = array_key_exists($metric, $totals) ? $totals[$metric] : []; |
| $newValue = $this->calculateTotals($value, $currentValue); |
| if (!empty($newValue)) { |
| $totals[$metric] = $newValue; |
| } |
| } |
|
|
| if (!array_key_exists($metric, $totals)) { |
| $totals[$metric] = $value; |
| } elseif (0 === strpos($metric, 'min_')) { |
| $totals[$metric] = min($totals[$metric], $value); |
| } elseif (0 === strpos($metric, 'max_')) { |
| $totals[$metric] = max($totals[$metric], $value); |
| } elseif ($value) { |
| $totals[$metric] += $value; |
| } |
| } |
|
|
| return $totals; |
| } |
|
|
| private function getColumnsToRemove() |
| { |
| $columnsToRemove = Common::getRequestVar('hideColumns', ''); |
|
|
| if ($columnsToRemove != '') { |
| return explode(',', $columnsToRemove); |
| } |
|
|
| return null; |
| } |
|
|
| private function getColumnsToKeep() |
| { |
| $columnsToKeep = Common::getRequestVar('showColumns', ''); |
|
|
| if ($columnsToKeep != '') { |
| $columnsToKeep = explode(',', $columnsToKeep); |
| $columnsToKeep[] = 'label'; |
|
|
| return $columnsToKeep; |
| } |
|
|
| return null; |
| } |
|
|
| private function buildReportMetadataCacheKey($idSite, $period, $date, $hideMetricsDoc, $showSubtableReports) |
| { |
| $request = $_GET + $_POST; |
|
|
| $key = ''; |
| foreach ($request as $k => $v) { |
| if (is_array($v)) { |
| $key .= $k . $this->getImplodedArray($v) . ','; |
| } else { |
| $key .= $k . $v . ','; |
| } |
| } |
|
|
| $key .= $idSite . 'x' . ($period === false ? 0 : $period) . 'x' . ($date === false ? 0 : $date); |
| $key .= (int)$hideMetricsDoc . (int)$showSubtableReports . Piwik::getCurrentUserLogin(); |
| return 'reportMetadata' . md5($key); |
| } |
|
|
| |
| |
| |
| |
| private function getImplodedArray($v) |
| { |
| return implode(', ', array_map(function ($entry) { |
| if (is_array($entry)) { |
| return implode(":", $entry); |
| } |
| return $entry; |
| }, $v)); |
| } |
|
|
| |
| |
| |
| |
| |
| |
| |
| |
| public static function getPrettyValue(Formatter $formatter, $idSite, string $columnName, $value) |
| { |
| if (!is_numeric($value)) { |
| return $value; |
| } |
|
|
| if (strpos($columnName, '_change') !== false) { |
| return $value == '0' ? '+0%' : $value; |
| } |
|
|
| |
| if (in_array($columnName, self::PERFORMANCE_METRICS_TO_FORMAT) || strpos($columnName, 'time_generation') !== false) { |
| return $formatter->getPrettyTimeFromSeconds($value, true); |
| } |
| if (strpos($columnName, 'time') !== false) { |
| return $formatter->getPrettyTimeFromSeconds($value); |
| } |
|
|
| |
| $isMoneyMetric = strpos($columnName, 'revenue') !== false || strpos($columnName, 'price') !== false; |
| if ($isMoneyMetric && strpos($columnName, 'evolution') === false) { |
| return $formatter->getPrettyMoney($value, $idSite); |
| } |
|
|
| |
| if (strpos($columnName, '_rate') !== false) { |
| if (strpos($value, "%") === false) { |
| return (100 * $value) . "%"; |
| } |
| } |
|
|
| return $value; |
| } |
|
|
| private function getComparisonColumns(array $metadataColumns): array |
| { |
| $result = $metadataColumns; |
| foreach ($metadataColumns as $columnName => $columnTranslation) { |
| $result[$columnName . '_change'] = Piwik::translate('General_ChangeInX', lcfirst($columnName)); |
| } |
| return $result; |
| } |
|
|
| private function getIdGoalToUseForActionsReports($idGoal, string $requestMethod) |
| { |
| if (\Piwik\Request::fromRequest()->getStringParameter('filter_show_goal_columns_process_goals', '')) { |
| return AddColumnsProcessedMetricsGoal::getProcessOnlyIdGoalToUseForReport($idGoal, $requestMethod); |
| } |
| return $idGoal; |
| } |
| } |
|
|