| <?php |
|
|
| |
| |
| |
| |
| |
| |
|
|
| namespace Piwik\ArchiveProcessor; |
|
|
| use Piwik\Common; |
| use Piwik\DataTable; |
| use Piwik\DataTable\Row; |
|
|
| |
| |
| |
| |
| |
| final class BlobTableAggregator |
| { |
| |
| |
| |
| |
| |
| |
| |
| public static function aggregateBlobRows( |
| iterable $archiveDataRows, |
| string $recordName, |
| ?array $columnsAggregationOperation, |
| callable $renameColumnsCallback, |
| ?callable $shouldIncludeRow = null, |
| ?callable $onMissingParentTable = null |
| ): array { |
| |
| |
| $tableIdToResultRowMapping = []; |
| $result = new DataTable(); |
| $hasRows = false; |
|
|
| if (!empty($columnsAggregationOperation)) { |
| $result->setMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME, $columnsAggregationOperation); |
| } |
|
|
| foreach ($archiveDataRows as $archiveDataRow) { |
| if ($shouldIncludeRow !== null && !$shouldIncludeRow($archiveDataRow)) { |
| continue; |
| } |
|
|
| $hasRows = true; |
| $period = $archiveDataRow['date1'] . ',' . $archiveDataRow['date2']; |
| $tableId = $archiveDataRow['name'] === $recordName |
| ? null |
| : self::parseSubtableIdFromBlobName($archiveDataRow['name']); |
|
|
| $blobTable = DataTable::fromSerializedArray($archiveDataRow['value']); |
| $blobTable->filter(function (DataTable $table) use ($renameColumnsCallback) { |
| $renameColumnsCallback($table); |
| }); |
|
|
| if ($tableId === null) { |
| $tableToAddTo = $result; |
| } elseif (empty($tableIdToResultRowMapping[$period][$tableId])) { |
| if ($onMissingParentTable !== null) { |
| $onMissingParentTable($period, $tableId); |
| } |
| Common::destroy($blobTable); |
| continue; |
| } else { |
| $rowToAddTo = $tableIdToResultRowMapping[$period][$tableId]; |
| if (!$rowToAddTo->getIdSubDataTable()) { |
| $newTable = new DataTable(); |
| if (!empty($columnsAggregationOperation)) { |
| $newTable->setMetadata(DataTable::COLUMN_AGGREGATION_OPS_METADATA_NAME, $columnsAggregationOperation); |
| } |
| $rowToAddTo->setSubtable($newTable); |
| } |
|
|
| $tableToAddTo = $rowToAddTo->getSubtable(); |
| } |
|
|
| $tableToAddTo->addDataTable($blobTable); |
|
|
| foreach ($blobTable->getRows() as $blobTableRow) { |
| $label = $blobTableRow->getColumn('label'); |
| $subtableId = $blobTableRow->getIdSubDataTable(); |
| if (empty($subtableId)) { |
| continue; |
| } |
|
|
| $rowToAddTo = $tableToAddTo->getRowFromLabel($label); |
| if ($rowToAddTo instanceof Row) { |
| $tableIdToResultRowMapping[$period][$subtableId] = $rowToAddTo; |
| } |
| } |
|
|
| Common::destroy($blobTable); |
| } |
|
|
| return [$result, $hasRows]; |
| } |
|
|
| public static function parseSubtableIdFromBlobName(string $recordName): ?int |
| { |
| $parts = explode('_', $recordName); |
| $id = end($parts); |
|
|
| if (!is_numeric($id)) { |
| return null; |
| } |
|
|
| return (int) $id; |
| } |
| } |
|
|