115 lines
3.7 KiB
PHP
115 lines
3.7 KiB
PHP
<?php
|
|
|
|
namespace App\Support;
|
|
|
|
/**
|
|
* Normalizza l'oggetto `configurazione` (payload) proveniente dal configuratore in
|
|
* una lista ordinata di righe { label, value } pronte per PDF e backoffice.
|
|
*
|
|
* I valori sono misti: alcune chiavi sono stringhe (es. finitura_interna, maniglia),
|
|
* altre sono oggetti listino (es. tipo_finitura, cerniere_scomparsa, azionamento).
|
|
*/
|
|
class ConfigurazioneFormatter
|
|
{
|
|
/** Etichette italiane per le chiavi note. */
|
|
private const LABELS = [
|
|
'width' => 'Larghezza (cm)',
|
|
'height' => 'Altezza (cm)',
|
|
'tipo_finitura' => 'Tipo finitura',
|
|
'finitura_interna' => 'Finitura interna',
|
|
'finitura_esterna' => 'Finitura esterna',
|
|
'maniglia' => 'Maniglia',
|
|
'altezza_maniglia' => 'Altezza maniglia',
|
|
'vetro' => 'Vetro',
|
|
'cerniere_scomparsa' => 'Cerniere a scomparsa',
|
|
'azionamento' => 'Azionamento',
|
|
'apertura_portoncino' => 'Apertura',
|
|
'tipo_ispezione' => 'Tipo ispezione',
|
|
'avvolgibile' => 'Avvolgibile',
|
|
'cassonetto' => 'Cassonetto',
|
|
];
|
|
|
|
/** Ordine di visualizzazione preferito. */
|
|
private const ORDER = [
|
|
'width', 'height', 'tipo_finitura', 'finitura_interna', 'finitura_esterna',
|
|
'maniglia', 'altezza_maniglia', 'vetro', 'cerniere_scomparsa', 'azionamento',
|
|
'apertura_portoncino', 'tipo_ispezione', 'avvolgibile', 'cassonetto',
|
|
];
|
|
|
|
/** Chiavi tecniche da non mostrare nella lista (usate altrove, es. titolo). */
|
|
private const SKIP = ['nome'];
|
|
|
|
/**
|
|
* @param array<string,mixed>|null $configurazione
|
|
* @return array<int,array{label:string,value:string}>
|
|
*/
|
|
public static function toRows(?array $configurazione): array
|
|
{
|
|
if (empty($configurazione)) {
|
|
return [];
|
|
}
|
|
|
|
$keys = array_keys($configurazione);
|
|
|
|
// Ordina: prima le chiavi note nell'ordine preferito, poi le rimanenti.
|
|
usort($keys, function ($a, $b) {
|
|
$ia = array_search($a, self::ORDER, true);
|
|
$ib = array_search($b, self::ORDER, true);
|
|
$ia = $ia === false ? PHP_INT_MAX : $ia;
|
|
$ib = $ib === false ? PHP_INT_MAX : $ib;
|
|
|
|
return $ia <=> $ib ?: strcmp($a, $b);
|
|
});
|
|
|
|
$rows = [];
|
|
foreach ($keys as $key) {
|
|
if (in_array($key, self::SKIP, true)) {
|
|
continue;
|
|
}
|
|
|
|
$value = self::extractValue($configurazione[$key]);
|
|
if ($value === null || $value === '') {
|
|
continue;
|
|
}
|
|
|
|
$rows[] = [
|
|
'label' => self::LABELS[$key] ?? self::humanize($key),
|
|
'value' => $value,
|
|
];
|
|
}
|
|
|
|
return $rows;
|
|
}
|
|
|
|
/** Estrae un valore leggibile da stringa/numero/oggetto listino. */
|
|
private static function extractValue(mixed $value): ?string
|
|
{
|
|
if (is_scalar($value)) {
|
|
return trim((string) $value);
|
|
}
|
|
|
|
if (is_array($value)) {
|
|
// Preferisci i campi descrittivi tipici degli oggetti listino.
|
|
foreach (['descrizione', 'finitura', 'valore', 'label', 'id'] as $field) {
|
|
if (isset($value[$field]) && is_scalar($value[$field]) && $value[$field] !== '') {
|
|
return trim((string) $value[$field]);
|
|
}
|
|
}
|
|
|
|
// Fallback: primo valore scalare non vuoto.
|
|
foreach ($value as $v) {
|
|
if (is_scalar($v) && $v !== '') {
|
|
return trim((string) $v);
|
|
}
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
|
|
private static function humanize(string $key): string
|
|
{
|
|
return ucfirst(str_replace('_', ' ', $key));
|
|
}
|
|
}
|