Beispiel #1
0
 /**
  * Given an array of strings, a number and, if wanted, an optional locale (the default one is used
  * otherwise), this picks the right string according to plural rules of the locale
  *
  * @param  array|string $strings
  * @param  int          $number
  * @throws Exception\InvalidArgumentException
  * @return string
  */
 public function __invoke($strings, $number)
 {
     if ($this->rule === null) {
         throw new Exception\InvalidArgumentException(sprintf('No plural rule was set'));
     }
     if (!is_array($strings)) {
         $strings = (array) $strings;
     }
     $pluralIndex = $this->rule->evaluate($number);
     return $strings[$pluralIndex];
 }
Beispiel #2
0
 /**
  * load(): defined by FileLoaderInterface.
  *
  * @see    FileLoaderInterface::load()
  * @param  string $locale
  * @param  string $filename
  * @return TextDomain|null
  * @throws Exception\InvalidArgumentException
  */
 public function load($locale, $filename)
 {
     $resolvedIncludePath = stream_resolve_include_path($filename);
     $fromIncludePath = $resolvedIncludePath !== false ? $resolvedIncludePath : $filename;
     if (!$fromIncludePath || !is_file($fromIncludePath) || !is_readable($fromIncludePath)) {
         throw new Exception\InvalidArgumentException(sprintf('Could not find or open file %s for reading', $filename));
     }
     $messages = [];
     $iniReader = new IniReader();
     $messagesNamespaced = $iniReader->fromFile($fromIncludePath);
     $list = $messagesNamespaced;
     if (isset($messagesNamespaced['translation'])) {
         $list = $messagesNamespaced['translation'];
     }
     foreach ($list as $message) {
         if (!is_array($message) || count($message) < 2) {
             throw new Exception\InvalidArgumentException('Each INI row must be an array with message and translation');
         }
         if (isset($message['message']) && isset($message['translation'])) {
             $messages[$message['message']] = $message['translation'];
             continue;
         }
         $messages[array_shift($message)] = array_shift($message);
     }
     if (!is_array($messages)) {
         throw new Exception\InvalidArgumentException(sprintf('Expected an array, but received %s', gettype($messages)));
     }
     $textDomain = new TextDomain($messages);
     if (array_key_exists('plural', $messagesNamespaced) && isset($messagesNamespaced['plural']['plural_forms'])) {
         $textDomain->setPluralRule(PluralRule::fromString($messagesNamespaced['plural']['plural_forms']));
     }
     return $textDomain;
 }
Beispiel #3
0
 /**
  * Get the plural rule.
  *
  * Lazy loads a default rule if none already registered
  *
  * @return PluralRule
  */
 public function getPluralRule()
 {
     if ($this->pluralRule === null) {
         $this->setPluralRule(PluralRule::fromString('nplurals=2; plural=n != 1;'));
     }
     return $this->pluralRule;
 }
Beispiel #4
0
 /**
  * @dataProvider completeRuleProvider
  */
 public function testCompleteRules($rule, $expectedValues)
 {
     $rule = Rule::fromString('nplurals=9; plural=' . $rule);
     for ($i = 0; $i < 200; $i++) {
         $this->assertEquals((int) $expectedValues[$i], $rule->evaluate($i));
     }
 }
Beispiel #5
0
 /**
  * Returns a shared default plural rule.
  *
  * @return PluralRule
  */
 public static function getDefaultPluralRule()
 {
     if (static::$defaultPluralRule === null) {
         static::$defaultPluralRule = PluralRule::fromString('nplurals=2; plural=n != 1;');
     }
     return static::$defaultPluralRule;
 }
Beispiel #6
0
 /**
  * Set the plural rule to use
  *
  * @param  PluralRule|string $pluralRule
  * @return Plural
  */
 public function setPluralRule($pluralRule)
 {
     if (!$pluralRule instanceof PluralRule) {
         $pluralRule = PluralRule::fromString($pluralRule);
     }
     $this->rule = $pluralRule;
     return $this;
 }
Beispiel #7
0
 public function testMergingIncompatibleTextDomains()
 {
     $this->setExpectedException('Zend\\I18n\\Exception\\RuntimeException', 'is not compatible');
     $domainA = new TextDomain();
     $domainB = new TextDomain();
     $domainB->setPluralRule(PluralRule::fromString('nplurals=3; plural=n'));
     $domainA->merge($domainB);
 }
Beispiel #8
0
 public function testMergingTextDomainWithoutPluralRuleIntoTextDomainWithPluralRule()
 {
     $domainA = new TextDomain();
     $domainB = new TextDomain();
     $domainA->setPluralRule(PluralRule::fromString('nplurals=3; plural=n'));
     $domainA->merge($domainB);
     $this->assertEquals(3, $domainA->getPluralRule()->getNumPlurals());
     $this->assertFalse($domainB->hasPluralRule());
 }
Beispiel #9
0
 /**
  * Translate a plural message.
  *
  * @param  string                         $singular
  * @param  string                         $plural
  * @param  int                            $number
  * @param  string                         $textDomain
  * @param  string|null                    $locale
  * @return string
  * @throws Exception\OutOfBoundsException
  */
 public function translatePlural($singular, $plural, $number, $textDomain = 'default', $locale = null)
 {
     $locale = $locale ?: $this->getLocale();
     $translation = $this->getTranslatedMessage($singular, $locale, $textDomain);
     if ($translation === null || $translation === '') {
         if (null !== ($fallbackLocale = $this->getFallbackLocale()) && $locale !== $fallbackLocale) {
             return $this->translatePlural($singular, $plural, $number, $textDomain, $fallbackLocale);
         }
         return $number == 1 ? $singular : $plural;
     }
     $index = Rule::fromString('nplurals=3; nplural=(n%100>10&&n%100<20 ? 2 : (n%100%10>1&&n%100%10<5 ? 1 : (n%100%10==1 ? 0 : 2)))')->evaluate($number);
     if (!isset($translation[$index])) {
         throw new Exception\OutOfBoundsException(sprintf('Provided index %d does not exist in plural array', $index));
     }
     return $translation[$index];
 }
Beispiel #10
0
 /**
  * {@inheritdoc}
  */
 public function load($locale, $filename)
 {
     if (!is_file($filename) || !is_readable($filename)) {
         throw new Exception\InvalidArgumentException(sprintf('Could not open file %s for reading', $filename));
     }
     $messages = (include $filename);
     if (!is_array($messages)) {
         throw new Exception\InvalidArgumentException(sprintf('Expected an array, but received %s', gettype($messages)));
     }
     $textDomain = new TextDomain($messages);
     if (array_key_exists('', $textDomain)) {
         if (isset($textDomain['']['plural_forms'])) {
             $textDomain->setPluralRule(PluralRule::fromString($textDomain['']['plural_forms']));
         }
         unset($textDomain['']);
     }
     return $textDomain;
 }
Beispiel #11
0
 /**
  * Load translations from a remote source.
  *
  * @param  string $locale
  * @param  string $textDomain
  *
  * @throws \Zend\I18n\Exception\InvalidArgumentException
  * @return \Zend\I18n\Translator\TextDomain|null
  */
 public function load($locale, $textDomain)
 {
     if (!is_array($this->messages)) {
         throw new Exception\InvalidArgumentException(sprintf('Expected an array, but received %s', gettype($this->messages)));
     }
     if (!isset($this->messages[$textDomain])) {
         throw new Exception\InvalidArgumentException(sprintf('Expected textdomain "%s" to be an array, but it is not set', $textDomain));
     }
     if (!isset($this->messages[$textDomain][$locale])) {
         throw new Exception\InvalidArgumentException(sprintf('Expected locale "%s" to be an array, but it is not set', $locale));
     }
     $textDomain = new TextDomain($this->messages[$textDomain][$locale]);
     if (array_key_exists('', $textDomain)) {
         if (isset($textDomain['']['plural_forms'])) {
             $textDomain->setPluralRule(PluralRule::fromString($textDomain['']['plural_forms']));
         }
         unset($textDomain['']);
     }
     return $textDomain;
 }
Beispiel #12
0
 /**
  * load(): defined by FileLoaderInterface.
  *
  * @see    FileLoaderInterface::load()
  * @param  string $locale
  * @param  string $filename
  * @return TextDomain|null
  * @throws Exception\InvalidArgumentException
  */
 public function load($locale, $filename)
 {
     if (!is_file($filename) || !is_readable($filename)) {
         throw new Exception\InvalidArgumentException(sprintf('Could not open file %s for reading', $filename));
     }
     $messages = json_decode(file_get_contents($filename), true);
     if (!is_array($messages)) {
         if (ipConfig()->isDevelopmentEnvironment()) {
             throw new Exception\InvalidArgumentException(sprintf('Expected an array, but received %s', gettype($messages)));
         } else {
             return null;
         }
     }
     $textDomain = new TextDomain($messages);
     if (array_key_exists('', $textDomain)) {
         if (isset($textDomain['']['plural_forms'])) {
             $textDomain->setPluralRule(PluralRule::fromString($textDomain['']['plural_forms']));
         }
         unset($textDomain['']);
     }
     return $textDomain;
 }
Beispiel #13
0
 /**
  * load(): defined by LoaderInterface.
  *
  * @see    LoaderInterface::load()
  * @param  string $filename
  * @param  string $locale
  * @return TextDomain|null
  * @throws Exception\InvalidArgumentException
  */
 public function load($locale, $filename)
 {
     if (!is_file($filename) || !is_readable($filename)) {
         throw new Exception\InvalidArgumentException(sprintf('Could not open file %s for reading', $filename));
     }
     $messages = array();
     if (($handle = fopen($filename, "r")) !== false) {
         while (($cell = $this->fgetcsv($handle)) !== false) {
             if (!isset($cell[0])) {
                 continue;
             }
             $messages[strtolower($cell[0])] = isset($cell[1]) ? $cell[1] : '';
         }
         fclose($handle);
     }
     $textDomain = new TextDomain($messages);
     if (array_key_exists('', $textDomain)) {
         if (isset($textDomain['']['plural_forms'])) {
             $textDomain->setPluralRule(PluralRule::fromString($textDomain['']['plural_forms']));
         }
         unset($textDomain['']);
     }
     return $textDomain;
 }
Beispiel #14
0
 public function testPluralRuleSetter()
 {
     $domain = new TextDomain();
     $domain->setPluralRule(PluralRule::fromString('nplurals=3; plural=n'));
     $this->assertEquals(2, $domain->getPluralRule()->evaluate(2));
 }
Beispiel #15
0
 /**
  * load(): defined by FileLoaderInterface.
  *
  * @see    FileLoaderInterface::load()
  * @param  string $locale
  * @param  string $filename
  * @return TextDomain
  * @throws Exception\InvalidArgumentException
  */
 public function load($locale, $filename)
 {
     $resolvedFile = $this->resolveFile($filename);
     if (!$resolvedFile) {
         throw new Exception\InvalidArgumentException(sprintf('Could not find or open file %s for reading', $filename));
     }
     $textDomain = new TextDomain();
     ErrorHandler::start();
     $this->file = fopen($resolvedFile, 'rb');
     $error = ErrorHandler::stop();
     if (false === $this->file) {
         throw new Exception\InvalidArgumentException(sprintf('Could not open file %s for reading', $filename), 0, $error);
     }
     // Verify magic number
     $magic = fread($this->file, 4);
     if ($magic == "•Þ") {
         $this->littleEndian = false;
     } elseif ($magic == "Þ•") {
         $this->littleEndian = true;
     } else {
         fclose($this->file);
         throw new Exception\InvalidArgumentException(sprintf('%s is not a valid gettext file', $filename));
     }
     // Verify major revision (only 0 and 1 supported)
     $majorRevision = $this->readInteger() >> 16;
     if ($majorRevision !== 0 && $majorRevision !== 1) {
         fclose($this->file);
         throw new Exception\InvalidArgumentException(sprintf('%s has an unknown major revision', $filename));
     }
     // Gather main information
     $numStrings = $this->readInteger();
     $originalStringTableOffset = $this->readInteger();
     $translationStringTableOffset = $this->readInteger();
     // Usually there follow size and offset of the hash table, but we have
     // no need for it, so we skip them.
     fseek($this->file, $originalStringTableOffset);
     $originalStringTable = $this->readIntegerList(2 * $numStrings);
     fseek($this->file, $translationStringTableOffset);
     $translationStringTable = $this->readIntegerList(2 * $numStrings);
     // Read in all translations
     for ($current = 0; $current < $numStrings; $current++) {
         $sizeKey = $current * 2 + 1;
         $offsetKey = $current * 2 + 2;
         $originalStringSize = $originalStringTable[$sizeKey];
         $originalStringOffset = $originalStringTable[$offsetKey];
         $translationStringSize = $translationStringTable[$sizeKey];
         $translationStringOffset = $translationStringTable[$offsetKey];
         $originalString = array('');
         if ($originalStringSize > 0) {
             fseek($this->file, $originalStringOffset);
             $originalString = explode("", fread($this->file, $originalStringSize));
         }
         if ($translationStringSize > 0) {
             fseek($this->file, $translationStringOffset);
             $translationString = explode("", fread($this->file, $translationStringSize));
             if (count($originalString) > 1 && count($translationString) > 1) {
                 $textDomain[$originalString[0]] = $translationString;
                 array_shift($originalString);
                 foreach ($originalString as $string) {
                     $textDomain[$string] = '';
                 }
             } else {
                 $textDomain[$originalString[0]] = $translationString[0];
             }
         }
     }
     // Read header entries
     if (array_key_exists('', $textDomain)) {
         $rawHeaders = explode("\n", trim($textDomain['']));
         foreach ($rawHeaders as $rawHeader) {
             list($header, $content) = explode(':', $rawHeader, 2);
             if (trim(strtolower($header)) === 'plural-forms') {
                 $textDomain->setPluralRule(PluralRule::fromString($content));
             }
         }
         unset($textDomain['']);
     }
     fclose($this->file);
     return $textDomain;
 }
Beispiel #16
0
 public function testGetNumPlurals()
 {
     $rule = Rule::fromString('nplurals=9; plural=n');
     $this->assertEquals(9, $rule->getNumPlurals());
 }