Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
TYPO3 Format NumberViewHelper with automatic config

Number ViewHelper for TYPO3 with automatic configuration

Description: This ViewHelper uses the given locale in the site configuration

Requirements

  • TYPO3 >= v9
  • Configured site management
  • PHP module intl

Additional flag

removeDecimalsIfIntegerValue

  • If set, it removes the decimals when the value is a number without decimal values
<?php
namespace Vendor\ExtensionName\ViewHelpers\Format;
use TYPO3\CMS\Core\Context\Context;
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3Fluid\Fluid\Core\Rendering\RenderingContextInterface;
class NumberViewHelper extends \TYPO3\CMS\Fluid\ViewHelpers\Format\NumberViewHelper
{
public function initializeArguments()
{
parent::initializeArguments();
$this->registerArgument('removeDecimalsIfIntegerValue', 'bool', 'Remove decimals if number is an integer value', false, false);
}
/**
* Format the numeric value as a number with grouped thousands, decimal point and
* precision.
*
* @param array $arguments
* @param \Closure $renderChildrenClosure
* @param RenderingContextInterface $renderingContext
*
* @return string The formatted number
*/
public static function renderStatic(
array $arguments,
\Closure $renderChildrenClosure,
RenderingContextInterface $renderingContext
) {
$decimals = $arguments['decimals'];
$decimalSeparator = $arguments['decimalSeparator'];
$thousandsSeparator = $arguments['thousandsSeparator'];
$stringToFormat = $renderChildrenClosure();
$site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByIdentifier('identifier');
if ($site) {
$languageId = GeneralUtility::makeInstance(Context::class)->getAspect('language')->getId();
$numberFormatter = new \NumberFormatter(
$site->getLanguageById($languageId)->getLocale(),
\NumberFormatter::DECIMAL
);
$decimalSeparator = $numberFormatter->getSymbol(\NumberFormatter::DECIMAL_SEPARATOR_SYMBOL);
$thousandsSeparator = $numberFormatter->getSymbol(\NumberFormatter::GROUPING_SEPARATOR_SYMBOL);
}
if ($arguments['removeDecimalsIfIntegerValue'] && self::isNotFloatNumber($stringToFormat)) {
$decimals = 0;
}
return number_format((float)$stringToFormat, $decimals, $decimalSeparator, $thousandsSeparator);
}
private static function isNotFloatNumber($number): bool
{
return (float)$number == (int)$number;
}
}
@mbrodala
Copy link

mbrodala commented Jun 15, 2021

You are missing a backup and restore of the locale here, currently this viewhelper is not side-effect free due to this.

Also maybe this could be achieved with NumberFormatter instead which would allow retrieving the info without temporary locale switch.

@spoonerWeb
Copy link
Author

spoonerWeb commented Jun 15, 2021

You are missing a backup and restore of the locale here, currently this viewhelper is not side-effect free due to this.

Also maybe this could be achieved with NumberFormatter instead which would allow retrieving the info without temporary locale switch.

Thanks for this hint. Changed it to use NumberFormatter.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment