示例#1
0
 /**
  * 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
  */
 public function choose($message, $number, $locale)
 {
     preg_match_all('/(?:\\|\\||[^\\|])++/', $message, $parts);
     $explicitRules = array();
     $standardRules = array();
     foreach ($parts[0] as $part) {
         $part = trim(str_replace('||', '|', $part));
         if (preg_match('/^(?P<interval>' . Interval::getIntervalRegexp() . ')\\s*(?P<message>.*?)$/xs', $part, $matches)) {
             $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[0]) && 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];
 }
 /**
  * Checks if translation is valid.
  *
  * @param string $message Message to check.
  * @param string $locale  Locale used for.
  *
  * @return bool
  */
 public static function check($message, $locale)
 {
     $parts = explode('|', $message);
     $explicitRules = [];
     $standardRules = [];
     foreach ($parts as $part) {
         $part = trim($part);
         if (preg_match('/^(?P<interval>' . Interval::getIntervalRegexp() . ')\\s*(?P<message> . *?)$/x', $part, $matches)) {
             $explicitRules[$matches['interval']] = $matches['message'];
         } elseif (preg_match('/^\\w+\\:\\s*(.*?)$/', $part, $matches)) {
             $standardRules[] = $matches[1];
         } else {
             $standardRules[] = $part;
         }
     }
     if (count($parts) !== 1 && count($parts) !== count($explicitRules)) {
         for ($count = 0; $count < 200; $count++) {
             $position = PluralizationRules::get($count, $locale);
             if (!isset($standardRules[$position])) {
                 return false;
             }
         }
     }
     return true;
 }
示例#3
0
 protected function generateTestData($plural, $langCodes)
 {
     $matrix = array();
     foreach ($langCodes as $langCode) {
         for ($count = 0; $count < 200; ++$count) {
             $plural = PluralizationRules::get($count, $langCode);
             $matrix[$langCode][$count] = $plural;
         }
     }
     return $matrix;
 }
示例#4
0
 private function getPlurals($locale, $count)
 {
     $numbers = array_fill(0, $count, NULL);
     $n = 1;
     do {
         $plural = \Symfony\Component\Translation\PluralizationRules::get($n, $locale);
         if (!isset($numbers[$plural])) {
             $numbers[$plural] = $n;
         }
         $n++;
         if ($n > 10000) {
             break;
         }
     } while (!$this->arrayFilled($numbers));
     return $numbers;
 }