Chris@0: count = $count; Chris@18: $translatable_string = implode(PoItem::DELIMITER, [$singular, $plural]); Chris@0: parent::__construct($translatable_string, $args, $options, $string_translation); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Constructs a new class instance from already translated markup. Chris@0: * Chris@0: * This method ensures that the string is pluralized correctly. As opposed Chris@0: * to the __construct() method, this method is designed to be invoked with Chris@0: * a string already translated (such as with configuration translation). Chris@0: * Chris@0: * @param int $count Chris@0: * The item count to display. Chris@0: * @param string $translated_string Chris@0: * The already translated string. Chris@0: * @param array $args Chris@0: * An associative array of replacements to make after translation. Instances Chris@0: * of any key in this array are replaced with the corresponding value. Chris@0: * Based on the first character of the key, the value is escaped and/or Chris@17: * themed. See \Drupal\Component\Render\FormattableMarkup. Note that you Chris@0: * do not need to include @count in this array; this replacement is done Chris@0: * automatically for the plural cases. Chris@0: * @param array $options Chris@0: * An associative array of additional options. See t() for allowed keys. Chris@0: * Chris@0: * @return \Drupal\Core\StringTranslation\PluralTranslatableMarkup Chris@0: * A PluralTranslatableMarkup object. Chris@0: */ Chris@0: public static function createFromTranslatedString($count, $translated_string, array $args = [], array $options = []) { Chris@0: $plural = new static($count, '', '', $args, $options); Chris@0: $plural->translatedString = $translated_string; Chris@0: return $plural; Chris@0: } Chris@0: Chris@0: /** Chris@0: * Renders the object as a string. Chris@0: * Chris@0: * @return string Chris@0: * The translated string. Chris@0: */ Chris@0: public function render() { Chris@0: if (!$this->translatedString) { Chris@0: $this->translatedString = $this->getStringTranslation()->translateString($this); Chris@0: } Chris@0: if ($this->translatedString === '') { Chris@0: return ''; Chris@0: } Chris@0: Chris@0: $arguments = $this->getArguments(); Chris@0: $arguments['@count'] = $this->count; Chris@18: $translated_array = explode(PoItem::DELIMITER, $this->translatedString); Chris@0: Chris@0: if ($this->count == 1) { Chris@0: return $this->placeholderFormat($translated_array[0], $arguments); Chris@0: } Chris@0: Chris@0: $index = $this->getPluralIndex(); Chris@0: if ($index == 0) { Chris@0: // Singular form. Chris@0: $return = $translated_array[0]; Chris@0: } Chris@0: else { Chris@0: if (isset($translated_array[$index])) { Chris@0: // N-th plural form. Chris@0: $return = $translated_array[$index]; Chris@0: } Chris@0: else { Chris@0: // If the index cannot be computed or there's no translation, use the Chris@0: // second plural form as a fallback (which allows for most flexibility Chris@0: // with the replaceable @count value). Chris@0: $return = $translated_array[1]; Chris@0: } Chris@0: } Chris@0: Chris@0: return $this->placeholderFormat($return, $arguments); Chris@0: } Chris@0: Chris@0: /** Chris@0: * Gets the plural index through the gettext formula. Chris@0: * Chris@0: * @return int Chris@0: */ Chris@0: protected function getPluralIndex() { Chris@0: // We have to test both if the function and the service exist since in Chris@0: // certain situations it is possible that locale code might be loaded but Chris@0: // the service does not exist. For example, where the parent test site has Chris@0: // locale installed but the child site does not. Chris@0: // @todo Refactor in https://www.drupal.org/node/2660338 so this code does Chris@0: // not depend on knowing that the Locale module exists. Chris@0: if (function_exists('locale_get_plural') && \Drupal::hasService('locale.plural.formula')) { Chris@0: return locale_get_plural($this->count, $this->getOption('langcode')); Chris@0: } Chris@0: return -1; Chris@0: } Chris@0: Chris@0: /** Chris@0: * {@inheritdoc} Chris@0: */ Chris@0: public function __sleep() { Chris@0: return array_merge(parent::__sleep(), ['count']); Chris@0: } Chris@0: Chris@0: }