Returns the first row of the DataTable.
public getFirstRow ( ) : |
||
return | The first row or `false` if it cannot be found. |
public function test_filter_shouldNotAppendAnything_IfNameToReplaceIsEmpty() { $columnNamesBefore = array('nb_visits', 'nb_conversions', 'revenue', 'conversion_rate'); $this->table->filter($this->filter, array('')); $this->table->filter($this->filter, array(null)); $this->table->filter($this->filter, array(false)); $columnNamesAfter = array_keys($this->table->getFirstRow()->getColumns()); $this->assertSame($columnNamesBefore, $columnNamesAfter); }
/** * See {@link Sort}. * * @param DataTable $table * @return mixed */ public function filter($table) { if ($table instanceof Simple) { return; } if (empty($this->columnToSort)) { return; } if (!$table->getRowsCountWithoutSummaryRow()) { return; } $row = $table->getFirstRow(); if ($row === false) { return; } $config = new Sorter\Config(); $sorter = new Sorter($config); $config->naturalSort = $this->naturalSort; $config->primaryColumnToSort = $sorter->getPrimaryColumnToSort($table, $this->columnToSort); $config->primarySortOrder = $sorter->getPrimarySortOrder($this->order); $config->primarySortFlags = $sorter->getBestSortFlags($table, $config->primaryColumnToSort); $config->secondaryColumnToSort = $sorter->getSecondaryColumnToSort($row, $config->primaryColumnToSort); $config->secondarySortOrder = $sorter->getSecondarySortOrder($this->order, $config->secondaryColumnToSort); $config->secondarySortFlags = $sorter->getBestSortFlags($table, $config->secondaryColumnToSort); // secondary sort should not be needed for all other sort flags (eg string/natural sort) as label is unique and would make it slower $isSecondaryColumnSortNeeded = $config->primarySortFlags === SORT_NUMERIC; $config->isSecondaryColumnSortEnabled = $this->isSecondaryColumnSortEnabled && $isSecondaryColumnSortNeeded; $this->sort($sorter, $table); }
/** * Merge the columns of two data tables. * Manipulates the first table. * * @param DataTable|DataTable\Map $table1 The table to eventually filter. * @param DataTable|DataTable\Map $table2 Whether to delete rows with no visits or not. */ public function mergeDataTables($table1, $table2) { // handle table arrays if ($table1 instanceof DataTable\Map && $table2 instanceof DataTable\Map) { $subTables2 = $table2->getDataTables(); foreach ($table1->getDataTables() as $index => $subTable1) { if (!array_key_exists($index, $subTables2)) { // occurs when archiving starts on dayN and continues into dayN+1, see https://github.com/piwik/piwik/issues/5168#issuecomment-50959925 continue; } $subTable2 = $subTables2[$index]; $this->mergeDataTables($subTable1, $subTable2); } return; } $firstRow2 = $table2->getFirstRow(); if (!$firstRow2 instanceof Row) { return; } $firstRow1 = $table1->getFirstRow(); if (empty($firstRow1)) { $firstRow1 = $table1->addRow(new Row()); } foreach ($firstRow2->getColumns() as $metric => $value) { $firstRow1->setColumn($metric, $value); } }
private function hasDataTableMetric(DataTable $dataTable, $metricId) { $firstRow = $dataTable->getFirstRow(); if (empty($firstRow)) { return false; } if (false === $this->getColumn($firstRow, $metricId)) { return false; } return true; }
private function getFirstAndLastDataPointsForMetric($metric) { $first = 0; $firstTable = $this->dataTable->getFirstRow(); if (!empty($firstTable)) { $row = $firstTable->getFirstRow(); if (!empty($row)) { $first = floatval($row->getColumn($metric)); } } $last = 0; $lastTable = $this->dataTable->getLastRow(); if (!empty($lastTable)) { $row = $lastTable->getFirstRow(); if (!empty($row)) { $last = floatval($row->getColumn($metric)); } } return array($first, $last); }
/** * Converts the output of the given simple data table * * @param DataTable|Simple $table * @param array $allColumns * @return string */ protected function renderDataTable($table, &$allColumns = array()) { if ($table instanceof Simple) { $row = $table->getFirstRow(); if ($row !== false) { $columnNameToValue = $row->getColumns(); if (count($columnNameToValue) == 1) { // simple tables should only have one column, the value $allColumns['value'] = true; $value = array_values($columnNameToValue); $str = 'value' . $this->lineEnd . $this->formatValue($value[0]); return $str; } } } $csv = array(); foreach ($table->getRows() as $row) { $csvRow = $this->flattenColumnArray($row->getColumns()); if ($this->exportMetadata) { $metadata = $row->getMetadata(); foreach ($metadata as $name => $value) { if ($name == 'idsubdatatable_in_db') { continue; } //if a metadata and a column have the same name make sure they dont overwrite if ($this->translateColumnNames) { $name = Piwik::translate('General_Metadata') . ': ' . $name; } else { $name = 'metadata_' . $name; } $csvRow[$name] = $value; } } foreach ($csvRow as $name => $value) { $allColumns[$name] = true; } if ($this->exportIdSubtable) { $idsubdatatable = $row->getIdSubDataTable(); if ($idsubdatatable !== false && $this->hideIdSubDatatable === false) { $csvRow['idsubdatatable'] = $idsubdatatable; } } $csv[] = $csvRow; } // now we make sure that all the rows in the CSV array have all the columns foreach ($csv as &$row) { foreach ($allColumns as $columnName => $true) { if (!isset($row[$columnName])) { $row[$columnName] = ''; } } } $str = ''; // specific case, we have only one column and this column wasn't named properly (indexed by a number) // we don't print anything in the CSV file => an empty line if (sizeof($allColumns) == 1 && reset($allColumns) && !is_string(key($allColumns))) { $str .= ''; } else { // render row names $str .= $this->getHeaderLine(array_keys($allColumns)) . $this->lineEnd; } // we render the CSV foreach ($csv as $theRow) { $rowStr = ''; foreach ($allColumns as $columnName => $true) { $rowStr .= $this->formatValue($theRow[$columnName]) . $this->separator; } // remove the last separator $rowStr = substr_replace($rowStr, "", -strlen($this->separator)); $str .= $rowStr . $this->lineEnd; } $str = substr($str, 0, -strlen($this->lineEnd)); return $str; }
public function test_renderDataTable_shouldRenderSubtables() { $subtable = new DataTable(); $subtable->addRowFromSimpleArray(array('nb_visits' => 2, 'nb_random' => 6)); $dataTable = new DataTable(); $dataTable->addRowFromSimpleArray(array('nb_visits' => 5, 'nb_random' => 10)); $dataTable->getFirstRow()->setSubtable($subtable); $response = $this->builder->renderDataTable($dataTable); $expected = array(array('nb_visits' => 5, 'nb_random' => 10, 'idsubdatatable' => 1)); $this->assertEquals($expected, $response); }
/** * Converts the output of the given simple data table * * @param DataTable|Simple $table * @param array $allColumns * @return string */ protected function renderDataTable($table, &$allColumns = array()) { if ($table instanceof Simple) { $row = $table->getFirstRow(); if ($row !== false) { $columnNameToValue = $row->getColumns(); if (count($columnNameToValue) == 1) { // simple tables should only have one column, the value $allColumns['value'] = true; $value = array_values($columnNameToValue); $str = 'value' . $this->lineEnd . $this->formatValue($value[0]); return $str; } } } $csv = $this->makeArrayFromDataTable($table, $allColumns); // now we make sure that all the rows in the CSV array have all the columns foreach ($csv as &$row) { foreach ($allColumns as $columnName => $true) { if (!isset($row[$columnName])) { $row[$columnName] = ''; } } } $str = $this->buildCsvString($allColumns, $csv); return $str; }
/** * Sums a DataTable to this one. * * This method will sum rows that have the same label. If a row is found in `$tableToSum` whose * label is not found in `$this`, the row will be added to `$this`. * * If the subtables for this table are loaded, they will be summed as well. * * Rows are summed together by summing individual columns. By default columns are summed by * adding one column value to another. Some columns cannot be aggregated this way. In these * cases, the {@link COLUMN_AGGREGATION_OPS_METADATA_NAME} * metadata can be used to specify a different type of operation. * * @param \Piwik\DataTable $tableToSum * @throws Exception */ public function addDataTable(DataTable $tableToSum) { if ($tableToSum instanceof Simple) { if ($tableToSum->getRowsCount() > 1) { throw new Exception("Did not expect a Simple table with more than one row in addDataTable()"); } $row = $tableToSum->getFirstRow(); $this->aggregateRowFromSimpleTable($row); } else { $columnAggregationOps = $this->getMetadata(self::COLUMN_AGGREGATION_OPS_METADATA_NAME); foreach ($tableToSum->getRowsWithoutSummaryRow() as $row) { $this->aggregateRowWithLabel($row, $columnAggregationOps); } // we do not use getRows() as this method might get called 100k times when aggregating many datatables and // this takes a lot of time. $row = $tableToSum->getRowFromId(DataTable::ID_SUMMARY_ROW); if ($row) { $this->aggregateRowWithLabel($row, $columnAggregationOps); } } }
public function test_renderDataTable_shouldRenderSubtables() { $subtable = new DataTable(); $subtable->addRowFromSimpleArray(array('nb_visits' => 2, 'nb_random' => 6)); $dataTable = new DataTable(); $dataTable->addRowFromSimpleArray(array('nb_visits' => 5, 'nb_random' => 10)); $dataTable->getFirstRow()->setSubtable($subtable); $response = $this->builder->renderDataTable($dataTable); $this->assertEquals('<table id="MultiSites_getAll" border="1"> <thead> <tr> <th>nb_visits</th> <th>nb_random</th> <th>_idSubtable</th> </tr> </thead> <tbody> <tr> <td>5</td> <td>10</td> <td>1</td> </tr> </tbody> </table> ', $response); }
/** * Helper method that determines the actual column for a metric in a {@link Piwik\DataTable}. * * @param DataTable $table * @param string $columnName * @param int[]|null $mappingNameToId A custom mapping of metric names to special index values. By * default {@link Metrics::getMappingFromNameToId()} is used. * @return string */ public static function getActualMetricColumn(DataTable $table, $columnName, $mappingNameToId = null) { if (empty($mappingIdToName)) { $mappingNameToId = Metrics::getMappingFromNameToId(); } $firstRow = $table->getFirstRow(); if (!empty($firstRow) && $firstRow->getColumn($columnName) === false) { $columnName = $mappingNameToId[$columnName]; } return $columnName; }
/** * Detect the column to be used for sorting * * @param DataTable $table * @param string|int $columnToSort column name or column id * @return int */ public function getPrimaryColumnToSort(DataTable $table, $columnToSort) { // we fallback to nb_visits in case columnToSort does not exist $columnsToCheck = array($columnToSort, 'nb_visits'); $row = $table->getFirstRow(); foreach ($columnsToCheck as $column) { $column = Metric::getActualMetricColumn($table, $column); if ($row->hasColumn($column)) { // since getActualMetricColumn() returns a default value, we need to make sure it actually has that column return $column; } } return $columnToSort; }
/** * See {@link Sort}. * * @param DataTable $table * @return mixed */ public function filter($table) { if ($table instanceof Simple) { return; } if (empty($this->columnToSort)) { return; } if (!$table->getRowsCount()) { return; } $row = $table->getFirstRow(); if ($row === false) { return; } $this->columnToSort = $this->selectColumnToSort($row); $value = $this->getFirstValueFromDataTable($table); if (is_numeric($value) && $this->columnToSort !== 'label') { $methodToUse = "numberSort"; } else { if ($this->naturalSort) { $methodToUse = "naturalSort"; } else { $methodToUse = "sortString"; } } $this->sort($table, $methodToUse); }
private function hasAverageTimeGeneration(DataTable $table) { return $table->getFirstRow()->getColumn('avg_time_generation') !== false; }
/** * Sums a DataTable to this one. * * This method will sum rows that have the same label. If a row is found in `$tableToSum` whose * label is not found in `$this`, the row will be added to `$this`. * * If the subtables for this table are loaded, they will be summed as well. * * Rows are summed together by summing individual columns. By default columns are summed by * adding one column value to another. Some columns cannot be aggregated this way. In these * cases, the {@link COLUMN_AGGREGATION_OPS_METADATA_NAME} * metadata can be used to specify a different type of operation. * * @param \Piwik\DataTable $tableToSum */ public function addDataTable(DataTable $tableToSum, $doAggregateSubTables = true) { if ($tableToSum instanceof Simple) { if ($tableToSum->getRowsCount() > 1) { throw new Exception("Did not expect a Simple table with more than one row in addDataTable()"); } $row = $tableToSum->getFirstRow(); $this->aggregateRowFromSimpleTable($row); } else { foreach ($tableToSum->getRows() as $row) { $this->aggregateRowWithLabel($row, $doAggregateSubTables); } } }
public function test_renderDataTable_shouldRenderSubtables() { $subtable = new DataTable(); $subtable->addRowFromSimpleArray(array('nb_visits' => 2, 'nb_random' => 6)); $dataTable = new DataTable(); $dataTable->addRowFromSimpleArray(array('nb_visits' => 5, 'nb_random' => 10)); $dataTable->getFirstRow()->setSubtable($subtable); $response = $this->builder->renderDataTable($dataTable); $this->assertEquals('<?xml version="1.0" encoding="utf-8" ?> <result> <row> <nb_visits>5</nb_visits> <nb_random>10</nb_random> <idsubdatatable>1</idsubdatatable> </row> </result>', $response); }
public function test_renderDataTable_shouldNotRenderSubtables_AsItIsNotSupportedYet() { $subtable = new DataTable(); $subtable->addRowFromSimpleArray(array('nb_visits' => 2, 'nb_random' => 6)); $dataTable = new DataTable(); $dataTable->addRowFromSimpleArray(array('nb_visits' => 5, 'nb_random' => 10)); $dataTable->getFirstRow()->setSubtable($subtable); $response = $this->builder->renderDataTable($dataTable); $this->assertEquals('nb_visits,nb_random 5,10', $response); }
/** * @expectedException \Exception * @expectedExceptionMessage RSS feeds can be generated for one specific website */ public function test_renderDataTable_shouldFailForSubtables() { $subtable = new DataTable(); $subtable->addRowFromSimpleArray(array('nb_visits' => 2, 'nb_random' => 6)); $dataTable = new DataTable(); $dataTable->addRowFromSimpleArray(array('nb_visits' => 5, 'nb_random' => 10)); $dataTable->getFirstRow()->setSubtable($subtable); $this->builder->renderDataTable($dataTable); }
public function test_renderDataTable_shouldRenderSubtables() { $subtable = new DataTable(); $subtable->addRowFromSimpleArray(array('nb_visits' => 2, 'nb_random' => 6)); $dataTable = new DataTable(); $dataTable->addRowFromSimpleArray(array('nb_visits' => 5, 'nb_random' => 10)); $dataTable->getFirstRow()->setSubtable($subtable); $response = $this->jsonBuilder->renderDataTable($dataTable); $this->assertEquals('[{"nb_visits":5,"nb_random":10,"idsubdatatable":1}]', $response); $this->assertNoJsonError($response); }