siFormatter = $siFormatter; } protected function configureOptions(OptionsResolver $resolver) { $resolver->setDefaults([ 'show_prefix' => function (Options $options) { if ($options['measurement_unit'] !== null) { /** @var MeasurementUnit $unit */ $unit = $options['measurement_unit']; return $unit->isUseSIPrefix(); } return true; }, 'is_integer' => function (Options $options) { if ($options['measurement_unit'] !== null) { /** @var MeasurementUnit $unit */ $unit = $options['measurement_unit']; return $unit->isInteger(); } return true; }, 'unit' => function (Options $options) { if ($options['measurement_unit'] !== null) { /** @var MeasurementUnit $unit */ $unit = $options['measurement_unit']; return $unit->getUnit(); } return ''; }, 'decimals' => 2, 'error_mapping' => [ '.' => 'value'] ]); $resolver->setAllowedTypes('decimals', 'int'); $resolver->setNormalizer('decimals', function (Options $options, $value) { // If the unit is integer based, then dont show any decimals if ($options['is_integer']) { return 0; } return $value; }); } /** * Formats the given value using the measurement unit and options. * @param $value float|int The value that should be formatted. Must be numeric. * @param MeasurementUnit|null $unit The measurement unit, whose unit symbol should be used for formatting. * If set to null, it is assumed that the part amount is measured in pieces. * @param array $options * @return string The formatted string * @throws \InvalidArgumentException Thrown if $value is not numeric. */ public function format($value, ?MeasurementUnit $unit = null, array $options = []) { if (!is_numeric($value)) { throw new \InvalidArgumentException('$value must be an numeric value!'); } $value = (float) $value; //Find out what options to use $resolver = new OptionsResolver(); $resolver->setDefault('measurement_unit', $unit); $this->configureOptions($resolver); $options = $resolver->resolve($options); if ($options['is_integer']) { $value = round($value); } //If the measurement unit uses a SI prefix format it that way. if ($options['show_prefix']) { return $this->siFormatter->format($value, $options['unit'], $options['decimals']); } //Otherwise just output it $format_string = '%.' . $options['decimals'] . 'f ' . $options['unit']; return sprintf($format_string, $value); } }