Download plugins/CoreVisualizations/Visualizations/HtmlTable.php from Leon4gr45/matomo: direct link, hf CLI and curl.
- Browser
- Download file 12 kB
-
https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreVisualizations/Visualizations/HtmlTable.php
- Command line
-
hf download hf://spaces/Leon4gr45/matomo/plugins/CoreVisualizations/Visualizations/HtmlTable.php
-
curl -L -o HtmlTable.php https://huggingface.co/spaces/Leon4gr45/matomo/resolve/main/plugins/CoreVisualizations/Visualizations/HtmlTable.php
12 kB
| /** | |
| * Matomo - free/libre analytics platform | |
| * | |
| * @link https://matomo.org | |
| * @license https://www.gnu.org/licenses/gpl-3.0.html GPL v3 or later | |
| */ | |
| namespace Piwik\Plugins\CoreVisualizations\Visualizations; | |
| use Piwik\API\Request as ApiRequest; | |
| use Piwik\Columns\Dimension; | |
| use Piwik\Common; | |
| use Piwik\DataTable\Row; | |
| use Piwik\Metrics; | |
| use Piwik\DataTable; | |
| use Piwik\NumberFormatter; | |
| use Piwik\Period; | |
| use Piwik\Piwik; | |
| use Piwik\Plugin\Visualization; | |
| /** | |
| * DataTable visualization that shows DataTable data in an HTML table. | |
| * | |
| * @property HtmlTable\Config $config | |
| */ | |
| class HtmlTable extends Visualization | |
| { | |
| public const ID = 'table'; | |
| public const TEMPLATE_FILE = "@CoreVisualizations/_dataTableViz_htmlTable.twig"; | |
| public const FOOTER_ICON = 'icon-table'; | |
| public const FOOTER_ICON_TITLE = 'General_DisplaySimpleTable'; | |
| protected $siteSummary; | |
| public static function getDefaultConfig() | |
| { | |
| return new HtmlTable\Config(); | |
| } | |
| public static function getDefaultRequestConfig() | |
| { | |
| return new HtmlTable\RequestConfig(); | |
| } | |
| public function beforeLoadDataTable() | |
| { | |
| $this->checkRequestIsNotForMultiplePeriods(); | |
| if ($this->isComparing()) { | |
| $request = $this->getRequestArray(); | |
| if ( | |
| !empty($request['comparePeriods']) | |
| && count($request['comparePeriods']) == 1 | |
| ) { | |
| $this->requestConfig->request_parameters_to_modify['invert_compare_change_compute'] = 1; | |
| } | |
| // forward the comparisonIdSubtables var if present so it will be used when next/prev links are clicked | |
| $comparisonIdSubtables = Common::getRequestVar('comparisonIdSubtables', false, 'string'); | |
| if (!empty($comparisonIdSubtables)) { | |
| $comparisonIdSubtables = Common::unsanitizeInputValue($comparisonIdSubtables); | |
| $this->config->custom_parameters['comparisonIdSubtables'] = $comparisonIdSubtables; | |
| } | |
| } | |
| } | |
| public function beforeRender() | |
| { | |
| if ( | |
| $this->requestConfig->idSubtable | |
| && $this->config->show_embedded_subtable | |
| ) { | |
| $this->config->show_visualization_only = true; | |
| } | |
| if ($this->requestConfig->idSubtable) { | |
| $this->config->show_totals_row = false; | |
| } | |
| foreach (Metrics::getMetricIdsToProcessReportTotal() as $metricId) { | |
| $this->config->report_ratio_columns[] = Metrics::getReadableColumnName($metricId); | |
| } | |
| if (!empty($this->report)) { | |
| foreach ($this->report->getMetricNamesToProcessReportTotals() as $metricName) { | |
| $this->config->report_ratio_columns[] = $metricName; | |
| } | |
| } | |
| if ($this->dataTable->getRowsCount()) { | |
| $siteTotalRow = $this->getSiteSummary() ? $this->getSiteSummary()->getFirstRow() : null; | |
| $this->assignTemplateVar('siteTotalRow', $siteTotalRow); | |
| } | |
| if ($this->isPivoted()) { | |
| $this->config->columns_to_display = $this->dataTable->getColumns(); | |
| } | |
| if ( | |
| $this->isComparing() | |
| && !empty($this->dataTable) | |
| ) { | |
| $this->assignTemplateVar('comparisonTotals', $this->dataTable->getMetadata('comparisonTotals')); | |
| } | |
| // Note: This needs to be done right before rendering, as otherwise some plugins might change the columns to display again | |
| if ($this->isFlattened()) { | |
| $dimensions = $this->dataTable->getMetadata('dimensions'); | |
| $hasMultipleDimensions = is_array($dimensions) && count($dimensions) > 1; | |
| $this->assignTemplateVar('hasMultipleDimensions', $hasMultipleDimensions); | |
| if ($hasMultipleDimensions) { | |
| if ($this->shouldShowDimensions()) { | |
| // ensure first metric translation is used as label if other dimensions are in separate columns | |
| $this->config->addTranslation('label', $this->config->translations[reset($dimensions)]); | |
| } else { | |
| // concatenate dimensions if table is shown flattened | |
| foreach ($dimensions as $dimension) { | |
| $labels[] = $this->config->translations[$dimension]; | |
| } | |
| $this->config->addTranslation('label', implode(' - ', $labels)); | |
| } | |
| } | |
| if ($this->shouldShowDimensions() && $hasMultipleDimensions) { | |
| $properties = $this->config; | |
| array_shift($dimensions); // shift away first dimension, as that will be shown as label | |
| $this->dataTable->filter(function (DataTable $dataTable) use ($properties, $dimensions) { | |
| if (empty($properties->columns_to_display)) { | |
| $columns = $dataTable->getColumns(); | |
| $hasNbVisits = in_array('nb_visits', $columns); | |
| $hasNbUniqVisitors = in_array('nb_uniq_visitors', $columns); | |
| $properties->setDefaultColumnsToDisplay($columns, $hasNbVisits, $hasNbUniqVisitors); | |
| } | |
| $label = array_search('label', $properties->columns_to_display); | |
| if ($label !== false) { | |
| unset($properties->columns_to_display[$label]); | |
| } | |
| foreach (array_reverse($dimensions) as $dimension) { | |
| array_unshift($properties->columns_to_display, $dimension); | |
| } | |
| array_unshift($properties->columns_to_display, 'label'); | |
| }); | |
| } | |
| } | |
| $this->assignTemplateVar('segmentTitlePretty', $this->dataTable->getMetadata('segmentPretty')); | |
| $period = $this->dataTable->getMetadata('period'); | |
| $this->assignTemplateVar('periodTitlePretty', $period ? $period->getLocalizedShortString() : ''); | |
| } | |
| public function beforeGenericFiltersAreAppliedToLoadedDataTable() | |
| { | |
| if ($this->isPivoted()) { | |
| $this->config->columns_to_display = $this->dataTable->getColumns(); | |
| $this->dataTable->applyQueuedFilters(); | |
| } | |
| parent::beforeGenericFiltersAreAppliedToLoadedDataTable(); | |
| // Note: This needs to be done right before generic filter are applied, to make sorting such columns possible | |
| if ($this->isFlattened()) { | |
| $dimensions = $this->dataTable->getMetadata('dimensions'); | |
| $hasMultipleDimensions = is_array($dimensions) && count($dimensions) > 1; | |
| if ($hasMultipleDimensions) { | |
| foreach (Dimension::getAllDimensions() as $dimension) { | |
| $dimensionId = str_replace('.', '_', $dimension->getId()); | |
| $dimensionName = $dimension->getName(); | |
| if (!empty($dimensionId) && !empty($dimensionName) && in_array($dimensionId, $dimensions)) { | |
| $this->config->translations[$dimensionId] = $dimensionName; | |
| } | |
| } | |
| } | |
| if ($this->shouldShowDimensions() && $hasMultipleDimensions) { | |
| # replace original label column with first dimension | |
| $firstDimension = array_shift($dimensions); | |
| $this->dataTable->filter('ColumnCallbackAddMetadata', array( | |
| 'label', | |
| 'combinedLabel', | |
| function ($label) { | |
| return $label; | |
| }, | |
| )); | |
| $this->dataTable->filter('ColumnDelete', array('label')); | |
| $this->dataTable->filter('ReplaceColumnNames', array(array($firstDimension => 'label'))); | |
| } | |
| } | |
| } | |
| public function afterGenericFiltersAreAppliedToLoadedDataTable() | |
| { | |
| parent::afterGenericFiltersAreAppliedToLoadedDataTable(); | |
| $this->calculateTotalPercentages(); // this must be done before metrics are formatted | |
| } | |
| private function calculateTotalPercentages() | |
| { | |
| if (empty($this->report)) { | |
| return; | |
| } | |
| $columnNamesToIndices = Metrics::getMappingFromNameToId(); | |
| $formatter = NumberFormatter::getInstance(); | |
| $totals = $this->dataTable->getMetadata('totalsUnformatted'); | |
| $siteSummary = $this->getSiteSummary(); | |
| $siteTotalRow = $siteSummary ? $siteSummary->getFirstRow() : null; | |
| foreach ($this->dataTable->getRows() as $row) { | |
| foreach ($this->report->getMetrics() as $column => $translation) { | |
| // Try to check the column by it's index (not possible for all metrics, like custom columns) | |
| $indexColumn = !empty($columnNamesToIndices[$column]) ? $columnNamesToIndices[$column] : null; | |
| $value = (($indexColumn && $row->getColumn($indexColumn)) ? $row->getColumn($indexColumn) : $row->getColumn($column)) ?: 0; | |
| if ($column == 'label') { | |
| continue; | |
| } | |
| $reportTotal = isset($totals[$column]) ? $totals[$column] : 0; | |
| if (is_numeric($value)) { | |
| $percentageColumnName = $column . '_row_percentage'; | |
| $rowPercentage = $formatter->formatPercent(Piwik::getPercentageSafe($value, $reportTotal, $precision = 1), $precision); | |
| $row->setMetadata($percentageColumnName, $rowPercentage); | |
| } | |
| if ($siteTotalRow) { | |
| $siteTotal = $siteTotalRow->getColumn($column) ?: 0; | |
| $siteTotalPercentage = $column . '_site_total_percentage'; | |
| if ($siteTotal && $siteTotal > $reportTotal) { | |
| $rowPercentage = $formatter->formatPercent(Piwik::getPercentageSafe($value, $siteTotal, $precision = 1), $precision); | |
| $row->setMetadata($siteTotalPercentage, $rowPercentage); | |
| } | |
| } | |
| } | |
| } | |
| } | |
| protected function isPivoted() | |
| { | |
| return $this->requestConfig->pivotBy || Common::getRequestVar('pivotBy', ''); | |
| } | |
| /** | |
| * Override to compute a custom cell HTML attributes (such as style). | |
| * | |
| * @param $column | |
| * @return array|null Array of name => value pairs, or null if no custom attributes. | |
| */ | |
| public function getCellHtmlAttributes(Row $row, $column) | |
| { | |
| return null; | |
| } | |
| public function supportsComparison() | |
| { | |
| return true; | |
| } | |
| protected function isFlattened() | |
| { | |
| return $this->requestConfig->flat || Common::getRequestVar('flat', ''); | |
| } | |
| protected function shouldShowDimensions() | |
| { | |
| return $this->requestConfig->show_dimensions || Common::getRequestVar('show_dimensions', ''); | |
| } | |
| private function getSiteSummary() | |
| { | |
| if (empty($this->siteSummary)) { | |
| // we do not want to get a datatable\map | |
| $period = Common::getRequestVar('period', 'day', 'string'); | |
| if (Period\Range::parseDateRange($period)) { | |
| $period = 'range'; | |
| } | |
| $this->siteSummary = ApiRequest::processRequest('API.get', [ | |
| 'module' => 'API', | |
| 'action' => 'get', | |
| 'filter_limit' => '-1', | |
| 'disable_generic_filters' => 1, | |
| 'filter_offset' => 0, | |
| 'date' => Common::getRequestVar('date', null, 'string'), | |
| 'idSite' => Common::getRequestVar('idSite', null, 'int'), | |
| 'period' => $period, | |
| 'showColumns' => implode(',', $this->config->columns_to_display), | |
| 'columns' => implode(',', $this->config->columns_to_display), | |
| ], $default = []); | |
| } | |
| return $this->siteSummary; | |
| } | |
| } | |