nid == $translation->nid) { continue; } // Load full node, we need all data here. $translation = node_load($translation->nid, NULL, TRUE); $i18n_options = i18n_sync_node_options($node->type); // Invoke callback for each field, the default is just copy over foreach ($field_names as $field) { if (!empty($i18n_options[$field]['field_name'])) { i18n_sync_field_translation_sync('node', $node->type, $translation, $translation->language, $node, $node->language, $i18n_options[$field]['field_name']); } elseif (isset($node->$field)) { // Standard node field, just copy over. $translation->$field = $node->$field; } } // Give a chance to other modules for additional sync module_invoke_all('i18n_sync_translation', 'node', $translation, $translation->language, $node, $node->language, $field_names); node_save($translation); $count++; } i18n_sync(TRUE); i18n_select(TRUE); drupal_set_message(format_plural($count, 'One node translation has been synchronized.', 'All @count node translations have been synchronized.')); } /** * Node attachments (CCK) that may have translation. */ function i18n_sync_node_translation_attached_node(&$node, &$translation, $field) { if ($attached = node_load($node->$field)) { $translation->$field = i18n_sync_node_translation_reference_field($attached, $node->$field, $translation->language); } } /** * Translating a nodereference field (cck). */ function i18n_sync_node_translation_nodereference_field(&$node, &$translation, $field) { $translated_references = array(); foreach ($node->$field as $reference) { if ($reference_node = node_load($reference['nid'])) { $translated_references[] = array( 'nid' => i18n_sync_node_translation_reference_field($reference_node, $reference['nid'], $translation->language) ); } } $translation->$field = $translated_references; } /** * Helper function to which translates reference field. We try to use translations for reference, otherwise fallback. * Example: * English A references English B and English C. * English A and B are translated to German A and B, but English C is not. * The syncronization from English A to German A would it German B and English C. */ function i18n_sync_node_translation_reference_field(&$reference_node, $default_value, $langcode) { if (isset($reference_node->tnid) && translation_supported_type($reference_node->type)) { // This content type has translations, find the one. if (($reference_trans = translation_node_get_translations($reference_node->tnid)) && isset($reference_trans[$langcode])) { return $reference_trans[$langcode]->nid; } else { // No requested language found, just copy the field. return $default_value; } } else { // Content type without language, just copy the field. return $default_value; } } /** * Synchronize configurable field * * @param $field_info * Field API field information. */ function i18n_sync_node_translation_default_field($node, $translation, $field, $field_info) { switch ($field_info['field']['type']) { case 'file': case 'image': i18n_sync_node_translation_file_field($node, $translation, $field); break; default: // For fields that don't need special handling, just copy it over if defined. if (isset($node->{$field}[$node->language])) { $translation->{$field}[$translation->language] = $node->{$field}[$node->language]; } break; } } /** * Sync a file or image field: * - file-id's (fid) are synced * - order of fid's is synced * - description, alt, title is kept if already existing, copied otherwise * * @param object $node the node whose changes are to be synced * @param object $translation a node to which the changes need to be synced * @param string $field field name */ function i18n_sync_node_translation_file_field($node, $translation, $field) { if (isset($node->{$field}[$node->language])) { // Build a copy of the existing files in the translation node // indexed by fid for easy retrieval in the copy loop below $existing_files = array(); if (isset($translation->{$field}[$translation->language])) { foreach ($translation->{$field}[$translation->language] as $delta => $file) { $existing_files[$file['fid']] = $file; } } // Start creating the translated copy $translated_files = $node->{$field}[$node->language]; foreach ($translated_files as $delta => &$file) { // keep alt, title, description if they already exist if (array_key_exists($file['fid'], $existing_files)) { foreach (array('title', 'description', 'alt') as $property) { if (!empty($existing_files[$file['fid']][$property])) { $file[$property] = $existing_files[$file['fid']][$property]; } } } } $translation->{$field}[$translation->language] = $translated_files; } }