2015-08-18 00:00:26 +00:00
< ? php
/*
* This file is part of the Symfony package .
*
* ( c ) Fabien Potencier < fabien @ symfony . com >
*
* For the full copyright and license information , please view the LICENSE
* file that was distributed with this source code .
*/
namespace Symfony\Component\Translation ;
/**
* MessageSelector .
*
* @ author Fabien Potencier < fabien @ symfony . com >
* @ author Bernhard Schussek < bschussek @ gmail . com >
*
* @ api
*/
class MessageSelector
{
/**
* 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 :
*
* interval : { 0 } There are no apples | { 1 } There is one apple | ] 1 , Inf ] There are % count % apples
* indexed : There is one apple | There are % count % apples
*
* 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 :
* { 0 } There are no apples | one : There is one apple | more : There are % count % apples
*
* @ 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
*
* @ return string
*
* @ throws \InvalidArgumentException
*
* @ api
*/
public function choose ( $message , $number , $locale )
{
$parts = explode ( '|' , $message );
$explicitRules = array ();
$standardRules = array ();
foreach ( $parts as $part ) {
$part = trim ( $part );
2015-08-27 19:03:05 +00:00
if ( preg_match ( '/^(?P<interval>' . Interval :: getIntervalRegexp () . ')\s*(?P<message>.*?)$/xs' , $part , $matches )) {
2015-08-18 00:00:26 +00:00
$explicitRules [ $matches [ 'interval' ]] = $matches [ 'message' ];
} elseif ( preg_match ( '/^\w+\:\s*(.*?)$/' , $part , $matches )) {
$standardRules [] = $matches [ 1 ];
} else {
$standardRules [] = $part ;
}
}
// try to match an explicit rule, then fallback to the standard ones
foreach ( $explicitRules as $interval => $m ) {
if ( Interval :: test ( $number , $interval )) {
return $m ;
}
}
$position = PluralizationRules :: get ( $number , $locale );
if ( ! isset ( $standardRules [ $position ])) {
// 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 ];
}
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 ));
}
return $standardRules [ $position ];
}
}