translation_source->{$field_name}) || !is_array($node->translation_source->{$field_name})) { continue; } // If the i18n module is NOT enabled, then the Allowed Values related // queries in nodereference module are NOT filtered by language, hence // all references in source translation are still valid in new node. // @todo: In fact, this could really be fixed in nodereference module. if (!module_exists('i18n')) { $node->{$field_name} = $node->translation_source->{$field_name}; continue; } // When the i18n module is enabled, queries against the node table are // filtered to match the "Content selection mode" option enabled in the // site. Here, there are several options that allow language neutral // references, or options that allow only current language, default // language or both. However, when "Content selection mode" is disabled // all references in source translation are still valid in new node. // @todo: In fact, this could really be fixed in nodereference module. if (i18n_selection_mode() == 'off') { $node->{$field_name} = $node->translation_source->{$field_name}; continue; } // When the i18n module is enabled, and "Content selection mode" is not // disabled, then the i18n module applies a complex logic to alters node // related queries to enforce language selection options. // The easiest way to see if references in source translation are still // valid for new node is perform a query using n.nid IN (...) with the // help of the nodereference code used to check for valid allowed values. // So, let's extract references in the translation source that are still // valid for this translation. $ids = array(); foreach ($node->translation_source->{$field_name} as $delta => $item) { if (is_array($item) && !empty($item['nid']) && is_numeric($item['nid'])) { $ids[] = $item['nid']; } } $field = content_fields($field_name, $node->type); $valid_references = _nodereference_potential_references($field, '', NULL, $ids); // Ok, now we can try to rebuild the items of this nodereference field // while still keeping original deltas. $node->{$field_name} = array(); foreach ($node->translation_source->{$field_name} as $delta => $reference) { // Keep delta even when the reference does not exist. if (empty($reference['nid']) || !is_numeric($reference['nid'])) { $node->{$field_name}[$delta] = array('nid' => NULL); continue; } // If the reference is valid for the translation, just get it as-is. if (isset($valid_references[$reference['nid']])) { $node->{$field_name}[$delta] = $reference; continue; } // Here we have a reference that is not valid for the translation due to // content selection rules enforced by i18n module. Let's try to find // translations for these references. To do so, we first need to read // the original referenced node. $reference_node = node_load($reference['nid']); // If translation is not supported by reference in source translation, // we can only warn the user about it. It makes no sense to offer them // a method to translate something that cannot be translated. if (!translation_supported_type($reference_node->type)) { $node->{$field_name}[$delta] = array( 'translate_and_reference' => array( 'translation_supported' => FALSE, 'translation_source' => $reference_node, ), 'nid' => NULL, ); continue; } // Ok, let's see if we already have a translation for this reference // and use it if it exists. Note that we are creating a translation // here, so that means the node being translated has its language // attribute populated, and it is a valid language code. $translations = translation_node_get_translations($reference_node->tnid); if (!empty($translations) && isset($translations[$node->language])) { $node->{$field_name}[$delta] = array('nid' => $translations[$node->language]->nid); continue; } // Finally, we have a translatable reference that has not already been // translated. This is where our "Translate and reference" option can // add real value to the translation workflow. Let's provide a method // to easily translate this reference from the new node. $node->{$field_name}[$delta] = array( 'translate_and_reference' => array( 'translation_supported' => TRUE, 'translation_source' => $reference_node, ), 'nid' => NULL, ); } } } /** * Build translation settings for the current node edit form. */ function _noderelationships_parent_node_form_build_translation_settings(&$node, &$field_settings, $noderef_settings) { foreach ($field_settings as $field_name => $field_options) { // Skip if "Translate and reference" feature has not been enabled for this field. if (!isset($noderef_settings['translate_and_reference'][$field_name])) { continue; } // Skip if this field does not exist in current node. if (!isset($node->{$field_name}) || !is_array($node->{$field_name})) { continue; } // Scan all items in this nodereference field. foreach ($node->{$field_name} as $delta => $reference) { // Skip if manual translation for this reference if not required. if (!isset($reference['translate_and_reference']) || empty($reference['translate_and_reference']['translation_source'])) { continue; } $reference_source = $reference['translate_and_reference']['translation_source']; // Generate a warning message for the user to note a translation for this // reference is missing. // Also, allow them to review the source reference on new window. $field_settings[$field_name]['missingTranslations'][$delta] = t('Missing translation for !title.', array( '!title' => l($reference_source->title .' [nid: '. $reference_source->nid .']', 'node/'. $reference_source->nid, array( 'attributes' => array( 'target' => '_blank', 'title' => t('View @title [nid: @nid] in new window...', array( '@title' => $reference_source->title, '@nid' => $reference_source->nid, )), ), )), )); // Provide a link to "Translate and reference" when possible. if ($reference['translate_and_reference']['translation_supported']) { $field_settings[$field_name]['missingTranslations'][$delta] .= ' '. t('You can !translate now.', array( '!translate' => l(t('translate and reference'), 'noderelationships/create/'. $node->type .'/'. $field_name, array( 'query' => 'translation='. $reference_source->nid .'&language='. $GLOBALS['language']->language, 'attributes' => array( 'class' => 'noderelationships-translate', 'title' => t('Click here to translate and reference @title [nid: @nid] now.', array( '@title' => $reference_source->title, '@nid' => $reference_source->nid, )), ), )), )); } else { $field_settings[$field_name]['missingTranslations'][$delta] .= ' '. t('Translation of this reference is not supported.'); } } } }