diff --git a/core/modules/content_translation/config/content_translation.field_settings.yml b/core/modules/content_translation/config/content_translation.field_settings.yml new file mode 100644 index 0000000..f3120e5 --- /dev/null +++ b/core/modules/content_translation/config/content_translation.field_settings.yml @@ -0,0 +1 @@ +translation_sync: { } diff --git a/core/modules/content_translation/config/schema/content_translation.field_settings.schema.yml b/core/modules/content_translation/config/schema/content_translation.field_settings.schema.yml new file mode 100644 index 0000000..dfdb104 --- /dev/null +++ b/core/modules/content_translation/config/schema/content_translation.field_settings.schema.yml @@ -0,0 +1,21 @@ +# Schema for field settings for the Content Translation module. + +content_translation.field_settings: + type: mapping + label: 'Content translation field settings' + mapping: + translation_sync: + type: sequence + label: 'Field translation synchronisation settings' + sequence: + - type: sequence + label: 'Entity type' + sequence: + - type: sequence + label: 'Bundle' + sequence: + - type: sequence + label: 'Field' + sequence: + - type: string + label: 'Column' diff --git a/core/modules/content_translation/content_translation.admin.inc b/core/modules/content_translation/content_translation.admin.inc index 557f06e..b416173 100644 --- a/core/modules/content_translation/content_translation.admin.inc +++ b/core/modules/content_translation/content_translation.admin.inc @@ -6,7 +6,6 @@ */ use Drupal\Component\Utility\String; -use Drupal\Core\Field\FieldDefinitionInterface; use Drupal\Core\Language\Language; use Drupal\Core\Render\Element; use Drupal\field\Field as FieldService; @@ -15,13 +14,13 @@ /** * Returns a form element to configure field synchronization. * - * @param \Drupal\Core\Field\FieldDefinitionInterface $field - * A field definition object. + * @param \Drupal\field\FieldInstanceConfigInterface $field + * A field instance. * * @return array * A form element to configure field synchronization. */ -function content_translation_field_sync_widget(FieldDefinitionInterface $field) { +function content_translation_field_sync_widget(FieldInstanceConfigInterface $field) { $element = array(); $definition = \Drupal::service('plugin.manager.field.field_type')->getDefinition($field->getType()); @@ -37,12 +36,18 @@ function content_translation_field_sync_widget(FieldDefinitionInterface $field) $settings = array('dependent_selectors' => array('instance[settings][translation_sync]' => array('file'))); - $translation_sync = $field->getSetting('translation_sync'); + // Create an associative array of column groups, keyed on column name, with + // the value of disabled columns set to FALSE. + $translation_sync = content_translation_get_field_config($field, 'translation_sync') ?: array(); + $default = array_map(function ($value) use ($translation_sync) { + return in_array($value, $translation_sync) ? $value : FALSE; + }, array_combine(array_keys($default), array_keys($default))); + $element = array( '#type' => 'checkboxes', '#title' => t('Translatable elements'), '#options' => $options, - '#default_value' => !empty($translation_sync) ? $translation_sync : $default, + '#default_value' => $default, '#attached' => array( 'library' => array( 'content_translation/drupal.content_translation.admin', diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 8739c84..2eb5ce8 100644 --- a/core/modules/content_translation/content_translation.module +++ b/core/modules/content_translation/content_translation.module @@ -14,6 +14,7 @@ use Drupal\Core\Language\Language; use Drupal\Core\Session\AccountInterface; use Drupal\Core\TypedData\TranslatableInterface; +use Drupal\field\FieldInstanceConfigInterface; use Drupal\node\NodeInterface; /** @@ -311,6 +312,47 @@ function content_translation_set_config($entity_type, $bundle, $setting, $value) } /** + * Retrieves the value for the given field setting. + * + * @param \Drupal\field\FieldInstanceConfigInterface $field + * The field for which to retrieve the value. + * @param string $setting + * The field setting to retrieve. + * + * @return mixed|NULL + * The configuration value, or NULL if no value was set. + */ +function content_translation_get_field_config(FieldInstanceConfigInterface $field, $setting) { + return \Drupal::config('content_translation.field_settings')->get($setting . '.' . $field->id()); +} + +/** + * Stores configuration for the given field setting. + * + * @param \Drupal\field\FieldInstanceConfigInterface $field + * The field for which to store the value. + * @param string $setting + * The field setting to store. + * @param mixed $value + * The configuration to store. + */ +function content_translation_set_field_config(FieldInstanceConfigInterface $field, $setting, $value) { + \Drupal::config('content_translation.field_settings')->set($setting . '.' . $field->id(), $value)->save(); +} + +/** + * Clears the configuration for the given field setting. + * + * @param \Drupal\field\FieldInstanceConfigInterface $field + * The field for which to clear the configuration. + * @param string $setting + * The field setting to clear. + */ +function content_translation_clear_field_config(FieldInstanceConfigInterface $field, $setting) { + \Drupal::config('content_translation.field_settings')->clear($setting . '.' . $field->id())->save(); +} + +/** * Determines whether the given entity type is translatable. * * @param string $entity_type @@ -682,29 +724,28 @@ function content_translation_form_field_ui_field_edit_form_submit($form, array & * Implements hook_form_FORM_ID_alter() for 'field_ui_field_instance_edit_form'. */ function content_translation_form_field_ui_field_instance_edit_form_alter(array &$form, array &$form_state, $form_id) { - if ($form['#field']->isTranslatable()) { + if ($form_state['instance']->isTranslatable()) { module_load_include('inc', 'content_translation', 'content_translation.admin'); - $element = content_translation_field_sync_widget($form['#field']); + $element = content_translation_field_sync_widget($form_state['instance']); if ($element) { $form['instance']['settings']['translation_sync'] = $element; + $form['#submit'][] = 'content_translation_form_field_ui_field_instance_edit_form_submit'; } } } /** + * Form submission handler for 'field_ui_field_instance_edit_form'. + */ +function content_translation_form_field_ui_field_instance_edit_form_submit($form, array &$form_state) { + $value = array_keys(array_filter($form_state['values']['instance']['settings']['translation_sync'])); + content_translation_set_field_config($form_state['instance'], 'translation_sync', $value); +} + +/** * Implements hook_entity_presave(). */ function content_translation_entity_presave(EntityInterface $entity) { - // By default no column has to be synchronized. - // @todo Replace with own storage in https://drupal.org/node/2224761 - if ($entity->getEntityTypeId() === 'field_config') { - $entity->settings += array('translation_sync' => FALSE); - } - // Synchronization can be enabled per instance. - // @todo Replace with own storage in https://drupal.org/node/2224761 - if ($entity->getEntityTypeId() === 'field_instance_config') { - $entity->settings += array('translation_sync' => FALSE); - } if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) { // @todo Avoid using request attributes once translation metadata become // regular fields. @@ -865,14 +906,15 @@ function content_translation_save_settings($settings) { // Store whether fields have translation enabled or not. if (!empty($bundle_settings['columns'])) { foreach ($bundle_settings['columns'] as $field_name => $column_settings) { + $column_settings = array_keys(array_filter($column_settings)); $instance = field_info_instance($entity_type, $field_name, $bundle); if ($instance->isTranslatable()) { - $instance->settings['translation_sync'] = $column_settings; + content_translation_set_field_config($instance, 'translation_sync', $column_settings); } // If the field does not have translatable enabled we need to reset // the sync settings to their defaults. else { - unset($instance->settings['translation_sync']); + content_translation_clear_field_config($instance, 'translation_sync'); } $instance->save(); } diff --git a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php index 196512b..4d42d9e 100644 --- a/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php +++ b/core/modules/content_translation/lib/Drupal/content_translation/FieldTranslationSynchronizer.php @@ -61,10 +61,11 @@ public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode // Sync if the field is translatable, not empty, and the synchronization // setting is enabled. - if ($field_definition->isTranslatable() && !$items->isEmpty() && $translation_sync = $field_definition->getSetting('translation_sync')) { + $key = 'translation_sync.' . $entity->getEntityTypeId() . '.' . $entity->bundle() . '.' . $field_name; + if ($field_definition->isTranslatable() && !$items->isEmpty() && $translation_sync = \Drupal::config('content_translation.field_settings')->get($key)) { // Retrieve all the untranslatable column groups and merge them into // single list. - $groups = array_keys(array_diff($translation_sync, array_filter($translation_sync))); + $groups = array_diff(array_keys($field_type_definition['column_groups']), $translation_sync); if (!empty($groups)) { $columns = array(); foreach ($groups as $group) { 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 3f990db..eb93da9 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 @@ -69,14 +69,25 @@ protected function setupTestFields() { 'field_name' => $this->fieldName, 'bundle' => $this->entityTypeId, 'label' => 'Test translatable image field', - 'settings' => array( - 'translation_sync' => array( - 'file' => FALSE, - 'alt' => 'alt', - 'title' => 'title', + ))->save(); + + // Enable content translation for image field on the test entity. + $settings = array( + 'content_translation' => array( + 'enabled' => TRUE, + 'fields' => array( + $this->fieldName => TRUE, ), ), - ))->save(); + ); + $key = $this->entityTypeId . '.' . $this->entityTypeId; + \Drupal::config('content_translation.settings')->set($key, $settings)->save(); + + // Enable content translation for the 'alt' and 'title' properties on the + // image field. + $settings = array('alt', 'title'); + $key = 'translation_sync.' . $this->entityTypeId . '.' . $this->entityTypeId . '.' . $this->fieldName; + \Drupal::config('content_translation.field_settings')->set($key, $settings)->save(); } /**