- [ propertyName => 'Human label' ] * - fieldUnits(): array - [ propertyName => 'unit'|null ] * * toArray() is built automatically via reflection on public properties. */ abstract readonly class AbstractIncoCompoPartDto implements IncoCompoPartDto { /** * Map of [ propertyName => 'Human readable label' ]. * * @return array */ abstract protected static function fieldLabels(): array; /** * Map of [ propertyName => 'unit string or null' ]. * * @return array */ abstract protected static function fieldUnits(): array; // ------------------------------------------------------------------------- /** * {@inheritDoc} */ public function toArray(): array { /** @var array $result */ $result = []; foreach (get_object_vars($this) as $name => $value) { if (\is_float($value) || \is_string($value) || $value === null) { $result[(string) $name] = $value; } } return $result; } /** * {@inheritDoc} */ public function humanReadableValues(): array { $values = $this->toArray(); $out = []; foreach (static::fieldLabels() as $property => $label) { $out[$label] = $values[$property] ?? null; } return $out; } /** * {@inheritDoc} */ public static function units(): array { return static::fieldUnits(); } /** * {@inheritDoc} */ public static function humanReadableUnits(): array { $out = []; foreach (static::fieldLabels() as $property => $label) { $units = static::fieldUnits(); if (\array_key_exists($property, $units)) { $out[$label] = $units[$property]; } } return $out; } /** * {@inheritDoc} * * @return array */ public function jsonSerialize(): array { return array_filter( $this->toArray(), static fn (mixed $value): bool => $value !== null, ); } /** * {@inheritDoc} */ public function __toString(): string { $values = $this->humanReadableValues(); $units = static::humanReadableUnits(); $lines = []; foreach ($values as $label => $value) { $unit = $units[$label] ?? null; $lines[] = $label . ' : ' . $value . ($unit !== null ? ' ' . $unit : ''); } return \implode("\n", $lines); } }