Friday
17
April
2009

Localizing and Normalizing with Zend_Filter

Sometimes you have to work with user-provided numbers or dates.
The problem with this data is, that when your users are using different locales, then you will have to normalize and localize the provided data to be able to work with them.

In past you had to convert the data manually or by using Zend_Locale.

$values = $form->getValues();
	
$values['firstnumber'] = Zend_Locale::getInteger($values['number']);
$values['secondnumber'] = Zend_Locale::getInteger($values['number']);

With Zend Framework 1.8 I added a filter which does this for you. Simply add the filter to your form

$element = new Zend_Form_Element_Text('firstnumber');
$element->addFilter('LocalizedToNormalized');

This filter can handle
* Numbers like Integer, Float, Real
* Dates
* Times

Numbers will be returned as string in the english/computer notation.
Dates and Times will be returned as array where every date part is seperated to a own key.

The german number 12.345,67
would become 12345.67

This comes handy, for example, when you want to store the provided data within a database because you should always use a normalized representation when you work with multiple locales.

Of course I added also a filter which does the reverse task… to localize a normalized value.

Let’s expect we have a normalized value from a internal source. To display it in a localized manner simply use Zend_Filter_NormalizedToLocalized.

$filter = new Zend_Filter_NormalizedToLocalized();
$date = array(
    'day' => 3,
    'month' => 10,
    'year' => 2009
);
	
print $filter->filter($date);

The benefits of this components are, that they can be used within every other component which allows the usage of filters. And both detect the type of the given value automatically. Of course this filter provides als several parameters which enables you to tweak what the components return. For details about the parameters take a look into the manual.

I hope you find them usefull.

Greetings
Thomas Weidner
I18N Team Leader, Zend Framework

Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework

Back to top
  1. Piotr Czachur

    Friday, May 8, 2009 - 18:00:27

    Thomas,
    I’m very happy I’ve found this blog :-)

    Using LocalizedToNormalized filter on a form field has one disadvantage: if user submits form with localized value and form doesn’t validate, *filtered* value will be displayed back to the user. He can be confused, why “1,99” has changed to “1.99”.
    Is there easy way to display back to user nonfiltered values, and get filtered only from $element->getValue() ?

  2. thomasw

    Friday, May 8, 2009 - 19:34:06

    Actually getValue() is called also internally when the element is rendered. So there is no way to differ between them.

    The only way I could think of, when you still want to filter the value is:

    * Localize the filtered value again when the validation has failed

    * Or if you can check the localized value (not all validators support actually localization) then attach the normalize filter after the validation has passed

  3. Piotr Czachur

    Monday, May 11, 2009 - 13:45:35

    LocalizedToNormalized filter on Float input causes it to be always invalid, bacause normalized version is passed to isValid() which accepts only localized format.
    I’ll wait for other validators to have localization support.

    (btw is magic_quotes_gpc on on this server?)

  4. thomasw

    Monday, May 11, 2009 - 23:06:58

    Of course… when your environment is also set to a locale (most are not because they are set to english) then normalization alone would not work. You need to change from one locale to another locale, and not from locale to english.

  5. Andreas

    Friday, June 26, 2009 - 13:29:43

    Hi Thomas,

    LocalizedToNormalized as a filter on a form element is working 1,2 is stored as 1.2 in the database.

    But what is with the way from database to form.
    If I load a 1.2 into the form, the element displays 12.

    What do I wrong, or what must I do

  6. thomasw

    Friday, June 26, 2009 - 13:35:43

    Look at NormalizedToLocalized for filtering the other direction.

  7. Andreas

    Friday, June 26, 2009 - 14:19:26

    Hello Thomas,

    first of all, I know that is a private blog and not a discussion forum. But I failed to find an answer. Where I have to look?

    Second, I know NormalizedToLocalized.

    Third, my problem

    In my first attempt I believe if the user type 1,2 into the form then I get with filter 1.2, to store it in the database (that works). I if I put a 1.2 into the form via form->populate it shows 1,2. But this does not work, it shows 12.

    Therefor I uses NormalizedToLocalized to localize my database data. Then I populate(1,2) and in the form zend shows 1.2 and not 1,2.

    No I am very confused. Thanks for your help.

    By the way, zend is very powerfull and if all question are answered the solutions are short and simple. But the track to the right solutions can be long and painfull.

  8. thomasw

    Friday, June 26, 2009 - 14:31:34

    You can find help at one of the following locations:

    IRC: #zftalk
    Mailinglist: fw-general@lists.zend.com
    FAQ: framework.zend.com/wiki/display/ZFFAQ
    Manual: framework.zend.com/manual/en
    Issues: framework.zend.com/issues

  9. ethylotests

    Monday, April 16, 2012 - 03:57:26

    yeah, i think you are right !
    ethylotest are important and alcootest too !