Initial commit: CloudOps infrastructure platform
This commit is contained in:
@@ -0,0 +1,260 @@
|
||||
<?php
|
||||
|
||||
namespace Mautic\ReportBundle\Crate;
|
||||
|
||||
use Mautic\CoreBundle\Twig\Helper\FormatterHelper;
|
||||
|
||||
class ReportDataResult
|
||||
{
|
||||
private int $totalResults;
|
||||
|
||||
/**
|
||||
* @var array
|
||||
*/
|
||||
private $data;
|
||||
|
||||
private array $headers = [];
|
||||
|
||||
private array $types = [];
|
||||
|
||||
/**
|
||||
* @var array<string>
|
||||
*/
|
||||
private array $columnKeys = [];
|
||||
|
||||
/**
|
||||
* @var array<mixed>
|
||||
*/
|
||||
private array $graphs = [];
|
||||
|
||||
private ?\DateTime $dateFrom;
|
||||
|
||||
private ?\DateTime $dateTo;
|
||||
|
||||
private ?int $limit;
|
||||
|
||||
private int $page;
|
||||
|
||||
/**
|
||||
* @param array<mixed> $data
|
||||
* @param array<mixed> $totals
|
||||
*/
|
||||
public function __construct(
|
||||
array $data,
|
||||
private array $totals = [],
|
||||
private int $preBatchSize = 0,
|
||||
private bool $isLastBatch = true,
|
||||
) {
|
||||
if (
|
||||
!array_key_exists('data', $data)
|
||||
|| !array_key_exists('dataColumns', $data)
|
||||
|| !array_key_exists('columns', $data)
|
||||
) {
|
||||
throw new \InvalidArgumentException("Keys 'data', 'dataColumns' and 'columns' have to be provided");
|
||||
}
|
||||
|
||||
$this->totalResults = (int) $data['totalResults'];
|
||||
$this->data = $data['data'];
|
||||
$this->graphs = $data['graphs'] ?? [];
|
||||
$this->dateFrom = $data['dateFrom'] ?? null;
|
||||
$this->dateTo = $data['dateTo'] ?? null;
|
||||
$this->limit = isset($data['limit']) ? (int) $data['limit'] : null;
|
||||
$this->page = isset($data['page']) ? (int) $data['page'] : 1;
|
||||
$this->columnKeys = isset($this->data[0]) ? array_keys($this->data[0]) : [];
|
||||
|
||||
$this->buildHeader($data);
|
||||
$this->buildTypes($data);
|
||||
$this->buildTotals($data['aggregatorColumns'] ?? []);
|
||||
}
|
||||
|
||||
public function getTotalResults(): int
|
||||
{
|
||||
return $this->totalResults;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getData()
|
||||
{
|
||||
return $this->data;
|
||||
}
|
||||
|
||||
public function getDataCount(): int
|
||||
{
|
||||
return count($this->data);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function getHeaders()
|
||||
{
|
||||
return $this->headers;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $column
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function getType($column)
|
||||
{
|
||||
return $this->types[$column] ?? 'string';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function getTotals(): array
|
||||
{
|
||||
return $this->totals;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
public function getGraphs(): array
|
||||
{
|
||||
return $this->graphs;
|
||||
}
|
||||
|
||||
public function getDateTo(): ?\DateTime
|
||||
{
|
||||
return $this->dateTo;
|
||||
}
|
||||
|
||||
public function getDateFrom(): ?\DateTime
|
||||
{
|
||||
return $this->dateFrom;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string>
|
||||
*/
|
||||
public function getTotalsToExport(FormatterHelper $formatterHelper): array
|
||||
{
|
||||
if (empty($this->totals)) {
|
||||
return [];
|
||||
}
|
||||
|
||||
foreach ($this->columnKeys as $key) {
|
||||
if (isset($this->totals[$key])) {
|
||||
$type = $this->getType($key);
|
||||
$totalsRow[$key] = $formatterHelper->_($this->totals[$key], $type, true);
|
||||
} else {
|
||||
$totalsRow[$key] = '';
|
||||
}
|
||||
}
|
||||
|
||||
return $totalsRow ?? [];
|
||||
}
|
||||
|
||||
public function isLastPage(): bool
|
||||
{
|
||||
// No limit set
|
||||
if (empty($this->limit)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return $this->page == ceil($this->totalResults / $this->limit);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<int, string>
|
||||
*/
|
||||
public function getColumnKeys(): array
|
||||
{
|
||||
return $this->columnKeys;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
private function buildHeader($data): void
|
||||
{
|
||||
foreach ($this->columnKeys as $k) {
|
||||
$dataColumn = $data['dataColumns'][$k];
|
||||
$label = $data['columns'][$dataColumn]['label'];
|
||||
|
||||
// Aggregated column
|
||||
if (isset($data['aggregatorColumns'][$k])) {
|
||||
$this->headers[] = str_replace($dataColumn, $label, $k);
|
||||
} else {
|
||||
$this->headers[] = $data['columns'][$dataColumn]['label'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
*/
|
||||
private function buildTypes($data): void
|
||||
{
|
||||
foreach ($this->columnKeys as $k) {
|
||||
if (isset($data['aggregatorColumns']) && array_key_exists($k, $data['aggregatorColumns'])) {
|
||||
$this->types[$k] = (str_starts_with($k, 'AVG')) ? 'float' : 'int';
|
||||
} else {
|
||||
$dataColumn = $data['dataColumns'][$k];
|
||||
$this->types[$k] = $data['columns'][$dataColumn]['type'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<mixed> $aggregatorVal
|
||||
*/
|
||||
public function calcTotal(string $calcFunction, int $rowsCount, array &$aggregatorVal, ?float $previousVal = null): float|int|null
|
||||
{
|
||||
switch ($calcFunction) {
|
||||
case 'COUNT':
|
||||
case 'SUM':
|
||||
return ($previousVal ?? 0) + array_sum($aggregatorVal);
|
||||
case 'AVG':
|
||||
$sum = ($previousVal ?? 0) + array_sum($aggregatorVal);
|
||||
if ($this->isLastBatch) {
|
||||
return round($sum / $rowsCount, FormatterHelper::FLOAT_PRECISION);
|
||||
}
|
||||
|
||||
return $sum;
|
||||
case 'MAX':
|
||||
if (!is_null($previousVal)) {
|
||||
$aggregatorVal[] = $previousVal;
|
||||
}
|
||||
|
||||
return max($aggregatorVal);
|
||||
case 'MIN':
|
||||
if (!is_null($previousVal)) {
|
||||
$aggregatorVal[] = $previousVal;
|
||||
}
|
||||
|
||||
return min($aggregatorVal);
|
||||
default:
|
||||
return $previousVal;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> $aggregators
|
||||
*/
|
||||
private function buildTotals(array $aggregators): void
|
||||
{
|
||||
$dataCount = count($this->data) + $this->preBatchSize;
|
||||
|
||||
if ($aggregators && !empty(array_keys($this->data))) {
|
||||
foreach ($aggregators as $j => $v) {
|
||||
$aggregatorVal = array_column($this->data, $j);
|
||||
|
||||
if ($aggregatorVal) {
|
||||
$calcFunc = $this->getAggregatorCalcFunc($j, $v);
|
||||
$this->totals[$j] = $this->calcTotal($calcFunc, $dataCount, $aggregatorVal, $this->totals[$j] ?? null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getAggregatorCalcFunc(string $index, string $value): string
|
||||
{
|
||||
return trim(str_replace($value, '', $index));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user