diff --git a/core/config/schema/core.entity.schema.yml b/core/config/schema/core.entity.schema.yml index 71b7ccd..146ef1c 100644 --- a/core/config/schema/core.entity.schema.yml +++ b/core/config/schema/core.entity.schema.yml @@ -279,33 +279,36 @@ field.formatter.settings.language: type: boolean label: 'Display in native language' -field.formatter.settings.number_decimal: +field_formatter_settings_numeric_base: type: mapping - label: 'Number decimal display format settings' mapping: thousand_separator: type: string label: 'Thousand marker' + prefix_suffix: + type: boolean + label: 'Display prefix and suffix' + format_plural: + type: boolean + label: 'Use plural formatting' + format_plural_string: + type: label + label: 'Singular and one or more plurals' + +field.formatter.settings.number_decimal: + type: field_formatter_settings_numeric_base + label: 'Number decimal display format settings' + mapping: decimal_separator: type: string label: 'Decimal marker' scale: type: integer label: 'Scale' - prefix_suffix: - type: boolean - label: 'Display prefix and suffix.' field.formatter.settings.number_integer: - type: mapping + type: field_formatter_settings_numeric_base label: 'Number integer display format settings' - mapping: - thousand_separator: - type: string - label: 'Thousand marker' - prefix_suffix: - type: boolean - label: 'Display prefix and suffix.' field.formatter.settings.number_unformatted: type: mapping diff --git a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php index c5cf7e3..1a003f6 100644 --- a/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php +++ b/core/lib/Drupal/Core/Entity/Entity/EntityViewDisplay.php @@ -196,6 +196,9 @@ public function getRenderer($field_name) { // Instantiate the formatter object from the stored display properties. if (($configuration = $this->getComponent($field_name)) && isset($configuration['type']) && ($definition = $this->getFieldDefinition($field_name))) { + // Record the language that the configuration was translated into, which + // is needed for plural formatting (for example). + $configuration['settings_langcode'] = $this->langcode; $formatter = $this->pluginManager->getInstance(array( 'field_definition' => $definition, 'view_mode' => $this->originalMode, diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php index 2fcdce5..a6246f3 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilder.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilder.php @@ -467,10 +467,20 @@ protected function getSingleFieldDisplay($entity, $field_name, $display_options) $bundle = $entity->bundle(); $key = $entity_type_id . ':' . $bundle . ':' . $field_name . ':' . hash('crc32b', serialize($display_options)); if (!isset($this->singleFieldDisplays[$key])) { + // Assign the incoming 'settings_langcode' as the langcode of the + // EntityViewDisplay, or default to the current interface language. + if (isset($display_options['settings_langcode'])) { + $langcode = $display_options['settings_langcode']; + unset($display_options['settings_langcode']); + } + else { + $langcode = $this->languageManager->getCurrentLanguage(LanguageInterface::TYPE_INTERFACE)->getId(); + } $this->singleFieldDisplays[$key] = EntityViewDisplay::create(array( 'targetEntityType' => $entity_type_id, 'bundle' => $bundle, 'status' => TRUE, + 'langcode' => $langcode, ))->setComponent($field_name, $display_options); } $display = $this->singleFieldDisplays[$key]; diff --git a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php index 0549060..ff086c6 100644 --- a/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php +++ b/core/lib/Drupal/Core/Entity/EntityViewBuilderInterface.php @@ -122,6 +122,10 @@ public function resetCache(array $entities = NULL); * also be used if the requested formatter is not available. * - settings: (array) Settings specific to the formatter. Defaults to the * formatter's default settings. + * - settings_langcode: (string) The langcode associated to the settings + * passed above. If the settings are read from a config entity, this + * should be the langcode of that config entity. Defaults to the + * langcode of the current interface language. * - weight: (float) The weight to assign to the renderable element. * Defaults to 0. * diff --git a/core/lib/Drupal/Core/Field/FormatterBase.php b/core/lib/Drupal/Core/Field/FormatterBase.php index a6c8cc8..41f8701 100644 --- a/core/lib/Drupal/Core/Field/FormatterBase.php +++ b/core/lib/Drupal/Core/Field/FormatterBase.php @@ -62,8 +62,10 @@ * The view mode. * @param array $third_party_settings * Any third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings) { + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode) { parent::__construct(array(), $plugin_id, $plugin_definition); $this->fieldDefinition = $field_definition; @@ -71,6 +73,7 @@ public function __construct($plugin_id, $plugin_definition, FieldDefinitionInter $this->label = $label; $this->viewMode = $view_mode; $this->thirdPartySettings = $third_party_settings; + $this->settingsLangcode = $settings_langcode; } /** diff --git a/core/lib/Drupal/Core/Field/FormatterPluginManager.php b/core/lib/Drupal/Core/Field/FormatterPluginManager.php index e6054a9..d100add 100644 --- a/core/lib/Drupal/Core/Field/FormatterPluginManager.php +++ b/core/lib/Drupal/Core/Field/FormatterPluginManager.php @@ -61,6 +61,9 @@ public function createInstance($plugin_id, array $configuration = array()) { $plugin_definition = $this->getDefinition($plugin_id); $plugin_class = DefaultFactory::getPluginClass($plugin_id, $plugin_definition); + // @todo Not sure we need to keep that, there should always be a settings_langcode set ? + $configuration += ['settings_langcode' => NULL]; + // @todo This is copied from \Drupal\Core\Plugin\Factory\ContainerFactory. // Find a way to restore sanity to // \Drupal\Core\Field\FormatterBase::__construct(). @@ -69,7 +72,7 @@ public function createInstance($plugin_id, array $configuration = array()) { return $plugin_class::create(\Drupal::getContainer(), $configuration, $plugin_id, $plugin_definition); } - return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings']); + return new $plugin_class($plugin_id, $plugin_definition, $configuration['field_definition'], $configuration['settings'], $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], $configuration['settings_langcode']); } /** @@ -94,6 +97,10 @@ public function createInstance($plugin_id, array $configuration = array()) { * defaults to the default value specified in the formatter definition. * - third_party_settings: (array) Settings provided by other extensions * through hook_field_formatter_third_party_settings_form(). + * - settings_langcode: (string) The language code associated to the + * settings passed above. That is typically the language code of the + * configuration entity the settings are taken from (an + * entity_view_display, a view...) * * @return \Drupal\Core\Field\FormatterInterface|null * A formatter object or NULL when plugin is not found. diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php index 0e43ac1..7c9a17b 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/DecimalFormatter.php @@ -32,10 +32,8 @@ class DecimalFormatter extends NumericFormatterBase { */ public static function defaultSettings() { return array( - 'thousand_separator' => '', 'decimal_separator' => '.', 'scale' => 2, - 'prefix_suffix' => TRUE, ) + parent::defaultSettings(); } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php index 1328f65..40d6686 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/EntityReferenceEntityFormatter.php @@ -52,13 +52,13 @@ class EntityReferenceEntityFormatter extends EntityReferenceFormatterBase implem * The view mode. * @param array $third_party_settings * Any third party settings settings. - * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager - * The entity manager. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param LoggerChannelFactoryInterface $logger_factory * The logger factory. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, LoggerChannelFactoryInterface $logger_factory) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, LoggerChannelFactoryInterface $logger_factory) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->loggerFactory = $logger_factory; } @@ -74,6 +74,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('logger.factory') ); } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php index 8768474..20e5d4b 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/IntegerFormatter.php @@ -27,16 +27,6 @@ class IntegerFormatter extends NumericFormatterBase { /** * {@inheritdoc} */ - public static function defaultSettings() { - return array( - 'thousand_separator' => '', - 'prefix_suffix' => TRUE, - ) + parent::defaultSettings(); - } - - /** - * {@inheritdoc} - */ protected function numberFormat($number) { return number_format($number, 0, '', $this->getSetting('thousand_separator')); } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php index e4b41b8..f0fbfa7 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/LanguageFormatter.php @@ -52,13 +52,15 @@ class LanguageFormatter extends StringFormatter { * The view mode. * @param array $third_party_settings * Any third party settings settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager * The language manager. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $entity_manager); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, EntityManagerInterface $entity_manager, LanguageManagerInterface $language_manager) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode, $entity_manager); $this->languageManager = $language_manager; } @@ -75,6 +77,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('entity.manager'), $container->get('language_manager') ); diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php index 01a748f..f139071 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/NumericFormatterBase.php @@ -22,6 +22,18 @@ /** * {@inheritdoc} */ + public static function defaultSettings() { + return array( + 'thousand_separator' => '', + 'prefix_suffix' => TRUE, + 'format_plural' => FALSE, + 'format_plural_string' => '1' . LOCALE_PLURAL_DELIMITER . '@count', + ) + parent::defaultSettings(); + } + + /** + * {@inheritdoc} + */ public function settingsForm(array $form, FormStateInterface $form_state) { $options = array( '' => t('- None -'), @@ -46,10 +58,71 @@ public function settingsForm(array $form, FormStateInterface $form_state) { '#weight' => 10, ); + $elements['format_plural'] = array( + '#type' => 'checkbox', + '#title' => $this->t('Use plural formatting'), + '#description' => $this->t('If checked, special handling will be used for plurality.'), + '#default_value' => $this->getSetting('format_plural'), + ); + $plural_array = explode(LOCALE_PLURAL_DELIMITER, $this->getSetting('format_plural_string')); + $elements['format_plural_values'] = array( + '#after_build' => [[get_class($this), 'formatPluralValuesAfterBuild']], + ); + $plurals = $this->getNumberOfPlurals($this->settingsLangcode); + for ($i = 0; $i < $plurals; $i++) { + $elements['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), + ), + ), + ); + } + if ($plurals == 2) { + // Simplify user interface text for the most common case. + $elements['format_plural_values'][0]['#description'] = $this->t('Text to use for the singular form, @count will be replaced with the value.'); + $elements['format_plural_values'][1]['#title'] = $this->t('Plural form'); + $elements['format_plural_values'][1]['#description'] = $this->t('Text to use for the plural form, @count will be replaced with the value.'); + } return $elements; } /** + * After-build callback: Sets the value for the format_plural_string property. + * + * This method is assigned as an #after_build function in + * \namespace\class::settingsForm(). + * + * The user interface for setting up singular/plural forms is an array of text + * fields, for usability, but for translation purposes, the values have to be + * stored as a single string in the field settings. This function implodes the + * values. + * + * @param array $element + * Textfield element where the plural format should be set. + * @param \Drupal\Core\Form\FormStateInterface $form_state + * The current state of the form. + * + * @return array + * Textfield element with plural string set. + */ + public static function formatPluralValuesAfterBuild($element, FormStateInterface $form_state) { + if ($form_state->isProcessingInput()) { + $keys = $element['#parents']; + $array_value = $form_state->getValue($keys); + $string_value = implode(LOCALE_PLURAL_DELIMITER, $array_value); + array_pop($keys); + $keys[] = 'format_plural_string'; + $form_state->setValue($keys, $string_value); + } + return $element; + } + + /** * {@inheritdoc} */ public function settingsSummary() { @@ -73,6 +146,10 @@ public function viewElements(FieldItemListInterface $items) { foreach ($items as $delta => $item) { $output = $this->numberFormat($item->value); + if ($this->getSetting('format_plural')) { + $output = $this->formatPluralTranslated($output, $this->getSetting('format_plural_string')); + } + // Account for prefix and suffix. if ($this->getSetting('prefix_suffix')) { $prefixes = isset($settings['prefix']) ? array_map(array('Drupal\Core\Field\FieldFilteredString', 'create'), explode('|', $settings['prefix'])) : array(''); diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php index fd5c3bb..c639456 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/StringFormatter.php @@ -52,11 +52,13 @@ class StringFormatter extends FormatterBase implements ContainerFactoryPluginInt * The view mode. * @param array $third_party_settings * Any third party settings settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager * The entity manager. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityManagerInterface $entity_manager) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, EntityManagerInterface $entity_manager) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->entityManager = $entity_manager; } @@ -73,6 +75,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('entity.manager') ); } diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php index 6443669..faf4f3b 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampAgoFormatter.php @@ -63,13 +63,15 @@ class TimestampAgoFormatter extends FormatterBase implements ContainerFactoryPlu * The view mode. * @param array $third_party_settings * Any third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Datetime\DateFormatter $date_formatter * The date formatter service. * @param \Symfony\Component\HttpFoundation\Request $request * The current request. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, Request $request) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, DateFormatter $date_formatter, Request $request) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->dateFormatter = $date_formatter; $this->request = $request; @@ -88,6 +90,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('date.formatter'), $container->get('request_stack')->getCurrentRequest() ); diff --git a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php index 36bfe15..f949699 100644 --- a/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php +++ b/core/lib/Drupal/Core/Field/Plugin/Field/FieldFormatter/TimestampFormatter.php @@ -62,13 +62,15 @@ class TimestampFormatter extends FormatterBase implements ContainerFactoryPlugin * The view mode. * @param array $third_party_settings * Third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Datetime\DateFormatter $date_formatter * The date formatter service. * @param \Drupal\Core\Entity\EntityStorageInterface $date_format_storage * The date format storage. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, EntityStorageInterface $date_format_storage) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, DateFormatter $date_formatter, EntityStorageInterface $date_format_storage) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->dateFormatter = $date_formatter; $this->dateFormatStorage = $date_format_storage; @@ -86,6 +88,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('date.formatter'), $container->get('entity.manager')->getStorage('date_format') ); diff --git a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php index adacf9d..edb6c41 100644 --- a/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php +++ b/core/modules/comment/src/Plugin/Field/FieldFormatter/CommentDefaultFormatter.php @@ -95,6 +95,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('current_user'), $container->get('entity.manager'), $container->get('entity.form_builder') @@ -118,6 +119,8 @@ public static function create(ContainerInterface $container, array $configuratio * The view mode. * @param array $third_party_settings * Third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Session\AccountInterface $current_user * The current user. * @param \Drupal\Core\Entity\EntityManagerInterface $entity_manager @@ -125,8 +128,8 @@ public static function create(ContainerInterface $container, array $configuratio * @param \Drupal\Core\Entity\EntityFormBuilderInterface $entity_form_builder * The entity form builder. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, EntityManagerInterface $entity_manager, EntityFormBuilderInterface $entity_form_builder) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, AccountInterface $current_user, EntityManagerInterface $entity_manager, EntityFormBuilderInterface $entity_form_builder) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->viewBuilder = $entity_manager->getViewBuilder('comment'); $this->storage = $entity_manager->getStorage('comment'); $this->currentUser = $current_user; diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php index aad8c16..4000af5 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeFormatterBase.php @@ -53,13 +53,15 @@ * The view mode. * @param array $third_party_settings * Third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Datetime\DateFormatter $date_formatter * The date formatter service. * @param \Drupal\Core\Entity\EntityStorageInterface $date_format_storage * The date format entity storage. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, EntityStorageInterface $date_format_storage) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, DateFormatter $date_formatter, EntityStorageInterface $date_format_storage) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->dateFormatter = $date_formatter; $this->dateFormatStorage = $date_format_storage; @@ -77,6 +79,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('date.formatter'), $container->get('entity.manager')->getStorage('date_format') ); diff --git a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php index 0bc56c6..14cdffc 100644 --- a/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php +++ b/core/modules/datetime/src/Plugin/Field/FieldFormatter/DateTimeTimeAgoFormatter.php @@ -62,13 +62,15 @@ class DateTimeTimeAgoFormatter extends FormatterBase implements ContainerFactory * The view mode. * @param array $third_party_settings * Third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Datetime\DateFormatter $date_formatter * The date formatter service. * @param \Symfony\Component\HttpFoundation\Request $request * The current request. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, DateFormatter $date_formatter, Request $request) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, DateFormatter $date_formatter, Request $request) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->dateFormatter = $date_formatter; $this->request = $request; @@ -99,6 +101,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('date.formatter'), $container->get('request_stack')->getCurrentRequest() ); diff --git a/core/modules/field/src/Plugin/migrate/process/d6/FieldFormatterSettingsDefaults.php b/core/modules/field/src/Plugin/migrate/process/d6/FieldFormatterSettingsDefaults.php index 4deeb16..53fbdf1 100644 --- a/core/modules/field/src/Plugin/migrate/process/d6/FieldFormatterSettingsDefaults.php +++ b/core/modules/field/src/Plugin/migrate/process/d6/FieldFormatterSettingsDefaults.php @@ -131,7 +131,8 @@ protected function numberSettings($type, $format) { ], ]; - return isset($map[$type][$format]) ? $map[$type][$format] : []; + $default = ['format_plural' => FALSE, 'format_plural_string' => '1' . LOCALE_PLURAL_DELIMITER . '@count']; + return isset($map[$type][$format]) ? $map[$type][$format] + $default : []; } } diff --git a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php index c9e9912..d500fa3 100644 --- a/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php +++ b/core/modules/field/src/Tests/Migrate/d6/MigrateFieldFormatterSettingsTest.php @@ -115,16 +115,20 @@ public function testEntityDisplaySettings() { $expected['settings'] = array( 'thousand_separator' => ',', 'prefix_suffix' => TRUE, + 'format_plural' => FALSE, + 'format_plural_string' => '1' . LOCALE_PLURAL_DELIMITER . '@count' ); $component = $display->getComponent('field_test_two'); $this->assertIdentical($expected, $component); $expected['weight'] = 2; $expected['type'] = 'number_decimal'; $expected['settings'] = array( - 'scale' => 2, - 'decimal_separator' => '.', - 'thousand_separator' => ',', - 'prefix_suffix' => TRUE, + 'scale' => 2, + 'decimal_separator' => '.', + 'thousand_separator' => ',', + 'prefix_suffix' => TRUE, + 'format_plural' => FALSE, + 'format_plural_string' => '1' . LOCALE_PLURAL_DELIMITER . '@count' ); $component = $display->getComponent('field_test_three'); $this->assertIdentical($expected, $component); diff --git a/core/modules/field/src/Tests/Number/NumberFieldTest.php b/core/modules/field/src/Tests/Number/NumberFieldTest.php index e4f104e..e9ee3d3 100644 --- a/core/modules/field/src/Tests/Number/NumberFieldTest.php +++ b/core/modules/field/src/Tests/Number/NumberFieldTest.php @@ -7,6 +7,7 @@ namespace Drupal\field\Tests\Number; +use Drupal\Component\Utility\Html; use Drupal\Component\Utility\Unicode; use Drupal\simpletest\WebTestBase; @@ -485,6 +486,23 @@ function testNumberFormatter() { $integer_formatted = number_format($random_integer, 0, '', $thousand_separator); $this->assertRaw($integer_formatted, 'Random integer formatted'); + + // Check with plural formatting settings. + $this->drupalGet("admin/structure/types/manage/$type/display"); + $this->drupalPostAjaxForm(NULL, array(), "${integer_field}_settings_edit"); + $edit["fields[${integer_field}][settings_edit_form][settings][format_plural]"] = TRUE; + $edit["fields[${integer_field}][settings_edit_form][settings][format_plural_values][0]"] = '1 item'; + $edit["fields[${integer_field}][settings_edit_form][settings][format_plural_values][1]"] = '@count items'; + $this->drupalPostAjaxForm(NULL, $edit, "${integer_field}_plugin_settings_update"); + $this->drupalPostForm(NULL, array(), t('Save')); + + $this->drupalGet('node/' . $node->id()); + + // Because of the @count placeholder in the 'format_plural_values' setting + // we need to check for the escaped value and not the raw one. + $integer_formatted = number_format($random_integer, 0, '', $thousand_separator); + $format_plural = $integer_formatted . ' item' . ($random_integer == 1 ? '' : 's'); + $this->assertEscaped($format_plural, 'Random integer formatted'); } /** diff --git a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php index 3069721..e7fa253 100644 --- a/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php +++ b/core/modules/image/src/Plugin/Field/FieldFormatter/ImageFormatter.php @@ -64,11 +64,13 @@ class ImageFormatter extends ImageFormatterBase implements ContainerFactoryPlugi * The view mode. * @param array $third_party_settings * Any third party settings settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Session\AccountInterface $current_user * The current user. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, AccountInterface $current_user, EntityStorageInterface $image_style_storage) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, AccountInterface $current_user, EntityStorageInterface $image_style_storage) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->currentUser = $current_user; $this->imageStyleStorage = $image_style_storage; } @@ -85,6 +87,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('current_user'), $container->get('entity.manager')->getStorage('image_style') ); diff --git a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php index ed80376..f93f4f2 100644 --- a/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php +++ b/core/modules/link/src/Plugin/Field/FieldFormatter/LinkFormatter.php @@ -52,6 +52,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('path.validator') ); } @@ -73,11 +74,13 @@ public static function create(ContainerInterface $container, array $configuratio * The view mode. * @param array $third_party_settings * Third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Path\PathValidatorInterface $path_validator * The path validator service. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, PathValidatorInterface $path_validator) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, PathValidatorInterface $path_validator) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->pathValidator = $path_validator; } diff --git a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php index 3620501..6e8bf69 100644 --- a/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php +++ b/core/modules/responsive_image/src/Plugin/Field/FieldFormatter/ResponsiveImageFormatter.php @@ -59,13 +59,15 @@ class ResponsiveImageFormatter extends ImageFormatterBase implements ContainerFa * The view mode. * @param array $third_party_settings * Any third party settings. + * @param string $settings_langcode + * The language code associated with the settings passed above. * @param \Drupal\Core\Entity\EntityStorageInterface $responsive_image_style_storage * The responsive image style storage. * @param \Drupal\Core\Entity\EntityStorageInterface $image_style_storage * The image style storage. */ - public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, EntityStorageInterface $responsive_image_style_storage, EntityStorageInterface $image_style_storage) { - parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings); + public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, $settings_langcode, EntityStorageInterface $responsive_image_style_storage, EntityStorageInterface $image_style_storage) { + parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings, $settings_langcode); $this->responsiveImageStyleStorage = $responsive_image_style_storage; $this->imageStyleStorage = $image_style_storage; @@ -83,6 +85,7 @@ public static function create(ContainerInterface $container, array $configuratio $configuration['label'], $configuration['view_mode'], $configuration['third_party_settings'], + $configuration['settings_langcode'], $container->get('entity.manager')->getStorage('responsive_image_style'), $container->get('entity.manager')->getStorage('image_style') ); diff --git a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php index 66d4fcf..7146fff 100644 --- a/core/modules/views/src/Entity/Render/EntityFieldRenderer.php +++ b/core/modules/views/src/Entity/Render/EntityFieldRenderer.php @@ -196,6 +196,8 @@ protected function buildFields(array $values) { if ($values && ($field_ids = $this->getRenderableFieldIds())) { $entity_type_id = $this->getEntityTypeId(); + // @todo could use double-check from dawehner / plach :-) + $settings_langcode = $this->view->storage->language()->getId(); // Collect the entities for the relationship, fetch the right translation, // and group by bundle. For each result row, the corresponding entity can @@ -230,6 +232,7 @@ protected function buildFields(array $values) { 'targetEntityType' => $entity_type_id, 'bundle' => $bundle, 'status' => TRUE, + 'langcode' => $settings_langcode, ]); foreach ($display_fields as $field_id => $field) { $display->setComponent($field->definition['field_name'], [ diff --git a/core/modules/views/src/Plugin/views/field/Field.php b/core/modules/views/src/Plugin/views/field/Field.php index e4e3b0a..9944160 100644 --- a/core/modules/views/src/Plugin/views/field/Field.php +++ b/core/modules/views/src/Plugin/views/field/Field.php @@ -476,6 +476,8 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) { 'configuration' => array( 'type' => $format, 'settings' => $settings, + // @todo could use double-check from dawehner / plach :-) + 'settings_langcode' => $this->view->storage->language()->getId(), 'label' => '', 'weight' => 0, ),