php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Request #61871 Named Argument support for MessageFormatter
Submitted: 2012-04-27 19:03 UTC Modified: 2013-02-06 21:06 UTC
From: web-php-bugs at sklar dot com Assigned: cataphract
Status: Closed Package: intl (PECL)
PHP Version: 5.3.11 OS:
Private report: No CVE-ID:
 [2012-04-27 19:03 UTC] web-php-bugs at sklar dot com
Description:
------------
Attached is a patch to add named argument support to MessageFormatter message formatting.

With this patch, you can pass an associative array of named arguments and they are interpolated into your messages. The type of the values in the associative array determine how they are parsed for formatting. Floats, longs, and strings are converted as you would expect (floats, longs, strings). Bool is turned into an int64 (0 or 1). Null is turned into the empty string. Objects and arrays are errors, except a DateTime object is turned into a date for formatting.


Test script:
---------------
$pattern = <<<_MSG_
{gender_of_host, select,
  female {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to her party.}
      =2 {{host} invites {guest} and one other person to her party.}
     other {{host} invites {guest} and # other people to her party.}}}
  male {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to his party.}
      =2 {{host} invites {guest} and one other person to his party.}
     other {{host} invites {guest} and # other people to his party.}}}
  other {{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to their party.}
      =2 {{host} invites {guest} and one other person to their party.}
      other {{host} invites {guest} and # other people to their party.}}}}
_MSG_;

$m = msgfmt_format_message('en_US', $pattern, array('gender_of_host' => 'male',
                                                                           'num_guests' => 4,
                                                                           'host' => 'ralph', 'guest' => 'beep'));
print "$m\n";

             $m = msgfmt_format_message('en_US', $pattern, array('gender_of_host' => 'female',                                                                            'num_guests' => 4));
print "$m\n";



Patches

intl-named-arguments-2.diff (last revision 2012-05-03 18:06 UTC) by web-php-bugs at sklar dot com)
intl-named-arguments (last revision 2012-04-27 19:03 UTC) by web-php-bugs at sklar dot com)

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2012-04-30 14:55 UTC] cataphract@php.net
-Assigned To: +Assigned To: cataphract
 [2012-04-30 20:41 UTC] cataphract@php.net
The only thing I don't like here is different path for converting PHP arguments to Formattables. I understand there's no interface to fetch the types in the pattern for the named arguments, but technically, there's no public way to do it for numeric arguments and we have to resort to reading private state of MessageFormat. Given that we already to such a thing, we might as well got the same path for named arguments.
 [2012-04-30 20:46 UTC] web-php-bugs at sklar dot com
Yeah, I'm not in love with the different way to convert the args to Formattables either, to be honest.

I looked down the path of trying to do it how the numbered-argument code does but internally, libicu does not populate the argTypes array for named arguments, so that information isn't even available.

I suppose one other possible path would be to use the (public) getFormats() method and then make some decisions based on the classes of the Format objects.
 [2012-04-30 21:16 UTC] cataphract@php.net
Yes, but MessageFormatAdapter is a friend class. We can add methods to MessageFormatAdapter declared in msgformat_helpers.cpp to access whatever we want from MessageFormat.
 [2012-05-03 18:09 UTC] web-php-bugs at sklar dot com
I've attached a new patch that makes use of the MessageFormat's internal MessagePattern to attempt to deduce the right types for each argument -- for both named and numbered arguments, to keep things consistent.

There are some new tests to verify named argument behavior as well as subpatterns (for both named and numbered arguments), which was the reason I started investigating this in the first place.

I've only tested this with icu 4.8 and 4.9, though. http://icu-project.org/apiref/icu4c/classMessagePattern.html says that MessagePattern is stable as of 4.8, so I am not sure how this will behave with older versions of ICU.
 [2012-05-04 07:13 UTC] cataphract@php.net
Thanks! I'll see if I can get this closed this weekend.
 [2012-05-06 23:23 UTC] cataphract@php.net
I made some changes on top of your patch:

https://github.com/cataphract/php-src/compare/fr61871

I still haven't tested this in old versions of ICU.
 [2012-05-13 20:46 UTC] cataphract@php.net
-Status: Assigned +Status: Closed
 [2012-05-13 20:46 UTC] cataphract@php.net
This bug has been fixed in SVN.

Snapshots of the sources are packaged every three hours; this change
will be in the next snapshot. You can grab the snapshot at
http://snaps.php.net/.

 For Windows:

http://windows.php.net/snapshots/
 
Thank you for the report, and for helping us make PHP better.


 [2013-02-06 20:52 UTC] messyo at yahoo dot de
Is it possible this issue still affects php 5.4?

I'm occuring the mentioned behavior and started browsing the source-code (github and also downloaded a snapshot-tarball) in which I could not find any hint for this (imho important) feature to be integrated.
 [2013-02-06 21:06 UTC] cataphract@php.net
We don't generally add features to patch releases. It will only be in 5.5. If you need the feature in 5.2/5.3/5.4, you install intl 3.x from PECL (pecl install intl-beta).
 [2013-02-06 21:39 UTC] messyo at yahoo dot de
Thank you very much for your really fast and helpful answer :)
 [2013-09-10 10:50 UTC] enigma dot org at gmx dot net
Unfortunately this function still does not work completely as it should, 
as the following example shows:

$pattern = <<<_MSG_
{num_guests} -- 
{num_guests, plural, offset:1
      =0 {{host} does not give a party.}
      =1 {{host} invites {guest} to her party.}
      =2 {{host} invites {guest} and one other person to her party.}
     other {{host} invites {guest} and # other people to her party.}}
_MSG_;



$a = array('gender_of_host' => 'male', 'num_guests' => 4, 'host' => 'ralph', 
'guest' => 'beep');

$m = msgfmt_format_message('en_US', $pattern, $a);
print "$m\n";


$a['gender_of_host'] = 'female';
$a['num_guests'] = 49;

$m = msgfmt_format_message('en_US', $pattern, $a);
print "$m\n";
 
PHP Copyright © 2001-2014 The PHP Group
All rights reserved.
Last updated: Thu Apr 24 19:01:53 2014 UTC