Returns metadata by name.
public getMetadata ( string $name ) : mixed | false | ||
$name | string | The metadata name. |
return | mixed | false | The metadata value or `false` if it cannot be found. |
public function getMetricTotalValue(DataTable $currentReport, $metric) { $totals = $currentReport->getMetadata('totals'); if (!empty($totals[$metric])) { $totalValue = (int) $totals[$metric]; } else { $totalValue = 0; } return $totalValue; }
/** * Sums a tables row with this one. * * @param DataTable $table */ private function sumTable($table) { $metadata = $table->getMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME); $enableCopyMetadata = false; foreach ($table->getRowsWithoutSummaryRow() as $row) { $this->sumRow($row, $enableCopyMetadata, $metadata); } $summaryRow = $table->getRowFromId(DataTable::ID_SUMMARY_ROW); if ($summaryRow) { $this->sumRow($summaryRow, $enableCopyMetadata, $metadata); } }
/** * See {@link ColumnCallbackAddColumn}. * * @param DataTable $table The table to filter. */ public function filter($table) { $columns = $this->columns; $functionParams = $this->functionParameters; $functionToApply = $this->functionToApply; $extraProcessedMetrics = $table->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME); if (empty($extraProcessedMetrics)) { $extraProcessedMetrics = array(); } $metric = new CallableProcessedMetric($this->columnToAdd, function (DataTable\Row $row) use($columns, $functionParams, $functionToApply) { $columnValues = array(); foreach ($columns as $column) { $columnValues[] = $row->getColumn($column); } $parameters = array_merge($columnValues, $functionParams); return call_user_func_array($functionToApply, $parameters); }, $columns); $extraProcessedMetrics[] = $metric; $table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $extraProcessedMetrics); foreach ($table->getRows() as $row) { $row->setColumn($this->columnToAdd, $metric->compute($row)); $this->filterSubTable($row); } }
/** * See {@link GroupBy}. * * @param DataTable $table */ public function filter($table) { $groupByRows = array(); $nonGroupByRowIds = array(); foreach ($table->getRows() as $rowId => $row) { // skip the summary row if ($rowId == DataTable::ID_SUMMARY_ROW) { continue; } // reduce the group by column of this row $groupByColumnValue = $row->getColumn($this->groupByColumn); $parameters = array_merge(array($groupByColumnValue), $this->parameters); $groupByValue = call_user_func_array($this->reduceFunction, $parameters); if (!isset($groupByRows[$groupByValue])) { // if we haven't encountered this group by value before, we mark this row as a // row to keep, and change the group by column to the reduced value. $groupByRows[$groupByValue] = $row; $row->setColumn($this->groupByColumn, $groupByValue); } else { // if we have already encountered this group by value, we add this row to the // row that will be kept, and mark this one for deletion $groupByRows[$groupByValue]->sumRow($row, $copyMeta = true, $table->getMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME)); $nonGroupByRowIds[] = $rowId; } } // delete the unneeded rows. $table->deleteRows($nonGroupByRowIds); }
private function createGroupSubtable(DataTable $sites) { $table = new DataTable(); $processedMetrics = $sites->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME); $table->setMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME, $processedMetrics); return $table; }
/** * Sums a DataTable to this row's subtable. If this row has no subtable a new * one is created. * * See {@link Piwik\DataTable::addDataTable()} to learn how DataTables are summed. * * @param DataTable $subTable Table to sum to this row's subtable. */ public function sumSubtable(DataTable $subTable) { if ($this->isSubtableLoaded()) { $thisSubTable = $this->getSubtable(); } else { $thisSubTable = new DataTable(); $this->addSubtable($thisSubTable); } $columnOps = $subTable->getMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME); $thisSubTable->setMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME, $columnOps); $thisSubTable->addDataTable($subTable); }
/** * Common filters for Page URLs and Page Titles * * @param DataTable|DataTable\Simple|DataTable\Map $dataTable */ protected function filterPageDatatable($dataTable) { $columnsToRemove = array('bounce_rate'); $dataTable->queueFilter('ColumnDelete', array($columnsToRemove)); // Average time on page = total time on page / number visits on that page $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_time_on_page', 'sum_time_spent', 'nb_visits', 0)); // Bounce rate = single page visits on this page / visits started on this page $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('bounce_rate', 'entry_bounce_count', 'entry_nb_visits', 0)); // % Exit = Number of visits that finished on this page / visits on this page $dataTable->queueFilter('ColumnCallbackAddColumnPercentage', array('exit_rate', 'exit_nb_visits', 'nb_visits', 0)); // Handle performance analytics $hasTimeGeneration = array_sum($dataTable->getColumn(Metrics::INDEX_PAGE_SUM_TIME_GENERATION)) > 0; if ($hasTimeGeneration) { // Average generation time = total generation time / number of pageviews $precisionAvgTimeGeneration = 3; $dataTable->queueFilter('ColumnCallbackAddColumnQuotient', array('avg_time_generation', 'sum_time_generation', 'nb_hits_with_time_generation', $precisionAvgTimeGeneration)); $dataTable->queueFilter('ColumnDelete', array(array('sum_time_generation'))); } else { // No generation time: remove it from the API output and add it to empty_columns metadata, so that // the columns can also be removed from the view $dataTable->filter('ColumnDelete', array(array(Metrics::INDEX_PAGE_SUM_TIME_GENERATION, Metrics::INDEX_PAGE_NB_HITS_WITH_TIME_GENERATION, Metrics::INDEX_PAGE_MIN_TIME_GENERATION, Metrics::INDEX_PAGE_MAX_TIME_GENERATION))); if ($dataTable instanceof DataTable) { $emptyColumns = $dataTable->getMetadata(DataTable::EMPTY_COLUMNS_METADATA_NAME); if (!is_array($emptyColumns)) { $emptyColumns = array(); } $emptyColumns[] = 'sum_time_generation'; $emptyColumns[] = 'avg_time_generation'; $emptyColumns[] = 'min_time_generation'; $emptyColumns[] = 'max_time_generation'; $dataTable->setMetadata(DataTable::EMPTY_COLUMNS_METADATA_NAME, $emptyColumns); } } }
/** * Sums a tables row with this one. * * @param DataTable $table */ private function sumTable($table) { foreach ($table->getRows() as $row) { $this->sumRow($row, $enableCopyMetadata = false, $table->getMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME)); } }
/** * @param DataTable $table */ private function addSummaryRow($table) { if ($table->getRowsCount() <= $this->truncateAfter + 1) { return; } $table->filter('Sort', array($this->columnToSortByBeforeTruncating, 'desc', $naturalSort = true, $recursiveSort = false)); $rows = array_values($table->getRows()); $count = $table->getRowsCount(); $newRow = new Row(array(Row::COLUMNS => array('label' => DataTable::LABEL_SUMMARY_ROW))); $aggregationOps = $table->getMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME); for ($i = $this->truncateAfter; $i < $count; $i++) { if (!isset($rows[$i])) { // case when the last row is a summary row, it is not indexed by $cout but by DataTable::ID_SUMMARY_ROW $summaryRow = $table->getRowFromId(DataTable::ID_SUMMARY_ROW); //FIXME: I'm not sure why it could return false, but it was reported in: http://forum.piwik.org/read.php?2,89324,page=1#msg-89442 if ($summaryRow) { $newRow->sumRow($summaryRow, $enableCopyMetadata = false, $aggregationOps); } } else { $newRow->sumRow($rows[$i], $enableCopyMetadata = false, $aggregationOps); } } $table->filter('Limit', array(0, $this->truncateAfter)); $table->addSummaryRow($newRow); unset($rows); }
/** * Returns the ID of the site a table is related to based on the 'site' metadata entry, * or null if there is none. * * @param DataTable $table * @return int|null */ public static function getSiteIdFromMetadata(DataTable $table) { $site = $table->getMetadata('site'); if (empty($site)) { return null; } else { return $site->getId(); } }
public function computeProcessedMetrics(DataTable $dataTable) { if ($dataTable->getMetadata(self::PROCESSED_METRICS_COMPUTED_FLAG)) { return; } /** @var ProcessedMetric[] $processedMetrics */ $processedMetrics = Report::getProcessedMetricsForTable($dataTable, $this->report); if (empty($processedMetrics)) { return; } $dataTable->setMetadata(self::PROCESSED_METRICS_COMPUTED_FLAG, true); foreach ($processedMetrics as $name => $processedMetric) { if (!$processedMetric->beforeCompute($this->report, $dataTable)) { continue; } foreach ($dataTable->getRows() as $row) { if ($row->getColumn($name) === false) { // only compute the metric if it has not been computed already $computedValue = $processedMetric->compute($row); if ($computedValue !== false) { $row->addColumn($name, $computedValue); } $subtable = $row->getSubtable(); if (!empty($subtable)) { $this->computeProcessedMetrics($subtable); } } } } }
private function assertTableMetadataEquals($expectedPeriod, DataTable $dataTable) { $period = $dataTable->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX); $this->assertFalse($dataTable->getMetadata(DataTableFactory::TABLE_METADATA_SITE_INDEX)); $this->assertTrue($period instanceof Period); $this->assertSame($expectedPeriod, $period->toString()); }
/** * Extends an already generated insight report by adding a column "isMoverAndShaker" whether a row is also a * "Mover and Shaker" or not. * * Avoids the need to fetch all reports again when we already have the currentReport/lastReport */ public function markMoversAndShakers(DataTable $insight, $currentReport, $lastReport, $totalValue, $lastTotalValue) { if (!$insight->getRowsCount()) { return; } $limitIncreaser = max($insight->getRowsCount(), 3); $limitDecreaser = max($insight->getRowsCount(), 3); $lastDate = $insight->getMetadata('lastDate'); $date = $insight->getMetadata('date'); $period = $insight->getMetadata('period'); $metric = $insight->getMetadata('metric'); $orderBy = $insight->getMetadata('orderBy'); $reportMetadata = $insight->getMetadata('report'); $shakers = $this->generateMoverAndShaker($reportMetadata, $period, $date, $lastDate, $metric, $currentReport, $lastReport, $totalValue, $lastTotalValue, $orderBy, $limitIncreaser, $limitDecreaser); foreach ($insight->getRows() as $row) { $label = $row->getColumn('label'); if ($shakers->getRowFromLabel($label)) { $row->setColumn('isMoverAndShaker', true); } else { $row->setColumn('isMoverAndShaker', false); } } $this->addMoversAndShakersMetadata($insight, $totalValue, $lastTotalValue); }
/** * Returns the Metrics that are displayed by a DataTable of a certain Report type. * * Includes ProcessedMetrics and Metrics. * * @param DataTable $dataTable * @param Report|null $report * @param string $baseType The base type each metric class needs to be of. * @return Metric[] * @api */ public static function getMetricsForTable(DataTable $dataTable, Report $report = null, $baseType = 'Piwik\\Plugin\\Metric') { $metrics = $dataTable->getMetadata(DataTable::EXTRA_PROCESSED_METRICS_METADATA_NAME) ?: array(); if (!empty($report)) { $metrics = array_merge($metrics, $report->getProcessedMetricsById()); } $result = array(); /** @var Metric $metric */ foreach ($metrics as $metric) { if (!$metric instanceof $baseType) { continue; } $result[$metric->getName()] = $metric; } return $result; }
/** * Load the subtable for a row. * Returns null if none is found. * * @param DataTable $dataTable * @param Row $row * * @return DataTable */ protected function loadSubtable($dataTable, $row) { if (!($this->apiModule && $this->apiMethod && count($this->request))) { return null; } $request = $this->request; $idSubTable = $row->getIdSubDataTable(); if ($idSubTable === null) { return null; } $request['idSubtable'] = $idSubTable; if ($dataTable) { $period = $dataTable->getMetadata(DataTableFactory::TABLE_METADATA_PERIOD_INDEX); if ($period instanceof Range) { $request['date'] = $period->getDateStart() . ',' . $period->getDateEnd(); } else { $request['date'] = $period->getDateStart()->toString(); } } $method = $this->getApiMethodForSubtable(); return $this->callApiAndReturnDataTable($this->apiModule, $method, $request); }
private function getRequestParamOverride(DataTable $table) { $params = array('pivotBy' => '', 'column' => '', 'flat' => 0, 'totals' => 0, 'disable_queued_filters' => 1, 'disable_generic_filters' => 1, 'showColumns' => '', 'hideColumns' => ''); /** @var Site $site */ $site = $table->getMetadata('site'); if (!empty($site)) { $params['idSite'] = $site->getId(); } /** @var Period $period */ $period = $table->getMetadata('period'); if (!empty($period)) { $params['period'] = $period->getLabel(); if ($params['period'] == 'range') { $params['date'] = $period->getRangeString(); } else { $params['date'] = $period->getDateStart()->toString(); } } return $params; }
/** * Sets the total evolution metadata for a datatable returned by $this->buildDataTable * given data for the last period. * * @param DataTable|DataTable\Map $dataTable * @param DataTable|DataTable\Map $pastData * @param array $apiMetrics Metrics info. */ private function setPastDataMetadata($dataTable, $pastData, $apiMetrics) { if ($dataTable instanceof DataTable\Map) { $pastArray = $pastData->getDataTables(); foreach ($dataTable->getDataTables() as $subTable) { $this->setPastDataMetadata($subTable, current($pastArray), $apiMetrics); next($pastArray); } } else { // calculate total visits/actions/revenue for past data $this->setMetricsTotalsMetadata($pastData, $apiMetrics); foreach ($apiMetrics as $label => $metricInfo) { // get the names of metadata to set $totalMetadataName = self::getTotalMetadataName($label); $lastPeriodTotalMetadataName = self::getLastPeriodMetadataName($totalMetadataName); $totalEvolutionMetadataName = self::getTotalMetadataName($metricInfo[self::METRIC_EVOLUTION_COL_NAME_KEY]); // set last period total $pastTotal = $pastData->getMetadata($totalMetadataName); $dataTable->setMetadata($lastPeriodTotalMetadataName, $pastTotal); // calculate & set evolution $currentTotal = $dataTable->getMetadata($totalMetadataName); $evolution = CalculateEvolutionFilter::calculate($currentTotal, $pastTotal); $dataTable->setMetadata($totalEvolutionMetadataName, $evolution); } } }