Commit cf30c78b authored by webchick's avatar webchick

#362021 by plach, yched, sun: Update field_attach_prepare_translation() for D7 entity API.

parent 8fb6adbc
......@@ -564,8 +564,6 @@ function hook_field_delete_revision($entity_type, $entity, $field, $instance, $l
/**
* Define custom prepare_translation behavior for this module's field types.
*
* TODO: This hook may or may not survive in Field API.
*
* @param $entity_type
* The type of $entity.
* @param $entity
......@@ -578,8 +576,20 @@ function hook_field_delete_revision($entity_type, $entity, $field, $instance, $l
* The language associated to $items.
* @param $items
* $entity->{$field['field_name']}[$langcode], or an empty array if unset.
*/
function hook_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items) {
* @param $source_entity
* The source entity from which field values are being copied.
* @param $source_langcode
* The source language from which field values are being copied.
*/
function hook_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
// If the translating user is not permitted to use the assigned text format,
// we must not expose the source values.
$field_name = $field['field_name'];
$formats = filter_formats();
$format_id = $source_entity->{$field_name}[$source_langcode][0]['format'];
if (!filter_access($formats[$format_id])) {
$items = array();
}
}
/**
......@@ -1179,6 +1189,26 @@ function hook_field_attach_view_alter(&$output, $context) {
// @todo Needs function body.
}
/**
* Perform alterations on field_attach_prepare_translation().
*
* This hook is invoked after the field module has performed the operation.
*
* @param &$entity
* The entity being prepared for translation.
* @param $context
* An associative array containing:
* - entity_type: The type of $entity; e.g. 'node' or 'user'.
* - langcode: The language the entity has to be translated in.
* - source_entity: The entity holding the field values to be translated.
* - source_langcode: The source language from which translate.
*/
function hook_field_attach_prepare_translation_alter(&$entity, $context) {
if ($context['entity_type'] == 'custom_entity_type') {
$entity->custom_field = $context['source_entity']->custom_field;
}
}
/**
* Perform alterations on field_language() values.
*
......
......@@ -1325,23 +1325,42 @@ function field_attach_preprocess($entity_type, $entity, $element, &$variables) {
}
/**
* Implements hook_node_prepare_translation().
* Prepares an entity for translation.
*
* TODO D7: We do not yet know if this really belongs in Field API.
* This function is used to fill-in the form default values for Field API fields
* while performing entity translation. By default it copies all the source
* values in the given source language to the new entity and assigns them the
* target language.
*
* This is used as part of the 'per entity' translation pattern, which is
* implemented only for nodes by translation.module. Other entity types may be
* supported through contributed modules.
*
* @param $entity_type
* The type of $entity; e.g. 'node' or 'user'.
* @param $entity
* The entity to be prepared for translation.
* @param $langcode
* The language the entity has to be translated in.
* @param $source_entity
* The source entity holding the field values to be translated.
* @param $source_langcode
* The source language from which translate.
*/
function field_attach_prepare_translation($node) {
// Prevent against invalid 'nodes' built by broken 3rd party code.
if (isset($node->type)) {
$type = content_types($node->type);
// Save cycles if the type has no fields.
if (!empty($type['instances'])) {
$default_additions = _field_invoke_default('prepare_translation', $node);
$additions = _field_invoke('prepare_translation', $node);
// Merge module additions after the default ones to enable overriding
// of field values.
$node = (object) array_merge((array) $node, $default_additions, $additions);
}
}
function field_attach_prepare_translation($entity_type, $entity, $langcode, $source_entity, $source_langcode) {
$options = array('language' => $langcode);
// Copy source field values into the entity to be prepared.
_field_invoke_default('prepare_translation', $entity_type, $entity, $source_entity, $source_langcode, $options);
// Let field types handle their own advanced translation pattern if needed.
_field_invoke('prepare_translation', $entity_type, $entity, $source_entity, $source_langcode, $options);
// Let other modules alter the entity translation.
$context = array(
'entity_type' => $entity_type,
'langcode' => $langcode,
'source_entity' => $source_entity,
'source_langcode' => $source_langcode,
);
drupal_alter('field_attach_prepare_translation', $entity, $context);
}
/**
......
......@@ -226,10 +226,33 @@ function field_default_view($entity_type, $entity, $field, $instance, $langcode,
return $addition;
}
function field_default_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items) {
$addition = array();
if (isset($entity->translation_source->$field['field_name'])) {
$addition[$field['field_name']] = $entity->translation_source->$field['field_name'];
/**
* Copies source field values into the entity to be prepared.
*
* @param $entity_type
* The type of $entity; e.g. 'node' or 'user'.
* @param $entity
* The entity to be prepared for translation.
* @param $field
* The field structure for the operation.
* @param $instance
* The instance structure for $field on $entity's bundle.
* @param $langcode
* The language the entity has to be translated in.
* @param $items
* $entity->{$field['field_name']}[$langcode], or an empty array if unset.
* @param $source_entity
* The source entity holding the field values to be translated.
* @param $source_langcode
* The source language from which translate.
*/
function field_default_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
$field_name = $field['field_name'];
// If the field is untranslatable keep using LANGUAGE_NONE.
if ($langcode == LANGUAGE_NONE) {
$source_langcode = LANGUAGE_NONE;
}
if (isset($source_entity->{$field_name}[$source_langcode])) {
$items = $source_entity->{$field_name}[$source_langcode];
}
return $addition;
}
......@@ -590,3 +590,16 @@ function text_field_widget_error($element, $error, $form, &$form_state) {
form_error($error_element, $error['message']);
}
/**
* Implements hook_field_prepare_translation().
*/
function text_field_prepare_translation($entity_type, $entity, $field, $instance, $langcode, &$items, $source_entity, $source_langcode) {
// If the translating user is not permitted to use the assigned text format,
// we must not expose the source values.
$field_name = $field['field_name'];
$formats = filter_formats();
$format_id = $source_entity->{$field_name}[$source_langcode][0]['format'];
if (!filter_access($formats[$format_id])) {
$items = array();
}
}
......@@ -96,8 +96,7 @@
* an existing node, it will already be loaded; see the Loading section
* above):
* - hook_prepare() (node-type-specific)
* - hook_node_prepare() (all); if translation.module is enabled, this will
* also invoke hook_node_prepare_translation() on all modules.
* - hook_node_prepare() (all)
* - hook_form() (node-type-specific)
* - field_attach_form()
* - Validating a node during editing form submit (calling
......@@ -554,21 +553,6 @@ function hook_node_prepare($node) {
}
}
/**
* Act on a node object being cloned for translation.
*
* This hook is invoked from translation_node_prepare() after the node is
* loaded. $node->language is set to the language being requested, and
* $node->translation_source is set to the node object being cloned.
*
* @param $node
* The node object being prepared for translation.
*
* @ingroup node_api_hooks
*/
function hook_node_prepare_translation($node) {
}
/**
* Act on a node being displayed as a search result.
*
......
......@@ -461,11 +461,11 @@ function poll_validate($node, $form) {
}
/**
* Implements hook_node_prepare_translation().
* Implements hook_field_attach_prepare_translation_alter().
*/
function poll_node_prepare_translation($node) {
if ($node->type == 'poll') {
$node->choice = $node->translation_source->choice;
function poll_field_attach_prepare_translation_alter(&$entity, $context) {
if ($context['entity_type'] == 'node' && $entity->type == 'poll') {
$entity->choice = $context['source_entity']->choice;
}
}
......
......@@ -240,13 +240,9 @@ function translation_node_prepare($node) {
$node->translation_source = $source_node;
$node->title = $source_node->title;
// If user has no access to the filter used for the body, Drupal core
// does not let the edit form to appear, so we should avoid exposing
// the source text here too.
$formats = filter_formats();
$node->body = (filter_access($formats[$source_node->body[$source_node->language][0]['format']])) ? $source_node->body : '';
// Let every module add custom translated fields.
module_invoke_all('node_prepare_translation', $node);
// Add field translations and let other modules module add custom translated
// fields.
field_attach_prepare_translation('node', $node, $node->language, $source_node, $source_node->language);
}
}
......
......@@ -48,7 +48,7 @@ class TranslationTestCase extends DrupalWebTestCase {
// Submit translation in Spanish.
$node_translation_title = $this->randomName();
$node_translation_body = $this->randomName();
$node_translation = $this->createTranslation($node->nid, $node_translation_title, $node_translation_body, 'es');
$node_translation = $this->createTranslation($node, $node_translation_title, $node_translation_body, 'es');
// Attempt to submit a duplicate translation by visiting the node/add page
// with identical query string.
......@@ -153,13 +153,16 @@ class TranslationTestCase extends DrupalWebTestCase {
* @param string $body Body of basic page in specified language.
* @param string $language Language code.
*/
function createTranslation($nid, $title, $body, $language) {
$this->drupalGet('node/add/page', array('query' => array('translation' => $nid, 'language' => $language)));
function createTranslation($node, $title, $body, $language) {
$this->drupalGet('node/add/page', array('query' => array('translation' => $node->nid, 'language' => $language)));
$body_key = "body[$language][0][value]";
$this->assertFieldByXPath('//input[@id="edit-title"]', $node->title, "Original title value correctly populated.");
$this->assertFieldByXPath("//textarea[@name='$body_key']", $node->body[$node->language][0]['value'], "Original body value correctly populated.");
$edit = array();
$langcode = LANGUAGE_NONE;
$edit["title"] = $title;
$edit["body[$language][0][value]"] = $body;
$edit[$body_key] = $body;
$this->drupalPost(NULL, $edit, t('Save'));
$this->assertRaw(t('Basic page %title has been created.', array('%title' => $title)), t('Translation created.'));
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment