From 6d3a7b7f43a1219c0697e7749c58bd157e616f58 Mon Sep 17 00:00:00 2001 From: Logan Smyth Date: Wed, 14 Sep 2011 16:32:36 -0400 Subject: [PATCH] Issue #1260640: Add 'entity_language', 'field_get_raw_items', 'field_set_raw_items', and 'field_process_translations'. --- includes/common.inc | 29 ++++++++++++++ modules/field/field.module | 85 +++++++++++++++++++++++++++++++++++++++++ modules/node/node.module | 1 + modules/system/system.api.php | 7 +++ 4 files changed, 122 insertions(+), 0 deletions(-) diff --git a/includes/common.inc b/includes/common.inc index 72fcf76..4889250 100644 --- a/includes/common.inc +++ b/includes/common.inc @@ -7610,6 +7610,35 @@ function entity_uri($entity_type, $entity) { } /** + * Returns the language of an entity. + * + * @param $entity_type + * The entity type; e.g., 'node' or 'user'. + * @param $entity + * The entity for which to get the language. + * + * @return + * The entity language, or LANGUAGE_NONE if not found. + */ +function entity_language($entity_type, $entity) { + $info = entity_get_info($entity_type); + + // Invoke the callback to get the language. If there is no callback, try + // to get it from a property of the entity, otherwise LANGUAGE_NONE. + if (isset($info['language callback']) && function_exists($info['language callback'])) { + $langcode = $info['language callback']($entity_type, $entity); + } + elseif (!empty($info['entity keys']['language']) && isset($entity->{$info['entity keys']['language']})) { + $langcode = $entity->{$info['entity keys']['language']}; + } + else { + $langcode = LANGUAGE_NONE; + } + + return $langcode; +} + +/** * Returns the label of an entity. * * See the 'label callback' component of the hook_entity_info() return value diff --git a/modules/field/field.module b/modules/field/field.module index 8969547..63d89eb 100644 --- a/modules/field/field.module +++ b/modules/field/field.module @@ -971,6 +971,91 @@ function field_get_items($entity_type, $entity, $field_name, $langcode = NULL) { } /** + * Returns the field items in the entity language or LANGUAGE_NONE if not found. + * + * @param $entity_type + * The type of $entity; e.g., 'node' or 'user'. + * @param $entity + * The entity containing the data to be returned. + * @param $field_name + * The field to be retrieved. + * + * @return + * An array of field items keyed by delta if available, FALSE otherwise. + */ +function field_get_raw_items($entity_type, $entity, $field_name) { + $field = field_info_field($field_name); + $langcode = field_is_translatable($entity_type, $field) ? entity_language($entity_type, $entity) : LANGUAGE_NONE; + return isset($entity->{$field_name}[$langcode]) ? $entity->{$field_name}[$langcode] : FALSE; +} + +/** + * Sets the given field items on the entity for the entity language. + * + * @param $entity_type + * The type of $entity; e.g., 'node' or 'user'. + * @param $entity + * The entity containing the data to be returned. + * @param $field_name + * The field to be retrieved. + * + */ +function field_set_raw_items($entity_type, $entity, $field_name, $items) { + $field = field_info_field($field_name); + $langcode = field_is_translatable($entity_type, $field) ? entity_language($entity_type, $entity) : LANGUAGE_NONE; + $entity->{$field_name}[$langcode] = $items; +} + +/** + * Invoke a callback on every available translation for a given entity field. + * + * @param $entity_type + * The type of $entity; e.g., 'node' or 'user'. + * @param $entity + * The entity containing the data to be returned. + * @param $field_name + * The field to be retrieved. + * @param $callback + * The function to execute on the translation. + * @param $options + * Options to pass to the callback function. + * + * @return + * An array of results returned from the callback. + */ +function field_process_translations($entity_type, $entity, $field_name, $callback, array $options = array()) { + $return = array(); + if (function_exists($callback)) { + list($id, $vid, $bundle) = entity_extract_ids($entity_type, $entity); + $instance = field_info_instance($entity_type, $field_name, $bundle); + + // Load field info and available field languages. + $field = field_info_field($field_name); + $available_languages = field_available_languages($entity_type, $field); + + // Execute callback for each set of items + foreach ($available_languages as $langcode) { + if (isset($entity->{$field_name}[$langcode])) { + $result = $callback($entity_type, $entity, $field, $instance, $langcode, $options, $entity->{$field_name}[$langcode]); + + if (isset($result)) { + // For callbacks with array results, we merge results together. + // For callbacks with scalar results, we collect results in an array. + if (is_array($result)) { + $return = array_merge($return, $result); + } + else { + $return[] = $result; + } + } + } + } + } + + return $return; +} + +/** * Determine whether a field has any data. * * @param $field diff --git a/modules/node/node.module b/modules/node/node.module index 92c6795..ade1a3e 100644 --- a/modules/node/node.module +++ b/modules/node/node.module @@ -177,6 +177,7 @@ function node_entity_info() { 'revision' => 'vid', 'bundle' => 'type', 'label' => 'title', + 'language' => 'language', ), 'bundle keys' => array( 'bundle' => 'type', diff --git a/modules/system/system.api.php b/modules/system/system.api.php index ec7f6b8..fa105a6 100644 --- a/modules/system/system.api.php +++ b/modules/system/system.api.php @@ -87,6 +87,9 @@ function hook_hook_info_alter(&$hooks) { * - uri callback: A function taking an entity as argument and returning the * uri elements of the entity, e.g. 'path' and 'options'. The actual entity * uri can be constructed by passing these elements to url(). + * - language callback: (optional) A function taking an entity type and an + * entity as arguments and returning the langcode of the entity. The entity + * language is used as the default language when processing field values. * - label callback: (optional) A function taking an entity type and an entity * as arguments and returning the label of the entity. The entity label is * the main string associated with an entity; for example, the title of a @@ -123,6 +126,10 @@ function hook_hook_info_alter(&$hooks) { * 'subject' should be specified here. If complex logic is required to * build the label, a 'label callback' should be defined instead (see * the 'label callback' section above for details). + * - language: The name of the property that contains the language. For + * example, if the entity's language is at $entity->language, then + * 'language' would be the value here. For complex language processing, + * you can use 'language callback' instead. * - bundle keys: An array describing how the Field API can extract the * information it needs from the bundle objects for this type. This entry * is required if the 'path' provided in the 'bundles'/'admin' section -- 1.7.5.3