Files
onboard/app/Services/Analytics/Dimension.php

57 lines
1.9 KiB
PHP

<?php
namespace App\Services\Analytics;
use Closure;
/**
* Измерение (группировка) отчёта: по чему группируем строки таблицы.
* Несёт SQL-выражение для SELECT/GROUP BY и опциональные join + резолвер подписей.
*/
readonly class Dimension
{
/**
* @param 'string'|'date' $type
* @param string $select raw SQL-выражение, дающее сырое значение измерения
* @param ?string $groupBy выражение для GROUP BY (по умолчанию = $select)
* @param ?Closure $applyJoin fn(\Illuminate\Database\Query\Builder $q): void — добавить нужный JOIN
* @param ?Closure $labels fn(array $rawValues): array<int|string,string> — карта «сырое значение => подпись»
*/
public function __construct(
public string $key,
public string $label,
public string $type,
public string $select,
public ?string $groupBy = null,
public ?Closure $applyJoin = null,
public ?Closure $labels = null,
) {}
public function groupByExpr(): string
{
return $this->groupBy ?? $this->select;
}
/**
* Подпись сырого значения для вывода в таблице.
*
* @param array<int|string,string>|null $labelMap
*/
public function display(mixed $raw, ?array $labelMap = null): string
{
if ($raw === null || $raw === '') {
return '—';
}
if ($labelMap !== null && array_key_exists($raw, $labelMap)) {
return $labelMap[$raw];
}
if ($this->type === 'date') {
return \Illuminate\Support\Carbon::parse((string) $raw)->format('d.m.Y');
}
return (string) $raw;
}
}