summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNathaniel Catchpole2013-10-14 15:40:28 (GMT)
committerNathaniel Catchpole2013-10-14 15:40:28 (GMT)
commit5b026c3854724cea1d922f6aaa050b0535e43ac7 (patch)
treef8a9b35e7d631d36fc34352286edf96fe5ca66ec
parent9afeeb2893d6e37b1d70574436412c6017efa280 (diff)
Issue #2004626 by plach, kfritsche, vijaycs85, Pancho, penyaskito: Make non-configurable field translation settings available in the content language settings.
-rw-r--r--core/lib/Drupal/Core/Entity/EntityManager.php22
-rw-r--r--core/modules/content_translation/content_translation.admin.inc62
-rw-r--r--core/modules/content_translation/content_translation.module32
-rw-r--r--core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php13
-rw-r--r--core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSyncImageTest.php3
-rw-r--r--core/modules/node/lib/Drupal/node/Entity/Node.php1
-rw-r--r--core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php9
-rw-r--r--core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php39
-rw-r--r--core/modules/system/tests/modules/entity_test/entity_test.module11
-rw-r--r--core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php6
10 files changed, 160 insertions, 38 deletions
diff --git a/core/lib/Drupal/Core/Entity/EntityManager.php b/core/lib/Drupal/Core/Entity/EntityManager.php
index 312c7d0..9a52464 100644
--- a/core/lib/Drupal/Core/Entity/EntityManager.php
+++ b/core/lib/Drupal/Core/Entity/EntityManager.php
@@ -489,13 +489,23 @@ class EntityManager extends PluginManagerBase {
$hooks = array('entity_field_info', $entity_type . '_field_info');
$this->moduleHandler->alter($hooks, $this->entityFieldInfo[$entity_type], $entity_type);
- // Enforce fields to be multiple by default.
- foreach ($this->entityFieldInfo[$entity_type]['definitions'] as &$definition) {
- $definition['list'] = TRUE;
- }
- foreach ($this->entityFieldInfo[$entity_type]['optional'] as &$definition) {
- $definition['list'] = TRUE;
+ // Enforce fields to be multiple and untranslatable by default.
+ $entity_info = $this->getDefinition($entity_type);
+ $keys = array_intersect_key(array_filter($entity_info['entity_keys']), array_flip(array('id', 'revision', 'uuid', 'bundle')));
+ $untranslatable_fields = array_flip(array('langcode') + $keys);
+ foreach (array('definitions', 'optional') as $key) {
+ foreach ($this->entityFieldInfo[$entity_type][$key] as $name => &$definition) {
+ $definition['list'] = TRUE;
+ // Ensure ids and langcode fields are never made translatable.
+ if (isset($untranslatable_fields[$name]) && !empty($definition['translatable'])) {
+ throw new \LogicException(format_string('The @field field cannot be translatable.', array('@field' => $definition['label'])));
+ }
+ if (!isset($definition['translatable'])) {
+ $definition['translatable'] = FALSE;
+ }
+ }
}
+
$this->cache->set($cid, $this->entityFieldInfo[$entity_type], CacheBackendInterface::CACHE_PERMANENT, array('entity_info' => TRUE, 'entity_field_info' => TRUE));
}
}
diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc
index d896918..b2a83b1 100644
--- a/core/modules/content_translation/content_translation.admin.inc
+++ b/core/modules/content_translation/content_translation.admin.inc
@@ -8,6 +8,7 @@
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Field\FieldDefinitionInterface;
use Drupal\Core\Language\Language;
+use Drupal\field\Field as FieldService;
/**
* Returns a form element to configure field synchronization.
@@ -73,6 +74,7 @@ function _content_translation_form_language_content_settings_form_alter(array &$
$form['#attached']['js'][] = array('data' => drupal_get_path('module', 'content_translation') . '/content_translation.admin.js', 'type' => 'file');
$dependent_options_settings = array();
+ $entity_manager = Drupal::entityManager();
foreach ($form['#labels'] as $entity_type => $label) {
$entity_info = entity_get_info($entity_type);
foreach (entity_get_bundles($entity_type) as $bundle => $bundle_info) {
@@ -84,31 +86,51 @@ function _content_translation_form_language_content_settings_form_alter(array &$
// Only show the checkbox to enable translation if the bundles in the
// entity might have fields and if there are fields to translate.
if (!empty($entity_info['fieldable'])) {
- $instances = field_info_instances($entity_type, $bundle);
- if ($instances) {
+ $fields = $entity_manager->getFieldDefinitions($entity_type, $bundle);
+ if ($fields) {
$form['settings'][$entity_type][$bundle]['translatable'] = array(
'#type' => 'checkbox',
'#title' => $bundle,
'#default_value' => content_translation_enabled($entity_type, $bundle),
);
- // @todo Exploit field definitions once all core entities and field
- // types are migrated to the Entity Field API.
- foreach ($instances as $field_name => $instance) {
- $form['settings'][$entity_type][$bundle]['fields'][$field_name] = array(
- '#label' => $instance->getFieldLabel(),
- '#type' => 'checkbox',
- '#title' => $instance->getFieldLabel(),
- '#default_value' => $instance->isFieldTranslatable(),
- );
- $column_element = content_translation_field_sync_widget($instance);
- if ($column_element) {
- $form['settings'][$entity_type][$bundle]['columns'][$field_name] = $column_element;
-
- if (isset($column_element['#options']['file'])) {
- $dependent_options_settings["settings[{$entity_type}][{$bundle}][columns][{$field_name}]"] = array('file');
+ $field_settings = content_translation_get_config($entity_type, $bundle, 'fields');
+ foreach ($fields as $field_name => $definition) {
+ $translatable = !empty($field_settings[$field_name]);
+
+ // We special case Field API fields as they always natively support
+ // translation.
+ // @todo Remove this special casing as soon as configurable and
+ // base field definitions are "unified".
+ if (!empty($definition['configurable']) && ($field = FieldService::fieldInfo()->getField($entity_type, $field_name))) {
+ $instance = FieldService::fieldInfo()->getInstance($entity_type, $bundle, $field_name);
+ $form['settings'][$entity_type][$bundle]['fields'][$field_name] = array(
+ '#label' => $instance->getFieldLabel(),
+ '#type' => 'checkbox',
+ '#title' => $instance->getFieldLabel(),
+ '#default_value' => $translatable,
+ );
+ $column_element = content_translation_field_sync_widget($instance);
+ if ($column_element) {
+ $form['settings'][$entity_type][$bundle]['columns'][$field_name] = $column_element;
+
+ // @todo This should not concern only files.
+ if (isset($column_element['#options']['file'])) {
+ $dependent_options_settings["settings[{$entity_type}][{$bundle}][columns][{$field_name}]"] = array('file');
+ }
}
}
+ // Instead we need to rely on field definitions to determine whether
+ // fields support translation. Whether they are actually enabled is
+ // determined through our settings. As a consequence only fields
+ // that support translation can be enabled or disabled.
+ elseif (isset($field_settings[$field_name]) || !empty($definition['translatable'])) {
+ $form['settings'][$entity_type][$bundle]['fields'][$field_name] = array(
+ '#label' => $definition['label'],
+ '#type' => 'checkbox',
+ '#default_value' => $translatable,
+ );
+ }
}
}
}
@@ -326,11 +348,11 @@ function _content_translation_update_field_translatability($settings) {
foreach ($bundle_settings['fields'] as $field_name => $translatable) {
// If a field is enabled for translation for at least one instance we
// need to mark it as translatable.
- $fields[$entity_type][$field_name] = $translatable || !empty($fields[$entity_type][$field_name]);
+ if (FieldService::fieldInfo()->getField($entity_type, $field_name)) {
+ $fields[$entity_type][$field_name] = $translatable || !empty($fields[$entity_type][$field_name]);
+ }
}
}
- // @todo Store non-configurable field settings to be able to alter their
- // definition afterwards.
}
}
diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module
index 20d72ed..fe80ac6 100644
--- a/core/modules/content_translation/content_translation.module
+++ b/core/modules/content_translation/content_translation.module
@@ -127,6 +127,33 @@ function content_translation_entity_bundle_info_alter(&$bundles) {
}
/**
+ * Implements hook_entity_field_info_alter().
+ */
+function content_translation_entity_field_info_alter(&$info, $entity_type) {
+ $translation_settings = config('content_translation.settings')->get($entity_type);
+
+ if ($translation_settings) {
+ // Currently field translatability is defined per-field but we may want to
+ // make it per-instance instead, so leaving the possibility open for further
+ // easier refactoring.
+ $fields = array();
+ foreach ($translation_settings as $bundle => $settings) {
+ $fields += !empty($settings['content_translation']['fields']) ? $settings['content_translation']['fields'] : array();
+ }
+
+ $keys = array('definitions', 'optional');
+ foreach ($fields as $name => $translatable) {
+ foreach ($keys as $key) {
+ if (isset($info[$key][$name])) {
+ $info[$key][$name]['translatable'] = (bool) $translatable;
+ break;
+ }
+ }
+ }
+ }
+}
+
+/**
* Implements hook_menu().
*/
function content_translation_menu() {
@@ -987,6 +1014,11 @@ function content_translation_save_settings($settings) {
// Store whether a bundle has translation enabled or not.
content_translation_set_config($entity_type, $bundle, 'enabled', $bundle_settings['translatable']);
+ // Store whether fields are translatable or not.
+ if (!empty($bundle_settings['fields'])) {
+ content_translation_set_config($entity_type, $bundle, 'fields', $bundle_settings['fields']);
+ }
+
// Store whether fields have translation enabled or not.
if (!empty($bundle_settings['columns'])) {
foreach ($bundle_settings['columns'] as $field_name => $column_settings) {
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
index 7e4664f..127f7ea 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSettingsTest.php
@@ -20,7 +20,7 @@ class ContentTranslationSettingsTest extends WebTestBase {
*
* @var array
*/
- public static $modules = array('language', 'content_translation', 'comment', 'field_ui');
+ public static $modules = array('language', 'content_translation', 'node', 'comment', 'field_ui');
public static function getInfo() {
return array(
@@ -114,6 +114,17 @@ class ContentTranslationSettingsTest extends WebTestBase {
$this->drupalPostForm('admin/structure/types/manage/article', $edit, t('Save content type'));
$this->drupalGet('admin/structure/types/manage/article');
$this->assertFieldChecked('edit-language-configuration-content-translation');
+
+ // Test that the title field of nodes is available in the settings form.
+ $edit = array(
+ 'entity_types[node]' => TRUE,
+ 'settings[node][article][settings][language][langcode]' => 'current_interface',
+ 'settings[node][article][settings][language][language_show]' => TRUE,
+ 'settings[node][article][translatable]' => TRUE,
+ 'settings[node][article][fields][title]' => TRUE
+ );
+ $this->assertSettings('node', NULL, TRUE, $edit);
+
}
/**
diff --git a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSyncImageTest.php b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSyncImageTest.php
index 9789dc5..f974837 100644
--- a/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSyncImageTest.php
+++ b/core/modules/content_translation/lib/Drupal/content_translation/Tests/ContentTranslationSyncImageTest.php
@@ -108,10 +108,13 @@ class ContentTranslationSyncImageTest extends ContentTranslationTestBase {
$this->assertNoFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-alt');
$this->assertNoFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-title');
$edit = array(
+ 'settings[entity_test_mul][entity_test_mul][fields][field_test_et_ui_image]' => TRUE,
'settings[entity_test_mul][entity_test_mul][columns][field_test_et_ui_image][alt]' => TRUE,
'settings[entity_test_mul][entity_test_mul][columns][field_test_et_ui_image][title]' => TRUE,
);
$this->drupalPostForm('admin/config/regional/content-language', $edit, t('Save'));
+ $errors = $this->xpath('//div[contains(@class, "messages--error")]');
+ $this->assertFalse($errors, 'Settings correctly stored.');
$this->assertFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-alt');
$this->assertFieldChecked('edit-settings-entity-test-mul-entity-test-mul-columns-field-test-et-ui-image-title');
$this->drupalLogin($this->translator);
diff --git a/core/modules/node/lib/Drupal/node/Entity/Node.php b/core/modules/node/lib/Drupal/node/Entity/Node.php
index 92f4f5b..de94ae8 100644
--- a/core/modules/node/lib/Drupal/node/Entity/Node.php
+++ b/core/modules/node/lib/Drupal/node/Entity/Node.php
@@ -359,6 +359,7 @@ class Node extends ContentEntityBase implements NodeInterface {
'property_constraints' => array(
'value' => array('Length' => array('max' => 255)),
),
+ 'translatable' => TRUE,
);
$properties['uid'] = array(
'label' => t('User ID'),
diff --git a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
index 77c0bbd..338955c 100644
--- a/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/lib/Drupal/node/Tests/NodeTranslationUITest.php
@@ -16,11 +16,6 @@ use Drupal\content_translation\Tests\ContentTranslationUITest;
class NodeTranslationUITest extends ContentTranslationUITest {
/**
- * The title of the test node.
- */
- protected $title;
-
- /**
* Modules to enable.
*
* @var array
@@ -38,7 +33,6 @@ class NodeTranslationUITest extends ContentTranslationUITest {
function setUp() {
$this->entityType = 'node';
$this->bundle = 'article';
- $this->title = $this->randomName();
parent::setUp();
$this->drupalPlaceBlock('system_help_block', array('region' => 'content'));
}
@@ -62,8 +56,7 @@ class NodeTranslationUITest extends ContentTranslationUITest {
* Overrides \Drupal\content_translation\Tests\ContentTranslationUITest::getNewEntityValues().
*/
protected function getNewEntityValues($langcode) {
- // Node title is not translatable yet, hence we use a fixed value.
- return array('title' => $this->title) + parent::getNewEntityValues($langcode);
+ return array('title' => $this->randomName()) + parent::getNewEntityValues($langcode);
}
/**
diff --git a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php
index b397f2c..e2b0d4f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Entity/EntityTranslationTest.php
@@ -9,6 +9,7 @@ namespace Drupal\system\Tests\Entity;
use Drupal\Core\Language\Language;
use Drupal\Core\TypedData\TranslatableInterface;
+use Drupal\entity_test\Entity\EntityTestMulRev;
/**
* Tests entity translation.
@@ -492,4 +493,42 @@ class EntityTranslationTest extends EntityUnitTestBase {
$this->assertEqual($field->getLangcode(), $langcode2, 'Field object has the expected langcode.');
}
+ /**
+ * Check that field translatability is handled properly.
+ */
+ function testFieldDefinitions() {
+ // Check that field translatability can be altered to be enabled or disabled
+ // in field definitions.
+ $entity_type = 'entity_test_mulrev';
+ $this->state->set('entity_test.field_definitions.translatable', array('name' => FALSE));
+ $this->entityManager->clearCachedFieldDefinitions();
+ $definitions = $this->entityManager->getFieldDefinitions($entity_type);
+ $this->assertFalse($definitions['name']['translatable'], 'Field translatability can be disabled programmatically.');
+
+ $this->state->set('entity_test.field_definitions.translatable', array('name' => TRUE));
+ $this->entityManager->clearCachedFieldDefinitions();
+ $definitions = $this->entityManager->getFieldDefinitions($entity_type);
+ $this->assertTrue($definitions['name']['translatable'], 'Field translatability can be enabled programmatically.');
+
+ // Check that field translatability is disabled by default.
+ $base_field_definitions = EntityTestMulRev::baseFieldDefinitions($entity_type);
+ $this->assertTrue(!isset($base_field_definitions['id']['translatable']), 'Translatability for the <em>id</em> field is not defined.');
+ $this->assertFalse($definitions['id']['translatable'], 'Field translatability is disabled by default.');
+
+ // Check that entity ids and langcode fields cannot be translatable.
+ foreach (array('id', 'uuid', 'revision_id', 'type', 'langcode') as $name) {
+ $this->state->set('entity_test.field_definitions.translatable', array($name => TRUE));
+ $this->entityManager->clearCachedFieldDefinitions();
+ $message = format_string('Field %field cannot be translatable.', array('%field' => $name));
+
+ try {
+ $definitions = $this->entityManager->getFieldDefinitions($entity_type);
+ $this->fail($message);
+ }
+ catch (\LogicException $e) {
+ $this->pass($message);
+ }
+ }
+ }
+
}
diff --git a/core/modules/system/tests/modules/entity_test/entity_test.module b/core/modules/system/tests/modules/entity_test/entity_test.module
index cc8800e..e949e50 100644
--- a/core/modules/system/tests/modules/entity_test/entity_test.module
+++ b/core/modules/system/tests/modules/entity_test/entity_test.module
@@ -73,6 +73,17 @@ function entity_test_entity_info_alter(&$info) {
}
/**
+ * Implements hook_entity_field_info_alter().
+ */
+function entity_test_entity_field_info_alter(&$info, $entity_type) {
+ if ($entity_type == 'entity_test_mulrev' && ($names = \Drupal::state()->get('entity_test.field_definitions.translatable'))) {
+ foreach ($names as $name => $value) {
+ $info['definitions'][$name]['translatable'] = $value;
+ }
+ }
+}
+
+/**
* Creates a new bundle for entity_test entities.
*
* @param string $bundle
diff --git a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
index 20becd1..99594ee 100644
--- a/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
+++ b/core/modules/taxonomy/lib/Drupal/taxonomy/Tests/TermTranslationUITest.php
@@ -90,9 +90,9 @@ class TermTranslationUITest extends ContentTranslationUITest {
// Make sure that no row was inserted for taxonomy vocabularies, which do
// not have translations enabled.
$rows = db_query('SELECT * FROM {content_translation}')->fetchAll();
- $this->assertEqual(2, count($rows));
- $this->assertEqual('taxonomy_term', $rows[0]->entity_type);
- $this->assertEqual('taxonomy_term', $rows[1]->entity_type);
+ foreach ($rows as $row) {
+ $this->assertEqual('taxonomy_term', $row->entity_type);
+ }
}
/**