2010-09-27 15:53:23 +01:00
< ? php
/*
2011-01-15 13:29:43 +00:00
* This file is part of the Symfony package .
2010-09-27 15:53:23 +01:00
*
2011-03-06 11:40:06 +00:00
* ( c ) Fabien Potencier < fabien @ symfony . com >
2010-09-27 15:53:23 +01:00
*
2011-01-15 13:29:43 +00:00
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
2010-09-27 15:53:23 +01:00
*/
2011-01-15 13:29:43 +00:00
namespace Symfony\Component\Translation ;
2010-09-27 15:53:23 +01:00
/**
* MessageSelector .
*
2011-03-06 11:40:06 +00:00
* @ author Fabien Potencier < fabien @ symfony . com >
2013-08-23 16:24:14 +01:00
* @ author Bernhard Schussek < bschussek @ gmail . com >
2010-09-27 15:53:23 +01:00
*/
class MessageSelector
{
2011-01-09 19:01:49 +00:00
/**
* Given a message with different plural translations separated by a
* pipe ( | ), this method returns the correct portion of the message based
* on the given number , locale and the pluralization rules in the message
* itself .
*
* The message supports two different types of pluralization rules :
*
2011-11-12 08:26:35 +00:00
* interval : { 0 } There are no apples | { 1 } There is one apple | ] 1 , Inf ] There are % count % apples
2012-07-15 08:21:44 +01:00
* indexed : There is one apple | There are % count % apples
2011-01-09 19:01:49 +00:00
*
* The indexed solution can also contain labels ( e . g . one : There is one apple ) .
* This is purely for making the translations more clear - it does not
* affect the functionality .
*
* The two methods can also be mixed :
2011-11-12 08:26:35 +00:00
* { 0 } There are no apples | one : There is one apple | more : There are % count % apples
2011-01-09 19:01:49 +00:00
*
2014-11-30 13:33:44 +00:00
* @ param string $message The message being translated
* @ param int $number The number of items represented for the message
* @ param string $locale The locale to use for choosing
2011-12-13 07:50:54 +00:00
*
2011-01-09 19:01:49 +00:00
* @ return string
2011-03-24 08:07:52 +00:00
*
2012-10-04 16:11:30 +01:00
* @ throws \InvalidArgumentException
2011-01-09 19:01:49 +00:00
*/
2010-09-27 15:53:23 +01:00
public function choose ( $message , $number , $locale )
{
$parts = explode ( '|' , $message );
$explicitRules = array ();
$standardRules = array ();
foreach ( $parts as $part ) {
$part = trim ( $part );
2015-06-06 17:39:32 +01:00
if ( preg_match ( '/^(?P<interval>' . Interval :: getIntervalRegexp () . ')\s*(?P<message>.*?)$/xs' , $part , $matches )) {
2010-09-28 06:14:43 +01:00
$explicitRules [ $matches [ 'interval' ]] = $matches [ 'message' ];
2011-09-14 21:04:39 +01:00
} elseif ( preg_match ( '/^\w+\:\s*(.*?)$/' , $part , $matches )) {
2010-09-27 15:53:23 +01:00
$standardRules [] = $matches [ 1 ];
} else {
$standardRules [] = $part ;
}
}
// try to match an explicit rule, then fallback to the standard ones
2010-09-28 06:14:43 +01:00
foreach ( $explicitRules as $interval => $m ) {
if ( Interval :: test ( $number , $interval )) {
2010-09-27 15:53:23 +01:00
return $m ;
}
}
$position = PluralizationRules :: get ( $number , $locale );
2013-08-23 16:24:14 +01:00
2010-09-27 15:53:23 +01:00
if ( ! isset ( $standardRules [ $position ])) {
2013-08-23 16:24:14 +01:00
// when there's exactly one rule given, and that rule is a standard
// rule, use this rule
if ( 1 === count ( $parts ) && isset ( $standardRules [ 0 ])) {
return $standardRules [ 0 ];
}
2014-05-14 14:24:58 +01:00
throw new \InvalidArgumentException ( sprintf ( 'Unable to choose a translation for "%s" with locale "%s" for value "%d". Double check that this translation has the correct plural options (e.g. "There is one apple|There are %%count%% apples").' , $message , $locale , $number ));
2010-09-27 15:53:23 +01:00
}
return $standardRules [ $position ];
}
}