Benutzer: Gast
Eintrag: Extbase PropertyMapper float Komma-Notierung

Extbase PropertyMapper float Komma-Notierung

von: marcel
Tags: Typo3, Extbase
Kreise: Typo3

Problem:

Im DomainModel notiert man bei den Properties den Typ – z.B. ‘float’.
Auf einer deutschen Webseite ist der Benutzer gewöhnt Komma als Dezimal-Trennzeichen zu verwenden. Der PropertyMapper von Typo3 kann mit einem Komma aber nicht umgehen. Beim Typ Float wird einfach nur auf nummerisch getestet und es führt zu einer Fehlermeldung. Die Lokalisierung wird nicht berücksichtigt.

Lösung

Man verwendet einen eigenen Typ-Konverter für Float. (hier quick and dirty, da ich es nur für eine Webseite benötige, die es nur in deutsch geben wird.)
Soweit ich weiß hat FLOW eine Lokalisierung implementiert, die eventuell portiert werden könnte?

Controller

Code: PHP
<?php
namespace COMPANY\MyExtension\Controller;

class MyController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {	
	/**
	 * @return void
	 */
	public function initializeAction() {
		if (isset( $this->arguments['myModel'] )) {			
			// use own converter for float to convert the german comma-notation to english point-notation
			$this->arguments["myModel"]->getPropertyMappingConfiguration()
				->forProperty( 'myFloatProperty' )
				->setTypeConverter( $this->objectManager->get( 'COMPANY\\MyExtension\\TypeConverter\\FloatConverter' ) );
		}
	}
}

FloatConverter

Code: TypoScript (TS)
<?php
namespace COMPANY\MyExtension\TypeConverter;

class FloatConverter extends \TYPO3\CMS\Extbase\Property\TypeConverter\FloatConverter {
	/**
	 * Actually convert from $source to $targetType, by doing a typecast.
	 *
	 * @param mixed $source
	 * @param string $targetType
	 * @param array $convertedChildProperties
	 * @param \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration
	 * @return float|\TYPO3\CMS\Extbase\Error\Error
	 * @api
	 */
	public function convertFrom($source, $targetType, array $convertedChildProperties = array(), \TYPO3\CMS\Extbase\Property\PropertyMappingConfigurationInterface $configuration = NULL) {
		if ($source === NULL || strlen($source) === 0) {
			return NULL;
		}
		
		$posComma = strpos( $source, "," );
		$posPoint = strpos( $source, "." );
		
		if ($posComma === FALSE && $posPoint === FALSE) { // should be an integer
			//$source = $source;
		} else if ($posComma !== FALSE && $posPoint === FALSE) { // there is a comma. Let us define this is a german value with decimals
			$source = str_replace( ",", ".", $source ); // transform to english notation
		} else if ($posComma === FALSE && $posPoint !== FALSE) { // there is a point. Let us define this is an english value with decimals
			//$source = $source;
		} else {
			// at this point we have a comma and a point.
			// Let us try to find out if it is 0.000,00 or 0,000.00
			if ($posComma < $posPoint) { // 0,000.00
				// we need no comma
				$source = str_replace( ",", "", $source );
			} else { // 0.000,00
				// remove the . and replace , with .
				$source = str_replace( ".", "", $source );
				$source = str_replace( ",", ".", $source );
			}
		}
		
		if (!is_numeric($source)) {
			return new \TYPO3\CMS\Extbase\Error\Error('"%s" cannot be converted to a float value.', 1332934124, array($source));
		}
		return (float) $source;
	}
}

Property im deutschen Formular

Code: XML XHTML XSLT HTML
<f:form.textfield property="myFloatProperty" value="{myModel.myFloatProperty -> f:format.number(decimals:2, decimalSeparator:',', thousandsSeparator:'')}"  />
(1) Sebastian Christoph schrieb am 11. 5. 2017 um 11:22 Uhr
Danke für diesen Tip, funktioniert.
Allerdings ein kleiner Hinweis: Es gibt evt. das Problem, dass die "priority" beim neuen Float Converter gleich ist, wie bei dem bereits vorhandenen. Dann bekommt man eine Typo3 Fehlermeldung, dass dies so ist.
Um das zu verhindern, sollte man in der Class FloatConverter noch folgendes angeben:

protected $priority = 101;

Damit ist das Problem aus der Welt.