Issues

ZF-5610: Solution to fetching/saving localized Float values using Zend_Db

Description

Need solution to fetching/saving Float values using Zend_Db on locale-aware sites.

Currently, I have to perform transformations:


$row; // Zend_Db_Table_Row

$value = '0,6'; // Localized float value (eg from Form)
$formatOptions = array(
    'locale' => Zend_Registry::get('Zend_Locale')
);
$row->value = Zend_Locale_Format::getFloat($value, $formatOptions);

$row; // Zend_Db_Table_Row

$formatOptions = array(
    'locale' => new Zend_Locale('en_US') // locale of MySQL floats
);
$value = Zend_Locale_Format::getFloat($row->value, $formatOptions);

instead of simple:


$row; // Zend_Db_Table_Row

$value = '0,6'; // Localized float value (eg from Form)
$row->value = $value

$row; // Zend_Db_Table_Row

$value = $row->value;

Comments

This is not a issue of Zend_Locale... erased component relation

This is definitly the wrong place for float conversion.

Within the database as also within the code you should ALWAYS work and use the standard float representation.

ONLY when you have to DISPLAY or INPUT/OUTPUT the value to the user you must localize it.

Right, but ... When fetching float values from Db, they receive in the string representation (eg "0.6") before populating their to form need to perform each float value floatval(), otherwise they will be printed in the presentation of the database


...
setlocale(LC_ALL, 'un_US.UTF-8');
$locale = new Zend_Locale(Zend_Locale::BROWSER);
Zend_Registry::set('Zend_Locale', $locale);
...

$row; // Zend_Db_Table_Row

$floatCols = array('compression', 'piston_stroke'); // float cols (from metadata)

$form; // Zend_Form

$data = $row->toArray();

$formatOptions = array(
    'locale' => Zend_Registry::get('Zend_Locale')
);
foreach ($floatCols as $key)
    if (isset($data[$key]))
        $data[$key] = Zend_Locale_Format::toFloat($data[$key], $formatOptions);

$form->populate($data);

and when fetching data from Form i'am forced to perform transformation


$row; // Zend_Db_Table_Row

$floatCols = array('compression', 'piston_stroke'); // float cols (from metadata)

$form; // Zend_Form

$values = $form->getValues();

foreach ($floatCols as $floatCol)
{
    $value = $values[$floatCol];
    $values[$floatCol] = strlen($value) ? Zend_Locale_Format::getFloat($value) : null;
}

$row->setFromArray($values);

Too difficult for the standard tasks on the locale-aware sites

Sorry, populate block code bad ... this is right


$row; // Zend_Db_Table_Row

$floatCols = array('compression', 'piston_stroke'); // float cols (from metadata)

$form; // Zend_Form

$data = $row->toArray();

foreach ($floatCols as $key)
    if (isset($data[$key]))
        $data[$key] = floatval($data[$key]);

$form->populate($data);

Yes, this is NOT an issue of Zend_Locale and should NOT become one.

What is needed here are INPUT and OUTPUT filters for Zend_Form_Element. I wonder why there isn't anything like that in Zend already.

$element->addInputFilter('toLocaleFloat'); $element->addOutputFilter('toRealFloat');

Further we should have $element->populate($value) which calls the InputFilter chain and something like $element->getValue() which applies the OutputFilter chain.

I'm going to add something like that in the next few days as I'm really in need of such a feature for a lot of fields (dates, currency values). If you're interested, just drop me a line. Maybe I'm also writing a proposal...

Regards, Maurice

I definitely would NOT want to see any such feature near Zend_Db. If I want to insert a value '0,03' I expect my rdbms to receive the value '0,03' and not 0.03 .

Same goes for retrieving values; if I have the value '0.03' in my Db, I expect to receive the value 0.03, and not '0,03'. What happens if I want to do some calculations with the floats zend_db returned? Kinda unhandy if they contain comma's.

@Moritz Zend_Form already has the getValues() method, which you can use to apply such a filter.

Just one note: There is a Zend_Filter_LocalizedToNormalizes which can also convert localized float values to normalized ones and another filter for the reverse conversion.

And filters can be applied to Zend_Form elements as also be used standalone.

In my opinion this issue can be closed as not an issue.

I'm closing this issue as not-an-issue as the general consensus (here, and on IRC) seems to be that it is definitely not something to be done within Zend_Db, and that such functionality is already provided in places where it's much better located.