diff --git a/core/modules/content_translation/config/schema/content_translation.settings.schema.yml b/core/modules/content_translation/config/schema/content_translation.settings.schema.yml new file mode 100644 index 0000000..f61248f --- /dev/null +++ b/core/modules/content_translation/config/schema/content_translation.settings.schema.yml @@ -0,0 +1,32 @@ +# Schema for the settings for the Content Translation module. + +#content_translation.settings: +# type: sequence +# label: 'Entity type' +# sequence: +# - type: sequence +# label: 'Bundle' +# sequence: +# - type: mapping +# label: 'Content translation settings' +# mapping: +# content_translation: +# type: mapping +# mapping: +# enabled: +# type: boolean +# label: 'Content translation status' +# fields: +# type: sequence +# sequence: +# - type: boolean +# label: 'Per field content translation' +# translation_sync: +# type: sequence +# label: 'Field translation synchronisation settings' +# 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..b8b3f94 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_sync($field) ?: 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.install b/core/modules/content_translation/content_translation.install index b814f2d..ec888b4 100644 --- a/core/modules/content_translation/content_translation.install +++ b/core/modules/content_translation/content_translation.install @@ -88,19 +88,6 @@ function content_translation_install() { // hook_module_implements_alter() is run among the last ones. module_set_weight('content_translation', 10); \Drupal::service('language_negotiator')->saveConfiguration(Language::TYPE_CONTENT, array(LanguageNegotiationUrl::METHOD_ID => 0)); - - $config_names = \Drupal::configFactory()->listAll('field.field.'); - foreach ($config_names as $name) { - \Drupal::config($name) - ->set('settings.translation_sync', FALSE) - ->save(); - } - $config_names = \Drupal::configFactory()->listAll('field.instance.'); - foreach ($config_names as $name) { - \Drupal::config($name) - ->set('settings.translation_sync', FALSE) - ->save(); - } } /** diff --git a/core/modules/content_translation/content_translation.module b/core/modules/content_translation/content_translation.module index 38b5b41..56e0a73 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,60 @@ 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. + * + * @return mixed|NULL + * The configuration value, or NULL if no value was set. + */ +function content_translation_get_field_sync(FieldInstanceConfigInterface $field) { + $key = _content_translation_get_field_sync_key($field); + return \Drupal::config('content_translation.settings')->get($key); +} + +/** + * Stores configuration for the given field setting. + * + * @param \Drupal\field\FieldInstanceConfigInterface $field + * The field for which to store the value. + * @param mixed $value + * The configuration to store. + */ +function content_translation_set_field_sync(FieldInstanceConfigInterface $field, $value) { + $key = _content_translation_get_field_sync_key($field); + \Drupal::config('content_translation.settings')->set($key, $value)->save(); +} + +/** + * Clears the configuration for the given field setting. + * + * @param \Drupal\field\FieldInstanceConfigInterface $field + * The field for which to clear the configuration. + */ +function content_translation_clear_field_sync(FieldInstanceConfigInterface $field) { + $key = _content_translation_get_field_sync_key($field); + \Drupal::config('content_translation.settings')->clear($key)->save(); +} + +/** + * Creates translation sync configuration key. + * + * @param FieldInstanceConfigInterface $field + * The field for which to create the key. + * + * @return string + * The configuration key. + */ +function _content_translation_get_field_sync_key(FieldInstanceConfigInterface $field) { + $entity_type = preg_replace('/[^0-9a-zA-Z_]/', "_", $field->getTargetEntityTypeId()); + $bundle = preg_replace('/[^0-9a-zA-Z_]/', "_", $field->targetBundle()); + $field_name = preg_replace('/[^0-9a-zA-Z_]/', "_", $field->getField()->getName()); + return $entity_type . '.' . $bundle . '.translation_sync.' . $field_name; +} + +/** * Determines whether the given entity type is translatable. * * @param string $entity_type @@ -687,24 +742,23 @@ function content_translation_form_field_ui_field_instance_edit_form_alter(array $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_sync($form_state['instance'], $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 +919,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_sync($instance, $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_sync($instance); } $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..09e7e2e 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 = $entity->getEntityTypeId() . '.' . $entity->bundle() . '.translation_sync.' . $field_name; + if ($field_definition->isTranslatable() && !$items->isEmpty() && $translation_sync = \Drupal::config('content_translation.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..5f6a265 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 @@ -2,7 +2,7 @@ /** * @file - * Contains \Drupal\entity\Tests\ContentTranslationSyncImageTest. + * Contains \Drupal\content_translation\Tests\ContentTranslationSyncImageTest. */ namespace Drupal\content_translation\Tests; @@ -64,19 +64,31 @@ protected function setupTestFields() { 'translatable' => TRUE, ))->save(); - entity_create('field_instance_config', array( + $field_instance = entity_create('field_instance_config', array( 'entity_type' => $this->entityTypeId, 'field_name' => $this->fieldName, 'bundle' => $this->entityTypeId, 'label' => 'Test translatable image field', - 'settings' => array( - 'translation_sync' => array( - 'file' => FALSE, - 'alt' => 'alt', - 'title' => 'title', + )); + $field_instance->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 = _content_translation_get_field_sync_key($field_instance); + \Drupal::config('content_translation.settings')->set($key, $settings)->save(); } /**