diff --git a/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php b/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php index 85a6e3f..0946709 100644 --- a/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php +++ b/core/lib/Drupal/Core/StringTranslation/StringTranslationTrait.php @@ -53,6 +53,28 @@ protected function formatPlural($count, $singular, $plural, array $args = array( } /** + * Formats a translated string containing a count of items. + * + * See the + * \Drupal\Core\StringTranslation\TranslationInterface::formatPluralTranslated() + * documentation for details. + */ + protected function formatPluralTranslated($count, $translated, array $args = array(), array $options = array()) { + return $this->getStringTranslation()->formatPluralTranslated($count, $translated, $args, $options); + } + + /** + * Returns number of plurals supported by a given language. + * + * See the + * \Drupal\Core\StringTranslation\TranslationInterface::getNumberOfPlurals() + * documentation for details. + */ + protected function getNumberOfPlurals($langcode = NULL) { + return $this->getStringTranslation()->getNumberOfPlurals($langcode); + } + + /** * Gets the string translation service. * * @return \Drupal\Core\StringTranslation\TranslationInterface diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php b/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php index 678c89e..d3626a6 100644 --- a/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php +++ b/core/lib/Drupal/Core/StringTranslation/TranslationInterface.php @@ -121,4 +121,15 @@ public function formatPlural($count, $singular, $plural, array $args = array(), */ public function formatPluralTranslated($count, $translation, array $args = array(), array $options = array()); + /** + * Returns number of plurals supported by a given language. + * + * @param null $langcode + * (optional) The language code. If not provided, the current language + * will be used. + * @return int + * Number of plural variants supported by the given language. + */ + public function getNumberOfPlurals($langcode = NULL); + } diff --git a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php index 2d165bf..83880e1 100644 --- a/core/lib/Drupal/Core/StringTranslation/TranslationManager.php +++ b/core/lib/Drupal/Core/StringTranslation/TranslationManager.php @@ -200,6 +200,18 @@ public function formatPluralTranslated($count, $translation, array $args = array } /** + * @inheritdoc. + */ + public function getNumberOfPlurals($langcode = NULL) { + $langcode = $langcode ?: $this->languageManager->getCurrentLanguage()->getId(); + $plural_formulas = $this->state->get('locale.translation.plurals') ?: array(); + if (isset($plural_formulas[$langcode]['plurals'])) { + return $plural_formulas[$langcode]['plurals']; + } + return 2; + } + + /** * Sets the default langcode. * * @param string $langcode diff --git a/core/modules/file/config/install/views.view.files.yml b/core/modules/file/config/install/views.view.files.yml index 6783c1b..ae330a9 100644 --- a/core/modules/file/config/install/views.view.files.yml +++ b/core/modules/file/config/install/views.view.files.yml @@ -529,8 +529,7 @@ display: decimal: . separator: ',' format_plural: true - format_plural_singular: '1 place' - format_plural_plural: '@count places' + format_plural_string: '1 place\u0003@count places' prefix: '' suffix: '' plugin_id: numeric @@ -952,8 +951,7 @@ display: decimal: . separator: ',' format_plural: false - format_plural_singular: '1' - format_plural_plural: '@count' + format_plural_string: '1\u0003@count' prefix: '' suffix: '' plugin_id: numeric diff --git a/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml b/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml index 1f917f0..9938089 100644 --- a/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml +++ b/core/modules/forum/tests/modules/forum_test_views/test_views/views.view.test_forum_index.yml @@ -141,8 +141,7 @@ display: decimal: . separator: ',' format_plural: false - format_plural_singular: '1' - format_plural_plural: '@count' + format_plural_string: '1\u0003@count' prefix: '' suffix: '' plugin_id: numeric diff --git a/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml b/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml index e8099fa..6a42631 100644 --- a/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml +++ b/core/modules/statistics/tests/modules/statistics_test_views/test_views/views.view.test_statistics_integration.yml @@ -160,8 +160,7 @@ display: decimal: . separator: '' format_plural: false - format_plural_singular: '1' - format_plural_plural: '@count' + format_plural_string: '1\u0003@count' prefix: '' suffix: '' plugin_id: numeric @@ -218,8 +217,7 @@ display: decimal: . separator: '' format_plural: false - format_plural_singular: '1' - format_plural_plural: '@count' + format_plural_string: '1\u0003@count' prefix: '' suffix: '' plugin_id: numeric diff --git a/core/modules/views/config/schema/views.field.schema.yml b/core/modules/views/config/schema/views.field.schema.yml index 0d636ac..69365e0 100644 --- a/core/modules/views/config/schema/views.field.schema.yml +++ b/core/modules/views/config/schema/views.field.schema.yml @@ -116,12 +116,9 @@ views.field.numeric: format_plural: type: boolean label: 'Format plural' - format_plural_singular: + format_plural_string: type: label - label: 'Singular form' - format_plural_plural: - type: label - label: 'Plural form' + label: 'Singular and one or more plurals' prefix: type: label label: 'Prefix' diff --git a/core/modules/views/src/Plugin/views/field/Numeric.php b/core/modules/views/src/Plugin/views/field/Numeric.php index da99d15..6b57d19 100644 --- a/core/modules/views/src/Plugin/views/field/Numeric.php +++ b/core/modules/views/src/Plugin/views/field/Numeric.php @@ -34,8 +34,7 @@ protected function defineOptions() { $options['decimal'] = array('default' => '.'); $options['separator'] = array('default' => ','); $options['format_plural'] = array('default' => FALSE); - $options['format_plural_singular'] = array('default' => '1'); - $options['format_plural_plural'] = array('default' => '@count'); + $options['format_plural_string'] = array('default' => '1' . LOCALE_PLURAL_DELIMITER . '@count'); $options['prefix'] = array('default' => ''); $options['suffix'] = array('default' => ''); @@ -93,28 +92,55 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { '#description' => $this->t('If checked, special handling will be used for plurality.'), '#default_value' => $this->options['format_plural'], ); - $form['format_plural_singular'] = array( - '#type' => 'textfield', - '#title' => $this->t('Singular form'), - '#default_value' => $this->options['format_plural_singular'], - '#description' => $this->t('Text to use for the singular form.'), - '#states' => array( - 'visible' => array( - ':input[name="options[format_plural]"]' => array('checked' => TRUE), - ), - ), + $form['format_plural_string'] = array( + '#type' => 'value', + '#default_value' => $this->options['format_plural_string'], ); - $form['format_plural_plural'] = array( - '#type' => 'textfield', - '#title' => $this->t('Plural form'), - '#default_value' => $this->options['format_plural_plural'], - '#description' => $this->t('Text to use for the plural form, @count will be replaced with the value.'), - '#states' => array( - 'visible' => array( - ':input[name="options[format_plural]"]' => array('checked' => TRUE), + + // @todo Figure out how to pass in the language of the view. + $plural_array = explode(LOCALE_PLURAL_DELIMITER, $this->options['format_plural_string']); + $plurals = $this->getNumberOfPlurals(); + if ($plurals > 2) { + for ($i = 0; $i < $plurals; $i++) { + $form['format_plural_values'][$i] = array( + '#type' => 'textfield', + '#title' => ($i == 0 ? $this->t('Singular form') : $this->formatPlural($i, 'First plural form', '@count. plural form')), + '#default_value' => isset($plural_array[$i]) ? $plural_array[$i] : '', + '#description' => $this->t('Text to use for this variant, @count will be replaced with the value.'), + '#states' => array( + 'visible' => array( + ':input[name="options[format_plural]"]' => array('checked' => TRUE), + ), + ), + ); + } + } + else { + // Fallback for unknown number of plurals. + $form['format_plural_values'][0] = array( + '#type' => 'textfield', + '#title' => $this->t('Singular form'), + '#default_value' => $plural_array[0], + '#description' => $this->t('Text to use for the singular form.'), + '#states' => array( + 'visible' => array( + ':input[name="options[format_plural]"]' => array('checked' => TRUE), + ), ), - ), - ); + ); + $form['format_plural_values'][1] = array( + '#type' => 'textfield', + '#title' => $this->t('Plural form'), + '#default_value' => isset($plural_array[1]) ? $plural_array[1] : '', + '#description' => $this->t('Text to use for the plural form, @count will be replaced with the value.'), + '#states' => array( + 'visible' => array( + ':input[name="options[format_plural]"]' => array('checked' => TRUE), + ), + ), + ); + } + $form['prefix'] = array( '#type' => 'textfield', '#title' => $this->t('Prefix'), @@ -132,6 +158,18 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { } /** + * @inheritdoc + */ + public function submitOptionsForm(&$form, FormStateInterface $form_state) { + // Merge plural format options into one string and drop the individual + // option values. + $options = &$form_state->getValue('options'); + $options['format_plural_string'] = implode(LOCALE_PLURAL_DELIMITER, $options['format_plural_values']); + unset($options['format_plural_values']); + parent::submitOptionsForm($form, $form_state); + } + + /** * {@inheritdoc} */ public function render(ResultRow $values) { @@ -156,7 +194,7 @@ public function render(ResultRow $values) { // Should we format as a plural. if (!empty($this->options['format_plural'])) { - $value = $this->formatPlural($value, $this->options['format_plural_singular'], $this->options['format_plural_plural']); + $value = $this->formatPluralTranslated($value, $this->options['format_plural_string']); } return $this->sanitizeValue($this->options['prefix'], 'xss')