Commit 8d87a928 authored by alexpott's avatar alexpott

Issue #2384863 by Gábor Hojtsy, vijaycs85, rodrigoaguilera: Translation...

Issue #2384863 by Gábor Hojtsy, vijaycs85, rodrigoaguilera: Translation language base field handler should use views field handler, provide unified options
parent 09891b7d
......@@ -248,6 +248,13 @@ field.formatter.settings.string:
type: boolean
label: 'Link to the entity'
field.formatter.settings.language:
type: field.formatter.settings.string
mapping:
native_language:
type: boolean
label: 'Display in native language'
field.formatter.settings.number_decimal:
type: mapping
label: 'Number decimal display format settings'
......
......@@ -8,8 +8,12 @@
namespace Drupal\Core\Field\Plugin\Field\FieldFormatter;
use Drupal\Component\Utility\String;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'language' formatter.
......@@ -22,22 +26,103 @@
* }
* )
*/
class LanguageFormatter extends FormatterBase {
class LanguageFormatter extends StringFormatter {
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* Constructs a LanguageFormatter instance.
*
* @param string $plugin_id
* The plugin_id for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The definition of the field to which the formatter is associated.
* @param array $settings
* The formatter settings.
* @param string $label
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Any third party settings settings.
* @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);
$this->languageManager = $language_manager;
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items) {
$elements = array();
// The 'language' cache context is not necessary, because what is printed
// here is the language's name in English, not in the language of the
// response.
foreach ($items as $delta => $item) {
$elements[$delta] = array('#markup' => $item->language ? String::checkPlain($item->language->getName()) : '');
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['label'],
$configuration['view_mode'],
$configuration['third_party_settings'],
$container->get('entity.manager'),
$container->get('language_manager')
);
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
$settings = parent::defaultSettings();
$settings['native_language'] = FALSE;
return $settings;
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$form['native_language'] = array(
'#title' => $this->t('Display in native language'),
'#type' => 'checkbox',
'#default_value' => $this->getSetting('native_language'),
);
return $form;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
$summary = parent::settingsSummary();
if ($this->getSetting('native_language')) {
$summary[] = $this->t('Displayed in native language');
}
return $summary;
}
return $elements;
/**
* {@inheritdoc}
*/
protected function viewValue(FieldItemInterface $item) {
// The language cache context is not necessary because the language is
// either displayed in its configured form (loaded directly from config
// storage by LanguageManager::getLanguages()) or in its native language
// name. That only depends on formatter settings and no language condition.
$languages = $this->getSetting('native_language') ? $this->languageManager->getNativeLanguages() : $this->languageManager->getLanguages();
return $item->language ? String::checkPlain($languages[$item->language->getId()]->getName()) : '';
}
}
......@@ -10,6 +10,7 @@
use Drupal\Component\Utility\String;
use Drupal\Core\Entity\EntityManagerInterface;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
......@@ -104,12 +105,12 @@ public function settingsForm(array $form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function settingsSummary() {
$build = [];
$summary = [];
if ($this->getSetting('link_to_entity')) {
$entity_type = $this->entityManager->getDefinition($this->fieldDefinition->getTargetEntityTypeId());
$build['#markup'] = $this->t('Linked to the @entity_label', ['@entity_label' => $entity_type->getLabel()]);
$summary[] = $this->t('Linked to the @entity_label', ['@entity_label' => $entity_type->getLabel()]);
}
return $build;
return $summary;
}
/**
......@@ -125,9 +126,7 @@ public function viewElements(FieldItemListInterface $items) {
}
foreach ($items as $delta => $item) {
// The text value has no text format assigned to it, so the user input
// should equal the output, including newlines.
$string = nl2br(String::checkPlain($item->value));
$string = $this->viewValue($item);
if ($url) {
$elements[$delta] = [
......@@ -144,4 +143,19 @@ public function viewElements(FieldItemListInterface $items) {
return $elements;
}
/**
* Generate the output appropriate for one field item.
*
* @param \Drupal\Core\Field\FieldItemInterface $item
* One field item.
*
* @return string
* The textual output generated.
*/
protected function viewValue(FieldItemInterface $item) {
// The text value has no text format assigned to it, so the user input
// should equal the output, including newlines.
return nl2br(String::checkPlain($item->value));
}
}
......@@ -105,7 +105,8 @@ interface LanguageInterface {
* Gets the name of the language.
*
* @return string
* The human-readable English name of the language.
* The human-readable name of the language (in the language that was
* used to construct this object).
*/
public function getName();
......
......@@ -497,10 +497,10 @@ function language_field_info_alter(&$info) {
* Implements hook_entity_field_access()
*/
function language_entity_field_access($operation, FieldDefinitionInterface $field_definition, AccountInterface $account, FieldItemListInterface $items = NULL) {
// Only allow access to a langcode field if the entity it is attached to is
// configured to have an alterable language.
// Without items we can not decide whether or not to allow access.
if ($items) {
// Only allow edit access on a langcode field if the entity it is attached to
// is configured to have an alterable language. Also without items we can not
// decide whether or not to allow access.
if ($items && $operation == 'edit') {
// Check if we are dealing with a langcode field.
$langcode_key = $items->getEntity()->getEntityType()->getKey('langcode');
if ($field_definition->getName() == $langcode_key) {
......
......@@ -93,14 +93,6 @@ views.argument_validator.node:
type: string
label: 'Filter value format'
views.field.node_language:
type: views.field.node
label: 'Node language'
mapping:
native_language:
type: boolean
label: 'Native language'
views.field.node:
type: views_field
label: 'Node'
......
......@@ -39,7 +39,6 @@ public function getViewsData() {
$data['node_field_data']['type']['argument']['id'] = 'node_type';
$data['node_field_data']['langcode']['help'] = t('The language of the content or translation.');
$data['node_field_data']['langcode']['field']['id'] = 'node_language';
$data['node_field_data']['status']['field']['output formats'] = [
'published-notpublished' => array(t('Published'), t('Not published')),
......@@ -289,7 +288,6 @@ public function getViewsData() {
) + $data['node_revision']['vid'];
$data['node_field_revision']['langcode']['help'] = t('The language the original content is in.');
$data['node_field_revision']['langcode']['field']['id'] = 'node_language';
$data['node_revision']['revision_log']['field']['id'] = 'xss';
......@@ -311,7 +309,6 @@ public function getViewsData() {
$data['node_field_revision']['title']['field']['id'] = 'node_revision';
$data['node_field_revision']['langcode']['help'] = t('The language of the content or translation.');
$data['node_field_revision']['langcode']['field']['id'] = 'node_language';
$data['node_revision']['link_to_revision'] = array(
'field' => array(
......
<?php
/**
* @file
* Definition of Drupal\node\Plugin\views\field\Language.
*/
namespace Drupal\node\Plugin\views\field;
use Drupal\Core\Form\FormStateInterface;
use Drupal\node\Plugin\views\field\Node;
use Drupal\views\ResultRow;
/**
* Field handler to translate a language into its readable form.
*
* @ingroup views_field_handlers
*
* @ViewsField("node_language")
*/
class Language extends Node {
protected function defineOptions() {
$options = parent::defineOptions();
$options['native_language'] = array('default' => FALSE);
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['native_language'] = array(
'#title' => $this->t('Native language'),
'#type' => 'checkbox',
'#default_value' => $this->options['native_language'],
'#description' => $this->t('If enabled, the native name of the language will be displayed'),
);
}
/**
* {@inheritdoc}
*/
public function render(ResultRow $values) {
// @todo: Drupal Core dropped native language until config translation is
// ready, see http://drupal.org/node/1616594.
$value = $this->getValue($values);
$language = \Drupal::languageManager()->getLanguage($value);
$value = $language ? $language->getName() : '';
return $this->renderLink($value, $values);
}
}
......@@ -11,6 +11,7 @@
use Drupal\language\Entity\ConfigurableLanguage;
use Drupal\views\Plugin\views\PluginBase;
use Drupal\views\Tests\ViewTestData;
use Drupal\views\Views;
/**
* Tests node language fields, filters, and sorting.
......@@ -22,7 +23,7 @@ class NodeLanguageTest extends NodeTestBase {
/**
* {@inheritdoc}
*/
public static $modules = array('language');
public static $modules = array('language', 'node_test_views');
/**
* Views used by this test.
......@@ -226,4 +227,55 @@ public function testLanguages() {
}
}
}
/**
* Tests native name display in language field.
*/
public function testNativeLanguageField() {
$this->assertLanguageNames();
// Modify test view to display native language names and set translations.
$config = $this->config('views.view.test_language');
$config->set('display.default.display_options.fields.langcode.settings.native_language', TRUE);
$config->save();
\Drupal::languageManager()->getLanguageConfigOverride('fr', 'language.entity.fr')->set('label', 'Français')->save();
\Drupal::languageManager()->getLanguageConfigOverride('es', 'language.entity.es')->set('label', 'Español')->save();
$this->assertLanguageNames(TRUE);
// Modify test view to use the views built-in language field and test that.
\Drupal::state()->set('node_test_views.use_basic_handler', TRUE);
Views::viewsData()->clear();
$config = $this->config('views.view.test_language');
$config->set('display.default.display_options.fields.langcode.native_language', FALSE);
$config->clear('display.default.display_options.fields.langcode.settings');
$config->clear('display.default.display_options.fields.langcode.type');
$config->set('display.default.display_options.fields.langcode.plugin_id', 'language');
$config->save();
$this->assertLanguageNames();
$config->set('display.default.display_options.fields.langcode.native_language', TRUE)->save();
$this->assertLanguageNames(TRUE);
}
/**
* Asserts the presence of language names in their English or native forms.
*
* @param bool $native
* (optional) Whether to assert the language name in its native form.
*/
protected function assertLanguageNames($native = FALSE) {
$this->drupalGet('test-language');
if ($native) {
$this->assertText('Français', 'French language shown in native form.');
$this->assertText('Español', 'Spanish language shown in native form.');
$this->assertNoText('French', 'French language not shown in English.');
$this->assertNoText('Spanish', 'Spanish language not shown in English.');
}
else {
$this->assertNoText('Français', 'French language not shown in native form.');
$this->assertNoText('Español', 'Spanish language not shown in native form.');
$this->assertText('French', 'French language shown in English.');
$this->assertText('Spanish', 'Spanish language shown in English.');
}
}
}
......@@ -7,3 +7,4 @@ core: 8.x
dependencies:
- node
- views
- language
<?php
/**
* @file
* Provides views data and hooks for node_test_views module.
*/
/**
* Implements hook_views_data_alter().
*/
function node_test_views_views_data_alter(array &$data) {
// Make node language use the basic field handler if requested.
if (\Drupal::state()->get('node_test_views.use_basic_handler')) {
$data['node_field_data']['langcode']['field']['id'] = 'language';
}
}
......@@ -159,11 +159,12 @@ display:
hide_empty: false
empty_zero: false
hide_alter_empty: true
link_to_node: false
native_language: false
plugin_id: node_language
plugin_id: field
entity_type: node
entity_field: langcode
settings:
native_language: false
type: language
filters:
status:
value: true
......
......@@ -83,10 +83,6 @@ views.argument_default.taxonomy_tid:
type: string
label: 'Multiple-value handling'
views.field.taxonomy_term_language:
type: views.field.taxonomy
label: 'Taxonomy language'
views.field.term_link_edit:
type: views_field
label: 'Taxonomy language'
......
<?php
/**
* @file
* Definition of Drupal\taxonomy\Plugin\views\field\Language.
*/
namespace Drupal\taxonomy\Plugin\views\field;
use Drupal\views\ResultRow;
/**
* Field handler to show the language of a taxonomy term.
*
* @ViewsField("taxonomy_term_language")
*/
class Language extends Taxonomy {
/**
* {@inheritdoc}
*/
public function render(ResultRow $values) {
$value = $this->getValue($values);
$language = \Drupal::languageManager()->getLanguage($value);
$value = $language ? $language->getName() : '';
return $this->renderLink($this->sanitizeValue($value), $values);
}
}
......@@ -100,8 +100,6 @@ public function getViewsData() {
$data['taxonomy_term_field_data']['description__value']['field']['click sortable'] = FALSE;
$data['taxonomy_term_field_data']['langcode']['field']['id'] = 'taxonomy_term_language';
$data['taxonomy_term_field_data']['changed']['title'] = t('Updated date');
$data['taxonomy_term_field_data']['changed']['help'] = t('The date the term was last updated.');
......
......@@ -67,10 +67,6 @@ views_field_user:
type: boolean
label: 'Link this field to its user'
views.field.user_language:
type: views_field_user
label: 'User language'
views.field.user_link:
type: views_field
label: 'User link'
......
<?php
/**
* @file
* Definition of Drupal\user\Plugin\views\field\Language.
*/
namespace Drupal\user\Plugin\views\field;
use Drupal\Core\Url;
use Drupal\views\ResultRow;
/**
* Views field handler for user language.
*
* @ingroup views_field_handlers
*
* @ViewsField("user_language")
*/
class Language extends User {
/**
* {@inheritdoc}
*/
protected function renderLink($data, ResultRow $values) {
if (!empty($this->options['link_to_user'])) {
$uid = $this->getValue($values, 'uid');
if ($this->view->getUser()->hasPermission('access user profiles') && $uid) {
$this->options['alter']['make_link'] = TRUE;
$this->options['alter']['url'] = Url::fromRoute('entity.user.canonical', ['user' => $uid]);
}
}
if (empty($data)) {
$lang = \Drupal::languageManager()->getDefaultLanguage();
}
else {
$lang = \Drupal::languageManager()->getLanguages();
$lang = $lang[$data];
}
return $this->sanitizeValue($lang->getName());
}
/**
* {@inheritdoc}
*/
public function render(ResultRow $values) {
$value = $this->getValue($values);
return $this->renderLink($this->sanitizeValue($value), $values);
}
}
......@@ -88,7 +88,6 @@ public function getViewsData() {
$data['users_field_data']['mail']['help'] = t('Email address for a given user. This field is normally not shown to users, so be cautious when using it.');
$data['users_field_data']['mail']['field']['id'] = 'user_mail';
$data['users_field_data']['langcode']['id'] = 'user_language';
$data['users_field_data']['langcode']['help'] = t('Original language of the user information');
$data['users_field_data']['langcode']['help'] = t('Language of the translation of user information');
......
......@@ -178,6 +178,10 @@ views.field.xss:
views.field.language:
type: views_field
label: 'Language'
mapping:
native_language:
type: boolean
label: 'Display in native language'
views.field.bulk_form:
type: views_field_bulk_form
......
......@@ -319,7 +319,7 @@ protected function mapSingleFieldViewsData($table, $field_name, $field_type, $co
break;
case 'language':
$views_field['field']['id'] = 'language';
$views_field['field']['id'] = 'field';
$views_field['argument']['id'] = 'language';
$views_field['filter']['id'] = 'language';
$views_field['sort']['id'] = 'standard';
......
......@@ -35,10 +35,9 @@ protected function defineOptions() {
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['native_language'] = array(
'#title' => $this->t('Native language'),
'#title' => $this->t('Display in native language'),
'#type' => 'checkbox',
'#default_value' => $this->options['native_language'],
'#description' => $this->t('If enabled, the native name of the language will be displayed'),
);
}
......@@ -46,11 +45,9 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
* {@inheritdoc}
*/
public function render(ResultRow $values) {
// @todo: Drupal Core dropped native language until config translation is
// ready, see http://drupal.org/node/1616594.
$value = $this->getValue($values);
$language = \Drupal::languageManager()->getLanguage($value);
return $language ? $language->getName() : '';
$languages = $this->options['native_language'] ? \Drupal::languageManager()->getNativeLanguages() : \Drupal::languageManager()->getLanguages();
return isset($languages[$value]) ? $languages[$value]->getName() : '';
}
}
......@@ -783,7 +783,7 @@ protected function assertNumericField($data) {
* The views data to check.
*/
protected function assertLanguageField($data) {
$this->assertEquals('language', $data['field']['id']);
$this->assertEquals('field', $data['field']['id']);
$this->assertEquals('language', $data['filter']['id']);
$this->assertEquals('language', $data['argument']['id']);
$this->assertEquals('standard', $data['sort']['id']);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment