diff --git a/includes/common.inc b/includes/common.inc index ce369332f5321eb6ae8134a3f6e028529aeac7e8..d4461f9396a3d3a76d22b6ef88b3f69ec5f44845 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -7492,8 +7492,15 @@ function entity_get_controller($entity_type) { * The type of entity, i.e. 'node', 'user'. * @param $entities * The entity objects which are being prepared for view, keyed by object ID. + * @param $langcode + * (optional) A language code to be used for rendering. Defaults to the global + * content language of the current request. */ -function entity_prepare_view($entity_type, $entities) { +function entity_prepare_view($entity_type, $entities, $langcode = NULL) { + if (!isset($langcode)) { + $langcode = $GLOBALS['language_content']->language; + } + // To ensure hooks are only run once per entity, check for an // entity_view_prepared flag and only process items without it. // @todo: resolve this more generally for both entity and field level hooks. @@ -7509,7 +7516,7 @@ function entity_prepare_view($entity_type, $entities) { } if (!empty($prepare)) { - module_invoke_all('entity_prepare_view', $prepare, $entity_type); + module_invoke_all('entity_prepare_view', $prepare, $entity_type, $langcode); } } diff --git a/modules/comment/comment.module b/modules/comment/comment.module index 55c6fcbb0e2c0bca4882d6df4633f86b7c214f70..0fc38f8ddaeade6f147fc87d9cdf1897840a0756 100644 --- a/modules/comment/comment.module +++ b/modules/comment/comment.module @@ -988,8 +988,8 @@ function comment_build_content($comment, $node, $view_mode = 'full', $langcode = $comment->content = array(); // Build fields content. - field_attach_prepare_view('comment', array($comment->cid => $comment), $view_mode); - entity_prepare_view('comment', array($comment->cid => $comment)); + field_attach_prepare_view('comment', array($comment->cid => $comment), $view_mode, $langcode); + entity_prepare_view('comment', array($comment->cid => $comment), $langcode); $comment->content += field_attach_view('comment', $comment, $view_mode, $langcode); $comment->content['links'] = array( @@ -1091,8 +1091,8 @@ function comment_links($comment, $node) { * An array in the format expected by drupal_render(). */ function comment_view_multiple($comments, $node, $view_mode = 'full', $weight = 0, $langcode = NULL) { - field_attach_prepare_view('comment', $comments, $view_mode); - entity_prepare_view('comment', $comments); + field_attach_prepare_view('comment', $comments, $view_mode, $langcode); + entity_prepare_view('comment', $comments, $langcode); $build = array( '#sorted' => TRUE, diff --git a/modules/field/field.attach.inc b/modules/field/field.attach.inc index 82aabc054fc7aa97c2ca9ec7b876a270bdc55c7b..3b15c76c87bc65e90028fcfe2557956892d49132 100644 --- a/modules/field/field.attach.inc +++ b/modules/field/field.attach.inc @@ -257,9 +257,9 @@ function _field_invoke($op, $entity_type, $entity, &$a = NULL, &$b = NULL, $opti * - 'deleted': If TRUE, the function will operate on deleted fields * as well as non-deleted fields. If unset or FALSE, only * non-deleted fields are operated on. - * - 'language': A language code or an array of language codes keyed by field - * name. It will be used to narrow down to a single value the available - * languages to act on. + * - 'language': A language code or an array of arrays of language codes keyed + * by entity id and field name. It will be used to narrow down to a single + * value the available languages to act on. * * @return * An array of returned values keyed by entity id. @@ -311,7 +311,8 @@ function _field_invoke_multiple($op, $entity_type, $entities, &$a = NULL, &$b = // Unless a language suggestion is provided we iterate on all the // available languages. $available_languages = field_available_languages($entity_type, $field); - $languages = _field_language_suggestion($available_languages, $options['language'], $field_name); + $language = !empty($options['language'][$id]) ? $options['language'][$id] : $options['language']; + $languages = _field_language_suggestion($available_languages, $language, $field_name); foreach ($languages as $langcode) { $grouped_items[$field_id][$langcode][$id] = isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : array(); } @@ -1074,8 +1075,13 @@ function field_attach_delete_revision($entity_type, $entity) { * An array of entities, keyed by entity id. * @param $view_mode * View mode, e.g. 'full', 'teaser'... + * @param $langcode + * (Optional) The language the field values are to be shown in. If no language + * is provided the current language is used. */ -function field_attach_prepare_view($entity_type, $entities, $view_mode) { +function field_attach_prepare_view($entity_type, $entities, $view_mode, $langcode = NULL) { + $options = array('language' => array()); + // To ensure hooks are only run once per entity, only process items without // the _field_view_prepared flag. // @todo: resolve this more generally for both entity and field level hooks. @@ -1085,17 +1091,22 @@ function field_attach_prepare_view($entity_type, $entities, $view_mode) { // Add this entity to the items to be prepared. $prepare[$id] = $entity; + // Determine the actual language to display for each field, given the + // languages available in the field data. + $options['language'][$id] = field_language($entity_type, $entity, NULL, $langcode); + // Mark this item as prepared. $entity->_field_view_prepared = TRUE; } } + $null = NULL; // First let the field types do their preparation. - _field_invoke_multiple('prepare_view', $entity_type, $prepare); + _field_invoke_multiple('prepare_view', $entity_type, $prepare, $null, $null, $options); // Then let the formatters do their own specific massaging. // field_default_prepare_view() takes care of dispatching to the correct // formatters according to the display settings for the view mode. - _field_invoke_multiple_default('prepare_view', $entity_type, $prepare, $view_mode); + _field_invoke_multiple_default('prepare_view', $entity_type, $prepare, $view_mode, $null, $options); } /** diff --git a/modules/node/node.module b/modules/node/node.module index a002e24c31fb773116bc36c101c1c21fce0cfb23..d19cf2985a54a2ce8b8ff26bee5f842be49d9391 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -1350,15 +1350,15 @@ function node_build_content($node, $view_mode = 'full', $langcode = NULL) { // The 'view' hook can be implemented to overwrite the default function // to display nodes. if (node_hook($node, 'view')) { - $node = node_invoke($node, 'view', $view_mode); + $node = node_invoke($node, 'view', $view_mode, $langcode); } // Build fields content. // In case of a multiple view, node_view_multiple() already ran the // 'prepare_view' step. An internal flag prevents the operation from running // twice. - field_attach_prepare_view('node', array($node->nid => $node), $view_mode); - entity_prepare_view('node', array($node->nid => $node)); + field_attach_prepare_view('node', array($node->nid => $node), $view_mode, $langcode); + entity_prepare_view('node', array($node->nid => $node), $langcode); $node->content += field_attach_view('node', $node, $view_mode, $langcode); // Always display a read more link on teasers because we have no way @@ -2517,8 +2517,8 @@ function node_feed($nids = FALSE, $channel = array()) { * An array in the format expected by drupal_render(). */ function node_view_multiple($nodes, $view_mode = 'teaser', $weight = 0, $langcode = NULL) { - field_attach_prepare_view('node', $nodes, $view_mode); - entity_prepare_view('node', $nodes); + field_attach_prepare_view('node', $nodes, $view_mode, $langcode); + entity_prepare_view('node', $nodes, $langcode); $build = array(); foreach ($nodes as $node) { $build['nodes'][$node->nid] = node_view($node, $view_mode, $langcode); diff --git a/modules/system/system.api.php b/modules/system/system.api.php index e38641f48ca0c1cae5c166731d654acb83c9cf21..9f56abade313407536d85b183690429c4e64ffd9 100644 --- a/modules/system/system.api.php +++ b/modules/system/system.api.php @@ -502,8 +502,10 @@ function hook_admin_paths_alter(&$paths) { * The entities keyed by entity ID. * @param $type * The type of entities being loaded (i.e. node, user, comment). + * @param $langcode + * The language to display the entity in. */ -function hook_entity_prepare_view($entities, $type) { +function hook_entity_prepare_view($entities, $type, $langcode) { // Load a specific node into the user object for later theming. if ($type == 'user') { $nodes = mymodule_get_user_nodes(array_keys($entities)); diff --git a/modules/taxonomy/taxonomy.module b/modules/taxonomy/taxonomy.module index f08df601e3b78a470c12d5fb832f470775afb2c8..71f3edbd9166803ffdea3b0d4d5ed5b484eb6aec 100644 --- a/modules/taxonomy/taxonomy.module +++ b/modules/taxonomy/taxonomy.module @@ -682,8 +682,8 @@ function taxonomy_term_view($term, $view_mode = 'full', $langcode = NULL) { $langcode = $GLOBALS['language_content']->language; } - field_attach_prepare_view('taxonomy_term', array($term->tid => $term), $view_mode); - entity_prepare_view('taxonomy_term', array($term->tid => $term)); + field_attach_prepare_view('taxonomy_term', array($term->tid => $term), $view_mode, $langcode); + entity_prepare_view('taxonomy_term', array($term->tid => $term), $langcode); $build = array( '#theme' => 'taxonomy_term', diff --git a/modules/user/user.module b/modules/user/user.module index 0c437ad41bfaea4c4ff77be8514e752bd10d024c..40023d3d12b659bc6dd04ff13897de7e639f3716 100644 --- a/modules/user/user.module +++ b/modules/user/user.module @@ -2523,8 +2523,8 @@ function user_build_content($account, $view_mode = 'full', $langcode = NULL) { $account->content = array(); // Build fields content. - field_attach_prepare_view('user', array($account->uid => $account), $view_mode); - entity_prepare_view('user', array($account->uid => $account)); + field_attach_prepare_view('user', array($account->uid => $account), $view_mode, $langcode); + entity_prepare_view('user', array($account->uid => $account), $langcode); $account->content += field_attach_view('user', $account, $view_mode, $langcode); // Populate $account->content with a render() array.